extension_tests.rs

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