updates dependencies and fixes property modified twice in a single render deprecations

This commit is contained in:
jelhan 2017-07-29 15:00:11 +02:00
parent b517f0dee2
commit 632c36eb12
40 changed files with 2262 additions and 1574 deletions

14
.eslintrc.js Normal file
View file

@ -0,0 +1,14 @@
module.exports = {
root: true,
parserOptions: {
ecmaVersion: 2017,
sourceType: 'module'
},
extends: 'eslint:recommended',
env: {
browser: true,
es6: true
},
rules: {
}
};

8
.gitignore vendored
View file

@ -1,4 +1,4 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# See https://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
@ -18,4 +18,10 @@
/coverage/*
/libpeerconnection.log
npm-debug.log*
yarn-error.log
testem.log
# ember-try
.node_modules.ember-try/
bower.json.ember-try
package.json.ember-try

View file

@ -1,32 +0,0 @@
{
"predef": [
"document",
"window",
"-Promise"
],
"browser": true,
"boss": true,
"curly": true,
"debug": false,
"devel": true,
"eqeqeq": true,
"evil": true,
"forin": false,
"immed": false,
"laxbreak": false,
"newcap": true,
"noarg": true,
"noempty": false,
"nonew": false,
"nomen": false,
"onevar": false,
"plusplus": false,
"regexp": false,
"undef": true,
"sub": true,
"strict": false,
"white": false,
"eqnull": true,
"esversion": 6,
"unused": true
}

View file

@ -16,26 +16,16 @@ sudo: false
cache:
yarn: true
directories:
- travis_phantomjs
addons:
apt:
sources:
- sourceline: 'deb https://dl.yarnpkg.com/debian/ stable main'
key_url: 'https://dl.yarnpkg.com/debian/pubkey.gpg'
packages:
- yarn
before_install:
# update node
- nvm install 6
# update phantomjs
- export PATH=$PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64/bin:$PATH; if [ $(phantomjs --version) != '2.1.1' ]; then rm -rf $PWD/travis_phantomjs; mkdir -p $PWD/travis_phantomjs && wget https://assets.membergetmember.co/software/phantomjs-2.1.1-linux-x86_64.tar.bz2 -O $PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2 && tar -xvf $PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2 -C $PWD/travis_phantomjs; fi
- if $TEST_EMBER || $TEST_SAUCHE; then curl -o- -L https://yarnpkg.com/install.sh | bash; fi
- if $TEST_EMBER || $TEST_SAUCHE; then export PATH=$HOME/.yarn/bin:$PATH; fi
- if $TEST_EMBER; then yarn global add phantomjs-prebuilt; fi
- if $TEST_EMBER; then phantomjs --version; fi
install:
- if $TEST_EMBER || $TEST_SAUCE; then yarn global add bower; fi
- if $TEST_EMBER || $TEST_SAUCE; then yarn install; fi
- if $TEST_EMBER || $TEST_SAUCE; then yarn global add bower; fi
- if $TEST_EMBER || $TEST_SAUCE; then yarn install --no-interactive; fi
- if $TEST_EMBER || $TEST_SAUCE; then bower install; fi
# install non development composer requirements for api
- if $TEST_EMBER || $TEST_SAUCE; then cd api/ && composer install --no-dev && cd ..; fi

View file

@ -7,8 +7,6 @@ const { Application } = Ember;
let App;
Ember.MODEL_FACTORY_INJECTIONS = true;
App = Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,

View file

@ -6,7 +6,7 @@ from 'ember-cp-validations';
import { groupBy } from 'ember-array-computed-macros';
import Form from 'ember-bootstrap/components/bs-form';
const { computed, Component, inject, isEmpty, isPresent, observer } = Ember;
const { computed, Component, inject, isArray, isEmpty, isPresent, observer } = Ember;
const { filter, mapBy, readOnly } = computed;
let modelValidations = buildValidations({
@ -147,7 +147,10 @@ export default Component.extend(modelValidations, {
return childView instanceof Form;
});
}),
formElements: readOnly('form.childFormElements'),
formElements: computed('form.childFormElements', function() {
let formElements = this.get('form.childFormElements');
return isArray(formElements) ? formElements : [];
}),
daysValidationState: computed('formElements.@each.validation', function() {
return this.get('formElements').reduce(function(daysValidationState, item) {
const day = item.get('model.day');

View file

@ -2,7 +2,7 @@ import Ember from 'ember';
import BsForm from 'ember-bootstrap/components/bs-form';
import { anyBy } from 'ember-array-computed-macros';
const { Component, computed, inject, observer, on } = Ember;
const { Component, computed, inject, observer, on, run } = Ember;
export default Component.extend({
actions: {
@ -49,21 +49,24 @@ export default Component.extend({
this.set('form', this.nearestOfType(BsForm));
}),
labelValidationClass: computed('anyElementHasFeedback', 'anyElementIsInvalid', 'everyElementIsValid', function() {
if (!this.get('anyElementHasFeedback')) {
return 'label-has-no-validation';
}
labelValidationClass: 'label-has-no-validation',
updateLabelValidationClass: observer('anyElementHasFeedback', 'anyElementIsInvalid', 'everyElementIsValid', function() {
run.scheduleOnce('sync', () => {
let validationClass;
if (this.get('anyElementIsInvalid')) {
return 'label-has-error';
}
if (!this.get('anyElementHasFeedback')) {
validationClass = 'label-has-no-validation';
} else if (this.get('anyElementIsInvalid')) {
validationClass = 'label-has-error';
} else if (this.get('everyElementIsValid')) {
validationClass = 'label-has-success';
} else {
validationClass = 'label-has-no-validation';
}
if (this.get('everyElementIsValid')) {
return 'label-has-success';
}
return 'label-has-no-validation';
}),
this.set('labelValidationClass', validationClass);
});
}).on('init'),
classNameBindings: ['labelValidationClass'],

View file

@ -3,6 +3,7 @@ import moment from 'moment';
/* global jstz */
const {
ArrayProxy,
computed,
Controller,
getOwner,
@ -13,6 +14,69 @@ const {
observer
} = Ember;
const dateObject = EmberObject.extend({
i18n: inject.service(),
init() {
// retrive locale on init to setup observers
this.get('i18n.locale');
},
date: computed('dateString', 'i18n.locale', function() {
let value = this.get('dateString');
let date;
if (isEmpty(value)) {
return null;
}
date = moment(value);
if (
this.get('hasTime') &&
!this.get('useLocalTimezone')
) {
date.tz(this.get('timezone'));
}
return date;
}),
formatted: computed('date', 'hasTime', 'timezone', 'useLocaleTImezone', function() {
let date = this.get('date');
if (!moment.isMoment(date)) {
return '';
}
if (
this.get('hasTime') &&
!this.get('useLocaleTimezone') &&
isPresent(this.get('timezone'))
) {
date.tz(this.get('timezone'));
}
return this.get('hasTime') ? date.format('LLLL') : date.format(
moment.localeData()
.longDateFormat('LLLL')
.replace(
moment.localeData().longDateFormat('LT'), '')
.trim()
);
}),
formattedTime: computed('date', function() {
let date = this.get('title');
if (!moment.isMoment(date)) {
return '';
}
return date.format('LT');
}),
hasTime: computed('dateString', function() {
return moment(this.get('dateString'), 'YYYY-MM-DD', true).isValid() === false;
}),
title: computed.readOnly('date')
});
export default Controller.extend({
actions: {
linkAction(type) {
@ -75,7 +139,7 @@ export default Controller.extend({
let count = 0;
let lastDate = null;
datetimes.forEach(function(el) {
let date = moment(el.title)
let date = moment(el.get('date'))
.hour(0)
.minute(0)
.seconds(0)
@ -114,75 +178,21 @@ export default Controller.extend({
/*
* handles options if they are dates
*/
dates: computed('model.options.[]', 'useLocalTimezone', function() {
let timezone = false;
let dates = [];
const dateObject = EmberObject.extend({
i18n: inject.service(),
init() {
// retrive locale to setup observers
this.get('i18n.locale');
},
formatted: computed('title', 'i18n.locale', function() {
const date = this.get('title');
const locale = this.get('i18n.locale');
dates: computed('model.options', 'model.timezone', 'useLocalTimezone', function() {
let owner = getOwner(this);
let timezone = this.get('model.timezone');
let useLocalTimezone = this.get('useLocalTimezone');
// locale is stored on date, we have to override it if it has changed since creation
if (date.locale() !== locale) {
date.locale(this.get('i18n.locale'));
}
return this.get('hasTime') ? date.format('LLLL') : date.format(
moment.localeData()
.longDateFormat('LLLL')
.replace(
moment.localeData().longDateFormat('LT'), '')
.trim()
);
}),
formattedTime: computed('title', 'i18n.locale', function() {
const date = this.get('title');
const locale = this.get('i18n.locale');
// locale is stored on date, we have to override it if it has changed since creation
if (date.locale() !== locale) {
date.locale(this.get('i18n.locale'));
}
return date.format('LT');
})
});
// if poll type is find a date
// we return an empty array
if (!this.get('model.isFindADate')) {
return [];
}
// if poll has dates with times we have to care about timezone
// but since user timezone is default we only have to set timezone
// if timezone poll got created in should be used
if (
this.get('hasTimes') &&
!this.get('useLocalTimezone')
) {
timezone = this.get('model.timezone');
}
const owner = getOwner(this);
dates = this.get('model.options').map((option) => {
const date = moment(option.get('title'));
const hasTime = moment(option.get('title'), 'YYYY-MM-DD', true).isValid() === false;
if (timezone && hasTime) {
date.tz(timezone);
return ArrayProxy.create({
content: this.get('model.options'),
objectAtContent(idx) {
return dateObject.create(owner.ownerInjection(), {
dateString: this.get('content').objectAt(idx).get('title'),
timezone,
useLocalTimezone
});
}
return dateObject.create(owner.ownerInjection(), {
title: date,
hasTime
});
});
return dates;
}),
flashMessages: inject.service(),

View file

@ -180,7 +180,7 @@ export default Controller.extend(Validations, {
selections: computed('pollController.model.options', 'pollController.dates', function() {
let options;
const isFindADate = this.get('isFindADate');
let isFindADate = this.get('isFindADate');
let lastDate;
if (this.get('isFindADate')) {
@ -195,14 +195,14 @@ export default Controller.extend(Validations, {
// format label
if (isFindADate) {
if (option.hasTime && lastDate && option.title.format('YYYY-MM-DD') === lastDate.format('YYYY-MM-DD')) {
if (option.get('hasTime') && lastDate && option.get('date').format('YYYY-MM-DD') === lastDate.format('YYYY-MM-DD')) {
// do not repeat dates for different times
labelValue = option.title;
labelValue = option.get('date');
labelFormat = 'time';
} else {
labelValue = option.title;
labelFormat = option.hasTime ? 'day-with-time' : 'day';
lastDate = option.title;
labelValue = option.get('date');
labelFormat = option.get('hasTime') ? 'day-with-time' : 'day';
lastDate = option.get('date');
}
} else {
labelValue = option.get('title');

View file

@ -7,20 +7,20 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="referrer" content="no-referrer">
{{content-for 'head'}}
{{content-for "head"}}
<link rel="stylesheet" href="assets/vendor.css">
<link rel="stylesheet" href="assets/croodle.css">
<link rel="stylesheet" href="{{rootURL}}assets/vendor.css">
<link rel="stylesheet" href="{{rootURL}}assets/croodle.css">
{{content-for 'head-footer'}}
{{content-for "head-footer"}}
</head>
<body>
{{content-for 'body'}}
{{content-for "body"}}
<script src="assets/vendor.js"></script>
<script src="assets/croodle.js"></script>
<script src="{{rootURL}}assets/vendor.js"></script>
<script src="{{rootURL}}assets/croodle.js"></script>
{{content-for 'body-footer'}}
{{content-for "body-footer"}}
<noscript>
<div class="container-fluid">

View file

View file

View file

@ -1,8 +1,6 @@
{
"name": "croodle",
"dependencies": {
"ember": "~2.8.0",
"ember-cli-shims": "0.1.3",
"sjcl": "~1.0.6",
"bootstrap": "~3.3.5",
"bootstrap-datepicker": "~1.4.0",

View file

@ -1,5 +1,5 @@
/* jshint node: true */
/* jscs:disable requireEnhancedObjectLiterals */
/* eslint-env node */
'use strict';
module.exports = function(environment) {
const ENV = {

9
config/targets.js Normal file
View file

@ -0,0 +1,9 @@
/* eslint-env node */
module.exports = {
browsers: [
'ie 9',
'last 1 Chrome versions',
'last 1 Firefox versions',
'last 1 Safari versions'
]
};

View file

@ -1,22 +1,22 @@
/*jshint node:true*/
/* global require, module */
/* eslint-env node */
'use strict';
const EmberApp = require('ember-cli/lib/broccoli/ember-app');
module.exports = function() {
module.exports = function(defaults) {
const Funnel = require('broccoli-funnel');
const unwatchedTree = require('broccoli-unwatched-tree');
const trees = [];
const app = new EmberApp({
babel: {
optional: ['es6.spec.symbols'],
includePolyfill: true
},
let app = new EmberApp(defaults, {
'buildInfoOptions': {
'metaTemplate': 'version={SEMVER}'
},
'ember-bootstrap': {
importBootstrapCSS: false
},
'ember-cli-babel': {
includePolyfill: true
}
});

View file

@ -1,22 +1,18 @@
{
"name": "croodle",
"version": "0.5.4",
"private": true,
"license": "MIT",
"author": "",
"directories": {
"doc": "doc",
"test": "tests"
},
"repository": "https://github.com/jelhan/croodle",
"scripts": {
"build": "ember build",
"start": "ember server",
"test": "ember test"
},
"repository": "https://github.com/jelhan/croodle",
"engines": {
"node": ">= 0.10.0"
},
"author": "",
"license": "MIT",
"devDependencies": {
"body-parser": "^1.2.0",
"broccoli-asset-rev": "^2.4.5",
@ -25,58 +21,64 @@
"chart.js": "2.2.1",
"connect-restreamer": "^1.0.1",
"cors": "^2.5.3",
"ember-ajax": "^2.4.1",
"ember-ajax": "^3.0.0",
"ember-array-computed-macros": "martndemus/ember-array-computed-macros#3fde9023336d227aa6009060b40b4de77d8b1a9b",
"ember-array-helper": "^1.0.1",
"ember-bootstrap": "^0.11.3",
"ember-bootstrap-cp-validations": "^0.2.0",
"ember-browserify": "^1.1.11",
"ember-cli": "2.9.0-beta.1",
"ember-cli-acceptance-test-helpers": "^0.4.0",
"ember-cli-app-version": "^2.0.0",
"ember-cli-babel": "^5.1.7",
"ember-cli": "~2.14.1",
"ember-cli-acceptance-test-helpers": "^1.0.0",
"ember-cli-app-version": "^3.0.0",
"ember-cli-babel": "^6.3.0",
"ember-cli-bootstrap-datepicker": "^0.5.5",
"ember-cli-browser-navigation-button-test-helper": "^0.0.2",
"ember-cli-browser-navigation-button-test-helper": "^0.0.4",
"ember-cli-build-info": "^0.2.0",
"ember-cli-chart": "git://github.com/jelhan/ember-cli-chart.git#52ae694db579df94e0ef057d2cf7d6d96c61f78f",
"ember-cli-clipboard": "0.4.1",
"ember-cli-content-security-policy": "0.5.0",
"ember-cli-dependency-checker": "^1.3.0",
"ember-cli-eslint": "^3.0.0",
"ember-cli-flash": "^1.4.0",
"ember-cli-htmlbars": "^1.0.10",
"ember-cli-htmlbars-inline-precompile": "^0.3.3",
"ember-cli-htmlbars": "^2.0.1",
"ember-cli-htmlbars-inline-precompile": "^0.4.3",
"ember-cli-inject-live-reload": "^1.4.1",
"ember-cli-jshint": "^1.0.4",
"ember-cli-less": "^1.5.3",
"ember-cli-moment-shim": "3.3.3",
"ember-cli-page-object": "1.7.0",
"ember-cli-pretender": "^0.6.0",
"ember-cli-qunit": "^2.1.0",
"ember-cli-qunit": "^4.0.0",
"ember-cli-release": "^0.2.9",
"ember-cli-sauce": "^1.6.0",
"ember-cli-shims": "^1.1.0",
"ember-cli-sri": "^2.1.0",
"ember-cli-test-loader": "^1.1.0",
"ember-cli-uglify": "^1.2.0",
"ember-cp-validations": "^2.9.3",
"ember-data": "~2.8.0",
"ember-data-model-fragments": "2.3.2",
"ember-export-application-global": "^1.0.5",
"ember-i18n": "^4.3.2",
"ember-data": "~2.14.3",
"ember-data-model-fragments": "^2.14.0",
"ember-export-application-global": "^2.0.0",
"ember-i18n": "^5.0.2",
"ember-i18n-cp-validations": "^3.0.2",
"ember-load-initializers": "^0.5.1",
"ember-load-initializers": "^1.0.0",
"ember-math-helpers": "^2.0.2",
"ember-moment": "7.3.1",
"ember-native-dom-helpers": "^0.5.2",
"ember-object-at-helper": "0.1.0",
"ember-page-title": "^3.0.6",
"ember-radio-buttons": "^4.0.1",
"ember-resolver": "^2.0.3",
"ember-resolver": "^4.0.0",
"ember-simple-select": "novafloss/ember-simple-select#1b2d13c0a8d5844757fd88b64b12f61c6455b94e",
"ember-source": "~2.14.1",
"ember-suave": "^4.0.0",
"ember-transition-helper": "0.0.6",
"ember-truth-helpers": "^1.2.0",
"express": "^4.8.5",
"glob": "^7.0.5",
"loader.js": "^4.0.10",
"loader.js": "^4.2.3",
"node-phpcgi": "^0.3.5"
}
},
"engines": {
"node": "^4.5 || 6.* || >= 7.*"
},
"private": true
}

View file

@ -1,13 +1,12 @@
/*jshint node:true*/
/* eslint-env node */
module.exports = {
"framework": "qunit",
"test_page": "tests/index.html?hidepassed",
"disable_watching": true,
"launch_in_ci": [
"PhantomJS"
test_page: 'tests/index.html?hidepassed',
disable_watching: true,
launch_in_ci: [
'PhantomJS'
],
"launch_in_dev": [
"PhantomJS",
"Chrome"
launch_in_dev: [
'PhantomJS',
'Chrome'
]
};

20
tests/.eslintrc.js Normal file
View file

@ -0,0 +1,20 @@
module.exports = {
env: {
embertest: true
},
globals: {
// ember-cli-acceptance-test-helpers
hasComponent: false,
// i18n test helper
t: false,
// browser-navigation-buttons-test-helper
backButton: false,
forwardButton: false,
setupBrowserNavigationButtons: false,
// local test helpers
pollHasUser: false,
pollHasUsersCount: false,
pollParticipate: false,
switchTab: false
}
};

View file

@ -1,64 +0,0 @@
{
"predef": [
"expectComponent",
"clickComponent",
"expectElement",
"expectNoElement",
"document",
"window",
"location",
"setTimeout",
"$",
"-Promise",
"define",
"console",
"visit",
"exists",
"fillIn",
"click",
"keyEvent",
"triggerEvent",
"find",
"findWithAssert",
"wait",
"DS",
"andThen",
"currentURL",
"currentPath",
"currentRouteName",
"pollHasUser",
"pollHasUsersCount",
"pollParticipate",
"switchTab",
"t",
"backButton",
"forwardButton",
"setupBrowserNavigationButtons"
],
"node": false,
"browser": false,
"boss": true,
"curly": true,
"debug": false,
"devel": false,
"eqeqeq": true,
"evil": true,
"forin": false,
"immed": false,
"laxbreak": false,
"newcap": true,
"noarg": true,
"noempty": false,
"nonew": false,
"nomen": false,
"onevar": false,
"plusplus": false,
"regexp": false,
"undef": true,
"sub": true,
"strict": false,
"white": false,
"eqnull": true,
"esversion": 6,
"unused": true
}

View file

@ -1,4 +1,5 @@
import { test } from 'qunit';
import jQuery from 'jquery';
import moduleForAcceptance from 'croodle/tests/helpers/module-for-acceptance';
moduleForAcceptance('Acceptance | build info');
@ -7,10 +8,11 @@ test('version is included as html meta tag', function(assert) {
visit('/');
andThen(function() {
assert.ok($('head meta[name="build-info"]').length === 1, 'tag exists');
// 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(
$('head meta[name="build-info"]').attr('content').match(/^version=\d[\d\.]+\d(-(alpha|beta|rc)\d)?(\+[\da-z]{8})?$/) !== null,
'format '.concat($('head meta[name="build-info"]').attr('content'), ' is correct')
jQuery('head meta[name="build-info"]').attr('content').match(/^version=\d[\d\.]+\d(-(alpha|beta|rc)\d)?(\+[\da-z]{8})?$/) !== null,
'format '.concat(jQuery('head meta[name="build-info"]').attr('content'), ' is correct')
);
});
});

View file

@ -22,13 +22,13 @@ const randomString = function(length) {
};
module('Acceptance | create a poll', {
beforeEach() {
beforeEach(assert) {
window.localStorage.setItem('locale', 'en');
let lastCreatedPoll = {};
const pollId = randomString(10);
application = startApp();
application = startApp({ assert });
application.__container__.lookup('adapter:application').__proto__.namespace = '';
server = new Pretender();
@ -304,7 +304,7 @@ test('create a poll for answering a question', function(assert) {
[false, false, false, true],
'status bar has correct items disabled (options)'
);
expectComponent('create-options-text');
assert.hasComponent('create-options-text');
assert.ok(
pageCreateOptions.firstTextOption.inputHasFocus,
'first option input has autofocus'
@ -785,7 +785,7 @@ test('create a poll for answering a question with only one option', function(ass
andThen(function() {
assert.equal(currentPath(), 'create.options');
expectComponent('create-options-text');
assert.hasComponent('create-options-text');
assert.equal(
pageCreateOptions.textOptions().count,

View file

@ -1,4 +1,5 @@
import Ember from 'ember';
import jQuery from 'jquery';
import { module, test } from 'qunit';
import startApp from '../helpers/start-app';
import Pretender from 'pretender';
@ -11,10 +12,10 @@ const { run } = Ember;
let application, server;
module('Acceptance | participate in a poll', {
beforeEach() {
beforeEach(assert) {
window.localStorage.setItem('locale', 'en');
application = startApp();
application = startApp({ assert });
application.__container__.lookup('adapter:application').__proto__.namespace = '';
server = new Pretender();
@ -30,6 +31,7 @@ module('Acceptance | participate in a poll', {
test('participate in a default poll', function(assert) {
let id = 'test';
let encryptionKey = 'abcdefghijklmnopqrstuvwxyz0123456789';
let nextUserId = 1;
server.get(`/polls/${id}`, function() {
return serverGetPolls(
@ -40,7 +42,9 @@ test('participate in a default poll', function(assert) {
});
server.post('/users',
function(request) {
return serverPostUsers(request.requestBody, 1);
let userId = nextUserId;
nextUserId++;
return serverPostUsers(request.requestBody, userId);
}
);
@ -64,12 +68,13 @@ test('participate in a default poll', function(assert) {
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) => $(el).prop('checked')),
!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')]);
});

View file

@ -1,4 +1,5 @@
import Ember from 'ember';
import jQuery from 'jquery';
import { module, test } from 'qunit';
import startApp from 'croodle/tests/helpers/start-app';
import Pretender from 'pretender';
@ -11,10 +12,10 @@ const { run } = Ember;
let application, server;
module('Acceptance | view evaluation', {
beforeEach() {
beforeEach(assert) {
window.localStorage.setItem('locale', 'en');
application = startApp();
application = startApp({ assert });
application.__container__.lookup('adapter:application').__proto__.namespace = '';
server = new Pretender();
@ -237,17 +238,17 @@ test('evaluation is correct for MakeAPoll', function(assert) {
'has a table showing user selections'
);
assert.deepEqual(
find('.user-selections-table thead th').map((i, el) => $(el).text().trim()).get(),
find('.user-selections-table thead th').map((i, el) => jQuery(el).text().trim()).get(),
['', '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) => $(el).text().trim()).get(),
find('.user-selections-table tbody tr:nth-child(1) td').map((i, el) => jQuery(el).text().trim()).get(),
['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) => $(el).text().trim()).get(),
find('.user-selections-table tbody tr:nth-child(2) td').map((i, el) => jQuery(el).text().trim()).get(),
['Peter', 'No', 'Yes'],
'answers shown in table are correct for second user'
);

View file

@ -12,10 +12,10 @@ const { run } = Ember;
let application, server;
module('Acceptance | view poll', {
beforeEach() {
beforeEach(assert) {
window.localStorage.setItem('locale', 'en');
application = startApp();
application = startApp({ assert });
application.__container__.lookup('adapter:application').__proto__.namespace = '';
server = new Pretender();

27
tests/contact.js Normal file
View file

@ -0,0 +1,27 @@
import {
validateFormat,
validateLength
} from 'ember-changeset-validations/validators';
import validatePhone from 'pruefung-client/validators/phone';
export default {
email: validateFormat({
allowBlank: true,
type: 'email'
}),
firstName: validateLength({
allowNone: false,
min: 3
}),
fieldOfDuties: validateLength({
allowNone: false,
min: 3
}),
lastName: validateLength({
allowNone: false,
min: 3
}),
telephone: validatePhone({
allowBlank: true
})
};

View file

@ -3,12 +3,12 @@ import Ember from 'ember';
import startApp from '../helpers/start-app';
import destroyApp from '../helpers/destroy-app';
const { RSVP: { Promise } } = Ember;
const { RSVP: { resolve } } = Ember;
export default function(name, options = {}) {
module(name, {
beforeEach() {
this.application = startApp();
beforeEach(assert) {
this.application = startApp({ assert });
if (options.beforeEach) {
return options.beforeEach.apply(this, arguments);
@ -17,7 +17,7 @@ export default function(name, options = {}) {
afterEach() {
let afterEach = options.afterEach && options.afterEach.apply(this, arguments);
return Promise.resolve(afterEach).then(() => destroyApp(this.application));
return resolve(afterEach).then(() => destroyApp(this.application));
}
});
}

View file

@ -1,26 +1,25 @@
import Ember from 'ember';
import registerAcceptanceTestHelpers from './201-created/register-acceptance-test-helpers';
import Application from '../../app';
import config from '../../config/environment';
import './poll-has-users';
import './poll-participate';
import './switch-tab';
import './t';
import './browser-navigation-buttons';
registerAcceptanceTestHelpers();
import registerAcceptanceTestHelpers from './201-created/register-acceptance-test-helpers';
import registerBrowserNavigationButtonTestHelpers from './browser-navigation-buttons';
export default function startApp(attrs) {
let application;
let attributes = Ember.merge({}, config.APP);
attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;
// use defaults, but you can override
let attributes = Ember.assign({}, config.APP, attrs);
Ember.run(() => {
application = Application.create(attributes);
return Ember.run(() => {
let application = Application.create(attributes);
application.setupForTesting();
application.injectTestHelpers();
});
return application;
registerAcceptanceTestHelpers(attrs.assert || window.QUnit.assert);
registerBrowserNavigationButtonTestHelpers();
application.injectTestHelpers();
return application;
});
}

View file

@ -7,8 +7,8 @@
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
{{content-for 'head'}}
{{content-for 'test-head'}}
{{content-for "head"}}
{{content-for "test-head"}}
<link rel="stylesheet" href="{{rootURL}}assets/vendor.css">
<link rel="stylesheet" href="{{rootURL}}assets/croodle.css">
@ -18,8 +18,8 @@
{{content-for "test-head-footer"}}
</head>
<body>
{{content-for 'body'}}
{{content-for 'test-body'}}
{{content-for "body"}}
{{content-for "test-body"}}
<script src="/testem.js" integrity=""></script>
<script src="{{rootURL}}assets/vendor.js"></script>
@ -27,7 +27,7 @@
<script src="{{rootURL}}assets/croodle.js"></script>
<script src="{{rootURL}}assets/tests.js"></script>
{{content-for 'body-footer'}}
{{content-for 'test-body-footer'}}
{{content-for "body-footer"}}
{{content-for "test-body-footer"}}
</body>
</html>

View file

@ -1,5 +1,6 @@
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import jQuery from 'jquery';
import Ember from 'ember';
import moment from 'moment';
@ -260,7 +261,7 @@ test('adopt times of first day - more times on first day than on others', functi
this.$('button.adopt-times-of-first-day').click();
});
assert.deepEqual(
this.$('.days .form-group input').map((i, el) => $(el).val()).toArray(),
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'
);
@ -292,7 +293,7 @@ test('adopt times of first day - excess times on other days got deleted', functi
'one excess time input got deleted'
);
assert.deepEqual(
this.$('.days .form-group input').map((i, el) => $(el).val()).toArray(),
this.$('.days .form-group input').map((i, el) => jQuery(el).val()).toArray(),
['10:00', '10:00'],
'additional time on secondary day got deleted'
);

View file

@ -1,6 +1,7 @@
import { moduleForComponent, test } from 'ember-qunit';
import { blur, fillIn, findAll, focus } from 'ember-native-dom-helpers';
import hbs from 'htmlbars-inline-precompile';
import expectComponent from 'croodle/tests/helpers/201-created/raw/expect-component';
import hasComponent from 'croodle/tests/helpers/201-created/raw/has-component';
import Ember from 'ember';
moduleForComponent('create-options', 'Integration | Component | create options', {
@ -18,10 +19,10 @@ test('renders component', function(assert) {
this.render(hbs`{{create-options options=options isDateTime=isDateTime isFindADate=isFindADate isMakeAPoll=isMakeAPoll}}`);
assert.ok(
expectComponent(this.container, 'create-options-dates', 1).ok
hasComponent(this.container, assert, 'create-options-dates').ok
);
assert.notOk(
expectComponent(this.container, 'create-options-text', 0).ok
hasComponent(this.container, assert, 'create-options-text').ok
);
this.set('isDateTime', false);
@ -29,14 +30,14 @@ test('renders component', function(assert) {
this.set('isMakeAPoll', true);
assert.notOk(
expectComponent(this.container, 'create-options-dates', 1).ok
hasComponent(this.container, assert, 'create-options-dates').ok
);
assert.ok(
expectComponent(this.container, 'create-options-text', 0).ok
hasComponent(this.container, assert, 'create-options-text').ok
);
});
test('shows validation errors if options are not unique (makeAPoll)', function(assert) {
test('shows validation errors if options are not unique (makeAPoll)', async function(assert) {
assert.expect(5);
this.set('isDateTime', false);
@ -64,11 +65,10 @@ test('shows validation errors if options are not unique (makeAPoll)', function(a
'assumptions are correct'
);
Ember.run(() => {
// there should be two inputs and both are changed to 'foo'
this.$('input').val('foo').trigger('change').trigger('focusout');
});
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'
@ -79,10 +79,8 @@ test('shows validation errors if options are not unique (makeAPoll)', function(a
'validation error is shown'
);
Ember.run(() => {
this.$('input').eq(0).val('bar').trigger('change');
});
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'
@ -94,7 +92,7 @@ test('shows validation errors if options are not unique (makeAPoll)', function(a
);
});
test('shows validation errors if option is empty (makeAPoll)', function(assert) {
test('shows validation errors if option is empty (makeAPoll)', async function(assert) {
this.set('isDateTime', false);
this.set('isFindADate', false);
this.set('isMakeAPoll', true);
@ -119,27 +117,71 @@ test('shows validation errors if option is empty (makeAPoll)', function(assert)
this.$('.form-group.has-error').length, 0
);
Ember.run(() => {
this.$('input').trigger('focusout');
});
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
);
Ember.run(() => {
this.$('input').eq(0).val('foo').trigger('change');
});
await fillIn(findAll('input')[0], 'foo');
await blur(findAll('input')[0]);
assert.equal(
this.$('.form-group.has-error').length, 1
);
Ember.run(() => {
this.$('input').eq(1).val('bar').trigger('change');
});
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;
Ember.run(() => {
poll = this.store.createRecord('poll', {
isFindADate: this.get('isFindADate'),
isDateTime: this.get('isDateTime'),
isMakeAPoll: this.get('isMakeAPoll')
});
});
this.set('options', poll.get('options'));
this.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'
);
});

View file

@ -1,5 +1,6 @@
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import jQuery from 'jquery';
import Ember from 'ember';
moduleForComponent('create-options-text', 'Integration | Component | create options text', {
@ -31,7 +32,7 @@ test('generates input fields according options', function(assert) {
);
assert.deepEqual(
this.$('input').map(function() {
return $(this).val();
return jQuery(this).val();
}).get(),
['foo', 'bar', 'baz'],
'input fields have correct values and order'
@ -120,7 +121,7 @@ test('allows to add another option', function(assert) {
);
assert.deepEqual(
this.$('input').map(function() {
return $(this).val();
return jQuery(this).val();
}).get(),
['foo', '', 'bar'],
'it is added at correct position'
@ -164,7 +165,7 @@ test('allows to delete an option', function(assert) {
);
assert.deepEqual(
this.$('input').map(function() {
return $(this).val();
return jQuery(this).val();
}).get(),
['foo', 'baz'],
'correct input field is deleted'

View file

@ -13,10 +13,10 @@ import pagePollParticipation from 'croodle/tests/pages/poll/participation';
let application;
module('Integration', {
beforeEach() {
beforeEach(assert) {
window.localStorage.setItem('locale', 'en');
application = startApp();
application = startApp({ assert });
moment.locale(
application.__container__.lookup('service:i18n').get('locale')
);

View file

@ -8,10 +8,10 @@ import pagePollParticipation from 'croodle/tests/pages/poll/participation';
let application;
module('Integration | legacy support', {
beforeEach() {
beforeEach(assert) {
window.localStorage.setItem('locale', 'en');
application = startApp();
application = startApp({ assert });
moment.locale(
application.__container__.lookup('service:i18n').get('locale')
);
@ -30,6 +30,7 @@ test('show a default poll created with v0.3.0', function(assert) {
visit(`/poll/${id}?encryptionKey=${encryptionKey}`);
andThen(function() {
assert.equal(currentPath(), 'poll.participation');
assert.equal(
pagePollParticipation.title,
'default poll created with v0.3.0'

View file

@ -1,4 +1,5 @@
import { findElement } from 'ember-cli-page-object';
import jQuery from 'jquery';
/*
* In Webkit `.is(':focus')` is `false` if document hasn't focus
@ -14,7 +15,7 @@ export function hasFocus(selector, options = {}) {
get() {
let [ el ] = findElement(this, selector, options);
let document = el.ownerDocument;
return $(el).is(':focus') || el === document.activeElement;
return jQuery(el).is(':focus') || el === document.activeElement;
}
};
}

View file

@ -1,8 +1,8 @@
import resolver from './helpers/resolver';
import './helpers/flash-message';
import {
setResolver
} from 'ember-qunit';
import { start } from 'ember-cli-qunit';
setResolver(resolver);
start();

View file

@ -5,7 +5,7 @@ import moment from 'moment';
const { Object: EmberObject, run } = Ember;
moduleForComponent('create-options-dates', 'Unit | Component | create options dates', {
needs: ['model:option'],
needs: ['config:environment', 'model:option', 'service:i18n'],
unit: true,
beforeEach() {
this.inject.service('store');
@ -83,46 +83,46 @@ test('options having times get mapped to dates as optionsBootstrapDatepicker (us
test('options get set correctly by optionsBootstrapDatepicker (used by ember-cli-bootstrap-datepicker)', function(assert) {
let controller = this.subject();
run.next(() => {
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(
Ember.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'
);
});
assert.ok(
Ember.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) {

View file

@ -5,7 +5,9 @@ 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() {

View file

@ -1,8 +1,12 @@
import { moduleFor, test } from 'ember-qunit';
moduleFor('controller:poll/participation', 'Unit | Controller | poll/participation', {
// Specify the other units that are required for this test.
// needs: ['controller:foo']
needs: [
'config:environment',
'controller:poll',
'service:encryption', 'service:i18n',
'validator:collection', 'validator:presence', 'validator:unique'
]
});
// Replace this with your real tests.

3042
yarn.lock

File diff suppressed because it is too large Load diff