Skip to content

Commit ebe689c

Browse files
committed
Auto merge of #2940 - Turbo87:rev-deps, r=locks
crate.reverse-dependencies: Show error notification if data loading fails Instead of showing an empty error page, this PR adjusts the code to show an error message popup through our regular `notifications` service system: <img width="633" alt="Bildschirmfoto 2020-10-21 um 16 16 52" src="https://user-images.githubusercontent.com/141300/96732693-ea417280-13b8-11eb-96fc-b7aa5dae0042.png"> Related to #187 r? `@locks`
2 parents 5865ac9 + 90eae29 commit ebe689c

File tree

3 files changed

+115
-6
lines changed

3 files changed

+115
-6
lines changed

app/routes/crate/reverse-dependencies.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,31 @@
11
import Route from '@ember/routing/route';
2+
import { inject as service } from '@ember/service';
23

34
export default class ReverseDependenciesRoute extends Route {
5+
@service notifications;
6+
47
queryParams = {
58
page: { refreshModel: true },
69
};
710

8-
model(params) {
11+
async model(params) {
912
params.reverse = true;
1013
params.crate = this.modelFor('crate');
14+
let crateName = params.crate.name;
15+
16+
try {
17+
return await this.store.query('dependency', params);
18+
} catch (error) {
19+
let message = `Could not load reverse dependencies for the "${crateName}" crate`;
20+
21+
let details = error.errors?.[0]?.detail;
22+
if (details && details !== '[object Object]') {
23+
message += `: ${details}`;
24+
}
1125

12-
return this.store.query('dependency', params);
26+
this.notifications.error(message);
27+
this.replaceWith('index');
28+
}
1329
}
1430

1531
setupController(controller) {

app/templates/crate/reverse-dependencies.hbs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@
1111
/>
1212
</div>
1313

14-
<div local-class="list">
15-
{{#each this.model as |dependency|}}
16-
<div local-class="row">
14+
<div local-class="list" data-test-list>
15+
{{#each this.model as |dependency index|}}
16+
<div local-class="row" data-test-row={{index}}>
1717
<div>
18-
<LinkTo @route="crate" @model={{dependency.version.crateName}}>{{dependency.version.crateName}}</LinkTo> requires {{dependency.req}}
18+
<LinkTo @route="crate" @model={{dependency.version.crateName}} data-test-crate-name>
19+
{{dependency.version.crateName}}
20+
</LinkTo>
21+
requires {{dependency.req}}
1922
</div>
2023
<div local-class="stats downloads">
2124
{{svg-jar "download-arrow" local-class="download-icon"}}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { click, currentURL } from '@ember/test-helpers';
2+
import { setupApplicationTest } from 'ember-qunit';
3+
import { module, test } from 'qunit';
4+
5+
import setupMirage from '../helpers/setup-mirage';
6+
import { visit } from '../helpers/visit-ignoring-abort';
7+
8+
module('Acceptance | /crates/:crate_id/reverse_dependencies', function (hooks) {
9+
setupApplicationTest(hooks);
10+
setupMirage(hooks);
11+
12+
function prepare({ server }) {
13+
let foo = server.create('crate', { name: 'foo' });
14+
server.create('version', { crate: foo });
15+
16+
let bar = server.create('crate', { name: 'bar' });
17+
server.create('version', { crate: bar });
18+
19+
let baz = server.create('crate', { name: 'baz' });
20+
server.create('version', { crate: baz });
21+
22+
server.create('dependency', { crate: foo, version: bar.versions.models[0] });
23+
server.create('dependency', { crate: foo, version: baz.versions.models[0] });
24+
25+
return { foo, bar, baz };
26+
}
27+
28+
test('shows a list of crates depending on the selected crate', async function (assert) {
29+
let { foo, bar, baz } = prepare(this);
30+
31+
await visit(`/crates/${foo.name}/reverse_dependencies`);
32+
assert.equal(currentURL(), `/crates/${foo.name}/reverse_dependencies`);
33+
assert.dom('[data-test-row]').exists({ count: 2 });
34+
assert.dom('[data-test-row="0"] [data-test-crate-name]').hasText(bar.name);
35+
assert.dom('[data-test-row="1"] [data-test-crate-name]').hasText(baz.name);
36+
});
37+
38+
test('supports pagination', async function (assert) {
39+
let { foo } = prepare(this);
40+
41+
for (let i = 0; i < 20; i++) {
42+
let crate = this.server.create('crate');
43+
let version = this.server.create('version', { crate });
44+
this.server.create('dependency', { crate: foo, version });
45+
}
46+
47+
await visit(`/crates/${foo.name}/reverse_dependencies`);
48+
assert.equal(currentURL(), `/crates/${foo.name}/reverse_dependencies`);
49+
assert.dom('[data-test-row]').exists({ count: 10 });
50+
assert.dom('[data-test-current-rows]').hasText('1-10');
51+
assert.dom('[data-test-total-rows]').hasText('22');
52+
53+
await click('[data-test-pagination-next]');
54+
assert.equal(currentURL(), `/crates/${foo.name}/reverse_dependencies?page=2`);
55+
assert.dom('[data-test-row]').exists({ count: 10 });
56+
assert.dom('[data-test-current-rows]').hasText('11-20');
57+
assert.dom('[data-test-total-rows]').hasText('22');
58+
59+
await click('[data-test-pagination-next]');
60+
assert.equal(currentURL(), `/crates/${foo.name}/reverse_dependencies?page=3`);
61+
assert.dom('[data-test-row]').exists({ count: 2 });
62+
assert.dom('[data-test-current-rows]').hasText('21-22');
63+
assert.dom('[data-test-total-rows]').hasText('22');
64+
});
65+
66+
test('shows an error if the server is broken', async function (assert) {
67+
let { foo } = prepare(this);
68+
69+
this.server.get('/api/v1/crates/:crate_id/reverse_dependencies', {}, 500);
70+
71+
await visit(`/crates/${foo.name}/reverse_dependencies`);
72+
assert.equal(currentURL(), '/');
73+
assert
74+
.dom('[data-test-notification-message="error"]')
75+
.hasText('Could not load reverse dependencies for the "foo" crate');
76+
});
77+
78+
test('shows an error if the server is broken', async function (assert) {
79+
let { foo } = prepare(this);
80+
81+
let payload = { errors: [{ detail: 'cannot request more than 100 items' }] };
82+
this.server.get('/api/v1/crates/:crate_id/reverse_dependencies', payload, 400);
83+
84+
await visit(`/crates/${foo.name}/reverse_dependencies`);
85+
assert.equal(currentURL(), '/');
86+
assert
87+
.dom('[data-test-notification-message="error"]')
88+
.hasText('Could not load reverse dependencies for the "foo" crate: cannot request more than 100 items');
89+
});
90+
});

0 commit comments

Comments
 (0)