mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
Wizard: Step 1
This commit is contained in:
@@ -98,7 +98,9 @@ function checkExtras(origScope, sep, extras) {
|
||||
for (var i=0; i<extras.length; i++) {
|
||||
var messages = extras[i];
|
||||
scope = origScope.split(sep);
|
||||
scope.shift();
|
||||
if (scope[0] === 'js') {
|
||||
scope.shift();
|
||||
}
|
||||
|
||||
while (messages && scope.length > 0) {
|
||||
currentScope = scope.shift();
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
//= require_tree ./ember-addons/utils
|
||||
//= require ./ember-addons/decorator-alias
|
||||
//= require ./ember-addons/macro-alias
|
||||
//= require ./ember-addons/ember-computed-decorators
|
||||
//= require discourse/lib/raw-handlebars
|
||||
//= require discourse/lib/helpers
|
||||
//= require wizard/resolver
|
||||
//= require wizard/router
|
||||
//= require wizard/wizard
|
||||
//= require_tree ./wizard/templates
|
||||
//= require_tree ./wizard/components
|
||||
//= require_tree ./wizard/models
|
||||
//= require_tree ./wizard/routes
|
||||
//= require_tree ./wizard/controllers
|
||||
//= require_tree ./wizard/lib
|
||||
//= require_tree ./wizard/mixins
|
||||
//= require_tree ./wizard/helpers
|
||||
//= require_tree ./wizard/initializers
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNameBindings: [':wizard-field', ':text-field', 'field.invalid'],
|
||||
|
||||
@computed('field.id')
|
||||
inputClassName: id => `field-${Ember.String.dasherize(id)}`
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNameBindings: [':wizard-step-form', 'customStepClass'],
|
||||
|
||||
@computed('step.id')
|
||||
customStepClass: stepId => `wizard-step-${stepId}`,
|
||||
});
|
||||
85
app/assets/javascripts/wizard/components/wizard-step.js.es6
Normal file
85
app/assets/javascripts/wizard/components/wizard-step.js.es6
Normal file
@@ -0,0 +1,85 @@
|
||||
import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: ['wizard-step'],
|
||||
saving: null,
|
||||
|
||||
didInsertElement() {
|
||||
this._super();
|
||||
this.autoFocus();
|
||||
},
|
||||
|
||||
@computed('step.displayIndex', 'wizard.totalSteps')
|
||||
showNextButton: (current, total) => current < total,
|
||||
|
||||
@computed('step.index')
|
||||
showBackButton: index => index > 0,
|
||||
|
||||
@observes('step.id')
|
||||
_stepChanged() {
|
||||
this.set('saving', false);
|
||||
this.autoFocus();
|
||||
},
|
||||
|
||||
keyPress(key) {
|
||||
if (key.keyCode === 13) {
|
||||
this.send('nextStep');
|
||||
}
|
||||
},
|
||||
|
||||
@computed('step.displayIndex', 'wizard.totalSteps')
|
||||
barStyle(displayIndex, totalSteps) {
|
||||
const ratio = parseFloat(displayIndex) / parseFloat(totalSteps) * 100;
|
||||
return Ember.String.htmlSafe(`width: ${ratio}%`);
|
||||
},
|
||||
|
||||
autoFocus() {
|
||||
Ember.run.scheduleOnce('afterRender', () => {
|
||||
const $invalid = $('.wizard-field.invalid:eq(0) input');
|
||||
|
||||
if ($invalid.length) {
|
||||
return $invalid.focus();
|
||||
}
|
||||
|
||||
$('input:eq(0)').focus();
|
||||
});
|
||||
},
|
||||
|
||||
saveStep() {
|
||||
const step = this.get('step');
|
||||
step.save()
|
||||
.then(() => this.sendAction('goNext'))
|
||||
.catch(response => {
|
||||
const errors = response.responseJSON.errors;
|
||||
if (errors && errors.length) {
|
||||
errors.forEach(err => {
|
||||
step.fieldError(err.field, err.description);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
actions: {
|
||||
backStep() {
|
||||
if (this.get('saving')) { return; }
|
||||
this.sendAction('goBack');
|
||||
},
|
||||
|
||||
nextStep() {
|
||||
if (this.get('saving')) { return; }
|
||||
|
||||
const step = this.get('step');
|
||||
step.checkFields();
|
||||
|
||||
if (step.get('valid')) {
|
||||
this.set('saving', true);
|
||||
step.save()
|
||||
.then(() => this.sendAction('goNext'))
|
||||
.catch(() => null) // we can swallow because the form is already marked as invalid
|
||||
.finally(() => this.set('saving', false));
|
||||
} else {
|
||||
this.autoFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,3 +1,13 @@
|
||||
export default Ember.Controller.extend({
|
||||
wizard: null,
|
||||
step: null,
|
||||
|
||||
actions: {
|
||||
goNext() {
|
||||
this.transitionToRoute('step', this.get('step.next'));
|
||||
},
|
||||
goBack() {
|
||||
this.transitionToRoute('step', this.get('step.previous'));
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
3
app/assets/javascripts/wizard/helpers/i18n.js.es6
Normal file
3
app/assets/javascripts/wizard/helpers/i18n.js.es6
Normal file
@@ -0,0 +1,3 @@
|
||||
import { registerUnbound } from 'discourse/lib/helpers';
|
||||
|
||||
registerUnbound('i18n', (key, params) => I18n.t(key, params));
|
||||
@@ -0,0 +1,11 @@
|
||||
export default {
|
||||
name: 'load-helpers',
|
||||
|
||||
initialize() {
|
||||
Object.keys(requirejs.entries).forEach(entry => {
|
||||
if ((/\/helpers\//).test(entry)) {
|
||||
require(entry, null, null, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
18
app/assets/javascripts/wizard/lib/ajax.js.es6
Normal file
18
app/assets/javascripts/wizard/lib/ajax.js.es6
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
let token;
|
||||
|
||||
export function ajax(args) {
|
||||
|
||||
if (!token) {
|
||||
token = $('meta[name="csrf-token"]').attr('content');
|
||||
}
|
||||
|
||||
return new Ember.RSVP.Promise((resolve, reject) => {
|
||||
args.headers = {
|
||||
'X-CSRF-Token': token
|
||||
};
|
||||
args.success = data => Ember.run(null, resolve, data);
|
||||
args.error = xhr => Ember.run(null, reject, xhr);
|
||||
Ember.$.ajax(args);
|
||||
});
|
||||
}
|
||||
30
app/assets/javascripts/wizard/mixins/valid-state.js.es6
Normal file
30
app/assets/javascripts/wizard/mixins/valid-state.js.es6
Normal file
@@ -0,0 +1,30 @@
|
||||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
export const States = {
|
||||
UNCHECKED: 0,
|
||||
INVALID: 1,
|
||||
VALID: 2
|
||||
};
|
||||
|
||||
export default {
|
||||
_validState: null,
|
||||
|
||||
init() {
|
||||
this._super();
|
||||
this.set('_validState', States.UNCHECKED);
|
||||
},
|
||||
|
||||
@computed('_validState')
|
||||
valid: state => state === States.VALID,
|
||||
|
||||
@computed('_validState')
|
||||
invalid: state => state === States.INVALID,
|
||||
|
||||
@computed('_validState')
|
||||
unchecked: state => state === States.UNCHECKED,
|
||||
|
||||
setValid(valid) {
|
||||
this.set('_validState', valid ? States.VALID : States.INVALID);
|
||||
}
|
||||
|
||||
};
|
||||
41
app/assets/javascripts/wizard/models/step.js.es6
Normal file
41
app/assets/javascripts/wizard/models/step.js.es6
Normal file
@@ -0,0 +1,41 @@
|
||||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
import ValidState from 'wizard/mixins/valid-state';
|
||||
import { ajax } from 'wizard/lib/ajax';
|
||||
|
||||
export default Ember.Object.extend(ValidState, {
|
||||
id: null,
|
||||
|
||||
@computed('index')
|
||||
displayIndex: index => index + 1,
|
||||
|
||||
checkFields() {
|
||||
let allValid = true;
|
||||
this.get('fields').forEach(field => {
|
||||
field.check();
|
||||
allValid = allValid && field.get('valid');
|
||||
});
|
||||
|
||||
this.setValid(allValid);
|
||||
},
|
||||
|
||||
fieldError(id, description) {
|
||||
const field = this.get('fields').findProperty('id', id);
|
||||
if (field) {
|
||||
field.setValid(false, description);
|
||||
}
|
||||
},
|
||||
|
||||
save() {
|
||||
const fields = {};
|
||||
this.get('fields').forEach(f => fields[f.id] = f.value);
|
||||
|
||||
return ajax({
|
||||
url: `/wizard/steps/${this.get('id')}`,
|
||||
type: 'PUT',
|
||||
data: { fields }
|
||||
}).catch(response => {
|
||||
response.responseJSON.errors.forEach(err => this.fieldError(err.field, err.description));
|
||||
throw response;
|
||||
});
|
||||
}
|
||||
});
|
||||
17
app/assets/javascripts/wizard/models/wizard-field.js.es6
Normal file
17
app/assets/javascripts/wizard/models/wizard-field.js.es6
Normal file
@@ -0,0 +1,17 @@
|
||||
import ValidState from 'wizard/mixins/valid-state';
|
||||
|
||||
export default Ember.Object.extend(ValidState, {
|
||||
id: null,
|
||||
type: null,
|
||||
value: null,
|
||||
required: null,
|
||||
|
||||
check() {
|
||||
if (!this.get('required')) {
|
||||
return this.setValid(true);
|
||||
}
|
||||
|
||||
const val = this.get('value');
|
||||
this.setValid(val && val.length > 0);
|
||||
}
|
||||
});
|
||||
23
app/assets/javascripts/wizard/models/wizard.js.es6
Normal file
23
app/assets/javascripts/wizard/models/wizard.js.es6
Normal file
@@ -0,0 +1,23 @@
|
||||
import Step from 'wizard/models/step';
|
||||
import WizardField from 'wizard/models/wizard-field';
|
||||
import { ajax } from 'wizard/lib/ajax';
|
||||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
const Wizard = Ember.Object.extend({
|
||||
@computed('steps.length')
|
||||
totalSteps: length => length
|
||||
});
|
||||
|
||||
export function findWizard() {
|
||||
return ajax({ url: '/wizard.json' }).then(response => {
|
||||
const wizard = response.wizard;
|
||||
wizard.steps = wizard.steps.map(step => {
|
||||
const stepObj = Step.create(step);
|
||||
stepObj.fields = stepObj.fields.map(f => WizardField.create(f));
|
||||
return stepObj;
|
||||
});
|
||||
|
||||
return Wizard.create(wizard);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,15 +8,15 @@ function resolveType(parsedName) {
|
||||
}
|
||||
}
|
||||
|
||||
function customResolve(parsedName) {
|
||||
return resolveType(parsedName) || this._super(parsedName);
|
||||
}
|
||||
|
||||
export default Ember.DefaultResolver.extend({
|
||||
|
||||
resolveRoute(parsedName) {
|
||||
return resolveType(parsedName) || this._super(parsedName);
|
||||
},
|
||||
|
||||
resolveController(parsedName) {
|
||||
return resolveType(parsedName) || this._super(parsedName);
|
||||
},
|
||||
resolveRoute: customResolve,
|
||||
resolveController: customResolve,
|
||||
resolveComponent: customResolve,
|
||||
|
||||
resolveTemplate(parsedName) {
|
||||
const templates = Ember.TEMPLATES;
|
||||
|
||||
7
app/assets/javascripts/wizard/routes/application.js.es6
Normal file
7
app/assets/javascripts/wizard/routes/application.js.es6
Normal file
@@ -0,0 +1,7 @@
|
||||
import { findWizard } from 'wizard/models/wizard';
|
||||
|
||||
export default Ember.Route.extend({
|
||||
model() {
|
||||
return findWizard();
|
||||
}
|
||||
});
|
||||
@@ -1,5 +1,6 @@
|
||||
export default Ember.Route.extend({
|
||||
beforeModel() {
|
||||
this.replaceWith('step', 'welcome');
|
||||
const appModel = this.modelFor('application');
|
||||
this.replaceWith('step', appModel.start);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
export default Ember.Route.extend({
|
||||
model(params) {
|
||||
return {
|
||||
id: params.step_id,
|
||||
title: "You're a wizard harry!"
|
||||
};
|
||||
const allSteps = this.modelFor('application').steps;
|
||||
return allSteps.findProperty('id', params.step_id);
|
||||
},
|
||||
|
||||
setupController(controller, model) {
|
||||
controller.set('step', model);
|
||||
setupController(controller, step) {
|
||||
controller.setProperties({
|
||||
step, wizard: this.modelFor('application')
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<div class='wizard-column'>
|
||||
<div class='wizard-column-contents'>
|
||||
Discourse!
|
||||
|
||||
{{outlet}}
|
||||
</div>
|
||||
<div class='wizard-footer'>
|
||||
<img src="/images/wizard/discourse.png" class="logo">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<label>
|
||||
<span class='label-value'>{{field.label}}</span>
|
||||
|
||||
<div class='input-area'>
|
||||
{{input value=field.value class=inputClassName placeholder=field.placeholder}}
|
||||
</div>
|
||||
</label>
|
||||
@@ -0,0 +1,37 @@
|
||||
{{#if step.title}}
|
||||
<h1 class='wizard-step-title'>{{step.title}}</h1>
|
||||
{{/if}}
|
||||
|
||||
{{#if step.description}}
|
||||
<p class='wizard-step-description'>{{step.description}}</p>
|
||||
{{/if}}
|
||||
|
||||
{{#wizard-step-form step=step}}
|
||||
{{#each step.fields as |field|}}
|
||||
{{wizard-field field=field}}
|
||||
{{/each}}
|
||||
{{/wizard-step-form}}
|
||||
|
||||
<div class='wizard-step-footer'>
|
||||
<div class='wizard-progress'>
|
||||
<div class='text'>{{i18n "wizard.step" current=step.displayIndex total=wizard.totalSteps}}</div>
|
||||
<div class='bar-container'>
|
||||
<div class='bar-contents' style={{barStyle}}></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if showBackButton}}
|
||||
<button class='wizard-btn back' {{action "backStep"}} disabled={{saving}}>
|
||||
<i class='fa fa-chevron-left'></i>
|
||||
{{i18n "wizard.back"}}
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
{{#if showNextButton}}
|
||||
<button class='wizard-btn next' {{action "nextStep"}} disabled={{saving}}>
|
||||
{{i18n "wizard.next"}}
|
||||
<i class='fa fa-chevron-right'></i>
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
</div>
|
||||
@@ -1,3 +1 @@
|
||||
<div class='wizard-step'>
|
||||
{{step.title}}
|
||||
</div>
|
||||
{{wizard-step step=step wizard=wizard goNext="goNext" goBack="goBack"}}
|
||||
|
||||
@@ -1,10 +1,54 @@
|
||||
|
||||
module("Acceptance: wizard");
|
||||
|
||||
test("Wizard loads", assert => {
|
||||
test("Wizard starts", assert => {
|
||||
visit("/");
|
||||
andThen(() => {
|
||||
assert.ok(exists('.wizard-column-contents'));
|
||||
assert.equal(currentPath(), 'steps');
|
||||
assert.equal(currentPath(), 'step');
|
||||
});
|
||||
});
|
||||
|
||||
test("Forum Name Step", assert => {
|
||||
visit("/step/hello-world");
|
||||
andThen(() => {
|
||||
assert.ok(exists('.wizard-step'));
|
||||
assert.ok(exists('.wizard-step-hello-world'), 'it adds a class for the step id');
|
||||
|
||||
assert.ok(exists('.wizard-progress'));
|
||||
assert.ok(exists('.wizard-step-title'));
|
||||
assert.ok(exists('.wizard-step-description'));
|
||||
assert.ok(!exists('.invalid .field-full-name'), "don't show it as invalid until the user does something");
|
||||
assert.ok(!exists('.wizard-btn.back'));
|
||||
});
|
||||
|
||||
// invalid data
|
||||
click('.wizard-btn.next');
|
||||
andThen(() => {
|
||||
assert.ok(exists('.invalid .field-full-name'));
|
||||
});
|
||||
|
||||
// server validation fail
|
||||
fillIn('input.field-full-name', "Server Fail");
|
||||
click('.wizard-btn.next');
|
||||
andThen(() => {
|
||||
assert.ok(exists('.invalid .field-full-name'));
|
||||
});
|
||||
|
||||
// server validation ok
|
||||
fillIn('input.field-full-name', "Evil Trout");
|
||||
click('.wizard-btn.next');
|
||||
andThen(() => {
|
||||
assert.ok(!exists('.wizard-step-title'));
|
||||
assert.ok(!exists('.wizard-step-description'));
|
||||
assert.ok(exists('input.field-email'), "went to the next step");
|
||||
assert.ok(!exists('.wizard-btn.next'));
|
||||
assert.ok(exists('.wizard-btn.back'), 'shows the back button');
|
||||
});
|
||||
|
||||
click('.wizard-btn.back');
|
||||
andThen(() => {
|
||||
assert.ok(exists('.wizard-step-title'));
|
||||
assert.ok(exists('.wizard-btn.next'));
|
||||
assert.ok(!exists('.wizard-prev'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import WizardField from 'wizard/models/wizard-field';
|
||||
|
||||
module("model:wizard-field");
|
||||
|
||||
test('basic state', assert => {
|
||||
const w = WizardField.create({ type: 'text' });
|
||||
assert.ok(w.get('unchecked'));
|
||||
assert.ok(!w.get('valid'));
|
||||
assert.ok(!w.get('invalid'));
|
||||
});
|
||||
|
||||
test('text - required - validation', assert => {
|
||||
const w = WizardField.create({ type: 'text', required: true });
|
||||
assert.ok(w.get('unchecked'));
|
||||
|
||||
w.check();
|
||||
assert.ok(!w.get('unchecked'));
|
||||
assert.ok(!w.get('valid'));
|
||||
assert.ok(w.get('invalid'));
|
||||
|
||||
w.set('value', 'a value');
|
||||
w.check();
|
||||
assert.ok(!w.get('unchecked'));
|
||||
assert.ok(w.get('valid'));
|
||||
assert.ok(!w.get('invalid'));
|
||||
});
|
||||
|
||||
test('text - optional - validation', assert => {
|
||||
const w = WizardField.create({ type: 'text' });
|
||||
assert.ok(w.get('unchecked'));
|
||||
|
||||
w.check();
|
||||
assert.ok(w.get('valid'));
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
/*global document, sinon, QUnit, Logster */
|
||||
/*global document, sinon, Logster, QUnit */
|
||||
|
||||
//= require env
|
||||
//= require jquery.debug
|
||||
@@ -8,9 +8,16 @@
|
||||
//= require ember.debug
|
||||
//= require ember-template-compiler
|
||||
//= require ember-qunit
|
||||
//= require ember-shim
|
||||
//= require wizard-application
|
||||
//= require helpers/assertions
|
||||
//= require_tree ./acceptance
|
||||
//= require_tree ./models
|
||||
//= require locales/en
|
||||
//= require fake_xml_http_request
|
||||
//= require route-recognizer
|
||||
//= require pretender
|
||||
//= require ./wizard-pretender
|
||||
|
||||
// Trick JSHint into allow document.write
|
||||
var d = document;
|
||||
@@ -23,15 +30,23 @@ if (window.Logster) {
|
||||
window.Logster = { enabled: false };
|
||||
}
|
||||
|
||||
var createPretendServer = require('wizard/test/wizard-pretender', null, null, false).default;
|
||||
|
||||
var server;
|
||||
QUnit.testStart(function() {
|
||||
server = createPretendServer();
|
||||
});
|
||||
|
||||
QUnit.testDone(function() {
|
||||
server.shutdown();
|
||||
});
|
||||
|
||||
var wizard = require('wizard/wizard').default.create({
|
||||
rootElement: '#ember-testing'
|
||||
});
|
||||
wizard.setupForTesting();
|
||||
wizard.injectTestHelpers();
|
||||
|
||||
QUnit.testDone(function() {
|
||||
wizard.reset();
|
||||
});
|
||||
wizard.start();
|
||||
|
||||
Object.keys(requirejs.entries).forEach(function(entry) {
|
||||
if ((/\-test/).test(entry)) {
|
||||
|
||||
83
app/assets/javascripts/wizard/test/wizard-pretender.js.es6
Normal file
83
app/assets/javascripts/wizard/test/wizard-pretender.js.es6
Normal file
@@ -0,0 +1,83 @@
|
||||
// TODO: This file has some copied and pasted functions from `create-pretender` - would be good
|
||||
// to centralize that code at some point.
|
||||
|
||||
function parsePostData(query) {
|
||||
const result = {};
|
||||
query.split("&").forEach(function(part) {
|
||||
const item = part.split("=");
|
||||
const firstSeg = decodeURIComponent(item[0]);
|
||||
const m = /^([^\[]+)\[([^\]]+)\]/.exec(firstSeg);
|
||||
|
||||
const val = decodeURIComponent(item[1]).replace(/\+/g, ' ');
|
||||
if (m) {
|
||||
result[m[1]] = result[m[1]] || {};
|
||||
result[m[1]][m[2]] = val;
|
||||
} else {
|
||||
result[firstSeg] = val;
|
||||
}
|
||||
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function response(code, obj) {
|
||||
if (typeof code === "object") {
|
||||
obj = code;
|
||||
code = 200;
|
||||
}
|
||||
return [code, {"Content-Type": "application/json"}, obj];
|
||||
}
|
||||
|
||||
export default function() {
|
||||
const server = new Pretender(function() {
|
||||
|
||||
this.get('/wizard.json', () => {
|
||||
return response(200, {
|
||||
wizard: {
|
||||
start: 'hello-world',
|
||||
steps: [{
|
||||
id: 'hello-world',
|
||||
title: 'hello there',
|
||||
index: 0,
|
||||
description: 'hello!',
|
||||
fields: [{ id: 'full_name', type: 'text', required: true }],
|
||||
next: 'second-step'
|
||||
},
|
||||
{
|
||||
id: 'second-step',
|
||||
index: 1,
|
||||
fields: [{ id: 'email', type: 'text', required: true }],
|
||||
previous: 'hello-world'
|
||||
}]
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.put('/wizard/steps/:id', request => {
|
||||
const body = parsePostData(request.requestBody);
|
||||
|
||||
if (body.fields.full_name === "Server Fail") {
|
||||
return response(422, {
|
||||
errors: [{ field: "full_name", description: "Invalid name" }]
|
||||
});
|
||||
} else {
|
||||
return response(200, { success: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
server.prepareBody = function(body){
|
||||
if (body && typeof body === "object") {
|
||||
return JSON.stringify(body);
|
||||
}
|
||||
return body;
|
||||
};
|
||||
|
||||
server.unhandledRequest = function(verb, path) {
|
||||
const error = 'Unhandled request in test environment: ' + path + ' (' + verb + ')';
|
||||
window.console.error(error);
|
||||
throw error;
|
||||
};
|
||||
|
||||
return server;
|
||||
}
|
||||
@@ -4,5 +4,15 @@ import Router from 'wizard/router';
|
||||
export default Ember.Application.extend({
|
||||
rootElement: '#wizard-main',
|
||||
Resolver,
|
||||
Router
|
||||
Router,
|
||||
|
||||
start() {
|
||||
Object.keys(requirejs._eak_seen).forEach(key => {
|
||||
if (/\/initializers\//.test(key)) {
|
||||
const module = require(key, null, null, true);
|
||||
if (!module) { throw new Error(key + ' must export an initializer.'); }
|
||||
this.instanceInitializer(module.default);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user