diff --git a/.eslintrc.js b/.eslintrc.js index b403793..0f71b0c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,4 +1,7 @@ module.exports = { + globals: { + server: true, + }, root: true, parserOptions: { ecmaVersion: 2017, diff --git a/README.md b/README.md index f848528..a253625 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Due to security reasons you should have SSL encryption enabled and provide a val ## Build process and installation -Production builds are provided [here](https://github.com/jelhan/croodle/releases). +Production builds are provided as github [release assets](https://github.com/jelhan/croodle/releases). If you like to build yourself you have to install [yarn](https://yarnpkg.com/), [bower](http://bower.io/), [ember-cli](http://www.ember-cli.com/) and [composer](https://getcomposer.org/) before. @@ -68,6 +68,8 @@ Files are watched for changes. If you only like to run tests ones against PhantomJS in command-line you could use `ember test`. This is also used in CI. +Test are run against a mock-api provided by [ember-cli-mirage](http://www.ember-cli-mirage.com/). + ### Api Api tests are provided by Codeception. To run them change current directory to `/api` and execute `./vendor/bin/codecept run`. You have diff --git a/bower.json b/bower.json index e2c5baf..11314a3 100644 --- a/bower.json +++ b/bower.json @@ -6,7 +6,6 @@ "bootstrap-datepicker": "~1.4.0", "floatThead": "^1.4.3", "jstimezonedetect": "~1.0.5", - "pretender": "^0.6.0", "ceibo": "1.1.0" } } diff --git a/mirage/config.js b/mirage/config.js new file mode 100644 index 0000000..05681de --- /dev/null +++ b/mirage/config.js @@ -0,0 +1,8 @@ +export default function() { + this.namespace = '/api/index.php'; // make this `api`, for example, if your API is namespaced + this.timing = 400; // delay for each request, automatically set to 0 during testing + + this.get('/polls/:id'); + this.post('/polls'); + this.post('/users'); +} diff --git a/mirage/factories/poll.js b/mirage/factories/poll.js new file mode 100644 index 0000000..3d43c1d --- /dev/null +++ b/mirage/factories/poll.js @@ -0,0 +1,56 @@ +import { Factory } from 'ember-cli-mirage'; +import encrypt from '../utils/encrypt'; + +export default Factory.extend({ + anonymousUser: false, + answers: [ + { + type: 'yes', + labelTranslation: 'answerTypes.yes.label', + icon: 'glyphicon glyphicon-thumbs-up', + label: 'Ja' + }, + { + type: 'no', + labelTranslation: 'answerTypes.no.label', + icon: 'glyphicon glyphicon-thumbs-down', + label: 'Nein' + } + ], + answerType: 'YesNo', + creationDate: '2015-04-01T11:11:11.111Z', + description: 'default description', + encryptionKey: 'abcdefghijklmnopqrstuvwxyz', + expirationDate: '', + forceAnswer: true, + isDateTime: false, + options: [ + { + title: '2017-12-24' + }, + { + title: '2018-01-01' + } + ], + pollType: 'FindADate', + title: 'default title', + timezone: '', + version: 'v0.3', + + afterCreate(poll, server) { + let propertiesToEncrypt = [ + 'anonymousUser', + 'answers', + 'answerType', + 'creationDate', + 'description', + 'expirationDate', + 'forceAnswer', + 'options', + 'pollType', + 'timezone', + 'title' + ]; + encrypt(propertiesToEncrypt, poll, server); + } +}); diff --git a/mirage/factories/user.js b/mirage/factories/user.js new file mode 100644 index 0000000..e9bfd52 --- /dev/null +++ b/mirage/factories/user.js @@ -0,0 +1,16 @@ +import { Factory } from 'ember-cli-mirage'; +import encrypt from '../utils/encrypt'; + +export default Factory.extend({ + creationDate: (new Date()).toISOString(), + name: 'John Doe', + selections: [], + afterCreate(user, server) { + let propertiesToEncrypt = [ + 'creationDate', + 'name', + 'selections' + ]; + encrypt(propertiesToEncrypt, user, server); + } +}); diff --git a/mirage/identity-managers/poll.js b/mirage/identity-managers/poll.js new file mode 100644 index 0000000..8b0143c --- /dev/null +++ b/mirage/identity-managers/poll.js @@ -0,0 +1,56 @@ +import generateRandomString from 'croodle/utils/generate-passphrase'; + +export default class { + constructor() { + this.reset(); + } + + /** + * Returns an unique identifier. + * + * @method fetch + * @param {Object} data Records attributes hash + * @return {String} Unique identifier + * @public + */ + fetch() { + let id; + + while (id === undefined) { + let randomString = generateRandomString(10); + if (this._ids[randomString] === undefined) { + id = randomString; + } + } + + this._ids[id] = true; + + return id; + } + + /** + * Register an identifier. + * Must throw if identifier is already used. + * + * @method set + * @param {String|Number} id + * @public + */ + set(id) { + if (typeof this._ids[id] !== 'undefined') { + throw new Error(`Id {id} is already used.`); + } + + this._ids[id] = true; + } + + /** + * Reset identity manager. + * + * @method reset + * @public + */ + reset() { + this._ids = {}; + } +} diff --git a/mirage/models/poll.js b/mirage/models/poll.js new file mode 100644 index 0000000..41d362e --- /dev/null +++ b/mirage/models/poll.js @@ -0,0 +1,5 @@ +import { Model, hasMany } from 'ember-cli-mirage'; + +export default Model.extend({ + users: hasMany('user') +}); diff --git a/mirage/models/user.js b/mirage/models/user.js new file mode 100644 index 0000000..fe42ae7 --- /dev/null +++ b/mirage/models/user.js @@ -0,0 +1,5 @@ +import { Model, belongsTo } from 'ember-cli-mirage'; + +export default Model.extend({ + poll: belongsTo('poll') +}); diff --git a/mirage/scenarios/default.js b/mirage/scenarios/default.js new file mode 100644 index 0000000..0d2db8d --- /dev/null +++ b/mirage/scenarios/default.js @@ -0,0 +1,11 @@ +export default function(/* server */) { + + /* + Seed your development database using your factories. + This data will not be loaded in your tests. + + Make sure to define a factory for each model you want to create. + */ + + // server.createList('post', 10); +} diff --git a/mirage/serializers/application.js b/mirage/serializers/application.js new file mode 100644 index 0000000..37f63f7 --- /dev/null +++ b/mirage/serializers/application.js @@ -0,0 +1,72 @@ +import { RestSerializer } from 'ember-cli-mirage'; +import { dasherize, pluralize } from 'ember-cli-mirage/utils/inflector'; + +export default RestSerializer.extend({ + keyForForeignKey(relationshipName) { + return relationshipName; + }, + keyForRelationshipIds(type) { + return type; + }, + normalize(payload) { + let [type] = Object.keys(payload); + let attrs = payload[type]; + let { belongsToAssociations, hasManyAssociations } = this.registry.schema._registry[type].class.prototype; + + let jsonApiPayload = { + data: { + type: pluralize(type) + } + }; + + Object.keys(attrs).forEach((key) => { + if (key === 'id') { + // records id + jsonApiPayload.data.id = attrs.id; + } else if ( + belongsToAssociations.hasOwnProperty(key) || + hasManyAssociations.hasOwnProperty(key) + ) { + // relationship + if (!jsonApiPayload.data.hasOwnProperty('relationships')) { + jsonApiPayload.data.relationships = {}; + } + + let association = belongsToAssociations.hasOwnProperty(key) ? belongsToAssociations[key] : hasManyAssociations[key]; + let associationType = belongsToAssociations.hasOwnProperty(key) ? 'belongsTo' : 'hasMany'; + let associationModel = association.modelName; + let relationshipObject = {}; + + switch (associationType) { + case 'belongsTo': + relationshipObject.data = { + type: associationModel, + id: attrs[key] + }; + break; + case 'hasMany': + relationshipObject.data = []; + attrs[key].forEach((value) => { + relationshipObject.data.push({ + type: associationModel, + id: value + }); + }); + break; + } + + jsonApiPayload.data.relationships[key] = relationshipObject; + } else { + // attribute + if (!jsonApiPayload.data.hasOwnProperty('attributes')) { + jsonApiPayload.data.attributes = {}; + } + + jsonApiPayload.data.attributes[dasherize(key)] = attrs[key]; + } + }); + + return jsonApiPayload; + }, + serializeIds: 'always' +}); diff --git a/mirage/serializers/poll.js b/mirage/serializers/poll.js new file mode 100644 index 0000000..76850d7 --- /dev/null +++ b/mirage/serializers/poll.js @@ -0,0 +1,6 @@ +import ApplicationSerializer from './application'; + +export default ApplicationSerializer.extend({ + embed: true, + include: ['users'] +}); diff --git a/mirage/utils/encrypt.js b/mirage/utils/encrypt.js new file mode 100644 index 0000000..0b2a4fa --- /dev/null +++ b/mirage/utils/encrypt.js @@ -0,0 +1,28 @@ +/* + * Encrypts all properties in mirage model (created by factory), encrypts them using + * sjcl and encryptionKey property of model as passphrase. + * Unsets encryptionKey property afterwards. + */ +import Ember from 'ember'; +import sjcl from 'sjcl'; + +const { assert, get, isArray, isPresent } = Ember; + +export default function(propertiesToEncrypt, model) { + assert(isArray(propertiesToEncrypt), 'first argument must be an array'); + assert(isPresent(get(model, 'encryptionKey')), 'model must have an encryptionKey property which isn\'t empty'); + + let passphrase = get(model, 'encryptionKey'); + let data = { + encryptionKey: undefined + }; + + propertiesToEncrypt.forEach((propertyToEncrypt) => { + let value = JSON.stringify( + get(model, propertyToEncrypt) + ); + data[propertyToEncrypt] = sjcl.encrypt(passphrase, value); + }); + + model.update(data); +} diff --git a/package.json b/package.json index 3b9a86d..1ee8100 100644 --- a/package.json +++ b/package.json @@ -14,13 +14,11 @@ "test": "ember test" }, "devDependencies": { - "body-parser": "^1.2.0", "broccoli-asset-rev": "^2.4.5", "broccoli-funnel": "^1.0.6", "broccoli-unwatched-tree": "^0.1.1", "chart.js": "2.2.1", "connect-restreamer": "^1.0.1", - "cors": "^2.5.3", "ember-ajax": "^3.0.0", "ember-array-computed-macros": "martndemus/ember-array-computed-macros#3fde9023336d227aa6009060b40b4de77d8b1a9b", "ember-array-helper": "^1.0.1", @@ -45,9 +43,9 @@ "ember-cli-htmlbars-inline-precompile": "^0.4.3", "ember-cli-inject-live-reload": "^1.4.1", "ember-cli-less": "^1.5.3", + "ember-cli-mirage": "^0.3.4", "ember-cli-moment-shim": "3.3.3", "ember-cli-page-object": "1.7.0", - "ember-cli-pretender": "^0.6.0", "ember-cli-qunit": "^4.0.0", "ember-cli-release": "^0.2.9", "ember-cli-sauce": "^1.6.0", @@ -73,10 +71,7 @@ "ember-suave": "^4.0.0", "ember-transition-helper": "0.0.6", "ember-truth-helpers": "^1.2.0", - "express": "^4.8.5", - "glob": "^7.0.5", - "loader.js": "^4.2.3", - "node-phpcgi": "^0.3.5" + "loader.js": "^4.2.3" }, "engines": { "node": "^4.5 || 6.* || >= 7.*" diff --git a/server/.jshintrc b/server/.jshintrc deleted file mode 100644 index c1f2978..0000000 --- a/server/.jshintrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "node": true -} diff --git a/server/index.js b/server/index.js deleted file mode 100644 index d8be33b..0000000 --- a/server/index.js +++ /dev/null @@ -1,41 +0,0 @@ -// To use it create some files under `routes/` -// e.g. `server/routes/ember-hamsters.js` -// -// module.exports = function(app) { -// app.get('/ember-hamsters', function(req, res) { -// res.send('hello'); -// }); -// }; - -module.exports = function(app) { - var bodyParser = require('body-parser'); - var globSync = require('glob').sync; - var mocks = globSync('./mocks/**/*.js', { cwd: __dirname }).map(require); - var proxies = globSync('./proxies/**/*.js', { cwd: __dirname }).map(require); - - /* use cors for testem requests */ - var cors = require('cors'); - app.use(cors()); - - /* use node-phpcgi to handle api */ - var phpcgi = require('node-phpcgi')({ - documentRoot: __dirname.substring(0, __dirname.length - 6) + '/dist', - includePath: '/api/index.php', - entryPoint: '/api/index.php' - }); - app.use(phpcgi); - - app.use(bodyParser.json()); - app.use(bodyParser.urlencoded({ - extended: true - })); - - mocks.forEach(function(route) { route(app); }); - - // proxy expects a stream, but express will have turned - // the request stream into an object because bodyParser - // has run. We have to convert it back to stream: - // https://github.com/nodejitsu/node-http-proxy/issues/180 - app.use(require('connect-restreamer')()); - proxies.forEach(function(route) { route(app); }); -}; diff --git a/tests/.eslintrc.js b/tests/.eslintrc.js index 8542b88..ab751b0 100644 --- a/tests/.eslintrc.js +++ b/tests/.eslintrc.js @@ -15,6 +15,7 @@ module.exports = { pollHasUser: false, pollHasUsersCount: false, pollParticipate: false, + server: false, switchTab: false } }; diff --git a/tests/acceptance/create-a-poll-test.js b/tests/acceptance/create-a-poll-test.js index e519f07..9005364 100644 --- a/tests/acceptance/create-a-poll-test.js +++ b/tests/acceptance/create-a-poll-test.js @@ -1,8 +1,5 @@ -import Ember from 'ember'; -import { module, test } from 'qunit'; -import startApp from '../helpers/start-app'; -import Pretender from 'pretender'; -import serverPostPolls from '../helpers/server-post-polls'; +import { test } from 'qunit'; +import moduleForAcceptance from 'croodle/tests/helpers/module-for-acceptance'; import moment from 'moment'; import pageCreateIndex from 'croodle/tests/pages/create/index'; import pageCreateMeta from 'croodle/tests/pages/create/meta'; @@ -12,61 +9,10 @@ import pageCreateSettings from 'croodle/tests/pages/create/settings'; import pagePollParticipation from 'croodle/tests/pages/poll/participation'; /* jshint proto: true */ -const { run } = Ember; - -let application, server; -let serverAvailable = true; - -const randomString = function(length) { - return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1); -}; - -module('Acceptance | create a poll', { - beforeEach(assert) { +moduleForAcceptance('Acceptance | create a poll', { + beforeEach() { window.localStorage.setItem('locale', 'en'); - - let lastCreatedPoll = {}; - const pollId = randomString(10); - - application = startApp({ assert }); - application.__container__.lookup('adapter:application').__proto__.namespace = ''; - - server = new Pretender(); - - server.post('/polls', - function(request) { - if (!serverAvailable) { - return [503]; - } - - let ret = serverPostPolls(request.requestBody, pollId); - lastCreatedPoll = ret[2]; - return ret; - } - ); - - server.get(`/polls/${pollId}`, - function() { - if (!serverAvailable) { - return [503]; - } - - return [ - 200, - { 'Content-Type': 'application/json' }, - lastCreatedPoll - ]; - } - ); - - moment.locale( - application.__container__.lookup('service:i18n').get('locale') - ); - }, - afterEach() { - server.shutdown(); - - run(application, 'destroy'); + moment.locale('en'); } }); @@ -187,14 +133,16 @@ test('create a default poll', function(assert) { ); // simulate temporate server error - serverAvailable = false; + server.post('/polls', undefined, 503); + pageCreateSettings .save(); andThen(() => { assert.equal(currentPath(), 'create.settings'); - serverAvailable = true; + // simulate server is available again + server.post('/polls'); pageCreateSettings .save(); diff --git a/tests/acceptance/participate-in-a-poll-test.js b/tests/acceptance/participate-in-a-poll-test.js index 7fdf78e..e120c3a 100644 --- a/tests/acceptance/participate-in-a-poll-test.js +++ b/tests/acceptance/participate-in-a-poll-test.js @@ -1,54 +1,23 @@ -import Ember from 'ember'; +import { test } from 'qunit'; import jQuery from 'jquery'; -import { module, test } from 'qunit'; -import startApp from '../helpers/start-app'; -import Pretender from 'pretender'; -import serverGetPolls from '../helpers/server-get-polls'; -import serverPostUsers from '../helpers/server-post-users'; +import moduleForAcceptance from 'croodle/tests/helpers/module-for-acceptance'; /* jshint proto: true */ -const { run } = Ember; - -let application, server; - -module('Acceptance | participate in a poll', { - beforeEach(assert) { +moduleForAcceptance('Acceptance | participate in a poll', { + beforeEach() { window.localStorage.setItem('locale', 'en'); - - application = startApp({ assert }); - application.__container__.lookup('adapter:application').__proto__.namespace = ''; - - server = new Pretender(); - }, - - afterEach() { - server.shutdown(); - - run(application, 'destroy'); } }); test('participate in a default poll', function(assert) { - let id = 'test'; + server.logging = true; + let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; - let nextUserId = 1; - - server.get(`/polls/${id}`, function() { - return serverGetPolls( - { - id - }, encryptionKey - ); + let poll = server.create('poll', { + encryptionKey }); - server.post('/users', - function(request) { - let userId = nextUserId; - nextUserId++; - return serverPostUsers(request.requestBody, userId); - } - ); - visit(`/poll/${id}?encryptionKey=${encryptionKey}`).then(function() { + visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`).then(function() { assert.equal(currentPath(), 'poll.participation', 'poll is redirected to poll.participation'); pollParticipate('Max Meiner', ['yes', 'no']); @@ -84,27 +53,14 @@ test('participate in a default poll', function(assert) { }); test('participate in a poll using freetext', function(assert) { - let id = 'test2'; let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; + let poll = server.create('poll', { + answerType: 'FreeText', + answers: [], + encryptionKey + }); - server.get(`/polls/${id}`, - function() { - return serverGetPolls( - { - id, - answerType: 'FreeText', - answers: [] - }, encryptionKey - ); - } - ); - server.post('/users', - function(request) { - return serverPostUsers(request.requestBody, 1); - } - ); - - visit(`/poll/${id}?encryptionKey=${encryptionKey}`).then(function() { + visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`).then(function() { assert.equal(currentPath(), 'poll.participation'); pollParticipate('Max Manus', ['answer 1', 'answer 2']); @@ -117,26 +73,13 @@ test('participate in a poll using freetext', function(assert) { }); test('participate in a poll which does not force an answer to all options', function(assert) { - let id = 'test'; let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; + let poll = server.create('poll', { + encryptionKey, + forceAnswer: false + }); - server.get(`/polls/${id}`, - function() { - return serverGetPolls( - { - id, - forceAnswer: false - }, encryptionKey - ); - } - ); - server.post('/users', - function(request) { - return serverPostUsers(request.requestBody, 1); - } - ); - - visit(`/poll/${id}/participation?encryptionKey=${encryptionKey}`).then(function() { + visit(`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`).then(function() { assert.equal(currentPath(), 'poll.participation'); pollParticipate('Karl Käfer', ['yes', null]); @@ -149,26 +92,13 @@ test('participate in a poll which does not force an answer to all options', func }); test('participate in a poll which allows anonymous participation', function(assert) { - let id = 'test'; let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; + let poll = server.create('poll', { + anonymousUser: true, + encryptionKey + }); - server.get(`/polls/${id}`, - function() { - return serverGetPolls( - { - id, - anonymousUser: true - }, encryptionKey - ); - } - ); - server.post('/users', - function(request) { - return serverPostUsers(request.requestBody, 1); - } - ); - - visit(`/poll/${id}/participation?encryptionKey=${encryptionKey}`).then(function() { + visit(`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`).then(function() { assert.equal(currentPath(), 'poll.participation'); pollParticipate(null, ['yes', 'no']); @@ -181,26 +111,14 @@ test('participate in a poll which allows anonymous participation', function(asse }); test('network connectivity errors', function(assert) { - let id = 'test'; let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; + let poll = server.create('poll', { + encryptionKey + }); - server.get(`/polls/${id}`, - function() { - return serverGetPolls( - { - id, - anonymousUser: true - }, encryptionKey - ); - } - ); - server.post('/users', - function() { - return [503]; // server temporary not available - } - ); + server.post('/users', undefined, 503); - visit(`/poll/${id}/participation?encryptionKey=${encryptionKey}`).then(function() { + visit(`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`).then(function() { assert.equal(currentPath(), 'poll.participation'); pollParticipate('foo bar', ['yes', 'no']); @@ -210,11 +128,7 @@ test('network connectivity errors', function(assert) { 'user gets notified that saving failed' ); - server.post('/users', - function(request) { - return serverPostUsers(request.requestBody, 1); - } - ); + server.post('/users'); click('#modal-saving-failed-modal button'); andThen(() => { diff --git a/tests/acceptance/view-evaluation-test.js b/tests/acceptance/view-evaluation-test.js index 771004f..fed9d98 100644 --- a/tests/acceptance/view-evaluation-test.js +++ b/tests/acceptance/view-evaluation-test.js @@ -1,46 +1,23 @@ -import Ember from 'ember'; +import { test } from 'qunit'; import jQuery from 'jquery'; -import { module, test } from 'qunit'; -import startApp from 'croodle/tests/helpers/start-app'; -import Pretender from 'pretender'; -import serverGetPolls from '../helpers/server-get-polls'; +import moduleForAcceptance from 'croodle/tests/helpers/module-for-acceptance'; import moment from 'moment'; /* jshint proto: true */ -const { run } = Ember; - -let application, server; - -module('Acceptance | view evaluation', { - beforeEach(assert) { +moduleForAcceptance('Acceptance | view evaluation', { + beforeEach() { window.localStorage.setItem('locale', 'en'); - - application = startApp({ assert }); - application.__container__.lookup('adapter:application').__proto__.namespace = ''; - - server = new Pretender(); - }, - afterEach() { - server.shutdown(); - - run(application, 'destroy'); + moment.locale('en'); } }); test('evaluation summary is not present for poll without participants', function(assert) { - let id = 'test'; let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; - - server.get(`/polls/${id}`, function() { - return serverGetPolls( - { - id, - users: [] - }, encryptionKey - ); + let poll = server.create('poll', { + encryptionKey }); - visit(`/poll/${id}?encryptionKey=${encryptionKey}`); + visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`); andThen(function() { assert.equal(currentPath(), 'poll.participation'); @@ -53,76 +30,69 @@ test('evaluation summary is not present for poll without participants', function }); test('evaluation is correct for FindADate', function(assert) { - let id = 'test'; let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; - - server.get(`/polls/${id}`, function() { - return serverGetPolls( + let user1 = server.create('user', { + creationDate: '2015-01-01T00:00:00.000Z', + encryptionKey, + name: 'Maximilian', + selections: [ { - id, - answers: [ - { - type: 'yes', - labelTranslation: 'answerTypes.yes.label', - icon: 'glyphicon glyphicon-thumbs-up', - label: 'Yes' - }, - { - type: 'no', - labelTranslation: 'answerTypes.no.label', - icon: 'glyphicon glyphicon-thumbs-down', - label: 'No' - } - ], - options: [ - { title: '2015-12-12' }, - { title: '2016-01-01' } - ], - users: [ - { - id: `${id}_0`, - name: 'Maximilian', - selections: [ - { - type: 'yes', - labelTranslation: 'answerTypes.yes.label', - icon: 'glyphicon glyphicon-thumbs-up', - label: 'Yes' - }, - { - type: 'yes', - labelTranslation: 'answerTypes.yes.label', - icon: 'glyphicon glyphicon-thumbs-up', - label: 'Yes' - } - ], - creationDate: '2015-01-01T00:00:00.000Z' - }, - { - id: `${id}_1`, - name: 'Peter', - selections: [ - { - type: 'no', - labelTranslation: 'answerTypes.no.label', - icon: 'glyphicon glyphicon-thumbs-down', - label: 'No' - }, - { - type: 'yes', - labelTranslation: 'answerTypes.yes.label', - icon: 'glyphicon glyphicon-thumbs-up', - label: 'Yes' - } - ], - creationDate: '2015-08-01T00:00:00.000Z' - } - ] - }, encryptionKey - ); + type: 'yes', + labelTranslation: 'answerTypes.yes.label', + icon: 'glyphicon glyphicon-thumbs-up', + label: 'Yes' + }, + { + type: 'yes', + labelTranslation: 'answerTypes.yes.label', + icon: 'glyphicon glyphicon-thumbs-up', + label: 'Yes' + } + ] + }); + let user2 = server.create('user', { + creationDate: '2015-08-01T00:00:00.000Z', + encryptionKey, + name: 'Peter', + selections: [ + { + type: 'no', + labelTranslation: 'answerTypes.no.label', + icon: 'glyphicon glyphicon-thumbs-down', + label: 'No' + }, + { + type: 'yes', + labelTranslation: 'answerTypes.yes.label', + icon: 'glyphicon glyphicon-thumbs-up', + label: 'Yes' + } + ] + }); + let poll = server.create('poll', { + answers: [ + { + type: 'yes', + labelTranslation: 'answerTypes.yes.label', + icon: 'glyphicon glyphicon-thumbs-up', + label: 'Yes' + }, + { + type: 'no', + labelTranslation: 'answerTypes.no.label', + icon: 'glyphicon glyphicon-thumbs-down', + label: 'No' + } + ], + encryptionKey, + options: [ + { title: '2015-12-12' }, + { title: '2016-01-01' } + ], + users: [user1, user2] }); - visit(`/poll/${id}/evaluation?encryptionKey=${encryptionKey}`); + visit(`/poll/${poll.id}/evaluation?encryptionKey=${encryptionKey}`); andThen(function() { assert.equal(currentPath(), 'poll.evaluation'); @@ -148,77 +118,70 @@ test('evaluation is correct for FindADate', function(assert) { }); test('evaluation is correct for MakeAPoll', function(assert) { - let id = 'test'; let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; - - server.get(`/polls/${id}`, function() { - return serverGetPolls( + let user1 = server.create('user', { + creationDate: '2015-01-01T00:00:00.000Z', + encryptionKey, + name: 'Maximilian', + selections: [ { - id, - answers: [ - { - type: 'yes', - labelTranslation: 'answerTypes.yes.label', - icon: 'glyphicon glyphicon-thumbs-up', - label: 'Yes' - }, - { - type: 'no', - labelTranslation: 'answerTypes.no.label', - icon: 'glyphicon glyphicon-thumbs-down', - label: 'No' - } - ], - options: [ - { title: 'first option' }, - { title: 'second option' } - ], - pollType: 'MakeAPoll', - users: [ - { - id: `${id}_0`, - name: 'Maximilian', - selections: [ - { - type: 'yes', - labelTranslation: 'answerTypes.yes.label', - icon: 'glyphicon glyphicon-thumbs-up', - label: 'Yes' - }, - { - type: 'yes', - labelTranslation: 'answerTypes.yes.label', - icon: 'glyphicon glyphicon-thumbs-up', - label: 'Yes' - } - ], - creationDate: '2015-01-01T00:00:00.000Z' - }, - { - id: `${id}_1`, - name: 'Peter', - selections: [ - { - type: 'no', - labelTranslation: 'answerTypes.no.label', - icon: 'glyphicon glyphicon-thumbs-down', - label: 'No' - }, - { - type: 'yes', - labelTranslation: 'answerTypes.yes.label', - icon: 'glyphicon glyphicon-thumbs-up', - label: 'Yes' - } - ], - creationDate: '2015-08-01T00:00:00.000Z' - } - ] - }, encryptionKey - ); + type: 'yes', + labelTranslation: 'answerTypes.yes.label', + icon: 'glyphicon glyphicon-thumbs-up', + label: 'Yes' + }, + { + type: 'yes', + labelTranslation: 'answerTypes.yes.label', + icon: 'glyphicon glyphicon-thumbs-up', + label: 'Yes' + } + ] + }); + let user2 = server.create('user', { + creationDate: '2015-08-01T00:00:00.000Z', + encryptionKey, + name: 'Peter', + selections: [ + { + type: 'no', + labelTranslation: 'answerTypes.no.label', + icon: 'glyphicon glyphicon-thumbs-down', + label: 'No' + }, + { + type: 'yes', + labelTranslation: 'answerTypes.yes.label', + icon: 'glyphicon glyphicon-thumbs-up', + label: 'Yes' + } + ] + }); + let poll = server.create('poll', { + answers: [ + { + type: 'yes', + labelTranslation: 'answerTypes.yes.label', + icon: 'glyphicon glyphicon-thumbs-up', + label: 'Yes' + }, + { + type: 'no', + labelTranslation: 'answerTypes.no.label', + icon: 'glyphicon glyphicon-thumbs-down', + label: 'No' + } + ], + encryptionKey, + options: [ + { title: 'first option' }, + { title: 'second option' } + ], + pollType: 'MakeAPoll', + users: [user1, user2] }); - visit(`/poll/${id}/evaluation?encryptionKey=${encryptionKey}`); + visit(`/poll/${poll.id}/evaluation?encryptionKey=${encryptionKey}`); andThen(function() { assert.equal(currentPath(), 'poll.evaluation'); @@ -263,14 +226,33 @@ test('evaluation is correct for MakeAPoll', function(assert) { }); test('could open evaluation by tab from poll participation', function(assert) { - let id = 'test'; let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; - - server.get(`/polls/${id}`, function() { - return serverGetPolls( + let poll = server.create('poll', { + answers: [ { - id, - answers: [ + type: 'yes', + labelTranslation: 'answerTypes.yes.label', + icon: 'glyphicon glyphicon-thumbs-up', + label: 'Yes' + }, + { + type: 'no', + labelTranslation: 'answerTypes.no.label', + icon: 'glyphicon glyphicon-thumbs-down', + label: 'No' + } + ], + encryptionKey, + options: [ + { title: '2015-12-12' }, + { title: '2016-01-01' } + ], + users: [ + server.create('user', { + creationDate: '2015-01-01T00:00:00.000Z', + encryptionKey, + name: 'Maximilian', + selections: [ { type: 'yes', labelTranslation: 'answerTypes.yes.label', @@ -278,61 +260,36 @@ test('could open evaluation by tab from poll participation', function(assert) { label: 'Yes' }, { - type: 'no', - labelTranslation: 'answerTypes.no.label', - icon: 'glyphicon glyphicon-thumbs-down', - label: 'No' - } - ], - options: [ - { title: '2015-12-12' }, - { title: '2016-01-01' } - ], - users: [ - { - id: `${id}_0`, - name: 'Maximilian', - selections: [ - { - type: 'yes', - labelTranslation: 'answerTypes.yes.label', - icon: 'glyphicon glyphicon-thumbs-up', - label: 'Yes' - }, - { - type: 'yes', - labelTranslation: 'answerTypes.yes.label', - icon: 'glyphicon glyphicon-thumbs-up', - label: 'Yes' - } - ], - creationDate: '2015-01-01T00:00:00.000Z' - }, - { - id: `${id}_1`, - name: 'Peter', - selections: [ - { - type: 'yes', - labelTranslation: 'answerTypes.yes.label', - icon: 'glyphicon glyphicon-thumbs-up', - label: 'Yes' - }, - { - id: 'no', - labelTranslation: 'answerTypes.yes.label', - icon: 'glyphicon glyphicon-thumbs-up', - label: 'Yes' - } - ], - creationDate: '2015-08-01T00:00:00.000Z' + type: 'yes', + labelTranslation: 'answerTypes.yes.label', + icon: 'glyphicon glyphicon-thumbs-up', + label: 'Yes' } ] - }, encryptionKey - ); + }), + server.create('user', { + creationDate: '2015-08-01T00:00:00.000Z', + encryptionKey, + name: 'Peter', + selections: [ + { + type: 'yes', + labelTranslation: 'answerTypes.yes.label', + icon: 'glyphicon glyphicon-thumbs-up', + label: 'Yes' + }, + { + id: 'no', + labelTranslation: 'answerTypes.yes.label', + icon: 'glyphicon glyphicon-thumbs-up', + label: 'Yes' + } + ] + }) + ] }); - visit(`/poll/${id}?encryptionKey=${encryptionKey}`); + visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`); andThen(function() { assert.equal(currentPath(), 'poll.participation'); diff --git a/tests/acceptance/view-poll-test.js b/tests/acceptance/view-poll-test.js index 01ed3b5..2bf1018 100644 --- a/tests/acceptance/view-poll-test.js +++ b/tests/acceptance/view-poll-test.js @@ -1,40 +1,24 @@ import Ember from 'ember'; -import { module, test } from 'qunit'; -import startApp from 'croodle/tests/helpers/start-app'; -import Pretender from 'pretender'; -import serverGetPolls from '../helpers/server-get-polls'; +import { test } from 'qunit'; +import moduleForAcceptance from 'croodle/tests/helpers/module-for-acceptance'; import pageParticipation from 'croodle/tests/pages/poll/participation'; +import moment from 'moment'; /* jshint proto: true */ -/* global jstz, moment */ +/* global jstz */ const { run } = Ember; -let application, server; - -module('Acceptance | view poll', { - beforeEach(assert) { +moduleForAcceptance('Acceptance | view poll', { + beforeEach() { window.localStorage.setItem('locale', 'en'); - - application = startApp({ assert }); - application.__container__.lookup('adapter:application').__proto__.namespace = ''; - - server = new Pretender(); - }, - afterEach() { - server.shutdown(); - - run(application, 'destroy'); + moment.locale('en'); } }); test('poll url', function(assert) { - let id = 'test'; let encryptionKey = 'abcdefghijklmnopqrstuvwxyz012345789'; - let pollUrl = `/poll/${id}?encryptionKey=${encryptionKey}`; - - server.get(`/polls/${id}`, function() { - return serverGetPolls({ id }, encryptionKey); - }); + let poll = server.create('poll', { encryptionKey }); + let pollUrl = `/poll/${poll.id}?encryptionKey=${encryptionKey}`; visit(pollUrl); andThen(function() { @@ -56,22 +40,16 @@ test('poll url', function(assert) { }); test('view a poll with dates', function(assert) { - let id = 'test'; let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; - - server.get(`/polls/${id}`, function() { - return serverGetPolls( - { - id, - options: [ - { title: '2015-12-12' }, - { title: '2016-01-01' } - ] - }, encryptionKey - ); + let poll = server.create('poll', { + encryptionKey, + options: [ + { title: '2015-12-12' }, + { title: '2016-01-01' } + ] }); - visit(`/poll/${id}?encryptionKey=${encryptionKey}`).then(function() { + visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`).then(function() { assert.deepEqual( pageParticipation.options().labels, [ @@ -83,26 +61,20 @@ test('view a poll with dates', function(assert) { }); test('view a poll with dates and times', function(assert) { - const id = 'test'; - const encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; - const timezone = jstz.determine().name(); - - server.get(`/polls/${id}`, function() { - return serverGetPolls( - { - id, - isDateTime: true, - options: [ - { title: '2015-12-12T11:11:00.000Z' }, - { title: '2015-12-12T13:13:00.000Z' }, - { title: '2016-01-01T11:11:00.000Z' } - ], - timezone - }, encryptionKey - ); + let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; + let timezone = jstz.determine().name(); + let poll = server.create('poll', { + encryptionKey, + isDateTime: true, + options: [ + { title: '2015-12-12T11:11:00.000Z' }, + { title: '2015-12-12T13:13:00.000Z' }, + { title: '2016-01-01T11:11:00.000Z' } + ], + timezone }); - visit(`/poll/${id}?encryptionKey=${encryptionKey}`).then(function() { + visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`).then(function() { assert.deepEqual( pageParticipation.options().labels, [ @@ -118,33 +90,21 @@ test('view a poll with dates and times', function(assert) { }); test('view a poll while timezone differs from the one poll got created in and choose local timezone', function(assert) { - const id = 'test'; - const encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; - const timezoneLocal = jstz.determine().name(); - let timezonePoll; - - if (timezoneLocal !== 'America/Caracas') { - timezonePoll = 'America/Caracas'; - } else { - timezonePoll = 'Europe/Moscow'; - } - - server.get(`/polls/${id}`, function() { - return serverGetPolls( - { - id, - isDateTime: true, - options: [ - { title: '2015-12-12T11:11:00.000Z' }, - { title: '2016-01-01T11:11:00.000Z' } - ], - timezone: timezonePoll - }, encryptionKey - ); + let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; + let timezoneUser = jstz.determine().name(); + let timezonePoll = timezoneUser !== 'America/Caracas' ? 'America/Caracas' : 'Europe/Moscow'; + let poll = server.create('poll', { + encryptionKey, + isDateTime: true, + options: [ + { title: '2015-12-12T11:11:00.000Z' }, + { title: '2016-01-01T11:11:00.000Z' } + ], + timezone: timezonePoll }); - visit(`/poll/${id}?encryptionKey=${encryptionKey}`).then(function() { - run.next(function() { + visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`).then(function() { + run.next(() => { assert.ok( find('#modal-choose-timezone-modal').is(':visible'), 'user gets asked which timezone should be used' @@ -152,16 +112,16 @@ test('view a poll while timezone differs from the one poll got created in and ch click('#modal-choose-timezone-modal button.use-local-timezone'); - andThen(function() { + andThen(() => { assert.deepEqual( pageParticipation.options().labels, [ - moment.tz('2015-12-12T11:11:00.000Z', timezoneLocal).locale('en').format('LLLL'), - moment.tz('2016-01-01T11:11:00.000Z', timezoneLocal).locale('en').format('LLLL') + moment.tz('2015-12-12T11:11:00.000Z', timezoneUser).locale('en').format('LLLL'), + moment.tz('2016-01-01T11:11:00.000Z', timezoneUser).locale('en').format('LLLL') ] ); - run.next(function() { + run.next(() => { assert.notOk( find('#modal-choose-timezone-modal').is(':visible'), 'modal is closed' @@ -173,32 +133,20 @@ test('view a poll while timezone differs from the one poll got created in and ch }); test('view a poll while timezone differs from the one poll got created in and choose poll timezone', function(assert) { - const id = 'test'; - const encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; - const timezoneLocal = jstz.determine().name(); - let timezonePoll; - - if (timezoneLocal !== 'America/Caracas') { - timezonePoll = 'America/Caracas'; - } else { - timezonePoll = 'Europe/Moscow'; - } - - server.get(`/polls/${id}`, function() { - return serverGetPolls( - { - id, - isDateTime: true, - options: [ - { title: '2015-12-12T11:11:00.000Z' }, - { title: '2016-01-01T11:11:00.000Z' } - ], - timezone: timezonePoll - }, encryptionKey - ); + let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789'; + let timezoneUser = jstz.determine().name(); + let timezonePoll = timezoneUser !== 'America/Caracas' ? 'America/Caracas' : 'Europe/Moscow'; + let poll = server.create('poll', { + encryptionKey, + isDateTime: true, + options: [ + { title: '2015-12-12T11:11:00.000Z' }, + { title: '2016-01-01T11:11:00.000Z' } + ], + timezone: timezonePoll }); - visit(`/poll/${id}?encryptionKey=${encryptionKey}`).then(function() { + visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`).then(function() { run.next(function() { assert.ok( diff --git a/tests/helpers/server-get-polls.js b/tests/helpers/server-get-polls.js deleted file mode 100644 index acbdee8..0000000 --- a/tests/helpers/server-get-polls.js +++ /dev/null @@ -1,86 +0,0 @@ -import Ember from 'ember'; -import sjcl from 'sjcl'; - -export default function(attr, key) { - const defaultAttr = { - id: 'test', - title: 'default title', - description: 'default description', - pollType: 'FindADate', - answerType: 'YesNo', - answers: [ - { - type: 'yes', - labelTranslation: 'answerTypes.yes.label', - icon: 'glyphicon glyphicon-thumbs-up', - label: 'Ja' - }, - { - type: 'no', - labelTranslation: 'answerTypes.no.label', - icon: 'glyphicon glyphicon-thumbs-down', - label: 'Nein' - } - ], - options: [ - { - title: '2017-12-24' - }, - { - title: '2018-01-01' - } - ], - creationDate: '2015-04-01T11:11:11.111Z', - forceAnswer: true, - anonymousUser: false, - isDateTime: false, - users: [], - expirationDate: '', - timezone: '', - version: 'v0.3' - }; - - const encrypt = function(prop) { - return sjcl.encrypt( - key, - JSON.stringify(prop) - ); - }; - - let data = Ember.merge(defaultAttr, attr); - - const users = data.users.map(function(user, index) { - return { - id: `${data.id}_${index}`, - creationDate: encrypt(user.creationDate), - name: encrypt(user.name), - poll: data.id, - selections: encrypt(user.selections), - version: data.version - }; - }); - - return [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify({ - poll: { - id: data.id, - title: encrypt(data.title), - description: encrypt(data.description), - pollType: encrypt(data.pollType), - answerType: encrypt(data.answerType), - answers: encrypt(data.answers), - options: encrypt(data.options), - creationDate: encrypt(data.creationDate), - forceAnswer: encrypt(data.forceAnswer), - anonymousUser: encrypt(data.anonymousUser), - isDateTime: encrypt(data.isDateTime), - timezone: encrypt(data.timezone), - expirationDate: encrypt(data.expirationDate), - users, - version: data.version - } - }) - ]; -} diff --git a/tests/helpers/server-post-polls.js b/tests/helpers/server-post-polls.js deleted file mode 100644 index 98eb56d..0000000 --- a/tests/helpers/server-post-polls.js +++ /dev/null @@ -1,9 +0,0 @@ -export default function(requestBody, id) { - let poll = JSON.parse(requestBody); - poll.poll.id = id; - return [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(poll) - ]; -} diff --git a/tests/helpers/server-post-users.js b/tests/helpers/server-post-users.js deleted file mode 100644 index ab9e67c..0000000 --- a/tests/helpers/server-post-users.js +++ /dev/null @@ -1,13 +0,0 @@ -export default function(requestBody, id) { - if (id === null) { - id = 1; - } - - let poll = JSON.parse(requestBody); - poll.user.id = id; - return [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(poll) - ]; -} diff --git a/tests/integration/create-a-poll-test.js b/tests/integration/create-a-poll-test.js index 87572d6..3681d92 100644 --- a/tests/integration/create-a-poll-test.js +++ b/tests/integration/create-a-poll-test.js @@ -1,6 +1,5 @@ -import Ember from 'ember'; -import { module, test } from 'qunit'; -import startApp from '../helpers/start-app'; +import { test } from 'qunit'; +import moduleForAcceptance from 'croodle/tests/helpers/module-for-acceptance'; import moment from 'moment'; import pageCreateIndex from 'croodle/tests/pages/create/index'; import pageCreateMeta from 'croodle/tests/pages/create/meta'; @@ -10,19 +9,10 @@ import pageCreateSettings from 'croodle/tests/pages/create/settings'; import pagePollParticipation from 'croodle/tests/pages/poll/participation'; /* jshint proto: true */ -let application; - -module('Integration', { - beforeEach(assert) { +moduleForAcceptance('Integration', { + beforeEach() { window.localStorage.setItem('locale', 'en'); - - application = startApp({ assert }); - moment.locale( - application.__container__.lookup('service:i18n').get('locale') - ); - }, - afterEach() { - Ember.run(application, 'destroy'); + moment.locale('en'); } }); diff --git a/tests/integration/legacy-support-test.js b/tests/integration/legacy-support-test.js index b4d5e46..918e1af 100644 --- a/tests/integration/legacy-support-test.js +++ b/tests/integration/legacy-support-test.js @@ -1,50 +1,49 @@ -import Ember from 'ember'; -import { module, test } from 'qunit'; -import startApp from 'croodle/tests/helpers/start-app'; +import { test } from 'qunit'; +import moduleForAcceptance from 'croodle/tests/helpers/module-for-acceptance'; +import moment from 'moment'; import pagePollParticipation from 'croodle/tests/pages/poll/participation'; -/* global moment */ /* jshint proto: true */ -let application; - -module('Integration | legacy support', { - beforeEach(assert) { +moduleForAcceptance('Integration | legacy support', { + beforeEach() { window.localStorage.setItem('locale', 'en'); - - application = startApp({ assert }); - moment.locale( - application.__container__.lookup('service:i18n').get('locale') - ); - }, - - afterEach() { - Ember.run(application, 'destroy'); + moment.locale('en'); } }); test('show a default poll created with v0.3.0', function(assert) { - const id = 'JlHpRs0Pzi'; const encryptionKey = '5MKFuNTKILUXw6RuqkAw6ooZw4k3mWWx98ZQw8vH'; - const timezone = 'Europe/Berlin'; - visit(`/poll/${id}?encryptionKey=${encryptionKey}`); + let poll = server.create('poll', { + encryptionKey, + // property 'id' of answers has been renamed to 'type' in v0.4.0 + answers: [{ 'id': 'yes','labelTranslation': 'answerTypes.yes.label','icon': 'glyphicon glyphicon-thumbs-up','label': 'Ja' },{ 'id': 'maybe','labelTranslation': 'answerTypes.maybe.label','icon': 'glyphicon glyphicon-hand-right','label': 'Vielleicht' },{ 'id': 'no','labelTranslation': 'answerTypes.no.label','icon': 'glyphicon glyphicon-thumbs-down','label': 'Nein' }], + options: [{ 'title': '2015-12-24T17:00:00.000Z' },{ 'title': '2015-12-24T19:00:00.000Z' },{ 'title': '2015-12-31T22:59:00.000Z' }], + users: [ + server.create('user', { + encryptionKey, + name: 'Fritz Bauer', + // selections.value was renamed to selections.label + // selections.id was renamed to selections.type + selections: [{ 'value': { 'id': 'yes','labelTranslation': 'answerTypes.yes.label','icon': 'glyphicon glyphicon-thumbs-up','label': 'Ja' } },{ 'value': { 'id': 'no','labelTranslation': 'answerTypes.no.label','icon': 'glyphicon glyphicon-thumbs-down','label': 'Nein' } },{ 'value': { 'id': 'no','labelTranslation': 'answerTypes.no.label','icon': 'glyphicon glyphicon-thumbs-down','label': 'Nein' } }], + // version tag had have wrong format + version: 'v0.3-0' + }) + ], + // version tag had have wrong format + version: 'v0.3-0' + }); + + visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`); andThen(function() { assert.equal(currentPath(), 'poll.participation'); - assert.equal( - pagePollParticipation.title, - 'default poll created with v0.3.0' - ); - assert.equal( - pagePollParticipation.description, - 'used for integration tests' - ); assert.deepEqual( pagePollParticipation.options().labels, [ - moment.tz('2015-12-24T17:00:00.000Z', timezone).format('LLLL'), - moment.tz('2015-12-24T19:00:00.000Z', timezone).format('LT'), - moment.tz('2015-12-31T22:59:00.000Z', timezone).format('LLLL') + moment('2015-12-24T17:00:00.000Z').format('LLLL'), + moment('2015-12-24T19:00:00.000Z').format('LT'), + moment('2015-12-31T22:59:00.000Z').format('LLLL') ] ); assert.deepEqual( @@ -69,14 +68,6 @@ test('show a default poll created with v0.3.0', function(assert) { t('answerTypes.no.label') ] ); - pollHasUser(assert, - 'Lothar Hermann', - [ - t('answerTypes.maybe.label'), - t('answerTypes.yes.label'), - t('answerTypes.no.label') - ] - ); switchTab('participation'); @@ -101,21 +92,32 @@ test('show a default poll created with v0.3.0', function(assert) { }); }); -test('find a poll using free text created with v0.3.0', function(assert) { - const id = 'PjW3XwbuRc'; - const encryptionKey = 'Rre6dAGOYLW9gYKOP4LhX7Qwfhe5Th3je0uKDtyy'; +test('show a poll using free text created with v0.3.0', function(assert) { + let encryptionKey = 'Rre6dAGOYLW9gYKOP4LhX7Qwfhe5Th3je0uKDtyy'; + let poll = server.create('poll', { + encryptionKey, + answerType: 'FreeText', + answers: [], + options: [{ 'title': 'apple pie' }, { 'title': 'pecan pie' }, { 'title': 'plum pie' }], + pollType: 'MakeAPoll', + users: [ + server.create('user', { + encryptionKey, + name: 'Paul Levi', + // selections.value was renamed to selections.label + // selections.id was renamed to selections.type + selections: [{ 'value': 'would be great!' }, { 'value': 'no way' }, { 'value': 'if I had to' }], + // version tag had have wrong format + version: 'v0.3-0' + }) + ], + // version tag had have wrong format + version: 'v0.3-0' + }); - visit(`/poll/${id}?encryptionKey=${encryptionKey}`); + visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`); andThen(function() { - assert.equal( - pagePollParticipation.title, - 'Which cake for birthday?' - ); - assert.equal( - pagePollParticipation.description, - '' - ); assert.deepEqual( pagePollParticipation.options().labels, [ diff --git a/tests/integration/mirage-test.js b/tests/integration/mirage-test.js new file mode 100644 index 0000000..f137449 --- /dev/null +++ b/tests/integration/mirage-test.js @@ -0,0 +1,35 @@ +import { module, test } from 'qunit'; +import { startMirage } from 'croodle/initializers/ember-cli-mirage'; +import sjcl from 'sjcl'; +import Ember from 'ember'; + +const { get } = Ember; + +module('Integration | Mirage api mocking', { + beforeEach() { + this.server = startMirage(); + }, + afterEach() { + this.server.shutdown(); + } +}); + +test('poll factory | encrypts properties', function(assert) { + let encryptionKey = 'abc'; + let poll = this.server.create('poll', { + description: 'bar', + encryptionKey, + title: 'foo' + }); + assert.equal(JSON.parse(sjcl.decrypt(encryptionKey, get(poll, 'title'))), 'foo'); + assert.equal(JSON.parse(sjcl.decrypt(encryptionKey, get(poll, 'description'))), 'bar'); +}); + +test('user factory | encrypts properties', function(assert) { + let encryptionKey = 'abc'; + let user = this.server.create('user', { + encryptionKey, + name: 'foo' + }); + assert.equal(JSON.parse(sjcl.decrypt(encryptionKey, get(user, 'name'))), 'foo'); +}); diff --git a/yarn.lock b/yarn.lock index 0a9aefb..39a3dc2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1164,7 +1164,7 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.7" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.7.tgz#ddb048e50d9482790094c13eb3fcfc833ce7ab46" -body-parser@^1.12.3, body-parser@^1.2.0: +body-parser@^1.12.3: version "1.17.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.2.tgz#f8892abc8f9e627d42aedafbca66bf5ab99104ee" dependencies: @@ -1420,7 +1420,7 @@ broccoli-funnel@^1.0.0, broccoli-funnel@^1.0.1, broccoli-funnel@^1.0.6: symlink-or-copy "^1.0.0" walk-sync "^0.3.1" -broccoli-funnel@^1.1.0, broccoli-funnel@^1.2.0: +broccoli-funnel@^1.0.2, broccoli-funnel@^1.1.0, broccoli-funnel@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/broccoli-funnel/-/broccoli-funnel-1.2.0.tgz#cddc3afc5ff1685a8023488fff74ce6fb5a51296" dependencies: @@ -1489,7 +1489,7 @@ broccoli-lint-eslint@^3.3.0: lodash.defaultsdeep "^4.6.0" md5-hex "^2.0.0" -broccoli-merge-trees@^1.0.0, broccoli-merge-trees@^1.1.1, broccoli-merge-trees@^1.1.2: +broccoli-merge-trees@^1.0.0, broccoli-merge-trees@^1.1.0, broccoli-merge-trees@^1.1.1, broccoli-merge-trees@^1.1.2: version "1.2.4" resolved "https://registry.yarnpkg.com/broccoli-merge-trees/-/broccoli-merge-trees-1.2.4.tgz#a001519bb5067f06589d91afa2942445a2d0fdb5" dependencies: @@ -1516,7 +1516,7 @@ broccoli-middleware@^1.0.0: handlebars "^4.0.4" mime "^1.2.11" -broccoli-persistent-filter@^1.0.0, broccoli-persistent-filter@^1.4.0, broccoli-persistent-filter@^1.4.2: +broccoli-persistent-filter@^1.0.0, broccoli-persistent-filter@^1.1.5, broccoli-persistent-filter@^1.4.0, broccoli-persistent-filter@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/broccoli-persistent-filter/-/broccoli-persistent-filter-1.4.2.tgz#17af1278a25ff2556f9d7d23e115accfad3a7ce7" dependencies: @@ -1623,7 +1623,7 @@ broccoli-stew@^1.2.0, broccoli-stew@^1.3.3: rsvp "^3.0.16" walk-sync "^0.3.0" -broccoli-stew@^1.4.0: +broccoli-stew@^1.4.0, broccoli-stew@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/broccoli-stew/-/broccoli-stew-1.5.0.tgz#d7af8c18511dce510e49d308a62e5977f461883c" dependencies: @@ -1642,6 +1642,13 @@ broccoli-stew@^1.4.0: symlink-or-copy "^1.1.8" walk-sync "^0.3.0" +broccoli-string-replace@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/broccoli-string-replace/-/broccoli-string-replace-0.1.2.tgz#1ed92f85680af8d503023925e754e4e33676b91f" + dependencies: + broccoli-persistent-filter "^1.1.5" + minimatch "^3.0.3" + broccoli-uglify-sourcemap@^1.0.0: version "1.5.1" resolved "https://registry.yarnpkg.com/broccoli-uglify-sourcemap/-/broccoli-uglify-sourcemap-1.5.1.tgz#9fd2e87f1c177b11a758e73c3a11d6a03d90d086" @@ -2334,13 +2341,6 @@ core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" -cors@^2.5.3: - version "2.8.4" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.4.tgz#2bd381f2eb201020105cd50ea59da63090694686" - dependencies: - object-assign "^4" - vary "^1" - crc32-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-2.0.0.tgz#e3cdd3b4df3168dd74e3de3fbbcb7b297fe908f4" @@ -3002,6 +3002,25 @@ ember-cli-lodash-subset@^1.0.11, ember-cli-lodash-subset@^1.0.7: version "1.0.12" resolved "https://registry.yarnpkg.com/ember-cli-lodash-subset/-/ember-cli-lodash-subset-1.0.12.tgz#af2e77eba5dcb0d77f3308d3a6fd7d3450f6e537" +ember-cli-mirage@^0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/ember-cli-mirage/-/ember-cli-mirage-0.3.4.tgz#eeb9d6e02c0c49c81915762178bab9a42d86ada8" + dependencies: + broccoli-funnel "^1.0.2" + broccoli-merge-trees "^1.1.0" + broccoli-stew "^1.5.0" + chalk "^1.1.1" + ember-cli-babel "^5.1.7" + ember-cli-node-assets "^0.1.4" + ember-get-config "0.2.1" + ember-inflector "^2.0.0" + ember-lodash "^4.17.3" + exists-sync "0.0.3" + fake-xml-http-request "^1.4.0" + faker "^3.0.0" + pretender "^1.4.2" + route-recognizer "^0.2.3" + ember-cli-moment-shim@3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/ember-cli-moment-shim/-/ember-cli-moment-shim-3.3.3.tgz#f0609c6ff606287c3eeee717163310331e0e9397" @@ -3018,7 +3037,7 @@ ember-cli-moment-shim@3.3.3: moment "^2.18.1" moment-timezone "~0.5.11" -ember-cli-node-assets@^0.1.2: +ember-cli-node-assets@^0.1.2, ember-cli-node-assets@^0.1.4: version "0.1.6" resolved "https://registry.yarnpkg.com/ember-cli-node-assets/-/ember-cli-node-assets-0.1.6.tgz#6488a2949048c801ad6d9e33753c7bce32fc1146" dependencies: @@ -3060,10 +3079,6 @@ ember-cli-preprocess-registry@^3.1.0: process-relative-require "^1.0.0" silent-error "^1.0.0" -ember-cli-pretender@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/ember-cli-pretender/-/ember-cli-pretender-0.6.0.tgz#7525ffa3081b8ba7b0791f24f1f229d83e87bd1e" - ember-cli-qunit@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/ember-cli-qunit/-/ember-cli-qunit-4.0.0.tgz#1f0022469a5bd64f627b8102880a25e94e533a3b" @@ -3326,6 +3341,13 @@ ember-factory-for-polyfill@^1.1.0: ember-cli-babel "^5.1.7" ember-cli-version-checker "^1.2.0" +ember-get-config@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ember-get-config/-/ember-get-config-0.2.1.tgz#a1325cceefcb4534c78fc6ccb2be87a3feda6817" + dependencies: + broccoli-file-creator "^1.1.1" + ember-cli-babel "^5.1.6" + ember-getowner-polyfill@^1.0.1: version "1.2.3" resolved "https://registry.yarnpkg.com/ember-getowner-polyfill/-/ember-getowner-polyfill-1.2.3.tgz#ea70f4a48b1c05b91056371d1878bbafe018222e" @@ -3369,6 +3391,17 @@ ember-load-initializers@^1.0.0: dependencies: ember-cli-babel "^6.0.0-beta.7" +ember-lodash@^4.17.3: + version "4.17.5" + resolved "https://registry.yarnpkg.com/ember-lodash/-/ember-lodash-4.17.5.tgz#bda557402facae144567d1ef530b3de7c38bcde1" + dependencies: + broccoli-debug "^0.6.1" + broccoli-funnel "^1.1.0" + broccoli-merge-trees "^2.0.0" + broccoli-string-replace "^0.1.1" + ember-cli-babel "^6.4.1" + lodash-es "^4.17.4" + ember-macro-helpers@^0.14.1: version "0.14.5" resolved "https://registry.yarnpkg.com/ember-macro-helpers/-/ember-macro-helpers-0.14.5.tgz#52b267db835c2dab25badfd44187e67d1f9c9e2c" @@ -3932,39 +3965,6 @@ express@^4.10.7, express@^4.12.3: utils-merge "1.0.0" vary "~1.1.0" -express@^4.8.5: - version "4.15.3" - resolved "https://registry.yarnpkg.com/express/-/express-4.15.3.tgz#bab65d0f03aa80c358408972fc700f916944b662" - dependencies: - accepts "~1.3.3" - array-flatten "1.1.1" - content-disposition "0.5.2" - content-type "~1.0.2" - cookie "0.3.1" - cookie-signature "1.0.6" - debug "2.6.7" - depd "~1.1.0" - encodeurl "~1.0.1" - escape-html "~1.0.3" - etag "~1.8.0" - finalhandler "~1.0.3" - fresh "0.5.0" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.1" - path-to-regexp "0.1.7" - proxy-addr "~1.1.4" - qs "6.4.0" - range-parser "~1.2.0" - send "0.15.3" - serve-static "1.12.3" - setprototypeof "1.0.3" - statuses "~1.3.1" - type-is "~1.6.15" - utils-merge "1.0.0" - vary "~1.1.1" - extend@3: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -3995,6 +3995,14 @@ eyes@0.1.x: version "0.1.8" resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" +fake-xml-http-request@^1.4.0, fake-xml-http-request@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/fake-xml-http-request/-/fake-xml-http-request-1.6.0.tgz#bd0ac79ae3e2660098282048a12c730a6f64d550" + +faker@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/faker/-/faker-3.1.0.tgz#0f908faf4e6ec02524e54a57e432c5c013e08c9f" + fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -4080,18 +4088,6 @@ finalhandler@~1.0.0: statuses "~1.3.1" unpipe "~1.0.0" -finalhandler@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.3.tgz#ef47e77950e999780e86022a560e3217e0d0cc89" - dependencies: - debug "2.6.7" - encodeurl "~1.0.1" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.1" - statuses "~1.3.1" - unpipe "~1.0.0" - find-index@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/find-index/-/find-index-1.1.0.tgz#53007c79cd30040d6816d79458e8837d5c5705ef" @@ -4833,10 +4829,6 @@ ipaddr.js@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.3.0.tgz#1e03a52fdad83a8bbb2b25cbf4998b4cffcd3dec" -ipaddr.js@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.4.0.tgz#296aca878a821816e5b85d0a285a99bcff4582f0" - is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -5319,6 +5311,10 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +lodash-es@^4.17.4: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7" + lodash._arraycopy@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1" @@ -5848,10 +5844,6 @@ node-notifier@^5.0.1: shellwords "^0.1.0" which "^1.2.12" -node-phpcgi@^0.3.5: - version "0.3.7" - resolved "https://registry.yarnpkg.com/node-phpcgi/-/node-phpcgi-0.3.7.tgz#277dc38b6f072a993a99d94942c63fb80ed080b5" - node-pre-gyp@^0.6.36: version "0.6.36" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786" @@ -5952,7 +5944,7 @@ object-assign@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0" -object-assign@4.1.1, object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0: +object-assign@4.1.1, object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -6244,6 +6236,13 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" +pretender@^1.4.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pretender/-/pretender-1.5.1.tgz#bd9098c03d39c3bc7dcb84a28ee27e096e2e32b8" + dependencies: + fake-xml-http-request "^1.6.0" + route-recognizer "^0.3.3" + printf@^0.2.3: version "0.2.5" resolved "https://registry.yarnpkg.com/printf/-/printf-0.2.5.tgz#c438ca2ca33e3927671db4ab69c0e52f936a4f0f" @@ -6299,13 +6298,6 @@ proxy-addr@~1.1.3: forwarded "~0.1.0" ipaddr.js "1.3.0" -proxy-addr@~1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.5.tgz#71c0ee3b102de3f202f3b64f608d173fcba1a918" - dependencies: - forwarded "~0.1.0" - ipaddr.js "1.4.0" - prr@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" @@ -6795,6 +6787,14 @@ rollup@^0.41.4: dependencies: source-map-support "^0.4.0" +route-recognizer@^0.2.3: + version "0.2.10" + resolved "https://registry.yarnpkg.com/route-recognizer/-/route-recognizer-0.2.10.tgz#024b2283c2e68d13a7c7f5173a5924645e8902df" + +route-recognizer@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/route-recognizer/-/route-recognizer-0.3.3.tgz#1d365e27fa6995e091675f7dc940a8c00353bd29" + rsvp@^3.0.14, rsvp@^3.0.16, rsvp@^3.0.17, rsvp@^3.0.18, rsvp@^3.0.21, rsvp@^3.0.6, rsvp@^3.1.0, rsvp@^3.2.1: version "3.5.0" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.5.0.tgz#a62c573a4ae4e1dfd0697ebc6242e79c681eaa34" @@ -6926,24 +6926,6 @@ send@0.15.1: range-parser "~1.2.0" statuses "~1.3.1" -send@0.15.3: - version "0.15.3" - resolved "https://registry.yarnpkg.com/send/-/send-0.15.3.tgz#5013f9f99023df50d1bd9892c19e3defd1d53309" - dependencies: - debug "2.6.7" - depd "~1.1.0" - destroy "~1.0.4" - encodeurl "~1.0.1" - escape-html "~1.0.3" - etag "~1.8.0" - fresh "0.5.0" - http-errors "~1.6.1" - mime "1.3.4" - ms "2.0.0" - on-finished "~2.3.0" - range-parser "~1.2.0" - statuses "~1.3.1" - serve-static@1.12.1: version "1.12.1" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.1.tgz#7443a965e3ced647aceb5639fa06bf4d1bbe0039" @@ -6953,15 +6935,6 @@ serve-static@1.12.1: parseurl "~1.3.1" send "0.15.1" -serve-static@1.12.3: - version "1.12.3" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.3.tgz#9f4ba19e2f3030c547f8af99107838ec38d5b1e2" - dependencies: - encodeurl "~1.0.1" - escape-html "~1.0.3" - parseurl "~1.3.1" - send "0.15.3" - set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -7781,7 +7754,7 @@ vargs@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/vargs/-/vargs-0.1.0.tgz#6b6184da6520cc3204ce1b407cac26d92609ebff" -vary@^1, vary@~1.1.0, vary@~1.1.1: +vary@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37"