chore: 🤖 Ensure create/update/delete error messages display

This commit is contained in:
Randall Morey committed 2020-06-03 19:00:34 -04:00
1 parent d2e55b19a1
commit 01b876a465
7 files changed
+197 -13

No files matched your search

+23 -4
View File
@@ -2,6 +2,7 @@
@onSubmit={{@submit}}
@cancel={{@cancel}}
@disabled={{@model.isSaving}}
@error={{true}}
as |form|
>
@@ -10,17 +11,35 @@
@type="name"
@value={{@model.name}}
@label={{t "form.label.name"}}
@error={{false}}
readonly={{false}} />
@error={{@model.errors.name}}
readonly={{false}}
as |field|>
{{#if @model.errors.name}}
<field.errors as |errors|>
{{#each @model.errors.name as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</field.errors>
{{/if}}
</form.input>
<form.textarea
name="description"
@type="description"
@value={{@model.description}}
@label={{t "form.label.description"}}
@error={{false}}
@error={{@model.errors.description}}
disabled={{@model.isSaving}}
readonly={{false}} />
readonly={{false}}
as |field|>
{{#if @model.errors.description}}
<field.errors as |errors|>
{{#each @model.errors.description as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</field.errors>
{{/if}}
</form.textarea>
<form.actions
@disabled={{if @model.cannotSave @model.cannotSave}}
+2 -2
View File
@@ -42,9 +42,9 @@ export default class OrgsOrgProjectsNewRoute extends Route {
this.transitionTo('orgs.org.projects.project', project);
// TODO: replace with translated strings
this.notify.success('Project created.');
} catch (e) {
} catch (error) {
// TODO: replace with translated strings
this.notify.error('Project could not be created.', {closeAfter: null});
this.notify.error(error.message, { closeAfter: null });
}
}
}
@@ -50,9 +50,9 @@ export default class OrgsOrgProjectsProjectRoute extends Route {
await project.save();
// TODO: replace with translated strings
this.notify.success('Save succeeded.');
} catch (e) {
} catch (error) {
// TODO: replace with translated strings
this.notify.error('An error occurred.', {closeAfter: null});
this.notify.error(error.message, { closeAfter: null });
}
}
@@ -67,9 +67,9 @@ export default class OrgsOrgProjectsProjectRoute extends Route {
this.transitionTo('orgs.org.projects');
// TODO: replace with translated strings
this.notify.success('Deleted project succesfully.');
} catch (e) {
} catch (error) {
// TODO: replace with translated strings
this.notify.error('An error occurred.', {closeAfter: null});
this.notify.error(error.message, { closeAfter: null });
}
}
}
+1 -1
View File
@@ -9,7 +9,7 @@
.rose-form {
width: 66%;
.rose-form-input {
width: 100%;
+1 -1
View File
@@ -41,7 +41,7 @@ module.exports = function (environment) {
'frame-src': ["'self'"],
'font-src': ["'self'"],
'connect-src': ["'self'"],
'img-src': ["'self'", "data:"],
'img-src': ["'self'", 'data:'],
'style-src': ["'self'"],
'media-src': ["'self'"],
'manifest-src': ["'self'"],
+28 -1
View File
@@ -1,4 +1,5 @@
import config from '../config/environment';
import { Response } from 'miragejs';
export default function() {
@@ -27,6 +28,32 @@ export default function() {
this.get('/orgs/:org_id/projects');
this.post('/orgs/:org_id/projects');
this.get('/orgs/:org_id/projects/:id');
this.patch('/orgs/:org_id/projects/:id');
this.patch('/orgs/:org_id/projects/:id', () => {
// return new Response(400, {}, {
// "status": 400,
// "code": "invalid_argument",
// "message": "The request contained invalid fields.",
// "details": {
// "request_id": "abc123",
// "TraceId": "0123-4567",
// "fields": [
// {
// "name": "name",
// "message": "name is required"
// },
// {
// "name": "description",
// "message": "The description must not be more than 1 trillion characters long."
// }
// ]
// }
// });
return new Response(409, {}, {
"status": 409,
"code": "invalid_argument",
"message": "The request was awful."
});
});
this.del('/orgs/:org_id/projects/:id');
}
+138
View File
@@ -0,0 +1,138 @@
import { module, test } from 'qunit';
import { visit, currentURL, click, fillIn, find } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import a11yAudit from 'ember-a11y-testing/test-support/audit';
import { Response } from 'miragejs';
module('Acceptance | projects', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
test('visiting projects', async function (assert) {
assert.expect(1);
await visit('/orgs/1/projects');
await a11yAudit();
assert.equal(currentURL(), '/orgs/1/projects');
});
test('saving a new project with invalid fields displays error messages', async function (assert) {
assert.expect(2);
this.server.post('/orgs/:org_id/projects', () => {
return new Response(
400,
{},
{
status: 400,
code: 'invalid_argument',
message: 'The request was invalid.',
details: {
fields: [
{
name: 'name',
message: 'Name is required.',
},
],
},
}
);
});
await visit('/orgs/1/projects/new');
await fillIn('[name="name"]', 'random string');
await click('[type="submit"]');
assert.ok(
find('[role="alert"]').textContent.trim(),
'The request was invalid.',
'Displays primary error message.'
);
assert.ok(
find('.rose-form-error-message').textContent.trim(),
'Name is required.',
'Displays field-level errors.'
);
});
test('saving an existing project with invalid fields displays error messages', async function (assert) {
assert.expect(2);
this.server.createList('project', 1);
this.server.patch('/orgs/:org_id/projects/:id', () => {
return new Response(
400,
{},
{
status: 400,
code: 'invalid_argument',
message: 'The request was invalid.',
details: {
fields: [
{
name: 'name',
message: 'Name is required.',
},
],
},
}
);
});
await visit('/orgs/1/projects/1');
await fillIn('[name="name"]', 'random string');
await click('[type="submit"]');
assert.ok(
find('[role="alert"]').textContent.trim(),
'The request was invalid.',
'Displays primary error message.'
);
assert.ok(
find('.rose-form-error-message').textContent.trim(),
'Name is required.',
'Displays field-level errors.'
);
});
test('errors are displayed when save project fails', async function (assert) {
assert.expect(1);
this.server.createList('project', 1);
this.server.patch('/orgs/:org_id/projects/:id', () => {
return new Response(
490,
{},
{
status: 490,
code: 'error',
message: 'Oops.',
}
);
});
await visit('/orgs/1/projects/1');
await fillIn('[name="name"]', 'random string');
await click('[type="submit"]');
assert.ok(
find('[role="alert"]').textContent.trim(),
'Oops.',
'Displays primary error message.'
);
});
test('errors are displayed when delete project fails', async function (assert) {
assert.expect(1);
this.server.createList('project', 1);
this.server.del('/orgs/:org_id/projects/:id', () => {
return new Response(
490,
{},
{
status: 490,
code: 'error',
message: 'Oops.',
}
);
});
await visit('/orgs/1/projects/1');
await click('.rose-button-warning');
assert.ok(
find('[role="alert"]').textContent.trim(),
'Oops.',
'Displays primary error message.'
);
});
});