diff --git a/mirage/factories/crate.js b/mirage/factories/crate.js index 741cf4e96ab..a9d7f96f308 100644 --- a/mirage/factories/crate.js +++ b/mirage/factories/crate.js @@ -23,10 +23,5 @@ export default Factory.extend({ updated_at: '2017-02-24T12:34:56Z', badges: () => [], - categories: () => [], - keywords: () => [], - versions: () => [], _extra_downloads: () => [], - _owner_teams: () => [], - _owner_users: () => [], }); diff --git a/mirage/factories/dependency.js b/mirage/factories/dependency.js index 414f10d6452..c97ebd7a197 100644 --- a/mirage/factories/dependency.js +++ b/mirage/factories/dependency.js @@ -3,13 +3,19 @@ import { Factory } from 'ember-cli-mirage'; const REQS = ['^0.1.0', '^2.1.3', '0.3.7', '~5.2.12']; export default Factory.extend({ - // crate_id, - // version_id, - default_features: i => i % 4 === 3, features: () => [], kind: i => (i % 3 === 0 ? 'dev' : 'normal'), optional: i => i % 4 !== 3, req: i => REQS[i % REQS.length], target: null, + + afterCreate(self) { + if (!self.crateId) { + throw new Error(`Missing \`crate\` relationship on \`dependency:${self.id}\``); + } + if (!self.versionId) { + throw new Error(`Missing \`version\` relationship on \`dependency:${self.id}\``); + } + }, }); diff --git a/mirage/factories/version-download.js b/mirage/factories/version-download.js index 2e5f0085360..0490a4fbe87 100644 --- a/mirage/factories/version-download.js +++ b/mirage/factories/version-download.js @@ -1,8 +1,12 @@ import { Factory } from 'ember-cli-mirage'; export default Factory.extend({ - // version - date: '2019-05-21', downloads: i => (((i * 42) % 13) + 4) * 2345, + + afterCreate(self) { + if (!self.versionId) { + throw new Error(`Missing \`version\` relationship on \`version-download:${self.date}\``); + } + }, }); diff --git a/mirage/factories/version.js b/mirage/factories/version.js index d3b49a050cf..a0fc91a6db3 100644 --- a/mirage/factories/version.js +++ b/mirage/factories/version.js @@ -11,10 +11,6 @@ export default Factory.extend({ yanked: false, license: i => LICENSES[i % LICENSES.length], - dl_path() { - return `/api/v1/crates/${this.crate}/${this.num}/download`; - }, - downloads: i => (((i + 13) * 42) % 13) * 1234, features: () => {}, @@ -22,8 +18,9 @@ export default Factory.extend({ crate_size: i => (((i + 13) * 42) % 13) * 54321, - afterCreate(version, server) { - let crate = server.schema.crates.find(version.crate); - crate.update({ versions: crate.versions.concat(parseInt(version.id, 10)) }); + afterCreate(version) { + if (!version.crateId) { + throw new Error(`Missing \`crate\` relationship on \`version:${version.num}\``); + } }, }); diff --git a/mirage/fixtures/crates.js b/mirage/fixtures/crates.js index 8ec46073fa6..fa5c64d8c22 100644 --- a/mirage/fixtures/crates.js +++ b/mirage/fixtures/crates.js @@ -15,13 +15,13 @@ export default [ recent_downloads: 125, homepage: 'https://icorderi.github.io/icorderi/kinetic-rust', id: 'kinetic-rust', - keywords: ['Protocol', 'Kinetic', 'Storage'], + keywordIds: [], max_version: '0.0.16', newest_version: '0.0.16', name: 'kinetic-rust', repository: 'https://github.com/icorderi/kinetic-rust/', updated_at: '2015-04-21T00:15:49Z', - versions: null, + versionIds: [], }, { badges: [ @@ -32,7 +32,7 @@ export default [ }, }, ], - categories: [], + categoryIds: [], created_at: '2014-12-08T02:08:06Z', description: 'A high-level, Rust idiomatic wrapper around nanomsg.', documentation: 'https://github.com/thehydroimpulse/nanomsg.rs', @@ -40,13 +40,13 @@ export default [ recent_downloads: 800, homepage: 'https://github.com/thehydroimpulse/nanomsg.rs', id: 'nanomsg', - keywords: ['network'], + keywordIds: ['network'], max_version: '0.7.0-alpha', newest_version: '0.6.1', name: 'nanomsg', repository: 'https://github.com/thehydroimpulse/nanomsg.rs', updated_at: '2016-12-28T08:40:00Z', - versions: [40906, 40905, 28431, 21273, 18445, 17384, 13574, 9014, 8236, 7190, 4944, 940, 924], + versionIds: [40906, 40905, 28431, 21273, 18445, 17384, 13574, 9014, 8236, 7190, 4944, 940, 924], _extra_downloads: [ { date: '2017-02-02', @@ -57,8 +57,8 @@ export default [ downloads: 14, }, ], - _owner_teams: [1, 303], - _owner_users: [2, 303], + teamOwnerIds: [1, 303], + userOwnerIds: [2, 303], }, { created_at: '2015-02-27T11:52:13Z', @@ -70,7 +70,7 @@ export default [ exact_match: true, homepage: 'https://github.com/huonw/external_mixin', id: 'rust_mixin', - keywords: ['rust', 'plugin', 'code-generation'], + keywordIds: ['rust', 'plugin', 'code-generation'], max_version: '0.0.1', newest_version: '0.0.1', name: 'rust_mixin', @@ -132,7 +132,7 @@ export default [ badge_type: 'coveralls', }, ], - versions: null, + versionIds: [], }, { created_at: '2015-02-27T11:51:58Z', @@ -143,13 +143,13 @@ export default [ recent_downloads: 497, homepage: 'https://github.com/huonw/external_mixin', id: 'external_mixin', - keywords: ['python', 'ruby', 'shell', 'plugin', 'code-generation'], + keywordIds: ['python', 'ruby', 'shell', 'plugin', 'code-generation'], max_version: '0.0.1', newest_version: '0.0.1', name: 'external_mixin', repository: 'https://github.com/huonw/external_mixin', updated_at: '2015-02-27T11:51:58Z', - versions: null, + versionIds: [], }, { created_at: '2015-02-27T11:51:40Z', @@ -159,13 +159,13 @@ export default [ recent_downloads: 0, homepage: 'https://github.com/huonw/external_mixin', id: 'external_mixin_umbrella', - keywords: ['plugin', 'code-generation'], + keywordIds: ['plugin', 'code-generation'], max_version: '0.0.2', newest_version: '0.0.2', name: 'external_mixin_umbrella', repository: 'https://github.com/huonw/external_mixin', updated_at: '2015-02-27T11:52:30Z', - versions: null, + versionIds: [], }, { created_at: '2015-10-10T15:26:24Z', @@ -176,13 +176,13 @@ export default [ recent_downloads: 1, homepage: 'https://github.com/whatisinternet/inflector', id: 'Inflector', - keywords: ['string', 'case', 'camel', 'snake', 'inflection'], + keywordIds: ['string', 'case', 'camel', 'snake', 'inflection'], max_version: '0.1.6', newest_version: '0.1.6', name: 'Inflector', repository: 'https://github.com/whatisinternet/inflector', updated_at: '2015-10-27T01:51:42Z', - versions: null, + versionIds: [], }, { created_at: '2015-05-21T17:43:38Z', @@ -192,13 +192,13 @@ export default [ recent_downloads: 21, homepage: null, id: 'rs-es', - keywords: ['elasticsearch', 'elastic'], + keywordIds: ['elasticsearch', 'elastic'], max_version: '0.1.17', newest_version: '0.1.17', name: 'rs-es', repository: 'https://github.com/benashford/rs-es', updated_at: '2015-09-09T15:34:50Z', - versions: null, + versionIds: [], }, { created_at: '2014-11-21T05:12:08Z', @@ -208,13 +208,13 @@ export default [ recent_downloads: 2000, homepage: 'https://github.com/DaGenix/rust-crypto/', id: 'rust-crypto', - keywords: ['Crypto', 'MD5', 'Sha1', 'Sha2', 'AES'], + keywordIds: [], max_version: '0.2.34', newest_version: '0.2.34', name: 'rust-crypto', repository: 'https://github.com/DaGenix/rust-crypto/', updated_at: '2015-10-29T01:16:17Z', - versions: null, + versionIds: [], }, { created_at: '2015-03-20T13:46:04Z', @@ -224,13 +224,13 @@ export default [ recent_downloads: 85, homepage: null, id: 'rust-htslib', - keywords: ['htslib', 'bam', 'bioinformatics', 'pileup', 'sequencing'], + keywordIds: [], max_version: '0.5.2', newest_version: '0.5.2', name: 'rust-htslib', repository: 'https://github.com/rust-bio/rust-htslib.git', updated_at: '2015-11-11T00:10:43Z', - versions: null, + versionIds: [], }, { created_at: '2014-11-29T17:51:55Z', @@ -240,13 +240,13 @@ export default [ recent_downloads: 500, homepage: 'https://github.com/rustless/rustless', id: 'rustless', - keywords: ['api', 'web', 'hyper', 'iron', 'rest'], + keywordIds: [], max_version: '0.8.0', newest_version: '0.8.0', name: 'rustless', repository: 'https://crates.io/crates/rustless', updated_at: '2015-10-31T11:49:29Z', - versions: null, + versionIds: [], }, { created_at: '2014-12-05T20:20:39Z', @@ -256,13 +256,13 @@ export default [ recent_downloads: 854, homepage: null, id: 'serde', - keywords: ['serde', 'serialization'], + keywordIds: [], max_version: '0.6.1', newest_version: '0.6.1', name: 'serde', repository: 'https://github.com/serde-rs/serde', updated_at: '2015-10-18T03:10:21Z', - versions: null, + versionIds: [], }, { created_at: '2015-08-26T13:50:58Z', @@ -272,13 +272,13 @@ export default [ recent_downloads: 54, homepage: 'https://github.com/livioribeiro/rusted-cypher', id: 'rusted_cypher', - keywords: ['neo4j', 'database', 'query', 'cypher', 'graph'], + keywordIds: [], max_version: '0.7.1', newest_version: '0.7.1', name: 'rusted_cypher', repository: 'https://github.com/livioribeiro/rusted-cypher', updated_at: '2015-11-07T17:26:55Z', - versions: null, + versionIds: [], }, { created_at: '2015-01-02T20:54:04Z', @@ -289,13 +289,13 @@ export default [ recent_downloads: 23, homepage: null, id: 'zlib', - keywords: [], + keywordIds: [], max_version: '0.0.1', newest_version: '0.0.1', name: 'zlib', repository: null, updated_at: '2015-01-02T20:54:04Z', - versions: null, + versionIds: [], }, { created_at: '2015-05-08T19:34:16Z', @@ -306,13 +306,13 @@ export default [ recent_downloads: 76, homepage: null, id: 'rustful', - keywords: ['web', 'rest', 'framework', 'http', 'routing'], + keywordIds: [], max_version: '0.5.0', newest_version: '0.5.0', name: 'rustful', repository: 'https://github.com/Ogeon/rustful', updated_at: '2015-09-19T21:10:27Z', - versions: null, + versionIds: [], }, { created_at: '2014-11-24T02:34:44Z', @@ -322,13 +322,13 @@ export default [ recent_downloads: 13, homepage: null, id: 'postgres', - keywords: ['database', 'sql'], + keywordIds: [], max_version: '0.10.1', newest_version: '0.10.1', name: 'postgres', repository: 'https://github.com/sfackler/rust-postgres', updated_at: '2015-11-08T00:48:59Z', - versions: null, + versionIds: [], }, { created_at: '2014-11-21T00:20:47Z', @@ -338,13 +338,13 @@ export default [ recent_downloads: 143, homepage: 'https://github.com/BurntSushi/quickcheck', id: 'quickcheck', - keywords: ['testing', 'quickcheck', 'property', 'shrinking', 'fuzz'], + keywordIds: [], max_version: '0.2.24', newest_version: '0.2.24', name: 'quickcheck', repository: 'https://github.com/BurntSushi/quickcheck', updated_at: '2015-09-20T21:53:38Z', - versions: null, + versionIds: [], }, { created_at: '2014-11-21T00:21:04Z', @@ -354,13 +354,13 @@ export default [ recent_downloads: 768, homepage: 'https://github.com/BurntSushi/quickcheck', id: 'quickcheck_macros', - keywords: ['testing', 'quickcheck', 'property', 'shrinking', 'fuzz'], + keywordIds: [], max_version: '0.2.24', newest_version: '0.2.24', name: 'quickcheck_macros', repository: 'https://github.com/BurntSushi/quickcheck', updated_at: '2015-09-20T21:53:57Z', - versions: null, + versionIds: [], }, { created_at: '2015-08-25T19:15:35Z', @@ -370,14 +370,14 @@ export default [ downloads: 109, recent_downloads: 0, homepage: 'https://github.com/nicolas-cherel/rustlex', - id: 'nc_rustlex', - keywords: ['lexer', 'lexical', 'analyser', 'generator'], + id: 'unicorn-rpc', + keywordIds: [], max_version: '0.3.1', newest_version: '0.3.1', - name: 'nc_rustlex', + name: 'unicorn-rpc', repository: 'https://github.com/nicolas-cherel/rustlex', updated_at: '2015-08-25T19:15:35Z', - versions: null, + versionIds: [], }, { created_at: '2015-01-17T17:47:52Z', @@ -387,12 +387,44 @@ export default [ recent_downloads: 69, homepage: null, id: 'nom', - keywords: ['parser', 'parser-combinators', 'parsing', 'streaming', 'bit'], + keywordIds: [], max_version: '1.0.1', newest_version: '1.0.1', name: 'nom', repository: 'https://github.com/Geal/nom', updated_at: '2015-11-22T22:00:41Z', - versions: null, + versionIds: [], + }, + { + id: 'libc', + name: 'libc', + max_version: '1.0.1', + newest_version: '1.0.1', + downloads: 5169, + recent_downloads: 69, + }, + { + id: 'nanomsg-sys', + name: 'nanomsg-sys', + max_version: '1.0.1', + newest_version: '1.0.1', + downloads: 5169, + recent_downloads: 69, + }, + { + id: 'mock-build-deps', + name: 'mock-build-deps', + max_version: '1.0.1', + newest_version: '1.0.1', + downloads: 5169, + recent_downloads: 69, + }, + { + id: 'mock-dev-deps', + name: 'mock-dev-deps', + max_version: '1.0.1', + newest_version: '1.0.1', + downloads: 5169, + recent_downloads: 69, }, ]; diff --git a/mirage/fixtures/dependencies.js b/mirage/fixtures/dependencies.js index 61fceb78ab2..8a55eef6952 100644 --- a/mirage/fixtures/dependencies.js +++ b/mirage/fixtures/dependencies.js @@ -1,6 +1,6 @@ export default [ { - crate_id: 'libc', + crateId: 'libc', default_features: true, features: '', id: 146231, @@ -8,10 +8,10 @@ export default [ optional: false, req: '^0.2.18', target: null, - version_id: 40905, + versionId: 40905, }, { - crate_id: 'nanomsg-sys', + crateId: 'nanomsg-sys', default_features: true, features: '', id: 146232, @@ -19,10 +19,10 @@ export default [ optional: false, req: '^0.6.1', target: null, - version_id: 40905, + versionId: 40905, }, { - crate_id: 'nanomsg', + crateId: 'nanomsg', default_features: true, features: '', id: 146233, @@ -30,10 +30,10 @@ export default [ optional: false, req: '^0.5.0', target: null, - version_id: 28674, + versionId: 28674, }, { - crate_id: 'mock-build-deps', + crateId: 'mock-build-deps', default_features: true, features: '', id: 146234, @@ -41,10 +41,10 @@ export default [ optional: false, req: '^0.6.1', target: null, - version_id: 40905, + versionId: 40905, }, { - crate_id: 'mock-dev-deps', + crateId: 'mock-dev-deps', default_features: true, features: '', id: 146235, @@ -52,6 +52,6 @@ export default [ optional: true, req: '^0.6.1', target: null, - version_id: 40905, + versionId: 40905, }, ]; diff --git a/mirage/fixtures/keywords.js b/mirage/fixtures/keywords.js index b370228b6b3..fda98b3966d 100644 --- a/mirage/fixtures/keywords.js +++ b/mirage/fixtures/keywords.js @@ -5,4 +5,82 @@ export default [ id: 'network', keyword: 'network', }, + { + crates_cnt: 1, + created_at: '2014-11-23T06:47:40Z', + id: 'rust', + keyword: 'rust', + }, + { + crates_cnt: 1, + created_at: '2014-11-23T06:47:40Z', + id: 'plugin', + keyword: 'plugin', + }, + { + crates_cnt: 1, + created_at: '2014-11-23T06:47:40Z', + id: 'code-generation', + keyword: 'code-generation', + }, + { + crates_cnt: 1, + created_at: '2014-11-23T06:47:40Z', + id: 'python', + keyword: 'python', + }, + { + crates_cnt: 1, + created_at: '2014-11-23T06:47:40Z', + id: 'ruby', + keyword: 'ruby', + }, + { + crates_cnt: 1, + created_at: '2014-11-23T06:47:40Z', + id: 'shell', + keyword: 'shell', + }, + { + crates_cnt: 1, + created_at: '2014-11-23T06:47:40Z', + id: 'string', + keyword: 'string', + }, + { + crates_cnt: 1, + created_at: '2014-11-23T06:47:40Z', + id: 'case', + keyword: 'case', + }, + { + crates_cnt: 1, + created_at: '2014-11-23T06:47:40Z', + id: 'camel', + keyword: 'camel', + }, + { + crates_cnt: 1, + created_at: '2014-11-23T06:47:40Z', + id: 'snake', + keyword: 'snake', + }, + { + crates_cnt: 1, + created_at: '2014-11-23T06:47:40Z', + id: 'inflection', + keyword: 'inflection', + }, + { + crates_cnt: 1, + created_at: '2014-11-23T06:47:40Z', + id: 'elastic', + keyword: 'elastic', + }, + { + crates_cnt: 1, + created_at: '2014-11-23T06:47:40Z', + id: 'elasticsearch', + keyword: 'elasticsearch', + }, ]; diff --git a/mirage/fixtures/version-downloads.js b/mirage/fixtures/version-downloads.js index d8ed3b7a6da..26728e8565c 100644 --- a/mirage/fixtures/version-downloads.js +++ b/mirage/fixtures/version-downloads.js @@ -2,16 +2,16 @@ export default [ { date: '2017-02-10T00:00:00Z', downloads: 2, - version: 40905, + versionId: 40905, }, { date: '2017-02-10T00:00:00Z', downloads: 1, - version: 18445, + versionId: 18445, }, { date: '2017-02-11T00:00:00Z', downloads: 1, - version: 40905, + versionId: 40905, }, ]; diff --git a/mirage/fixtures/versions.js b/mirage/fixtures/versions.js index e7aaa14bd6f..1acccfc7920 100644 --- a/mirage/fixtures/versions.js +++ b/mirage/fixtures/versions.js @@ -1,8 +1,7 @@ export default [ { - crate: 'nanomsg', + crateId: 'nanomsg', created_at: '2016-12-20T07:30:00Z', - dl_path: '/api/v1/crates/nanomsg/0.7.0-alpha.1/download', downloads: 260, features: { bundled: ['nanomsg-sys/bundled'], @@ -25,9 +24,8 @@ export default [ ], }, { - crate: 'nanomsg', + crateId: 'nanomsg', created_at: '2016-12-27T08:40:00Z', - dl_path: '/api/v1/crates/nanomsg/0.6.1/download', downloads: 260, features: { bundled: ['nanomsg-sys/bundled'], @@ -50,9 +48,8 @@ export default [ ], }, { - crate: 'nanomsg', + crateId: 'nanomsg', created_at: '2016-06-10T20:03:55Z', - dl_path: '/api/v1/crates/nanomsg/0.6.0/download', downloads: 904, features: {}, id: 28431, @@ -72,9 +69,8 @@ export default [ ], }, { - crate: 'nanomsg', + crateId: 'nanomsg', created_at: '2016-01-24T22:07:58Z', - dl_path: '/api/v1/crates/nanomsg/0.5.0/download', downloads: 1217, features: {}, id: 21273, @@ -94,9 +90,8 @@ export default [ ], }, { - crate: 'nanomsg', + crateId: 'nanomsg', created_at: '2015-11-23T12:10:09Z', - dl_path: '/api/v1/crates/nanomsg/0.4.2/download', downloads: 318, features: {}, id: 18445, @@ -116,9 +111,8 @@ export default [ ], }, { - crate: 'nanomsg', + crateId: 'nanomsg', created_at: '2015-10-29T22:13:45Z', - dl_path: '/api/v1/crates/nanomsg/0.4.1/download', downloads: 168, features: {}, id: 17384, @@ -138,9 +132,8 @@ export default [ ], }, { - crate: 'nanomsg', + crateId: 'nanomsg', created_at: '2015-07-23T05:54:44Z', - dl_path: '/api/v1/crates/nanomsg/0.4.0/download', downloads: 311, features: {}, id: 13574, @@ -160,9 +153,8 @@ export default [ ], }, { - crate: 'nanomsg', + crateId: 'nanomsg', created_at: '2015-04-18T20:45:03Z', - dl_path: '/api/v1/crates/nanomsg/0.3.4/download', downloads: 237, features: {}, id: 9014, @@ -182,9 +174,8 @@ export default [ ], }, { - crate: 'nanomsg', + crateId: 'nanomsg', created_at: '2015-04-06T18:57:47Z', - dl_path: '/api/v1/crates/nanomsg/0.3.3/download', downloads: 99, features: {}, id: 8236, @@ -204,9 +195,8 @@ export default [ ], }, { - crate: 'nanomsg', + crateId: 'nanomsg', created_at: '2015-03-26T06:51:10Z', - dl_path: '/api/v1/crates/nanomsg/0.3.2/download', downloads: 98, features: {}, id: 7190, @@ -226,9 +216,8 @@ export default [ ], }, { - crate: 'nanomsg', + crateId: 'nanomsg', created_at: '2015-02-12T20:20:32Z', - dl_path: '/api/v1/crates/nanomsg/0.3.1/download', downloads: 95, features: {}, id: 4944, @@ -248,9 +237,8 @@ export default [ ], }, { - crate: 'nanomsg', + crateId: 'nanomsg', created_at: '2014-12-08T16:21:01Z', - dl_path: '/api/v1/crates/nanomsg/0.3.0/download', downloads: 102, features: {}, id: 940, @@ -270,9 +258,8 @@ export default [ ], }, { - crate: 'nanomsg', + crateId: 'nanomsg', created_at: '2014-12-08T02:08:06Z', - dl_path: '/api/v1/crates/nanomsg/0.2.0/download', downloads: 79, features: {}, id: 924, @@ -292,9 +279,8 @@ export default [ ], }, { - crate: 'unicorn-rpc', + crateId: 'unicorn-rpc', created_at: '2014-12-08T02:08:06Z', - dl_path: '/api/v1/crates/unicorn-rpc/0.2.0/download', downloads: 79, features: {}, id: 28674, diff --git a/mirage/models/crate.js b/mirage/models/crate.js index 770b50936d3..74fb5b5d816 100644 --- a/mirage/models/crate.js +++ b/mirage/models/crate.js @@ -1,3 +1,9 @@ -import { Model } from 'ember-cli-mirage'; +import { Model, hasMany } from 'ember-cli-mirage'; -export default Model.extend({}); +export default Model.extend({ + categories: hasMany(), + keywords: hasMany(), + teamOwners: hasMany('team'), + versions: hasMany(), + userOwners: hasMany('user'), +}); diff --git a/mirage/models/dependency.js b/mirage/models/dependency.js index 770b50936d3..aab4813aa97 100644 --- a/mirage/models/dependency.js +++ b/mirage/models/dependency.js @@ -1,3 +1,6 @@ -import { Model } from 'ember-cli-mirage'; +import { Model, belongsTo } from 'ember-cli-mirage'; -export default Model.extend({}); +export default Model.extend({ + crate: belongsTo(), + version: belongsTo(), +}); diff --git a/mirage/models/version-download.js b/mirage/models/version-download.js index 770b50936d3..6728cf2f9e4 100644 --- a/mirage/models/version-download.js +++ b/mirage/models/version-download.js @@ -1,3 +1,5 @@ -import { Model } from 'ember-cli-mirage'; +import { Model, belongsTo } from 'ember-cli-mirage'; -export default Model.extend({}); +export default Model.extend({ + version: belongsTo(), +}); diff --git a/mirage/models/version.js b/mirage/models/version.js index 770b50936d3..ca4c10fcd01 100644 --- a/mirage/models/version.js +++ b/mirage/models/version.js @@ -1,3 +1,5 @@ -import { Model } from 'ember-cli-mirage'; +import { Model, belongsTo } from 'ember-cli-mirage'; -export default Model.extend({}); +export default Model.extend({ + crate: belongsTo(), +}); diff --git a/mirage/route-handlers/crates.js b/mirage/route-handlers/crates.js index ac72552c889..45472b63c46 100644 --- a/mirage/route-handlers/crates.js +++ b/mirage/route-handlers/crates.js @@ -38,17 +38,11 @@ export function register(server) { let crate = schema.crates.find(crateId); if (!crate) return notFound(); - let categories = schema.categories.all().filter(category => (crate.categories || []).indexOf(category.id) !== -1); - let keywords = schema.keywords.all().filter(keyword => (crate.keywords || []).indexOf(keyword.id) !== -1); - let versions = schema.versions - .all() - .filter(version => (crate.versions || []).indexOf(parseInt(version.id, 10)) !== -1); - return { ...this.serialize(crate), - ...this.serialize(categories), - ...this.serialize(keywords), - ...this.serialize(versions), + ...this.serialize(crate.categories), + ...this.serialize(crate.keywords), + ...this.serialize(crate.versions), }; }); @@ -61,7 +55,7 @@ export function register(server) { let crate = schema.crates.find(crateId); if (!crate) return notFound(); - return schema.versions.where({ crate: crateId }).sort((a, b) => compareIsoDates(b.created_at, a.created_at)); + return crate.versions.sort((a, b) => compareIsoDates(b.created_at, a.created_at)); }); server.get('/api/v1/crates/:crate_id/:version_num/authors', (schema, request) => { @@ -70,7 +64,7 @@ export function register(server) { if (!crate) return notFound(); let num = request.params.version_num; - let version = schema.versions.findBy({ crate: crateId, num }); + let version = schema.versions.findBy({ crateId, num }); if (!version) return { errors: [{ detail: `crate \`${crateId}\` does not have a version \`${num}\`` }] }; return { meta: { names: version._authors }, users: [] }; @@ -82,10 +76,10 @@ export function register(server) { if (!crate) return notFound(); let num = request.params.version_num; - let version = schema.versions.findBy({ crate: crateId, num }); + let version = schema.versions.findBy({ crateId, num }); if (!version) return { errors: [{ detail: `crate \`${crateId}\` does not have a version \`${num}\`` }] }; - return schema.dependencies.where({ version_id: version.id }); + return schema.dependencies.where({ versionId: version.id }); }); server.get('/api/v1/crates/:crate_id/:version_num/downloads', function(schema, request) { @@ -94,10 +88,10 @@ export function register(server) { if (!crate) return notFound(); let versionNum = request.params.version_num; - let version = schema.versions.findBy({ crate: crateId, num: versionNum }); + let version = schema.versions.findBy({ crateId, num: versionNum }); if (!version) return { errors: [{ detail: `crate \`${crateId}\` does not have a version \`${versionNum}\`` }] }; - return schema.versionDownloads.where({ version: version.id }); + return schema.versionDownloads.where({ versionId: version.id }); }); server.get('/api/v1/crates/:crate_id/owner_user', function(schema, request) { @@ -105,9 +99,7 @@ export function register(server) { let crate = schema.crates.find(crateId); if (!crate) return notFound(); - let users = schema.users.find(crate._owner_users); - - let response = this.serialize(users); + let response = this.serialize(crate.userOwners); response.users.forEach(user => { user.kind = 'user'; @@ -121,9 +113,7 @@ export function register(server) { let crate = schema.crates.find(crateId); if (!crate) return notFound(); - let teams = schema.teams.find(crate._owner_teams); - - let response = this.serialize(teams); + let response = this.serialize(crate.teamOwners); response.teams.forEach(team => { team.kind = 'team'; @@ -139,11 +129,11 @@ export function register(server) { let { start, end } = pageParams(request); - let allDependencies = schema.dependencies.where({ crate_id: crateId }); + let allDependencies = schema.dependencies.where({ crateId: crateId }); let dependencies = allDependencies.slice(start, end); let total = allDependencies.length; - let versions = schema.versions.find(dependencies.models.map(it => it.version_id)); + let versions = schema.versions.find(dependencies.models.map(it => it.versionId)); return { ...this.serialize(dependencies), @@ -157,9 +147,7 @@ export function register(server) { let crate = schema.crates.find(crateId); if (!crate) return notFound(); - let versionDownloads = schema.versionDownloads - .all() - .filter(it => crate.versions.indexOf(parseInt(it.version, 10)) !== -1); + let versionDownloads = schema.versionDownloads.all().filter(it => it.version.crateId === crateId); return withMeta(this.serialize(versionDownloads), { extra_downloads: crate._extra_downloads }); }); diff --git a/mirage/serializers/crate.js b/mirage/serializers/crate.js index ef9ad34957c..b14261e8b52 100644 --- a/mirage/serializers/crate.js +++ b/mirage/serializers/crate.js @@ -30,4 +30,32 @@ export default BaseSerializer.extend({ versions: `/api/v1/crates/${crate.id}/versions`, }; }, + + getHashForResource() { + let [hash, addToIncludes] = BaseSerializer.prototype.getHashForResource.apply(this, arguments); + + if (Array.isArray(hash)) { + for (let resource of hash) { + this._adjust(resource); + } + } else { + this._adjust(hash); + } + + return [hash, addToIncludes]; + }, + + _adjust(hash) { + hash.categories = hash.category_ids; + delete hash.category_ids; + + hash.keywords = hash.keyword_ids; + delete hash.keyword_ids; + + hash.versions = hash.version_ids; + delete hash.version_ids; + + delete hash.team_owner_ids; + delete hash.user_owner_ids; + }, }); diff --git a/mirage/serializers/version-download.js b/mirage/serializers/version-download.js new file mode 100644 index 00000000000..53b0582efcf --- /dev/null +++ b/mirage/serializers/version-download.js @@ -0,0 +1,23 @@ +import BaseSerializer from './application'; + +export default BaseSerializer.extend({ + getHashForResource() { + let [hash, addToIncludes] = BaseSerializer.prototype.getHashForResource.apply(this, arguments); + + if (Array.isArray(hash)) { + for (let resource of hash) { + this._adjust(resource); + } + } else { + this._adjust(hash); + } + + return [hash, addToIncludes]; + }, + + _adjust(hash) { + hash.version = hash.version_id; + delete hash.version_id; + delete hash.id; + }, +}); diff --git a/mirage/serializers/version.js b/mirage/serializers/version.js index 06f2d158ccc..e4c66d640ff 100644 --- a/mirage/serializers/version.js +++ b/mirage/serializers/version.js @@ -2,9 +2,8 @@ import BaseSerializer from './application'; export default BaseSerializer.extend({ attrs: [ - 'crate', + 'crate_id', 'created_at', - 'dl_path', 'downloads', 'features', 'id', @@ -18,9 +17,29 @@ export default BaseSerializer.extend({ links(version) { return { - authors: `/api/v1/crates/${version.crate}/${version.num}/authors`, - dependencies: `/api/v1/crates/${version.crate}/${version.num}/dependencies`, - version_downloads: `/api/v1/crates/${version.crate}/${version.num}/downloads`, + authors: `/api/v1/crates/${version.crateId}/${version.num}/authors`, + dependencies: `/api/v1/crates/${version.crateId}/${version.num}/dependencies`, + version_downloads: `/api/v1/crates/${version.crateId}/${version.num}/downloads`, }; }, + + getHashForResource() { + let [hash, addToIncludes] = BaseSerializer.prototype.getHashForResource.apply(this, arguments); + + if (Array.isArray(hash)) { + for (let resource of hash) { + this._adjust(resource); + } + } else { + this._adjust(hash); + } + + return [hash, addToIncludes]; + }, + + _adjust(hash) { + hash.dl_path = `/api/v1/crates/${hash.crate_id}/${hash.num}/download`; + hash.crate = hash.crate_id; + delete hash.crate_id; + }, }); diff --git a/tests/acceptance/crate-test.js b/tests/acceptance/crate-test.js index b189b7fdc60..6921e68c73c 100644 --- a/tests/acceptance/crate-test.js +++ b/tests/acceptance/crate-test.js @@ -16,8 +16,8 @@ module('Acceptance | crate page', function(hooks) { assert.expect(0); this.server.create('crate', { name: 'nanomsg', max_version: '0.6.1' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); + this.server.create('version', { crateId: 'nanomsg', num: '0.6.0' }); + this.server.create('version', { crateId: 'nanomsg', num: '0.6.1' }); await visit('/crates/nanomsg'); percySnapshot(assert); @@ -29,8 +29,8 @@ module('Acceptance | crate page', function(hooks) { assert.expect(0); this.server.create('crate', { name: 'nanomsg', max_version: '0.6.1' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); + this.server.create('version', { crateId: 'nanomsg', num: '0.6.0' }); + this.server.create('version', { crateId: 'nanomsg', num: '0.6.1' }); await visit('/crates/nanomsg/0.6.0'); percySnapshot(assert); @@ -51,7 +51,7 @@ module('Acceptance | crate page', function(hooks) { test('visiting a crate page from the front page', async function(assert) { this.server.create('crate', { name: 'nanomsg', newest_version: '0.6.1' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); + this.server.create('version', { crateId: 'nanomsg', num: '0.6.1' }); await visit('/'); await click('[data-test-just-updated] [data-test-crate-link="0"]'); @@ -65,8 +65,8 @@ module('Acceptance | crate page', function(hooks) { test('visiting /crates/nanomsg', async function(assert) { this.server.create('crate', { name: 'nanomsg', max_version: '0.6.1' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); + this.server.create('version', { crateId: 'nanomsg', num: '0.6.0' }); + this.server.create('version', { crateId: 'nanomsg', num: '0.6.1' }); await visit('/crates/nanomsg'); @@ -80,8 +80,8 @@ module('Acceptance | crate page', function(hooks) { test('visiting /crates/nanomsg/', async function(assert) { this.server.create('crate', { name: 'nanomsg', max_version: '0.6.1' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); + this.server.create('version', { crateId: 'nanomsg', num: '0.6.0' }); + this.server.create('version', { crateId: 'nanomsg', num: '0.6.1' }); await visit('/crates/nanomsg/'); @@ -95,8 +95,8 @@ module('Acceptance | crate page', function(hooks) { test('visiting /crates/nanomsg/0.6.0', async function(assert) { this.server.create('crate', { name: 'nanomsg', max_version: '0.6.1' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); + this.server.create('version', { crateId: 'nanomsg', num: '0.6.0' }); + this.server.create('version', { crateId: 'nanomsg', num: '0.6.1' }); await visit('/crates/nanomsg/0.6.0'); diff --git a/tests/acceptance/front-page-test.js b/tests/acceptance/front-page-test.js index 8fc023b87b0..71c38516b52 100644 --- a/tests/acceptance/front-page-test.js +++ b/tests/acceptance/front-page-test.js @@ -32,8 +32,8 @@ module('Acceptance | front page', function(hooks) { assert.dom('[data-test-all-crates-link]').exists(); assert.dom('[data-test-login-link]').exists(); - assert.dom('[data-test-total-downloads]').hasText('122,669'); - assert.dom('[data-test-total-crates]').hasText('19'); + assert.dom('[data-test-total-downloads]').hasText('143,345'); + assert.dom('[data-test-total-crates]').hasText('23'); assert.dom('[data-test-new-crates] [data-test-crate-link="0"]').hasText('Inflector (0.1.6)'); assert.dom('[data-test-new-crates] [data-test-crate-link="0"]').hasAttribute('href', '/crates/Inflector/0.1.6'); diff --git a/tests/acceptance/search-test.js b/tests/acceptance/search-test.js index 3068f5798e1..acd239a5825 100644 --- a/tests/acceptance/search-test.js +++ b/tests/acceptance/search-test.js @@ -34,7 +34,7 @@ module('Acceptance | search', function(hooks) { assert.equal(title(), "Search Results for 'rust' - crates.io: Rust Package Registry"); assert.dom('[data-test-heading]').hasText("Search Results for 'rust'"); - assert.dom('[data-test-search-nav]').hasText('Displaying 1-8 of 8 total results'); + assert.dom('[data-test-search-nav]').hasText('Displaying 1-7 of 7 total results'); assert .dom('[data-test-search-sort]') .hasText('Sort by Relevance Relevance All-Time Downloads Recent Downloads Recent Updates'); @@ -59,7 +59,7 @@ module('Acceptance | search', function(hooks) { assert.dom('[data-test-search-input]').hasValue('rust'); assert.dom('[data-test-heading]').hasText("Search Results for 'rust'"); - assert.dom('[data-test-search-nav]').hasText('Displaying 1-8 of 8 total results'); + assert.dom('[data-test-search-nav]').hasText('Displaying 1-7 of 7 total results'); }); test('clearing search results', async function(assert) { diff --git a/tests/mirage/crates-test.js b/tests/mirage/crates-test.js index 95828164889..66a17859a3b 100644 --- a/tests/mirage/crates-test.js +++ b/tests/mirage/crates-test.js @@ -216,14 +216,15 @@ module('Mirage | Keywords', function(hooks) { test('includes related versions', async function(assert) { this.server.create('crate', { name: 'rand' }); - this.server.create('version', { crate: 'rand', num: '1.0.0' }); - this.server.create('version', { crate: 'rand', num: '1.1.0' }); - this.server.create('version', { crate: 'rand', num: '1.2.0' }); + this.server.create('version', { crateId: 'rand', num: '1.0.0' }); + this.server.create('version', { crateId: 'rand', num: '1.1.0' }); + this.server.create('version', { crateId: 'rand', num: '1.2.0' }); let response = await fetch('/api/v1/crates/rand'); assert.equal(response.status, 200); let responsePayload = await response.json(); + assert.deepEqual(responsePayload.crate.versions, ['1', '2', '3']); assert.deepEqual(responsePayload.versions, [ { id: '1', @@ -282,12 +283,13 @@ module('Mirage | Keywords', function(hooks) { test('includes related categories', async function(assert) { this.server.create('category', { category: 'no-std' }); this.server.create('category', { category: 'cli' }); - this.server.create('crate', { name: 'rand', categories: ['no-std'] }); + this.server.create('crate', { name: 'rand', categoryIds: ['no-std'] }); let response = await fetch('/api/v1/crates/rand'); assert.equal(response.status, 200); let responsePayload = await response.json(); + assert.deepEqual(responsePayload.crate.categories, ['no-std']); assert.deepEqual(responsePayload.categories, [ { id: 'no-std', @@ -303,12 +305,13 @@ module('Mirage | Keywords', function(hooks) { test('includes related keywords', async function(assert) { this.server.create('keyword', { keyword: 'no-std' }); this.server.create('keyword', { keyword: 'cli' }); - this.server.create('crate', { name: 'rand', keywords: ['no-std'] }); + this.server.create('crate', { name: 'rand', keywordIds: ['no-std'] }); let response = await fetch('/api/v1/crates/rand'); assert.equal(response.status, 200); let responsePayload = await response.json(); + assert.deepEqual(responsePayload.crate.keywords, ['no-std']); assert.deepEqual(responsePayload.keywords, [ { crates_cnt: 0, @@ -342,9 +345,9 @@ module('Mirage | Keywords', function(hooks) { test('returns all versions belonging to the specified crate', async function(assert) { this.server.create('crate', { name: 'rand' }); - this.server.create('version', { crate: 'rand', num: '1.0.0' }); - this.server.create('version', { crate: 'rand', num: '1.1.0' }); - this.server.create('version', { crate: 'rand', num: '1.2.0' }); + this.server.create('version', { crateId: 'rand', num: '1.0.0' }); + this.server.create('version', { crateId: 'rand', num: '1.1.0' }); + this.server.create('version', { crateId: 'rand', num: '1.2.0' }); let response = await fetch('/api/v1/crates/rand/versions'); assert.equal(response.status, 200); @@ -431,7 +434,7 @@ module('Mirage | Keywords', function(hooks) { test('empty case', async function(assert) { this.server.create('crate', { name: 'rand' }); - this.server.create('version', { crate: 'rand', num: '1.0.0' }); + this.server.create('version', { crateId: 'rand', num: '1.0.0' }); let response = await fetch('/api/v1/crates/rand/1.0.0/authors'); assert.equal(response.status, 200); @@ -449,7 +452,7 @@ module('Mirage | Keywords', function(hooks) { let authors = ['John Doe ', 'The Rust Project Developers']; this.server.create('crate', { name: 'rand' }); - this.server.create('version', { crate: 'rand', num: '1.0.0', _authors: authors }); + this.server.create('version', { crateId: 'rand', num: '1.0.0', _authors: authors }); let response = await fetch('/api/v1/crates/rand/1.0.0/authors'); assert.equal(response.status, 200); @@ -487,7 +490,7 @@ module('Mirage | Keywords', function(hooks) { test('empty case', async function(assert) { this.server.create('crate', { name: 'rand' }); - this.server.create('version', { crate: 'rand', num: '1.0.0' }); + this.server.create('version', { crateId: 'rand', num: '1.0.0' }); let response = await fetch('/api/v1/crates/rand/1.0.0/dependencies'); assert.equal(response.status, 200); @@ -500,10 +503,14 @@ module('Mirage | Keywords', function(hooks) { test('returns a list of dependencies belonging to the specified crate version', async function(assert) { this.server.create('crate', { name: 'rand' }); - let version = this.server.create('version', { crate: 'rand', num: '1.0.0' }); - this.server.create('dependency', { crate_id: 'foo', version_id: version.id }); - this.server.create('dependency', { crate_id: 'bar', version_id: version.id }); - this.server.create('dependency', { crate_id: 'baz', version_id: version.id }); + let version = this.server.create('version', { crateId: 'rand', num: '1.0.0' }); + + this.server.create('crate', { name: 'foo' }); + this.server.create('dependency', { crateId: 'foo', versionId: version.id }); + this.server.create('crate', { name: 'bar' }); + this.server.create('dependency', { crateId: 'bar', versionId: version.id }); + this.server.create('crate', { name: 'baz' }); + this.server.create('dependency', { crateId: 'baz', versionId: version.id }); let response = await fetch('/api/v1/crates/rand/1.0.0/dependencies'); assert.equal(response.status, 200); @@ -572,7 +579,7 @@ module('Mirage | Keywords', function(hooks) { test('empty case', async function(assert) { this.server.create('crate', { name: 'rand' }); - this.server.create('version', { crate: 'rand', num: '1.0.0' }); + this.server.create('version', { crateId: 'rand', num: '1.0.0' }); let response = await fetch('/api/v1/crates/rand/1.0.0/downloads'); assert.equal(response.status, 200); @@ -585,32 +592,28 @@ module('Mirage | Keywords', function(hooks) { test('returns a list of version downloads belonging to the specified crate version', async function(assert) { this.server.create('crate', { name: 'rand' }); - let version = this.server.create('version', { crate: 'rand', num: '1.0.0' }); - this.server.create('version-download', { version: version.id, date: '2020-01-13' }); - this.server.create('version-download', { version: version.id, date: '2020-01-14' }); - this.server.create('version-download', { version: version.id, date: '2020-01-15' }); + let version = this.server.create('version', { crateId: 'rand', num: '1.0.0' }); + this.server.create('version-download', { version, date: '2020-01-13' }); + this.server.create('version-download', { version, date: '2020-01-14' }); + this.server.create('version-download', { version, date: '2020-01-15' }); let response = await fetch('/api/v1/crates/rand/1.0.0/downloads'); assert.equal(response.status, 200); - // TODO Remove the `id` properties from the response let responsePayload = await response.json(); assert.deepEqual(responsePayload, { version_downloads: [ { - id: '1', date: '2020-01-13', downloads: 9380, version: '1', }, { - id: '2', date: '2020-01-14', downloads: 16415, version: '1', }, { - id: '3', date: '2020-01-15', downloads: 23450, version: '1', @@ -643,7 +646,7 @@ module('Mirage | Keywords', function(hooks) { test('returns the list of users that own the specified crate', async function(assert) { let user = this.server.create('user', { name: 'John Doe' }); - this.server.create('crate', { name: 'rand', _owner_users: [user.id] }); + this.server.create('crate', { name: 'rand', userOwners: [user] }); let response = await fetch('/api/v1/crates/rand/owner_user'); assert.equal(response.status, 200); @@ -687,7 +690,7 @@ module('Mirage | Keywords', function(hooks) { test('returns the list of teams that own the specified crate', async function(assert) { let team = this.server.create('team', { name: 'maintainers' }); - this.server.create('crate', { name: 'rand', _owner_teams: [team.id] }); + this.server.create('crate', { name: 'rand', teamOwners: [team] }); let response = await fetch('/api/v1/crates/rand/owner_team'); assert.equal(response.status, 200); @@ -737,16 +740,16 @@ module('Mirage | Keywords', function(hooks) { this.server.create('crate', { name: 'foo' }); this.server.create('dependency', { - crate_id: 'foo', - version_id: this.server.create('version', { - crate: this.server.create('crate', { name: 'bar' }).id, + crateId: 'foo', + versionId: this.server.create('version', { + crate: this.server.create('crate', { name: 'bar' }), }).id, }); this.server.create('dependency', { - crate_id: 'foo', - version_id: this.server.create('version', { - crate: this.server.create('crate', { name: 'baz' }).id, + crateId: 'foo', + versionId: this.server.create('version', { + crate: this.server.create('crate', { name: 'baz' }), }).id, }); @@ -825,10 +828,10 @@ module('Mirage | Keywords', function(hooks) { this.server.create('crate', { name: 'foo' }); this.server.createList('dependency', 25, { - crate_id: 'foo', - version_id: () => + crateId: 'foo', + versionId: () => this.server.create('version', { - crate: () => this.server.create('crate', { name: 'bar' }).id, + crate: () => this.server.create('crate', { name: 'bar' }), }).id, }); @@ -848,11 +851,11 @@ module('Mirage | Keywords', function(hooks) { name: i => `crate-${String(i + 1).padStart(2, '0')}`, }); let versions = this.server.createList('version', crates.length, { - crate: i => crates[i].id, + crate: i => crates[i], }); this.server.createList('dependency', versions.length, { - crate_id: 'foo', - version_id: i => versions[i].id, + crateId: 'foo', + versionId: i => versions[i].id, }); let response = await fetch('/api/v1/crates/foo/reverse_dependencies?page=2&per_page=5'); @@ -895,32 +898,28 @@ module('Mirage | Keywords', function(hooks) { test('returns a list of version downloads belonging to the specified crate version', async function(assert) { this.server.create('crate', { name: 'rand' }); - let versions = this.server.createList('version', 2, { crate: 'rand' }); - this.server.create('version-download', { version: versions[0].id, date: '2020-01-13' }); - this.server.create('version-download', { version: versions[1].id, date: '2020-01-14' }); - this.server.create('version-download', { version: versions[1].id, date: '2020-01-15' }); + let versions = this.server.createList('version', 2, { crateId: 'rand' }); + this.server.create('version-download', { version: versions[0], date: '2020-01-13' }); + this.server.create('version-download', { version: versions[1], date: '2020-01-14' }); + this.server.create('version-download', { version: versions[1], date: '2020-01-15' }); let response = await fetch('/api/v1/crates/rand/downloads'); assert.equal(response.status, 200); - // TODO Remove the `id` properties from the response let responsePayload = await response.json(); assert.deepEqual(responsePayload, { version_downloads: [ { - id: '1', date: '2020-01-13', downloads: 9380, version: '1', }, { - id: '2', date: '2020-01-14', downloads: 16415, version: '2', }, { - id: '3', date: '2020-01-15', downloads: 23450, version: '2',