From 883516e8c7284fd0e49f136689b1d6c52a28af12 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 14 Jan 2020 20:45:27 +0100 Subject: [PATCH 01/18] Add tests for `GET /api/v1/categories/:id` mirage request handler --- tests/mirage/categories-test.js | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/mirage/categories-test.js diff --git a/tests/mirage/categories-test.js b/tests/mirage/categories-test.js new file mode 100644 index 00000000000..c2fe455da9b --- /dev/null +++ b/tests/mirage/categories-test.js @@ -0,0 +1,42 @@ +import { setupTest } from 'ember-qunit'; +import { module, test } from 'qunit'; + +import setupMirage from '../helpers/setup-mirage'; +import fetch from 'fetch'; + +module('Mirage | Categories', function(hooks) { + setupTest(hooks); + setupMirage(hooks); + + module('GET /api/v1/categories/:id', function() { + test('returns 404 for unknown categories', async function(assert) { + let response = await fetch('/api/v1/categories/foo'); + assert.equal(response.status, 404); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'Not Found' }] }); + }); + + test('returns a category object for known categories', async function(assert) { + this.server.create('category', { + category: 'no-std', + description: 'Crates that are able to function without the Rust standard library.', + }); + + let response = await fetch('/api/v1/categories/no-std'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + category: { + id: 'no-std', + category: 'no-std', + crates_cnt: 0, + created_at: '2010-06-16T21:30:45Z', + description: 'Crates that are able to function without the Rust standard library.', + slug: 'no-std', + }, + }); + }); + }); +}); From 0b458ecb74d878a6a097be6e7e08e599b779c333 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 14 Jan 2020 20:57:39 +0100 Subject: [PATCH 02/18] Add tests for `GET /api/v1/categories` mirage request handler --- tests/mirage/categories-test.js | 87 +++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/tests/mirage/categories-test.js b/tests/mirage/categories-test.js index c2fe455da9b..03935925da0 100644 --- a/tests/mirage/categories-test.js +++ b/tests/mirage/categories-test.js @@ -8,6 +8,93 @@ module('Mirage | Categories', function(hooks) { setupTest(hooks); setupMirage(hooks); + module('GET /api/v1/categories', function() { + test('empty case', async function(assert) { + let response = await fetch('/api/v1/categories'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + categories: [], + meta: { + total: 0, + }, + }); + }); + + test('returns a paginated categories list', async function(assert) { + this.server.create('category', { + category: 'no-std', + description: 'Crates that are able to function without the Rust standard library.', + }); + this.server.createList('category', 2); + + let response = await fetch('/api/v1/categories'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + categories: [ + { + id: 'category-1', + category: 'Category 1', + crates_cnt: 0, + created_at: '2010-06-16T21:30:45Z', + description: 'This is the description for the category called "Category 1"', + slug: 'category-1', + }, + { + id: 'category-2', + category: 'Category 2', + crates_cnt: 0, + created_at: '2010-06-16T21:30:45Z', + description: 'This is the description for the category called "Category 2"', + slug: 'category-2', + }, + { + id: 'no-std', + category: 'no-std', + crates_cnt: 0, + created_at: '2010-06-16T21:30:45Z', + description: 'Crates that are able to function without the Rust standard library.', + slug: 'no-std', + }, + ], + meta: { + total: 3, + }, + }); + }); + + test('never returns more than 10 results', async function(assert) { + this.server.createList('category', 25); + + let response = await fetch('/api/v1/categories'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.equal(responsePayload.categories.length, 10); + assert.equal(responsePayload.meta.total, 25); + }); + + test('supports `page` and `per_page` parameters', async function(assert) { + this.server.createList('category', 25, { + category: i => `cat-${String(i + 1).padStart(2, '0')}`, + }); + + let response = await fetch('/api/v1/categories?page=2&per_page=5'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.equal(responsePayload.categories.length, 5); + assert.deepEqual( + responsePayload.categories.map(it => it.id), + ['cat-06', 'cat-07', 'cat-08', 'cat-09', 'cat-10'], + ); + assert.equal(responsePayload.meta.total, 25); + }); + }); + module('GET /api/v1/categories/:id', function() { test('returns 404 for unknown categories', async function(assert) { let response = await fetch('/api/v1/categories/foo'); From 8c97bb5671946b124d38ea53bacf6d101803bd51 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 14 Jan 2020 21:15:30 +0100 Subject: [PATCH 03/18] Add tests for `GET /api/v1/category_slugs` mirage request handler --- tests/mirage/categories-test.js | 54 +++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/mirage/categories-test.js b/tests/mirage/categories-test.js index 03935925da0..4f51df3540b 100644 --- a/tests/mirage/categories-test.js +++ b/tests/mirage/categories-test.js @@ -126,4 +126,58 @@ module('Mirage | Categories', function(hooks) { }); }); }); + + module('GET /api/v1/category_slugs', function() { + test('empty case', async function(assert) { + let response = await fetch('/api/v1/category_slugs'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + category_slugs: [], + }); + }); + + test('returns a category slugs list', async function(assert) { + this.server.create('category', { + category: 'no-std', + description: 'Crates that are able to function without the Rust standard library.', + }); + this.server.createList('category', 2); + + let response = await fetch('/api/v1/category_slugs'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + category_slugs: [ + { + description: 'This is the description for the category called "Category 1"', + id: 'category-1', + slug: 'category-1', + }, + { + description: 'This is the description for the category called "Category 2"', + id: 'category-2', + slug: 'category-2', + }, + { + description: 'Crates that are able to function without the Rust standard library.', + id: 'no-std', + slug: 'no-std', + }, + ], + }); + }); + + test('has no pagination', async function(assert) { + this.server.createList('category', 25); + + let response = await fetch('/api/v1/category_slugs'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.equal(responsePayload.category_slugs.length, 25); + }); + }); }); From 768139abf277acf3bcb5d8d8075c63f4e721c06b Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 14 Jan 2020 21:40:23 +0100 Subject: [PATCH 04/18] Add tests for `GET /api/v1/keywords` mirage request handler --- tests/mirage/keywords-test.js | 85 +++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 tests/mirage/keywords-test.js diff --git a/tests/mirage/keywords-test.js b/tests/mirage/keywords-test.js new file mode 100644 index 00000000000..8f2dd18f098 --- /dev/null +++ b/tests/mirage/keywords-test.js @@ -0,0 +1,85 @@ +import { setupTest } from 'ember-qunit'; +import { module, test } from 'qunit'; + +import setupMirage from '../helpers/setup-mirage'; +import fetch from 'fetch'; + +module('Mirage | Keywords', function(hooks) { + setupTest(hooks); + setupMirage(hooks); + + module('GET /api/v1/keywords', function() { + test('empty case', async function(assert) { + let response = await fetch('/api/v1/keywords'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + keywords: [], + meta: { + total: 0, + }, + }); + }); + + test('returns a paginated keywords list', async function(assert) { + this.server.create('keyword', { keyword: 'api' }); + this.server.createList('keyword', 2); + + let response = await fetch('/api/v1/keywords'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + keywords: [ + { + id: 'api', + crates_cnt: 0, + keyword: 'api', + }, + { + id: 'keyword-2', + crates_cnt: 0, + keyword: 'keyword-2', + }, + { + id: 'keyword-3', + crates_cnt: 0, + keyword: 'keyword-3', + }, + ], + meta: { + total: 3, + }, + }); + }); + + test('never returns more than 10 results', async function(assert) { + this.server.createList('keyword', 25); + + let response = await fetch('/api/v1/keywords'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.equal(responsePayload.keywords.length, 10); + assert.equal(responsePayload.meta.total, 25); + }); + + test('supports `page` and `per_page` parameters', async function(assert) { + this.server.createList('keyword', 25, { + keyword: i => `k${String(i + 1).padStart(2, '0')}`, + }); + + let response = await fetch('/api/v1/keywords?page=2&per_page=5'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.equal(responsePayload.keywords.length, 5); + assert.deepEqual( + responsePayload.keywords.map(it => it.id), + ['k06', 'k07', 'k08', 'k09', 'k10'], + ); + assert.equal(responsePayload.meta.total, 25); + }); + }); +}); From b9128f32dc414831a6a24ce4113fd0f070a3d4a0 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 14 Jan 2020 21:41:19 +0100 Subject: [PATCH 05/18] Add tests for `GET /api/v1/keywords/:id` mirage request handler --- tests/mirage/keywords-test.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/mirage/keywords-test.js b/tests/mirage/keywords-test.js index 8f2dd18f098..a5178b0ddff 100644 --- a/tests/mirage/keywords-test.js +++ b/tests/mirage/keywords-test.js @@ -82,4 +82,30 @@ module('Mirage | Keywords', function(hooks) { assert.equal(responsePayload.meta.total, 25); }); }); + + module('GET /api/v1/keywords/:id', function() { + test('returns 404 for unknown keywords', async function(assert) { + let response = await fetch('/api/v1/keywords/foo'); + assert.equal(response.status, 404); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'Not Found' }] }); + }); + + test('returns a keyword object for known keywords', async function(assert) { + this.server.create('keyword', { keyword: 'cli' }); + + let response = await fetch('/api/v1/keywords/cli'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + keyword: { + id: 'cli', + crates_cnt: 0, + keyword: 'cli', + }, + }); + }); + }); }); From 977042f13ac8227b5254f357551cb071beedbc43 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 14 Jan 2020 21:58:42 +0100 Subject: [PATCH 06/18] Add tests for `GET /api/v1/teams/:id` mirage request handler --- tests/mirage/teams-test.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 tests/mirage/teams-test.js diff --git a/tests/mirage/teams-test.js b/tests/mirage/teams-test.js new file mode 100644 index 00000000000..c9fe4399300 --- /dev/null +++ b/tests/mirage/teams-test.js @@ -0,0 +1,38 @@ +import { setupTest } from 'ember-qunit'; +import { module, test } from 'qunit'; + +import setupMirage from '../helpers/setup-mirage'; +import fetch from 'fetch'; + +module('Mirage | Teams', function(hooks) { + setupTest(hooks); + setupMirage(hooks); + + module('GET /api/v1/teams/:id', function() { + test('returns 404 for unknown teams', async function(assert) { + let response = await fetch('/api/v1/teams/foo'); + assert.equal(response.status, 404); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'Not Found' }] }); + }); + + test('returns a team object for known teams', async function(assert) { + let team = this.server.create('team', { name: 'maintainers' }); + + let response = await fetch(`/api/v1/teams/${team.login}`); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + team: { + id: '1', + avatar: 'https://avatars1.githubusercontent.com/u/14631425?v=4', + login: 'github:rust-lang:maintainers', + name: 'maintainers', + url: 'https://github.com/rust-lang', + }, + }); + }); + }); +}); From 8c55acae8bdce319234276f97d45ea610f9d72b2 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 14 Jan 2020 22:01:33 +0100 Subject: [PATCH 07/18] Add tests for `GET /api/v1/users/:id` mirage request handler --- tests/mirage/users-test.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 tests/mirage/users-test.js diff --git a/tests/mirage/users-test.js b/tests/mirage/users-test.js new file mode 100644 index 00000000000..8766a5c98a3 --- /dev/null +++ b/tests/mirage/users-test.js @@ -0,0 +1,38 @@ +import { setupTest } from 'ember-qunit'; +import { module, test } from 'qunit'; + +import setupMirage from '../helpers/setup-mirage'; +import fetch from 'fetch'; + +module('Mirage | Users', function(hooks) { + setupTest(hooks); + setupMirage(hooks); + + module('GET /api/v1/users/:id', function() { + test('returns 404 for unknown users', async function(assert) { + let response = await fetch('/api/v1/users/foo'); + assert.equal(response.status, 404); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'Not Found' }] }); + }); + + test('returns a user object for known users', async function(assert) { + let user = this.server.create('user', { name: 'John Doe' }); + + let response = await fetch(`/api/v1/users/${user.login}`); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + user: { + id: '1', + avatar: 'https://avatars1.githubusercontent.com/u/14631425?v=4', + login: 'john-doe', + name: 'John Doe', + url: 'https://github.com/john-doe', + }, + }); + }); + }); +}); From 0f216cb9d2bf3af0ec2aeb8797ed1b6ba98819a7 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 14 Jan 2020 22:31:48 +0100 Subject: [PATCH 08/18] Add tests for `GET /api/v1/crates` mirage request handler --- tests/mirage/crates-test.js | 169 ++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 tests/mirage/crates-test.js diff --git a/tests/mirage/crates-test.js b/tests/mirage/crates-test.js new file mode 100644 index 00000000000..79f5e125eaa --- /dev/null +++ b/tests/mirage/crates-test.js @@ -0,0 +1,169 @@ +import { setupTest } from 'ember-qunit'; +import { module, test } from 'qunit'; + +import setupMirage from '../helpers/setup-mirage'; +import fetch from 'fetch'; + +module('Mirage | Keywords', function(hooks) { + setupTest(hooks); + setupMirage(hooks); + + module('GET /api/v1/crates', function() { + test('empty case', async function(assert) { + let response = await fetch('/api/v1/crates'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + crates: [], + meta: { + total: 0, + }, + }); + }); + + test('returns a paginated crates list', async function(assert) { + this.server.create('crate', { name: 'rand' }); + + let response = await fetch('/api/v1/crates'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + crates: [ + { + id: 'rand', + badges: [], + categories: [], + created_at: '2010-06-16T21:30:45Z', + description: 'This is the description for the crate called "rand"', + documentation: null, + downloads: 0, + homepage: null, + keywords: [], + links: { + owner_team: '/api/v1/crates/rand/owner_team', + owner_user: '/api/v1/crates/rand/owner_user', + reverse_dependencies: '/api/v1/crates/rand/reverse_dependencies', + version_downloads: '/api/v1/crates/rand/downloads', + versions: '/api/v1/crates/rand/versions', + }, + max_version: '1.0.0', + name: 'rand', + newest_version: '1.0.0', + repository: null, + updated_at: '2017-02-24T12:34:56Z', + versions: [], + }, + ], + meta: { + total: 1, + }, + }); + }); + + test('never returns more than 10 results', async function(assert) { + this.server.createList('crate', 25); + + let response = await fetch('/api/v1/crates'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.equal(responsePayload.crates.length, 10); + assert.equal(responsePayload.meta.total, 25); + }); + + test('supports `page` and `per_page` parameters', async function(assert) { + this.server.createList('crate', 25, { + name: i => `crate-${String(i + 1).padStart(2, '0')}`, + }); + + let response = await fetch('/api/v1/crates?page=2&per_page=5'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.equal(responsePayload.crates.length, 5); + assert.deepEqual( + responsePayload.crates.map(it => it.id), + ['crate-06', 'crate-07', 'crate-08', 'crate-09', 'crate-10'], + ); + assert.equal(responsePayload.meta.total, 25); + }); + + test('supports a `letter` parameter', async function(assert) { + this.server.create('crate', { name: 'foo' }); + this.server.create('crate', { name: 'bar' }); + this.server.create('crate', { name: 'BAZ' }); + + let response = await fetch('/api/v1/crates?letter=b'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.equal(responsePayload.crates.length, 2); + assert.deepEqual( + responsePayload.crates.map(it => it.id), + ['bar', 'BAZ'], + ); + assert.equal(responsePayload.meta.total, 2); + }); + + test('supports a `q` parameter', async function(assert) { + this.server.create('crate', { name: '123456' }); + this.server.create('crate', { name: '00123' }); + this.server.create('crate', { name: '87654' }); + + let response = await fetch('/api/v1/crates?q=123'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.equal(responsePayload.crates.length, 2); + assert.deepEqual( + responsePayload.crates.map(it => it.id), + ['123456', '00123'], + ); + assert.equal(responsePayload.meta.total, 2); + }); + + test('supports a `user_id` parameter', async function(assert) { + this.server.create('crate', { name: 'foo' }); + this.server.create('crate', { name: 'bar', _owner_users: [42] }); + this.server.create('crate', { name: 'baz', _owner_users: [13] }); + + let response = await fetch('/api/v1/crates?user_id=42'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.equal(responsePayload.crates.length, 1); + assert.equal(responsePayload.crates[0].id, 'bar'); + assert.equal(responsePayload.meta.total, 1); + }); + + test('supports a `team_id` parameter', async function(assert) { + this.server.create('crate', { name: 'foo' }); + this.server.create('crate', { name: 'bar', _owner_teams: [42] }); + this.server.create('crate', { name: 'baz', _owner_teams: [13] }); + + let response = await fetch('/api/v1/crates?team_id=42'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.equal(responsePayload.crates.length, 1); + assert.equal(responsePayload.crates[0].id, 'bar'); + assert.equal(responsePayload.meta.total, 1); + }); + + test('supports a `team_id` parameter', async function(assert) { + this.server.create('crate', { name: 'foo' }); + this.server.create('crate', { name: 'bar', _owner_teams: [42] }); + this.server.create('crate', { name: 'baz', _owner_teams: [13] }); + + let response = await fetch('/api/v1/crates?team_id=42'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.equal(responsePayload.crates.length, 1); + assert.equal(responsePayload.crates[0].id, 'bar'); + assert.equal(responsePayload.meta.total, 1); + }); + }); +}); From 21b71b931d8f49d5935422a9bdbd59edc7a680b1 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 14 Jan 2020 22:48:19 +0100 Subject: [PATCH 09/18] Add tests for `GET /api/v1/crates/:id` mirage request handler --- tests/mirage/crates-test.js | 152 ++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/tests/mirage/crates-test.js b/tests/mirage/crates-test.js index 79f5e125eaa..f02ec506166 100644 --- a/tests/mirage/crates-test.js +++ b/tests/mirage/crates-test.js @@ -166,4 +166,156 @@ module('Mirage | Keywords', function(hooks) { assert.equal(responsePayload.meta.total, 1); }); }); + + module('GET /api/v1/crates/:id', function() { + test('returns 404 for unknown crates', async function(assert) { + let response = await fetch('/api/v1/crates/foo'); + assert.equal(response.status, 404); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'Not Found' }] }); + }); + + test('returns a crate object for known crates', async function(assert) { + this.server.create('crate', { name: 'rand' }); + + let response = await fetch('/api/v1/crates/rand'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + categories: [], + crate: { + badges: [], + categories: [], + created_at: '2010-06-16T21:30:45Z', + description: 'This is the description for the crate called "rand"', + documentation: null, + downloads: 0, + homepage: null, + id: 'rand', + keywords: [], + links: { + owner_team: '/api/v1/crates/rand/owner_team', + owner_user: '/api/v1/crates/rand/owner_user', + reverse_dependencies: '/api/v1/crates/rand/reverse_dependencies', + version_downloads: '/api/v1/crates/rand/downloads', + versions: '/api/v1/crates/rand/versions', + }, + max_version: '1.0.0', + name: 'rand', + newest_version: '1.0.0', + repository: null, + updated_at: '2017-02-24T12:34:56Z', + versions: [], + }, + keywords: [], + versions: [], + }); + }); + + 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' }); + + let response = await fetch('/api/v1/crates/rand'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload.versions, [ + { + id: '1', + crate: 'rand', + crate_size: 0, + created_at: '2010-06-16T21:30:45Z', + dl_path: '/api/v1/crates/rand/1.0.0/download', + downloads: 0, + license: 'MIT/Apache-2.0', + links: { + authors: '/api/v1/crates/rand/1.0.0/authors', + dependencies: '/api/v1/crates/rand/1.0.0/dependencies', + version_downloads: '/api/v1/crates/rand/1.0.0/downloads', + }, + num: '1.0.0', + updated_at: '2017-02-24T12:34:56Z', + yanked: false, + }, + { + id: '2', + crate: 'rand', + crate_size: 162963, + created_at: '2010-06-16T21:30:45Z', + dl_path: '/api/v1/crates/rand/1.1.0/download', + downloads: 3702, + license: 'MIT', + links: { + authors: '/api/v1/crates/rand/1.1.0/authors', + dependencies: '/api/v1/crates/rand/1.1.0/dependencies', + version_downloads: '/api/v1/crates/rand/1.1.0/downloads', + }, + num: '1.1.0', + updated_at: '2017-02-24T12:34:56Z', + yanked: false, + }, + { + id: '3', + crate: 'rand', + crate_size: 325926, + created_at: '2010-06-16T21:30:45Z', + dl_path: '/api/v1/crates/rand/1.2.0/download', + downloads: 7404, + license: 'Apache-2.0', + links: { + authors: '/api/v1/crates/rand/1.2.0/authors', + dependencies: '/api/v1/crates/rand/1.2.0/dependencies', + version_downloads: '/api/v1/crates/rand/1.2.0/downloads', + }, + num: '1.2.0', + updated_at: '2017-02-24T12:34:56Z', + yanked: false, + }, + ]); + }); + + 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'] }); + + let response = await fetch('/api/v1/crates/rand'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload.categories, [ + { + id: 'no-std', + category: 'no-std', + crates_cnt: 0, + created_at: '2010-06-16T21:30:45Z', + description: 'This is the description for the category called "no-std"', + slug: 'no-std', + }, + ]); + }); + + 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'] }); + + let response = await fetch('/api/v1/crates/rand'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload.keywords, [ + { + crates_cnt: 0, + id: 'no-std', + keyword: 'no-std', + }, + ]); + }); + }); }); From ce7e23871436646f1d83999e54e6674fbbe9b86c Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Wed, 15 Jan 2020 09:40:59 +0100 Subject: [PATCH 10/18] Add tests for `GET /api/v1/crates/:id/versions` mirage request handler --- tests/mirage/crates-test.js | 89 +++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/tests/mirage/crates-test.js b/tests/mirage/crates-test.js index f02ec506166..10b6e0bd7df 100644 --- a/tests/mirage/crates-test.js +++ b/tests/mirage/crates-test.js @@ -318,4 +318,93 @@ module('Mirage | Keywords', function(hooks) { ]); }); }); + + module('GET /api/v1/crates/:id/versions', function() { + test('returns 404 for unknown crates', async function(assert) { + let response = await fetch('/api/v1/crates/foo/versions'); + assert.equal(response.status, 404); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'Not Found' }] }); + }); + + test('empty case', async function(assert) { + this.server.create('crate', { name: 'rand' }); + + let response = await fetch('/api/v1/crates/rand/versions'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + versions: [], + }); + }); + + 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' }); + + let response = await fetch('/api/v1/crates/rand/versions'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + versions: [ + { + id: '1', + crate: 'rand', + crate_size: 0, + created_at: '2010-06-16T21:30:45Z', + dl_path: '/api/v1/crates/rand/1.0.0/download', + downloads: 0, + license: 'MIT/Apache-2.0', + links: { + authors: '/api/v1/crates/rand/1.0.0/authors', + dependencies: '/api/v1/crates/rand/1.0.0/dependencies', + version_downloads: '/api/v1/crates/rand/1.0.0/downloads', + }, + num: '1.0.0', + updated_at: '2017-02-24T12:34:56Z', + yanked: false, + }, + { + id: '2', + crate: 'rand', + crate_size: 162963, + created_at: '2010-06-16T21:30:45Z', + dl_path: '/api/v1/crates/rand/1.1.0/download', + downloads: 3702, + license: 'MIT', + links: { + authors: '/api/v1/crates/rand/1.1.0/authors', + dependencies: '/api/v1/crates/rand/1.1.0/dependencies', + version_downloads: '/api/v1/crates/rand/1.1.0/downloads', + }, + num: '1.1.0', + updated_at: '2017-02-24T12:34:56Z', + yanked: false, + }, + { + id: '3', + crate: 'rand', + crate_size: 325926, + created_at: '2010-06-16T21:30:45Z', + dl_path: '/api/v1/crates/rand/1.2.0/download', + downloads: 7404, + license: 'Apache-2.0', + links: { + authors: '/api/v1/crates/rand/1.2.0/authors', + dependencies: '/api/v1/crates/rand/1.2.0/dependencies', + version_downloads: '/api/v1/crates/rand/1.2.0/downloads', + }, + num: '1.2.0', + updated_at: '2017-02-24T12:34:56Z', + yanked: false, + }, + ], + }); + }); + }); }); From e53425e3ce7a975a9f474ca089399d708d9c6b4a Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Wed, 15 Jan 2020 09:51:14 +0100 Subject: [PATCH 11/18] Add tests for `GET /api/v1/crates/:id/:version/authors` mirage request handler --- tests/mirage/crates-test.js | 56 +++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tests/mirage/crates-test.js b/tests/mirage/crates-test.js index 10b6e0bd7df..95909f6c5aa 100644 --- a/tests/mirage/crates-test.js +++ b/tests/mirage/crates-test.js @@ -407,4 +407,60 @@ module('Mirage | Keywords', function(hooks) { }); }); }); + + module('GET /api/v1/crates/:id/:version/authors', function() { + test('returns 404 for unknown crates', async function(assert) { + let response = await fetch('/api/v1/crates/foo/1.0.0/authors'); + assert.equal(response.status, 404); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'Not Found' }] }); + }); + + test('returns 200 for unknown versions', async function(assert) { + this.server.create('crate', { name: 'rand' }); + + let response = await fetch('/api/v1/crates/rand/1.0.0/authors'); + // we should probably return 404 for this, but the production API + // currently doesn't do this either + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'crate `rand` does not have a version `1.0.0`' }] }); + }); + + test('empty case', async function(assert) { + this.server.create('crate', { name: 'rand' }); + this.server.create('version', { crate: 'rand', num: '1.0.0' }); + + let response = await fetch('/api/v1/crates/rand/1.0.0/authors'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + meta: { + names: [], + }, + users: [], + }); + }); + + test('returns a list of authors belonging to the specified crate version', async function(assert) { + 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 }); + + let response = await fetch('/api/v1/crates/rand/1.0.0/authors'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + meta: { + names: authors, + }, + users: [], + }); + }); + }); }); From b1ea91a759e6717645ca495c38b8cb0ad0b789ff Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Wed, 15 Jan 2020 10:06:12 +0100 Subject: [PATCH 12/18] Add tests for `GET /api/v1/crates/:id/:version/dependencies` mirage request handler --- tests/mirage/crates-test.js | 85 +++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/tests/mirage/crates-test.js b/tests/mirage/crates-test.js index 95909f6c5aa..2e22f166cd5 100644 --- a/tests/mirage/crates-test.js +++ b/tests/mirage/crates-test.js @@ -463,4 +463,89 @@ module('Mirage | Keywords', function(hooks) { }); }); }); + + module('GET /api/v1/crates/:id/:version/dependencies', function() { + test('returns 404 for unknown crates', async function(assert) { + let response = await fetch('/api/v1/crates/foo/1.0.0/dependencies'); + assert.equal(response.status, 404); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'Not Found' }] }); + }); + + test('returns 200 for unknown versions', async function(assert) { + this.server.create('crate', { name: 'rand' }); + + let response = await fetch('/api/v1/crates/rand/1.0.0/dependencies'); + // we should probably return 404 for this, but the production API + // currently doesn't do this either + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'crate `rand` does not have a version `1.0.0`' }] }); + }); + + test('empty case', async function(assert) { + this.server.create('crate', { name: 'rand' }); + this.server.create('version', { crate: 'rand', num: '1.0.0' }); + + let response = await fetch('/api/v1/crates/rand/1.0.0/dependencies'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + dependencies: [], + }); + }); + + 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 response = await fetch('/api/v1/crates/rand/1.0.0/dependencies'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + dependencies: [ + { + id: '1', + crate_id: 'foo', + default_features: false, + features: [], + kind: 'dev', + optional: true, + req: '^0.1.0', + target: null, + version_id: '1', + }, + { + id: '2', + crate_id: 'bar', + default_features: false, + features: [], + kind: 'normal', + optional: true, + req: '^2.1.3', + target: null, + version_id: '1', + }, + { + id: '3', + crate_id: 'baz', + default_features: false, + features: [], + kind: 'normal', + optional: true, + req: '0.3.7', + target: null, + version_id: '1', + }, + ], + }); + }); + }); }); From cba2f81a351517faae324ec92203ba7ddf7e9c91 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Wed, 15 Jan 2020 10:22:22 +0100 Subject: [PATCH 13/18] Add tests for `GET /api/v1/crates/:id/:version/downloads` mirage request handler --- tests/mirage/crates-test.js | 71 +++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/tests/mirage/crates-test.js b/tests/mirage/crates-test.js index 2e22f166cd5..83f25105f11 100644 --- a/tests/mirage/crates-test.js +++ b/tests/mirage/crates-test.js @@ -548,4 +548,75 @@ module('Mirage | Keywords', function(hooks) { }); }); }); + + module('GET /api/v1/crates/:id/:version/downloads', function() { + test('returns 404 for unknown crates', async function(assert) { + let response = await fetch('/api/v1/crates/foo/1.0.0/downloads'); + assert.equal(response.status, 404); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'Not Found' }] }); + }); + + test('returns 200 for unknown versions', async function(assert) { + this.server.create('crate', { name: 'rand' }); + + let response = await fetch('/api/v1/crates/rand/1.0.0/downloads'); + // we should probably return 404 for this, but the production API + // currently doesn't do this either + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'crate `rand` does not have a version `1.0.0`' }] }); + }); + + test('empty case', async function(assert) { + this.server.create('crate', { name: 'rand' }); + this.server.create('version', { crate: 'rand', num: '1.0.0' }); + + let response = await fetch('/api/v1/crates/rand/1.0.0/downloads'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + version_downloads: [], + }); + }); + + 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 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', + }, + ], + }); + }); + }); }); From 2f79d35766a88fc5fb4f00d60d7b92d7a52743c4 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Wed, 15 Jan 2020 13:50:39 +0100 Subject: [PATCH 14/18] Add tests for `GET /api/v1/crates/:id/owner_user` mirage request handler --- tests/mirage/crates-test.js | 44 +++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/mirage/crates-test.js b/tests/mirage/crates-test.js index 83f25105f11..bc220496160 100644 --- a/tests/mirage/crates-test.js +++ b/tests/mirage/crates-test.js @@ -619,4 +619,48 @@ module('Mirage | Keywords', function(hooks) { }); }); }); + + module('GET /api/v1/crates/:id/owner_user', function() { + test('returns 404 for unknown crates', async function(assert) { + let response = await fetch('/api/v1/crates/foo/owner_user'); + assert.equal(response.status, 404); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'Not Found' }] }); + }); + + test('empty case', async function(assert) { + this.server.create('crate', { name: 'rand' }); + + let response = await fetch('/api/v1/crates/rand/owner_user'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + users: [], + }); + }); + + 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] }); + + let response = await fetch('/api/v1/crates/rand/owner_user'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + users: [ + { + id: '1', + avatar: 'https://avatars1.githubusercontent.com/u/14631425?v=4', + kind: 'user', + login: 'john-doe', + name: 'John Doe', + url: 'https://github.com/john-doe', + }, + ], + }); + }); + }); }); From e4ed29be91f9b831ca4300a807f495a2d5314f61 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Wed, 15 Jan 2020 13:50:45 +0100 Subject: [PATCH 15/18] Add tests for `GET /api/v1/crates/:id/owner_team` mirage request handler --- tests/mirage/crates-test.js | 44 +++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/mirage/crates-test.js b/tests/mirage/crates-test.js index bc220496160..e7e65dd6a55 100644 --- a/tests/mirage/crates-test.js +++ b/tests/mirage/crates-test.js @@ -663,4 +663,48 @@ module('Mirage | Keywords', function(hooks) { }); }); }); + + module('GET /api/v1/crates/:id/owner_team', function() { + test('returns 404 for unknown crates', async function(assert) { + let response = await fetch('/api/v1/crates/foo/owner_team'); + assert.equal(response.status, 404); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'Not Found' }] }); + }); + + test('empty case', async function(assert) { + this.server.create('crate', { name: 'rand' }); + + let response = await fetch('/api/v1/crates/rand/owner_team'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + teams: [], + }); + }); + + 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] }); + + let response = await fetch('/api/v1/crates/rand/owner_team'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + teams: [ + { + id: '1', + avatar: 'https://avatars1.githubusercontent.com/u/14631425?v=4', + kind: 'team', + login: 'github:rust-lang:maintainers', + name: 'maintainers', + url: 'https://github.com/rust-lang', + }, + ], + }); + }); + }); }); From 4f2a7978676c752ba97e916fdc64b401985dfbc9 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Wed, 15 Jan 2020 14:16:10 +0100 Subject: [PATCH 16/18] Add tests for `GET /api/v1/crates/:id/reverse_dependencies` mirage request handler --- tests/mirage/crates-test.js | 161 ++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) diff --git a/tests/mirage/crates-test.js b/tests/mirage/crates-test.js index e7e65dd6a55..b97e8095877 100644 --- a/tests/mirage/crates-test.js +++ b/tests/mirage/crates-test.js @@ -707,4 +707,165 @@ module('Mirage | Keywords', function(hooks) { }); }); }); + + module('GET /api/v1/crates/:id/reverse_dependencies', function() { + test('returns 404 for unknown crates', async function(assert) { + let response = await fetch('/api/v1/crates/foo/reverse_dependencies'); + assert.equal(response.status, 404); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'Not Found' }] }); + }); + + test('empty case', async function(assert) { + this.server.create('crate', { name: 'rand' }); + + let response = await fetch('/api/v1/crates/rand/reverse_dependencies'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + dependencies: [], + versions: [], + meta: { + total: 0, + }, + }); + }); + + test('returns a paginated list of crate versions depending to the specified crate', async function(assert) { + 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, + }).id, + }); + + this.server.create('dependency', { + crate_id: 'foo', + version_id: this.server.create('version', { + crate: this.server.create('crate', { name: 'baz' }).id, + }).id, + }); + + let response = await fetch('/api/v1/crates/foo/reverse_dependencies'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + dependencies: [ + { + id: '1', + crate_id: 'foo', + default_features: false, + features: [], + kind: 'dev', + optional: true, + req: '^0.1.0', + target: null, + version_id: '1', + }, + { + id: '2', + crate_id: 'foo', + default_features: false, + features: [], + kind: 'normal', + optional: true, + req: '^2.1.3', + target: null, + version_id: '2', + }, + ], + versions: [ + { + id: '1', + crate: 'bar', + crate_size: 0, + created_at: '2010-06-16T21:30:45Z', + dl_path: '/api/v1/crates/bar/1.0.0/download', + downloads: 0, + license: 'MIT/Apache-2.0', + links: { + authors: '/api/v1/crates/bar/1.0.0/authors', + dependencies: '/api/v1/crates/bar/1.0.0/dependencies', + version_downloads: '/api/v1/crates/bar/1.0.0/downloads', + }, + num: '1.0.0', + updated_at: '2017-02-24T12:34:56Z', + yanked: false, + }, + { + id: '2', + crate: 'baz', + crate_size: 162963, + created_at: '2010-06-16T21:30:45Z', + dl_path: '/api/v1/crates/baz/1.0.1/download', + downloads: 3702, + license: 'MIT', + links: { + authors: '/api/v1/crates/baz/1.0.1/authors', + dependencies: '/api/v1/crates/baz/1.0.1/dependencies', + version_downloads: '/api/v1/crates/baz/1.0.1/downloads', + }, + num: '1.0.1', + updated_at: '2017-02-24T12:34:56Z', + yanked: false, + }, + ], + meta: { + total: 2, + }, + }); + }); + + test('never returns more than 10 results', async function(assert) { + this.server.create('crate', { name: 'foo' }); + + this.server.createList('dependency', 25, { + crate_id: 'foo', + version_id: () => + this.server.create('version', { + crate: () => this.server.create('crate', { name: 'bar' }).id, + }).id, + }); + + let response = await fetch('/api/v1/crates/foo/reverse_dependencies'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.equal(responsePayload.dependencies.length, 10); + assert.equal(responsePayload.versions.length, 10); + assert.equal(responsePayload.meta.total, 25); + }); + + test('supports `page` and `per_page` parameters', async function(assert) { + this.server.create('crate', { name: 'foo' }); + + let crates = this.server.createList('crate', 25, { + name: i => `crate-${String(i + 1).padStart(2, '0')}`, + }); + let versions = this.server.createList('version', crates.length, { + crate: i => crates[i].id, + }); + this.server.createList('dependency', versions.length, { + crate_id: 'foo', + version_id: i => versions[i].id, + }); + + let response = await fetch('/api/v1/crates/foo/reverse_dependencies?page=2&per_page=5'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.equal(responsePayload.dependencies.length, 5); + assert.deepEqual( + responsePayload.versions.map(it => it.crate), + // offset by one because we created the `foo` crate first + ['crate-07', 'crate-08', 'crate-09', 'crate-10', 'crate-11'], + ); + assert.equal(responsePayload.meta.total, 25); + }); + }); }); From 0f11af4c609365a3c13dfb591f150cf09539e682 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Wed, 15 Jan 2020 14:20:25 +0100 Subject: [PATCH 17/18] Add tests for `GET /api/v1/crates/:id/downloads` mirage request handler --- tests/mirage/crates-test.js | 64 +++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/tests/mirage/crates-test.js b/tests/mirage/crates-test.js index b97e8095877..95828164889 100644 --- a/tests/mirage/crates-test.js +++ b/tests/mirage/crates-test.js @@ -868,4 +868,68 @@ module('Mirage | Keywords', function(hooks) { assert.equal(responsePayload.meta.total, 25); }); }); + + module('GET /api/v1/crates/:id/downloads', function() { + test('returns 404 for unknown crates', async function(assert) { + let response = await fetch('/api/v1/crates/foo/downloads'); + assert.equal(response.status, 404); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { errors: [{ detail: 'Not Found' }] }); + }); + + test('empty case', async function(assert) { + this.server.create('crate', { name: 'rand' }); + + let response = await fetch('/api/v1/crates/rand/downloads'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + version_downloads: [], + meta: { + extra_downloads: [], + }, + }); + }); + + 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 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', + }, + ], + meta: { + extra_downloads: [], + }, + }); + }); + }); }); From 32a520128fb955603dbf64c1e5b560c9c74639d5 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Mon, 13 Jan 2020 18:30:49 +0100 Subject: [PATCH 18/18] Add tests for `GET /api/v1/summary` mirage request handler --- tests/mirage/summary-test.js | 164 +++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 tests/mirage/summary-test.js diff --git a/tests/mirage/summary-test.js b/tests/mirage/summary-test.js new file mode 100644 index 00000000000..0e732b8a2b1 --- /dev/null +++ b/tests/mirage/summary-test.js @@ -0,0 +1,164 @@ +import { setupTest } from 'ember-qunit'; +import { module, test } from 'qunit'; + +import setupMirage from '../helpers/setup-mirage'; +import fetch from 'fetch'; + +module('Mirage | Summary', function(hooks) { + setupTest(hooks); + setupMirage(hooks); + + module('GET /api/v1/summary', function() { + test('empty case', async function(assert) { + let response = await fetch('/api/v1/summary'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + assert.deepEqual(responsePayload, { + just_updated: [], + most_downloaded: [], + most_recently_downloaded: [], + new_crates: [], + num_crates: 0, + num_downloads: 0, + popular_categories: [], + popular_keywords: [], + }); + }); + + test('returns the data for the front page', async function(assert) { + this.server.createList('category', 15); + this.server.createList('keyword', 25); + this.server.createList('crate', 20); + + let response = await fetch('/api/v1/summary'); + assert.equal(response.status, 200); + + let responsePayload = await response.json(); + + assert.equal(responsePayload.just_updated.length, 10); + assert.deepEqual(responsePayload.just_updated[0], { + id: 'crate-0', + badges: [], + categories: [], + created_at: '2010-06-16T21:30:45Z', + description: 'This is the description for the crate called "crate-0"', + documentation: null, + downloads: 0, + homepage: null, + keywords: [], + links: { + owner_team: '/api/v1/crates/crate-0/owner_team', + owner_user: '/api/v1/crates/crate-0/owner_user', + reverse_dependencies: '/api/v1/crates/crate-0/reverse_dependencies', + version_downloads: '/api/v1/crates/crate-0/downloads', + versions: '/api/v1/crates/crate-0/versions', + }, + max_version: '1.0.0', + name: 'crate-0', + newest_version: '1.0.0', + repository: null, + updated_at: '2017-02-24T12:34:56Z', + versions: null, + }); + + assert.equal(responsePayload.most_downloaded.length, 10); + assert.deepEqual(responsePayload.most_downloaded[0], { + id: 'crate-4', + badges: [], + categories: [], + created_at: '2010-06-16T21:30:45Z', + description: 'This is the description for the crate called "crate-4"', + documentation: null, + downloads: 148140, + homepage: null, + keywords: [], + links: { + owner_team: '/api/v1/crates/crate-4/owner_team', + owner_user: '/api/v1/crates/crate-4/owner_user', + reverse_dependencies: '/api/v1/crates/crate-4/reverse_dependencies', + version_downloads: '/api/v1/crates/crate-4/downloads', + versions: '/api/v1/crates/crate-4/versions', + }, + max_version: '1.0.0', + name: 'crate-4', + newest_version: '1.0.0', + repository: null, + updated_at: '2017-02-24T12:34:56Z', + versions: null, + }); + + assert.equal(responsePayload.most_recently_downloaded.length, 10); + assert.deepEqual(responsePayload.most_recently_downloaded[0], { + id: 'crate-0', + badges: [], + categories: [], + created_at: '2010-06-16T21:30:45Z', + description: 'This is the description for the crate called "crate-0"', + documentation: null, + downloads: 0, + homepage: null, + keywords: [], + links: { + owner_team: '/api/v1/crates/crate-0/owner_team', + owner_user: '/api/v1/crates/crate-0/owner_user', + reverse_dependencies: '/api/v1/crates/crate-0/reverse_dependencies', + version_downloads: '/api/v1/crates/crate-0/downloads', + versions: '/api/v1/crates/crate-0/versions', + }, + max_version: '1.0.0', + name: 'crate-0', + newest_version: '1.0.0', + repository: null, + updated_at: '2017-02-24T12:34:56Z', + versions: null, + }); + + assert.equal(responsePayload.new_crates.length, 10); + assert.deepEqual(responsePayload.new_crates[0], { + id: 'crate-0', + badges: [], + categories: [], + created_at: '2010-06-16T21:30:45Z', + description: 'This is the description for the crate called "crate-0"', + documentation: null, + downloads: 0, + homepage: null, + keywords: [], + links: { + owner_team: '/api/v1/crates/crate-0/owner_team', + owner_user: '/api/v1/crates/crate-0/owner_user', + reverse_dependencies: '/api/v1/crates/crate-0/reverse_dependencies', + version_downloads: '/api/v1/crates/crate-0/downloads', + versions: '/api/v1/crates/crate-0/versions', + }, + max_version: '1.0.0', + name: 'crate-0', + newest_version: '1.0.0', + repository: null, + updated_at: '2017-02-24T12:34:56Z', + versions: null, + }); + + assert.equal(responsePayload.num_crates, 20); + assert.equal(responsePayload.num_downloads, 1419675); + + assert.equal(responsePayload.popular_categories.length, 10); + assert.deepEqual(responsePayload.popular_categories[0], { + id: 'category-0', + category: 'Category 0', + crates_cnt: 0, + created_at: '2010-06-16T21:30:45Z', + description: 'This is the description for the category called "Category 0"', + slug: 'category-0', + }); + + assert.equal(responsePayload.popular_keywords.length, 10); + assert.deepEqual(responsePayload.popular_keywords[0], { + id: 'keyword-1', + crates_cnt: 0, + keyword: 'keyword-1', + }); + }); + }); +});