Set up ember-cli-mirage and update existing acceptance tests

refs #6039
- adds ember-cli-mirage dependency
- sets up mirage to match our API endpoints and responses
- adds fixture data for settings that are always present for all blogs
- converts existing acceptance tests to use mirage
This commit is contained in:
Kevin Ansfield 2015-10-13 14:52:41 +01:00
parent 5f68b5477a
commit d98ad41008
15 changed files with 496 additions and 283 deletions

View File

@ -1,5 +1,6 @@
{
"predef": [
"server",
"document",
"window",
"-Promise",

147
app/mirage/config.js Normal file
View File

@ -0,0 +1,147 @@
import Ember from 'ember';
const {isBlank} = Ember;
function paginatedResponse(modelName, allModels, request) {
const page = +request.queryParams.page || 1;
let limit = request.queryParams.limit || 15;
let pages, models, next, prev;
if (limit === 'all') {
models = allModels;
pages = 1;
} else {
limit = +limit;
let start = (page - 1) * limit,
end = start + limit;
models = allModels.slice(start, end);
pages = Math.ceil(allModels.length / limit);
if (start > 0) {
prev = page - 1;
}
if (end < allModels.length) {
next = page + 1;
}
}
return {
meta: {
pagination: {
page: page,
limit: limit,
pages: pages,
total: allModels.length,
next: next || null,
prev: prev || null
}
},
[modelName]: models
};
}
export default function () {
// this.urlPrefix = ''; // make this `http://localhost:8080`, for example, if your API is on a different server
this.namespace = 'ghost/api/v0.1'; // make this `api`, for example, if your API is namespaced
// this.timing = 400; // delay for each request, automatically set to 0 during testing
/* Notifications -------------------------------------------------------- */
this.get('/notifications/', 'notifications');
/* Settings ------------------------------------------------------------- */
this.get('/settings/', function (db, request) {
const filters = request.queryParams.type.split(','),
settings = [];
filters.forEach(filter => {
settings.pushObjects(db.settings.where({type: filter}));
});
return {
meta: {
filters: {
type: request.queryParams.type
}
},
settings: settings
};
});
this.put('/settings/', function (db, request) {
const newSettings = JSON.parse(request.requestBody);
db.settings.remove();
db.settings.insert(newSettings);
return {
meta: {},
settings: db.settings
};
});
/* Tags ----------------------------------------------------------------- */
this.post('/tags/', function (db, request) {
const [attrs] = JSON.parse(request.requestBody).tags;
let tag;
if (isBlank(attrs.slug) && !isBlank(attrs.name)) {
attrs.slug = attrs.name.dasherize();
}
tag = db.tags.insert(attrs);
return {
tag: tag
};
});
this.get('/tags/', function (db, request) {
const response = paginatedResponse('tags', db.tags, request);
// TODO: remove post_count unless requested?
return response;
});
this.get('/tags/slug/:slug/', function (db, request) {
const [tag] = db.tags.where({slug: request.params.slug});
// TODO: remove post_count unless requested?
return {
tag: tag
};
});
this.put('/tags/:id/', function (db, request) {
const id = request.params.id,
[attrs] = JSON.parse(request.requestBody).contacts,
record = db.tags.update(id, attrs);
return {
tag: record
};
});
this.del('/tags/:id/', 'tag');
/* Users ---------------------------------------------------------------- */
// /users/me = Always return the user with ID=1
this.get('/users/me', function (db) {
return {
users: [db.users.find(1)]
};
});
}
/*
You can optionally export a config that is only loaded during tests
export function testConfig() {
}
*/

View File

@ -0,0 +1,9 @@
/* jscs:disable */
import Mirage from 'ember-cli-mirage';
export default Mirage.Factory.extend({
dismissible: true,
message: 'This is an alert',
status: 'alert',
type: 'error'
});

View File

@ -0,0 +1,12 @@
/* jscs:disable */
import Mirage from 'ember-cli-mirage';
export default Mirage.Factory.extend({
created_at() { return '2013-11-25T14:48:11.000Z'; },
created_by() { return 1; },
description(i) { return `Role ${i}`; },
name() { return ''; },
updated_at() { return '2013-11-25T14:48:11.000Z'; },
updated_by() { return 1; },
uuid(i) { return `role-${i}`; }
});

View File

@ -0,0 +1,13 @@
/* jscs:disable */
import Mirage from 'ember-cli-mirage';
export default Mirage.Factory.extend({
uuid(i) { return `setting-${i}`; },
key(i) { return `setting-${i}`; },
value() { return null; },
type() { return 'blog'; },
created_at() { return '2015-01-12T18:29:01.000Z'; },
created_by() { return 1; },
updated_at() { return '2015-10-27T17:39:58.288Z'; },
updated_by() { return 1; }
});

View File

@ -0,0 +1,19 @@
/* jscs:disable */
import Mirage from 'ember-cli-mirage';
export default Mirage.Factory.extend({
created_at() { return '2015-09-11T09:44:29.871Z'; },
created_by() { return 1; },
description(i) { return `Description for tag ${i}.`; },
hidden() { return false; },
image(i) { return `/content/images/2015/10/tag-${i}.jpg`; },
meta_description(i) { return `Meta description for tag ${i}.`; },
meta_title(i) { return `Meta Title for tag ${i}`; },
name(i) { return `Tag ${i}`; },
parent() { return null; },
post_count() { return 1; },
slug(i) { return `tag-${i}`; },
updated_at() { return '2015-10-19T16:25:07.756Z'; },
updated_by() { return 1; },
uuid(i) { return `tag-${i}`; }
});

View File

@ -0,0 +1,27 @@
/* jscs:disable */
import Mirage from 'ember-cli-mirage';
export default Mirage.Factory.extend({
accessibility() { return null; },
bio() { return null; },
cover() { return null; },
created_at() { return '2015-09-02T13:41:50.000Z'; },
created_by() { return null; },
email(i) { return `user-${i}@example.com`; },
image() { return '//www.gravatar.com/avatar/3ae045bc198a157401827c8455cd7c99?s=250&d=mm&r=x'; },
language() { return 'en_US'; },
last_login() { return '2015-11-02T16:12:05.000Z'; },
location() { return null; },
meta_description() { return null; },
meta_title() { return null; },
name(i) { return `User ${i}`; },
slug(i) { return `user-${i}`; },
status() { return 'active'; },
tour() { return null; },
updated_at() { return '2015-11-02T16:12:05.000Z'; },
updated_by() { return '2015-09-02T13:41:50.000Z'; },
uuid(i) { return `user-${i}`; },
website() { return 'http://example.com'; },
roles() { return []; }
});

View File

@ -0,0 +1,173 @@
export default [
{
created_at: '2015-09-11T09:44:30.805Z',
created_by: 1,
id: 1,
key: 'title',
type: 'blog',
updated_at: '2015-10-04T16:26:05.195Z',
updated_by: 1,
uuid: '39e16daf-43fa-4bf0-87d4-44948ba8bf4c',
value: 'Test Blog'
},
{
created_at: '2015-09-11T09:44:30.806Z',
created_by: 1,
id: 2,
key: 'description',
type: 'blog',
updated_at: '2015-10-04T16:26:05.198Z',
updated_by: 1,
uuid: 'e6c8b636-6925-4c4a-a5d9-1dc0870fb8ea',
value: 'Thoughts, stories and ideas.'
},
{
id: 3,
uuid: '347cedbe-f867-4184-a04d-e176dff24053',
key: 'email',
value: 'info@example.com',
type: 'blog',
created_at: '2013-11-25T14:48:11.000Z',
created_by: 1,
updated_at: '2015-08-20T04:30:20.000Z',
updated_by: 1
},
{
id: 4,
uuid: '4339ce48-b485-418a-acc2-1d34cf17a5e3',
key: 'logo',
value: '/content/images/2013/Nov/logo.png',
type: 'blog',
created_at: '2013-11-25T14:48:11.000Z',
created_by: 1,
updated_at: '2015-10-27T17:39:58.273Z',
updated_by: 1
},
{
id: 5,
uuid: 'e41b6c2a-7f72-45ea-96d8-ee016f06d78b',
key: 'cover',
value: '/content/images/2014/Feb/cover.jpg',
type: 'blog',
created_at: '2013-11-25T14:48:11.000Z',
created_by: 1,
updated_at: '2015-10-27T17:39:58.276Z',
updated_by: 1
},
{
id: 6,
uuid: '4558457e-9f61-47a5-9d45-8b83829bf1cf',
key: 'defaultLang',
value: 'en_US',
type: 'blog',
created_at: '2013-11-25T14:48:11.000Z',
created_by: 1,
updated_at: '2015-10-27T17:39:58.278Z',
updated_by: 1
},
{
created_at: '2015-09-11T09:44:30.809Z',
created_by: 1,
id: 7,
key: 'postsPerPage',
type: 'blog',
updated_at: '2015-10-04T16:26:05.211Z',
updated_by: 1,
uuid: '775e6ca1-bcc3-4347-a53d-15d5d76c04a4',
value: '5'
},
{
id: 8,
uuid: '3c93b240-d22b-473f-9063-537023e06c2d',
key: 'forceI18n',
value: 'true',
type: 'blog',
created_at: '2013-11-25T14:48:11.000Z',
created_by: 1,
updated_at: '2015-10-27T17:39:58.280Z',
updated_by: 1
},
{
id: 9,
uuid: '4e58389f-f173-4387-b28c-0435623882ad',
key: 'activeTheme',
value: 'casper',
type: 'theme',
created_at: '2013-11-25T14:48:11.000Z',
created_by: 1,
updated_at: '2015-10-27T17:39:58.284Z',
updated_by: 1
},
{
id: 10,
uuid: '8052c2bf-9c19-4d6c-8944-7465321d00be',
key: 'permalinks',
value: '/:slug/',
type: 'blog',
created_at: '2014-01-14T12:01:51.000Z',
created_by: 1,
updated_at: '2015-10-27T17:39:58.282Z',
updated_by: 1
},
{
created_at: '2015-09-11T09:44:30.809Z',
created_by: 1,
id: 11,
key: 'ghost_head',
type: 'blog',
updated_at: '2015-09-23T13:32:49.858Z',
updated_by: 1,
uuid: 'df7f3151-bc08-4a77-be9d-dd315b630d51',
value: ''
},
{
created_at: '2015-09-11T09:44:30.809Z',
created_by: 1,
id: 12,
key: 'ghost_foot',
type: 'blog',
updated_at: '2015-09-23T13:32:49.858Z',
updated_by: 1,
uuid: '0649d45e-828b-4dd0-8381-3dff6d1d5ddb',
value: ''
},
{
id: 13,
uuid: 'd806f358-7996-4c74-b153-8876959c4b70',
key: 'labs',
value: '{"codeInjectionUI":true}',
type: 'blog',
created_at: '2015-01-12T18:29:01.000Z',
created_by: 1,
updated_at: '2015-10-27T17:39:58.288Z',
updated_by: 1
},
{
created_at: '2015-09-11T09:44:30.810Z',
created_by: 1,
id: 14,
key: 'navigation',
type: 'blog',
updated_at: '2015-09-23T13:32:49.868Z',
updated_by: 1,
uuid: '4cc51d1c-fcbd-47e6-a71b-fdd1abb223fc',
value: JSON.stringify([
{label: 'Home', url: '/'},
{label: 'About', url: '/about'}
])
},
{
key: 'availableThemes',
value: [
{
name: 'casper',
package: {
name: 'Blog',
version: '1.0'
},
active: true
}
],
type: 'theme'
}
];

View File

@ -0,0 +1,6 @@
export default function (/* server */) {
// Seed your development database using your factories. This
// data will not be loaded in your tests.
// server.createList('contact', 10);
}

View File

@ -11,6 +11,8 @@
"ember-mocha": "0.8.6",
"ember-load-initializers": "ember-cli/ember-load-initializers#0.1.5",
"ember-resolver": "0.1.18",
"es5-shim": "4.2.0",
"Faker": "3.0.1",
"fastclick": "1.0.6",
"google-caja": "5669.0.0",
"jquery": "2.1.4",
@ -21,10 +23,11 @@
"jquery.simulate.drag-sortable": "0.1.0",
"keymaster": "1.6.3",
"loader.js": "3.2.1",
"lodash": "~3.7.0",
"moment": "2.10.3",
"normalize.css": "3.0.3",
"password-generator": "git://github.com/bermi/password-generator#49accd7",
"pretender": "~0.9.0",
"pretender": "0.10.1",
"rangyinputs": "1.2.0",
"selectize": "~0.12.1",
"showdown-ghost": "0.3.6",

View File

@ -39,6 +39,9 @@ module.exports = function (environment) {
ENV.APP.LOG_TRANSITIONS = true;
ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
ENV.APP.LOG_VIEW_LOOKUPS = true;
ENV['ember-cli-mirage'] = {
enabled: false
};
}
if (environment === 'test') {

View File

@ -25,11 +25,13 @@
"ember-cli-babel": "^5.1.3",
"ember-cli-content-security-policy": "0.4.0",
"ember-cli-dependency-checker": "^1.0.1",
"ember-cli-es5-shim": "0.1.1",
"ember-cli-fastclick": "1.0.3",
"ember-cli-htmlbars": "0.7.9",
"ember-cli-htmlbars-inline-precompile": "^0.2.0",
"ember-cli-ic-ajax": "0.2.1",
"ember-cli-inject-live-reload": "^1.3.1",
"ember-cli-mirage": "0.1.9",
"ember-cli-mocha": "0.9.3",
"ember-cli-pretender": "0.5.0",
"ember-cli-release": "0.2.3",

View File

@ -1,5 +1,6 @@
{
"predef": [
"server",
"authenticateSession",
"invalidateSession",
"currentSession",

View File

@ -8,79 +8,19 @@ import {
import { expect } from 'chai';
import Ember from 'ember';
import startApp from '../../helpers/start-app';
import Pretender from 'pretender';
import { invalidateSession, authenticateSession } from 'ghost/tests/helpers/ember-simple-auth';
import requiredSettings from '../../fixtures/settings';
const {run} = Ember;
describe('Acceptance: Settings - Navigation', function () {
let application,
store,
server;
let application;
beforeEach(function () {
application = startApp();
store = application.__container__.lookup('service:store');
server = new Pretender(function () {
// TODO: This needs to either be fleshed out to include all user data, or be killed with fire
// as it needs to be loaded with all authenticated page loads
this.get('/ghost/api/v0.1/users/me', function () {
return [200, {'Content-Type': 'application/json'}, JSON.stringify({users: []})];
});
this.get('/ghost/api/v0.1/settings/', function (_request) {
let response = {meta: {filters: 'blog,theme'}};
response.settings = [{
created_at: '2015-09-11T09:44:30.810Z',
created_by: 1,
id: 16,
key: 'navigation',
type: 'blog',
updated_at: '2015-09-23T13:32:49.868Z',
updated_by: 1,
uuid: '4cc51d1c-fcbd-47e6-a71b-fdd1abb223fc',
value: JSON.stringify([
{label: 'Home', url: '/'},
{label: 'About', url: '/about'}
])
}];
response.settings.pushObjects(requiredSettings);
return [200, {'Content-Type': 'application/json'}, JSON.stringify(response)];
});
// TODO: This will be needed for all authenticated page loads
// - is there some way to make this a default?
this.get('/ghost/api/v0.1/notifications/', function (_request) {
return [200, {'Content-Type': 'application/json'}, JSON.stringify({notifications: []})];
});
this.put('/ghost/api/v0.1/settings/', function (_request) {
let response = {meta: {}};
response.settings = [{
created_at: '2015-09-11T09:44:30.810Z',
created_by: 1,
id: 16,
key: 'navigation',
type: 'blog',
updated_at: '2015-09-23T13:32:49.868Z',
updated_by: 1,
uuid: '4cc51d1c-fcbd-47e6-a71b-fdd1abb223fc',
value: JSON.stringify([
{label: 'Test', url: '/test'},
{label: 'About', url: '/about'}
])
}];
response.settings.pushObjects(requiredSettings);
return [200, {'Content-Type': 'application/json'}, JSON.stringify(response)];
});
});
});
afterEach(function () {
Ember.run(application, 'destroy');
run(application, 'destroy');
});
it('redirects to signin when not authenticated', function () {
@ -88,30 +28,30 @@ describe('Acceptance: Settings - Navigation', function () {
visit('/settings/navigation');
andThen(function () {
expect(currentPath()).to.not.equal('settings.navigation');
expect(currentURL(), 'currentURL').to.equal('/signin');
});
});
it('redirects to team page when authenticated as author', function () {
run(() => {
let role = store.push('role', {id: 1, name: 'Author'});
store.push('user', {id: 'me', roles: [role]});
});
const role = server.create('role', {name: 'Author'}),
user = server.create('user', {roles: [role], slug: 'test-user'});
authenticateSession(application);
visit('/settings/navigation');
andThen(function () {
expect(currentPath()).to.equal('team.user');
expect(currentURL(), 'currentURL').to.equal('/team/test-user');
});
});
describe('when logged in', function () {
beforeEach(function () {
run(() => {
let role = store.push('role', {id: 1, name: 'Administrator'});
store.push('user', {id: 'me', roles: [role]});
});
const role = server.create('role', {name: 'Administrator'}),
user = server.create('user', {roles: [role]});
// load the settings fixtures
// TODO: this should always be run for acceptance tests
server.loadFixtures();
authenticateSession(application);
});
@ -122,7 +62,7 @@ describe('Acceptance: Settings - Navigation', function () {
andThen(function () {
expect(currentPath()).to.equal('settings.navigation');
// test has expected number of rows
expect($('.gh-blognav-item').length).to.equal(3);
expect($('.gh-blognav-item').length, 'navigation items count').to.equal(3);
});
});

View File

@ -8,9 +8,7 @@ import {
import { expect } from 'chai';
import Ember from 'ember';
import startApp from '../../helpers/start-app';
import Pretender from 'pretender';
import { invalidateSession, authenticateSession } from 'ghost/tests/helpers/ember-simple-auth';
import requiredSettings from '../../fixtures/settings';
const {run} = Ember,
// Grabbed from keymaster's testing code because Ember's `keyEvent` helper
@ -41,194 +39,14 @@ const {run} = Ember,
};
describe('Acceptance: Settings - Tags', function () {
let application,
store,
server,
roleName;
let application;
beforeEach(function () {
application = startApp();
store = application.__container__.lookup('service:store');
server = new Pretender(function () {
// TODO: This needs to either be fleshed out to include all user data, or be killed with fire
// as it needs to be loaded with all authenticated page loads
this.get('/ghost/api/v0.1/users/me', function () {
return [200, {'Content-Type': 'application/json'}, JSON.stringify({users: [{
id: '1',
roles: [{
id: 1,
name: roleName,
slug: 'barry'
}]
}]})];
});
this.get('/ghost/api/v0.1/settings/', function (_request) {
let response = {meta: {filters: 'blog,theme'}};
response.settings = requiredSettings;
return [200, {'Content-Type': 'application/json'}, JSON.stringify(response)];
});
// TODO: This will be needed for all authenticated page loads
// - is there some way to make this a default?
this.get('/ghost/api/v0.1/notifications/', function (_request) {
return [200, {'Content-Type': 'application/json'}, JSON.stringify({notifications: []})];
});
this.get('/ghost/api/v0.1/tags/', function (_request) {
let response = {};
response.meta = {
pagination: {
page: 1,
limit: 15,
pages: 1,
total: 2,
next: null,
prev: null
}
};
response.tags = [
{
id: 1,
parent: null,
uuid: 'e2016ef1-4b51-46ff-9388-c6f066fc2e6c',
image: '/content/images/2015/10/tag-1.jpg',
name: 'Tag One',
slug: 'tag-one',
description: 'Description one.',
meta_title: 'Meta Title One',
meta_description: 'Meta description one.',
created_at: '2015-09-11T09:44:29.871Z',
created_by: 1,
updated_at: '2015-10-19T16:25:07.756Z',
updated_by: 1,
hidden: false,
post_count: 1
},
{
id: 2,
parent: null,
uuid: '0cade0f9-7a3f-4fd1-a80a-3a1ab7028340',
image: '/content/images/2015/10/tag-2.jpg',
name: 'Tag Two',
slug: 'tag-two',
description: 'Description two.',
meta_title: 'Meta Title Two',
meta_description: 'Meta description two.',
created_at: '2015-09-11T09:44:29.871Z',
created_by: 1,
updated_at: '2015-10-19T16:25:07.756Z',
updated_by: 1,
hidden: false,
post_count: 2
}
];
return [200, {'Content-Type': 'application/json'}, JSON.stringify(response)];
});
this.get('/ghost/api/v0.1/tags/slug/tag-two/', function (_request) {
let response = {};
response.tag = {
id: 2,
parent: null,
uuid: '0cade0f9-7a3f-4fd1-a80a-3a1ab7028340',
image: '/content/images/2015/10/tag-2.jpg',
name: 'Tag Two',
slug: 'tag-two',
description: 'Description two.',
meta_title: 'Meta Title Two',
meta_description: 'Meta description two.',
created_at: '2015-09-11T09:44:29.871Z',
created_by: 1,
updated_at: '2015-10-19T16:25:07.756Z',
updated_by: 1,
hidden: false,
post_count: 2
};
return [200, {'Content-Type': 'application/json'}, JSON.stringify(response)];
});
this.put('/ghost/api/v0.1/tags/2/', function (_request) {
let response = {};
response.tag = {
id: 2,
parent: null,
uuid: '0cade0f9-7a3f-4fd1-a80a-3a1ab7028340',
image: '/content/images/2015/10/tag-2.jpg',
name: 'Saved Tag',
slug: 'tag-two',
description: 'Description two.',
meta_title: 'Meta Title Two',
meta_description: 'Meta description two.',
created_at: '2015-09-11T09:44:29.871Z',
created_by: 1,
updated_at: '2015-10-19T16:25:07.756Z',
updated_by: 1,
hidden: false,
post_count: 2
};
return [200, {'Content-Type': 'application/json'}, JSON.stringify(response)];
});
this.post('/ghost/api/v0.1/tags/', function (_request) {
let response = {};
response.tag = {
id: 3,
parent: null,
uuid: 'de9f4636-0398-4e23-a963-e073d12bc511',
image: '/content/images/2015/10/tag-3.jpg',
name: 'Tag Three',
slug: 'tag-three',
description: 'Description three.',
meta_title: 'Meta Title Three',
meta_description: 'Meta description three.',
created_at: '2015-09-11T09:44:29.871Z',
created_by: 1,
updated_at: '2015-10-19T16:25:07.756Z',
updated_by: 1,
hidden: false,
post_count: 2
};
return [200, {'Content-Type': 'application/json'}, JSON.stringify(response)];
});
this.delete('/ghost/api/v0.1/tags/3/', function (_request) {
let response = {tags: []};
response.tags.push({
id: 3,
parent: null,
uuid: 'de9f4636-0398-4e23-a963-e073d12bc511',
image: '/content/images/2015/10/tag-3.jpg',
name: 'Tag Three',
slug: 'tag-three',
description: 'Description three.',
meta_title: 'Meta Title Three',
meta_description: 'Meta description three.',
created_at: '2015-09-11T09:44:29.871Z',
created_by: 1,
updated_at: '2015-10-19T16:25:07.756Z',
updated_by: 1,
hidden: false,
post_count: 2
});
return [200, {'Content-Type': 'application/json'}, JSON.stringify(response)];
});
});
});
afterEach(function () {
Ember.run(application, 'destroy');
run(application, 'destroy');
});
it('redirects to signin when not authenticated', function () {
@ -241,27 +59,38 @@ describe('Acceptance: Settings - Tags', function () {
});
it('redirects to team page when authenticated as author', function () {
roleName = 'Author';
const role = server.create('role', {name: 'Author'}),
user = server.create('user', {roles: [role], slug: 'test-user'});
authenticateSession(application);
visit('/settings/navigation');
andThen(() => {
expect(currentURL()).to.match(/^\/team\//);
expect(currentURL(), 'currentURL').to.equal('/team/test-user');
});
});
describe('when logged in', function () {
beforeEach(function () {
roleName = 'Administrator';
const role = server.create('role', {name: 'Administrator'}),
user = server.create('user', {roles: [role]});
// load the settings fixtures
// TODO: this should always be run for acceptance tests
server.loadFixtures();
authenticateSession(application);
});
it('it renders, can be navigated, can edit, create & delete tags', function () {
const tag1 = server.create('tag'),
tag2 = server.create('tag');
visit('/settings/tags');
andThen(() => {
// it redirects to first tag
expect(currentURL(), 'currentURL').to.equal('/settings/tags/tag-one');
expect(currentURL(), 'currentURL').to.equal(`/settings/tags/${tag1.slug}`);
// it has correct page title
expect(document.title, 'page title').to.equal('Settings - Tags - Test Blog');
@ -274,17 +103,17 @@ describe('Acceptance: Settings - Tags', function () {
expect(find('.settings-tags .settings-tag').length, 'tag list count')
.to.equal(2);
expect(find('.settings-tags .settings-tag:first .tag-title').text(), 'tag list item title')
.to.equal('Tag One');
.to.equal(tag1.name);
// it highlights selected tag
expect(find('a[href="/settings/tags/tag-one"]').hasClass('active'), 'highlights selected tag')
expect(find(`a[href="/settings/tags/${tag1.slug}"]`).hasClass('active'), 'highlights selected tag')
.to.be.true;
// it shows selected tag form
expect(find('.tag-settings-pane h4').text(), 'settings pane title')
.to.equal('Tag Settings');
expect(find('.tag-settings-pane input[name="name"]').val(), 'loads correct tag into form')
.to.equal('Tag One');
.to.equal(tag1.name);
});
// click the second tag in the list
@ -292,15 +121,15 @@ describe('Acceptance: Settings - Tags', function () {
andThen(() => {
// it navigates to selected tag
expect(currentURL(), 'url after clicking tag').to.equal('/settings/tags/tag-two');
expect(currentURL(), 'url after clicking tag').to.equal(`/settings/tags/${tag2.slug}`);
// it highlights selected tag
expect(find('a[href="/settings/tags/tag-two"]').hasClass('active'), 'highlights selected tag')
expect(find(`a[href="/settings/tags/${tag2.slug}"]`).hasClass('active'), 'highlights selected tag')
.to.be.true;
// it shows selected tag form
expect(find('.tag-settings-pane input[name="name"]').val(), 'loads correct tag into form')
.to.equal('Tag Two');
.to.equal(tag2.name);
});
andThen(() => {
@ -311,10 +140,10 @@ describe('Acceptance: Settings - Tags', function () {
});
// it navigates to previous tag
expect(currentURL(), 'url after keyboard up arrow').to.equal('/settings/tags/tag-one');
expect(currentURL(), 'url after keyboard up arrow').to.equal(`/settings/tags/${tag1.slug}`);
// it highlights selected tag
expect(find('a[href="/settings/tags/tag-one"]').hasClass('active'), 'selects previous tag')
expect(find(`a[href="/settings/tags/${tag1.slug}"]`).hasClass('active'), 'selects previous tag')
.to.be.true;
});
@ -326,10 +155,10 @@ describe('Acceptance: Settings - Tags', function () {
});
// it navigates to previous tag
expect(currentURL(), 'url after keyboard down arrow').to.equal('/settings/tags/tag-two');
expect(currentURL(), 'url after keyboard down arrow').to.equal(`/settings/tags/${tag2.slug}`);
// it highlights selected tag
expect(find('a[href="/settings/tags/tag-two"]').hasClass('active'), 'selects next tag')
expect(find(`a[href="/settings/tags/${tag2.slug}"]`).hasClass('active'), 'selects next tag')
.to.be.true;
});
@ -340,9 +169,9 @@ describe('Acceptance: Settings - Tags', function () {
andThen(() => {
// check we update with the data returned from the server
expect(find('.settings-tags .settings-tag:last .tag-title').text(), 'tag list updates on save')
.to.equal('Saved Tag');
.to.equal('New Name');
expect(find('.tag-settings-pane input[name="name"]').val(), 'settings form updates on save')
.to.equal('Saved Tag');
.to.equal('New Name');
});
// start new tag
@ -369,14 +198,14 @@ describe('Acceptance: Settings - Tags', function () {
andThen(() => {
// it redirects to the new tag's URL
expect(currentURL(), 'URL after tag creation').to.equal('/settings/tags/tag-three');
expect(currentURL(), 'URL after tag creation').to.equal('/settings/tags/new-tag');
// it adds the tag to the list and selects
expect(find('.settings-tags .settings-tag').length, 'tag list count after creation')
.to.equal(3);
expect(find('.settings-tags .settings-tag:last .tag-title').text(), 'new tag list item title')
.to.equal('Tag Three');
expect(find('a[href="/settings/tags/tag-three"]').hasClass('active'), 'highlights new tag')
.to.equal('New Tag');
expect(find('a[href="/settings/tags/new-tag"]').hasClass('active'), 'highlights new tag')
.to.be.true;
});
@ -386,7 +215,7 @@ describe('Acceptance: Settings - Tags', function () {
andThen(() => {
// it redirects to the first tag
expect(currentURL(), 'URL after tag deletion').to.equal('/settings/tags/tag-one');
expect(currentURL(), 'URL after tag deletion').to.equal(`/settings/tags/${tag1.slug}`);
// it removes the tag from the list
expect(find('.settings-tags .settings-tag').length, 'tag list count after deletion')
@ -395,25 +224,53 @@ describe('Acceptance: Settings - Tags', function () {
});
it('loads tag via slug when accessed directly', function () {
visit('/settings/tags/tag-two');
server.createList('tag', 2);
visit('/settings/tags/tag-1');
andThen(() => {
expect(currentURL(), 'URL after direct load').to.equal('/settings/tags/tag-two');
expect(currentURL(), 'URL after direct load').to.equal('/settings/tags/tag-1');
// it loads all other tags
expect(find('.settings-tags .settings-tag').length, 'tag list count after direct load')
.to.equal(2);
// selects tag in list
expect(find('a[href="/settings/tags/tag-two"]').hasClass('active'), 'highlights requested tag')
expect(find('a[href="/settings/tags/tag-1"]').hasClass('active'), 'highlights requested tag')
.to.be.true;
// shows requested tag in settings pane
expect(find('.tag-settings-pane input[name="name"]').val(), 'loads correct tag into form')
.to.equal('Tag Two');
.to.equal('Tag 1');
});
});
it('has infinite scroll pagination of tags list');
it('has infinite scroll pagination of tags list', function () {
server.createList('tag', 32);
visit('settings/tags/tag-0');
andThen(() => {
// it loads first page
expect(find('.settings-tags .settings-tag').length, 'tag list count on first load')
.to.equal(15);
find('.tag-list').scrollTop(find('.tag-list-content').height());
});
wait().then(() => {
// it loads the second page
expect(find('.settings-tags .settings-tag').length, 'tag list count on second load')
.to.equal(30);
find('.tag-list').scrollTop(find('.tag-list-content').height());
});
wait().then(() => {
// it loads the final page
expect(find('.settings-tags .settings-tag').length, 'tag list count on third load')
.to.equal(32);
});
});
});
});