mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-21 09:52:06 +03:00
143921948d
refs b6728ecb0f
- The "no-shadow" eslint rune was introduced into ghost's eslint plugin (referenced commmit), which resulted in flood of warning in console output when linting the project codebase.
- This cleanup is aiming to make any new linting issues more visible. Follow up commits will contain similar cleanups in other parts of the codebase
338 lines
13 KiB
JavaScript
338 lines
13 KiB
JavaScript
const should = require('should');
|
|
const _ = require('lodash');
|
|
const supertest = require('supertest');
|
|
const Promise = require('bluebird');
|
|
const testUtils = require('../../utils');
|
|
const config = require('../../../core/shared/config');
|
|
const db = require('../../../core/server/data/db');
|
|
const models = require('../../../core/server/models');
|
|
const localUtils = require('./utils');
|
|
|
|
const ghost = testUtils.startGhost;
|
|
let request;
|
|
|
|
describe('User API', function () {
|
|
let inactiveUser;
|
|
let admin;
|
|
|
|
before(function () {
|
|
return ghost()
|
|
.then(function () {
|
|
request = supertest.agent(config.get('url'));
|
|
})
|
|
.then(function () {
|
|
// create inactive user
|
|
return testUtils.createUser({
|
|
user: testUtils.DataGenerator.forKnex.createUser({email: 'test+3@ghost.org', status: 'inactive'}),
|
|
role: testUtils.DataGenerator.Content.roles[2].name
|
|
});
|
|
})
|
|
.then(function (_user) {
|
|
inactiveUser = _user;
|
|
|
|
// create admin user
|
|
return testUtils.createUser({
|
|
user: testUtils.DataGenerator.forKnex.createUser({email: 'test+admin@ghost.org', slug: 'admin'}),
|
|
role: testUtils.DataGenerator.Content.roles[0].name
|
|
});
|
|
})
|
|
.then(function (_user) {
|
|
admin = _user;
|
|
|
|
// by default we login with the owner
|
|
return localUtils.doAuth(request);
|
|
});
|
|
});
|
|
|
|
it('Can request all users ordered by id', function (done) {
|
|
// @NOTE: ASC is default
|
|
request.get(localUtils.API.getApiQuery('users/?order=id%20DESC'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
|
|
const jsonResponse = res.body;
|
|
should.exist(jsonResponse.users);
|
|
localUtils.API.checkResponse(jsonResponse, 'users');
|
|
|
|
// owner use + ghost-author user when Ghost starts
|
|
// and two extra users, see createUser in before
|
|
jsonResponse.users.should.have.length(4);
|
|
|
|
localUtils.API.checkResponse(jsonResponse.users[0], 'user');
|
|
|
|
jsonResponse.users[0].email.should.eql(admin.email);
|
|
jsonResponse.users[0].status.should.eql(admin.status);
|
|
|
|
jsonResponse.users[1].email.should.eql(inactiveUser.email);
|
|
jsonResponse.users[1].status.should.eql(inactiveUser.status);
|
|
|
|
jsonResponse.users[2].email.should.eql('ghost-author@example.com');
|
|
jsonResponse.users[3].email.should.eql(testUtils.DataGenerator.Content.users[0].email);
|
|
|
|
testUtils.API.isISO8601(jsonResponse.users[3].last_seen).should.be.true();
|
|
testUtils.API.isISO8601(jsonResponse.users[3].created_at).should.be.true();
|
|
testUtils.API.isISO8601(jsonResponse.users[3].updated_at).should.be.true();
|
|
|
|
// only "ghost" author has a published post
|
|
jsonResponse.users[0].url.should.eql(`${config.get('url')}/404/`);
|
|
jsonResponse.users[1].url.should.eql(`${config.get('url')}/404/`);
|
|
jsonResponse.users[2].url.should.eql(`${config.get('url')}/author/ghost/`);
|
|
jsonResponse.users[3].url.should.eql(`${config.get('url')}/404/`);
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Can include user roles', function (done) {
|
|
request.get(localUtils.API.getApiQuery('users/?include=roles'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
const jsonResponse = res.body;
|
|
should.exist(jsonResponse.users);
|
|
localUtils.API.checkResponse(jsonResponse, 'users');
|
|
|
|
jsonResponse.users.should.have.length(4);
|
|
localUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Can paginate users', function (done) {
|
|
request.get(localUtils.API.getApiQuery('users/?page=2'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
const jsonResponse = res.body;
|
|
should.equal(jsonResponse.meta.pagination.page, 2);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Can retrieve a user by id', function (done) {
|
|
request.get(localUtils.API.getApiQuery('users/' + testUtils.existingData.users[0].id + '/?include=roles,roles.permissions,count.posts'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
const jsonResponse = res.body;
|
|
should.exist(jsonResponse.users);
|
|
should.not.exist(jsonResponse.meta);
|
|
|
|
jsonResponse.users.should.have.length(1);
|
|
localUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles', 'count']);
|
|
localUtils.API.checkResponse(jsonResponse.users[0].roles[0], 'role', ['permissions']);
|
|
|
|
should.exist(jsonResponse.users[0].count.posts);
|
|
jsonResponse.users[0].count.posts.should.equal(0);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Can retrieve a user by slug', function (done) {
|
|
request.get(localUtils.API.getApiQuery('users/slug/joe-bloggs/'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
const jsonResponse = res.body;
|
|
should.exist(jsonResponse.users);
|
|
should.not.exist(jsonResponse.meta);
|
|
|
|
jsonResponse.users.should.have.length(1);
|
|
localUtils.API.checkResponse(jsonResponse.users[0], 'user');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Can retrieve a user by email', function (done) {
|
|
request.get(localUtils.API.getApiQuery('users/email/jbloggs%40example.com/'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
const jsonResponse = res.body;
|
|
should.exist(jsonResponse.users);
|
|
should.not.exist(jsonResponse.meta);
|
|
|
|
jsonResponse.users.should.have.length(1);
|
|
localUtils.API.checkResponse(jsonResponse.users[0], 'user');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('can edit a user', function () {
|
|
return request.put(localUtils.API.getApiQuery('users/me/'))
|
|
.set('Origin', config.get('url'))
|
|
.send({
|
|
users: [{
|
|
website: 'http://joe-bloggs.ghost.org',
|
|
password: 'mynewfancypasswordwhichisnotallowed'
|
|
}]
|
|
})
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.then(function (res) {
|
|
const putBody = res.body;
|
|
res.headers['x-cache-invalidate'].should.eql('/*');
|
|
should.exist(putBody.users[0]);
|
|
putBody.users[0].website.should.eql('http://joe-bloggs.ghost.org');
|
|
putBody.users[0].email.should.eql('jbloggs@example.com');
|
|
localUtils.API.checkResponse(putBody.users[0], 'user');
|
|
|
|
should.not.exist(putBody.users[0].password);
|
|
|
|
return models.User.findOne({id: putBody.users[0].id})
|
|
.then((user) => {
|
|
return models.User.isPasswordCorrect({
|
|
plainPassword: 'mynewfancypasswordwhichisnotallowed',
|
|
hashedPassword: user.get('password')
|
|
});
|
|
})
|
|
.then(Promise.reject)
|
|
.catch((err) => {
|
|
err.code.should.eql('PASSWORD_INCORRECT');
|
|
});
|
|
});
|
|
});
|
|
|
|
it('Can destroy an active user', function () {
|
|
const userId = testUtils.existingData.users[1].id;
|
|
|
|
return request
|
|
.get(localUtils.API.getApiQuery(`posts/?filter=author_id:${userId}`))
|
|
.set('Origin', config.get('url'))
|
|
.expect(200)
|
|
.then((res) => {
|
|
res.body.posts.length.should.eql(7);
|
|
|
|
return request
|
|
.delete(localUtils.API.getApiQuery(`users/${userId}`))
|
|
.set('Origin', config.get('url'))
|
|
.expect(200);
|
|
})
|
|
.then((res) => {
|
|
should.exist(res.body.meta.filename);
|
|
|
|
return request
|
|
.get(localUtils.API.getApiQuery(`db/?filename=${res.body.meta.filename}/`))
|
|
.set('Origin', config.get('url'))
|
|
.expect(200);
|
|
})
|
|
.then(() => {
|
|
return request
|
|
.get(localUtils.API.getApiQuery(`users/${userId}/`))
|
|
.set('Origin', config.get('url'))
|
|
.expect(404);
|
|
})
|
|
.then(() => {
|
|
return request
|
|
.get(localUtils.API.getApiQuery(`posts/?filter=author_id:${userId}`))
|
|
.set('Origin', config.get('url'))
|
|
.expect(200);
|
|
})
|
|
.then((res) => {
|
|
res.body.posts.length.should.eql(0);
|
|
|
|
return db.knex('roles_users')
|
|
.where({
|
|
user_id: userId
|
|
})
|
|
.select();
|
|
})
|
|
.then((rolesUsersModels) => {
|
|
rolesUsersModels.length.should.eql(0);
|
|
|
|
return db.knex('roles_users')
|
|
.select();
|
|
})
|
|
.then((rolesUsers) => {
|
|
rolesUsers.length.should.greaterThan(0);
|
|
});
|
|
});
|
|
|
|
it('Can transfer ownership to admin user', function () {
|
|
return request
|
|
.put(localUtils.API.getApiQuery('users/owner'))
|
|
.set('Origin', config.get('url'))
|
|
.send({
|
|
owner: [{
|
|
id: admin.id
|
|
}]
|
|
})
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.then((res) => {
|
|
res.body.users[0].roles[0].name.should.equal(testUtils.DataGenerator.Content.roles[0].name);
|
|
res.body.users[1].roles[0].name.should.equal(testUtils.DataGenerator.Content.roles[3].name);
|
|
});
|
|
});
|
|
|
|
it('Can change password and retain the session', async function () {
|
|
await request
|
|
.put(localUtils.API.getApiQuery('users/password'))
|
|
.set('Origin', config.get('url'))
|
|
.send({
|
|
password: [{
|
|
newPassword: '1234abcde!!',
|
|
ne2Password: '1234abcde!!',
|
|
oldPassword: 'Sl1m3rson99',
|
|
user_id: testUtils.existingData.users[0].id
|
|
}]
|
|
})
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.then((res) => {
|
|
should.exist(res.body.password);
|
|
should.exist(res.body.password[0].message);
|
|
});
|
|
|
|
await request
|
|
.get(localUtils.API.getApiQuery('session/'))
|
|
.set('Origin', config.get('url'))
|
|
.expect(200);
|
|
});
|
|
});
|