extension_tests.rs

  1use super::Database;
  2use crate::{
  3    db::{queries::extensions::convert_time_to_chrono, ExtensionMetadata, NewExtensionVersion},
  4    test_both_dbs,
  5};
  6use std::sync::Arc;
  7
  8test_both_dbs!(
  9    test_extensions,
 10    test_extensions_postgres,
 11    test_extensions_sqlite
 12);
 13
 14async fn test_extensions(db: &Arc<Database>) {
 15    let versions = db.get_known_extension_versions().await.unwrap();
 16    assert!(versions.is_empty());
 17
 18    let extensions = db.get_extensions(None, 1, 5).await.unwrap();
 19    assert!(extensions.is_empty());
 20
 21    let t0 = time::OffsetDateTime::from_unix_timestamp_nanos(0).unwrap();
 22    let t0 = time::PrimitiveDateTime::new(t0.date(), t0.time());
 23
 24    let t0_chrono = convert_time_to_chrono(t0);
 25
 26    db.insert_extension_versions(
 27        &[
 28            (
 29                "ext1",
 30                vec![
 31                    NewExtensionVersion {
 32                        name: "Extension 1".into(),
 33                        version: semver::Version::parse("0.0.1").unwrap(),
 34                        description: "an extension".into(),
 35                        authors: vec!["max".into()],
 36                        repository: "ext1/repo".into(),
 37                        schema_version: 1,
 38                        wasm_api_version: None,
 39                        published_at: t0,
 40                    },
 41                    NewExtensionVersion {
 42                        name: "Extension One".into(),
 43                        version: semver::Version::parse("0.0.2").unwrap(),
 44                        description: "a good extension".into(),
 45                        authors: vec!["max".into(), "marshall".into()],
 46                        repository: "ext1/repo".into(),
 47                        schema_version: 1,
 48                        wasm_api_version: None,
 49                        published_at: t0,
 50                    },
 51                ],
 52            ),
 53            (
 54                "ext2",
 55                vec![NewExtensionVersion {
 56                    name: "Extension Two".into(),
 57                    version: semver::Version::parse("0.2.0").unwrap(),
 58                    description: "a great extension".into(),
 59                    authors: vec!["marshall".into()],
 60                    repository: "ext2/repo".into(),
 61                    schema_version: 0,
 62                    wasm_api_version: None,
 63                    published_at: t0,
 64                }],
 65            ),
 66        ]
 67        .into_iter()
 68        .collect(),
 69    )
 70    .await
 71    .unwrap();
 72
 73    let versions = db.get_known_extension_versions().await.unwrap();
 74    assert_eq!(
 75        versions,
 76        [
 77            ("ext1".into(), vec!["0.0.1".into(), "0.0.2".into()]),
 78            ("ext2".into(), vec!["0.2.0".into()])
 79        ]
 80        .into_iter()
 81        .collect()
 82    );
 83
 84    // The latest version of each extension is returned.
 85    let extensions = db.get_extensions(None, 1, 5).await.unwrap();
 86    assert_eq!(
 87        extensions,
 88        &[
 89            ExtensionMetadata {
 90                id: "ext1".into(),
 91                manifest: rpc::ExtensionApiManifest {
 92                    name: "Extension One".into(),
 93                    version: "0.0.2".into(),
 94                    authors: vec!["max".into(), "marshall".into()],
 95                    description: Some("a good extension".into()),
 96                    repository: "ext1/repo".into(),
 97                    schema_version: Some(1),
 98                    wasm_api_version: None,
 99                },
100                published_at: t0_chrono,
101                download_count: 0,
102            },
103            ExtensionMetadata {
104                id: "ext2".into(),
105                manifest: rpc::ExtensionApiManifest {
106                    name: "Extension Two".into(),
107                    version: "0.2.0".into(),
108                    authors: vec!["marshall".into()],
109                    description: Some("a great extension".into()),
110                    repository: "ext2/repo".into(),
111                    schema_version: Some(0),
112                    wasm_api_version: None,
113                },
114                published_at: t0_chrono,
115                download_count: 0
116            },
117        ]
118    );
119
120    // Extensions with too new of a schema version are excluded.
121    let extensions = db.get_extensions(None, 0, 5).await.unwrap();
122    assert_eq!(
123        extensions,
124        &[ExtensionMetadata {
125            id: "ext2".into(),
126            manifest: rpc::ExtensionApiManifest {
127                name: "Extension Two".into(),
128                version: "0.2.0".into(),
129                authors: vec!["marshall".into()],
130                description: Some("a great extension".into()),
131                repository: "ext2/repo".into(),
132                schema_version: Some(0),
133                wasm_api_version: None,
134            },
135            published_at: t0_chrono,
136            download_count: 0
137        },]
138    );
139
140    // Record extensions being downloaded.
141    for _ in 0..7 {
142        assert!(db.record_extension_download("ext2", "0.0.2").await.unwrap());
143    }
144
145    for _ in 0..3 {
146        assert!(db.record_extension_download("ext1", "0.0.1").await.unwrap());
147    }
148
149    for _ in 0..2 {
150        assert!(db.record_extension_download("ext1", "0.0.2").await.unwrap());
151    }
152
153    // Record download returns false if the extension does not exist.
154    assert!(!db
155        .record_extension_download("no-such-extension", "0.0.2")
156        .await
157        .unwrap());
158
159    // Extensions are returned in descending order of total downloads.
160    let extensions = db.get_extensions(None, 1, 5).await.unwrap();
161    assert_eq!(
162        extensions,
163        &[
164            ExtensionMetadata {
165                id: "ext2".into(),
166                manifest: rpc::ExtensionApiManifest {
167                    name: "Extension Two".into(),
168                    version: "0.2.0".into(),
169                    authors: vec!["marshall".into()],
170                    description: Some("a great extension".into()),
171                    repository: "ext2/repo".into(),
172                    schema_version: Some(0),
173                    wasm_api_version: None,
174                },
175                published_at: t0_chrono,
176                download_count: 7
177            },
178            ExtensionMetadata {
179                id: "ext1".into(),
180                manifest: rpc::ExtensionApiManifest {
181                    name: "Extension One".into(),
182                    version: "0.0.2".into(),
183                    authors: vec!["max".into(), "marshall".into()],
184                    description: Some("a good extension".into()),
185                    repository: "ext1/repo".into(),
186                    schema_version: Some(1),
187                    wasm_api_version: None,
188                },
189                published_at: t0_chrono,
190                download_count: 5,
191            },
192        ]
193    );
194
195    // Add more extensions, including a new version of `ext1`, and backfilling
196    // an older version of `ext2`.
197    db.insert_extension_versions(
198        &[
199            (
200                "ext1",
201                vec![NewExtensionVersion {
202                    name: "Extension One".into(),
203                    version: semver::Version::parse("0.0.3").unwrap(),
204                    description: "a real good extension".into(),
205                    authors: vec!["max".into(), "marshall".into()],
206                    repository: "ext1/repo".into(),
207                    schema_version: 1,
208                    wasm_api_version: None,
209                    published_at: t0,
210                }],
211            ),
212            (
213                "ext2",
214                vec![NewExtensionVersion {
215                    name: "Extension Two".into(),
216                    version: semver::Version::parse("0.1.0").unwrap(),
217                    description: "an old extension".into(),
218                    authors: vec!["marshall".into()],
219                    repository: "ext2/repo".into(),
220                    schema_version: 0,
221                    wasm_api_version: None,
222                    published_at: t0,
223                }],
224            ),
225        ]
226        .into_iter()
227        .collect(),
228    )
229    .await
230    .unwrap();
231
232    let versions = db.get_known_extension_versions().await.unwrap();
233    assert_eq!(
234        versions,
235        [
236            (
237                "ext1".into(),
238                vec!["0.0.1".into(), "0.0.2".into(), "0.0.3".into()]
239            ),
240            ("ext2".into(), vec!["0.1.0".into(), "0.2.0".into()])
241        ]
242        .into_iter()
243        .collect()
244    );
245
246    let extensions = db.get_extensions(None, 1, 5).await.unwrap();
247    assert_eq!(
248        extensions,
249        &[
250            ExtensionMetadata {
251                id: "ext2".into(),
252                manifest: rpc::ExtensionApiManifest {
253                    name: "Extension Two".into(),
254                    version: "0.2.0".into(),
255                    authors: vec!["marshall".into()],
256                    description: Some("a great extension".into()),
257                    repository: "ext2/repo".into(),
258                    schema_version: Some(0),
259                    wasm_api_version: None,
260                },
261                published_at: t0_chrono,
262                download_count: 7
263            },
264            ExtensionMetadata {
265                id: "ext1".into(),
266                manifest: rpc::ExtensionApiManifest {
267                    name: "Extension One".into(),
268                    version: "0.0.3".into(),
269                    authors: vec!["max".into(), "marshall".into()],
270                    description: Some("a real good extension".into()),
271                    repository: "ext1/repo".into(),
272                    schema_version: Some(1),
273                    wasm_api_version: None,
274                },
275                published_at: t0_chrono,
276                download_count: 5,
277            },
278        ]
279    );
280}