Meaningful error pages (#177)

Adds meaningful error pages if
- poll does not exist
- encryption key is wrong.
This commit is contained in:
jelhan 2019-04-23 17:37:42 +02:00 committed by GitHub
parent 596cd40d2f
commit 17cfb4ab6d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 134 additions and 14 deletions

View file

@ -1,8 +1,3 @@
import { computed } from '@ember/object';
import Controller from '@ember/controller';
export default Controller.extend({
isDecryptionError: computed('model.type', function() {
return this.get('model.type') === 'decryption-failed';
})
});
export default Controller.extend({});

View file

@ -0,0 +1,11 @@
import Controller from '@ember/controller';
import { computed } from '@ember/object';
import { equal } from '@ember/object/computed';
import sjcl from 'sjcl';
export default Controller.extend({
decryptionFailed: computed('model', function() {
return this.model instanceof sjcl.exception.corrupt;
}),
notFound: equal('model.errors.firstObject.status', '404')
});

View file

@ -44,6 +44,14 @@ export default {
'create.settings.forceAnswer.label': 'Força una resposta per a cada opció?',
'create.title': 'Crea una enquesta',
'error': 'Error',
'error.poll.decryptionFailed.title': 'Decryption failed',
'error.poll.decryptionFailed.description': 'Decrypting poll data failed. This is most likely caused by a wrong encryption key. Please double-check the URL entered, especially the part after the question mark.',
'error.poll.notFound.title': 'Poll could not be found',
'error.poll.notFound.description': 'The poll you are looking for could not be found. This could be caused by different reasons, including:',
'error.poll.notFound.reasons.expired': 'The poll is expired and has been deleted.',
'error.poll.notFound.reasons.typo': 'There is a typo in the URL. You may want to double-check it - especially the part before the question mark.',
'error.generic.unexpected.title': 'An unexpected error occured',
'error.generic.unexpected.description': 'We are sorry. An unexpected error occurred. Please try again later.',
'index.title': 'Croodle simplifica la data i la presa de decisions ...<br/>... i protegeix les teves dades',
'index.features.title': 'Funcions',
'index.features.list.overview': '<strong> Troba una data </strong> o <strong> fer una enquesta </strong> amb tantes persones com vulgui.',

View file

@ -44,6 +44,14 @@ export default {
'create.settings.forceAnswer.label': 'Eine Antwort für jede Option erzwingen?',
'create.title': 'Umfrage erstellen',
'error': 'Fehler',
'error.poll.decryptionFailed.title': 'Decryption failed',
'error.poll.decryptionFailed.description': 'Decrypting poll data failed. This is most likely caused by a wrong encryption key. Please double-check the URL entered, especially the part after the question mark.',
'error.poll.notFound.title': 'Poll could not be found',
'error.poll.notFound.description': 'The poll you are looking for could not be found. This could be caused by different reasons, including:',
'error.poll.notFound.reasons.expired': 'The poll is expired and has been deleted.',
'error.poll.notFound.reasons.typo': 'There is a typo in the URL. You may want to double-check it - especially the part before the question mark.',
'error.generic.unexpected.title': 'An unexpected error occured',
'error.generic.unexpected.description': 'We are sorry. An unexpected error occurred. Please try again later.',
'index.title': 'Croodle vereinfacht die Termin- und Entscheidungsfindung ...<br/>... und schützt dabei deine Daten',
'index.features.title': 'Funktionen',
'index.features.list.overview': '<strong>Finde einen Termin</strong> oder <strong>mache eine Umfrage</strong> mit so vielen Leuten, wie du möchtest.',

View file

@ -44,6 +44,14 @@ export default {
'create.settings.forceAnswer.label': 'Force an answer for every option?',
'create.title': 'Create a poll',
'error': 'Error',
'error.poll.decryptionFailed.title': 'Decryption failed',
'error.poll.decryptionFailed.description': 'Decrypting poll data failed. This is most likely caused by a wrong encryption key. Please double-check the URL entered, especially the part after the question mark.',
'error.poll.notFound.title': 'Poll could not be found',
'error.poll.notFound.description': 'The poll you are looking for could not be found. This could be caused by different reasons, including:',
'error.poll.notFound.reasons.expired': 'The poll is expired and has been deleted.',
'error.poll.notFound.reasons.typo': 'There is a typo in the URL. You may want to double-check it - especially the part before the question mark.',
'error.generic.unexpected.title': 'An unexpected error occured',
'error.generic.unexpected.description': 'We are sorry. An unexpected error occurred. Please try again later.',
'index.title': 'Croodle simplifies date and decision-making ...<br/>... and protects your data',
'index.features.title': 'Functions',
'index.features.list.overview': '<strong>Find a date</strong> or <strong> make a survey</strong> with as many people as you want.',

View file

@ -44,6 +44,14 @@ export default {
'create.settings.forceAnswer.label': '¿Obligar a responder todas las preguntas/opciones?',
'create.title': 'Crear una encuesta',
'error': 'Error',
'error.poll.decryptionFailed.title': 'Decryption failed',
'error.poll.decryptionFailed.description': 'Decrypting poll data failed. This is most likely caused by a wrong encryption key. Please double-check the URL entered, especially the part after the question mark.',
'error.poll.notFound.title': 'Poll could not be found',
'error.poll.notFound.description': 'The poll you are looking for could not be found. This could be caused by different reasons, including:',
'error.poll.notFound.reasons.expired': 'The poll is expired and has been deleted.',
'error.poll.notFound.reasons.typo': 'There is a typo in the URL. You may want to double-check it - especially the part before the question mark.',
'error.generic.unexpected.title': 'An unexpected error occured',
'error.generic.unexpected.description': 'We are sorry. An unexpected error occurred. Please try again later.',
'index.title': 'Croodle simplifica las citas y la toma de decisiones ...<br/>... y al mismo tiempo protege tus datos',
'index.features.title': 'Funciones',
'index.features.list.overview': '<strong>Encontrar una fecha</strong> o <strong>hacer una encuesta</strong> con la cantidad de personas que quieras.',

View file

@ -44,6 +44,14 @@ export default {
'create.settings.forceAnswer.label': 'Forzare una risposta per ogni opzione?',
'create.title': 'Crea un sondaggio',
'error': 'Errore',
'error.poll.decryptionFailed.title': 'Decryption failed',
'error.poll.decryptionFailed.description': 'Decrypting poll data failed. This is most likely caused by a wrong encryption key. Please double-check the URL entered, especially the part after the question mark.',
'error.poll.notFound.title': 'Poll could not be found',
'error.poll.notFound.description': 'The poll you are looking for could not be found. This could be caused by different reasons, including:',
'error.poll.notFound.reasons.expired': 'The poll is expired and has been deleted.',
'error.poll.notFound.reasons.typo': 'There is a typo in the URL. You may want to double-check it - especially the part before the question mark.',
'error.generic.unexpected.title': 'An unexpected error occured',
'error.generic.unexpected.description': 'We are sorry. An unexpected error occurred. Please try again later.',
'index.title': 'Croodle semplifica la scelta delle date e il processo decisionale ...<br/>... e protegge i tuoi dati',
'index.features.title': 'funzioni',
'index.features.list.overview': '<strong>Trova una data</strong> o <strong>fai una inchiesta</strong> con tante persone come vuoi.',

View file

@ -1,11 +1,8 @@
<div class="box">
<h2>error</h2>
<h2>
{{t "error.generic.unexpected.title"}}
</h2>
<p>
{{#if isDecryptionError}}
Decryption failed. Please double check the URL. Make sure that no
character is missing.
{{else}}
We are sorry. An unexpected error occurred.
{{/if}}
{{t "error.generic.unexpected.description"}}
</p>
</div>

View file

@ -0,0 +1,32 @@
<div class="box">
{{#if decryptionFailed}}
<h2 data-test-error-type="decryption-failed">
{{t "error.poll.decryptionFailed.title"}}
</h2>
<p>
{{t "error.poll.decryptionFailed.description"}}
</p>
{{else if notFound}}
<h2 data-test-error-type="not-found">
{{t "error.poll.notFound.title"}}
</h2>
<p>
{{t "error.poll.notFound.description"}}
</p>
<ul>
<li>
{{t "error.poll.notFound.reasons.expired"}}
</li>
<li>
{{t "error.poll.notFound.reasons.typo"}}
</li>
</ul>
{{else}}
<h2 data-test-error-type="unexpected">
{{t "error.poll.unexpected.title"}}
</h2>
<p>
{{t "error.poll.unexpected.description"}}
</p>
{{/if}}
</div>

View file

@ -1,4 +1,4 @@
import { click, visit } from '@ember/test-helpers';
import { click, currentURL, currentRouteName, visit } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
@ -211,4 +211,37 @@ module('Acceptance | view poll', function(hooks) {
[moment.tz('2015-12-12T11:11:00.000Z', timezonePoll).locale('en').format('LLLL')]
);
});
test('shows error page if poll does not exist', async function(assert) {
let pollId = 'not-existing';
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
await visit(`/poll/${pollId}?encryptionKey=${encryptionKey}`);
assert.equal(currentURL(), `/poll/${pollId}?encryptionKey=${encryptionKey}`, 'shows URL entered by user');
assert.equal(currentRouteName(), 'poll_error', 'shows error substate of poll route');
assert.dom('[data-test-error-type]').hasAttribute('data-test-error-type', 'not-found');
});
test('shows error page if encryption key is wrong', async function(assert) {
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
let poll = this.server.create('poll', { encryptionKey: 'anotherkey' });
await visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
assert.equal(currentURL(), `/poll/${poll.id}?encryptionKey=${encryptionKey}`, 'shows URL entered by user');
assert.equal(currentRouteName(), 'poll_error', 'shows error substate of poll route');
assert.dom('[data-test-error-type]').hasAttribute('data-test-error-type', 'decryption-failed');
});
test('shows error page if server returns a 500', async function(assert) {
let pollId = 'not-existing';
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
// mock server returning 500 error
this.server.get('polls/:id', () => {}, 500);
await visit(`/poll/${pollId}?encryptionKey=${encryptionKey}`);
assert.equal(currentURL(), `/poll/${pollId}?encryptionKey=${encryptionKey}`, 'shows URL entered by user');
assert.equal(currentRouteName(), 'poll_error', 'shows error substate of poll route');
assert.dom('[data-test-error-type]').hasAttribute('data-test-error-type', 'unexpected');
})
});

View file

@ -0,0 +1,12 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Controller | poll-error', function(hooks) {
setupTest(hooks);
// Replace this with your real tests.
test('it exists', function(assert) {
let controller = this.owner.lookup('controller:poll-error');
assert.ok(controller);
});
});