5146bbdf36
* fix: Use of assign has been deprecated. Please use Object.assign or the spread operator instead. * fix @tagName argument of <LinkTo> is deprecated * clean-up deprecation workflow
418 lines
13 KiB
JavaScript
418 lines
13 KiB
JavaScript
import {
|
|
click,
|
|
find,
|
|
findAll,
|
|
currentURL,
|
|
currentRouteName,
|
|
waitFor,
|
|
visit,
|
|
} from '@ember/test-helpers';
|
|
import { module, test } from 'qunit';
|
|
import { setupApplicationTest } from 'ember-qunit';
|
|
import { setupIntl, t } from 'ember-intl/test-support';
|
|
import { setupMirage } from 'ember-cli-mirage/test-support';
|
|
import PollEvaluationPage from 'croodle/tests/pages/poll/evaluation';
|
|
import pollParticipate from 'croodle/tests/helpers/poll-participate';
|
|
|
|
module('Acceptance | participate in a poll', function (hooks) {
|
|
let yesLabel;
|
|
let noLabel;
|
|
|
|
hooks.beforeEach(function () {
|
|
window.localStorage.setItem('locale', 'en');
|
|
});
|
|
|
|
setupApplicationTest(hooks);
|
|
setupIntl(hooks);
|
|
setupMirage(hooks);
|
|
|
|
hooks.beforeEach(function () {
|
|
yesLabel = t('answerTypes.yes.label').toString();
|
|
noLabel = t('answerTypes.no.label').toString();
|
|
});
|
|
|
|
test('participate in a default poll', async function (assert) {
|
|
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
let poll = this.server.create('poll', {
|
|
encryptionKey,
|
|
});
|
|
|
|
await visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
|
|
assert.equal(
|
|
currentRouteName(),
|
|
'poll.participation',
|
|
'poll is redirected to poll.participation',
|
|
);
|
|
|
|
await pollParticipate('Max Meiner', ['yes', 'no']);
|
|
assert.equal(currentRouteName(), 'poll.evaluation');
|
|
assert.equal(
|
|
currentURL().split('?')[1],
|
|
`encryptionKey=${encryptionKey}`,
|
|
'encryption key is part of query params',
|
|
);
|
|
assert.equal(
|
|
PollEvaluationPage.participants.length,
|
|
1,
|
|
'user is added to participants table',
|
|
);
|
|
let participant = PollEvaluationPage.participants.filterBy(
|
|
'name',
|
|
'Max Meiner',
|
|
)[0];
|
|
assert.ok(participant, 'user exists in participants table');
|
|
assert.deepEqual(
|
|
participant.selections.map((_) => _.answer),
|
|
[yesLabel, noLabel],
|
|
'participants table shows correct answers for new participant',
|
|
);
|
|
|
|
await click('.nav [data-test-link="participation"]');
|
|
assert.equal(currentRouteName(), 'poll.participation');
|
|
assert.equal(find('.name input').value, '', 'input for name is cleared');
|
|
assert.notOk(
|
|
findAll('input[type="radio"]').some((el) => el.checked),
|
|
'radios are cleared',
|
|
);
|
|
|
|
await pollParticipate('Peter Müller', ['yes', 'yes']);
|
|
assert.equal(currentRouteName(), 'poll.evaluation');
|
|
assert.equal(
|
|
PollEvaluationPage.participants.length,
|
|
2,
|
|
'user is added to participants table',
|
|
);
|
|
participant = PollEvaluationPage.participants.filterBy(
|
|
'name',
|
|
'Peter Müller',
|
|
)[0];
|
|
assert.ok(participant, 'user exists in participants table');
|
|
assert.deepEqual(
|
|
participant.selections.map((_) => _.answer),
|
|
[yesLabel, yesLabel],
|
|
'participants table shows correct answers for new participant',
|
|
);
|
|
});
|
|
|
|
test('participate in a poll using freetext', async function (assert) {
|
|
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
let poll = this.server.create('poll', {
|
|
answerType: 'FreeText',
|
|
answers: [],
|
|
encryptionKey,
|
|
});
|
|
|
|
await visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
|
|
assert.equal(currentRouteName(), 'poll.participation');
|
|
|
|
await pollParticipate('Max Manus', ['answer 1', 'answer 2']);
|
|
assert.equal(currentRouteName(), 'poll.evaluation');
|
|
assert.equal(
|
|
PollEvaluationPage.participants.length,
|
|
1,
|
|
'user is added to participants table',
|
|
);
|
|
|
|
let participant = PollEvaluationPage.participants.filterBy(
|
|
'name',
|
|
'Max Manus',
|
|
)[0];
|
|
assert.ok(participant, 'user exists in participants table');
|
|
assert.deepEqual(
|
|
participant.selections.map((_) => _.answer),
|
|
['answer 1', 'answer 2'],
|
|
'participants table shows correct answers for new participant',
|
|
);
|
|
});
|
|
|
|
test('participate in a poll which does not force an answer to all options', async function (assert) {
|
|
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
let poll = this.server.create('poll', {
|
|
encryptionKey,
|
|
forceAnswer: false,
|
|
});
|
|
|
|
await visit(
|
|
`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`,
|
|
);
|
|
assert.equal(currentRouteName(), 'poll.participation');
|
|
|
|
await pollParticipate('Karl Käfer', ['yes', null]);
|
|
assert.equal(currentRouteName(), 'poll.evaluation');
|
|
assert.equal(
|
|
PollEvaluationPage.participants.length,
|
|
1,
|
|
'user is added to participants table',
|
|
);
|
|
|
|
let participant = PollEvaluationPage.participants.filterBy(
|
|
'name',
|
|
'Karl Käfer',
|
|
)[0];
|
|
assert.ok(participant, 'user exists in participants table');
|
|
assert.deepEqual(
|
|
participant.selections.map((_) => _.answer),
|
|
[yesLabel, ''],
|
|
'participants table shows correct answers for new participant',
|
|
);
|
|
});
|
|
|
|
test('participate in a poll which allows anonymous participation', async function (assert) {
|
|
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
let poll = this.server.create('poll', {
|
|
anonymousUser: true,
|
|
encryptionKey,
|
|
});
|
|
|
|
await visit(
|
|
`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`,
|
|
);
|
|
assert.equal(currentRouteName(), 'poll.participation');
|
|
|
|
await pollParticipate(null, ['yes', 'no']);
|
|
assert.equal(currentRouteName(), 'poll.evaluation');
|
|
assert.equal(
|
|
PollEvaluationPage.participants.length,
|
|
1,
|
|
'user is added to participants table',
|
|
);
|
|
|
|
let participant = PollEvaluationPage.participants.filterBy('name', '')[0];
|
|
assert.ok(participant, 'user exists in participants table');
|
|
assert.deepEqual(
|
|
participant.selections.map((_) => _.answer),
|
|
[yesLabel, noLabel],
|
|
'participants table shows correct answers for new participant',
|
|
);
|
|
});
|
|
|
|
test('network connectivity errors', async function (assert) {
|
|
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
let poll = this.server.create('poll', {
|
|
encryptionKey,
|
|
});
|
|
|
|
this.server.post('/users', undefined, 503);
|
|
|
|
await visit(
|
|
`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`,
|
|
);
|
|
assert.equal(currentRouteName(), 'poll.participation');
|
|
assert
|
|
.dom('[data-test-modal="saving-failed"] .modal-content')
|
|
.isNotVisible(
|
|
'failed saving notification is not shown before attempt to save',
|
|
);
|
|
|
|
await pollParticipate('John Doe', ['yes', 'no']);
|
|
assert
|
|
.dom('[data-test-modal="saving-failed"] .modal-content')
|
|
.isVisible('user gets notified that saving failed');
|
|
|
|
this.server.post('/users');
|
|
|
|
await click('[data-test-modal="saving-failed"] [data-test-button="retry"]');
|
|
assert
|
|
.dom('[data-test-modal="saving-failed"] .modal-content')
|
|
.isNotVisible(
|
|
'Notification is hidden after another save attempt was successful',
|
|
);
|
|
assert.equal(currentRouteName(), 'poll.evaluation');
|
|
assert.equal(
|
|
PollEvaluationPage.participants.length,
|
|
1,
|
|
'user is added to participants table',
|
|
);
|
|
|
|
let participant = PollEvaluationPage.participants.filterBy(
|
|
'name',
|
|
'John Doe',
|
|
)[0];
|
|
assert.ok(participant, 'user exists in participants table');
|
|
assert.deepEqual(
|
|
participant.selections.map((_) => _.answer),
|
|
[yesLabel, noLabel],
|
|
'participants table shows correct answers for new participant',
|
|
);
|
|
});
|
|
|
|
test('shows loading spinner while submitting', async function (assert) {
|
|
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
let poll = this.server.create('poll', {
|
|
encryptionKey,
|
|
});
|
|
|
|
let resolveSubmission;
|
|
let resolveSubmissionWith;
|
|
this.server.post('/users', function (schema) {
|
|
return new Promise((resolve) => {
|
|
let attrs = this.normalizedRequestAttrs();
|
|
|
|
resolveSubmission = resolve;
|
|
resolveSubmissionWith = schema.users.create(attrs);
|
|
});
|
|
});
|
|
|
|
await visit(
|
|
`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`,
|
|
);
|
|
pollParticipate('John Doe', ['yes', 'no']);
|
|
|
|
await waitFor('[data-test-button="submit"] .spinner-border', {
|
|
timeoutMessage: 'timeout while waiting for loading spinner to appear',
|
|
});
|
|
assert.ok(
|
|
true,
|
|
'loading spinner shown cause otherwise there would have been a timeout',
|
|
);
|
|
|
|
// resolve promise for test to finish
|
|
// need to resolve with a valid response cause otherwise Ember Data would throw
|
|
resolveSubmission(resolveSubmissionWith);
|
|
});
|
|
|
|
module('validation', function () {
|
|
test('shows validation errors for participation form on submit', async function (assert) {
|
|
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
let poll = this.server.create('poll', {
|
|
encryptionKey,
|
|
});
|
|
|
|
await visit(
|
|
`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`,
|
|
);
|
|
await click('button[type="submit"]');
|
|
|
|
assert
|
|
.dom('[data-test-form-element="name"] input')
|
|
.hasClass('is-invalid');
|
|
assert
|
|
.dom('[data-test-form-element="option-2017-12-24"] input[id$="yes"]')
|
|
.hasClass('is-invalid');
|
|
assert
|
|
.dom('[data-test-form-element="option-2017-12-24"] input[id$="no"]')
|
|
.hasClass('is-invalid');
|
|
assert
|
|
.dom('[data-test-form-element="option-2018-01-01"] input[id$="yes"]')
|
|
.hasClass('is-invalid');
|
|
assert
|
|
.dom('[data-test-form-element="option-2018-01-01"] input[id$="no"]')
|
|
.hasClass('is-invalid');
|
|
|
|
assert.dom('[data-test-form-element="name"] input').isFocused();
|
|
|
|
assert.equal(
|
|
currentRouteName(),
|
|
'poll.participation',
|
|
'invalid form prevents a transition',
|
|
);
|
|
});
|
|
|
|
test('does not show validation error for name if poll allows anonymous participation', async function (assert) {
|
|
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
let poll = this.server.create('poll', {
|
|
anonymousUser: true,
|
|
encryptionKey,
|
|
});
|
|
|
|
await visit(
|
|
`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`,
|
|
);
|
|
await click('button[type="submit"]');
|
|
|
|
assert.dom('[data-test-form-element="name"] input').hasClass('is-valid');
|
|
assert
|
|
.dom('[data-test-form-element="option-2017-12-24"] input[id$="yes"]')
|
|
.hasClass('is-invalid');
|
|
assert
|
|
.dom('[data-test-form-element="option-2017-12-24"] input[id$="no"]')
|
|
.hasClass('is-invalid');
|
|
assert
|
|
.dom('[data-test-form-element="option-2018-01-01"] input[id$="yes"]')
|
|
.hasClass('is-invalid');
|
|
assert
|
|
.dom('[data-test-form-element="option-2018-01-01"] input[id$="no"]')
|
|
.hasClass('is-invalid');
|
|
|
|
assert
|
|
.dom('[data-test-form-element="option-2017-12-24"] input[id$="yes"]')
|
|
.isFocused();
|
|
assert.equal(
|
|
currentRouteName(),
|
|
'poll.participation',
|
|
'invalid form prevents a transition',
|
|
);
|
|
});
|
|
|
|
test('does not show validation error for option inputs if poll does not force an answer to each option', async function (assert) {
|
|
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
let poll = this.server.create('poll', {
|
|
encryptionKey,
|
|
forceAnswer: false,
|
|
});
|
|
|
|
await visit(
|
|
`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`,
|
|
);
|
|
await click('button[type="submit"]');
|
|
|
|
assert
|
|
.dom('[data-test-form-element="name"] input')
|
|
.hasClass('is-invalid');
|
|
assert
|
|
.dom('[data-test-form-element="option-2017-12-24"] input[id$="yes"]')
|
|
.hasClass('is-valid');
|
|
assert
|
|
.dom('[data-test-form-element="option-2017-12-24"] input[id$="no"]')
|
|
.hasClass('is-valid');
|
|
assert
|
|
.dom('[data-test-form-element="option-2018-01-01"] input[id$="yes"]')
|
|
.hasClass('is-valid');
|
|
assert
|
|
.dom('[data-test-form-element="option-2018-01-01"] input[id$="no"]')
|
|
.hasClass('is-valid');
|
|
|
|
assert.dom('[data-test-form-element="name"] input').isFocused();
|
|
|
|
assert.equal(
|
|
currentRouteName(),
|
|
'poll.participation',
|
|
'invalid form prevents a transition',
|
|
);
|
|
});
|
|
|
|
test('does not show validation errors while saving participation', async function (assert) {
|
|
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
let poll = this.server.create('poll', {
|
|
encryptionKey,
|
|
});
|
|
|
|
let resolveSubmission;
|
|
let resolveSubmissionWith;
|
|
this.server.post('/users', function (schema) {
|
|
return new Promise((resolve) => {
|
|
let attrs = this.normalizedRequestAttrs();
|
|
|
|
resolveSubmission = resolve;
|
|
resolveSubmissionWith = schema.users.create(attrs);
|
|
});
|
|
});
|
|
|
|
await visit(
|
|
`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`,
|
|
);
|
|
pollParticipate('John Doe', ['yes', 'no']);
|
|
|
|
await waitFor('[data-test-button="submit"] .spinner-border', {
|
|
timeoutMessage: 'timeout while waiting for loading spinner to appear',
|
|
});
|
|
assert
|
|
.dom('.is-invalid')
|
|
.doesNotExist('does not show any validation error');
|
|
|
|
// resolve promise for test to finish
|
|
// need to resolve with a valid response cause otherwise Ember Data would throw
|
|
resolveSubmission(resolveSubmissionWith);
|
|
});
|
|
});
|
|
});
|