upgrade to ember 3.4
This commit is contained in:
parent
b7e63ed83b
commit
bcd4bc7ac6
94 changed files with 5485 additions and 6034 deletions
18
.eslintignore
Normal file
18
.eslintignore
Normal file
|
@ -0,0 +1,18 @@
|
|||
# unconventional js
|
||||
/blueprints/*/files/
|
||||
/vendor/
|
||||
|
||||
# compiled output
|
||||
/dist/
|
||||
/tmp/
|
||||
|
||||
# dependencies
|
||||
/bower_components/
|
||||
|
||||
# misc
|
||||
/coverage/
|
||||
|
||||
# ember-try
|
||||
/.node_modules.ember-try/
|
||||
/bower.json.ember-try
|
||||
/package.json.ember-try
|
25
.eslintrc.js
25
.eslintrc.js
|
@ -1,7 +1,4 @@
|
|||
module.exports = {
|
||||
globals: {
|
||||
server: true,
|
||||
},
|
||||
root: true,
|
||||
parserOptions: {
|
||||
ecmaVersion: 2017,
|
||||
|
@ -24,8 +21,10 @@ module.exports = {
|
|||
// node files
|
||||
{
|
||||
files: [
|
||||
'testem.js',
|
||||
'.template-lintrc.js',
|
||||
'ember-cli-build.js',
|
||||
'testem.js',
|
||||
'blueprints/*/index.js',
|
||||
'config/**/*.js',
|
||||
'lib/*/index.js'
|
||||
],
|
||||
|
@ -37,24 +36,6 @@ module.exports = {
|
|||
browser: false,
|
||||
node: true
|
||||
}
|
||||
},
|
||||
|
||||
// test files
|
||||
{
|
||||
files: ['tests/**/*.js'],
|
||||
excludedFiles: ['tests/dummy/**/*.js'],
|
||||
env: {
|
||||
embertest: true
|
||||
},
|
||||
globals: {
|
||||
backButton: true,
|
||||
pollHasUser: true,
|
||||
pollHasUsersCount: true,
|
||||
pollParticipate: true,
|
||||
setupBrowserNavigationButtons: true,
|
||||
switchTab: true,
|
||||
t: true,
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
30
.gitignore
vendored
30
.gitignore
vendored
|
@ -1,27 +1,27 @@
|
|||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/api/tests/_output
|
||||
/api/tests/_tmp
|
||||
/api/tests/_support/_generated
|
||||
/dist/
|
||||
/tmp/
|
||||
/api/tests/_output/
|
||||
/api/tests/_tmp/
|
||||
/api/tests/_support/_generated/
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/bower_components
|
||||
/api/vendor
|
||||
/bower_components/
|
||||
/node_modules/
|
||||
/api/vendor/
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage/*
|
||||
/coverage/
|
||||
/libpeerconnection.log
|
||||
npm-debug.log*
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/npm-debug.log*
|
||||
/testem.log
|
||||
/yarn-error.log
|
||||
|
||||
# ember-try
|
||||
.node_modules.ember-try/
|
||||
bower.json.ember-try
|
||||
package.json.ember-try
|
||||
/.node_modules.ember-try/
|
||||
/bower.json.ember-try
|
||||
/package.json.ember-try
|
||||
|
|
5
.template-lintrc.js
Normal file
5
.template-lintrc.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
extends: 'recommended'
|
||||
};
|
|
@ -45,6 +45,7 @@ before_script:
|
|||
|
||||
script:
|
||||
# run frontend and integration tests
|
||||
- if $TEST_EMBER; then yarn run lint:hbs; fi
|
||||
- if $TEST_EMBER; then yarn run lint:js; fi
|
||||
- if $TEST_EMBER; then yarn test; fi
|
||||
# test against different browsers using sauce lab
|
||||
|
|
252
MODULE_REPORT.md
252
MODULE_REPORT.md
|
@ -1,252 +0,0 @@
|
|||
## Module Report
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/controllers/create.js` at line 3
|
||||
|
||||
```js
|
||||
import Ember from 'ember';
|
||||
|
||||
const { computed, Controller, getOwner, inject } = Ember;
|
||||
|
||||
const formStepObject = Ember.Object.extend({
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/adapters/application.js` at line 5
|
||||
|
||||
```js
|
||||
|
||||
const { RESTAdapter } = DS;
|
||||
const { inject } = Ember;
|
||||
|
||||
export default RESTAdapter.extend({
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/controllers/poll.js` at line 7
|
||||
|
||||
```js
|
||||
computed,
|
||||
Controller,
|
||||
inject,
|
||||
isEmpty,
|
||||
isPresent,
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/components/create-options-dates.js` at line 4
|
||||
|
||||
```js
|
||||
import moment from 'moment';
|
||||
|
||||
const { computed, Component, inject, isArray, isEmpty } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/components/create-options-datetime.js` at line 9
|
||||
|
||||
```js
|
||||
import Form from 'ember-bootstrap/components/bs-form';
|
||||
|
||||
const { computed, Component, inject, isArray, isEmpty, isPresent, observer } = Ember;
|
||||
const { filter, mapBy, readOnly } = computed;
|
||||
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/components/create-options-text.js` at line 5
|
||||
|
||||
```js
|
||||
import { anyBy } from 'ember-array-computed-macros';
|
||||
|
||||
const { Component, computed, inject, observer, run } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/components/create-options.js` at line 7
|
||||
|
||||
```js
|
||||
from 'ember-cp-validations';
|
||||
|
||||
const { Component, inject } = Ember;
|
||||
|
||||
let Validations = buildValidations({
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/components/form-navigation-buttons.js` at line 4
|
||||
|
||||
```js
|
||||
import { translationMacro as t } from 'ember-i18n';
|
||||
|
||||
const { Component, computed, get, inject } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/components/language-select.js` at line 4
|
||||
|
||||
```js
|
||||
import localesMeta from 'croodle/locales/meta';
|
||||
|
||||
const { Component, computed, inject } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/components/poll-evaluation-chart.js` at line 4
|
||||
|
||||
```js
|
||||
import moment from 'moment';
|
||||
|
||||
const { Component, computed, get, inject, isArray, isPresent } = Ember;
|
||||
|
||||
const addArrays = function() {
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/models/option.js` at line 12
|
||||
|
||||
```js
|
||||
|
||||
const { attr } = DS;
|
||||
const { assert, computed, inject, isEmpty } = Ember;
|
||||
|
||||
const Validations = buildValidations({
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/controllers/create/index.js` at line 7
|
||||
|
||||
```js
|
||||
from 'ember-cp-validations';
|
||||
|
||||
const { computed, Controller, getOwner, Object: EmberObject, inject } = Ember;
|
||||
|
||||
const Validations = buildValidations({
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/controllers/create/meta.js` at line 7
|
||||
|
||||
```js
|
||||
from 'ember-cp-validations';
|
||||
|
||||
const { computed, Controller, inject } = Ember;
|
||||
|
||||
const Validations = buildValidations({
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/controllers/create/settings.js` at line 13
|
||||
|
||||
```js
|
||||
copy,
|
||||
getOwner,
|
||||
inject,
|
||||
isEmpty,
|
||||
Object: EmberObject,
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.ObjectController`
|
||||
|
||||
**Location**: `app/controllers/modal/save-retry.js` at line 3
|
||||
|
||||
```js
|
||||
import Ember from 'ember';
|
||||
|
||||
const { $, ObjectController } = Ember;
|
||||
|
||||
export default ObjectController.extend({
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/controllers/poll/evaluation.js` at line 3
|
||||
|
||||
```js
|
||||
import Ember from 'ember';
|
||||
|
||||
const { $, computed, Controller, inject } = Ember;
|
||||
|
||||
export default Controller.extend({
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.inject`
|
||||
|
||||
**Location**: `app/controllers/poll/participation.js` at line 12
|
||||
|
||||
```js
|
||||
Controller,
|
||||
getOwner,
|
||||
inject,
|
||||
isEmpty,
|
||||
isPresent,
|
||||
```
|
||||
|
||||
### Unknown Global
|
||||
|
||||
**Global**: `Ember.K`
|
||||
|
||||
**Location**: `tests/helpers/flash-message.js` at line 4
|
||||
|
||||
```js
|
||||
import FlashObject from 'ember-cli-flash/flash/object';
|
||||
|
||||
const { K } = Ember;
|
||||
|
||||
FlashObject.reopen({ init: K });
|
||||
```
|
|
@ -13,7 +13,7 @@ export default Component.extend({
|
|||
*/
|
||||
optionsBootstrapDatepicker: computed('options', {
|
||||
get() {
|
||||
const options = this.get('options');
|
||||
const options = this.options;
|
||||
const validDates = options.filter(function(option) {
|
||||
return moment(option.get('title')).isValid();
|
||||
});
|
||||
|
@ -38,7 +38,7 @@ export default Component.extend({
|
|||
* value is an of Date objects set by ember-cli-bootstrap-datepicker
|
||||
*/
|
||||
set(key, days) {
|
||||
const options = this.get('options');
|
||||
const options = this.options;
|
||||
|
||||
// remove all days if value isn't an array of if it's empty
|
||||
if (!isArray(days) || isEmpty(days)) {
|
||||
|
@ -81,7 +81,7 @@ export default Component.extend({
|
|||
}
|
||||
options.insertAt(
|
||||
position,
|
||||
this.get('store').createFragment('option', {
|
||||
this.store.createFragment('option', {
|
||||
title: moment(newDay).format('YYYY-MM-DD')
|
||||
})
|
||||
);
|
||||
|
|
|
@ -28,9 +28,9 @@ let modelValidations = buildValidations({
|
|||
export default Component.extend(modelValidations, {
|
||||
actions: {
|
||||
addOption(afterOption) {
|
||||
let options = this.get('dates');
|
||||
let options = this.dates;
|
||||
let dayString = afterOption.get('day');
|
||||
let fragment = this.get('store').createFragment('option', {
|
||||
let fragment = this.store.createFragment('option', {
|
||||
title: dayString
|
||||
});
|
||||
let position = options.indexOf(afterOption) + 1;
|
||||
|
@ -40,10 +40,10 @@ export default Component.extend(modelValidations, {
|
|||
);
|
||||
},
|
||||
adoptTimesOfFirstDay() {
|
||||
const dates = this.get('dates');
|
||||
const datesForFirstDay = this.get('datesForFirstDay');
|
||||
const timesForFirstDay = this.get('timesForFirstDay');
|
||||
const datesWithoutFirstDay = this.get('groupedDates').slice(1);
|
||||
const dates = this.dates;
|
||||
const datesForFirstDay = this.datesForFirstDay;
|
||||
const timesForFirstDay = this.timesForFirstDay;
|
||||
const datesWithoutFirstDay = this.groupedDates.slice(1);
|
||||
|
||||
/* validate if times on firstDay are valid */
|
||||
const datesForFirstDayAreValid = datesForFirstDay.every((date) => {
|
||||
|
@ -82,7 +82,7 @@ export default Component.extend(modelValidations, {
|
|||
const basisDate = get(items[0], 'date').clone();
|
||||
let [hour, minute] = timeOfFirstDate.split(':');
|
||||
let dateString = basisDate.hour(hour).minute(minute).toISOString();
|
||||
let fragment = this.get('store').createFragment('option', {
|
||||
let fragment = this.store.createFragment('option', {
|
||||
title: dateString
|
||||
});
|
||||
dates.insertAt(
|
||||
|
@ -104,12 +104,12 @@ export default Component.extend(modelValidations, {
|
|||
* otherwise it deletes time for this date
|
||||
*/
|
||||
deleteOption(target) {
|
||||
let position = this.get('dates').indexOf(target);
|
||||
let datesForThisDay = this.get('groupedDates').find((group) => {
|
||||
let position = this.dates.indexOf(target);
|
||||
let datesForThisDay = this.groupedDates.find((group) => {
|
||||
return group.value === target.get('day');
|
||||
}).items;
|
||||
if (datesForThisDay.length > 1) {
|
||||
this.get('dates').removeAt(position);
|
||||
this.dates.removeAt(position);
|
||||
} else {
|
||||
target.set('time', null);
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ export default Component.extend(modelValidations, {
|
|||
return isArray(formElements) ? formElements : [];
|
||||
}),
|
||||
daysValidationState: computed('formElements.@each.validation', function() {
|
||||
return this.get('formElements').reduce(function(daysValidationState, item) {
|
||||
return this.formElements.reduce(function(daysValidationState, item) {
|
||||
const day = item.get('model.day');
|
||||
const validation = item.get('validation');
|
||||
let currentValidationState;
|
||||
|
|
|
@ -2,24 +2,32 @@ import { inject as service } from '@ember/service';
|
|||
import { filter } from '@ember/object/computed';
|
||||
import Component from '@ember/component';
|
||||
import { observer, computed, get } from '@ember/object';
|
||||
import { run } from '@ember/runloop';
|
||||
import { run, next } from '@ember/runloop';
|
||||
import BsFormElement from 'ember-bootstrap/components/bs-form/element';
|
||||
import { any } from 'ember-awesome-macros/array';
|
||||
|
||||
export default Component.extend({
|
||||
actions: {
|
||||
addOption(element) {
|
||||
let fragment = this.get('store').createFragment('option');
|
||||
let options = this.get('options');
|
||||
let position = this.get('options').indexOf(element) + 1;
|
||||
let fragment = this.store.createFragment('option');
|
||||
let options = this.options;
|
||||
let position = this.options.indexOf(element) + 1;
|
||||
options.insertAt(
|
||||
position,
|
||||
fragment
|
||||
);
|
||||
|
||||
next(() => {
|
||||
this.notifyPropertyChange('childViews');
|
||||
});
|
||||
},
|
||||
deleteOption(element) {
|
||||
let position = this.get('options').indexOf(element);
|
||||
this.get('options').removeAt(position);
|
||||
let position = this.options.indexOf(element);
|
||||
this.options.removeAt(position);
|
||||
|
||||
next(() => {
|
||||
this.notifyPropertyChange('childViews');
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -32,13 +40,13 @@ export default Component.extend({
|
|||
}),
|
||||
|
||||
everyElementIsValid: computed('childFormElements.@each.validation', function() {
|
||||
const anyElementIsInvalid = this.get('anyElementIsInvalid');
|
||||
const anyElementIsInvalid = this.anyElementIsInvalid;
|
||||
if (anyElementIsInvalid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// childFormElements contains button wrapper element which should not be taken into account here
|
||||
const childFormElements = this.get('childFormElements').filterBy('hasValidator');
|
||||
const childFormElements = this.childFormElements.filterBy('hasValidator');
|
||||
if (childFormElements) {
|
||||
return childFormElements.every((childFormElement) => {
|
||||
return childFormElement.get('hasFeedback') && childFormElement.get('validation') === 'success';
|
||||
|
@ -57,11 +65,11 @@ export default Component.extend({
|
|||
run.scheduleOnce('sync', () => {
|
||||
let validationClass;
|
||||
|
||||
if (!this.get('anyElementHasFeedback')) {
|
||||
if (!this.anyElementHasFeedback) {
|
||||
validationClass = 'label-has-no-validation';
|
||||
} else if (this.get('anyElementIsInvalid')) {
|
||||
} else if (this.anyElementIsInvalid) {
|
||||
validationClass = 'label-has-error';
|
||||
} else if (this.get('everyElementIsValid')) {
|
||||
} else if (this.everyElementIsValid) {
|
||||
validationClass = 'label-has-success';
|
||||
} else {
|
||||
validationClass = 'label-has-no-validation';
|
||||
|
@ -75,14 +83,18 @@ export default Component.extend({
|
|||
|
||||
enforceMinimalOptionsAmount: observer('options', 'isMakeAPoll', function() {
|
||||
if (this.get('options.length') < 2) {
|
||||
let options = this.get('options');
|
||||
let options = this.options;
|
||||
for (let missingOptions = 2 - this.get('options.length'); missingOptions > 0; missingOptions--) {
|
||||
options.pushObject(
|
||||
this.get('store').createFragment('option')
|
||||
this.store.createFragment('option')
|
||||
);
|
||||
}
|
||||
}
|
||||
}).on('init'),
|
||||
|
||||
store: service('store')
|
||||
store: service('store'),
|
||||
|
||||
didInsertElement() {
|
||||
this.notifyPropertyChange('childViews');
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { inject as service } from '@ember/service';
|
||||
import Component from '@ember/component';
|
||||
import { get, computed } from '@ember/object';
|
||||
import { computed } from '@ember/object';
|
||||
import { translationMacro as t } from 'ember-i18n';
|
||||
|
||||
export default Component.extend({
|
||||
|
@ -38,7 +38,7 @@ export default Component.extend({
|
|||
* @private
|
||||
*/
|
||||
nextButtonClasses: computed('renderPrevButton', function() {
|
||||
let renderPrevButton = get(this, 'renderPrevButton');
|
||||
let renderPrevButton = this.renderPrevButton;
|
||||
|
||||
if (renderPrevButton) {
|
||||
return ['col-xs-6', 'col-md-8'];
|
||||
|
@ -53,7 +53,7 @@ export default Component.extend({
|
|||
* @private
|
||||
*/
|
||||
nextButtonClassesString: computed('nextButtonClasses.[]', function() {
|
||||
let nextButtonClasses = get(this, 'nextButtonClasses');
|
||||
let nextButtonClasses = this.nextButtonClasses;
|
||||
|
||||
return nextButtonClasses.join(' ');
|
||||
}),
|
||||
|
|
|
@ -25,6 +25,12 @@ export default Component.extend({
|
|||
|
||||
change() {
|
||||
let locale = this.$().val();
|
||||
this.get('i18n').set('locale', locale);
|
||||
|
||||
this.i18n.set('locale', locale);
|
||||
this.moment.changeLocale(locale);
|
||||
|
||||
if (window.localStorage) {
|
||||
window.localStorage.setItem('locale', locale);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -27,30 +27,30 @@ export default Component.extend({
|
|||
i18n: service(),
|
||||
type: 'bar',
|
||||
data: computed('users.[]', 'options.{[],each.title}', 'currentLocale', function() {
|
||||
let labels = this.get('options').map((option) => {
|
||||
let labels = this.options.map((option) => {
|
||||
let value = get(option, 'title');
|
||||
if (!get(this, 'isFindADate')) {
|
||||
if (!this.isFindADate) {
|
||||
return value;
|
||||
}
|
||||
|
||||
let hasTime = value.length > 10; // 'YYYY-MM-DD'.length === 10
|
||||
let momentFormat = hasTime ? 'LLLL' : get(this, 'momentLongDayFormat');
|
||||
let timezone = get(this, 'timezone');
|
||||
let momentFormat = hasTime ? 'LLLL' : this.momentLongDayFormat;
|
||||
let timezone = this.timezone;
|
||||
let date = hasTime && isPresent(timezone) ? moment.tz(value, timezone) : moment(value);
|
||||
date.locale(get(this, 'currentLocale'));
|
||||
date.locale(this.currentLocale);
|
||||
return date.format(momentFormat);
|
||||
});
|
||||
|
||||
let datasets = [];
|
||||
let participants = this.get('users.length');
|
||||
|
||||
let yes = this.get('users').map((user) => {
|
||||
let yes = this.users.map((user) => {
|
||||
return user.get('selections').map((selection) => {
|
||||
return selection.get('type') === 'yes' ? 1 : 0;
|
||||
});
|
||||
});
|
||||
datasets.push({
|
||||
label: this.get('i18n').t('answerTypes.yes.label').toString(),
|
||||
label: this.i18n.t('answerTypes.yes.label').toString(),
|
||||
backgroundColor: 'rgba(151,187,205,0.5)',
|
||||
borderColor: 'rgba(151,187,205,0.8)',
|
||||
hoverBackgroundColor: 'rgba(151,187,205,0.75)',
|
||||
|
@ -58,14 +58,14 @@ export default Component.extend({
|
|||
data: addArrays.apply(this, yes).map((value) => Math.round(value / participants * 100))
|
||||
});
|
||||
|
||||
if (this.get('answerType') === 'YesNoMaybe') {
|
||||
let maybe = this.get('users').map((user) => {
|
||||
if (this.answerType === 'YesNoMaybe') {
|
||||
let maybe = this.users.map((user) => {
|
||||
return user.get('selections').map((selection) => {
|
||||
return selection.get('type') === 'maybe' ? 1 : 0;
|
||||
});
|
||||
});
|
||||
datasets.push({
|
||||
label: this.get('i18n').t('answerTypes.maybe.label').toString(),
|
||||
label: this.i18n.t('answerTypes.maybe.label').toString(),
|
||||
backgroundColor: 'rgba(220,220,220,0.5)',
|
||||
borderColor: 'rgba(220,220,220,0.8)',
|
||||
hoverBackgroundColor: 'rgba(220,220,220,0.75)',
|
||||
|
|
|
@ -7,7 +7,7 @@ import { getOwner } from '@ember/application';
|
|||
const formStepObject = EmberObject.extend({
|
||||
active: computed('routing.currentRouteName', function() {
|
||||
const currentRouteName = this.get('routing.currentRouteName');
|
||||
return currentRouteName === this.get('route');
|
||||
return currentRouteName === this.route;
|
||||
}),
|
||||
disabled: true,
|
||||
hidden: false,
|
||||
|
@ -15,7 +15,7 @@ const formStepObject = EmberObject.extend({
|
|||
route: null,
|
||||
routing: service('-routing'),
|
||||
updateDisabledState: observer('active', function() {
|
||||
if (this.get('active')) {
|
||||
if (this.active) {
|
||||
this.set('disabled', false);
|
||||
}
|
||||
}).on('init'),
|
||||
|
@ -35,7 +35,7 @@ export default Controller.extend({
|
|||
}),
|
||||
formStepObject.extend({
|
||||
label: computed('pollType', function() {
|
||||
const pollType = this.get('pollType');
|
||||
const pollType = this.pollType;
|
||||
if (pollType === 'FindADate') {
|
||||
return 'create.formStep.options.days';
|
||||
} else {
|
||||
|
@ -44,18 +44,18 @@ export default Controller.extend({
|
|||
}),
|
||||
pollType: readOnly('model.pollType')
|
||||
}).create(owner.ownerInjection(), {
|
||||
model: this.get('model'),
|
||||
model: this.model,
|
||||
route: 'create.options'
|
||||
}),
|
||||
formStepObject.extend({
|
||||
hidden: computed('pollType', function() {
|
||||
const pollType = this.get('pollType');
|
||||
const pollType = this.pollType;
|
||||
return pollType !== 'FindADate';
|
||||
}),
|
||||
pollType: readOnly('model.pollType')
|
||||
}).create(owner.ownerInjection(), {
|
||||
label: 'create.formStep.options-datetime',
|
||||
model: this.get('model'),
|
||||
model: this.model,
|
||||
route: 'create.options-datetime'
|
||||
}),
|
||||
formStepObject.create(owner.ownerInjection(), {
|
||||
|
|
|
@ -24,7 +24,7 @@ const Validations = buildValidations({
|
|||
const TranslateableObject = EmberObject.extend({
|
||||
i18n: service(),
|
||||
label: computed('labelTranslation', 'i18n.locale', function() {
|
||||
return this.get('i18n').t(this.get('labelTranslation'));
|
||||
return this.i18n.t(this.labelTranslation);
|
||||
}),
|
||||
labelTranslation: undefined
|
||||
});
|
||||
|
|
|
@ -12,7 +12,7 @@ export default Controller.extend({
|
|||
},
|
||||
|
||||
normalizeOptions() {
|
||||
const options = this.get('options');
|
||||
const options = this.options;
|
||||
|
||||
// remove all days from options which haven't a time but there is atleast
|
||||
// one option with time for that day
|
||||
|
|
|
@ -4,7 +4,7 @@ import Controller from '@ember/controller';
|
|||
export default Controller.extend({
|
||||
actions: {
|
||||
nextPage() {
|
||||
if (this.get('isFindADate')) {
|
||||
if (this.isFindADate) {
|
||||
this.transitionToRoute('create.options-datetime');
|
||||
} else {
|
||||
this.transitionToRoute('create.settings');
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { inject as service } from '@ember/service';
|
||||
import { alias } from '@ember/object/computed';
|
||||
import Controller from '@ember/controller';
|
||||
import { copy } from '@ember/object/internals';
|
||||
import { getOwner } from '@ember/application';
|
||||
import { isEmpty } from '@ember/utils';
|
||||
import EmberObject, { observer, computed } from '@ember/object';
|
||||
|
@ -32,7 +31,7 @@ const Validations = buildValidations({
|
|||
const TranslateableObject = EmberObject.extend({
|
||||
i18n: service(),
|
||||
label: computed('labelTranslation', 'i18n.locale', function() {
|
||||
return this.get('i18n').t(this.get('labelTranslation'));
|
||||
return this.i18n.t(this.labelTranslation);
|
||||
}),
|
||||
labelTranslation: undefined
|
||||
});
|
||||
|
@ -41,7 +40,7 @@ export default Controller.extend(Validations, {
|
|||
actions: {
|
||||
submit() {
|
||||
if (this.get('validations.isValid')) {
|
||||
const model = this.get('model');
|
||||
const model = this.model;
|
||||
// set timezone if there is atleast one option with time
|
||||
if (
|
||||
this.get('model.isFindADate') &&
|
||||
|
@ -58,7 +57,7 @@ export default Controller.extend(Validations, {
|
|||
// reload as workaround for bug: duplicated records after save
|
||||
model.reload().then((model) => {
|
||||
// redirect to new poll
|
||||
this.get('target').send('transitionToPoll', model);
|
||||
this.target.send('transitionToPoll', model);
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
|
@ -169,13 +168,13 @@ export default Controller.extend(Validations, {
|
|||
*/
|
||||
updateAnswers: observer('model.answerType', function() {
|
||||
const selectedAnswer = this.get('model.answerType');
|
||||
const answerTypes = this.get('answerTypes');
|
||||
const answerTypes = this.answerTypes;
|
||||
let answers = [];
|
||||
|
||||
if (selectedAnswer !== null) {
|
||||
for (let i = 0; i < answerTypes.length; i++) {
|
||||
if (answerTypes[i].id === selectedAnswer) {
|
||||
answers = answerTypes[i].answers.map(copy);
|
||||
answers = answerTypes[i].answers.slice();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,7 +183,7 @@ export default Controller.extend(Validations, {
|
|||
}),
|
||||
|
||||
updateExpirationDate: observer('expirationDuration', function() {
|
||||
const expirationDuration = this.get('expirationDuration');
|
||||
const expirationDuration = this.expirationDuration;
|
||||
|
||||
if (isEmpty(expirationDuration)) {
|
||||
this.set('model.expirationDate', '');
|
||||
|
|
|
@ -8,7 +8,7 @@ import moment from 'moment';
|
|||
export default Controller.extend({
|
||||
actions: {
|
||||
linkAction(type) {
|
||||
let flashMessages = this.get('flashMessages');
|
||||
let flashMessages = this.flashMessages;
|
||||
switch (type) {
|
||||
case 'copied':
|
||||
flashMessages.success(`poll.link.copied`);
|
||||
|
@ -47,7 +47,7 @@ export default Controller.extend({
|
|||
i18n: service(),
|
||||
|
||||
momentLongDayFormat: computed('currentLocale', function() {
|
||||
let currentLocale = this.get('currentLocale');
|
||||
let currentLocale = this.currentLocale;
|
||||
return moment.localeData(currentLocale)
|
||||
.longDateFormat('LLLL')
|
||||
.replace(
|
||||
|
@ -62,10 +62,10 @@ export default Controller.extend({
|
|||
preventEncryptionKeyChanges: observer('encryptionKey', function() {
|
||||
if (
|
||||
!isEmpty(this.get('encryption.key')) &&
|
||||
this.get('encryptionKey') !== this.get('encryption.key')
|
||||
this.encryptionKey !== this.get('encryption.key')
|
||||
) {
|
||||
// work-a-round for url not being updated
|
||||
window.location.hash = window.location.hash.replace(this.get('encryptionKey'), this.get('encryption.key'));
|
||||
window.location.hash = window.location.hash.replace(this.encryptionKey, this.get('encryption.key'));
|
||||
|
||||
this.set('encryptionKey', this.get('encryption.key'));
|
||||
}
|
||||
|
@ -92,10 +92,10 @@ export default Controller.extend({
|
|||
useLocalTimezone: false,
|
||||
|
||||
mustChooseTimezone: computed('timezoneDiffers', 'timezoneChoosen', function() {
|
||||
return this.get('timezoneDiffers') && !this.get('timezoneChoosen');
|
||||
return this.timezoneDiffers && !this.timezoneChoosen;
|
||||
}),
|
||||
|
||||
timezone: computed('useLocalTimezone', function() {
|
||||
return this.get('useLocalTimezone') ? undefined : this.get('model.timezone');
|
||||
return this.useLocalTimezone ? undefined : this.get('model.timezone');
|
||||
})
|
||||
});
|
||||
|
|
|
@ -65,14 +65,14 @@ export default Controller.extend(Validations, {
|
|||
version: config.APP.version,
|
||||
});
|
||||
|
||||
user.set('name', this.get('name'));
|
||||
user.set('name', this.name);
|
||||
|
||||
const selections = user.get('selections');
|
||||
const possibleAnswers = this.get('pollController.model.answers');
|
||||
|
||||
this.get('selections').forEach((selection) => {
|
||||
this.selections.forEach((selection) => {
|
||||
if (selection.get('value') !== null) {
|
||||
if (this.get('isFreeText')) {
|
||||
if (this.isFreeText) {
|
||||
selections.createFragment({
|
||||
label: selection.get('value')
|
||||
});
|
||||
|
@ -95,18 +95,18 @@ export default Controller.extend(Validations, {
|
|||
}
|
||||
},
|
||||
save() {
|
||||
const user = this.get('newUserRecord');
|
||||
const user = this.newUserRecord;
|
||||
user.save()
|
||||
.then(() => {
|
||||
this.set('savingFailed', false);
|
||||
|
||||
// reset form
|
||||
this.set('name', '');
|
||||
this.get('selections').forEach((selection) => {
|
||||
this.selections.forEach((selection) => {
|
||||
selection.set('value', null);
|
||||
});
|
||||
|
||||
this.transitionToRoute('poll.evaluation', this.get('model'), {
|
||||
this.transitionToRoute('poll.evaluation', this.model, {
|
||||
queryParams: { encryptionKey: this.get('encryption.key') }
|
||||
});
|
||||
}, () => {
|
||||
|
@ -151,7 +151,7 @@ export default Controller.extend(Validations, {
|
|||
return AnswerObject.extend(owner.ownerInjection(), {
|
||||
i18n: service(),
|
||||
label: computed('i18n.locale', function() {
|
||||
return this.get('i18n').t(this.get('labelTranslation'));
|
||||
return this.i18n.t(this.labelTranslation);
|
||||
}),
|
||||
labelTranslation: answer.get('labelTranslation')
|
||||
}).create();
|
||||
|
@ -166,8 +166,8 @@ export default Controller.extend(Validations, {
|
|||
savingFailed: false,
|
||||
|
||||
selections: computed('options', 'pollController.dates', function() {
|
||||
let options = this.get('options');
|
||||
let isFindADate = this.get('isFindADate');
|
||||
let options = this.options;
|
||||
let isFindADate = this.isFindADate;
|
||||
let lastDate;
|
||||
|
||||
// https://github.com/offirgolan/ember-cp-validations#basic-usage---objects
|
||||
|
@ -177,8 +177,8 @@ export default Controller.extend(Validations, {
|
|||
let SelectionObject = EmberObject.extend(owner.ownerInjection(), SelectionValidations, {
|
||||
// forceAnswer and isFreeText must be included in model
|
||||
// cause otherwise validations can't depend on it
|
||||
forceAnswer: this.get('forceAnswer'),
|
||||
isFreeText: this.get('isFreeText'),
|
||||
forceAnswer: this.forceAnswer,
|
||||
isFreeText: this.isFreeText,
|
||||
value: null
|
||||
});
|
||||
|
||||
|
@ -190,7 +190,7 @@ export default Controller.extend(Validations, {
|
|||
// format label
|
||||
if (isFindADate) {
|
||||
let hasTime = value.length > 10; // 'YYYY-MM-DD'.length === 10
|
||||
let timezone = this.get('timezone');
|
||||
let timezone = this.timezone;
|
||||
let date = isPresent(timezone) ? moment.tz(value, timezone) : moment(value);
|
||||
if (hasTime && lastDate && date.format('YYYY-MM-DD') === lastDate.format('YYYY-MM-DD')) {
|
||||
labelValue = value;
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
import { getOwner } from '@ember/application';
|
||||
import { isPresent, isEmpty } from '@ember/utils';
|
||||
|
||||
export default {
|
||||
name: 'i18n',
|
||||
initialize(appInstance) {
|
||||
let i18n = appInstance.lookup('service:i18n');
|
||||
let availableLocales = i18n.get('locales');
|
||||
let moment = appInstance.lookup('service:moment');
|
||||
|
||||
i18n.addObserver('locale', i18n, localeChanged);
|
||||
i18n.set('locale', getLocale(availableLocales));
|
||||
let availableLocales = i18n.get('locales');
|
||||
let locale = getLocale(availableLocales);
|
||||
|
||||
i18n.set('locale', locale);
|
||||
moment.changeLocale(locale);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -102,20 +104,3 @@ function getSavedLocale() {
|
|||
|
||||
return [locale];
|
||||
}
|
||||
|
||||
function saveLocale(locale) {
|
||||
let { localStorage } = window;
|
||||
|
||||
// test browser support
|
||||
if (!localStorage) {
|
||||
return;
|
||||
}
|
||||
|
||||
localStorage.setItem('locale', locale);
|
||||
}
|
||||
|
||||
function localeChanged() {
|
||||
let locale = this.get('locale');
|
||||
getOwner(this).lookup('service:moment').changeLocale(locale);
|
||||
saveLocale(locale);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ export default Mixin.create({
|
|||
didInsertElement() {
|
||||
this._super(...arguments);
|
||||
|
||||
if (this.get('autofocus')) {
|
||||
if (this.autofocus) {
|
||||
this.$().focus();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ export default Fragment.extend(Validations, {
|
|||
'YYYY-MM-DD',
|
||||
'YYYY-MM-DDTHH:mm:ss.SSSZ'
|
||||
];
|
||||
const value = this.get('title');
|
||||
const value = this.title;
|
||||
if (isEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ export default Fragment.extend(Validations, {
|
|||
}),
|
||||
|
||||
day: computed('date', function() {
|
||||
const date = this.get('date');
|
||||
const date = this.date;
|
||||
if (!moment.isMoment(date)) {
|
||||
return;
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ export default Fragment.extend(Validations, {
|
|||
}),
|
||||
|
||||
dayFormatted: computed('date', 'i18n.locale', function() {
|
||||
let date = this.get('date');
|
||||
let date = this.date;
|
||||
if (!moment.isMoment(date)) {
|
||||
return;
|
||||
}
|
||||
|
@ -110,19 +110,19 @@ export default Fragment.extend(Validations, {
|
|||
}),
|
||||
|
||||
hasTime: computed('title', function() {
|
||||
return moment.isMoment(this.get('date')) &&
|
||||
this.get('title').length === 'YYYY-MM-DDTHH:mm:ss.SSSZ'.length;
|
||||
return moment.isMoment(this.date) &&
|
||||
this.title.length === 'YYYY-MM-DDTHH:mm:ss.SSSZ'.length;
|
||||
}),
|
||||
|
||||
time: computed('date', {
|
||||
get() {
|
||||
const date = this.get('date');
|
||||
const date = this.date;
|
||||
if (!moment.isMoment(date)) {
|
||||
return;
|
||||
}
|
||||
// verify that value is an ISO 8601 date string containg time
|
||||
// testing length is faster than parsing with moment
|
||||
const value = this.get('title');
|
||||
const value = this.title;
|
||||
if (value.length !== 'YYYY-MM-DDTHH:mm:ss.SSSZ'.length) {
|
||||
return;
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ export default Fragment.extend(Validations, {
|
|||
return date.format('HH:mm');
|
||||
},
|
||||
set(key, value) {
|
||||
const date = this.get('date');
|
||||
const date = this.date;
|
||||
assert(
|
||||
'can not set a time if current value is not a valid date',
|
||||
moment.isMoment(date)
|
||||
|
|
|
@ -65,14 +65,14 @@ export default Model.extend({
|
|||
* computed properties
|
||||
*/
|
||||
isFindADate: computed('pollType', function() {
|
||||
return this.get('pollType') === 'FindADate';
|
||||
return this.pollType === 'FindADate';
|
||||
}),
|
||||
|
||||
isFreeText: computed('answerType', function() {
|
||||
return this.get('answerType') === 'FreeText';
|
||||
return this.answerType === 'FreeText';
|
||||
}),
|
||||
|
||||
isMakeAPoll: computed('pollType', function() {
|
||||
return this.get('pollType') === 'MakeAPoll';
|
||||
return this.pollType === 'MakeAPoll';
|
||||
})
|
||||
});
|
||||
|
|
|
@ -9,7 +9,7 @@ export default Route.extend({
|
|||
transitionToPoll(poll) {
|
||||
this.transitionTo('poll', poll, {
|
||||
queryParams: {
|
||||
encryptionKey: this.get('encryptionKey')
|
||||
encryptionKey: this.encryptionKey
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ export default Route.extend({
|
|||
}
|
||||
|
||||
// set encryption key
|
||||
this.get('encryption').generateKey();
|
||||
this.encryption.generateKey();
|
||||
},
|
||||
|
||||
encryption: service(),
|
||||
|
|
|
@ -31,7 +31,7 @@ export default DS.RESTSerializer.extend({
|
|||
attributes.options.encrypted !== false
|
||||
) {
|
||||
if (typeof resourceHash[key] !== 'undefined' && resourceHash[key] !== null) {
|
||||
resourceHash[key] = this.get('encryption').decrypt(resourceHash[key]);
|
||||
resourceHash[key] = this.encryption.decrypt(resourceHash[key]);
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
|
@ -63,7 +63,7 @@ export default DS.RESTSerializer.extend({
|
|||
if (
|
||||
attribute.options.encrypted !== false
|
||||
) {
|
||||
json[key] = this.get('encryption').encrypt(json[key]);
|
||||
json[key] = this.encryption.encrypt(json[key]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@ export default Service.extend({
|
|||
decrypt(value) {
|
||||
return JSON.parse(
|
||||
sjcl.decrypt(
|
||||
this.get('key'),
|
||||
this.key,
|
||||
value
|
||||
)
|
||||
);
|
||||
|
@ -16,7 +16,7 @@ export default Service.extend({
|
|||
|
||||
encrypt(value) {
|
||||
return sjcl.encrypt(
|
||||
this.get('key'),
|
||||
this.key,
|
||||
JSON.stringify(value)
|
||||
);
|
||||
},
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{{title 'Croodle'}}
|
||||
{{title "Croodle"}}
|
||||
|
||||
<div class="container">
|
||||
<div id="header">
|
||||
<h1 class="logo">{{#link-to 'index'}}Croodle{{/link-to}}</h1>
|
||||
<h1 class="logo">{{#link-to "index"}}Croodle{{/link-to}}</h1>
|
||||
<form class="form-inline">
|
||||
{{language-select class="form-control"}}
|
||||
</form>
|
||||
|
@ -12,11 +12,6 @@
|
|||
{{#each flashMessages.queue as |flash|}}
|
||||
{{#flash-message flash=flash}}
|
||||
{{t flash.message}}
|
||||
{{#if showProgressBar}}
|
||||
<div class="alert-progress">
|
||||
<div class="alert-progressBar" style={{progressDuration}}></div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/flash-message}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
@ -25,4 +20,4 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{outlet 'modal'}}
|
||||
{{outlet "modal"}}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{{#form.element
|
||||
classNames='days'
|
||||
label=(t 'create.options.dates.label')
|
||||
property='options'
|
||||
as |el|
|
||||
classNames="days"
|
||||
label=(t "create.options.dates.label")
|
||||
property="options"
|
||||
as |el|
|
||||
}}
|
||||
{{bootstrap-datepicker-inline
|
||||
id=el.id
|
||||
|
|
|
@ -6,18 +6,24 @@
|
|||
{{/if}}
|
||||
|
||||
{{#bs-form
|
||||
onSubmit=(action 'submit')
|
||||
formLayout='horizontal'
|
||||
onSubmit=(action "submit")
|
||||
formLayout="horizontal"
|
||||
model=this
|
||||
novalidate=true
|
||||
as |form|
|
||||
as |form|
|
||||
}}
|
||||
<div class="days">
|
||||
{{#each dates as |date index|}}
|
||||
{{!
|
||||
show summarized validation state for all times in a day
|
||||
}}
|
||||
<div class="{{unless (get daysValidationState date.day) 'label-has-no-validation' (concat 'label-has-' (get daysValidationState date.day))}}">
|
||||
<div
|
||||
class={{if
|
||||
(get daysValidationState date.day)
|
||||
(concat "label-has-" (get daysValidationState date.day))
|
||||
"label-has-no-validation"
|
||||
}}
|
||||
>
|
||||
{{!
|
||||
show label only if it differ from label before
|
||||
Nested-helpers are called first and object-at requires a positive integer
|
||||
|
@ -26,34 +32,56 @@
|
|||
by zero there can't be any element with an index === array.length.
|
||||
}}
|
||||
{{#form.element
|
||||
classNames='option'
|
||||
classNames="option"
|
||||
label=date.dayFormatted
|
||||
invisibleLabel=(eq date.dayFormatted (get (object-at (if index (sub index 1) dates.length) dates) 'dayFormatted'))
|
||||
invisibleLabel=(eq date.dayFormatted (get (object-at (if index (sub index 1) dates.length) dates) "dayFormatted"))
|
||||
model=date
|
||||
property='time'
|
||||
as |el|
|
||||
property="time"
|
||||
as |el|
|
||||
}}
|
||||
<div class="input-group">
|
||||
{{bs-form/element/control/input
|
||||
autofocus=(unless index true false)
|
||||
id=el.id
|
||||
placeholder='00:00'
|
||||
type='time'
|
||||
placeholder="00:00"
|
||||
type="time"
|
||||
value=el.value
|
||||
onChange=(action (mut el.value))
|
||||
}}
|
||||
<div class="input-group-btn">
|
||||
{{! disable delete button if there is only one option }}
|
||||
<button {{action 'deleteOption' date}}
|
||||
class="delete btn {{if (eq el.validation 'success') 'btn-success'}} {{if (eq el.validation 'error') 'btn-danger'}} {{unless el.validation 'btn-default'}}">
|
||||
<span class='glyphicon glyphicon-trash' aria-hidden='true'></span>
|
||||
<span class='sr-only'>{{t 'create.options.button.delete.label'}}</span>
|
||||
</button>
|
||||
<button {{action 'addOption' date}}
|
||||
class="add btn {{if (eq el.validation 'success') 'btn-success'}} {{if (eq el.validation 'error') 'btn-danger'}} {{unless el.validation 'btn-default'}}">
|
||||
<span class='glyphicon glyphicon-plus' aria-hidden='true'></span>
|
||||
<span class='sr-only'>{{t 'create.options.button.add.label'}}</span>
|
||||
</button>
|
||||
{{#bs-button
|
||||
onClick=(action "deleteOption" date)
|
||||
type=(if
|
||||
(eq el.validation "success")
|
||||
"btn-success"
|
||||
(if
|
||||
(eq el.validation "error")
|
||||
"btn-danger"
|
||||
"btn-default"
|
||||
)
|
||||
)
|
||||
class="delete"
|
||||
}}
|
||||
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
|
||||
<span class="sr-only">{{t "create.options.button.delete.label"}}</span>
|
||||
{{/bs-button}}
|
||||
{{#bs-button
|
||||
onClick=(action "addOption" date)
|
||||
type=(if
|
||||
(eq el.validation "success")
|
||||
"btn-success"
|
||||
(if
|
||||
(eq el.validation "error")
|
||||
"btn-danger"
|
||||
"btn-default"
|
||||
)
|
||||
)
|
||||
class="add"
|
||||
}}
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
||||
<span class="sr-only">{{t "create.options.button.add.label"}}</span>
|
||||
{{/bs-button}}
|
||||
</div>
|
||||
</div>
|
||||
{{/form.element}}
|
||||
|
@ -63,12 +91,17 @@
|
|||
|
||||
{{#if (gt groupedDates.length 1)}}
|
||||
{{#form.element}}
|
||||
<button {{action "adoptTimesOfFirstDay"}} class="btn btn-default adopt-times-of-first-day">{{t "create.options-datetime.copy-first-line"}}</button>
|
||||
{{#bs-button
|
||||
onClick=(action "adoptTimesOfFirstDay")
|
||||
class="adopt-times-of-first-day"
|
||||
}}
|
||||
{{t "create.options-datetime.copy-first-line"}}
|
||||
{{/bs-button}}
|
||||
{{/form.element}}
|
||||
{{/if}}
|
||||
|
||||
{{form-navigation-buttons
|
||||
onPrev=(action 'previousPage')
|
||||
onPrev=(action "previousPage")
|
||||
}}
|
||||
{{/bs-form}}
|
||||
</div>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{{#each options as |option index|}}
|
||||
{{! show label only on first item }}
|
||||
{{#form.element
|
||||
classNames='option'
|
||||
label=(unless index (t 'create.options.options.label'))
|
||||
classNames="option"
|
||||
label=(unless index (t "create.options.options.label"))
|
||||
model=option
|
||||
property='title'
|
||||
as |el|
|
||||
property="title"
|
||||
as |el|
|
||||
}}
|
||||
<div class="input-group">
|
||||
{{bs-form/element/control/input
|
||||
|
@ -16,17 +16,39 @@
|
|||
}}
|
||||
<div class="input-group-btn">
|
||||
{{! disable delete button if there is only one option }}
|
||||
<button {{action 'deleteOption' option}}
|
||||
class="delete btn {{if (eq el.validation 'success') 'btn-success'}} {{if (eq el.validation 'error') 'btn-danger'}} {{unless el.validation 'btn-default'}}"
|
||||
disabled={{if (gt options.length 1) false true}}>
|
||||
<span class='glyphicon glyphicon-trash' aria-hidden='true'></span>
|
||||
<span class='sr-only'>{{t 'create.options.button.delete.label'}}</span>
|
||||
</button>
|
||||
<button {{action 'addOption' option}}
|
||||
class="add btn {{if (eq el.validation 'success') 'btn-success'}} {{if (eq el.validation 'error') 'btn-danger'}} {{unless el.validation 'btn-default'}}">
|
||||
<span class='glyphicon glyphicon-plus' aria-hidden='true'></span>
|
||||
<span class='sr-only'>{{t 'create.options.button.add.label'}}</span>
|
||||
</button>
|
||||
{{#bs-button
|
||||
onClick=(action "deleteOption" option)
|
||||
type=(if
|
||||
(eq el.validation "success")
|
||||
"btn-success"
|
||||
(if
|
||||
(eq el.validation "error")
|
||||
"btn-danger"
|
||||
"btn-default"
|
||||
)
|
||||
)
|
||||
disabled=(lte options.length 1)
|
||||
class="delete"
|
||||
}}
|
||||
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
|
||||
<span class="sr-only">{{t "create.options.button.delete.label"}}</span>
|
||||
{{/bs-button}}
|
||||
{{#bs-button
|
||||
onClick=(action "addOption" option)
|
||||
type=(if
|
||||
(eq el.validation "success")
|
||||
"btn-success"
|
||||
(if
|
||||
(eq el.validation "error")
|
||||
"btn-danger"
|
||||
"btn-default"
|
||||
)
|
||||
)
|
||||
class="add"
|
||||
}}
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
||||
<span class="sr-only">{{t "create.options.button.add.label"}}</span>
|
||||
{{/bs-button}}
|
||||
</div>
|
||||
</div>
|
||||
{{/form.element}}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
<div class="box">
|
||||
{{#bs-form
|
||||
action='submit'
|
||||
formLayout='horizontal'
|
||||
action="submit"
|
||||
formLayout="horizontal"
|
||||
model=this
|
||||
novalidate=true
|
||||
onSubmit=(action 'submit')
|
||||
as |form|
|
||||
onSubmit=(action "submit")
|
||||
as |form|
|
||||
}}
|
||||
{{#if isMakeAPoll}}
|
||||
{{create-options-text
|
||||
options=options
|
||||
addOption='addOption'
|
||||
deleteOption='deleteOption'
|
||||
addOption="addOption"
|
||||
deleteOption="deleteOption"
|
||||
form=form
|
||||
}}
|
||||
{{else}}
|
||||
|
@ -22,7 +22,7 @@
|
|||
{{/if}}
|
||||
|
||||
{{form-navigation-buttons
|
||||
onPrev=(action 'previousPage')
|
||||
onPrev=(action "previousPage")
|
||||
}}
|
||||
{{/bs-form}}
|
||||
</div>
|
||||
|
|
|
@ -2,21 +2,21 @@
|
|||
{{#if renderPrevButton}}
|
||||
<div class="col-xs-6 col-md-4 text-right">
|
||||
{{bs-button
|
||||
onClick=(action 'prev')
|
||||
classNames='prev'
|
||||
onClick=(action "prev")
|
||||
classNames="prev"
|
||||
disabled=disablePrevButton
|
||||
defaultText=prevButtonText
|
||||
}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if renderNextButton}}
|
||||
<div class="{{nextButtonClassesString}}">
|
||||
<div class={{nextButtonClassesString}}>
|
||||
{{bs-button
|
||||
buttonType='submit'
|
||||
classNames='next'
|
||||
buttonType="submit"
|
||||
classNames="next"
|
||||
defaultText=nextButtonText
|
||||
disabled=disableNextButton
|
||||
type='primary'
|
||||
type="primary"
|
||||
}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
{{#each locales as |locale|}}
|
||||
<option value="{{locale.id}}" selected={{locale.selected}}>{{locale.text}}</option>
|
||||
<option value={{locale.id}} selected={{locale.selected}}>
|
||||
{{locale.text}}
|
||||
</option>
|
||||
{{/each}}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<tr class="dateGroups">
|
||||
<th> </th>
|
||||
{{#each optionsGroupedByDates as |optionGroup|}}
|
||||
<th colspan="{{optionGroup.items.length}}">
|
||||
<th colspan={{optionGroup.items.length}}>
|
||||
{{moment-format
|
||||
optionGroup.value
|
||||
momentLongDayFormat
|
||||
|
@ -26,7 +26,7 @@
|
|||
{{#if option.hasTime}}
|
||||
{{moment-format
|
||||
option.title
|
||||
'LT'
|
||||
"LT"
|
||||
locale=currentLocale
|
||||
timeZone=timezone
|
||||
}}
|
||||
|
@ -60,8 +60,8 @@
|
|||
{{/if}}
|
||||
{{#if selection.labelTranslation}}
|
||||
{{#unless isFreeText}}
|
||||
<span class="{{selection.type}}">
|
||||
<span class="{{selection.icon}}"></span>
|
||||
<span class={{selection.type}}>
|
||||
<span class={{selection.icon}}></span>
|
||||
{{t selection.labelTranslation}}
|
||||
</span>
|
||||
{{/unless}}
|
||||
|
|
|
@ -3,37 +3,58 @@
|
|||
we will see a space between option string and following dot.
|
||||
--}}
|
||||
{{#if isFindADate}}
|
||||
<strong class='best-option-value'>{{moment-format
|
||||
evaluationBestOption.option.title
|
||||
(if evaluationBestOption.option.hasTime 'LLLL' momentLongDayFormat)
|
||||
locale=currentLocale
|
||||
timeZone=timezone
|
||||
}}</strong>.
|
||||
{{! Need to disable block indentation rule cause there shouldn't be a space between date and dot }}
|
||||
{{! template-lint-disable block-indentation }}
|
||||
<strong class="best-option-value">
|
||||
{{moment-format
|
||||
evaluationBestOption.option.title
|
||||
(if evaluationBestOption.option.hasTime "LLLL" momentLongDayFormat)
|
||||
locale=currentLocale
|
||||
timeZone=timezone
|
||||
}}</strong>.
|
||||
{{! template-lint-enable block-indentation }}
|
||||
{{else}}
|
||||
<strong class='best-option-value'>{{evaluationBestOption.option.title}}</strong>.
|
||||
<strong class="best-option-value">{{evaluationBestOption.option.title}}</strong>.
|
||||
{{/if}}
|
||||
|
||||
|
||||
<br/>
|
||||
<br>
|
||||
|
||||
{{#if isFindADate}}
|
||||
{{#if evaluationBestOption.answers.yes}}
|
||||
{{t "poll.evaluation.bestOptionParticipants.findADate.yes" count=evaluationBestOption.answers.yes}}
|
||||
{{t
|
||||
"poll.evaluation.bestOptionParticipants.findADate.yes"
|
||||
count=evaluationBestOption.answers.yes
|
||||
}}
|
||||
{{/if}}
|
||||
{{#if evaluationBestOption.answers.maybe}}
|
||||
{{t "poll.evaluation.bestOptionParticipants.findADate.maybe" count=evaluationBestOption.answers.maybe}}
|
||||
{{t
|
||||
"poll.evaluation.bestOptionParticipants.findADate.maybe"
|
||||
count=evaluationBestOption.answers.maybe
|
||||
}}
|
||||
{{/if}}
|
||||
{{#if evaluationBestOption.answers.no}}
|
||||
{{t "poll.evaluation.bestOptionParticipants.findADate.no" count=evaluationBestOption.answers.no}}
|
||||
{{t
|
||||
"poll.evaluation.bestOptionParticipants.findADate.no"
|
||||
count=evaluationBestOption.answers.no
|
||||
}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
{{#if evaluationBestOption.answers.yes}}
|
||||
{{t "poll.evaluation.bestOptionParticipants.makeAPoll.yes" count=evaluationBestOption.answers.yes}}
|
||||
{{t
|
||||
"poll.evaluation.bestOptionParticipants.makeAPoll.yes"
|
||||
count=evaluationBestOption.answers.yes
|
||||
}}
|
||||
{{/if}}
|
||||
{{#if evaluationBestOption.answers.maybe}}
|
||||
{{t "poll.evaluation.bestOptionParticipants.makeAPoll.maybe" count=evaluationBestOption.answers.maybe}}
|
||||
{{t
|
||||
"poll.evaluation.bestOptionParticipants.makeAPoll.maybe"
|
||||
count=evaluationBestOption.answers.maybe
|
||||
}}
|
||||
{{/if}}
|
||||
{{#if evaluationBestOption.answers.no}}
|
||||
{{t "poll.evaluation.bestOptionParticipants.makeAPoll.no" count=evaluationBestOption.answers.no}}
|
||||
{{t
|
||||
"poll.evaluation.bestOptionParticipants.makeAPoll.no"
|
||||
count=evaluationBestOption.answers.no
|
||||
}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
|
|
@ -8,38 +8,47 @@
|
|||
|
||||
<p class="best-options">
|
||||
{{#if poll.isFindADate}}
|
||||
{{t "poll.evaluation.bestOption.label.findADate" count=evaluationBestOptions.length}}
|
||||
{{t
|
||||
"poll.evaluation.bestOption.label.findADate"
|
||||
count=evaluationBestOptions.length
|
||||
}}
|
||||
{{else}}
|
||||
{{t "poll.evaluation.bestOption.label.makeAPoll" count=evaluationBestOptions.length}}
|
||||
{{t
|
||||
"poll.evaluation.bestOption.label.makeAPoll"
|
||||
count=evaluationBestOptions.length
|
||||
}}
|
||||
{{/if}}
|
||||
|
||||
{{#if evaluationBestOptionsMultiple}}
|
||||
<ul>
|
||||
{{#each evaluationBestOptions as |evaluationBestOption|}}
|
||||
{{component 'poll-evaluation-summary-option'
|
||||
{{component
|
||||
"poll-evaluation-summary-option"
|
||||
currentLocale=currentLocale
|
||||
evaluationBestOption=evaluationBestOption
|
||||
isFindADate=poll.isFindADate
|
||||
momentLongDayFormat=momentLongDayFormat
|
||||
tagName='li'
|
||||
tagName="li"
|
||||
timezone=timezone
|
||||
}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{else}}
|
||||
{{component 'poll-evaluation-summary-option'
|
||||
{{component
|
||||
"poll-evaluation-summary-option"
|
||||
currentLocale=currentLocale
|
||||
evaluationBestOption=evaluationBestOptions.firstObject
|
||||
isFindADate=poll.isFindADate
|
||||
momentLongDayFormat=momentLongDayFormat
|
||||
tagName='span'
|
||||
tagName="span"
|
||||
timezone=timezone
|
||||
}}
|
||||
{{/if}}
|
||||
</p>
|
||||
|
||||
<p class="last-participation">
|
||||
{{t "poll.evaluation.lastParticipation"
|
||||
{{t
|
||||
"poll.evaluation.lastParticipation"
|
||||
ago=(moment-from-now evaluationLastParticipation locale=currentLocale timezone=timezone)
|
||||
}}
|
||||
</p>
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
{{title (t 'create.title')}}
|
||||
{{title (t "create.title")}}
|
||||
|
||||
{{#bs-button-group justified=true classNames="form-steps"}}
|
||||
{{#each formSteps as |formStep|}}
|
||||
{{#unless formStep.hidden}}
|
||||
<div class="btn-group" role="group">
|
||||
{{#bs-button action=(transition-to formStep.route) type=(if formStep.active 'primary' 'default') disabled=formStep.disabled}}
|
||||
{{#bs-button
|
||||
onClick=(transition-to formStep.route)
|
||||
type=(if formStep.active "primary" "default")
|
||||
disabled=formStep.disabled
|
||||
}}
|
||||
{{t formStep.label}}
|
||||
{{/bs-button}}
|
||||
</div>
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
formLayout="horizontal"
|
||||
model=this
|
||||
novalidate=true
|
||||
onSubmit=(action 'submit')
|
||||
as |form|
|
||||
onSubmit=(action "submit")
|
||||
as |form|
|
||||
}}
|
||||
{{#form.element
|
||||
classNames='poll-type'
|
||||
label=(t 'create.index.input.pollType.label')
|
||||
classNames="poll-type"
|
||||
label=(t "create.index.input.pollType.label")
|
||||
property="pollType"
|
||||
showValidationOn=(array 'change' 'focusOut')
|
||||
showValidationOn=(array "change" "focusOut")
|
||||
useIcons=false
|
||||
as |el|
|
||||
as |el|
|
||||
}}
|
||||
{{simple-select
|
||||
autofocus=true
|
||||
|
@ -21,7 +21,7 @@
|
|||
optionLabelPath="label"
|
||||
optionValuePath="id"
|
||||
value=el.value
|
||||
action=(action (mut el.value) value='id')
|
||||
action=(action (mut el.value) value="id")
|
||||
}}
|
||||
{{/form.element}}
|
||||
{{form-navigation-buttons
|
||||
|
|
|
@ -3,26 +3,26 @@
|
|||
formLayout="horizontal"
|
||||
model=this
|
||||
novalidate=true
|
||||
onSubmit=(action 'submit')
|
||||
as |form|
|
||||
onSubmit=(action "submit")
|
||||
as |form|
|
||||
}}
|
||||
{{form.element
|
||||
autofocus=true
|
||||
classNames='title'
|
||||
classNames="title"
|
||||
controlType="text"
|
||||
label=(t 'create.meta.input.title.label')
|
||||
placeholder=(t 'create.meta.input.title.placeholder')
|
||||
label=(t "create.meta.input.title.label")
|
||||
placeholder=(t "create.meta.input.title.placeholder")
|
||||
property="title"
|
||||
}}
|
||||
{{form.element
|
||||
classNames='description'
|
||||
classNames="description"
|
||||
controlType="textarea"
|
||||
label=(t 'create.meta.input.description.label')
|
||||
placeholder=(t 'create.meta.input.description.placeholder')
|
||||
label=(t "create.meta.input.description.label")
|
||||
placeholder=(t "create.meta.input.description.placeholder")
|
||||
property="description"
|
||||
}}
|
||||
{{form-navigation-buttons
|
||||
onPrev=(route-action 'previousPage')
|
||||
onPrev=(route-action "previousPage")
|
||||
}}
|
||||
{{/bs-form}}
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{{create-options-datetime
|
||||
dates=options
|
||||
onNextPage=(action 'nextPage')
|
||||
onPrevPage=(route-action 'previousPage')
|
||||
onNextPage=(action "nextPage")
|
||||
onPrevPage=(route-action "previousPage")
|
||||
}}
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
isFindADate=model.isFindADate
|
||||
isMakeAPoll=model.isMakeAPoll
|
||||
options=model.options
|
||||
onPrevPage=(route-action 'previousPage')
|
||||
onNextPage=(action 'nextPage')
|
||||
onPrevPage=(route-action "previousPage")
|
||||
onNextPage=(action "nextPage")
|
||||
}}
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
formLayout="horizontal"
|
||||
model=this
|
||||
novalidate=true
|
||||
onSubmit=(action 'submit')
|
||||
as |form|
|
||||
onSubmit=(action "submit")
|
||||
as |form|
|
||||
}}
|
||||
{{#form.element
|
||||
classNames='answer-type'
|
||||
label=(t 'create.settings.answerType.label')
|
||||
classNames="answer-type"
|
||||
label=(t "create.settings.answerType.label")
|
||||
property="answerType"
|
||||
showValidationOn=(array 'change' 'focusOut')
|
||||
showValidationOn=(array "change" "focusOut")
|
||||
useIcons=false
|
||||
as |el|
|
||||
as |el|
|
||||
}}
|
||||
{{simple-select
|
||||
autofocus=true
|
||||
|
@ -21,43 +21,43 @@
|
|||
optionLabelPath="label"
|
||||
optionValuePath="id"
|
||||
value=el.value
|
||||
action=(action (mut el.value) value='id')
|
||||
action=(action (mut el.value) value="id")
|
||||
}}
|
||||
{{/form.element}}
|
||||
{{#form.element
|
||||
classNames='expiration-duration'
|
||||
label=(t 'create.settings.expirationDate.label')
|
||||
property='expirationDuration'
|
||||
showValidationOn=(array 'change' 'focusOut')
|
||||
classNames="expiration-duration"
|
||||
label=(t "create.settings.expirationDate.label")
|
||||
property="expirationDuration"
|
||||
showValidationOn=(array "change" "focusOut")
|
||||
useIcons=false
|
||||
as |el|
|
||||
as |el|
|
||||
}}
|
||||
{{simple-select
|
||||
id=el.id
|
||||
content=expirationDurations
|
||||
optionLabelPath='label'
|
||||
optionValuePath='id'
|
||||
optionLabelPath="label"
|
||||
optionValuePath="id"
|
||||
value=el.value
|
||||
action=(action (mut el.value) value='id')
|
||||
action=(action (mut el.value) value="id")
|
||||
}}
|
||||
{{/form.element}}
|
||||
{{form.element
|
||||
classNames='anonymous-user'
|
||||
controlType='checkbox'
|
||||
label=(t 'create.settings.anonymousUser.label')
|
||||
showValidationOn='change'
|
||||
classNames="anonymous-user"
|
||||
controlType="checkbox"
|
||||
label=(t "create.settings.anonymousUser.label")
|
||||
showValidationOn="change"
|
||||
value=anonymousUser
|
||||
}}
|
||||
{{form.element
|
||||
classNames='force-answer'
|
||||
controlType='checkbox'
|
||||
label=(t 'create.settings.forceAnswer.label')
|
||||
showValidationOn='change'
|
||||
classNames="force-answer"
|
||||
controlType="checkbox"
|
||||
label=(t "create.settings.forceAnswer.label")
|
||||
showValidationOn="change"
|
||||
value=forceAnswer
|
||||
}}
|
||||
{{form-navigation-buttons
|
||||
nextButtonText=(t 'action.save')
|
||||
onPrev=(route-action 'previousPage')
|
||||
nextButtonText=(t "action.save")
|
||||
onPrev=(route-action "previousPage")
|
||||
}}
|
||||
{{/bs-form}}
|
||||
</div>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
<p class="have-a-try">
|
||||
<span class="glyphicon glyphicon-share-alt"></span>
|
||||
{{#link-to 'create'}}{{t "index.link.have-a-try"}}{{/link-to}}
|
||||
{{#link-to "create"}}{{t "index.link.have-a-try"}}{{/link-to}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,10 +7,20 @@
|
|||
<h2 class="title">{{model.title}}</h2>
|
||||
<p class="description">{{model.description}}</p>
|
||||
<p class="dates">
|
||||
<span class="creationDate">{{t "poll.created-date" date=(moment-format model.creationDate 'LLLL' locale=currentLocale)}}</span>
|
||||
<span class="creationDate">
|
||||
{{t
|
||||
"poll.created-date"
|
||||
date=(moment-format model.creationDate "LLLL" locale=currentLocale)
|
||||
}}
|
||||
</span>
|
||||
{{#if model.expirationDate}}
|
||||
<br>
|
||||
<span class="expirationDate">{{t "poll.expiration-date" date=(moment-format model.expirationDate 'LLLL' locale=currentLocale)}}</span>
|
||||
<span class="expirationDate">
|
||||
{{t
|
||||
"poll.expiration-date"
|
||||
date=(moment-format model.expirationDate "LLLL" locale=currentLocale)
|
||||
}}
|
||||
</span>
|
||||
{{/if}}
|
||||
</p>
|
||||
</div>
|
||||
|
@ -19,18 +29,20 @@
|
|||
<div class="box poll-link">
|
||||
<p>{{t "poll.share"}}</p>
|
||||
<p class="link">
|
||||
<a href="{{pollUrl}}">{{pollUrl}}</a>
|
||||
<a href={{pollUrl}}>
|
||||
{{pollUrl}}
|
||||
</a>
|
||||
{{#copy-button
|
||||
clipboardText=pollUrl
|
||||
classNames="btn btn-default"
|
||||
success=(action 'linkAction' 'copied')
|
||||
error=(action 'linkAction' 'selected')
|
||||
success=(action "linkAction" "copied")
|
||||
error=(action "linkAction" "selected")
|
||||
}}
|
||||
<span class="glyphicon glyphicon-copy"></span>
|
||||
{{/copy-button}}
|
||||
</p>
|
||||
<p class="notice">
|
||||
{{t "poll.share.notice"}}
|
||||
{{t "poll.share.notice"}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -39,8 +51,11 @@
|
|||
{{#if showExpirationWarning}}
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
{{#bs-alert type="warning" classNames='expiration-warning'}}
|
||||
{{t "poll.expiration-date-warning" timeToNow=(moment-from-now model.expirationDate locale=currentLocale)}}
|
||||
{{#bs-alert type="warning" classNames="expiration-warning"}}
|
||||
{{t
|
||||
"poll.expiration-date-warning"
|
||||
timeToNow=(moment-from-now model.expirationDate locale=currentLocale)
|
||||
}}
|
||||
{{/bs-alert}}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -48,14 +63,26 @@
|
|||
|
||||
<div class="box container-fluid">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
{{#link-to "poll.participation" model tagName='li' activeClass='active' class='participation'}}
|
||||
{{#link-to
|
||||
"poll.participation"
|
||||
model
|
||||
tagName="li"
|
||||
activeClass="active"
|
||||
class="participation"
|
||||
}}
|
||||
{{#link-to "poll.participation" model}}
|
||||
{{t 'poll.tab-title.participation'}}
|
||||
{{t "poll.tab-title.participation"}}
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
{{#link-to "poll.evaluation" model tagName='li' activeClass='active' class='evaluation'}}
|
||||
{{#link-to
|
||||
"poll.evaluation"
|
||||
model
|
||||
tagName="li"
|
||||
activeClass="active"
|
||||
class="evaluation"
|
||||
}}
|
||||
{{#link-to "poll.evaluation" model}}
|
||||
{{t 'poll.tab-title.evaluation'}}
|
||||
{{t "poll.tab-title.evaluation"}}
|
||||
{{/link-to}}
|
||||
{{/link-to}}
|
||||
</ul>
|
||||
|
@ -75,19 +102,25 @@
|
|||
closeButton=false
|
||||
keyboard=false
|
||||
autoClose=false
|
||||
id='modal-choose-timezone'
|
||||
as |modal|
|
||||
id="modal-choose-timezone"
|
||||
as |modal|
|
||||
}}
|
||||
{{#modal.body}}
|
||||
<p>
|
||||
{{t "poll.modal.timezoneDiffers.body"}}
|
||||
</p>
|
||||
{{/modal.body}}
|
||||
{{#modal.footer as |footer|}}
|
||||
{{#bs-button onClick=(action "useLocalTimezone") class="use-local-timezone"}}
|
||||
{{#modal.footer}}
|
||||
{{#bs-button
|
||||
onClick=(action "useLocalTimezone")
|
||||
class="use-local-timezone"
|
||||
}}
|
||||
{{t "poll.modal.timezoneDiffers.button.useLocalTimezone"}}
|
||||
{{/bs-button}}
|
||||
{{#bs-button onClick=(action (mut timezoneChoosen) true) classNames="use-poll-timezone"}}
|
||||
{{#bs-button
|
||||
onClick=(action (mut timezoneChoosen) true)
|
||||
classNames="use-poll-timezone"
|
||||
}}
|
||||
{{t "poll.modal.timezoneDiffers.button.usePollTimezone"}}
|
||||
{{/bs-button}}
|
||||
{{/modal.footer}}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
timezone=timezone
|
||||
}}
|
||||
|
||||
<h3>{{t 'poll.evaluation.overview'}}</h3>
|
||||
<h3>{{t "poll.evaluation.overview"}}</h3>
|
||||
{{poll-evaluation-chart
|
||||
answerType=model.answerType
|
||||
currentLocale=currentLocale
|
||||
|
@ -19,7 +19,7 @@
|
|||
}}
|
||||
{{/if}}
|
||||
|
||||
<h3>{{t 'poll.evaluation.participantTable'}}</h3>
|
||||
<h3>{{t "poll.evaluation.participantTable"}}</h3>
|
||||
{{poll-evaluation-participants-table
|
||||
currentLocale=currentLocale
|
||||
hasTimes=hasTimes
|
||||
|
|
|
@ -1,52 +1,52 @@
|
|||
<div class="participation">
|
||||
{{#bs-form
|
||||
onSubmit=(action 'submit')
|
||||
formLayout='horizontal'
|
||||
onSubmit=(action "submit")
|
||||
formLayout="horizontal"
|
||||
model=this
|
||||
novalidate=true
|
||||
as |form|
|
||||
as |form|
|
||||
}}
|
||||
{{form.element
|
||||
autofocus=true
|
||||
controlType='text'
|
||||
label=(t 'poll.input.newUserName.label')
|
||||
placeholder=(t 'poll.input.newUserName.placeholder')
|
||||
property='name'
|
||||
classNames='name'
|
||||
controlType="text"
|
||||
label=(t "poll.input.newUserName.label")
|
||||
placeholder=(t "poll.input.newUserName.placeholder")
|
||||
property="name"
|
||||
classNames="name"
|
||||
}}
|
||||
<div class="selections">
|
||||
{{#each selections as |selection index|}}
|
||||
{{#each selections as |selection|}}
|
||||
{{#if isFreeText}}
|
||||
{{form.element
|
||||
controlType='text'
|
||||
controlType="text"
|
||||
label=(if isFindADate
|
||||
(moment-format
|
||||
selection.labelValue
|
||||
(if (eq selection.momentFormat 'day') momentLongDayFormat selection.momentFormat)
|
||||
(if (eq selection.momentFormat "day") momentLongDayFormat selection.momentFormat)
|
||||
locale=currentLocale
|
||||
timeZone=timezone
|
||||
)
|
||||
selection.labelValue
|
||||
)
|
||||
model=selection
|
||||
property='value'
|
||||
property="value"
|
||||
}}
|
||||
{{else}}
|
||||
{{#form.element
|
||||
label=(if isFindADate
|
||||
(moment-format
|
||||
selection.labelValue
|
||||
(if (eq selection.momentFormat 'day') momentLongDayFormat selection.momentFormat)
|
||||
(if (eq selection.momentFormat "day") momentLongDayFormat selection.momentFormat)
|
||||
locale=currentLocale
|
||||
timeZone=timezone
|
||||
)
|
||||
selection.labelValue
|
||||
)
|
||||
model=selection
|
||||
property='value'
|
||||
showValidationOn='change'
|
||||
property="value"
|
||||
showValidationOn="change"
|
||||
useIcons=false
|
||||
as |el|
|
||||
as |el|
|
||||
}}
|
||||
{{#each possibleAnswers as |possibleAnswer|}}
|
||||
<div class="radio {{possibleAnswer.type}}">
|
||||
|
@ -73,22 +73,22 @@
|
|||
|
||||
{{#bs-modal
|
||||
open=savingFailed
|
||||
title=(t 'modal.save-retry.title')
|
||||
title=(t "modal.save-retry.title")
|
||||
body=false
|
||||
footer=false
|
||||
closeButton=false
|
||||
autoClose=false
|
||||
id='modal-saving-failed'
|
||||
as |modal|
|
||||
id="modal-saving-failed"
|
||||
as |modal|
|
||||
}}
|
||||
{{#modal.body}}
|
||||
<p>{{t "modal.save-retry.text"}}</p>
|
||||
{{/modal.body}}
|
||||
{{#modal.footer}}
|
||||
{{bs-button
|
||||
defaultText=(t 'modal.save-retry.button-retry')
|
||||
type='primary'
|
||||
onClick=(action 'save')
|
||||
defaultText=(t "modal.save-retry.button-retry")
|
||||
type="primary"
|
||||
onClick=(action "save")
|
||||
}}
|
||||
{{/modal.footer}}
|
||||
{{/bs-modal}}
|
||||
|
|
3
config/optional-features.json
Normal file
3
config/optional-features.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"jquery-integration": true
|
||||
}
|
|
@ -1,8 +1,18 @@
|
|||
'use strict';
|
||||
|
||||
const browsers = [
|
||||
'last 1 Chrome versions',
|
||||
'last 1 Firefox versions',
|
||||
'last 1 Safari versions'
|
||||
];
|
||||
|
||||
const isCI = !!process.env.CI;
|
||||
const isProduction = process.env.EMBER_ENV === 'production';
|
||||
|
||||
if (isCI || isProduction) {
|
||||
browsers.push('ie 11');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
browsers: [
|
||||
'ie 9',
|
||||
'last 1 Chrome versions',
|
||||
'last 1 Firefox versions',
|
||||
'last 1 Safari versions'
|
||||
]
|
||||
browsers
|
||||
};
|
||||
|
|
57
package.json
57
package.json
|
@ -2,76 +2,81 @@
|
|||
"name": "croodle",
|
||||
"version": "0.5.6",
|
||||
"private": true,
|
||||
"repository": "https://github.com/jelhan/croodle",
|
||||
"license": "MIT",
|
||||
"author": "",
|
||||
"directories": {
|
||||
"doc": "doc",
|
||||
"test": "tests"
|
||||
},
|
||||
"repository": "https://github.com/jelhan/croodle",
|
||||
"scripts": {
|
||||
"build": "ember build",
|
||||
"lint:js": "eslint ./*.js app config lib server tests",
|
||||
"lint:hbs": "ember-template-lint .",
|
||||
"lint:js": "eslint .",
|
||||
"start": "ember serve",
|
||||
"test": "ember test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ember/jquery": "^0.5.2",
|
||||
"@ember/optional-features": "^0.6.3",
|
||||
"bootstrap": "^3.3.7",
|
||||
"ember-ajax": "^3.0.0",
|
||||
"ember-ajax": "^4.0.0",
|
||||
"ember-array-helper": "^5.0.0",
|
||||
"ember-awesome-macros": "^3.1.0",
|
||||
"ember-bootstrap": "^2.1.2",
|
||||
"ember-bootstrap-cp-validations": "^1.0.0",
|
||||
"ember-browserify": "^1.1.11",
|
||||
"ember-cli": "~2.18.2",
|
||||
"ember-cli": "~3.4.4",
|
||||
"ember-cli-acceptance-test-helpers": "^1.0.0",
|
||||
"ember-cli-app-version": "^3.0.0",
|
||||
"ember-cli-babel": "^6.6.0",
|
||||
"ember-cli-app-version": "^3.2.0",
|
||||
"ember-cli-babel": "^6.16.0",
|
||||
"ember-cli-bootstrap-datepicker": "^0.6.1",
|
||||
"ember-cli-browser-navigation-button-test-helper": "^0.0.4",
|
||||
"ember-cli-browser-navigation-button-test-helper": "^0.1.1",
|
||||
"ember-cli-chart": "^3.3.1",
|
||||
"ember-cli-clipboard": "^0.8.0",
|
||||
"ember-cli-content-security-policy": "^0.6.2",
|
||||
"ember-cli-dependency-checker": "^2.0.0",
|
||||
"ember-cli-dependency-checker": "^3.0.0",
|
||||
"ember-cli-deprecation-workflow": "^0.2.3",
|
||||
"ember-cli-eslint": "^4.2.1",
|
||||
"ember-cli-eslint": "^4.2.3",
|
||||
"ember-cli-flash": "^1.4.0",
|
||||
"ember-cli-htmlbars": "^2.0.1",
|
||||
"ember-cli-htmlbars-inline-precompile": "^1.0.0",
|
||||
"ember-cli-inject-live-reload": "^1.4.1",
|
||||
"ember-cli-htmlbars": "^3.0.0",
|
||||
"ember-cli-htmlbars-inline-precompile": "^1.0.3",
|
||||
"ember-cli-inject-live-reload": "^1.8.2",
|
||||
"ember-cli-less": "^1.5.3",
|
||||
"ember-cli-mirage": "^0.4.10",
|
||||
"ember-cli-moment-shim": "^3.7.1",
|
||||
"ember-cli-page-object": "^1.11.0",
|
||||
"ember-cli-qunit": "^4.1.1",
|
||||
"ember-cli-qunit": "^4.3.2",
|
||||
"ember-cli-release": "^0.2.9",
|
||||
"ember-cli-sauce": "^1.6.0",
|
||||
"ember-cli-shims": "^1.2.0",
|
||||
"ember-cli-sri": "^2.1.0",
|
||||
"ember-cli-uglify": "^2.0.0",
|
||||
"ember-cli-sri": "^2.1.1",
|
||||
"ember-cli-template-lint": "^1.0.0-beta.1",
|
||||
"ember-cli-uglify": "^2.1.0",
|
||||
"ember-composable-helpers": "^2.1.0",
|
||||
"ember-cp-validations": "^3.5.0",
|
||||
"ember-data": "~2.18.0",
|
||||
"ember-data-model-fragments": "^2.14.0",
|
||||
"ember-data": "~3.4.0",
|
||||
"ember-data-model-fragments": "^3.3.0",
|
||||
"ember-export-application-global": "^2.0.0",
|
||||
"ember-i18n": "^5.0.2",
|
||||
"ember-i18n-cp-validations": "^3.0.2",
|
||||
"ember-load-initializers": "^1.0.0",
|
||||
"ember-load-initializers": "^1.1.0",
|
||||
"ember-math-helpers": "^2.8.1",
|
||||
"ember-maybe-import-regenerator": "^0.1.6",
|
||||
"ember-moment": "^7.8.0",
|
||||
"ember-native-dom-helpers": "^0.6.2",
|
||||
"ember-page-title": "^3.0.6",
|
||||
"ember-radio-buttons": "^4.0.1",
|
||||
"ember-resolver": "^4.0.0",
|
||||
"ember-resolver": "^5.0.1",
|
||||
"ember-route-action-helper": "^2.0.6",
|
||||
"ember-simple-select": "^0.6.1",
|
||||
"ember-source": "~2.18.0",
|
||||
"ember-simple-select": "jelhan/ember-simple-select#ember-3.4",
|
||||
"ember-source": "~3.4.0",
|
||||
"ember-transition-helper": "^1.0.0",
|
||||
"ember-truth-helpers": "^2.1.0",
|
||||
"eslint-plugin-ember": "^5.0.0",
|
||||
"loader.js": "^4.2.3"
|
||||
"eslint-plugin-ember": "^5.2.0",
|
||||
"loader.js": "^4.7.0",
|
||||
"qunit-dom": "^0.7.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^4.5 || 6.* || >= 7.*"
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
},
|
||||
"ember-addon": {
|
||||
"paths": [
|
||||
|
|
11
testem.js
11
testem.js
|
@ -9,13 +9,14 @@ module.exports = {
|
|||
],
|
||||
browser_args: {
|
||||
Chrome: {
|
||||
mode: 'ci',
|
||||
args: [
|
||||
ci: [
|
||||
// --no-sandbox is needed when running Chrome inside a container
|
||||
process.env.TRAVIS ? '--no-sandbox' : null,
|
||||
|
||||
'--disable-gpu',
|
||||
process.env.CI ? '--no-sandbox' : null,
|
||||
'--headless',
|
||||
'--disable-gpu',
|
||||
'--disable-dev-shm-usage',
|
||||
'--disable-software-rasterizer',
|
||||
'--mute-audio',
|
||||
'--remote-debugging-port=0',
|
||||
'--window-size=1440,900'
|
||||
].filter(Boolean)
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import { test } from 'qunit';
|
||||
import { visit } from '@ember/test-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import jQuery from 'jquery';
|
||||
import moduleForAcceptance from 'croodle/tests/helpers/module-for-acceptance';
|
||||
|
||||
moduleForAcceptance('Acceptance | build info');
|
||||
module('Acceptance | build info', function(hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
|
||||
test('version is included as html meta tag', function(assert) {
|
||||
visit('/');
|
||||
test('version is included as html meta tag', async function(assert) {
|
||||
await visit('/');
|
||||
|
||||
andThen(function() {
|
||||
// ToDo: figure out why find() helper does not work but jQuery does
|
||||
assert.ok(jQuery('head meta[name="build-info"]').length === 1, 'tag exists');
|
||||
assert.ok(
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,26 +1,24 @@
|
|||
import { test } from 'qunit';
|
||||
import moduleForAcceptance from 'croodle/tests/helpers/module-for-acceptance';
|
||||
import { find, visit } from '@ember/test-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import pageIndex from 'croodle/tests/pages/index';
|
||||
|
||||
moduleForAcceptance('Acceptance | i18n', {
|
||||
beforeEach() {
|
||||
window.localStorage.setItem('locale', 'en');
|
||||
}
|
||||
});
|
||||
module('Acceptance | i18n', function(hooks) {
|
||||
hooks.beforeEach(function() {
|
||||
window.localStorage.setItem('locale', 'de');
|
||||
});
|
||||
|
||||
test('locale is saved in localStorage', function(assert) {
|
||||
visit('/');
|
||||
setupApplicationTest(hooks);
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(find('.language-select').val(), 'en');
|
||||
pageIndex.locale('de');
|
||||
test('locale is saved in localStorage', async function(assert) {
|
||||
await visit('/');
|
||||
assert.equal(find('.language-select').value, 'de', 'picks up locale in locale storage');
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(find('.language-select').val(), 'de');
|
||||
assert.equal(
|
||||
window.localStorage.getItem('locale'), 'de',
|
||||
'persisted in localeStorage'
|
||||
);
|
||||
});
|
||||
await pageIndex.locale('en');
|
||||
assert.equal(find('.language-select').value, 'en');
|
||||
assert.equal(
|
||||
window.localStorage.getItem('locale'), 'en',
|
||||
'persisted in localeStorage'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,43 +1,47 @@
|
|||
import { test } from 'qunit';
|
||||
import moduleForAcceptance from 'croodle/tests/helpers/module-for-acceptance';
|
||||
import { 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';
|
||||
import { t } from 'ember-i18n/test-support';
|
||||
import switchTab from 'croodle/tests/helpers/switch-tab';
|
||||
import pollHasUser from 'croodle/tests/helpers/poll-has-user';
|
||||
import pollParticipate from 'croodle/tests/helpers/poll-participate';
|
||||
import moment from 'moment';
|
||||
import pagePollParticipation from 'croodle/tests/pages/poll/participation';
|
||||
/* jshint proto: true */
|
||||
|
||||
moduleForAcceptance('Acceptance | legacy support', {
|
||||
beforeEach() {
|
||||
module('Acceptance | legacy support', function(hooks) {
|
||||
hooks.beforeEach(function() {
|
||||
window.localStorage.setItem('locale', 'en');
|
||||
moment.locale('en');
|
||||
}
|
||||
});
|
||||
|
||||
test('show a default poll created with v0.3.0', function(assert) {
|
||||
const encryptionKey = '5MKFuNTKILUXw6RuqkAw6ooZw4k3mWWx98ZQw8vH';
|
||||
|
||||
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}`);
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.participation');
|
||||
test('show a default poll created with v0.3.0', async function(assert) {
|
||||
const encryptionKey = '5MKFuNTKILUXw6RuqkAw6ooZw4k3mWWx98ZQw8vH';
|
||||
|
||||
let poll = this.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: [
|
||||
this.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'
|
||||
});
|
||||
|
||||
await visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
|
||||
assert.equal(currentRouteName(), 'poll.participation');
|
||||
assert.deepEqual(
|
||||
pagePollParticipation.options().labels,
|
||||
[
|
||||
|
@ -55,70 +59,57 @@ test('show a default poll created with v0.3.0', function(assert) {
|
|||
]
|
||||
);
|
||||
|
||||
switchTab('evaluation');
|
||||
await switchTab('evaluation');
|
||||
assert.equal(currentRouteName(), 'poll.evaluation');
|
||||
pollHasUser(assert,
|
||||
'Fritz Bauer',
|
||||
[
|
||||
t('answerTypes.yes.label'),
|
||||
t('answerTypes.no.label'),
|
||||
t('answerTypes.no.label')
|
||||
]
|
||||
);
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.evaluation');
|
||||
await switchTab('participation');
|
||||
assert.equal(currentRouteName(), 'poll.participation');
|
||||
|
||||
pollHasUser(assert,
|
||||
'Fritz Bauer',
|
||||
[
|
||||
t('answerTypes.yes.label'),
|
||||
t('answerTypes.no.label'),
|
||||
t('answerTypes.no.label')
|
||||
]
|
||||
);
|
||||
await pollParticipate('Hermann Langbein', ['yes', 'maybe', 'yes']);
|
||||
assert.equal(currentRouteName(), 'poll.evaluation');
|
||||
pollHasUser(assert,
|
||||
'Hermann Langbein',
|
||||
[
|
||||
t('answerTypes.yes.label'),
|
||||
t('answerTypes.maybe.label'),
|
||||
t('answerTypes.yes.label')
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
switchTab('participation');
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.participation');
|
||||
|
||||
pollParticipate('Hermann Langbein', ['yes', 'maybe', 'yes']);
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.evaluation');
|
||||
pollHasUser(assert,
|
||||
'Hermann Langbein',
|
||||
[
|
||||
t('answerTypes.yes.label'),
|
||||
t('answerTypes.maybe.label'),
|
||||
t('answerTypes.yes.label')
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
test('show a poll using free text created with v0.3.0', async function(assert) {
|
||||
let encryptionKey = 'Rre6dAGOYLW9gYKOP4LhX7Qwfhe5Th3je0uKDtyy';
|
||||
let poll = this.server.create('poll', {
|
||||
encryptionKey,
|
||||
answerType: 'FreeText',
|
||||
answers: [],
|
||||
options: [{ 'title': 'apple pie' }, { 'title': 'pecan pie' }, { 'title': 'plum pie' }],
|
||||
pollType: 'MakeAPoll',
|
||||
users: [
|
||||
this.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'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
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/${poll.id}?encryptionKey=${encryptionKey}`);
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.participation');
|
||||
await visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
|
||||
assert.equal(currentRouteName(), 'poll.participation');
|
||||
assert.deepEqual(
|
||||
pagePollParticipation.options().labels,
|
||||
[
|
||||
|
@ -128,37 +119,29 @@ test('show a poll using free text created with v0.3.0', function(assert) {
|
|||
]
|
||||
);
|
||||
|
||||
switchTab('evaluation');
|
||||
await switchTab('evaluation');
|
||||
assert.equal(currentRouteName(), 'poll.evaluation');
|
||||
pollHasUser(assert,
|
||||
'Paul Levi',
|
||||
[
|
||||
'would be great!',
|
||||
'no way',
|
||||
'if I had to'
|
||||
]
|
||||
);
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.evaluation');
|
||||
pollHasUser(assert,
|
||||
'Paul Levi',
|
||||
[
|
||||
'would be great!',
|
||||
'no way',
|
||||
'if I had to'
|
||||
]
|
||||
);
|
||||
await switchTab('participation');
|
||||
assert.equal(currentRouteName(), 'poll.participation');
|
||||
|
||||
switchTab('participation');
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.participation');
|
||||
pollParticipate('Hermann Langbein', ["I don't care", 'would be awesome', "can't imagine anything better"]);
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.evaluation');
|
||||
pollHasUser(assert,
|
||||
'Hermann Langbein',
|
||||
[
|
||||
"I don't care",
|
||||
'would be awesome',
|
||||
"can't imagine anything better"
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
await pollParticipate('Hermann Langbein', ["I don't care", 'would be awesome', "can't imagine anything better"]);
|
||||
assert.equal(currentRouteName(), 'poll.evaluation');
|
||||
pollHasUser(assert,
|
||||
'Hermann Langbein',
|
||||
[
|
||||
"I don't care",
|
||||
'would be awesome',
|
||||
"can't imagine anything better"
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,145 +1,135 @@
|
|||
import { test } from 'qunit';
|
||||
import {
|
||||
click,
|
||||
find,
|
||||
findAll,
|
||||
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';
|
||||
import { t } from 'ember-i18n/test-support';
|
||||
import pollHasUser, { pollHasUsersCount } from 'croodle/tests/helpers/poll-has-user';
|
||||
import pollParticipate from 'croodle/tests/helpers/poll-participate';
|
||||
import jQuery from 'jquery';
|
||||
import moduleForAcceptance from 'croodle/tests/helpers/module-for-acceptance';
|
||||
/* jshint proto: true */
|
||||
|
||||
moduleForAcceptance('Acceptance | participate in a poll', {
|
||||
beforeEach() {
|
||||
module('Acceptance | participate in a poll', function(hooks) {
|
||||
hooks.beforeEach(function() {
|
||||
window.localStorage.setItem('locale', 'en');
|
||||
}
|
||||
});
|
||||
|
||||
test('participate in a default poll', function(assert) {
|
||||
server.logging = true;
|
||||
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = server.create('poll', {
|
||||
encryptionKey
|
||||
});
|
||||
|
||||
visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`).then(function() {
|
||||
assert.equal(currentPath(), 'poll.participation', 'poll is redirected to poll.participation');
|
||||
pollParticipate('Max Meiner', ['yes', 'no']);
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.evaluation');
|
||||
assert.equal(
|
||||
currentURL().split('?')[1],
|
||||
`encryptionKey=${encryptionKey}`,
|
||||
'encryption key is part of query params'
|
||||
);
|
||||
pollHasUsersCount(assert, 1, 'user is added to user selections table');
|
||||
pollHasUser(assert, 'Max Meiner', [t('answerTypes.yes.label'), t('answerTypes.no.label')]);
|
||||
|
||||
click('.nav .participation');
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(currentPath(), 'poll.participation');
|
||||
assert.equal(find('.name input').val(), '', 'input for name is cleared');
|
||||
assert.ok(
|
||||
!find('input[type="radio"]').toArray().some((el) => jQuery(el).prop('checked')),
|
||||
'radios are cleared'
|
||||
);
|
||||
pollParticipate('Peter Müller', ['yes', 'yes']);
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(currentPath(), 'poll.evaluation');
|
||||
pollHasUsersCount(assert, 2, 'user is added to user selections table');
|
||||
pollHasUser(assert, 'Peter Müller', [t('answerTypes.yes.label'), t('answerTypes.yes.label')]);
|
||||
});
|
||||
});
|
||||
test('participate in a default poll', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = this.server.create('poll', {
|
||||
encryptionKey
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('participate in a poll using freetext', function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = server.create('poll', {
|
||||
answerType: 'FreeText',
|
||||
answers: [],
|
||||
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'
|
||||
);
|
||||
pollHasUsersCount(assert, 1, 'user is added to user selections table');
|
||||
pollHasUser(assert, 'Max Meiner', [t('answerTypes.yes.label'), t('answerTypes.no.label')]);
|
||||
|
||||
await click('.nav .participation');
|
||||
assert.equal(currentRouteName(), 'poll.participation');
|
||||
assert.equal(find('.name input').value, '', 'input for name is cleared');
|
||||
assert.ok(
|
||||
!findAll('input[type="radio"]').toArray().some((el) => el.checked),
|
||||
'radios are cleared'
|
||||
);
|
||||
|
||||
await pollParticipate('Peter Müller', ['yes', 'yes']);
|
||||
assert.equal(currentRouteName(), 'poll.evaluation');
|
||||
pollHasUsersCount(assert, 2, 'user is added to user selections table');
|
||||
pollHasUser(assert, 'Peter Müller', [t('answerTypes.yes.label'), t('answerTypes.yes.label')]);
|
||||
});
|
||||
|
||||
visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`).then(function() {
|
||||
assert.equal(currentPath(), 'poll.participation');
|
||||
pollParticipate('Max Manus', ['answer 1', 'answer 2']);
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.evaluation');
|
||||
pollHasUsersCount(assert, 1, 'user is added to user selections table');
|
||||
pollHasUser(assert, 'Max Manus', ['answer 1', 'answer 2']);
|
||||
test('participate in a poll using freetext', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = this.server.create('poll', {
|
||||
answerType: 'FreeText',
|
||||
answers: [],
|
||||
encryptionKey
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('participate in a poll which does not force an answer to all options', function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = server.create('poll', {
|
||||
encryptionKey,
|
||||
forceAnswer: false
|
||||
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');
|
||||
pollHasUsersCount(assert, 1, 'user is added to user selections table');
|
||||
pollHasUser(assert, 'Max Manus', ['answer 1', 'answer 2']);
|
||||
});
|
||||
|
||||
visit(`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`).then(function() {
|
||||
assert.equal(currentPath(), 'poll.participation');
|
||||
pollParticipate('Karl Käfer', ['yes', null]);
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.evaluation');
|
||||
pollHasUsersCount(assert, 1, 'user is added to user selections table');
|
||||
pollHasUser(assert, 'Karl Käfer', [t('answerTypes.yes.label'), '']);
|
||||
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
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('participate in a poll which allows anonymous participation', function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = server.create('poll', {
|
||||
anonymousUser: true,
|
||||
encryptionKey
|
||||
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');
|
||||
pollHasUsersCount(assert, 1, 'user is added to user selections table');
|
||||
pollHasUser(assert, 'Karl Käfer', [t('answerTypes.yes.label'), '']);
|
||||
});
|
||||
|
||||
visit(`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`).then(function() {
|
||||
assert.equal(currentPath(), 'poll.participation');
|
||||
pollParticipate(null, ['yes', 'no']);
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.evaluation');
|
||||
pollHasUsersCount(assert, 1, 'user is added to user selections table');
|
||||
pollHasUser(assert, '', [t('answerTypes.yes.label'), t('answerTypes.no.label')]);
|
||||
test('participate in a poll which allows anonymous participation', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = this.server.create('poll', {
|
||||
anonymousUser: true,
|
||||
encryptionKey
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('network connectivity errors', function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = server.create('poll', {
|
||||
encryptionKey
|
||||
await visit(`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`);
|
||||
assert.equal(currentRouteName(), 'poll.participation');
|
||||
|
||||
await pollParticipate(null, ['yes', 'no']);
|
||||
assert.equal(currentRouteName(), 'poll.evaluation');
|
||||
pollHasUsersCount(assert, 1, 'user is added to user selections table');
|
||||
pollHasUser(assert, '', [t('answerTypes.yes.label'), t('answerTypes.no.label')]);
|
||||
});
|
||||
|
||||
server.post('/users', undefined, 503);
|
||||
|
||||
visit(`/poll/${poll.id}/participation?encryptionKey=${encryptionKey}`).then(function() {
|
||||
assert.equal(currentPath(), 'poll.participation');
|
||||
pollParticipate('foo bar', ['yes', 'no']);
|
||||
|
||||
andThen(() => {
|
||||
assert.ok(
|
||||
find('#modal-saving-failed-modal').is(':visible'),
|
||||
'user gets notified that saving failed'
|
||||
);
|
||||
|
||||
server.post('/users');
|
||||
click('#modal-saving-failed-modal button');
|
||||
|
||||
andThen(() => {
|
||||
assert.notOk(
|
||||
find('#modal-saving-failed-modal').is(':visible'),
|
||||
'modal is hidden after saving was successful'
|
||||
);
|
||||
assert.equal(currentPath(), 'poll.evaluation');
|
||||
pollHasUsersCount(assert, 1, 'user is added to user selections table');
|
||||
pollHasUser(assert, 'foo bar', [t('answerTypes.yes.label'), t('answerTypes.no.label')]);
|
||||
});
|
||||
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');
|
||||
|
||||
await pollParticipate('foo bar', ['yes', 'no']);
|
||||
assert.ok(
|
||||
jQuery(find('#modal-saving-failed-modal')).is(':visible'),
|
||||
'user gets notified that saving failed'
|
||||
);
|
||||
|
||||
this.server.post('/users');
|
||||
|
||||
await click('#modal-saving-failed-modal button');
|
||||
assert.notOk(
|
||||
jQuery(find('#modal-saving-failed-modal')).is(':visible'),
|
||||
'modal is hidden after saving was successful'
|
||||
);
|
||||
assert.equal(currentRouteName(), 'poll.evaluation');
|
||||
pollHasUsersCount(assert, 1, 'user is added to user selections table');
|
||||
pollHasUser(assert, 'foo bar', [t('answerTypes.yes.label'), t('answerTypes.no.label')]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,307 +1,295 @@
|
|||
import { test } from 'qunit';
|
||||
import jQuery from 'jquery';
|
||||
import moduleForAcceptance from 'croodle/tests/helpers/module-for-acceptance';
|
||||
import { findAll, currentRouteName, find, 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';
|
||||
import { t } from 'ember-i18n/test-support';
|
||||
import switchTab from 'croodle/tests/helpers/switch-tab';
|
||||
import moment from 'moment';
|
||||
/* jshint proto: true */
|
||||
|
||||
moduleForAcceptance('Acceptance | view evaluation', {
|
||||
beforeEach() {
|
||||
module('Acceptance | view evaluation', function(hooks) {
|
||||
hooks.beforeEach(function() {
|
||||
window.localStorage.setItem('locale', 'en');
|
||||
moment.locale('en');
|
||||
}
|
||||
});
|
||||
|
||||
test('evaluation summary is not present for poll without participants', function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = server.create('poll', {
|
||||
encryptionKey
|
||||
});
|
||||
|
||||
visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.participation');
|
||||
switchTab('evaluation');
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(find('.tab-content .tab-pane .evaluation-summary').length, 0, 'evaluation summary is not present');
|
||||
test('evaluation summary is not present for poll without participants', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = this.server.create('poll', {
|
||||
encryptionKey
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('evaluation is correct for FindADate', function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let user1 = server.create('user', {
|
||||
creationDate: '2015-01-01T00:00:00.000Z',
|
||||
encryptionKey,
|
||||
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'
|
||||
}
|
||||
]
|
||||
});
|
||||
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]
|
||||
await visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
|
||||
assert.equal(currentRouteName(), 'poll.participation');
|
||||
|
||||
await switchTab('evaluation');
|
||||
assert.equal(findAll('.tab-content .tab-pane .evaluation-summary').length, 0, 'evaluation summary is not present');
|
||||
});
|
||||
|
||||
visit(`/poll/${poll.id}/evaluation?encryptionKey=${encryptionKey}`);
|
||||
test('evaluation is correct for FindADate', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let user1 = this.server.create('user', {
|
||||
creationDate: '2015-01-01T00:00:00.000Z',
|
||||
encryptionKey,
|
||||
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'
|
||||
}
|
||||
]
|
||||
});
|
||||
let user2 = this.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 = this.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]
|
||||
});
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.evaluation');
|
||||
assert.equal(find('.tab-content .tab-pane .evaluation-summary').length, 1, 'evaluation summary is present');
|
||||
await visit(`/poll/${poll.id}/evaluation?encryptionKey=${encryptionKey}`);
|
||||
assert.equal(currentRouteName(), 'poll.evaluation');
|
||||
assert.equal(findAll('.tab-content .tab-pane .evaluation-summary').length, 1, 'evaluation summary is present');
|
||||
assert.equal(
|
||||
find('.participants').text().trim(),
|
||||
find('.participants').textContent.trim(),
|
||||
t('poll.evaluation.participants', { count: 2 }).toString(),
|
||||
'participants are counted correctly'
|
||||
);
|
||||
assert.equal(
|
||||
find('.best-options strong').text().trim(),
|
||||
find('.best-options strong').textContent.trim(),
|
||||
'Friday, January 1, 2016',
|
||||
'options are evaluated correctly'
|
||||
);
|
||||
assert.equal(
|
||||
find('.last-participation').text().trim(),
|
||||
find('.last-participation').textContent.trim(),
|
||||
t('poll.evaluation.lastParticipation', {
|
||||
ago: moment('2015-08-01T00:00:00.000Z').from()
|
||||
}).toString(),
|
||||
'last participation is evaluated correctly'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('evaluation is correct for MakeAPoll', function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let user1 = server.create('user', {
|
||||
creationDate: '2015-01-01T00:00:00.000Z',
|
||||
encryptionKey,
|
||||
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'
|
||||
}
|
||||
]
|
||||
});
|
||||
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]
|
||||
});
|
||||
test('evaluation is correct for MakeAPoll', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let user1 = this.server.create('user', {
|
||||
creationDate: '2015-01-01T00:00:00.000Z',
|
||||
encryptionKey,
|
||||
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'
|
||||
}
|
||||
]
|
||||
});
|
||||
let user2 = this.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 = this.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/${poll.id}/evaluation?encryptionKey=${encryptionKey}`);
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.evaluation');
|
||||
assert.equal(find('.tab-content .tab-pane .evaluation-summary').length, 1, 'evaluation summary is present');
|
||||
await visit(`/poll/${poll.id}/evaluation?encryptionKey=${encryptionKey}`);
|
||||
assert.equal(currentRouteName(), 'poll.evaluation');
|
||||
assert.equal(findAll('.tab-content .tab-pane .evaluation-summary').length, 1, 'evaluation summary is present');
|
||||
assert.equal(
|
||||
find('.participants').text().trim(),
|
||||
find('.participants').textContent.trim(),
|
||||
t('poll.evaluation.participants', { count: 2 }).toString(),
|
||||
'participants are counted correctly'
|
||||
);
|
||||
assert.equal(
|
||||
find('.best-options strong').text().trim(),
|
||||
find('.best-options strong').textContent.trim(),
|
||||
'second option',
|
||||
'options are evaluated correctly'
|
||||
);
|
||||
assert.ok(
|
||||
find('.user-selections-table').length,
|
||||
findAll('.user-selections-table').length,
|
||||
'has a table showing user selections'
|
||||
);
|
||||
assert.deepEqual(
|
||||
find('.user-selections-table thead th').map((i, el) => jQuery(el).text().trim()).get(),
|
||||
findAll('.user-selections-table thead th').toArray().map((el) => el.textContent.trim()),
|
||||
['', 'first option', 'second option'],
|
||||
'dates are used as table headers'
|
||||
);
|
||||
assert.deepEqual(
|
||||
find('.user-selections-table tbody tr:nth-child(1) td').map((i, el) => jQuery(el).text().trim()).get(),
|
||||
findAll('.user-selections-table tbody tr:nth-child(1) td').toArray().map((el) => el.textContent.trim()),
|
||||
['Maximilian', 'Yes', 'Yes'],
|
||||
'answers shown in table are correct for first user'
|
||||
);
|
||||
assert.deepEqual(
|
||||
find('.user-selections-table tbody tr:nth-child(2) td').map((i, el) => jQuery(el).text().trim()).get(),
|
||||
findAll('.user-selections-table tbody tr:nth-child(2) td').toArray().map((el) => el.textContent.trim()),
|
||||
['Peter', 'No', 'Yes'],
|
||||
'answers shown in table are correct for second user'
|
||||
);
|
||||
assert.equal(
|
||||
find('.last-participation').text().trim(),
|
||||
find('.last-participation').textContent.trim(),
|
||||
t('poll.evaluation.lastParticipation', {
|
||||
ago: moment('2015-08-01T00:00:00.000Z').from()
|
||||
}).toString(),
|
||||
'last participation is evaluated correctly'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('could open evaluation by tab from poll participation', function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
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: [
|
||||
server.create('user', {
|
||||
creationDate: '2015-01-01T00:00:00.000Z',
|
||||
encryptionKey,
|
||||
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'
|
||||
}
|
||||
]
|
||||
}),
|
||||
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/${poll.id}?encryptionKey=${encryptionKey}`);
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.participation');
|
||||
switchTab('evaluation');
|
||||
|
||||
andThen(function() {
|
||||
assert.equal(currentPath(), 'poll.evaluation');
|
||||
assert.equal(
|
||||
find('.tab-pane h2').text().trim(),
|
||||
t('poll.evaluation.label').toString(),
|
||||
'headline is there'
|
||||
);
|
||||
test('could open evaluation by tab from poll participation', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = this.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: [
|
||||
this.server.create('user', {
|
||||
creationDate: '2015-01-01T00:00:00.000Z',
|
||||
encryptionKey,
|
||||
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'
|
||||
}
|
||||
]
|
||||
}),
|
||||
this.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'
|
||||
}
|
||||
]
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
await visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
|
||||
assert.equal(currentRouteName(), 'poll.participation');
|
||||
|
||||
await switchTab('evaluation');
|
||||
assert.equal(currentRouteName(), 'poll.evaluation');
|
||||
assert.equal(
|
||||
find('.tab-pane h2').textContent.trim(),
|
||||
t('poll.evaluation.label').toString(),
|
||||
'headline is there'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,24 +1,27 @@
|
|||
import { test } from 'qunit';
|
||||
import moduleForAcceptance from 'croodle/tests/helpers/module-for-acceptance';
|
||||
import { find, click, 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';
|
||||
import switchTab from 'croodle/tests/helpers/switch-tab';
|
||||
import pageParticipation from 'croodle/tests/pages/poll/participation';
|
||||
import pageEvaluation from 'croodle/tests/pages/poll/evaluation';
|
||||
import moment from 'moment';
|
||||
/* jshint proto: true */
|
||||
import jQuery from 'jquery';
|
||||
|
||||
moduleForAcceptance('Acceptance | view poll', {
|
||||
beforeEach() {
|
||||
module('Acceptance | view poll', function(hooks) {
|
||||
hooks.beforeEach(function() {
|
||||
window.localStorage.setItem('locale', 'en');
|
||||
moment.locale('en');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('poll url', function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz012345789';
|
||||
let poll = server.create('poll', { encryptionKey });
|
||||
let pollUrl = `/poll/${poll.id}?encryptionKey=${encryptionKey}`;
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
|
||||
visit(pollUrl);
|
||||
andThen(function() {
|
||||
test('poll url', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz012345789';
|
||||
let poll = this.server.create('poll', { encryptionKey });
|
||||
let pollUrl = `/poll/${poll.id}?encryptionKey=${encryptionKey}`;
|
||||
|
||||
await visit(pollUrl);
|
||||
assert.equal(
|
||||
pageParticipation.url,
|
||||
window.location.href,
|
||||
|
@ -34,32 +37,31 @@ test('poll url', function(assert) {
|
|||
* https://github.com/poteto/ember-cli-flash/issues/202
|
||||
*/
|
||||
});
|
||||
});
|
||||
|
||||
test('shows a warning if poll is about to be expired', function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = server.create('poll', {
|
||||
encryptionKey,
|
||||
expirationDate: moment().add(1, 'week')
|
||||
});
|
||||
visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`).then(function() {
|
||||
test('shows a warning if poll is about to be expired', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = this.server.create('poll', {
|
||||
encryptionKey,
|
||||
expirationDate: moment().add(1, 'week')
|
||||
});
|
||||
|
||||
await visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
|
||||
assert.ok(
|
||||
pageParticipation.showsExpirationWarning
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('view a poll with dates', function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = server.create('poll', {
|
||||
encryptionKey,
|
||||
options: [
|
||||
{ title: '2015-12-12' },
|
||||
{ title: '2016-01-01' }
|
||||
]
|
||||
});
|
||||
test('view a poll with dates', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let poll = this.server.create('poll', {
|
||||
encryptionKey,
|
||||
options: [
|
||||
{ title: '2015-12-12' },
|
||||
{ title: '2016-01-01' }
|
||||
]
|
||||
});
|
||||
|
||||
visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`).then(function() {
|
||||
await visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
|
||||
assert.deepEqual(
|
||||
pageParticipation.options().labels,
|
||||
[
|
||||
|
@ -68,24 +70,23 @@ test('view a poll with dates', function(assert) {
|
|||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('view a poll with dates and times', function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let timezone = moment.tz.guess();
|
||||
let poll = server.create('poll', {
|
||||
encryptionKey,
|
||||
expirationDate: moment().add(1, 'year'),
|
||||
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
|
||||
});
|
||||
test('view a poll with dates and times', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let timezone = moment.tz.guess();
|
||||
let poll = this.server.create('poll', {
|
||||
encryptionKey,
|
||||
expirationDate: moment().add(1, 'year'),
|
||||
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/${poll.id}?encryptionKey=${encryptionKey}`).then(function() {
|
||||
await visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
|
||||
assert.deepEqual(
|
||||
pageParticipation.options().labels,
|
||||
[
|
||||
|
@ -102,123 +103,122 @@ test('view a poll with dates and times', function(assert) {
|
|||
'does not show an expiration warning if poll will not expire in next weeks'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('view a poll while timezone differs from the one poll got created in and choose local timezone', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let timezoneUser = moment.tz.guess();
|
||||
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,
|
||||
users: [
|
||||
server.create('user', {
|
||||
encryptionKey,
|
||||
selections: [
|
||||
{
|
||||
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'
|
||||
}
|
||||
]
|
||||
})
|
||||
]
|
||||
test('view a poll while timezone differs from the one poll got created in and choose local timezone', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let timezoneUser = moment.tz.guess();
|
||||
let timezonePoll = timezoneUser !== 'America/Caracas' ? 'America/Caracas' : 'Europe/Moscow';
|
||||
let poll = this.server.create('poll', {
|
||||
encryptionKey,
|
||||
isDateTime: true,
|
||||
options: [
|
||||
{ title: '2015-12-12T11:11:00.000Z' },
|
||||
{ title: '2016-01-01T11:11:00.000Z' }
|
||||
],
|
||||
timezone: timezonePoll,
|
||||
users: [
|
||||
this.server.create('user', {
|
||||
encryptionKey,
|
||||
selections: [
|
||||
{
|
||||
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'
|
||||
}
|
||||
]
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
await visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
|
||||
assert.ok(
|
||||
jQuery(find('#modal-choose-timezone-modal')).is(':visible'),
|
||||
'user gets asked which timezone should be used'
|
||||
);
|
||||
|
||||
await click('#modal-choose-timezone-modal button.use-local-timezone');
|
||||
assert.deepEqual(
|
||||
pageParticipation.options().labels,
|
||||
[
|
||||
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')
|
||||
]
|
||||
);
|
||||
assert.notOk(
|
||||
jQuery(find('#modal-choose-timezone-modal')).is(':visible'),
|
||||
'modal is closed'
|
||||
);
|
||||
|
||||
await switchTab('evaluation');
|
||||
assert.deepEqual(
|
||||
pageEvaluation.preferedOptions,
|
||||
[moment.tz('2015-12-12T11:11:00.000Z', timezoneUser).locale('en').format('LLLL')]
|
||||
);
|
||||
});
|
||||
|
||||
await visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
|
||||
assert.ok(
|
||||
find('#modal-choose-timezone-modal').is(':visible'),
|
||||
'user gets asked which timezone should be used'
|
||||
);
|
||||
test('view a poll while timezone differs from the one poll got created in and choose poll timezone', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let timezoneUser = moment.tz.guess();
|
||||
let timezonePoll = timezoneUser !== 'America/Caracas' ? 'America/Caracas' : 'Europe/Moscow';
|
||||
let poll = this.server.create('poll', {
|
||||
encryptionKey,
|
||||
isDateTime: true,
|
||||
options: [
|
||||
{ title: '2015-12-12T11:11:00.000Z' },
|
||||
{ title: '2016-01-01T11:11:00.000Z' }
|
||||
],
|
||||
timezone: timezonePoll,
|
||||
users: [
|
||||
this.server.create('user', {
|
||||
encryptionKey,
|
||||
selections: [
|
||||
{
|
||||
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'
|
||||
}
|
||||
]
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
await click('#modal-choose-timezone-modal button.use-local-timezone');
|
||||
assert.deepEqual(
|
||||
pageParticipation.options().labels,
|
||||
[
|
||||
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')
|
||||
]
|
||||
);
|
||||
assert.notOk(
|
||||
find('#modal-choose-timezone-modal').is(':visible'),
|
||||
'modal is closed'
|
||||
);
|
||||
await visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
|
||||
assert.ok(
|
||||
jQuery(find('#modal-choose-timezone-modal')).is(':visible'),
|
||||
'user gets asked which timezone should be used'
|
||||
);
|
||||
|
||||
await switchTab('evaluation');
|
||||
assert.deepEqual(
|
||||
pageEvaluation.preferedOptions,
|
||||
[moment.tz('2015-12-12T11:11:00.000Z', timezoneUser).locale('en').format('LLLL')]
|
||||
);
|
||||
});
|
||||
await click('#modal-choose-timezone-modal button.use-poll-timezone');
|
||||
assert.deepEqual(
|
||||
pageParticipation.options().labels,
|
||||
[
|
||||
moment.tz('2015-12-12T11:11:00.000Z', timezonePoll).locale('en').format('LLLL'),
|
||||
moment.tz('2016-01-01T11:11:00.000Z', timezonePoll).locale('en').format('LLLL')
|
||||
]
|
||||
);
|
||||
assert.notOk(
|
||||
jQuery(find('#modal-choose-timezone-modal')).is(':visible'),
|
||||
'modal is closed'
|
||||
);
|
||||
|
||||
test('view a poll while timezone differs from the one poll got created in and choose poll timezone', async function(assert) {
|
||||
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let timezoneUser = moment.tz.guess();
|
||||
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,
|
||||
users: [
|
||||
server.create('user', {
|
||||
encryptionKey,
|
||||
selections: [
|
||||
{
|
||||
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'
|
||||
}
|
||||
]
|
||||
})
|
||||
]
|
||||
await switchTab('evaluation');
|
||||
assert.deepEqual(
|
||||
pageEvaluation.preferedOptions,
|
||||
[moment.tz('2015-12-12T11:11:00.000Z', timezonePoll).locale('en').format('LLLL')]
|
||||
);
|
||||
});
|
||||
|
||||
await visit(`/poll/${poll.id}?encryptionKey=${encryptionKey}`);
|
||||
assert.ok(
|
||||
find('#modal-choose-timezone-modal').is(':visible'),
|
||||
'user gets asked which timezone should be used'
|
||||
);
|
||||
|
||||
await click('#modal-choose-timezone-modal button.use-poll-timezone');
|
||||
assert.deepEqual(
|
||||
pageParticipation.options().labels,
|
||||
[
|
||||
moment.tz('2015-12-12T11:11:00.000Z', timezonePoll).locale('en').format('LLLL'),
|
||||
moment.tz('2016-01-01T11:11:00.000Z', timezonePoll).locale('en').format('LLLL')
|
||||
]
|
||||
);
|
||||
|
||||
assert.notOk(
|
||||
find('#modal-choose-timezone-modal').is(':visible'),
|
||||
'modal is closed'
|
||||
);
|
||||
|
||||
await switchTab('evaluation');
|
||||
assert.deepEqual(
|
||||
pageEvaluation.preferedOptions,
|
||||
[moment.tz('2015-12-12T11:11:00.000Z', timezonePoll).locale('en').format('LLLL')]
|
||||
);
|
||||
});
|
||||
|
|
0
tests/helpers/.gitkeep
Normal file
0
tests/helpers/.gitkeep
Normal file
|
@ -1,10 +0,0 @@
|
|||
import { run } from '@ember/runloop';
|
||||
|
||||
export default function destroyApp(application) {
|
||||
// this is required to fix "second Pretender instance" warnings
|
||||
if (server) {
|
||||
server.shutdown();
|
||||
}
|
||||
|
||||
run(application, 'destroy');
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
import { module } from 'qunit';
|
||||
import { resolve } from 'rsvp';
|
||||
import startApp from '../helpers/start-app';
|
||||
import destroyApp from '../helpers/destroy-app';
|
||||
|
||||
export default function(name, options = {}) {
|
||||
module(name, {
|
||||
beforeEach(assert) {
|
||||
this.application = startApp({ assert });
|
||||
|
||||
if (options.beforeEach) {
|
||||
return options.beforeEach.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
|
||||
afterEach() {
|
||||
let afterEach = options.afterEach && options.afterEach.apply(this, arguments);
|
||||
return resolve(afterEach).then(() => destroyApp(this.application));
|
||||
}
|
||||
});
|
||||
}
|
33
tests/helpers/poll-has-user.js
Normal file
33
tests/helpers/poll-has-user.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { isEmpty } from '@ember/utils';
|
||||
import { findAll } from '@ember/test-helpers';
|
||||
|
||||
function pollHasUser(assert, name, selections) {
|
||||
let elBase = findAll('.user').find((el) => {
|
||||
return el.querySelector('td:nth-child(1)').textContent.trim() === name;
|
||||
});
|
||||
assert.ok(elBase, `user ${name} exists`);
|
||||
|
||||
if (elBase) {
|
||||
selections.forEach((selection, index) => {
|
||||
assert.equal(
|
||||
elBase.querySelector(`td:nth-child(${index + 2})`).textContent.trim(),
|
||||
selection.toString(),
|
||||
`selection ${index} is as expected`
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function pollHasUsersCount(assert, count, message) {
|
||||
if (isEmpty(message)) {
|
||||
message = 'poll has expected count of users';
|
||||
}
|
||||
assert.equal(
|
||||
findAll('.user').length,
|
||||
count,
|
||||
message
|
||||
);
|
||||
}
|
||||
|
||||
export default pollHasUser;
|
||||
export { pollHasUsersCount };
|
|
@ -1,37 +0,0 @@
|
|||
import { isEmpty } from '@ember/utils';
|
||||
import { registerHelper } from '@ember/test';
|
||||
|
||||
const helpers = function() {
|
||||
registerHelper('pollHasUser', function(app, assert, name, selections) {
|
||||
let elBase;
|
||||
find('.user').each((index, el) => {
|
||||
if (find('td:nth-child(1)', el).text().trim() === name) {
|
||||
elBase = el;
|
||||
}
|
||||
});
|
||||
assert.ok(elBase, `user ${name} exists`);
|
||||
|
||||
if (elBase) {
|
||||
selections.forEach((selection, index) => {
|
||||
assert.equal(
|
||||
find(`td:nth-child(${index + 2})`, elBase).text().trim(),
|
||||
selection,
|
||||
`selection ${index} is as expected`
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
registerHelper('pollHasUsersCount', function(app, assert, count, message) {
|
||||
if (isEmpty(message)) {
|
||||
message = 'poll has expected count of users';
|
||||
}
|
||||
assert.equal(
|
||||
find('.user').length,
|
||||
count,
|
||||
message
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
export default helpers();
|
|
@ -1,21 +1,21 @@
|
|||
import { isEmpty } from '@ember/utils';
|
||||
import { registerAsyncHelper } from '@ember/test';
|
||||
import { findAll, fillIn, click } from '@ember/test-helpers';
|
||||
|
||||
export default registerAsyncHelper('pollParticipate', function(app, name, selections) {
|
||||
export default async function(name, selections) {
|
||||
if (!isEmpty(name)) {
|
||||
fillIn('.participation .name input', name);
|
||||
await fillIn('.participation .name input', name);
|
||||
}
|
||||
|
||||
const isFreeText = find('.participation .selections .radio').length ? false : true;
|
||||
selections.forEach((selection, index) => {
|
||||
const isFreeText = findAll('.participation .selections .radio').length > 0 ? false : true;
|
||||
for (let [index, selection] of selections.entries()) {
|
||||
if (!isEmpty(selection)) {
|
||||
if (isFreeText) {
|
||||
fillIn(`.participation .selections .form-group:nth-child(${index + 1}) input`, selection);
|
||||
await fillIn(`.participation .selections .form-group:nth-child(${index + 1}) input`, selection);
|
||||
} else {
|
||||
click(`.participation .selections .form-group:nth-child(${index + 1}) .${selection}.radio input`);
|
||||
await click(`.participation .selections .form-group:nth-child(${index + 1}) .${selection}.radio input`);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
click('.participation button[type="submit"]');
|
||||
});
|
||||
await click('.participation button[type="submit"]');
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
import Application from '../../app';
|
||||
import config from '../../config/environment';
|
||||
import { merge } from '@ember/polyfills';
|
||||
import { run } from '@ember/runloop';
|
||||
import './poll-has-users';
|
||||
import './poll-participate';
|
||||
import './switch-tab';
|
||||
import registerAcceptanceTestHelpers from './201-created/register-acceptance-test-helpers';
|
||||
import registerBrowserNavigationButtonTestHelpers from './browser-navigation-buttons';
|
||||
import './ember-i18n/test-helpers';
|
||||
|
||||
export default function startApp(attrs) {
|
||||
let attributes = merge({}, config.APP);
|
||||
attributes.autoboot = true;
|
||||
attributes = merge(attributes, attrs); // use defaults, but you can override;
|
||||
|
||||
return run(() => {
|
||||
let application = Application.create(attributes);
|
||||
application.setupForTesting();
|
||||
|
||||
registerAcceptanceTestHelpers(attrs.assert || window.QUnit.assert);
|
||||
registerBrowserNavigationButtonTestHelpers();
|
||||
|
||||
application.injectTestHelpers();
|
||||
return application;
|
||||
});
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { registerAsyncHelper } from '@ember/test';
|
||||
import { click } from '@ember/test-helpers';
|
||||
|
||||
export default registerAsyncHelper('switchTab', function(app, tab) {
|
||||
click(`.nav-tabs .${tab} a`);
|
||||
});
|
||||
export default function(tab) {
|
||||
return click(`.nav-tabs .${tab} a`);
|
||||
}
|
||||
|
|
|
@ -1,66 +1,68 @@
|
|||
import EmberObject from '@ember/object';
|
||||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import moment from 'moment';
|
||||
|
||||
moduleForComponent('create-options-dates', 'Integration | Component | create options dates', {
|
||||
integration: true
|
||||
});
|
||||
|
||||
test('it renders a ember-cli-bootstrap-datepicker component', function(assert) {
|
||||
this.set('options', []);
|
||||
this.render(hbs`{{#bs-form as |form|}}{{create-options-dates options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
assert.equal(
|
||||
this.$('.days .ember-view:has(.datepicker:first-child)').length, 1
|
||||
);
|
||||
});
|
||||
|
||||
test('bootstrap-datepicker shows dates in options', function(assert) {
|
||||
this.set('options', [
|
||||
EmberObject.create({ title: '2015-01-01' }),
|
||||
EmberObject.create({ title: '2015-01-02' })
|
||||
]);
|
||||
this.render(hbs`{{#bs-form as |form|}}{{create-options-dates options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
assert.equal(
|
||||
this.$('.days .ember-view:has(.datepicker:first-child)').datepicker('getDates')[0].toISOString(),
|
||||
moment('2015-01-01').toISOString(),
|
||||
'date is correct (a)'
|
||||
);
|
||||
assert.equal(
|
||||
this.$('.days .ember-view:has(.datepicker:first-child)').datepicker('getDates')[1].toISOString(),
|
||||
moment('2015-01-02').toISOString(),
|
||||
'date is correct (b)'
|
||||
);
|
||||
});
|
||||
|
||||
test('dates set in bootstrap-datepicker are set to options', function(assert) {
|
||||
this.set('options', []);
|
||||
this.render(hbs`{{#bs-form as |form|}}{{create-options-dates options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
this.$('.days .ember-view:has(.datepicker:first-child)').datepicker('setDates', [
|
||||
moment('2015-01-01').toDate(),
|
||||
moment('2015-01-02').toDate()
|
||||
]);
|
||||
assert.equal(
|
||||
this.get('options.0.title'),
|
||||
'2015-01-01',
|
||||
'dates are correct (a)'
|
||||
);
|
||||
assert.equal(
|
||||
this.get('options.1.title'),
|
||||
'2015-01-02',
|
||||
'dates are correct (b)'
|
||||
);
|
||||
|
||||
this.$('.days .ember-view:has(.datepicker:first-child)').datepicker('setDates', [
|
||||
moment('2016-12-31').toDate(),
|
||||
moment('2016-01-01').toDate()
|
||||
]);
|
||||
assert.equal(
|
||||
this.get('options.firstObject.title'),
|
||||
'2016-01-01',
|
||||
'dates are sorted'
|
||||
);
|
||||
module('Integration | Component | create options dates', function(hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders a ember-cli-bootstrap-datepicker component', async function(assert) {
|
||||
this.set('options', []);
|
||||
await render(hbs`{{#bs-form as |form|}}{{create-options-dates options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
assert.equal(
|
||||
this.$('.days .ember-view:has(.datepicker:first-child)').length, 1
|
||||
);
|
||||
});
|
||||
|
||||
test('bootstrap-datepicker shows dates in options', async function(assert) {
|
||||
this.set('options', [
|
||||
EmberObject.create({ title: '2015-01-01' }),
|
||||
EmberObject.create({ title: '2015-01-02' })
|
||||
]);
|
||||
await render(hbs`{{#bs-form as |form|}}{{create-options-dates options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
assert.equal(
|
||||
this.$('.days .ember-view:has(.datepicker:first-child)').datepicker('getDates')[0].toISOString(),
|
||||
moment('2015-01-01').toISOString(),
|
||||
'date is correct (a)'
|
||||
);
|
||||
assert.equal(
|
||||
this.$('.days .ember-view:has(.datepicker:first-child)').datepicker('getDates')[1].toISOString(),
|
||||
moment('2015-01-02').toISOString(),
|
||||
'date is correct (b)'
|
||||
);
|
||||
});
|
||||
|
||||
test('dates set in bootstrap-datepicker are set to options', async function(assert) {
|
||||
this.set('options', []);
|
||||
await render(hbs`{{#bs-form as |form|}}{{create-options-dates options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
this.$('.days .ember-view:has(.datepicker:first-child)').datepicker('setDates', [
|
||||
moment('2015-01-01').toDate(),
|
||||
moment('2015-01-02').toDate()
|
||||
]);
|
||||
assert.equal(
|
||||
this.get('options.0.title'),
|
||||
'2015-01-01',
|
||||
'dates are correct (a)'
|
||||
);
|
||||
assert.equal(
|
||||
this.get('options.1.title'),
|
||||
'2015-01-02',
|
||||
'dates are correct (b)'
|
||||
);
|
||||
|
||||
this.$('.days .ember-view:has(.datepicker:first-child)').datepicker('setDates', [
|
||||
moment('2016-12-31').toDate(),
|
||||
moment('2016-01-01').toDate()
|
||||
]);
|
||||
assert.equal(
|
||||
this.get('options.firstObject.title'),
|
||||
'2016-01-01',
|
||||
'dates are sorted'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,196 +1,204 @@
|
|||
import { alias } from '@ember/object/computed';
|
||||
import { run } from '@ember/runloop';
|
||||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import {
|
||||
render,
|
||||
click,
|
||||
fillIn,
|
||||
find,
|
||||
findAll,
|
||||
triggerEvent
|
||||
} from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import jQuery from 'jquery';
|
||||
import moment from 'moment';
|
||||
|
||||
moduleForComponent('create-options-datetime', 'Integration | Component | create options datetime', {
|
||||
integration: true,
|
||||
beforeEach() {
|
||||
this.inject.service('store');
|
||||
}
|
||||
});
|
||||
module('Integration | Component | create options datetime', function(hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
/*
|
||||
* watch out:
|
||||
* polyfill adds another input[type="text"] for every input[type="time"]
|
||||
* if browser doesn't support input[type="time"]
|
||||
* that ones could be identifed by class 'ws-inputreplace'
|
||||
*/
|
||||
|
||||
test('it generates inpute field for options iso 8601 date string (without time)', function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
isFindADate: true,
|
||||
isMakeAPoll: false,
|
||||
options: [
|
||||
{ title: '2015-01-01' }
|
||||
]
|
||||
}));
|
||||
hooks.beforeEach(function() {
|
||||
this.store = this.owner.lookup('service:store');
|
||||
});
|
||||
this.render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
|
||||
assert.equal(
|
||||
this.$('.days .form-group input').length,
|
||||
1,
|
||||
'there is one input field'
|
||||
);
|
||||
assert.equal(
|
||||
this.$('.days .form-group input').val(),
|
||||
'',
|
||||
'value is an empty string'
|
||||
);
|
||||
});
|
||||
/*
|
||||
* watch out:
|
||||
* polyfill adds another input[type="text"] for every input[type="time"]
|
||||
* if browser doesn't support input[type="time"]
|
||||
* that ones could be identifed by class 'ws-inputreplace'
|
||||
*/
|
||||
|
||||
test('it generates inpute field for options iso 8601 datetime string (with time)', function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
isFindADate: true,
|
||||
isMakeAPoll: false,
|
||||
options: [
|
||||
{ title: '2015-01-01T11:11:00.000Z' }
|
||||
]
|
||||
}));
|
||||
});
|
||||
this.render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
test('it generates inpute field for options iso 8601 date string (without time)', async function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
isFindADate: true,
|
||||
isMakeAPoll: false,
|
||||
options: [
|
||||
{ title: '2015-01-01' }
|
||||
]
|
||||
}));
|
||||
});
|
||||
await render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
|
||||
assert.equal(
|
||||
this.$('.days .form-group input').length,
|
||||
1,
|
||||
'there is one input field'
|
||||
);
|
||||
assert.equal(
|
||||
this.$('.days .form-group input').val(),
|
||||
moment('2015-01-01T11:11:00.000Z').format('HH:mm'),
|
||||
'it has time in option as value'
|
||||
);
|
||||
});
|
||||
|
||||
test('it hides repeated labels', function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
isFindADate: true,
|
||||
isMakeAPoll: false,
|
||||
options: [
|
||||
{ title: moment('2015-01-01T10:11').toISOString() },
|
||||
{ title: moment('2015-01-01T22:22').toISOString() },
|
||||
{ title: '2015-02-02' }
|
||||
]
|
||||
}));
|
||||
});
|
||||
this.render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
|
||||
assert.equal(
|
||||
this.$('.days label').length,
|
||||
3,
|
||||
'every form-group has a label'
|
||||
);
|
||||
assert.equal(
|
||||
this.$('.days label:not(.sr-only)').length,
|
||||
2,
|
||||
'there are two not hidden labels for two different dates'
|
||||
);
|
||||
assert.notOk(
|
||||
this.$('.days .form-group').eq(0).find('label').hasClass('sr-only'),
|
||||
'the first label is shown'
|
||||
);
|
||||
assert.ok(
|
||||
this.$('.days .form-group').eq(1).find('label').hasClass('sr-only'),
|
||||
'the repeated label on second form-group is hidden by sr-only class'
|
||||
);
|
||||
assert.notOk(
|
||||
this.$('.days .form-group').eq(2).find('label').hasClass('sr-only'),
|
||||
'the new label on third form-group is shown'
|
||||
);
|
||||
});
|
||||
|
||||
test('allows to add another option', function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
options: [
|
||||
{ title: '2015-01-01' },
|
||||
{ title: '2015-02-02' }
|
||||
]
|
||||
}));
|
||||
});
|
||||
this.render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
|
||||
assert.equal(
|
||||
this.$('.days .form-group input').length,
|
||||
2,
|
||||
'there are two input fields before'
|
||||
);
|
||||
this.$('.days .form-group').eq(0).find('.add').click();
|
||||
assert.equal(
|
||||
this.$('.days .form-group input').length,
|
||||
3,
|
||||
'another input field is added'
|
||||
);
|
||||
assert.equal(
|
||||
this.$('.days .form-group').eq(1).find('label').text(),
|
||||
this.$('.days .form-group').eq(0).find('label').text(),
|
||||
'new input has correct label'
|
||||
);
|
||||
assert.ok(
|
||||
this.$('.days .form-group').eq(1).find('label').hasClass('sr-only'),
|
||||
'label ofnew input is hidden cause it\'s repeated'
|
||||
);
|
||||
});
|
||||
|
||||
test('allows to delete an option', function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
isFindADate: true,
|
||||
isMakeAPoll: false,
|
||||
options: [
|
||||
{ title: moment('2015-01-01T11:11').toISOString() },
|
||||
{ title: moment('2015-01-01T22:22').toISOString() }
|
||||
]
|
||||
}));
|
||||
});
|
||||
this.render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
|
||||
assert.equal(
|
||||
this.$('.days input').length,
|
||||
2,
|
||||
'there are two input fields before'
|
||||
);
|
||||
assert.ok(
|
||||
this.$('.delete').get().every((el) => {
|
||||
return el.disabled === false;
|
||||
}),
|
||||
'options are deleteable'
|
||||
);
|
||||
this.$('.days .form-group').eq(0).find('.delete').click();
|
||||
run(() => {
|
||||
assert.equal(
|
||||
this.$('.days .form-group input').length,
|
||||
findAll('.days .form-group input').length,
|
||||
1,
|
||||
'there is one input field'
|
||||
);
|
||||
assert.equal(
|
||||
find('.days .form-group input').value,
|
||||
'',
|
||||
'value is an empty string'
|
||||
);
|
||||
});
|
||||
|
||||
test('it generates inpute field for options iso 8601 datetime string (with time)', async function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
isFindADate: true,
|
||||
isMakeAPoll: false,
|
||||
options: [
|
||||
{ title: '2015-01-01T11:11:00.000Z' }
|
||||
]
|
||||
}));
|
||||
});
|
||||
await render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
|
||||
assert.equal(
|
||||
findAll('.days .form-group input').length,
|
||||
1,
|
||||
'there is one input field'
|
||||
);
|
||||
assert.equal(
|
||||
find('.days .form-group input').value,
|
||||
moment('2015-01-01T11:11:00.000Z').format('HH:mm'),
|
||||
'it has time in option as value'
|
||||
);
|
||||
});
|
||||
|
||||
test('it hides repeated labels', async function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
isFindADate: true,
|
||||
isMakeAPoll: false,
|
||||
options: [
|
||||
{ title: moment('2015-01-01T10:11').toISOString() },
|
||||
{ title: moment('2015-01-01T22:22').toISOString() },
|
||||
{ title: '2015-02-02' }
|
||||
]
|
||||
}));
|
||||
});
|
||||
await render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
|
||||
assert.equal(
|
||||
findAll('.days label').length,
|
||||
3,
|
||||
'every form-group has a label'
|
||||
);
|
||||
assert.equal(
|
||||
findAll('.days label:not(.sr-only)').length,
|
||||
2,
|
||||
'there are two not hidden labels for two different dates'
|
||||
);
|
||||
assert.notOk(
|
||||
this.$('.days .form-group').eq(0).find('label').hasClass('sr-only'),
|
||||
'the first label is shown'
|
||||
);
|
||||
assert.ok(
|
||||
this.$('.days .form-group').eq(1).find('label').hasClass('sr-only'),
|
||||
'the repeated label on second form-group is hidden by sr-only class'
|
||||
);
|
||||
assert.notOk(
|
||||
this.$('.days .form-group').eq(2).find('label').hasClass('sr-only'),
|
||||
'the new label on third form-group is shown'
|
||||
);
|
||||
});
|
||||
|
||||
test('allows to add another option', async function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
options: [
|
||||
{ title: '2015-01-01' },
|
||||
{ title: '2015-02-02' }
|
||||
]
|
||||
}));
|
||||
});
|
||||
await render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
|
||||
assert.equal(
|
||||
findAll('.days .form-group input').length,
|
||||
2,
|
||||
'there are two input fields before'
|
||||
);
|
||||
|
||||
await click(findAll('.days .form-group')[0].querySelector('.add'));
|
||||
assert.equal(
|
||||
findAll('.days .form-group input').length,
|
||||
3,
|
||||
'another input field is added'
|
||||
);
|
||||
assert.equal(
|
||||
this.$('.days .form-group').eq(1).find('label').text(),
|
||||
this.$('.days .form-group').eq(0).find('label').text(),
|
||||
'new input has correct label'
|
||||
);
|
||||
assert.ok(
|
||||
this.$('.days .form-group').eq(1).find('label').hasClass('sr-only'),
|
||||
'label ofnew input is hidden cause it\'s repeated'
|
||||
);
|
||||
});
|
||||
|
||||
test('allows to delete an option', async function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
isFindADate: true,
|
||||
isMakeAPoll: false,
|
||||
options: [
|
||||
{ title: moment('2015-01-01T11:11').toISOString() },
|
||||
{ title: moment('2015-01-01T22:22').toISOString() }
|
||||
]
|
||||
}));
|
||||
});
|
||||
await render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
|
||||
assert.equal(
|
||||
findAll('.days input').length,
|
||||
2,
|
||||
'there are two input fields before'
|
||||
);
|
||||
assert.ok(
|
||||
findAll('.delete').every((el) => el.disabled === false),
|
||||
'options are deleteable'
|
||||
);
|
||||
|
||||
await click(findAll('.days .form-group')[0].querySelector('.delete'));
|
||||
assert.equal(
|
||||
findAll('.days .form-group input').length,
|
||||
1,
|
||||
'one input field is removed after deletion'
|
||||
);
|
||||
assert.equal(
|
||||
this.$('.days .form-group input').val(),
|
||||
find('.days .form-group input').value,
|
||||
'22:22',
|
||||
'correct input field is deleted'
|
||||
);
|
||||
|
@ -205,150 +213,141 @@ test('allows to delete an option', function(assert) {
|
|||
'correct option is deleted'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('adopt times of first day - simple', function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
options: [
|
||||
{ title: moment().hour(10).minute(0).toISOString() },
|
||||
{ title: '2015-02-02' },
|
||||
{ title: '2015-03-03' }
|
||||
]
|
||||
}));
|
||||
test('adopt times of first day - simple', async function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
options: [
|
||||
{ title: moment().hour(10).minute(0).toISOString() },
|
||||
{ title: '2015-02-02' },
|
||||
{ title: '2015-03-03' }
|
||||
]
|
||||
}));
|
||||
});
|
||||
await render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
await click('button.adopt-times-of-first-day');
|
||||
assert.equal(
|
||||
findAll('.days .form-group')[0].querySelector('input').value,
|
||||
'10:00',
|
||||
'time was not changed for first day'
|
||||
);
|
||||
assert.equal(
|
||||
findAll('.days .form-group')[1].querySelector('input').value,
|
||||
'10:00',
|
||||
'time was adopted for second day'
|
||||
);
|
||||
assert.equal(
|
||||
findAll('.days .form-group')[2].querySelector('input').value,
|
||||
'10:00',
|
||||
'time was adopted for third day'
|
||||
);
|
||||
});
|
||||
this.render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
run(() => {
|
||||
this.$('button.adopt-times-of-first-day').click();
|
||||
});
|
||||
assert.equal(
|
||||
this.$('.days .form-group').eq(0).find('input').val(),
|
||||
'10:00',
|
||||
'time was not changed for first day'
|
||||
);
|
||||
assert.equal(
|
||||
this.$('.days .form-group').eq(1).find('input').val(),
|
||||
'10:00',
|
||||
'time was adopted for second day'
|
||||
);
|
||||
assert.equal(
|
||||
this.$('.days .form-group').eq(2).find('input').val(),
|
||||
'10:00',
|
||||
'time was adopted for third day'
|
||||
);
|
||||
});
|
||||
|
||||
test('adopt times of first day - more times on first day than on others', function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
options: [
|
||||
{ title: moment().hour(10).minute(0).toISOString() },
|
||||
{ title: moment().hour(22).minute(0).toISOString() },
|
||||
{ title: '2015-02-02' },
|
||||
{ title: '2015-03-03' }
|
||||
]
|
||||
}));
|
||||
test('adopt times of first day - more times on first day than on others', async function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
options: [
|
||||
{ title: moment().hour(10).minute(0).toISOString() },
|
||||
{ title: moment().hour(22).minute(0).toISOString() },
|
||||
{ title: '2015-02-02' },
|
||||
{ title: '2015-03-03' }
|
||||
]
|
||||
}));
|
||||
});
|
||||
await render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
await click('button.adopt-times-of-first-day');
|
||||
assert.deepEqual(
|
||||
this.$('.days .form-group input').map((i, el) => jQuery(el).val()).toArray(),
|
||||
['10:00', '22:00', '10:00', '22:00', '10:00', '22:00'],
|
||||
'times were adopted correctly'
|
||||
);
|
||||
});
|
||||
this.render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
run(() => {
|
||||
this.$('button.adopt-times-of-first-day').click();
|
||||
});
|
||||
assert.deepEqual(
|
||||
this.$('.days .form-group input').map((i, el) => jQuery(el).val()).toArray(),
|
||||
['10:00', '22:00', '10:00', '22:00', '10:00', '22:00'],
|
||||
'times were adopted correctly'
|
||||
);
|
||||
});
|
||||
|
||||
test('adopt times of first day - excess times on other days got deleted', function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
isFindADate: true,
|
||||
isMakeAPoll: false,
|
||||
options: [
|
||||
{ title: moment().hour(10).minute(0).toISOString() },
|
||||
{ title: moment().add(1, 'day').hour(10).minute(0).toISOString() },
|
||||
{ title: moment().add(1, 'day').hour(22).minute(0).toISOString() }
|
||||
]
|
||||
}));
|
||||
test('adopt times of first day - excess times on other days got deleted', async function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
isFindADate: true,
|
||||
isMakeAPoll: false,
|
||||
options: [
|
||||
{ title: moment().hour(10).minute(0).toISOString() },
|
||||
{ title: moment().add(1, 'day').hour(10).minute(0).toISOString() },
|
||||
{ title: moment().add(1, 'day').hour(22).minute(0).toISOString() }
|
||||
]
|
||||
}));
|
||||
});
|
||||
await render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
await click('button.adopt-times-of-first-day');
|
||||
assert.equal(
|
||||
findAll('.days .form-group').length,
|
||||
2,
|
||||
'one excess time input got deleted'
|
||||
);
|
||||
assert.deepEqual(
|
||||
this.$('.days .form-group input').map((i, el) => jQuery(el).val()).toArray(),
|
||||
['10:00', '10:00'],
|
||||
'additional time on secondary day got deleted'
|
||||
);
|
||||
});
|
||||
this.render(hbs`{{create-options-datetime dates=poll.options}}`);
|
||||
run(() => {
|
||||
this.$('button.adopt-times-of-first-day').click();
|
||||
});
|
||||
assert.equal(
|
||||
this.$('.days .form-group').length,
|
||||
2,
|
||||
'one excess time input got deleted'
|
||||
);
|
||||
assert.deepEqual(
|
||||
this.$('.days .form-group input').map((i, el) => jQuery(el).val()).toArray(),
|
||||
['10:00', '10:00'],
|
||||
'additional time on secondary day got deleted'
|
||||
);
|
||||
});
|
||||
|
||||
test('validation', function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
isFindADate: true,
|
||||
isMakeAPoll: false
|
||||
}));
|
||||
this.set('options', alias('poll.options'));
|
||||
this.get('options').pushObjects([
|
||||
{ title: '2015-01-01' },
|
||||
{ title: '2015-02-02' }
|
||||
]);
|
||||
test('validation', async function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
run(() => {
|
||||
this.set('poll', this.store.createRecord('poll', {
|
||||
isFindADate: true,
|
||||
isMakeAPoll: false
|
||||
}));
|
||||
this.set('options', alias('poll.options'));
|
||||
this.get('options').pushObjects([
|
||||
{ title: '2015-01-01' },
|
||||
{ title: '2015-02-02' }
|
||||
]);
|
||||
});
|
||||
await render(hbs`{{create-options-datetime dates=options}}`);
|
||||
assert.ok(
|
||||
findAll('.has-error').length === 0,
|
||||
'does not show a validation error before user interaction'
|
||||
);
|
||||
|
||||
await fillIn(findAll('.form-group')[1].querySelector('input'), '10:');
|
||||
assert.ok(
|
||||
findAll('.form-group')[1].classList.contains('has-error') ||
|
||||
// browsers with input type time support prevent non time input
|
||||
findAll('.form-group')[1].querySelector('input').value === '',
|
||||
'shows error after invalid input or prevents invalid input'
|
||||
);
|
||||
|
||||
// simulate unique violation
|
||||
await click(findAll('.form-group')[0].querySelector('.add'));
|
||||
await fillIn(findAll('.form-group')[0].querySelector('input'), '10:00');
|
||||
await fillIn(findAll('.form-group')[1].querySelector('input'), '10:00');
|
||||
await fillIn(findAll('.form-group')[2].querySelector('input'), '10:00');
|
||||
await triggerEvent('form', 'submit');
|
||||
assert.ok(
|
||||
findAll('.form-group')[0].classList.contains('has-success'),
|
||||
'first time shows validation success'
|
||||
);
|
||||
assert.ok(
|
||||
findAll('.form-group')[1].classList.contains('has-error'),
|
||||
'same time for same day shows validation error'
|
||||
);
|
||||
assert.ok(
|
||||
findAll('.form-group')[2].classList.contains('has-success'),
|
||||
'same time for different day shows validation success'
|
||||
);
|
||||
});
|
||||
this.render(hbs`{{create-options-datetime dates=options}}`);
|
||||
assert.ok(
|
||||
this.$('.has-error').length === 0,
|
||||
'does not show a validation error before user interaction'
|
||||
);
|
||||
this.$('.form-group').eq(1).find('input').trigger('focusout');
|
||||
assert.ok(
|
||||
this.$('.form-group').eq(1).hasClass('has-success'),
|
||||
'does show validation errors after user interaction'
|
||||
);
|
||||
this.$('.form-group').eq(1).find('input').val('10:').trigger('change');
|
||||
assert.ok(
|
||||
this.$('.form-group').eq(1).hasClass('has-error') ||
|
||||
// browsers with input type time support prevent non time input
|
||||
this.$('.form-group').eq(1).find('input').val() === '',
|
||||
'shows error after invalid input or prevents invalid input'
|
||||
);
|
||||
// simulate unique violation
|
||||
this.$('.form-group').eq(0).find('.add').click();
|
||||
this.$('.form-group input').eq(0).val('10:00').trigger('change');
|
||||
this.$('.form-group input').eq(1).val('10:00').trigger('change');
|
||||
this.$('.form-group input').eq(2).val('10:00').trigger('change');
|
||||
this.$('form').submit();
|
||||
assert.ok(
|
||||
this.$('.form-group').eq(0).hasClass('has-success'),
|
||||
'first time shows validation success'
|
||||
);
|
||||
assert.ok(
|
||||
this.$('.form-group').eq(1).hasClass('has-error'),
|
||||
'same time for same day shows validation error'
|
||||
);
|
||||
assert.ok(
|
||||
this.$('.form-group').eq(2).hasClass('has-success'),
|
||||
'same time for different day shows validation success'
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,187 +1,197 @@
|
|||
import { run } from '@ember/runloop';
|
||||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import { blur, fillIn, findAll, focus } from 'ember-native-dom-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, findAll, blur, fillIn, focus } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import hasComponent from 'croodle/tests/helpers/201-created/raw/has-component';
|
||||
|
||||
moduleForComponent('create-options', 'Integration | Component | create options', {
|
||||
integration: true,
|
||||
beforeEach() {
|
||||
this.inject.service('store');
|
||||
}
|
||||
});
|
||||
module('Integration | Component | create options', function(hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('renders component', function(assert) {
|
||||
this.set('options', []);
|
||||
this.set('isDateTime', false);
|
||||
this.set('isFindADate', true);
|
||||
this.set('isMakeAPoll', false);
|
||||
this.render(hbs`{{create-options options=options isDateTime=isDateTime isFindADate=isFindADate isMakeAPoll=isMakeAPoll}}`);
|
||||
|
||||
assert.ok(
|
||||
hasComponent(this.container, assert, 'create-options-dates').ok
|
||||
);
|
||||
assert.notOk(
|
||||
hasComponent(this.container, assert, 'create-options-text').ok
|
||||
);
|
||||
|
||||
this.set('isDateTime', false);
|
||||
this.set('isFindADate', false);
|
||||
this.set('isMakeAPoll', true);
|
||||
|
||||
assert.notOk(
|
||||
hasComponent(this.container, assert, 'create-options-dates').ok
|
||||
);
|
||||
assert.ok(
|
||||
hasComponent(this.container, assert, 'create-options-text').ok
|
||||
);
|
||||
});
|
||||
|
||||
test('shows validation errors if options are not unique (makeAPoll)', async function(assert) {
|
||||
assert.expect(5);
|
||||
|
||||
this.set('isDateTime', false);
|
||||
this.set('isFindADate', false);
|
||||
this.set('isMakeAPoll', true);
|
||||
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
isFindADate: this.get('isFindADate'),
|
||||
isDateTime: this.get('isDateTime'),
|
||||
isMakeAPoll: this.get('isMakeAPoll')
|
||||
});
|
||||
hooks.beforeEach(function() {
|
||||
this.store = this.owner.lookup('service:store');
|
||||
});
|
||||
this.set('options', poll.get('options'));
|
||||
|
||||
this.render(hbs`{{create-options options=options isDateTime=isDateTime isFindADate=isFindADate isMakeAPoll=isMakeAPoll}}`);
|
||||
test('renders component', async function(assert) {
|
||||
this.set('options', []);
|
||||
this.set('isDateTime', false);
|
||||
this.set('isFindADate', true);
|
||||
this.set('isMakeAPoll', false);
|
||||
await render(
|
||||
hbs`{{create-options options=options isDateTime=isDateTime isFindADate=isFindADate isMakeAPoll=isMakeAPoll}}`
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
this.$('input').length === 2,
|
||||
'assumptions are correct'
|
||||
);
|
||||
assert.ok(
|
||||
hasComponent(this.owner, assert, 'create-options-dates').ok
|
||||
);
|
||||
assert.notOk(
|
||||
hasComponent(this.owner, assert, 'create-options-text').ok
|
||||
);
|
||||
|
||||
await fillIn(findAll('input')[0], 'foo');
|
||||
await blur(findAll('input')[0]);
|
||||
await fillIn(findAll('input')[1], 'foo');
|
||||
await blur(findAll('input')[1]);
|
||||
assert.ok(
|
||||
this.$('.form-group').eq(1).hasClass('has-error'),
|
||||
'second input field has validation error'
|
||||
);
|
||||
this.set('isDateTime', false);
|
||||
this.set('isFindADate', false);
|
||||
this.set('isMakeAPoll', true);
|
||||
|
||||
assert.ok(
|
||||
this.$('.form-group').eq(1).find('.help-block').length === 1,
|
||||
'validation error is shown'
|
||||
);
|
||||
|
||||
await fillIn(findAll('input')[0], 'bar');
|
||||
await blur(findAll('input')[0]);
|
||||
assert.ok(
|
||||
this.$('.form-group .help-block').length === 0,
|
||||
'there is no validation error anymore after a unique value is entered'
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
this.$('.form-group.has-error').length === 0,
|
||||
'has-error classes are removed'
|
||||
);
|
||||
});
|
||||
|
||||
test('shows validation errors if option is empty (makeAPoll)', async function(assert) {
|
||||
this.set('isDateTime', false);
|
||||
this.set('isFindADate', false);
|
||||
this.set('isMakeAPoll', true);
|
||||
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
isFindADate: this.get('isFindADate'),
|
||||
isDateTime: this.get('isDateTime'),
|
||||
isMakeAPoll: this.get('isMakeAPoll')
|
||||
});
|
||||
assert.notOk(
|
||||
hasComponent(this.owner, assert, 'create-options-dates').ok
|
||||
);
|
||||
assert.ok(
|
||||
hasComponent(this.owner, assert, 'create-options-text').ok
|
||||
);
|
||||
});
|
||||
this.set('options', poll.get('options'));
|
||||
|
||||
this.render(hbs`{{create-options options=options isDateTime=isDateTime isFindADate=isFindADate isMakeAPoll=isMakeAPoll}}`);
|
||||
test('shows validation errors if options are not unique (makeAPoll)', async function(assert) {
|
||||
assert.expect(5);
|
||||
|
||||
assert.equal(
|
||||
this.$('.form-group.has-error').length, 0
|
||||
);
|
||||
this.set('isDateTime', false);
|
||||
this.set('isFindADate', false);
|
||||
this.set('isMakeAPoll', true);
|
||||
|
||||
await focus(findAll('input')[0]);
|
||||
await blur(findAll('input')[0]);
|
||||
await focus(findAll('input')[1]);
|
||||
await blur(findAll('input')[1]);
|
||||
assert.equal(
|
||||
this.$('.form-group.has-error').length, 2
|
||||
);
|
||||
|
||||
await fillIn(findAll('input')[0], 'foo');
|
||||
await blur(findAll('input')[0]);
|
||||
assert.equal(
|
||||
this.$('.form-group.has-error').length, 1
|
||||
);
|
||||
|
||||
await fillIn(findAll('input')[1], 'bar');
|
||||
await blur(findAll('input')[1]);
|
||||
assert.equal(
|
||||
this.$('.form-group.has-error').length, 0
|
||||
);
|
||||
});
|
||||
|
||||
test('label reflects validation state of all inputs (makeAPoll)', async function(assert) {
|
||||
this.set('isDateTime', false);
|
||||
this.set('isFindADate', false);
|
||||
this.set('isMakeAPoll', true);
|
||||
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
isFindADate: this.get('isFindADate'),
|
||||
isDateTime: this.get('isDateTime'),
|
||||
isMakeAPoll: this.get('isMakeAPoll')
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
isFindADate: this.get('isFindADate'),
|
||||
isDateTime: this.get('isDateTime'),
|
||||
isMakeAPoll: this.get('isMakeAPoll')
|
||||
});
|
||||
});
|
||||
this.set('options', poll.get('options'));
|
||||
|
||||
await render(
|
||||
hbs`{{create-options options=options isDateTime=isDateTime isFindADate=isFindADate isMakeAPoll=isMakeAPoll}}`
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
findAll('input').length === 2,
|
||||
'assumptions are correct'
|
||||
);
|
||||
|
||||
await fillIn(findAll('input')[0], 'foo');
|
||||
await blur(findAll('input')[0]);
|
||||
await fillIn(findAll('input')[1], 'foo');
|
||||
await blur(findAll('input')[1]);
|
||||
assert.ok(
|
||||
this.$('.form-group').eq(1).hasClass('has-error'),
|
||||
'second input field has validation error'
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
this.$('.form-group').eq(1).find('.help-block').length === 1,
|
||||
'validation error is shown'
|
||||
);
|
||||
|
||||
await fillIn(findAll('input')[0], 'bar');
|
||||
await blur(findAll('input')[0]);
|
||||
assert.ok(
|
||||
findAll('.form-group .help-block').length === 0,
|
||||
'there is no validation error anymore after a unique value is entered'
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
findAll('.form-group.has-error').length === 0,
|
||||
'has-error classes are removed'
|
||||
);
|
||||
});
|
||||
this.set('options', poll.get('options'));
|
||||
|
||||
this.render(hbs`{{create-options options=options isDateTime=isDateTime isFindADate=isFindADate isMakeAPoll=isMakeAPoll}}`);
|
||||
test('shows validation errors if option is empty (makeAPoll)', async function(assert) {
|
||||
this.set('isDateTime', false);
|
||||
this.set('isFindADate', false);
|
||||
this.set('isMakeAPoll', true);
|
||||
|
||||
assert.ok(
|
||||
this.$('form').children().hasClass('label-has-no-validation'),
|
||||
'does not show validation state if there wasn\'t any user interaction yet'
|
||||
);
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
isFindADate: this.get('isFindADate'),
|
||||
isDateTime: this.get('isDateTime'),
|
||||
isMakeAPoll: this.get('isMakeAPoll')
|
||||
});
|
||||
});
|
||||
this.set('options', poll.get('options'));
|
||||
|
||||
await focus(findAll('input')[0]);
|
||||
await blur(findAll('input')[0]);
|
||||
assert.ok(
|
||||
this.$('form').children().hasClass('label-has-error'),
|
||||
'shows as having error if atleast on field has an error'
|
||||
);
|
||||
await render(
|
||||
hbs`{{create-options options=options isDateTime=isDateTime isFindADate=isFindADate isMakeAPoll=isMakeAPoll}}`
|
||||
);
|
||||
|
||||
await fillIn(findAll('input')[0], 'foo');
|
||||
await blur(findAll('input')[0]);
|
||||
assert.ok(
|
||||
this.$('form').children().hasClass('label-has-no-validation'),
|
||||
'does not show validation state if no field has error but not all fields are showing error yet'
|
||||
);
|
||||
assert.equal(
|
||||
findAll('.form-group.has-error').length, 0
|
||||
);
|
||||
|
||||
await fillIn(findAll('input')[1], 'bar');
|
||||
await blur(findAll('input')[1]);
|
||||
assert.ok(
|
||||
this.$('form').children().hasClass('label-has-success'),
|
||||
'shows as having success if all fields are showing success'
|
||||
);
|
||||
await focus(findAll('input')[0]);
|
||||
await blur(findAll('input')[0]);
|
||||
await focus(findAll('input')[1]);
|
||||
await blur(findAll('input')[1]);
|
||||
assert.equal(
|
||||
findAll('.form-group.has-error').length, 2
|
||||
);
|
||||
|
||||
await fillIn(findAll('input')[0], 'foo');
|
||||
await blur(findAll('input')[0]);
|
||||
assert.equal(
|
||||
findAll('.form-group.has-error').length, 1
|
||||
);
|
||||
|
||||
await fillIn(findAll('input')[1], 'bar');
|
||||
await blur(findAll('input')[1]);
|
||||
assert.equal(
|
||||
findAll('.form-group.has-error').length, 0
|
||||
);
|
||||
});
|
||||
|
||||
test('label reflects validation state of all inputs (makeAPoll)', async function(assert) {
|
||||
this.set('isDateTime', false);
|
||||
this.set('isFindADate', false);
|
||||
this.set('isMakeAPoll', true);
|
||||
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
isFindADate: this.get('isFindADate'),
|
||||
isDateTime: this.get('isDateTime'),
|
||||
isMakeAPoll: this.get('isMakeAPoll')
|
||||
});
|
||||
});
|
||||
this.set('options', poll.get('options'));
|
||||
|
||||
await render(
|
||||
hbs`{{create-options options=options isDateTime=isDateTime isFindADate=isFindADate isMakeAPoll=isMakeAPoll}}`
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
this.$('form').children().hasClass('label-has-no-validation'),
|
||||
'does not show validation state if there wasn\'t any user interaction yet'
|
||||
);
|
||||
|
||||
await focus(findAll('input')[0]);
|
||||
await blur(findAll('input')[0]);
|
||||
assert.ok(
|
||||
this.$('form').children().hasClass('label-has-error'),
|
||||
'shows as having error if atleast on field has an error'
|
||||
);
|
||||
|
||||
await fillIn(findAll('input')[0], 'foo');
|
||||
await blur(findAll('input')[0]);
|
||||
assert.ok(
|
||||
this.$('form').children().hasClass('label-has-no-validation'),
|
||||
'does not show validation state if no field has error but not all fields are showing error yet'
|
||||
);
|
||||
|
||||
await fillIn(findAll('input')[1], 'bar');
|
||||
await blur(findAll('input')[1]);
|
||||
assert.ok(
|
||||
this.$('form').children().hasClass('label-has-success'),
|
||||
'shows as having success if all fields are showing success'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,173 +1,171 @@
|
|||
import { run } from '@ember/runloop';
|
||||
import EmberObject from '@ember/object';
|
||||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, findAll, click } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import jQuery from 'jquery';
|
||||
|
||||
moduleForComponent('create-options-text', 'Integration | Component | create options text', {
|
||||
integration: true,
|
||||
beforeEach() {
|
||||
this.inject.service('store');
|
||||
}
|
||||
});
|
||||
module('Integration | Component | create options text', function(hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it generates at least two input fields', function(assert) {
|
||||
this.set('options', []);
|
||||
this.render(hbs`{{#bs-form as |form|}}{{create-options-text options=options form=form}}{{/bs-form}}`);
|
||||
hooks.beforeEach(function() {
|
||||
this.store = this.owner.lookup('service:store');
|
||||
});
|
||||
|
||||
assert.equal(this.$('input').length, 2);
|
||||
});
|
||||
test('it generates at least two input fields', async function(assert) {
|
||||
this.set('options', []);
|
||||
await render(hbs`{{#bs-form as |form|}}{{create-options-text options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
test('generates input fields according options', function(assert) {
|
||||
this.set('options', [
|
||||
EmberObject.create({ title: 'foo' }),
|
||||
EmberObject.create({ title: 'bar' }),
|
||||
EmberObject.create({ title: 'baz' })
|
||||
]);
|
||||
this.render(hbs`{{#bs-form as |form|}}{{create-options-text options=options form=form}}{{/bs-form}}`);
|
||||
assert.equal(findAll('input').length, 2);
|
||||
});
|
||||
|
||||
assert.equal(
|
||||
this.$('input').length,
|
||||
3,
|
||||
'correct amount of input fields'
|
||||
);
|
||||
assert.deepEqual(
|
||||
this.$('input').map(function() {
|
||||
return jQuery(this).val();
|
||||
}).get(),
|
||||
['foo', 'bar', 'baz'],
|
||||
'input fields have correct values and order'
|
||||
);
|
||||
});
|
||||
|
||||
test('observes changes to options', function(assert) {
|
||||
this.set('options', [
|
||||
EmberObject.create({ title: 'foo' }),
|
||||
EmberObject.create({ title: 'bar' })
|
||||
]);
|
||||
this.render(hbs`{{#bs-form as |form|}}{{create-options-text options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
assert.equal(
|
||||
this.$('input').length,
|
||||
2,
|
||||
'has correct amount of input fields before change'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
this.get('options').pushObject(
|
||||
test('generates input fields according options', async function(assert) {
|
||||
this.set('options', [
|
||||
EmberObject.create({ title: 'foo' }),
|
||||
EmberObject.create({ title: 'bar' }),
|
||||
EmberObject.create({ title: 'baz' })
|
||||
);
|
||||
});
|
||||
]);
|
||||
await render(hbs`{{#bs-form as |form|}}{{create-options-text options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
assert.equal(
|
||||
this.$('input').length,
|
||||
3,
|
||||
'has correct amount of input fields after change'
|
||||
);
|
||||
assert.equal(
|
||||
this.$('input').eq(2).val(),
|
||||
'baz',
|
||||
'input field was added with correct value'
|
||||
);
|
||||
});
|
||||
|
||||
test('changes to value updates option', function(assert) {
|
||||
this.set('options', [
|
||||
EmberObject.create({ title: 'foo' }),
|
||||
EmberObject.create({ title: 'bar' })
|
||||
]);
|
||||
this.render(hbs`{{#bs-form as |form|}}{{create-options-text options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
this.$('input').eq(0).val('baz').trigger('change');
|
||||
assert.equal(
|
||||
this.get('options')[0].get('title'),
|
||||
'baz',
|
||||
'option was updated'
|
||||
);
|
||||
});
|
||||
|
||||
test('allows to add another option', function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
isFindADate: this.get('isFindADate'),
|
||||
isDateTime: this.get('isDateTime'),
|
||||
isMakeAPoll: this.get('isMakeAPoll'),
|
||||
options: [
|
||||
{ title: 'foo' },
|
||||
{ title: 'bar' }
|
||||
]
|
||||
});
|
||||
});
|
||||
this.set('options', poll.get('options'));
|
||||
this.render(hbs`{{#bs-form as |form|}}{{create-options-text options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
assert.equal(
|
||||
this.$('.form-group input').length,
|
||||
2,
|
||||
'there are two input fields before'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
this.$('.form-group .add').eq(0).click();
|
||||
});
|
||||
assert.equal(
|
||||
this.$('.form-group input').length,
|
||||
3,
|
||||
'another input field is added'
|
||||
);
|
||||
assert.deepEqual(
|
||||
this.$('input').map(function() {
|
||||
return jQuery(this).val();
|
||||
}).get(),
|
||||
['foo', '', 'bar'],
|
||||
'it is added at correct position'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
this.$('.form-group input').eq(1).val('baz').trigger('change');
|
||||
});
|
||||
assert.equal(
|
||||
this.get('options').objectAt(1).get('title'),
|
||||
'baz',
|
||||
'options are observed for new input field'
|
||||
);
|
||||
});
|
||||
|
||||
test('allows to delete an option', function(assert) {
|
||||
this.set('options', [
|
||||
EmberObject.create({ title: 'foo' }),
|
||||
EmberObject.create({ title: 'bar' }),
|
||||
EmberObject.create({ title: 'baz' })
|
||||
]);
|
||||
this.render(hbs`{{#bs-form as |form|}}{{create-options-text options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
assert.equal(
|
||||
this.$('.form-group input').length,
|
||||
3,
|
||||
'there are three input fields before'
|
||||
);
|
||||
assert.ok(
|
||||
this.$('.delete').get().every((el) => {
|
||||
return el.disabled === false;
|
||||
}),
|
||||
'options are deleteable'
|
||||
);
|
||||
this.$('.form-group .delete').eq(1).click();
|
||||
run(() => {
|
||||
assert.equal(
|
||||
this.$('.form-group input').length,
|
||||
2,
|
||||
'one input field is deleted'
|
||||
findAll('input').length,
|
||||
3,
|
||||
'correct amount of input fields'
|
||||
);
|
||||
assert.deepEqual(
|
||||
this.$('input').map(function() {
|
||||
return jQuery(this).val();
|
||||
}).get(),
|
||||
['foo', 'bar', 'baz'],
|
||||
'input fields have correct values and order'
|
||||
);
|
||||
});
|
||||
|
||||
test('observes changes to options', async function(assert) {
|
||||
this.set('options', [
|
||||
EmberObject.create({ title: 'foo' }),
|
||||
EmberObject.create({ title: 'bar' })
|
||||
]);
|
||||
await render(hbs`{{#bs-form as |form|}}{{create-options-text options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
assert.equal(
|
||||
findAll('input').length,
|
||||
2,
|
||||
'has correct amount of input fields before change'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
this.get('options').pushObject(
|
||||
EmberObject.create({ title: 'baz' })
|
||||
);
|
||||
});
|
||||
|
||||
assert.equal(
|
||||
findAll('input').length,
|
||||
3,
|
||||
'has correct amount of input fields after change'
|
||||
);
|
||||
assert.equal(
|
||||
this.$('input').eq(2).val(),
|
||||
'baz',
|
||||
'input field was added with correct value'
|
||||
);
|
||||
});
|
||||
|
||||
test('changes to value updates option', async function(assert) {
|
||||
this.set('options', [
|
||||
EmberObject.create({ title: 'foo' }),
|
||||
EmberObject.create({ title: 'bar' })
|
||||
]);
|
||||
await render(hbs`{{#bs-form as |form|}}{{create-options-text options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
this.$('input').eq(0).val('baz').trigger('change');
|
||||
assert.equal(
|
||||
this.get('options')[0].get('title'),
|
||||
'baz',
|
||||
'option was updated'
|
||||
);
|
||||
});
|
||||
|
||||
test('allows to add another option', async function(assert) {
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
isFindADate: this.get('isFindADate'),
|
||||
isDateTime: this.get('isDateTime'),
|
||||
isMakeAPoll: this.get('isMakeAPoll'),
|
||||
options: [
|
||||
{ title: 'foo' },
|
||||
{ title: 'bar' }
|
||||
]
|
||||
});
|
||||
});
|
||||
this.set('options', poll.get('options'));
|
||||
await render(hbs`{{#bs-form as |form|}}{{create-options-text options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
assert.equal(
|
||||
findAll('.form-group input').length,
|
||||
2,
|
||||
'there are two input fields before'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
this.$('.form-group .add').eq(0).click();
|
||||
});
|
||||
assert.equal(
|
||||
findAll('.form-group input').length,
|
||||
3,
|
||||
'another input field is added'
|
||||
);
|
||||
assert.deepEqual(
|
||||
this.$('input').map(function() {
|
||||
return jQuery(this).val();
|
||||
}).get(),
|
||||
['foo', '', 'bar'],
|
||||
'it is added at correct position'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
this.$('.form-group input').eq(1).val('baz').trigger('change');
|
||||
});
|
||||
assert.equal(
|
||||
this.get('options').objectAt(1).get('title'),
|
||||
'baz',
|
||||
'options are observed for new input field'
|
||||
);
|
||||
});
|
||||
|
||||
test('allows to delete an option', async function(assert) {
|
||||
this.set('options', [
|
||||
EmberObject.create({ title: 'foo' }),
|
||||
EmberObject.create({ title: 'bar' }),
|
||||
EmberObject.create({ title: 'baz' })
|
||||
]);
|
||||
await render(hbs`{{#bs-form as |form|}}{{create-options-text options=options form=form}}{{/bs-form}}`);
|
||||
|
||||
assert.equal(
|
||||
findAll('.form-group input').length,
|
||||
3,
|
||||
'there are three input fields before'
|
||||
);
|
||||
assert.ok(
|
||||
findAll('.delete').every((el) => el.disabled === false),
|
||||
'options are deleteable'
|
||||
);
|
||||
|
||||
await click(findAll('.form-group .delete')[1]);
|
||||
assert.equal(
|
||||
findAll('.form-group input').length,
|
||||
2,
|
||||
'one input field is deleted'
|
||||
);
|
||||
assert.deepEqual(
|
||||
findAll('input').toArray().map((el) => el.value),
|
||||
['foo', 'baz'],
|
||||
'correct input field is deleted'
|
||||
);
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, findAll, find } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
moduleForComponent('form-navigation-buttons', 'Integration | Component | form navigation buttons', {
|
||||
integration: true
|
||||
});
|
||||
module('Integration | Component | form navigation buttons', function(hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders two buttons as default', function(assert) {
|
||||
this.render(hbs`{{form-navigation-buttons}}`);
|
||||
assert.equal(this.$('button').length, 2);
|
||||
});
|
||||
test('it renders two buttons as default', async function(assert) {
|
||||
await render(hbs`{{form-navigation-buttons}}`);
|
||||
assert.equal(findAll('button').length, 2);
|
||||
});
|
||||
|
||||
test('buttons could be disabled', function(assert) {
|
||||
this.render(hbs`{{form-navigation-buttons disableNextButton=true disablePrevButton=true}}`);
|
||||
assert.equal(this.$('button.next').prop('disabled'), true, 'next button is disabled');
|
||||
assert.equal(this.$('button.prev').prop('disabled'), true, 'prev button is disabled');
|
||||
});
|
||||
test('buttons could be disabled', async function(assert) {
|
||||
await render(hbs`{{form-navigation-buttons disableNextButton=true disablePrevButton=true}}`);
|
||||
assert.equal(find('button.next').disabled, true, 'next button is disabled');
|
||||
assert.equal(find('button.prev').disabled, true, 'prev button is disabled');
|
||||
});
|
||||
|
||||
test('could prevent rendering of prev button', function(assert) {
|
||||
this.render(hbs`{{form-navigation-buttons renderPrevButton=false}}`);
|
||||
assert.ok(this.$('button.prev').length === 0, 'prev button is not rendered');
|
||||
assert.ok(this.$('button.next').length === 1, 'next button is rendered');
|
||||
test('could prevent rendering of prev button', async function(assert) {
|
||||
await render(hbs`{{form-navigation-buttons renderPrevButton=false}}`);
|
||||
assert.ok(findAll('button.prev').length === 0, 'prev button is not rendered');
|
||||
assert.ok(findAll('button.next').length === 1, 'next button is rendered');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,75 +1,78 @@
|
|||
import EmberObject from '@ember/object';
|
||||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import moment from 'moment';
|
||||
|
||||
moduleForComponent('poll-evaluation-chart', 'Integration | Component | poll evaluation chart', {
|
||||
integration: true,
|
||||
beforeEach() {
|
||||
moment.locale('en');
|
||||
}
|
||||
});
|
||||
module('Integration | Component | poll evaluation chart', function(hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', function(assert) {
|
||||
this.set('options', [
|
||||
EmberObject.create({
|
||||
formatted: 'Thursday, January 1, 2015',
|
||||
title: moment('2015-01-01'),
|
||||
hasTime: false
|
||||
}),
|
||||
EmberObject.create({
|
||||
formatted: 'Monday, February 2, 2015',
|
||||
title: moment('2015-02-02'),
|
||||
hasTime: false
|
||||
}),
|
||||
EmberObject.create({
|
||||
formatted: 'Tuesday, March 3, 2015 1:00 AM',
|
||||
title: moment('2015-03-03T01:00'),
|
||||
hasTime: true
|
||||
}),
|
||||
EmberObject.create({
|
||||
formatted: 'Tuesday, March 3, 2015 11:00 AM',
|
||||
title: moment('2015-03-03T11:00'),
|
||||
hasTime: true
|
||||
})
|
||||
]);
|
||||
this.set('answerType', 'YesNoMaybe');
|
||||
this.set('users', [
|
||||
EmberObject.create({
|
||||
id: 1,
|
||||
selections: [
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'maybe'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
})
|
||||
]
|
||||
}),
|
||||
EmberObject.create({
|
||||
id: 2,
|
||||
selections: [
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'maybe'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
})
|
||||
]
|
||||
})
|
||||
]);
|
||||
this.render(hbs`{{poll-evaluation-chart options=options answerType=answerType users=users}}`);
|
||||
assert.ok(this.$('canvas'), 'it renders a canvas element');
|
||||
hooks.beforeEach(function() {
|
||||
moment.locale('en');
|
||||
});
|
||||
|
||||
test('it renders', async function(assert) {
|
||||
this.set('options', [
|
||||
EmberObject.create({
|
||||
formatted: 'Thursday, January 1, 2015',
|
||||
title: moment('2015-01-01'),
|
||||
hasTime: false
|
||||
}),
|
||||
EmberObject.create({
|
||||
formatted: 'Monday, February 2, 2015',
|
||||
title: moment('2015-02-02'),
|
||||
hasTime: false
|
||||
}),
|
||||
EmberObject.create({
|
||||
formatted: 'Tuesday, March 3, 2015 1:00 AM',
|
||||
title: moment('2015-03-03T01:00'),
|
||||
hasTime: true
|
||||
}),
|
||||
EmberObject.create({
|
||||
formatted: 'Tuesday, March 3, 2015 11:00 AM',
|
||||
title: moment('2015-03-03T11:00'),
|
||||
hasTime: true
|
||||
})
|
||||
]);
|
||||
this.set('answerType', 'YesNoMaybe');
|
||||
this.set('users', [
|
||||
EmberObject.create({
|
||||
id: 1,
|
||||
selections: [
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'maybe'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
})
|
||||
]
|
||||
}),
|
||||
EmberObject.create({
|
||||
id: 2,
|
||||
selections: [
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'maybe'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
})
|
||||
]
|
||||
})
|
||||
]);
|
||||
await render(hbs`{{poll-evaluation-chart options=options answerType=answerType users=users}}`);
|
||||
assert.ok(this.$('canvas'), 'it renders a canvas element');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,31 +3,32 @@ import { module, test } from 'qunit';
|
|||
import { startMirage } from 'croodle/initializers/ember-cli-mirage';
|
||||
import sjcl from 'sjcl';
|
||||
|
||||
module('Integration | Mirage api mocking', {
|
||||
beforeEach() {
|
||||
module('Integration | Mirage api mocking', function(hooks) {
|
||||
hooks.beforeEach(function() {
|
||||
this.server = startMirage();
|
||||
},
|
||||
afterEach() {
|
||||
});
|
||||
|
||||
hooks.afterEach(function() {
|
||||
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'
|
||||
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');
|
||||
});
|
||||
assert.equal(JSON.parse(sjcl.decrypt(encryptionKey, get(user, 'name'))), 'foo');
|
||||
});
|
||||
|
|
|
@ -1,76 +1,77 @@
|
|||
import { getOwner } from '@ember/application';
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import config from 'croodle/config/environment';
|
||||
import LocaleHelper from 'ember-i18n/utils/locale';
|
||||
import localesMeta from 'croodle/locales/meta';
|
||||
|
||||
moduleFor('service:i18n', 'Integration | translations', {
|
||||
integration: true
|
||||
});
|
||||
module('Integration | translations', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('configuration is correct', function(assert) {
|
||||
const i18n = this.subject();
|
||||
const locales = i18n.get('locales');
|
||||
const { defaultLocale } = config.i18n;
|
||||
// Replace this with your real tests.
|
||||
test('configuration is correct', function(assert) {
|
||||
const i18n = this.owner.lookup('service:i18n');
|
||||
const locales = i18n.get('locales');
|
||||
const { defaultLocale } = config.i18n;
|
||||
|
||||
assert.ok(defaultLocale, 'default locale is set');
|
||||
assert.ok(locales, 'there are locales');
|
||||
assert.ok(locales.indexOf(defaultLocale) !== -1, 'default locale is part of locales');
|
||||
});
|
||||
|
||||
test('all locales have same amount of translation strings as default locale', function(assert) {
|
||||
const i18n = this.subject();
|
||||
const locales = i18n.get('locales');
|
||||
const { defaultLocale } = config.i18n;
|
||||
const { translations: defaultTranslations } = new LocaleHelper(defaultLocale, getOwner(i18n));
|
||||
|
||||
assert.expect((locales.length - 1) * 2);
|
||||
|
||||
locales.map((locale) => {
|
||||
if (locale === defaultLocale) {
|
||||
return;
|
||||
}
|
||||
const { translations } = new LocaleHelper(locale, getOwner(i18n));
|
||||
assert.ok(translations, `could retrive locale ${locale}`);
|
||||
assert.equal(
|
||||
Object.keys(translations).length,
|
||||
Object.keys(defaultTranslations).length,
|
||||
`correct amount of translations for locale ${locale}`
|
||||
);
|
||||
assert.ok(defaultLocale, 'default locale is set');
|
||||
assert.ok(locales, 'there are locales');
|
||||
assert.ok(locales.indexOf(defaultLocale) !== -1, 'default locale is part of locales');
|
||||
});
|
||||
});
|
||||
|
||||
test('all locales have same translation strings as default locale', function(assert) {
|
||||
const i18n = this.subject();
|
||||
const locales = i18n.get('locales');
|
||||
const { defaultLocale } = config.i18n;
|
||||
const { translations: defaultTranslations } = new LocaleHelper(defaultLocale, getOwner(i18n));
|
||||
test('all locales have same amount of translation strings as default locale', function(assert) {
|
||||
const i18n = this.owner.lookup('service:i18n');
|
||||
const locales = i18n.get('locales');
|
||||
const { defaultLocale } = config.i18n;
|
||||
const { translations: defaultTranslations } = new LocaleHelper(defaultLocale, this.owner);
|
||||
|
||||
assert.expect(
|
||||
// count of non default locales * translation strings of default locale
|
||||
(locales.length - 1) * Object.keys(defaultTranslations).length
|
||||
);
|
||||
assert.expect((locales.length - 1) * 2);
|
||||
|
||||
Object.keys(defaultTranslations).map((translationString) => {
|
||||
locales.map((locale) => {
|
||||
if (locale === defaultLocale) {
|
||||
return;
|
||||
}
|
||||
|
||||
i18n.set('locale', locale);
|
||||
assert.ok(
|
||||
i18n.exists(translationString),
|
||||
`translation for ${translationString} exists in locale ${locale}`
|
||||
const { translations } = new LocaleHelper(locale, getOwner(i18n));
|
||||
assert.ok(translations, `could retrive locale ${locale}`);
|
||||
assert.equal(
|
||||
Object.keys(translations).length,
|
||||
Object.keys(defaultTranslations).length,
|
||||
`correct amount of translations for locale ${locale}`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('all locales have an entry in locales/meta', function(assert) {
|
||||
const i18n = this.subject();
|
||||
assert.deepEqual(
|
||||
i18n.get('locales'),
|
||||
Object.keys(localesMeta)
|
||||
);
|
||||
test('all locales have same translation strings as default locale', function(assert) {
|
||||
const i18n = this.owner.lookup('service:i18n');
|
||||
const locales = i18n.get('locales');
|
||||
const { defaultLocale } = config.i18n;
|
||||
const { translations: defaultTranslations } = new LocaleHelper(defaultLocale, this.owner);
|
||||
|
||||
assert.expect(
|
||||
// count of non default locales * translation strings of default locale
|
||||
(locales.length - 1) * Object.keys(defaultTranslations).length
|
||||
);
|
||||
|
||||
Object.keys(defaultTranslations).map((translationString) => {
|
||||
locales.map((locale) => {
|
||||
if (locale === defaultLocale) {
|
||||
return;
|
||||
}
|
||||
|
||||
i18n.set('locale', locale);
|
||||
assert.ok(
|
||||
i18n.exists(translationString),
|
||||
`translation for ${translationString} exists in locale ${locale}`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('all locales have an entry in locales/meta', function(assert) {
|
||||
const i18n = this.owner.lookup('service:i18n');
|
||||
assert.deepEqual(
|
||||
i18n.get('locales'),
|
||||
Object.keys(localesMeta)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -21,7 +21,7 @@ const setBootstrapDatepicker = function(selector, options = {}) {
|
|||
return {
|
||||
isDescriptor: true,
|
||||
value(dates) {
|
||||
const el = findElementWithAssert(this, selector, options);
|
||||
const el = findElementWithAssert(this, selector, options).parent();
|
||||
if (isPresent(dates)) {
|
||||
const normalizedDates = dates.map((date) => {
|
||||
if (typeof date.toDate === 'function') {
|
||||
|
@ -41,7 +41,7 @@ const setBootstrapDatepicker = function(selector, options = {}) {
|
|||
};
|
||||
|
||||
export default PageObject.create(assign({}, defaultsForCreate, {
|
||||
dateOptions: setBootstrapDatepicker('.days .ember-view:has(.datepicker:first-child)'),
|
||||
dateOptions: setBootstrapDatepicker('.days .datepicker'),
|
||||
dateHasError: isVisible('.days.has-error'),
|
||||
dateError: text('.days .help-block'),
|
||||
textOptions: collection({
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
isVisible,
|
||||
text
|
||||
} from 'ember-cli-page-object';
|
||||
import { currentURL } from '@ember/test-helpers';
|
||||
|
||||
const urlMatches = function(regExp) {
|
||||
return function() {
|
||||
|
|
|
@ -1,208 +1,209 @@
|
|||
import { isArray } from '@ember/array';
|
||||
import EmberObject from '@ember/object';
|
||||
import { run } from '@ember/runloop';
|
||||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import moment from 'moment';
|
||||
|
||||
moduleForComponent('create-options-dates', 'Unit | Component | create options dates', {
|
||||
needs: ['config:environment', 'model:option', 'service:i18n'],
|
||||
unit: true,
|
||||
beforeEach() {
|
||||
this.inject.service('store');
|
||||
}
|
||||
});
|
||||
module('Unit | Component | create options dates', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('options get mapped to dates as optionsBootstrapDatepicker (used by ember-cli-bootstrap-datepicker)', function(assert) {
|
||||
let controller = this.subject();
|
||||
controller.set('options', [
|
||||
EmberObject.create({ title: '1945-05-09' }),
|
||||
EmberObject.create({ title: '1987-05-01' }),
|
||||
EmberObject.create({ title: 'non valid date string' })
|
||||
]);
|
||||
assert.ok(
|
||||
isArray(
|
||||
controller.get('optionsBootstrapDatepicker')
|
||||
),
|
||||
"it's an array"
|
||||
);
|
||||
assert.equal(
|
||||
controller.get('optionsBootstrapDatepicker.length'),
|
||||
2,
|
||||
'array length is correct'
|
||||
);
|
||||
assert.ok(
|
||||
controller.get('optionsBootstrapDatepicker').every((el) => {
|
||||
return moment.isDate(el);
|
||||
}),
|
||||
'array elements are date objects'
|
||||
);
|
||||
assert.equal(
|
||||
controller.get('optionsBootstrapDatepicker.firstObject').toISOString(),
|
||||
moment('1945-05-09').toISOString(),
|
||||
'date is correct'
|
||||
);
|
||||
});
|
||||
|
||||
test('options having times get mapped to dates as optionsBootstrapDatepicker (used by ember-cli-bootstrap-datepicker)', function(assert) {
|
||||
let controller = this.subject();
|
||||
controller.set('options', [
|
||||
EmberObject.create({ title: '2014-01-01T12:00:00.00Z' }),
|
||||
EmberObject.create({ title: '2015-02-02T15:00:00.00Z' }),
|
||||
EmberObject.create({ title: '2015-02-02T15:00:00.00Z' }),
|
||||
EmberObject.create({ title: '2016-03-03' })
|
||||
]);
|
||||
assert.ok(
|
||||
isArray(
|
||||
controller.get('optionsBootstrapDatepicker')
|
||||
),
|
||||
"it's an array"
|
||||
);
|
||||
assert.equal(
|
||||
controller.get('optionsBootstrapDatepicker.length'),
|
||||
3,
|
||||
'array length is correct'
|
||||
);
|
||||
assert.ok(
|
||||
controller.get('optionsBootstrapDatepicker').every((el) => {
|
||||
return moment.isDate(el);
|
||||
}),
|
||||
'array elements are date objects'
|
||||
);
|
||||
assert.deepEqual(
|
||||
controller.get('optionsBootstrapDatepicker').map((option) => {
|
||||
return option.toISOString();
|
||||
}),
|
||||
[
|
||||
moment('2014-01-01').toISOString(),
|
||||
moment('2015-02-02').toISOString(),
|
||||
moment('2016-03-03').toISOString()
|
||||
],
|
||||
'date is correct'
|
||||
);
|
||||
});
|
||||
|
||||
test('options get set correctly by optionsBootstrapDatepicker (used by ember-cli-bootstrap-datepicker)', function(assert) {
|
||||
let controller = this.subject();
|
||||
run(() => {
|
||||
controller.set('options', []);
|
||||
// dates must be in wrong order to test sorting
|
||||
controller.set('optionsBootstrapDatepicker', [
|
||||
moment('1918-11-09').toDate(),
|
||||
moment('1917-10-25').toDate()
|
||||
]);
|
||||
hooks.beforeEach(function() {
|
||||
this.store = this.owner.lookup('service:store');
|
||||
});
|
||||
assert.ok(
|
||||
isArray(
|
||||
controller.get('options')
|
||||
),
|
||||
'options is still an array'
|
||||
);
|
||||
assert.equal(
|
||||
controller.get('options.length'),
|
||||
2,
|
||||
'array has correct length'
|
||||
);
|
||||
assert.ok(
|
||||
controller.get('options').every((option) => {
|
||||
return typeof option.get('title') === 'string';
|
||||
}),
|
||||
'option.title is a string'
|
||||
);
|
||||
assert.ok(
|
||||
controller.get('options').every((option) => {
|
||||
return moment(option.get('title'), 'YYYY-MM-DD', true).isValid();
|
||||
}),
|
||||
'option.title is an ISO-8601 date string without time'
|
||||
);
|
||||
assert.ok(
|
||||
controller.get('options').findBy('title', '1918-11-09'),
|
||||
'date is correct'
|
||||
);
|
||||
assert.equal(
|
||||
controller.get('options.firstObject.title'),
|
||||
'1917-10-25',
|
||||
'dates are in correct order'
|
||||
);
|
||||
});
|
||||
|
||||
test('existing times are preserved if new days get selected', function(assert) {
|
||||
let component;
|
||||
run(() => {
|
||||
component = this.subject({
|
||||
options: [
|
||||
this.store.createFragment('option', {
|
||||
title: moment('2015-01-01T11:11').toISOString()
|
||||
}),
|
||||
this.store.createFragment('option', {
|
||||
title: moment('2015-01-01T22:22').toISOString()
|
||||
}),
|
||||
this.store.createFragment('option', {
|
||||
title: moment('2015-06-06T08:08').toISOString()
|
||||
}),
|
||||
this.store.createFragment('option', {
|
||||
title: '2016-01-01'
|
||||
})
|
||||
]
|
||||
test('options get mapped to dates as optionsBootstrapDatepicker (used by ember-cli-bootstrap-datepicker)', function(assert) {
|
||||
let controller = this.owner.factoryFor('component:create-options-dates').create();
|
||||
controller.set('options', [
|
||||
EmberObject.create({ title: '1945-05-09' }),
|
||||
EmberObject.create({ title: '1987-05-01' }),
|
||||
EmberObject.create({ title: 'non valid date string' })
|
||||
]);
|
||||
assert.ok(
|
||||
isArray(
|
||||
controller.get('optionsBootstrapDatepicker')
|
||||
),
|
||||
"it's an array"
|
||||
);
|
||||
assert.equal(
|
||||
controller.get('optionsBootstrapDatepicker.length'),
|
||||
2,
|
||||
'array length is correct'
|
||||
);
|
||||
assert.ok(
|
||||
controller.get('optionsBootstrapDatepicker').every((el) => {
|
||||
return moment.isDate(el);
|
||||
}),
|
||||
'array elements are date objects'
|
||||
);
|
||||
assert.equal(
|
||||
controller.get('optionsBootstrapDatepicker.firstObject').toISOString(),
|
||||
moment('1945-05-09').toISOString(),
|
||||
'date is correct'
|
||||
);
|
||||
});
|
||||
|
||||
test('options having times get mapped to dates as optionsBootstrapDatepicker (used by ember-cli-bootstrap-datepicker)', function(assert) {
|
||||
let controller = this.owner.factoryFor('component:create-options-dates').create();
|
||||
controller.set('options', [
|
||||
EmberObject.create({ title: '2014-01-01T12:00:00.00Z' }),
|
||||
EmberObject.create({ title: '2015-02-02T15:00:00.00Z' }),
|
||||
EmberObject.create({ title: '2015-02-02T15:00:00.00Z' }),
|
||||
EmberObject.create({ title: '2016-03-03' })
|
||||
]);
|
||||
assert.ok(
|
||||
isArray(
|
||||
controller.get('optionsBootstrapDatepicker')
|
||||
),
|
||||
"it's an array"
|
||||
);
|
||||
assert.equal(
|
||||
controller.get('optionsBootstrapDatepicker.length'),
|
||||
3,
|
||||
'array length is correct'
|
||||
);
|
||||
assert.ok(
|
||||
controller.get('optionsBootstrapDatepicker').every((el) => {
|
||||
return moment.isDate(el);
|
||||
}),
|
||||
'array elements are date objects'
|
||||
);
|
||||
assert.deepEqual(
|
||||
controller.get('optionsBootstrapDatepicker').map((option) => {
|
||||
return option.toISOString();
|
||||
}),
|
||||
[
|
||||
moment('2014-01-01').toISOString(),
|
||||
moment('2015-02-02').toISOString(),
|
||||
moment('2016-03-03').toISOString()
|
||||
],
|
||||
'date is correct'
|
||||
);
|
||||
});
|
||||
|
||||
test('options get set correctly by optionsBootstrapDatepicker (used by ember-cli-bootstrap-datepicker)', function(assert) {
|
||||
let controller = this.owner.factoryFor('component:create-options-dates').create();
|
||||
run(() => {
|
||||
controller.set('options', []);
|
||||
// dates must be in wrong order to test sorting
|
||||
controller.set('optionsBootstrapDatepicker', [
|
||||
moment('1918-11-09').toDate(),
|
||||
moment('1917-10-25').toDate()
|
||||
]);
|
||||
});
|
||||
assert.ok(
|
||||
isArray(
|
||||
controller.get('options')
|
||||
),
|
||||
'options is still an array'
|
||||
);
|
||||
assert.equal(
|
||||
controller.get('options.length'),
|
||||
2,
|
||||
'array has correct length'
|
||||
);
|
||||
assert.ok(
|
||||
controller.get('options').every((option) => {
|
||||
return typeof option.get('title') === 'string';
|
||||
}),
|
||||
'option.title is a string'
|
||||
);
|
||||
assert.ok(
|
||||
controller.get('options').every((option) => {
|
||||
return moment(option.get('title'), 'YYYY-MM-DD', true).isValid();
|
||||
}),
|
||||
'option.title is an ISO-8601 date string without time'
|
||||
);
|
||||
assert.ok(
|
||||
controller.get('options').findBy('title', '1918-11-09'),
|
||||
'date is correct'
|
||||
);
|
||||
assert.equal(
|
||||
controller.get('options.firstObject.title'),
|
||||
'1917-10-25',
|
||||
'dates are in correct order'
|
||||
);
|
||||
});
|
||||
// add another day
|
||||
run(() => {
|
||||
component.set('optionsBootstrapDatepicker', [
|
||||
moment('2015-01-01').toDate(),
|
||||
moment('2015-06-06').toDate(),
|
||||
moment('2016-01-01').toDate(),
|
||||
moment('2016-06-06').toDate() // new day
|
||||
]);
|
||||
|
||||
test('existing times are preserved if new days get selected', function(assert) {
|
||||
let component;
|
||||
run(() => {
|
||||
component = this.owner.factoryFor('component:create-options-dates').create({
|
||||
options: [
|
||||
this.store.createFragment('option', {
|
||||
title: moment('2015-01-01T11:11').toISOString()
|
||||
}),
|
||||
this.store.createFragment('option', {
|
||||
title: moment('2015-01-01T22:22').toISOString()
|
||||
}),
|
||||
this.store.createFragment('option', {
|
||||
title: moment('2015-06-06T08:08').toISOString()
|
||||
}),
|
||||
this.store.createFragment('option', {
|
||||
title: '2016-01-01'
|
||||
})
|
||||
]
|
||||
});
|
||||
});
|
||||
// add another day
|
||||
run(() => {
|
||||
component.set('optionsBootstrapDatepicker', [
|
||||
moment('2015-01-01').toDate(),
|
||||
moment('2015-06-06').toDate(),
|
||||
moment('2016-01-01').toDate(),
|
||||
moment('2016-06-06').toDate() // new day
|
||||
]);
|
||||
});
|
||||
assert.deepEqual(
|
||||
component.get('options').map((option) => option.get('title')),
|
||||
[
|
||||
moment('2015-01-01T11:11').toISOString(),
|
||||
moment('2015-01-01T22:22').toISOString(),
|
||||
moment('2015-06-06T08:08').toISOString(),
|
||||
'2016-01-01',
|
||||
'2016-06-06'
|
||||
],
|
||||
'preseve existing times if another day is added'
|
||||
);
|
||||
// delete a day
|
||||
run(() => {
|
||||
component.set('optionsBootstrapDatepicker', [
|
||||
moment('2015-06-06').toDate(),
|
||||
moment('2016-01-01').toDate(),
|
||||
moment('2016-06-06').toDate()
|
||||
]);
|
||||
});
|
||||
assert.deepEqual(
|
||||
component.get('options').map((option) => option.get('title')),
|
||||
[
|
||||
moment('2015-06-06T08:08').toISOString(),
|
||||
'2016-01-01',
|
||||
'2016-06-06'
|
||||
],
|
||||
'preseve existing times if a day is deleted'
|
||||
);
|
||||
// order if multiple days are added
|
||||
run(() => {
|
||||
component.set('optionsBootstrapDatepicker', [
|
||||
moment('2015-06-06').toDate(),
|
||||
moment('2016-01-01').toDate(),
|
||||
moment('2016-06-06').toDate(),
|
||||
moment('2016-12-12').toDate(),
|
||||
moment('2015-01-01').toDate(),
|
||||
moment('2016-03-03').toDate()
|
||||
]);
|
||||
});
|
||||
assert.deepEqual(
|
||||
component.get('options').map((option) => option.get('title')),
|
||||
[
|
||||
'2015-01-01',
|
||||
moment('2015-06-06T08:08').toISOString(),
|
||||
'2016-01-01',
|
||||
'2016-03-03',
|
||||
'2016-06-06',
|
||||
'2016-12-12'
|
||||
],
|
||||
'options are in correct order after multiple days are added'
|
||||
);
|
||||
});
|
||||
assert.deepEqual(
|
||||
component.get('options').map((option) => option.get('title')),
|
||||
[
|
||||
moment('2015-01-01T11:11').toISOString(),
|
||||
moment('2015-01-01T22:22').toISOString(),
|
||||
moment('2015-06-06T08:08').toISOString(),
|
||||
'2016-01-01',
|
||||
'2016-06-06'
|
||||
],
|
||||
'preseve existing times if another day is added'
|
||||
);
|
||||
// delete a day
|
||||
run(() => {
|
||||
component.set('optionsBootstrapDatepicker', [
|
||||
moment('2015-06-06').toDate(),
|
||||
moment('2016-01-01').toDate(),
|
||||
moment('2016-06-06').toDate()
|
||||
]);
|
||||
});
|
||||
assert.deepEqual(
|
||||
component.get('options').map((option) => option.get('title')),
|
||||
[
|
||||
moment('2015-06-06T08:08').toISOString(),
|
||||
'2016-01-01',
|
||||
'2016-06-06'
|
||||
],
|
||||
'preseve existing times if a day is deleted'
|
||||
);
|
||||
// order if multiple days are added
|
||||
run(() => {
|
||||
component.set('optionsBootstrapDatepicker', [
|
||||
moment('2015-06-06').toDate(),
|
||||
moment('2016-01-01').toDate(),
|
||||
moment('2016-06-06').toDate(),
|
||||
moment('2016-12-12').toDate(),
|
||||
moment('2015-01-01').toDate(),
|
||||
moment('2016-03-03').toDate()
|
||||
]);
|
||||
});
|
||||
assert.deepEqual(
|
||||
component.get('options').map((option) => option.get('title')),
|
||||
[
|
||||
'2015-01-01',
|
||||
moment('2015-06-06T08:08').toISOString(),
|
||||
'2016-01-01',
|
||||
'2016-03-03',
|
||||
'2016-06-06',
|
||||
'2016-12-12'
|
||||
],
|
||||
'options are in correct order after multiple days are added'
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,255 +1,251 @@
|
|||
import { run } from '@ember/runloop';
|
||||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import moment from 'moment';
|
||||
|
||||
moduleForComponent('create-options-datetime', 'Unit | Component | create options datetime', {
|
||||
unit: true,
|
||||
needs: [
|
||||
'config:environment',
|
||||
'model:option', 'model:poll', 'model:user',
|
||||
'service:i18n',
|
||||
'validator:alias', 'validator:collection', 'validator:iso8601', 'validator:length', 'validator:presence', 'validator:time', 'validator:unique', 'validator:valid-collection'
|
||||
],
|
||||
beforeEach() {
|
||||
this.inject.service('store');
|
||||
}
|
||||
});
|
||||
module('Unit | Component | create options datetime', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('delete a date', function(assert) {
|
||||
let component = this.subject();
|
||||
let a, b, c, d, e;
|
||||
run(() => {
|
||||
a = this.store.createFragment('option', { title: moment('2015-01-01T01:01:00.000').toISOString() });
|
||||
b = this.store.createFragment('option', { title: moment('2015-01-01T11:11:00.000').toISOString() });
|
||||
c = this.store.createFragment('option', { title: moment('2015-02-02T11:11:00.000').toISOString() });
|
||||
d = this.store.createFragment('option', { title: '2015-02-02' });
|
||||
e = this.store.createFragment('option', { title: '2015-02-03' });
|
||||
component.set('dates', [a, b, c, d, e]);
|
||||
hooks.beforeEach(function() {
|
||||
this.store = this.owner.lookup('service:store');
|
||||
});
|
||||
component.send('deleteOption', b);
|
||||
assert.deepEqual(
|
||||
component.get('dates').map((date) => date.get('title')),
|
||||
[
|
||||
moment('2015-01-01T01:01:00.000').toISOString(),
|
||||
moment('2015-02-02T11:11:00.000').toISOString(),
|
||||
'2015-02-02',
|
||||
'2015-02-03'
|
||||
],
|
||||
'date get deleted if there is another date with same day (both having a time)'
|
||||
);
|
||||
component.send('deleteOption', d);
|
||||
assert.deepEqual(
|
||||
component.get('dates').map((date) => date.get('title')),
|
||||
[
|
||||
moment('2015-01-01T01:01:00.000').toISOString(),
|
||||
moment('2015-02-02T11:11:00.000').toISOString(),
|
||||
'2015-02-03'
|
||||
],
|
||||
'date get deleted if there is another date with same day (date does not have a time)'
|
||||
);
|
||||
run(() => {
|
||||
component.send('deleteOption', c);
|
||||
});
|
||||
assert.deepEqual(
|
||||
component.get('dates').map((date) => date.get('title')),
|
||||
[
|
||||
moment('2015-01-01T01:01:00.000').toISOString(),
|
||||
'2015-02-02',
|
||||
'2015-02-03'
|
||||
],
|
||||
'time is removed from date if there isn\' t any other date with same day'
|
||||
);
|
||||
component.send('deleteOption', d);
|
||||
assert.deepEqual(
|
||||
component.get('dates').map((date) => date.get('title')),
|
||||
[
|
||||
moment('2015-01-01T01:01:00.000').toISOString(),
|
||||
'2015-02-02',
|
||||
'2015-02-03'
|
||||
],
|
||||
'nothing changes if it\'s the only date for this day it it doesn\'t have a time'
|
||||
);
|
||||
});
|
||||
|
||||
test('datetimes are grouped by date', function(assert) {
|
||||
let component = this.subject();
|
||||
let a, b, c;
|
||||
// have to set dates in local time and than convert to ISO 8601 strings
|
||||
// because otherwise test could fail caused by timezone
|
||||
run(() => {
|
||||
a = this.store.createFragment('option', { title: moment('2015-01-01T01:01:00').toISOString() });
|
||||
b = this.store.createFragment('option', { title: moment('2015-01-01T11:11:00').toISOString() });
|
||||
c = this.store.createFragment('option', { title: moment('2015-02-02T01:01:00').toISOString() });
|
||||
component.set('dates', [a, b, c]);
|
||||
});
|
||||
assert.equal(
|
||||
component.get('groupedDates.length'),
|
||||
2,
|
||||
'length is correct'
|
||||
);
|
||||
assert.deepEqual(
|
||||
component.get('groupedDates.firstObject.items').map((item) => {
|
||||
return item.get('date').toISOString();
|
||||
}),
|
||||
[a.get('title'), b.get('title')],
|
||||
'first dates having same day are grouped together'
|
||||
);
|
||||
assert.equal(
|
||||
component.get('groupedDates.lastObject.items.firstObject.date').toISOString(),
|
||||
[c.get('title')],
|
||||
'last date having another day is in a separate group'
|
||||
);
|
||||
});
|
||||
|
||||
test('bindings are working on grouped datetimes', function(assert) {
|
||||
let component = this.subject();
|
||||
run(() => {
|
||||
component.set('dates', [
|
||||
this.store.createFragment('option', {
|
||||
title: moment('2015-01-01T11:11:00.000Z').toISOString()
|
||||
})
|
||||
]);
|
||||
});
|
||||
assert.equal(
|
||||
component.get('groupedDates.firstObject.items.firstObject.time'),
|
||||
moment('2015-01-01T11:11:00.000Z').format('HH:mm'),
|
||||
'time is correct before'
|
||||
);
|
||||
run(() => {
|
||||
component.set(
|
||||
'groupedDates.firstObject.items.firstObject.time',
|
||||
'00:00'
|
||||
test('delete a date', function(assert) {
|
||||
let component = this.owner.factoryFor('component:create-options-datetime').create();
|
||||
let a, b, c, d, e;
|
||||
run(() => {
|
||||
a = this.store.createFragment('option', { title: moment('2015-01-01T01:01:00.000').toISOString() });
|
||||
b = this.store.createFragment('option', { title: moment('2015-01-01T11:11:00.000').toISOString() });
|
||||
c = this.store.createFragment('option', { title: moment('2015-02-02T11:11:00.000').toISOString() });
|
||||
d = this.store.createFragment('option', { title: '2015-02-02' });
|
||||
e = this.store.createFragment('option', { title: '2015-02-03' });
|
||||
component.set('dates', [a, b, c, d, e]);
|
||||
});
|
||||
component.send('deleteOption', b);
|
||||
assert.deepEqual(
|
||||
component.get('dates').map((date) => date.get('title')),
|
||||
[
|
||||
moment('2015-01-01T01:01:00.000').toISOString(),
|
||||
moment('2015-02-02T11:11:00.000').toISOString(),
|
||||
'2015-02-02',
|
||||
'2015-02-03'
|
||||
],
|
||||
'date get deleted if there is another date with same day (both having a time)'
|
||||
);
|
||||
component.send('deleteOption', d);
|
||||
assert.deepEqual(
|
||||
component.get('dates').map((date) => date.get('title')),
|
||||
[
|
||||
moment('2015-01-01T01:01:00.000').toISOString(),
|
||||
moment('2015-02-02T11:11:00.000').toISOString(),
|
||||
'2015-02-03'
|
||||
],
|
||||
'date get deleted if there is another date with same day (date does not have a time)'
|
||||
);
|
||||
run(() => {
|
||||
component.send('deleteOption', c);
|
||||
});
|
||||
assert.deepEqual(
|
||||
component.get('dates').map((date) => date.get('title')),
|
||||
[
|
||||
moment('2015-01-01T01:01:00.000').toISOString(),
|
||||
'2015-02-02',
|
||||
'2015-02-03'
|
||||
],
|
||||
'time is removed from date if there isn\' t any other date with same day'
|
||||
);
|
||||
component.send('deleteOption', d);
|
||||
assert.deepEqual(
|
||||
component.get('dates').map((date) => date.get('title')),
|
||||
[
|
||||
moment('2015-01-01T01:01:00.000').toISOString(),
|
||||
'2015-02-02',
|
||||
'2015-02-03'
|
||||
],
|
||||
'nothing changes if it\'s the only date for this day it it doesn\'t have a time'
|
||||
);
|
||||
});
|
||||
assert.equal(
|
||||
component.get('dates.firstObject.title'),
|
||||
moment('2015-01-01T00:00').toISOString(),
|
||||
'option is updated after time changed on grouped datetimes'
|
||||
);
|
||||
run(() => {
|
||||
component.get('dates').pushObject(
|
||||
this.store.createFragment('option', { title: moment('2015-01-01T12:12').toISOString() })
|
||||
|
||||
test('datetimes are grouped by date', function(assert) {
|
||||
let component = this.owner.factoryFor('component:create-options-datetime').create();
|
||||
let a, b, c;
|
||||
// have to set dates in local time and than convert to ISO 8601 strings
|
||||
// because otherwise test could fail caused by timezone
|
||||
run(() => {
|
||||
a = this.store.createFragment('option', { title: moment('2015-01-01T01:01:00').toISOString() });
|
||||
b = this.store.createFragment('option', { title: moment('2015-01-01T11:11:00').toISOString() });
|
||||
c = this.store.createFragment('option', { title: moment('2015-02-02T01:01:00').toISOString() });
|
||||
component.set('dates', [a, b, c]);
|
||||
});
|
||||
assert.equal(
|
||||
component.get('groupedDates.length'),
|
||||
2,
|
||||
'length is correct'
|
||||
);
|
||||
assert.deepEqual(
|
||||
component.get('groupedDates.firstObject.items').map((item) => {
|
||||
return item.get('date').toISOString();
|
||||
}),
|
||||
[a.get('title'), b.get('title')],
|
||||
'first dates having same day are grouped together'
|
||||
);
|
||||
assert.equal(
|
||||
component.get('groupedDates.lastObject.items.firstObject.date').toISOString(),
|
||||
[c.get('title')],
|
||||
'last date having another day is in a separate group'
|
||||
);
|
||||
});
|
||||
assert.equal(
|
||||
component.get('groupedDates.firstObject.items.length'),
|
||||
2,
|
||||
'grouped datetimes got updated after option was added (same day)'
|
||||
);
|
||||
assert.equal(
|
||||
component.get('groupedDates.firstObject.items.lastObject.time'),
|
||||
'12:12',
|
||||
'grouped datetimes got updated correctly after option was added (same day)'
|
||||
);
|
||||
run(() => {
|
||||
component.get('dates').pushObject(
|
||||
this.store.createFragment('option', { title: moment('2015-02-02T01:01').toISOString() })
|
||||
|
||||
test('bindings are working on grouped datetimes', function(assert) {
|
||||
let component = this.owner.factoryFor('component:create-options-datetime').create();
|
||||
run(() => {
|
||||
component.set('dates', [
|
||||
this.store.createFragment('option', {
|
||||
title: moment('2015-01-01T11:11:00.000Z').toISOString()
|
||||
})
|
||||
]);
|
||||
});
|
||||
assert.equal(
|
||||
component.get('groupedDates.firstObject.items.firstObject.time'),
|
||||
moment('2015-01-01T11:11:00.000Z').format('HH:mm'),
|
||||
'time is correct before'
|
||||
);
|
||||
run(() => {
|
||||
component.set(
|
||||
'groupedDates.firstObject.items.firstObject.time',
|
||||
'00:00'
|
||||
);
|
||||
});
|
||||
assert.equal(
|
||||
component.get('dates.firstObject.title'),
|
||||
moment('2015-01-01T00:00').toISOString(),
|
||||
'option is updated after time changed on grouped datetimes'
|
||||
);
|
||||
run(() => {
|
||||
component.get('dates').pushObject(
|
||||
this.store.createFragment('option', { title: moment('2015-01-01T12:12').toISOString() })
|
||||
);
|
||||
});
|
||||
assert.equal(
|
||||
component.get('groupedDates.firstObject.items.length'),
|
||||
2,
|
||||
'grouped datetimes got updated after option was added (same day)'
|
||||
);
|
||||
assert.equal(
|
||||
component.get('groupedDates.firstObject.items.lastObject.time'),
|
||||
'12:12',
|
||||
'grouped datetimes got updated correctly after option was added (same day)'
|
||||
);
|
||||
run(() => {
|
||||
component.get('dates').pushObject(
|
||||
this.store.createFragment('option', { title: moment('2015-02-02T01:01').toISOString() })
|
||||
);
|
||||
});
|
||||
assert.equal(
|
||||
component.get('groupedDates.length'),
|
||||
2,
|
||||
'grouped datetimes got updated after option was added (other day)'
|
||||
);
|
||||
assert.equal(
|
||||
component.get('groupedDates.lastObject.items.firstObject.time'),
|
||||
'01:01',
|
||||
'grouped datetimes got updated correctly after option was added (same day)'
|
||||
);
|
||||
});
|
||||
assert.equal(
|
||||
component.get('groupedDates.length'),
|
||||
2,
|
||||
'grouped datetimes got updated after option was added (other day)'
|
||||
);
|
||||
assert.equal(
|
||||
component.get('groupedDates.lastObject.items.firstObject.time'),
|
||||
'01:01',
|
||||
'grouped datetimes got updated correctly after option was added (same day)'
|
||||
);
|
||||
});
|
||||
|
||||
test('adopt times of first day - simple', function(assert) {
|
||||
let component;
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
options: [
|
||||
{ title: moment('2015-01-01T11:11:00.000').toISOString() },
|
||||
{ title: moment('2015-01-01T22:22:00.000').toISOString() },
|
||||
{ title: moment('2015-01-02').toISOString() },
|
||||
{ title: moment('2015-01-03').toISOString() }
|
||||
]
|
||||
test('adopt times of first day - simple', function(assert) {
|
||||
let component;
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
options: [
|
||||
{ title: moment('2015-01-01T11:11:00.000').toISOString() },
|
||||
{ title: moment('2015-01-01T22:22:00.000').toISOString() },
|
||||
{ title: moment('2015-01-02').toISOString() },
|
||||
{ title: moment('2015-01-03').toISOString() }
|
||||
]
|
||||
});
|
||||
component = this.owner.factoryFor('component:create-options-datetime').create({
|
||||
dates: poll.get('options')
|
||||
});
|
||||
component.send('adoptTimesOfFirstDay');
|
||||
});
|
||||
component = this.subject({
|
||||
dates: poll.get('options')
|
||||
});
|
||||
component.send('adoptTimesOfFirstDay');
|
||||
assert.deepEqual(
|
||||
component.get('dates').map((option) => option.get('title')),
|
||||
[
|
||||
moment('2015-01-01T11:11:00.000').toISOString(),
|
||||
moment('2015-01-01T22:22:00.000').toISOString(),
|
||||
moment('2015-01-02T11:11:00.000').toISOString(),
|
||||
moment('2015-01-02T22:22:00.000').toISOString(),
|
||||
moment('2015-01-03T11:11:00.000').toISOString(),
|
||||
moment('2015-01-03T22:22:00.000').toISOString()
|
||||
],
|
||||
'times adopted correctly'
|
||||
);
|
||||
});
|
||||
assert.deepEqual(
|
||||
component.get('dates').map((option) => option.get('title')),
|
||||
[
|
||||
moment('2015-01-01T11:11:00.000').toISOString(),
|
||||
moment('2015-01-01T22:22:00.000').toISOString(),
|
||||
moment('2015-01-02T11:11:00.000').toISOString(),
|
||||
moment('2015-01-02T22:22:00.000').toISOString(),
|
||||
moment('2015-01-03T11:11:00.000').toISOString(),
|
||||
moment('2015-01-03T22:22:00.000').toISOString()
|
||||
],
|
||||
'times adopted correctly'
|
||||
);
|
||||
});
|
||||
|
||||
test('adopt times of first day - having times on the other days', function(assert) {
|
||||
let component;
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
options: [
|
||||
{ title: moment('2015-01-01T11:11:00.000').toISOString() },
|
||||
{ title: moment('2015-01-01T22:22:00.000').toISOString() },
|
||||
{ title: moment('2015-01-02T09:11:00.000').toISOString() },
|
||||
{ title: moment('2015-01-03T01:11:00.000').toISOString() },
|
||||
{ title: moment('2015-01-03T11:11:00.000').toISOString() },
|
||||
{ title: moment('2015-01-04T02:11:00.000').toISOString() },
|
||||
{ title: moment('2015-01-04T05:11:00.000').toISOString() },
|
||||
{ title: moment('2015-01-04T12:11:00.000').toISOString() }
|
||||
]
|
||||
test('adopt times of first day - having times on the other days', function(assert) {
|
||||
let component;
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
options: [
|
||||
{ title: moment('2015-01-01T11:11:00.000').toISOString() },
|
||||
{ title: moment('2015-01-01T22:22:00.000').toISOString() },
|
||||
{ title: moment('2015-01-02T09:11:00.000').toISOString() },
|
||||
{ title: moment('2015-01-03T01:11:00.000').toISOString() },
|
||||
{ title: moment('2015-01-03T11:11:00.000').toISOString() },
|
||||
{ title: moment('2015-01-04T02:11:00.000').toISOString() },
|
||||
{ title: moment('2015-01-04T05:11:00.000').toISOString() },
|
||||
{ title: moment('2015-01-04T12:11:00.000').toISOString() }
|
||||
]
|
||||
});
|
||||
component = this.owner.factoryFor('component:create-options-datetime').create({
|
||||
dates: poll.get('options')
|
||||
});
|
||||
component.send('adoptTimesOfFirstDay');
|
||||
});
|
||||
component = this.subject({
|
||||
dates: poll.get('options')
|
||||
});
|
||||
component.send('adoptTimesOfFirstDay');
|
||||
assert.deepEqual(
|
||||
component.get('dates').map((option) => option.get('title')),
|
||||
[
|
||||
moment('2015-01-01T11:11:00.000').toISOString(),
|
||||
moment('2015-01-01T22:22:00.000').toISOString(),
|
||||
moment('2015-01-02T11:11:00.000').toISOString(),
|
||||
moment('2015-01-02T22:22:00.000').toISOString(),
|
||||
moment('2015-01-03T11:11:00.000').toISOString(),
|
||||
moment('2015-01-03T22:22:00.000').toISOString(),
|
||||
moment('2015-01-04T11:11:00.000').toISOString(),
|
||||
moment('2015-01-04T22:22:00.000').toISOString()
|
||||
],
|
||||
'times adopted correctly'
|
||||
);
|
||||
});
|
||||
assert.deepEqual(
|
||||
component.get('dates').map((option) => option.get('title')),
|
||||
[
|
||||
moment('2015-01-01T11:11:00.000').toISOString(),
|
||||
moment('2015-01-01T22:22:00.000').toISOString(),
|
||||
moment('2015-01-02T11:11:00.000').toISOString(),
|
||||
moment('2015-01-02T22:22:00.000').toISOString(),
|
||||
moment('2015-01-03T11:11:00.000').toISOString(),
|
||||
moment('2015-01-03T22:22:00.000').toISOString(),
|
||||
moment('2015-01-04T11:11:00.000').toISOString(),
|
||||
moment('2015-01-04T22:22:00.000').toISOString()
|
||||
],
|
||||
'times adopted correctly'
|
||||
);
|
||||
});
|
||||
|
||||
test('adopt times of first day - no times on first day', function(assert) {
|
||||
let component;
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
options: [
|
||||
{ title: '2015-01-01' },
|
||||
{ title: '2015-01-02' },
|
||||
{ title: moment('2015-01-03T11:00:00.000Z').toISOString() },
|
||||
{ title: moment('2015-01-03T15:00:00.000Z').toISOString() }
|
||||
]
|
||||
test('adopt times of first day - no times on first day', function(assert) {
|
||||
let component;
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
options: [
|
||||
{ title: '2015-01-01' },
|
||||
{ title: '2015-01-02' },
|
||||
{ title: moment('2015-01-03T11:00:00.000Z').toISOString() },
|
||||
{ title: moment('2015-01-03T15:00:00.000Z').toISOString() }
|
||||
]
|
||||
});
|
||||
component = this.owner.factoryFor('component:create-options-datetime').create({
|
||||
dates: poll.get('options')
|
||||
});
|
||||
component.send('adoptTimesOfFirstDay');
|
||||
});
|
||||
component = this.subject({
|
||||
dates: poll.get('options')
|
||||
});
|
||||
component.send('adoptTimesOfFirstDay');
|
||||
assert.deepEqual(
|
||||
component.get('dates').map((option) => option.get('title')),
|
||||
[
|
||||
'2015-01-01',
|
||||
'2015-01-02',
|
||||
'2015-01-03'
|
||||
],
|
||||
'times are removed from all days'
|
||||
);
|
||||
});
|
||||
assert.deepEqual(
|
||||
component.get('dates').map((option) => option.get('title')),
|
||||
[
|
||||
'2015-01-01',
|
||||
'2015-01-02',
|
||||
'2015-01-03'
|
||||
],
|
||||
'times are removed from all days'
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { run } from '@ember/runloop';
|
||||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import moment from 'moment';
|
||||
// validator consumes i18n service
|
||||
// have to register it therefore
|
||||
|
@ -7,205 +8,185 @@ import moment from 'moment';
|
|||
import tHelper from 'ember-i18n/helper';
|
||||
import localeConfig from 'ember-i18n/config/en';
|
||||
|
||||
moduleForComponent('create-options', 'Unit | Component | create options', {
|
||||
needs: [
|
||||
'model:option',
|
||||
'model:poll',
|
||||
'validator:alias',
|
||||
'model:user',
|
||||
'validator:collection',
|
||||
'validator:iso8601',
|
||||
'validator:length',
|
||||
'validator:presence',
|
||||
'validator:time',
|
||||
'validator:unique',
|
||||
'validator:valid-collection',
|
||||
'validator:messages',
|
||||
module('Unit | Component | create options', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
hooks.beforeEach(function() {
|
||||
this.store = this.owner.lookup('service:store');
|
||||
// validator consumes i18n service
|
||||
'service:i18n',
|
||||
'locale:en/translations',
|
||||
// 'locale:en/config', https://github.com/jamesarosen/ember-i18n/issues/368
|
||||
'util:i18n/missing-message',
|
||||
'util:i18n/compile-template',
|
||||
'config:environment'
|
||||
],
|
||||
unit: true,
|
||||
beforeEach() {
|
||||
this.inject.service('store');
|
||||
// validator consumes i18n service
|
||||
this.container.lookup('service:i18n').set('locale', 'en');
|
||||
this.registry.register('locale:en/config', localeConfig);
|
||||
this.registry.register('helper:t', tHelper);
|
||||
}
|
||||
});
|
||||
|
||||
test('validation for make a poll', function(assert) {
|
||||
let component = this.subject();
|
||||
component.set('options', []);
|
||||
component.set('isFindADate', false);
|
||||
component.set('isMakeAPoll', true);
|
||||
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
isFindADate: component.get('isFindADate'),
|
||||
isMakeAPoll: component.get('isMakeAPoll')
|
||||
});
|
||||
});
|
||||
|
||||
assert.notOk(
|
||||
component.get('validations.isValid'),
|
||||
'invalid without any options'
|
||||
);
|
||||
run(() => {
|
||||
let option = this.store.createFragment('option', {
|
||||
title: 'first option'
|
||||
});
|
||||
poll.get('options').pushObject(option);
|
||||
component.get('options').pushObject(option);
|
||||
});
|
||||
assert.ok(
|
||||
component.get('validations.isValid'),
|
||||
'valid if there is atleast one valid option'
|
||||
);
|
||||
run(() => {
|
||||
let option = this.store.createFragment('option', {
|
||||
title: 'second option'
|
||||
});
|
||||
poll.get('options').pushObject(option);
|
||||
component.get('options').pushObject(option);
|
||||
});
|
||||
assert.ok(
|
||||
component.get('validations.isValid'),
|
||||
'valid for two options which are not empty strings'
|
||||
);
|
||||
run(() => {
|
||||
component.set('options.firstObject.title', '');
|
||||
});
|
||||
assert.notOk(
|
||||
component.get('validations.isValid'),
|
||||
'invalid if atleast one string is empty'
|
||||
);
|
||||
});
|
||||
|
||||
test('validation for find a date without times', function(assert) {
|
||||
let component = this.subject();
|
||||
component.set('options', []);
|
||||
component.set('isFindADate', true);
|
||||
component.set('isMakeAPoll', false);
|
||||
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
isFindADate: component.get('isFindADate'),
|
||||
isMakeAPoll: component.get('isMakeAPoll')
|
||||
});
|
||||
});
|
||||
|
||||
assert.notOk(
|
||||
component.get('validations.isValid'),
|
||||
'invalid without any options'
|
||||
);
|
||||
run(() => {
|
||||
let option = this.store.createFragment('option', {
|
||||
title: '2015-01-01'
|
||||
});
|
||||
poll.get('options').pushObject(option);
|
||||
component.get('options').pushObject(option);
|
||||
});
|
||||
assert.ok(
|
||||
component.get('validations.isValid'),
|
||||
'valid if there is atleast one valid date'
|
||||
);
|
||||
run(() => {
|
||||
let option = this.store.createFragment('option', {
|
||||
title: '2015-01-02'
|
||||
});
|
||||
poll.get('options').pushObject(option);
|
||||
component.get('options').pushObject(option);
|
||||
});
|
||||
assert.ok(
|
||||
component.get('validations.isValid'),
|
||||
'valid for two valid dates'
|
||||
);
|
||||
run(() => {
|
||||
let option = this.store.createFragment('option', {
|
||||
title: 'foo'
|
||||
});
|
||||
poll.get('options').pushObject(option);
|
||||
component.get('options').pushObject(option);
|
||||
});
|
||||
assert.notOk(
|
||||
component.get('validations.isValid'),
|
||||
'invalid if atleast one option is not a valid date'
|
||||
);
|
||||
run(() => {
|
||||
component.set('options.lastObject.title', '2015-01-03');
|
||||
});
|
||||
assert.ok(
|
||||
component.get('validations.isValid'),
|
||||
'valid again after title is a valid date again'
|
||||
);
|
||||
run(() => {
|
||||
component.set('options.firstObject.title', '2015-01-01');
|
||||
component.set('options.lastObject.title', '2015-01-01');
|
||||
});
|
||||
assert.ok(
|
||||
component.get('validations.isInvalid'),
|
||||
'invalid if dates are not unique'
|
||||
);
|
||||
});
|
||||
|
||||
test('validation for find a date with times', function(assert) {
|
||||
let component = this.subject();
|
||||
component.set('options', []);
|
||||
component.set('isMakeAPoll', false);
|
||||
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
isFindADate: component.get('isFindADate'),
|
||||
isMakeAPoll: component.get('isMakeAPoll')
|
||||
});
|
||||
});
|
||||
assert.notOk(
|
||||
component.get('validations.isValid'),
|
||||
'invalid without any options'
|
||||
);
|
||||
run(() => {
|
||||
let option = this.store.createFragment('option', {
|
||||
title: moment().add('1', 'day').format('YYYY-MM-DD')
|
||||
});
|
||||
poll.get('options').pushObject(option);
|
||||
component.get('options').pushObject(option);
|
||||
});
|
||||
assert.ok(
|
||||
component.get('validations.isValid'),
|
||||
'valid if there is atleast one valid date'
|
||||
);
|
||||
/*
|
||||
Ember.run(() => {
|
||||
let option = this.store.createFragment('option', {
|
||||
title: moment().add('1', 'day').hour(22).minute(30).seconds(0).milliseconds(0).toISOString()
|
||||
});
|
||||
poll.get('options').pushObject(option);
|
||||
component.get('options').pushObject(option);
|
||||
});
|
||||
assert.notOk(
|
||||
component.get('validations.isValid'),
|
||||
'invalid if there is a option without time for a day with has another option with time specified'
|
||||
);
|
||||
*/
|
||||
this.owner.lookup('service:i18n').set('locale', 'en');
|
||||
this.owner.register('locale:en/config', localeConfig);
|
||||
this.owner.register('helper:t', tHelper);
|
||||
});
|
||||
|
||||
test('validation for make a poll', function(assert) {
|
||||
let component = this.owner.factoryFor('component:create-options').create();
|
||||
component.set('options', []);
|
||||
component.set('isFindADate', false);
|
||||
component.set('isMakeAPoll', true);
|
||||
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
isFindADate: component.get('isFindADate'),
|
||||
isMakeAPoll: component.get('isMakeAPoll')
|
||||
});
|
||||
});
|
||||
|
||||
assert.notOk(
|
||||
component.get('validations.isValid'),
|
||||
'invalid without any options'
|
||||
);
|
||||
run(() => {
|
||||
let option = this.store.createFragment('option', {
|
||||
title: 'first option'
|
||||
});
|
||||
poll.get('options').pushObject(option);
|
||||
component.get('options').pushObject(option);
|
||||
});
|
||||
assert.ok(
|
||||
component.get('validations.isValid'),
|
||||
'valid if there is atleast one valid option'
|
||||
);
|
||||
run(() => {
|
||||
let option = this.store.createFragment('option', {
|
||||
title: 'second option'
|
||||
});
|
||||
poll.get('options').pushObject(option);
|
||||
component.get('options').pushObject(option);
|
||||
});
|
||||
assert.ok(
|
||||
component.get('validations.isValid'),
|
||||
'valid for two options which are not empty strings'
|
||||
);
|
||||
run(() => {
|
||||
component.set('options.firstObject.title', '');
|
||||
});
|
||||
assert.notOk(
|
||||
component.get('validations.isValid'),
|
||||
'invalid if atleast one string is empty'
|
||||
);
|
||||
});
|
||||
|
||||
test('validation for find a date without times', function(assert) {
|
||||
let component = this.owner.factoryFor('component:create-options').create();
|
||||
component.set('options', []);
|
||||
component.set('isFindADate', true);
|
||||
component.set('isMakeAPoll', false);
|
||||
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
isFindADate: component.get('isFindADate'),
|
||||
isMakeAPoll: component.get('isMakeAPoll')
|
||||
});
|
||||
});
|
||||
|
||||
assert.notOk(
|
||||
component.get('validations.isValid'),
|
||||
'invalid without any options'
|
||||
);
|
||||
run(() => {
|
||||
let option = this.store.createFragment('option', {
|
||||
title: '2015-01-01'
|
||||
});
|
||||
poll.get('options').pushObject(option);
|
||||
component.get('options').pushObject(option);
|
||||
});
|
||||
assert.ok(
|
||||
component.get('validations.isValid'),
|
||||
'valid if there is atleast one valid date'
|
||||
);
|
||||
run(() => {
|
||||
let option = this.store.createFragment('option', {
|
||||
title: '2015-01-02'
|
||||
});
|
||||
poll.get('options').pushObject(option);
|
||||
component.get('options').pushObject(option);
|
||||
});
|
||||
assert.ok(
|
||||
component.get('validations.isValid'),
|
||||
'valid for two valid dates'
|
||||
);
|
||||
run(() => {
|
||||
let option = this.store.createFragment('option', {
|
||||
title: 'foo'
|
||||
});
|
||||
poll.get('options').pushObject(option);
|
||||
component.get('options').pushObject(option);
|
||||
});
|
||||
assert.notOk(
|
||||
component.get('validations.isValid'),
|
||||
'invalid if atleast one option is not a valid date'
|
||||
);
|
||||
run(() => {
|
||||
component.set('options.lastObject.title', '2015-01-03');
|
||||
});
|
||||
assert.ok(
|
||||
component.get('validations.isValid'),
|
||||
'valid again after title is a valid date again'
|
||||
);
|
||||
run(() => {
|
||||
component.set('options.firstObject.title', '2015-01-01');
|
||||
component.set('options.lastObject.title', '2015-01-01');
|
||||
});
|
||||
assert.ok(
|
||||
component.get('validations.isInvalid'),
|
||||
'invalid if dates are not unique'
|
||||
);
|
||||
});
|
||||
|
||||
test('validation for find a date with times', function(assert) {
|
||||
let component = this.owner.factoryFor('component:create-options').create();
|
||||
component.set('options', []);
|
||||
component.set('isMakeAPoll', false);
|
||||
|
||||
// validation is based on validation of every option fragment
|
||||
// which validates according to poll model it belongs to
|
||||
// therefore each option needs to be pushed to poll model to have it as
|
||||
// it's owner
|
||||
let poll;
|
||||
run(() => {
|
||||
poll = this.store.createRecord('poll', {
|
||||
isFindADate: component.get('isFindADate'),
|
||||
isMakeAPoll: component.get('isMakeAPoll')
|
||||
});
|
||||
});
|
||||
assert.notOk(
|
||||
component.get('validations.isValid'),
|
||||
'invalid without any options'
|
||||
);
|
||||
run(() => {
|
||||
let option = this.store.createFragment('option', {
|
||||
title: moment().add('1', 'day').format('YYYY-MM-DD')
|
||||
});
|
||||
poll.get('options').pushObject(option);
|
||||
component.get('options').pushObject(option);
|
||||
});
|
||||
assert.ok(
|
||||
component.get('validations.isValid'),
|
||||
'valid if there is atleast one valid date'
|
||||
);
|
||||
/*
|
||||
Ember.run(() => {
|
||||
let option = this.store.createFragment('option', {
|
||||
title: moment().add('1', 'day').hour(22).minute(30).seconds(0).milliseconds(0).toISOString()
|
||||
});
|
||||
poll.get('options').pushObject(option);
|
||||
component.get('options').pushObject(option);
|
||||
});
|
||||
assert.notOk(
|
||||
component.get('validations.isValid'),
|
||||
'invalid if there is a option without time for a day with has another option with time specified'
|
||||
);
|
||||
*/
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,141 +1,37 @@
|
|||
import EmberObject from '@ember/object';
|
||||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import moment from 'moment';
|
||||
import tHelper from 'ember-i18n/helper';
|
||||
import localeConfig from 'ember-i18n/config/en';
|
||||
|
||||
moduleForComponent('poll-evaluation-chart', 'Unit | Component | poll evaluation chart', {
|
||||
unit: true,
|
||||
// https://github.com/jamesarosen/ember-i18n/wiki/Doc:-Testing#unit-tests
|
||||
needs: [
|
||||
'service:i18n',
|
||||
'locale:en/translations',
|
||||
'util:i18n/missing-message',
|
||||
'util:i18n/compile-template',
|
||||
'config:environment'
|
||||
],
|
||||
beforeEach() {
|
||||
module('Unit | Component | poll evaluation chart', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
hooks.beforeEach(function() {
|
||||
moment.locale('en');
|
||||
|
||||
this.container.lookup('service:i18n').set('locale', 'en');
|
||||
this.registry.register('locale:en/config', localeConfig);
|
||||
this.registry.register('helper:t', tHelper);
|
||||
}
|
||||
});
|
||||
|
||||
test('data is a valid ChartJS dataset for FindADate using poll timezone', function(assert) {
|
||||
let options = [
|
||||
EmberObject.create({
|
||||
title: '2015-01-01'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: '2015-02-02'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: '2015-03-03T01:00:00.000Z'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: '2015-03-03T11:00:00.000Z'
|
||||
})
|
||||
];
|
||||
let users = [
|
||||
EmberObject.create({
|
||||
id: 1,
|
||||
selections: [
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'maybe'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
})
|
||||
]
|
||||
}),
|
||||
EmberObject.create({
|
||||
id: 2,
|
||||
selections: [
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'maybe'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
})
|
||||
]
|
||||
})
|
||||
];
|
||||
let currentLocale = 'en';
|
||||
let momentLongDayFormat = moment.localeData(currentLocale)
|
||||
.longDateFormat('LLLL')
|
||||
.replace(
|
||||
moment.localeData(currentLocale).longDateFormat('LT'), '')
|
||||
.trim();
|
||||
let component = this.subject({
|
||||
answerType: 'YesNoMaybe',
|
||||
currentLocale,
|
||||
isFindADate: true,
|
||||
momentLongDayFormat,
|
||||
options,
|
||||
timezone: 'Asia/Hong_Kong',
|
||||
users
|
||||
this.owner.lookup('service:i18n').set('locale', 'en');
|
||||
this.owner.register('locale:en/config', localeConfig);
|
||||
this.owner.register('helper:t', tHelper);
|
||||
});
|
||||
const data = component.get('data');
|
||||
assert.deepEqual(
|
||||
data.labels,
|
||||
['Thursday, January 1, 2015', 'Monday, February 2, 2015', 'Tuesday, March 3, 2015 9:00 AM', 'Tuesday, March 3, 2015 7:00 PM'],
|
||||
'Labels are correct'
|
||||
);
|
||||
assert.equal(
|
||||
data.datasets.length,
|
||||
2,
|
||||
'there are two datasets'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets.map((dataset) => dataset.label),
|
||||
['Yes', 'Maybe'],
|
||||
'datasets having answers as label and are in correct order'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets[0].data,
|
||||
[100, 50, 0, 0],
|
||||
'dataset for yes is correct'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets[1].data,
|
||||
[0, 50, 50, 0],
|
||||
'dataset for maybe is correct'
|
||||
);
|
||||
});
|
||||
|
||||
test('data is a valid ChartJS dataset for MakeAPoll', function(assert) {
|
||||
const options = [
|
||||
EmberObject.create({
|
||||
title: 'first option'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: 'second option'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: 'third option'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: 'fourth option'
|
||||
})
|
||||
];
|
||||
let component = this.subject({
|
||||
answerType: 'YesNoMaybe',
|
||||
options,
|
||||
users: [
|
||||
test('data is a valid ChartJS dataset for FindADate using poll timezone', function(assert) {
|
||||
let options = [
|
||||
EmberObject.create({
|
||||
title: '2015-01-01'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: '2015-02-02'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: '2015-03-03T01:00:00.000Z'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: '2015-03-03T11:00:00.000Z'
|
||||
})
|
||||
];
|
||||
let users = [
|
||||
EmberObject.create({
|
||||
id: 1,
|
||||
selections: [
|
||||
|
@ -170,149 +66,247 @@ test('data is a valid ChartJS dataset for MakeAPoll', function(assert) {
|
|||
})
|
||||
]
|
||||
})
|
||||
]
|
||||
];
|
||||
let currentLocale = 'en';
|
||||
let momentLongDayFormat = moment.localeData(currentLocale)
|
||||
.longDateFormat('LLLL')
|
||||
.replace(
|
||||
moment.localeData(currentLocale).longDateFormat('LT'), '')
|
||||
.trim();
|
||||
let component = this.owner.factoryFor('component:poll-evaluation-chart').create({
|
||||
answerType: 'YesNoMaybe',
|
||||
currentLocale,
|
||||
isFindADate: true,
|
||||
momentLongDayFormat,
|
||||
options,
|
||||
timezone: 'Asia/Hong_Kong',
|
||||
users
|
||||
});
|
||||
const data = component.get('data');
|
||||
assert.deepEqual(
|
||||
data.labels,
|
||||
['Thursday, January 1, 2015', 'Monday, February 2, 2015', 'Tuesday, March 3, 2015 9:00 AM', 'Tuesday, March 3, 2015 7:00 PM'],
|
||||
'Labels are correct'
|
||||
);
|
||||
assert.equal(
|
||||
data.datasets.length,
|
||||
2,
|
||||
'there are two datasets'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets.map((dataset) => dataset.label),
|
||||
['Yes', 'Maybe'],
|
||||
'datasets having answers as label and are in correct order'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets[0].data,
|
||||
[100, 50, 0, 0],
|
||||
'dataset for yes is correct'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets[1].data,
|
||||
[0, 50, 50, 0],
|
||||
'dataset for maybe is correct'
|
||||
);
|
||||
});
|
||||
const data = component.get('data');
|
||||
assert.deepEqual(
|
||||
data.labels,
|
||||
options.map((option) => option.get('title')),
|
||||
'Labels are correct'
|
||||
);
|
||||
assert.equal(
|
||||
data.datasets.length,
|
||||
2,
|
||||
'there are two datasets'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets.map((dataset) => dataset.label),
|
||||
['Yes', 'Maybe'],
|
||||
'datasets having answers as label and are in correct order'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets[0].data,
|
||||
[100, 50, 0, 0],
|
||||
'dataset for yes is correct'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets[1].data,
|
||||
[0, 50, 50, 0],
|
||||
'dataset for maybe is correct'
|
||||
);
|
||||
});
|
||||
|
||||
test('data is a valid ChartJS dataset for FindADate using poll timezone', function(assert) {
|
||||
let options = [
|
||||
EmberObject.create({
|
||||
title: '2015-01-01'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: '2015-02-02'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: '2015-03-03T01:00:00.000Z'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: '2015-03-03T11:00:00.000Z'
|
||||
})
|
||||
];
|
||||
let users = [
|
||||
EmberObject.create({
|
||||
id: 1,
|
||||
selections: [
|
||||
test('data is a valid ChartJS dataset for MakeAPoll', function(assert) {
|
||||
const options = [
|
||||
EmberObject.create({
|
||||
title: 'first option'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: 'second option'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: 'third option'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: 'fourth option'
|
||||
})
|
||||
];
|
||||
let component = this.owner.factoryFor('component:poll-evaluation-chart').create({
|
||||
answerType: 'YesNoMaybe',
|
||||
options,
|
||||
users: [
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
id: 1,
|
||||
selections: [
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'maybe'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
})
|
||||
]
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'maybe'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
id: 2,
|
||||
selections: [
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'maybe'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
})
|
||||
]
|
||||
})
|
||||
]
|
||||
}),
|
||||
EmberObject.create({
|
||||
id: 2,
|
||||
selections: [
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'maybe'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
})
|
||||
]
|
||||
})
|
||||
];
|
||||
let currentLocale = 'en';
|
||||
let momentLongDayFormat = moment.localeData(currentLocale)
|
||||
.longDateFormat('LLLL')
|
||||
.replace(
|
||||
moment.localeData(currentLocale).longDateFormat('LT'), '')
|
||||
.trim();
|
||||
let component = this.subject({
|
||||
answerType: 'YesNoMaybe',
|
||||
currentLocale,
|
||||
isFindADate: true,
|
||||
momentLongDayFormat,
|
||||
options,
|
||||
timezone: 'Asia/Hong_Kong',
|
||||
users
|
||||
});
|
||||
const data = component.get('data');
|
||||
assert.deepEqual(
|
||||
data.labels,
|
||||
options.map((option) => option.get('title')),
|
||||
'Labels are correct'
|
||||
);
|
||||
assert.equal(
|
||||
data.datasets.length,
|
||||
2,
|
||||
'there are two datasets'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets.map((dataset) => dataset.label),
|
||||
['Yes', 'Maybe'],
|
||||
'datasets having answers as label and are in correct order'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets[0].data,
|
||||
[100, 50, 0, 0],
|
||||
'dataset for yes is correct'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets[1].data,
|
||||
[0, 50, 50, 0],
|
||||
'dataset for maybe is correct'
|
||||
);
|
||||
});
|
||||
const data = component.get('data');
|
||||
assert.deepEqual(
|
||||
data.labels,
|
||||
['Thursday, January 1, 2015', 'Monday, February 2, 2015', 'Tuesday, March 3, 2015 9:00 AM', 'Tuesday, March 3, 2015 7:00 PM'],
|
||||
'Labels are correct'
|
||||
);
|
||||
assert.equal(
|
||||
data.datasets.length,
|
||||
2,
|
||||
'there are two datasets'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets.map((dataset) => dataset.label),
|
||||
['Yes', 'Maybe'],
|
||||
'datasets having answers as label and are in correct order'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets[0].data,
|
||||
[100, 50, 0, 0],
|
||||
'dataset for yes is correct'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets[1].data,
|
||||
[0, 50, 50, 0],
|
||||
'dataset for maybe is correct'
|
||||
);
|
||||
});
|
||||
|
||||
test('data is a valid ChartJS dataset for FindADate using locale timezone', function(assert) {
|
||||
let options = [
|
||||
EmberObject.create({
|
||||
title: '2015-03-03T01:00:00.000Z'
|
||||
})
|
||||
];
|
||||
let component = this.subject({
|
||||
answerType: 'YesNoMaybe',
|
||||
currentLocale: 'en',
|
||||
isFindADate: true,
|
||||
momentLongDayFormat: '',
|
||||
options,
|
||||
timezone: undefined,
|
||||
users: []
|
||||
test('data is a valid ChartJS dataset for FindADate using poll timezone', function(assert) {
|
||||
let options = [
|
||||
EmberObject.create({
|
||||
title: '2015-01-01'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: '2015-02-02'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: '2015-03-03T01:00:00.000Z'
|
||||
}),
|
||||
EmberObject.create({
|
||||
title: '2015-03-03T11:00:00.000Z'
|
||||
})
|
||||
];
|
||||
let users = [
|
||||
EmberObject.create({
|
||||
id: 1,
|
||||
selections: [
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'maybe'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
})
|
||||
]
|
||||
}),
|
||||
EmberObject.create({
|
||||
id: 2,
|
||||
selections: [
|
||||
EmberObject.create({
|
||||
type: 'yes'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'maybe'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
}),
|
||||
EmberObject.create({
|
||||
type: 'no'
|
||||
})
|
||||
]
|
||||
})
|
||||
];
|
||||
let currentLocale = 'en';
|
||||
let momentLongDayFormat = moment.localeData(currentLocale)
|
||||
.longDateFormat('LLLL')
|
||||
.replace(
|
||||
moment.localeData(currentLocale).longDateFormat('LT'), '')
|
||||
.trim();
|
||||
let component = this.owner.factoryFor('component:poll-evaluation-chart').create({
|
||||
answerType: 'YesNoMaybe',
|
||||
currentLocale,
|
||||
isFindADate: true,
|
||||
momentLongDayFormat,
|
||||
options,
|
||||
timezone: 'Asia/Hong_Kong',
|
||||
users
|
||||
});
|
||||
const data = component.get('data');
|
||||
assert.deepEqual(
|
||||
data.labels,
|
||||
['Thursday, January 1, 2015', 'Monday, February 2, 2015', 'Tuesday, March 3, 2015 9:00 AM', 'Tuesday, March 3, 2015 7:00 PM'],
|
||||
'Labels are correct'
|
||||
);
|
||||
assert.equal(
|
||||
data.datasets.length,
|
||||
2,
|
||||
'there are two datasets'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets.map((dataset) => dataset.label),
|
||||
['Yes', 'Maybe'],
|
||||
'datasets having answers as label and are in correct order'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets[0].data,
|
||||
[100, 50, 0, 0],
|
||||
'dataset for yes is correct'
|
||||
);
|
||||
assert.deepEqual(
|
||||
data.datasets[1].data,
|
||||
[0, 50, 50, 0],
|
||||
'dataset for maybe is correct'
|
||||
);
|
||||
});
|
||||
|
||||
test('data is a valid ChartJS dataset for FindADate using locale timezone', function(assert) {
|
||||
let options = [
|
||||
EmberObject.create({
|
||||
title: '2015-03-03T01:00:00.000Z'
|
||||
})
|
||||
];
|
||||
let component = this.owner.factoryFor('component:poll-evaluation-chart').create({
|
||||
answerType: 'YesNoMaybe',
|
||||
currentLocale: 'en',
|
||||
isFindADate: true,
|
||||
momentLongDayFormat: '',
|
||||
options,
|
||||
timezone: undefined,
|
||||
users: []
|
||||
});
|
||||
const data = component.get('data');
|
||||
assert.deepEqual(
|
||||
data.labels,
|
||||
[moment('2015-03-03T01:00:00.000Z').format('LLLL')],
|
||||
'Labels are correct'
|
||||
);
|
||||
});
|
||||
const data = component.get('data');
|
||||
assert.deepEqual(
|
||||
data.labels,
|
||||
[moment('2015-03-03T01:00:00.000Z').format('LLLL')],
|
||||
'Labels are correct'
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:create', 'Unit | Controller | create', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
module('Unit | Controller | create', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.owner.lookup('controller:create');
|
||||
assert.ok(controller);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,58 +1,60 @@
|
|||
import { run } from '@ember/runloop';
|
||||
import EmberObject from '@ember/object';
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import moment from 'moment';
|
||||
|
||||
moduleFor('controller:create/options-datetime', 'Unit | Controller | create/options datetime', {
|
||||
});
|
||||
module('Unit | Controller | create/options datetime', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('normalize options - remove days without time if there is another option with a time for that day', function(assert) {
|
||||
const dirtyOption = EmberObject.create({ title: '2015-01-01' });
|
||||
let controller = this.subject({
|
||||
model: {
|
||||
options: [
|
||||
EmberObject.create({ title: '2015-01-01T12:00:00.000Z' }),
|
||||
dirtyOption,
|
||||
EmberObject.create({ title: '2017-11-11' }),
|
||||
EmberObject.create({ title: '2018-04-04T11:11:00.000Z' })
|
||||
]
|
||||
}
|
||||
test('normalize options - remove days without time if there is another option with a time for that day', function(assert) {
|
||||
const dirtyOption = EmberObject.create({ title: '2015-01-01' });
|
||||
let controller = this.owner.factoryFor('controller:create/options-datetime').create({
|
||||
model: {
|
||||
options: [
|
||||
EmberObject.create({ title: '2015-01-01T12:00:00.000Z' }),
|
||||
dirtyOption,
|
||||
EmberObject.create({ title: '2017-11-11' }),
|
||||
EmberObject.create({ title: '2018-04-04T11:11:00.000Z' })
|
||||
]
|
||||
}
|
||||
});
|
||||
run(() => {
|
||||
controller.normalizeOptions();
|
||||
});
|
||||
assert.equal(
|
||||
controller.get('options.length'),
|
||||
3,
|
||||
'one option is removed'
|
||||
);
|
||||
assert.ok(
|
||||
controller.get('options').indexOf(dirtyOption) === -1,
|
||||
'correct option is removed'
|
||||
);
|
||||
});
|
||||
run(() => {
|
||||
controller.normalizeOptions();
|
||||
});
|
||||
assert.equal(
|
||||
controller.get('options.length'),
|
||||
3,
|
||||
'one option is removed'
|
||||
);
|
||||
assert.ok(
|
||||
controller.get('options').indexOf(dirtyOption) === -1,
|
||||
'correct option is removed'
|
||||
);
|
||||
});
|
||||
|
||||
test('normalize options - sort them', function(assert) {
|
||||
const dateA = moment().hour(5).toISOString();
|
||||
const dateB = moment().hour(10).toISOString();
|
||||
const dateC = moment().hour(22).toISOString();
|
||||
const dateD = moment().add(1, 'day').toISOString();
|
||||
let controller = this.subject({
|
||||
model: {
|
||||
options: [
|
||||
EmberObject.create({ title: dateB }),
|
||||
EmberObject.create({ title: dateA }),
|
||||
EmberObject.create({ title: dateC }),
|
||||
EmberObject.create({ title: dateD })
|
||||
]
|
||||
}
|
||||
test('normalize options - sort them', function(assert) {
|
||||
const dateA = moment().hour(5).toISOString();
|
||||
const dateB = moment().hour(10).toISOString();
|
||||
const dateC = moment().hour(22).toISOString();
|
||||
const dateD = moment().add(1, 'day').toISOString();
|
||||
let controller = this.owner.factoryFor('controller:create/options-datetime').create({
|
||||
model: {
|
||||
options: [
|
||||
EmberObject.create({ title: dateB }),
|
||||
EmberObject.create({ title: dateA }),
|
||||
EmberObject.create({ title: dateC }),
|
||||
EmberObject.create({ title: dateD })
|
||||
]
|
||||
}
|
||||
});
|
||||
run(() => {
|
||||
controller.normalizeOptions();
|
||||
});
|
||||
assert.deepEqual(
|
||||
controller.get('options').map((option) => option.get('title')),
|
||||
[dateA, dateB, dateC, dateD],
|
||||
'options are sorted'
|
||||
);
|
||||
});
|
||||
run(() => {
|
||||
controller.normalizeOptions();
|
||||
});
|
||||
assert.deepEqual(
|
||||
controller.get('options').map((option) => option.get('title')),
|
||||
[dateA, dateB, dateC, dateD],
|
||||
'options are sorted'
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:create/options', 'Unit | Controller | create/options', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
module('Unit | Controller | create/options', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.owner.lookup('controller:create/options');
|
||||
assert.ok(controller);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:error', 'Unit | Controller | error', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
module('Unit | Controller | error', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.owner.lookup('controller:error');
|
||||
assert.ok(controller);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,30 +1,31 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import moment from 'moment';
|
||||
|
||||
moduleFor('controller:poll', 'Unit | Controller | poll', {
|
||||
needs: ['service:encryption', 'service:flashMessages', 'service:i18n']
|
||||
});
|
||||
module('Unit | Controller | poll', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('#showExpirationWarning', function(assert) {
|
||||
let controller = this.subject({
|
||||
model: {
|
||||
expirationDate: undefined
|
||||
}
|
||||
test('#showExpirationWarning', function(assert) {
|
||||
let controller = this.owner.factoryFor('controller:poll').create({
|
||||
model: {
|
||||
expirationDate: undefined
|
||||
}
|
||||
});
|
||||
assert.notOk(
|
||||
controller.get('showExpirationWarning'),
|
||||
'is false if expirationDate is undefined'
|
||||
);
|
||||
|
||||
controller.set('model.expirationDate', moment().add(1, 'week').toISOString());
|
||||
assert.ok(
|
||||
controller.get('showExpirationWarning'),
|
||||
'is true if expirationDate is less than 2 weeks in future'
|
||||
);
|
||||
|
||||
controller.set('model.expirationDate', moment().add(1, 'month').toISOString());
|
||||
assert.notOk(
|
||||
controller.get('showExpirationWarning'),
|
||||
'is false if expirationDate is more than 2 weeks in future'
|
||||
);
|
||||
});
|
||||
assert.notOk(
|
||||
controller.get('showExpirationWarning'),
|
||||
'is false if expirationDate is undefined'
|
||||
);
|
||||
|
||||
controller.set('model.expirationDate', moment().add(1, 'week').toISOString());
|
||||
assert.ok(
|
||||
controller.get('showExpirationWarning'),
|
||||
'is true if expirationDate is less than 2 weeks in future'
|
||||
);
|
||||
|
||||
controller.set('model.expirationDate', moment().add(1, 'month').toISOString());
|
||||
assert.notOk(
|
||||
controller.get('showExpirationWarning'),
|
||||
'is false if expirationDate is more than 2 weeks in future'
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:poll/participation', 'Unit | Controller | poll/participation', {
|
||||
needs: [
|
||||
'config:environment',
|
||||
'controller:poll',
|
||||
'service:encryption', 'service:i18n',
|
||||
'validator:collection', 'validator:presence', 'validator:unique'
|
||||
]
|
||||
});
|
||||
module('Unit | Controller | poll/participation', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.owner.lookup('controller:poll/participation');
|
||||
assert.ok(controller);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,11 +2,11 @@ import EmberObject from '@ember/object';
|
|||
import AutofocusSupportMixin from 'croodle/mixins/autofocus-support';
|
||||
import { module, test } from 'qunit';
|
||||
|
||||
module('Unit | Mixin | autofocus support');
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it works', function(assert) {
|
||||
let AutofocusSupportObject = EmberObject.extend(AutofocusSupportMixin);
|
||||
let subject = AutofocusSupportObject.create();
|
||||
assert.ok(subject);
|
||||
module('Unit | Mixin | autofocus support', function() {
|
||||
// Replace this with your real tests.
|
||||
test('it works', function(assert) {
|
||||
let AutofocusSupportObject = EmberObject.extend(AutofocusSupportMixin);
|
||||
let subject = AutofocusSupportObject.create();
|
||||
assert.ok(subject);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { run } from '@ember/runloop';
|
||||
import Service from '@ember/service';
|
||||
import { moduleForModel, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import moment from 'moment';
|
||||
|
||||
const i18nStub = Service.extend({
|
||||
|
@ -10,356 +11,347 @@ const i18nStub = Service.extend({
|
|||
locale: 'en'
|
||||
});
|
||||
|
||||
moduleForModel('option', 'Unit | Model | option', {
|
||||
needs: [
|
||||
'validator:alias',
|
||||
'validator:iso8601',
|
||||
'validator:unique',
|
||||
'validator:presence',
|
||||
'validator:messages',
|
||||
'validator:time',
|
||||
'model:poll',
|
||||
'model:user'
|
||||
],
|
||||
module('Unit | Model | option', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
beforeEach() {
|
||||
this.register('service:i18n', i18nStub);
|
||||
this.inject.service('i18n', { as: 'i18n' });
|
||||
hooks.beforeEach(function() {
|
||||
this.owner.register('service:i18n', i18nStub);
|
||||
this.i18n = this.owner.lookup('service:i18n');
|
||||
moment.locale('en');
|
||||
}
|
||||
});
|
||||
|
||||
test('date property (get)', function(assert) {
|
||||
let option = this.subject({
|
||||
title: '2015-01-01'
|
||||
});
|
||||
assert.ok(
|
||||
moment.isMoment(option.get('date')),
|
||||
'returns a moment instance if title is an ISO 8601 day string'
|
||||
);
|
||||
assert.equal(
|
||||
option.get('date').format('YYYY-MM-DD HH:mm:ss.SSS'),
|
||||
'2015-01-01 00:00:00.000',
|
||||
'string to date conversion is correct for ISO 8601 day string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', '2015-01-01T11:11:00.000Z');
|
||||
});
|
||||
assert.ok(
|
||||
moment.isMoment(option.get('date')),
|
||||
'returns a moment instance if title is an ISO 8601 datetime string'
|
||||
);
|
||||
assert.equal(
|
||||
option.get('date').toISOString(),
|
||||
'2015-01-01T11:11:00.000Z',
|
||||
'string to date conversion is correct for ISO 8601 datetime string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', null);
|
||||
});
|
||||
assert.equal(
|
||||
option.get('date'),
|
||||
undefined,
|
||||
'returns undefined if title is empty'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', 'abc');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('date'),
|
||||
undefined,
|
||||
'returns undefined if title is not a valid ISO 8601 date string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', '2015');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('date'),
|
||||
undefined,
|
||||
'returns undefined if title ISO 8601 string only contains a year'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', '2015-01');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('date'),
|
||||
undefined,
|
||||
'returns undefined if title ISO 8601 string only contains a year and a month'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', '2013W06');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('date'),
|
||||
undefined,
|
||||
'returns undefined if title ISO 8601 string only contains a year and a week'
|
||||
);
|
||||
});
|
||||
|
||||
test('day property (get)', function(assert) {
|
||||
let option = this.subject({
|
||||
title: '2015-01-01'
|
||||
});
|
||||
assert.equal(
|
||||
option.get('day'),
|
||||
'2015-01-01',
|
||||
'returns ISO 8601 day string if title is ISO 8601 day string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', '2015-01-01T11:11:00.000Z');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('day'),
|
||||
moment('2015-01-01T11:11:00.000Z').format('YYYY-MM-DD'),
|
||||
'returns ISO 8601 day string if title is ISO 8601 datetime string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', 'abc');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('day'),
|
||||
undefined,
|
||||
'returns undefined if title is not a valid ISO 8601 string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', null);
|
||||
});
|
||||
assert.equal(
|
||||
option.get('day'),
|
||||
undefined,
|
||||
'returns undefined if title is null'
|
||||
);
|
||||
});
|
||||
|
||||
test('dayFormatted property (get)', function(assert) {
|
||||
let option = this.subject({
|
||||
title: '2015-01-01'
|
||||
});
|
||||
assert.equal(
|
||||
option.get('dayFormatted'),
|
||||
'Thursday, January 1, 2015',
|
||||
'returns formatted date if title is ISO 8601 day string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', moment('2015-01-01').toISOString());
|
||||
});
|
||||
assert.equal(
|
||||
option.get('dayFormatted'),
|
||||
'Thursday, January 1, 2015',
|
||||
'returns formatted date if title is ISO 8601 datetime string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('i18n.locale', 'de');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('dayFormatted'),
|
||||
'Donnerstag, 1. Januar 2015',
|
||||
'observes locale changes'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', 'abc');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('dayFormatted'),
|
||||
undefined,
|
||||
'returns undfined if title is not a valid ISO 8601 string'
|
||||
);
|
||||
});
|
||||
|
||||
test('hasTime property', function(assert) {
|
||||
let option = this.subject({
|
||||
title: '2015-01-01T11:11:00.000Z'
|
||||
});
|
||||
assert.ok(option.get('hasTime'));
|
||||
run(() => {
|
||||
option.set('title', '2015-01-01');
|
||||
});
|
||||
assert.notOk(option.get('hasTime'));
|
||||
run(() => {
|
||||
option.set('title', 'foo');
|
||||
});
|
||||
assert.notOk(option.get('hasTime'));
|
||||
});
|
||||
|
||||
test('time property (get)', function(assert) {
|
||||
let option = this.subject({
|
||||
title: '2015-01-01T11:11:00.000Z'
|
||||
});
|
||||
assert.equal(
|
||||
option.get('time'),
|
||||
moment('2015-01-01T11:11:00.000Z').format('HH:mm'),
|
||||
'returns time if title is ISO 8601 datetime string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', '2015-01-01');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('time'),
|
||||
undefined,
|
||||
'returns undefined if title is ISO 8601 day string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', 'abc');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('time'),
|
||||
undefined,
|
||||
'returns undefined if title is not an ISO 8601 date string'
|
||||
);
|
||||
});
|
||||
|
||||
test('time property (set)', function(assert) {
|
||||
let option = this.subject({
|
||||
title: '2015-01-01'
|
||||
});
|
||||
|
||||
run(() => {
|
||||
option.set('time', '11:00');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('title'),
|
||||
moment('2015-01-01T11:00').toISOString(),
|
||||
'sets title according to time'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('time', null);
|
||||
});
|
||||
assert.equal(
|
||||
option.get('title'),
|
||||
'2015-01-01',
|
||||
'removes time from option if value is false'
|
||||
);
|
||||
|
||||
const before = option.get('title');
|
||||
run(() => {
|
||||
option.set('time', 'abc');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('title'),
|
||||
before,
|
||||
'does not set title if time is invalid'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', 'abc');
|
||||
});
|
||||
assert.throws(
|
||||
() => {
|
||||
option.set('time', '11:11');
|
||||
},
|
||||
'throws if attempt to set a time if title is not a date string'
|
||||
);
|
||||
});
|
||||
|
||||
test('validation for MakeAPoll', function(assert) {
|
||||
run(() => {
|
||||
let store = this.store();
|
||||
let poll = store.createRecord('poll', {
|
||||
pollType: 'MakeAPoll'
|
||||
});
|
||||
let option = store.createFragment('option');
|
||||
poll.get('options').pushObject(option);
|
||||
option.validate();
|
||||
assert.notOk(
|
||||
option.get('validations.isValid'),
|
||||
'default value is not valid'
|
||||
test('date property (get)', function(assert) {
|
||||
let option = run(() => this.owner.lookup('service:store').createRecord('option', {
|
||||
title: '2015-01-01'
|
||||
}));
|
||||
assert.ok(
|
||||
moment.isMoment(option.get('date')),
|
||||
'returns a moment instance if title is an ISO 8601 day string'
|
||||
);
|
||||
assert.equal(
|
||||
option.get('date').format('YYYY-MM-DD HH:mm:ss.SSS'),
|
||||
'2015-01-01 00:00:00.000',
|
||||
'string to date conversion is correct for ISO 8601 day string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', 'Spasibo!');
|
||||
option.set('title', '2015-01-01T11:11:00.000Z');
|
||||
});
|
||||
assert.ok(
|
||||
option.get('validations.isValid'),
|
||||
'is valid for a non empty string'
|
||||
moment.isMoment(option.get('date')),
|
||||
'returns a moment instance if title is an ISO 8601 datetime string'
|
||||
);
|
||||
run(() => {
|
||||
option.set('title', '!');
|
||||
});
|
||||
assert.ok(
|
||||
option.get('validations.isValid'),
|
||||
'is invalid if set to empty string again'
|
||||
assert.equal(
|
||||
option.get('date').toISOString(),
|
||||
'2015-01-01T11:11:00.000Z',
|
||||
'string to date conversion is correct for ISO 8601 datetime string'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('validation for FindADate', function(assert) {
|
||||
run(() => {
|
||||
let store = this.store();
|
||||
let poll = store.createRecord('poll', {
|
||||
isDateTime: false,
|
||||
pollType: 'FindADate'
|
||||
});
|
||||
let option = store.createFragment('option');
|
||||
poll.get('options').pushObject(option);
|
||||
option.validate();
|
||||
assert.notOk(
|
||||
option.get('validations.isValid'),
|
||||
'default value is not valid'
|
||||
);
|
||||
run(() => {
|
||||
option.set('title', '1945-05-08');
|
||||
option.set('title', null);
|
||||
});
|
||||
assert.ok(
|
||||
option.get('validations.isValid'),
|
||||
'iso 8601 date string is valid'
|
||||
assert.equal(
|
||||
option.get('date'),
|
||||
undefined,
|
||||
'returns undefined if title is empty'
|
||||
);
|
||||
run(() => {
|
||||
option.set('title', 'Spasibo!');
|
||||
});
|
||||
assert.notOk(
|
||||
option.get('validations.isValid'),
|
||||
'random string is not valid'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('validation for FindADate', function(assert) {
|
||||
run(() => {
|
||||
let store = this.store();
|
||||
let poll = store.createRecord('poll', {
|
||||
pollType: 'FindADate'
|
||||
});
|
||||
let option = store.createFragment('option');
|
||||
poll.get('options').pushObject(option);
|
||||
option.validate();
|
||||
assert.notOk(
|
||||
option.get('validations.isValid'),
|
||||
'default value is not valid'
|
||||
);
|
||||
run(() => {
|
||||
option.set('title', '1945-05-08T00:00:00.000Z');
|
||||
option.set('title', 'abc');
|
||||
});
|
||||
assert.ok(
|
||||
option.get('validations.isValid'),
|
||||
'iso 8601 datetime string is valid'
|
||||
assert.equal(
|
||||
option.get('date'),
|
||||
undefined,
|
||||
'returns undefined if title is not a valid ISO 8601 date string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', 'Spasibo!');
|
||||
option.set('title', '2015');
|
||||
});
|
||||
assert.notOk(
|
||||
option.get('validations.isValid'),
|
||||
'random string is not valid'
|
||||
assert.equal(
|
||||
option.get('date'),
|
||||
undefined,
|
||||
'returns undefined if title ISO 8601 string only contains a year'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', '1945-05-08');
|
||||
option.set('title', '2015-01');
|
||||
});
|
||||
assert.ok(
|
||||
option.get('validations.isValid'),
|
||||
'iso 8601 date string is valid'
|
||||
assert.equal(
|
||||
option.get('date'),
|
||||
undefined,
|
||||
'returns undefined if title ISO 8601 string only contains a year and a month'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', '2013W06');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('date'),
|
||||
undefined,
|
||||
'returns undefined if title ISO 8601 string only contains a year and a week'
|
||||
);
|
||||
});
|
||||
|
||||
test('day property (get)', function(assert) {
|
||||
let option = run(() => this.owner.lookup('service:store').createRecord('option', {
|
||||
title: '2015-01-01'
|
||||
}));
|
||||
assert.equal(
|
||||
option.get('day'),
|
||||
'2015-01-01',
|
||||
'returns ISO 8601 day string if title is ISO 8601 day string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', '2015-01-01T11:11:00.000Z');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('day'),
|
||||
moment('2015-01-01T11:11:00.000Z').format('YYYY-MM-DD'),
|
||||
'returns ISO 8601 day string if title is ISO 8601 datetime string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', 'abc');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('day'),
|
||||
undefined,
|
||||
'returns undefined if title is not a valid ISO 8601 string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', null);
|
||||
});
|
||||
assert.equal(
|
||||
option.get('day'),
|
||||
undefined,
|
||||
'returns undefined if title is null'
|
||||
);
|
||||
});
|
||||
|
||||
test('dayFormatted property (get)', function(assert) {
|
||||
let option = run(() => this.owner.lookup('service:store').createRecord('option', {
|
||||
title: '2015-01-01'
|
||||
}));
|
||||
assert.equal(
|
||||
option.get('dayFormatted'),
|
||||
'Thursday, January 1, 2015',
|
||||
'returns formatted date if title is ISO 8601 day string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', moment('2015-01-01').toISOString());
|
||||
});
|
||||
assert.equal(
|
||||
option.get('dayFormatted'),
|
||||
'Thursday, January 1, 2015',
|
||||
'returns formatted date if title is ISO 8601 datetime string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('i18n.locale', 'de');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('dayFormatted'),
|
||||
'Donnerstag, 1. Januar 2015',
|
||||
'observes locale changes'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', 'abc');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('dayFormatted'),
|
||||
undefined,
|
||||
'returns undfined if title is not a valid ISO 8601 string'
|
||||
);
|
||||
});
|
||||
|
||||
test('hasTime property', function(assert) {
|
||||
let option = run(() => this.owner.lookup('service:store').createRecord('option', {
|
||||
title: '2015-01-01T11:11:00.000Z'
|
||||
}));
|
||||
assert.ok(option.get('hasTime'));
|
||||
run(() => {
|
||||
option.set('title', '2015-01-01');
|
||||
});
|
||||
assert.notOk(option.get('hasTime'));
|
||||
run(() => {
|
||||
option.set('title', 'foo');
|
||||
});
|
||||
assert.notOk(option.get('hasTime'));
|
||||
});
|
||||
|
||||
test('time property (get)', function(assert) {
|
||||
let option = run(() => this.owner.lookup('service:store').createRecord('option', {
|
||||
title: '2015-01-01T11:11:00.000Z'
|
||||
}));
|
||||
assert.equal(
|
||||
option.get('time'),
|
||||
moment('2015-01-01T11:11:00.000Z').format('HH:mm'),
|
||||
'returns time if title is ISO 8601 datetime string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', '2015-01-01');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('time'),
|
||||
undefined,
|
||||
'returns undefined if title is ISO 8601 day string'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', 'abc');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('time'),
|
||||
undefined,
|
||||
'returns undefined if title is not an ISO 8601 date string'
|
||||
);
|
||||
});
|
||||
|
||||
test('time property (set)', function(assert) {
|
||||
let option = run(() => this.owner.lookup('service:store').createRecord('option', {
|
||||
title: '2015-01-01'
|
||||
}));
|
||||
|
||||
run(() => {
|
||||
option.set('time', '11:00');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('title'),
|
||||
moment('2015-01-01T11:00').toISOString(),
|
||||
'sets title according to time'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('time', null);
|
||||
});
|
||||
assert.equal(
|
||||
option.get('title'),
|
||||
'2015-01-01',
|
||||
'removes time from option if value is false'
|
||||
);
|
||||
|
||||
const before = option.get('title');
|
||||
run(() => {
|
||||
option.set('time', 'abc');
|
||||
});
|
||||
assert.equal(
|
||||
option.get('title'),
|
||||
before,
|
||||
'does not set title if time is invalid'
|
||||
);
|
||||
|
||||
run(() => {
|
||||
option.set('title', 'abc');
|
||||
});
|
||||
assert.throws(
|
||||
() => {
|
||||
option.set('time', '11:11');
|
||||
},
|
||||
'throws if attempt to set a time if title is not a date string'
|
||||
);
|
||||
});
|
||||
|
||||
test('validation for MakeAPoll', function(assert) {
|
||||
run(() => {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let poll = store.createRecord('poll', {
|
||||
pollType: 'MakeAPoll'
|
||||
});
|
||||
let option = store.createFragment('option');
|
||||
poll.get('options').pushObject(option);
|
||||
option.validate();
|
||||
assert.notOk(
|
||||
option.get('validations.isValid'),
|
||||
'default value is not valid'
|
||||
);
|
||||
run(() => {
|
||||
option.set('title', 'Spasibo!');
|
||||
});
|
||||
assert.ok(
|
||||
option.get('validations.isValid'),
|
||||
'is valid for a non empty string'
|
||||
);
|
||||
run(() => {
|
||||
option.set('title', '!');
|
||||
});
|
||||
assert.ok(
|
||||
option.get('validations.isValid'),
|
||||
'is invalid if set to empty string again'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('validation for FindADate', function(assert) {
|
||||
run(() => {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let poll = store.createRecord('poll', {
|
||||
isDateTime: false,
|
||||
pollType: 'FindADate'
|
||||
});
|
||||
let option = store.createFragment('option');
|
||||
poll.get('options').pushObject(option);
|
||||
option.validate();
|
||||
assert.notOk(
|
||||
option.get('validations.isValid'),
|
||||
'default value is not valid'
|
||||
);
|
||||
run(() => {
|
||||
option.set('title', '1945-05-08');
|
||||
});
|
||||
assert.ok(
|
||||
option.get('validations.isValid'),
|
||||
'iso 8601 date string is valid'
|
||||
);
|
||||
run(() => {
|
||||
option.set('title', 'Spasibo!');
|
||||
});
|
||||
assert.notOk(
|
||||
option.get('validations.isValid'),
|
||||
'random string is not valid'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('validation for FindADate', function(assert) {
|
||||
run(() => {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let poll = store.createRecord('poll', {
|
||||
pollType: 'FindADate'
|
||||
});
|
||||
let option = store.createFragment('option');
|
||||
poll.get('options').pushObject(option);
|
||||
option.validate();
|
||||
assert.notOk(
|
||||
option.get('validations.isValid'),
|
||||
'default value is not valid'
|
||||
);
|
||||
run(() => {
|
||||
option.set('title', '1945-05-08T00:00:00.000Z');
|
||||
});
|
||||
assert.ok(
|
||||
option.get('validations.isValid'),
|
||||
'iso 8601 datetime string is valid'
|
||||
);
|
||||
run(() => {
|
||||
option.set('title', 'Spasibo!');
|
||||
});
|
||||
assert.notOk(
|
||||
option.get('validations.isValid'),
|
||||
'random string is not valid'
|
||||
);
|
||||
run(() => {
|
||||
option.set('title', '1945-05-08');
|
||||
});
|
||||
assert.ok(
|
||||
option.get('validations.isValid'),
|
||||
'iso 8601 date string is valid'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
moduleFor('route:create/options-datetime', 'Unit | Route | create/options datetime', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
module('Unit | Route | create/options datetime', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.subject();
|
||||
assert.ok(route);
|
||||
test('it exists', function(assert) {
|
||||
let route = this.owner.lookup('route:create/options-datetime');
|
||||
assert.ok(route);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
moduleFor('service:encryption', 'Unit | Service | encryption', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['service:foo']
|
||||
});
|
||||
module('Unit | Service | encryption', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let service = this.subject();
|
||||
assert.ok(service);
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let service = this.owner.lookup('service:encryption');
|
||||
assert.ok(service);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,96 +1,98 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
moduleFor('validator:iso8601', 'Unit | Validator | iso8601', {
|
||||
});
|
||||
module('Unit | Validator | iso8601', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('default validation is correct', function(assert) {
|
||||
let validator = this.subject();
|
||||
assert.equal(
|
||||
validator.validate('1945-05-08T23:01:00.000Z'),
|
||||
true,
|
||||
'iso 8601 datetime string with milliseconds in UTC is valid by default'
|
||||
);
|
||||
assert.notOk(
|
||||
validator.validate(null) === true,
|
||||
'null is invalid'
|
||||
);
|
||||
assert.notOk(
|
||||
validator.validate(undefined) === true,
|
||||
'undefined is invalid'
|
||||
);
|
||||
assert.notOk(
|
||||
validator.validate('') === true,
|
||||
'empty string is invalid'
|
||||
);
|
||||
assert.notOk(
|
||||
validator.validate('abc123') === true,
|
||||
'random string is invalid'
|
||||
);
|
||||
});
|
||||
test('default validation is correct', function(assert) {
|
||||
let validator = this.owner.lookup('validator:iso8601');
|
||||
assert.equal(
|
||||
validator.validate('1945-05-08T23:01:00.000Z'),
|
||||
true,
|
||||
'iso 8601 datetime string with milliseconds in UTC is valid by default'
|
||||
);
|
||||
assert.notOk(
|
||||
validator.validate(null) === true,
|
||||
'null is invalid'
|
||||
);
|
||||
assert.notOk(
|
||||
validator.validate(undefined) === true,
|
||||
'undefined is invalid'
|
||||
);
|
||||
assert.notOk(
|
||||
validator.validate('') === true,
|
||||
'empty string is invalid'
|
||||
);
|
||||
assert.notOk(
|
||||
validator.validate('abc123') === true,
|
||||
'random string is invalid'
|
||||
);
|
||||
});
|
||||
|
||||
test('option.active disables validation on false', function(assert) {
|
||||
let validator = this.subject();
|
||||
const buildOptions = validator.buildOptions({ active: false }, {});
|
||||
assert.notOk(
|
||||
validator.validate(null) === true,
|
||||
'is validated on default'
|
||||
);
|
||||
assert.equal(
|
||||
validator.validate(null, buildOptions),
|
||||
true,
|
||||
'validation is disabled on active === false'
|
||||
);
|
||||
});
|
||||
test('option.active disables validation on false', function(assert) {
|
||||
let validator = this.owner.lookup('validator:iso8601');
|
||||
const buildOptions = validator.buildOptions({ active: false }, {});
|
||||
assert.notOk(
|
||||
validator.validate(null) === true,
|
||||
'is validated on default'
|
||||
);
|
||||
assert.equal(
|
||||
validator.validate(null, buildOptions),
|
||||
true,
|
||||
'validation is disabled on active === false'
|
||||
);
|
||||
});
|
||||
|
||||
test('option.active could be a function', function(assert) {
|
||||
let validator = this.subject();
|
||||
const buildOptions = validator.buildOptions({
|
||||
active() {
|
||||
return false;
|
||||
}
|
||||
}, {});
|
||||
assert.equal(
|
||||
validator.validate(null, buildOptions),
|
||||
true,
|
||||
'validation is dislabed if function returns false'
|
||||
);
|
||||
});
|
||||
test('option.active could be a function', function(assert) {
|
||||
let validator = this.owner.lookup('validator:iso8601');
|
||||
const buildOptions = validator.buildOptions({
|
||||
active() {
|
||||
return false;
|
||||
}
|
||||
}, {});
|
||||
assert.equal(
|
||||
validator.validate(null, buildOptions),
|
||||
true,
|
||||
'validation is dislabed if function returns false'
|
||||
);
|
||||
});
|
||||
|
||||
test('valid iso8601 string formats could be defined by options.validFormats', function(assert) {
|
||||
let validator = this.subject();
|
||||
const buildOptions = validator.buildOptions({
|
||||
validFormats: [
|
||||
'YYYY-MM-DD',
|
||||
'YYYY-MM-DDTHH:mmZ',
|
||||
'YYYY-MM-DDTHH:mm:ssZ'
|
||||
]
|
||||
}, {});
|
||||
assert.notOk(
|
||||
validator.validate('1945-05-08') === true,
|
||||
'iso 8601 date string is invalid by default'
|
||||
);
|
||||
assert.equal(
|
||||
validator.validate('1945-05-08', buildOptions),
|
||||
true,
|
||||
'iso 8601 date string is valid if it\'s in validFormats options'
|
||||
);
|
||||
assert.notOk(
|
||||
validator.validate('1945-05-08T23:01Z') === true,
|
||||
'iso 8601 datetime string in UTC is invalid by default'
|
||||
);
|
||||
assert.equal(
|
||||
validator.validate('1945-05-08T23:01Z', buildOptions),
|
||||
true,
|
||||
'iso 8601 datetime string in UTC is valid if it\'s in validFormats options'
|
||||
);
|
||||
assert.notOk(
|
||||
validator.validate('1945-05-08T23:01:00Z') === true,
|
||||
true,
|
||||
'iso 8601 datetime string with seconds in UTC is invalid by default'
|
||||
);
|
||||
assert.equal(
|
||||
validator.validate('1945-05-08T23:01:00Z', buildOptions),
|
||||
true,
|
||||
'iso 8601 datetime string with seconds in UTC is valid if it\'s in validFormats options'
|
||||
);
|
||||
test('valid iso8601 string formats could be defined by options.validFormats', function(assert) {
|
||||
let validator = this.owner.lookup('validator:iso8601');
|
||||
const buildOptions = validator.buildOptions({
|
||||
validFormats: [
|
||||
'YYYY-MM-DD',
|
||||
'YYYY-MM-DDTHH:mmZ',
|
||||
'YYYY-MM-DDTHH:mm:ssZ'
|
||||
]
|
||||
}, {});
|
||||
assert.notOk(
|
||||
validator.validate('1945-05-08') === true,
|
||||
'iso 8601 date string is invalid by default'
|
||||
);
|
||||
assert.equal(
|
||||
validator.validate('1945-05-08', buildOptions),
|
||||
true,
|
||||
'iso 8601 date string is valid if it\'s in validFormats options'
|
||||
);
|
||||
assert.notOk(
|
||||
validator.validate('1945-05-08T23:01Z') === true,
|
||||
'iso 8601 datetime string in UTC is invalid by default'
|
||||
);
|
||||
assert.equal(
|
||||
validator.validate('1945-05-08T23:01Z', buildOptions),
|
||||
true,
|
||||
'iso 8601 datetime string in UTC is valid if it\'s in validFormats options'
|
||||
);
|
||||
assert.notOk(
|
||||
validator.validate('1945-05-08T23:01:00Z') === true,
|
||||
true,
|
||||
'iso 8601 datetime string with seconds in UTC is invalid by default'
|
||||
);
|
||||
assert.equal(
|
||||
validator.validate('1945-05-08T23:01:00Z', buildOptions),
|
||||
true,
|
||||
'iso 8601 datetime string with seconds in UTC is valid if it\'s in validFormats options'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,47 +1,49 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
moduleFor('validator:time', 'Unit | Validator | time', {
|
||||
});
|
||||
|
||||
test('HH:mm is treated as valid', function(assert) {
|
||||
let validator = this.subject();
|
||||
|
||||
assert.equal(validator.validate('00:00'), true);
|
||||
assert.equal(validator.validate('23:59'), true);
|
||||
});
|
||||
|
||||
test('24:00 is invalid', function(assert) {
|
||||
let validator = this.subject();
|
||||
|
||||
assert.ok(typeof validator.validate('24:00') === 'string');
|
||||
});
|
||||
|
||||
test('00:60 is invalid', function(assert) {
|
||||
let validator = this.subject();
|
||||
|
||||
assert.ok(typeof validator.validate('00:60') === 'string');
|
||||
});
|
||||
|
||||
test('an empty string is invalid', function(assert) {
|
||||
let validator = this.subject();
|
||||
|
||||
assert.ok(typeof validator.validate('') === 'string');
|
||||
});
|
||||
|
||||
test('null is invalid', function(assert) {
|
||||
let validator = this.subject();
|
||||
|
||||
assert.ok(typeof validator.validate(null) === 'string');
|
||||
});
|
||||
|
||||
test('undefined is invalid', function(assert) {
|
||||
let validator = this.subject();
|
||||
|
||||
assert.ok(typeof validator.validate(undefined) === 'string');
|
||||
});
|
||||
|
||||
test('a valid time wrapped by spaces is valid', function(assert) {
|
||||
let validator = this.subject();
|
||||
|
||||
assert.equal(validator.validate(' 10:00 '), true);
|
||||
module('Unit | Validator | time', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('HH:mm is treated as valid', function(assert) {
|
||||
let validator = this.owner.lookup('validator:time');
|
||||
|
||||
assert.equal(validator.validate('00:00'), true);
|
||||
assert.equal(validator.validate('23:59'), true);
|
||||
});
|
||||
|
||||
test('24:00 is invalid', function(assert) {
|
||||
let validator = this.owner.lookup('validator:time');
|
||||
|
||||
assert.ok(typeof validator.validate('24:00') === 'string');
|
||||
});
|
||||
|
||||
test('00:60 is invalid', function(assert) {
|
||||
let validator = this.owner.lookup('validator:time');
|
||||
|
||||
assert.ok(typeof validator.validate('00:60') === 'string');
|
||||
});
|
||||
|
||||
test('an empty string is invalid', function(assert) {
|
||||
let validator = this.owner.lookup('validator:time');
|
||||
|
||||
assert.ok(typeof validator.validate('') === 'string');
|
||||
});
|
||||
|
||||
test('null is invalid', function(assert) {
|
||||
let validator = this.owner.lookup('validator:time');
|
||||
|
||||
assert.ok(typeof validator.validate(null) === 'string');
|
||||
});
|
||||
|
||||
test('undefined is invalid', function(assert) {
|
||||
let validator = this.owner.lookup('validator:time');
|
||||
|
||||
assert.ok(typeof validator.validate(undefined) === 'string');
|
||||
});
|
||||
|
||||
test('a valid time wrapped by spaces is valid', function(assert) {
|
||||
let validator = this.owner.lookup('validator:time');
|
||||
|
||||
assert.equal(validator.validate(' 10:00 '), true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,88 +1,90 @@
|
|||
import { A } from '@ember/array';
|
||||
import EmberObject from '@ember/object';
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
moduleFor('validator:unique', 'Unit | Validator | unique', {
|
||||
});
|
||||
module('Unit | Validator | unique', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('throws if required option is missing', function(assert) {
|
||||
const validator = this.subject();
|
||||
assert.throws(
|
||||
function() {
|
||||
validator.validate(null, {
|
||||
parent: 'foo',
|
||||
dependentKeys: ['foo']
|
||||
});
|
||||
},
|
||||
'throws if attributeInParrent is not defined'
|
||||
);
|
||||
assert.throws(
|
||||
function() {
|
||||
validator.validate(null, {
|
||||
attributeInParent: 'foo',
|
||||
dependentKeys: ['foo']
|
||||
});
|
||||
},
|
||||
'throws if parent is not defined'
|
||||
);
|
||||
assert.throws(
|
||||
function() {
|
||||
validator.validate(null, {
|
||||
parent: 'foo',
|
||||
attributeInParent: 'foo'
|
||||
});
|
||||
},
|
||||
'throws if dependentKeys is not defined'
|
||||
);
|
||||
});
|
||||
|
||||
test('validation', function(assert) {
|
||||
const validator = this.subject();
|
||||
const parent = EmberObject.create({
|
||||
collection: A([])
|
||||
test('throws if required option is missing', function(assert) {
|
||||
const validator = this.owner.lookup('validator:unique');
|
||||
assert.throws(
|
||||
function() {
|
||||
validator.validate(null, {
|
||||
parent: 'foo',
|
||||
dependentKeys: ['foo']
|
||||
});
|
||||
},
|
||||
'throws if attributeInParrent is not defined'
|
||||
);
|
||||
assert.throws(
|
||||
function() {
|
||||
validator.validate(null, {
|
||||
attributeInParent: 'foo',
|
||||
dependentKeys: ['foo']
|
||||
});
|
||||
},
|
||||
'throws if parent is not defined'
|
||||
);
|
||||
assert.throws(
|
||||
function() {
|
||||
validator.validate(null, {
|
||||
parent: 'foo',
|
||||
attributeInParent: 'foo'
|
||||
});
|
||||
},
|
||||
'throws if dependentKeys is not defined'
|
||||
);
|
||||
});
|
||||
const childObject = EmberObject.extend({
|
||||
parent
|
||||
|
||||
test('validation', function(assert) {
|
||||
const validator = this.owner.lookup('validator:unique');
|
||||
const parent = EmberObject.create({
|
||||
collection: A([])
|
||||
});
|
||||
const childObject = EmberObject.extend({
|
||||
parent
|
||||
});
|
||||
const options = {
|
||||
parent: 'parent',
|
||||
attributeInParent: 'collection',
|
||||
dependentKeys: ['parent.collection.@each.value']
|
||||
};
|
||||
const child1 = childObject.create({ value: 'foo' });
|
||||
const child2 = childObject.create({ value: 'bar' });
|
||||
const child3 = childObject.create({ value: 'foo' });
|
||||
|
||||
parent.get('collection').push(child1);
|
||||
assert.ok(
|
||||
validator.validate(
|
||||
child1.get('value'),
|
||||
options,
|
||||
child1,
|
||||
'value'
|
||||
) === true,
|
||||
'valid for only one element'
|
||||
);
|
||||
|
||||
parent.get('collection').push(child2);
|
||||
assert.ok(
|
||||
validator.validate(
|
||||
child2.get('value'),
|
||||
options,
|
||||
child2,
|
||||
'value'
|
||||
) === true,
|
||||
'still valid after pushing another element with different value'
|
||||
);
|
||||
|
||||
parent.get('collection').push(child3);
|
||||
assert.ok(
|
||||
typeof validator.validate(
|
||||
child3.get('value'),
|
||||
options,
|
||||
child3,
|
||||
'value'
|
||||
) === 'string',
|
||||
'invalid after pushing element with same value'
|
||||
);
|
||||
});
|
||||
const options = {
|
||||
parent: 'parent',
|
||||
attributeInParent: 'collection',
|
||||
dependentKeys: ['parent.collection.@each.value']
|
||||
};
|
||||
const child1 = childObject.create({ value: 'foo' });
|
||||
const child2 = childObject.create({ value: 'bar' });
|
||||
const child3 = childObject.create({ value: 'foo' });
|
||||
|
||||
parent.get('collection').push(child1);
|
||||
assert.ok(
|
||||
validator.validate(
|
||||
child1.get('value'),
|
||||
options,
|
||||
child1,
|
||||
'value'
|
||||
) === true,
|
||||
'valid for only one element'
|
||||
);
|
||||
|
||||
parent.get('collection').push(child2);
|
||||
assert.ok(
|
||||
validator.validate(
|
||||
child2.get('value'),
|
||||
options,
|
||||
child2,
|
||||
'value'
|
||||
) === true,
|
||||
'still valid after pushing another element with different value'
|
||||
);
|
||||
|
||||
parent.get('collection').push(child3);
|
||||
assert.ok(
|
||||
typeof validator.validate(
|
||||
child3.get('value'),
|
||||
options,
|
||||
child3,
|
||||
'value'
|
||||
) === 'string',
|
||||
'invalid after pushing element with same value'
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
moduleFor('validator:valid-collection', 'Unit | Validator | valid-collection', {
|
||||
});
|
||||
module('Unit | Validator | valid-collection', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it works', function(assert) {
|
||||
let validator = this.subject();
|
||||
assert.ok(validator);
|
||||
test('it works', function(assert) {
|
||||
let validator = this.owner.lookup('validator:valid-collection');
|
||||
assert.ok(validator);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue