diff --git a/core/server/api/index.js b/core/server/api/index.js index 1ec2a41182..fb58e88874 100644 --- a/core/server/api/index.js +++ b/core/server/api/index.js @@ -49,10 +49,10 @@ init = function () { * @return {Promise(String)} Resolves to header string */ cacheInvalidationHeader = function (req, result) { - var parsedUrl = req._parsedUrl.pathname.replace(/\/$/, '').split('/'), + var parsedUrl = req._parsedUrl.pathname.replace(/^\/|\/$/g, '').split('/'), method = req.method, - endpoint = parsedUrl[4], - id = parsedUrl[5], + endpoint = parsedUrl[0], + id = parsedUrl[1], cacheInvalidate, jsonResult = result.toJSON ? result.toJSON() : result, post, @@ -104,16 +104,15 @@ locationHeader = function (req, result) { location, post, notification, - parsedUrl = req._parsedUrl.pathname.replace(/\/$/, '').split('/'), - endpoint = parsedUrl[4]; + endpoint = req._parsedUrl.pathname; if (req.method === 'POST') { if (result.hasOwnProperty('posts')) { post = result.posts[0]; location = apiRoot + '/posts/' + post.id + '/?status=' + post.status; - } else if (endpoint === 'notifications') { + } else if (endpoint === '/notifications/') { notification = result.notifications; - location = apiRoot + '/notifications/' + notification[0].id; + location = apiRoot + endpoint + notification[0].id; } } diff --git a/core/server/api/users.js b/core/server/api/users.js index e06b1e526a..6ef4ab9406 100644 --- a/core/server/api/users.js +++ b/core/server/api/users.js @@ -58,7 +58,7 @@ users = { * @returns {Promise(User)} User */ read: function read(options) { - var attrs = ['id'], + var attrs = ['id', 'slug', 'email'], data = _.pick(options, attrs); options = _.omit(options, attrs); @@ -250,7 +250,7 @@ users = { /** * ### Change Password - * @param {password} object + * @param {password} object * @param {{context}} options * @returns {Promise(password}} success message */ diff --git a/core/server/middleware/index.js b/core/server/middleware/index.js index 4d63460ac4..3e5f0245a3 100644 --- a/core/server/middleware/index.js +++ b/core/server/middleware/index.js @@ -288,7 +288,6 @@ module.exports = function (server) { // ### Caching expressServer.use(middleware.cacheControl('public')); - expressServer.use(subdir + '/api/', middleware.cacheControl('private')); expressServer.use(subdir + '/ghost/', middleware.cacheControl('private')); @@ -304,7 +303,7 @@ module.exports = function (server) { // ### Routing // Set up API routes - expressServer.use(subdir, routes.api(middleware)); + expressServer.use(subdir + routes.apiBaseUri, routes.api(middleware)); // Set up Admin routes expressServer.use(subdir, routes.admin(middleware)); diff --git a/core/server/routes/api.js b/core/server/routes/api.js index 2b5eb2abdd..7ebe8ea2ce 100644 --- a/core/server/routes/api.js +++ b/core/server/routes/api.js @@ -1,46 +1,71 @@ // # API routes var express = require('express'), api = require('../api'), - apiRoutes; + apiRoutes, + resources; + +resources = { + posts: function (router) { + router.get('/posts', api.http(api.posts.browse)); + router.post('/posts', api.http(api.posts.add)); + router.get('/posts/:id', api.http(api.posts.read)); + router.get('/posts/slug/:slug', api.http(api.posts.read)); + router.put('/posts/:id', api.http(api.posts.edit)); + router.del('/posts/:id', api.http(api.posts.destroy)); + } +}; apiRoutes = function (middleware) { var router = express.Router(); + // alias delete with del + router.del = router.delete; // ## Posts - router.get('/ghost/api/v0.1/posts', api.http(api.posts.browse)); - router.post('/ghost/api/v0.1/posts', api.http(api.posts.add)); - router.get('/ghost/api/v0.1/posts/:id(\\d+)', api.http(api.posts.read)); - router.get('/ghost/api/v0.1/posts/:slug([a-z-]+)', api.http(api.posts.read)); - router.put('/ghost/api/v0.1/posts/:id', api.http(api.posts.edit)); - router['delete']('/ghost/api/v0.1/posts/:id', api.http(api.posts.destroy)); + router.get('/posts', api.http(api.posts.browse)); + router.post('/posts', api.http(api.posts.add)); + router.get('/posts/:id', api.http(api.posts.read)); + router.get('/posts/slug/:slug', api.http(api.posts.read)); + router.put('/posts/:id', api.http(api.posts.edit)); + router.del('/posts/:id', api.http(api.posts.destroy)); + // ## Settings - router.get('/ghost/api/v0.1/settings/', api.http(api.settings.browse)); - router.get('/ghost/api/v0.1/settings/:key/', api.http(api.settings.read)); - router.put('/ghost/api/v0.1/settings/', api.http(api.settings.edit)); + router.get('/settings', api.http(api.settings.browse)); + router.get('/settings/:key', api.http(api.settings.read)); + router.put('/settings', api.http(api.settings.edit)); + // ## Users - router.get('/ghost/api/v0.1/users/', api.http(api.users.browse)); - router.get('/ghost/api/v0.1/users/:id/', api.http(api.users.read)); - router.put('/ghost/api/v0.1/users/password/', api.http(api.users.changePassword)); - router.put('/ghost/api/v0.1/users/:id/', api.http(api.users.edit)); - router.post('/ghost/api/v0.1/users/', api.http(api.users.invite)); - router['delete']('/ghost/api/v0.1/users/:id/', api.http(api.users.destroy)); + router.get('/users', api.http(api.users.browse)); + router.get('/users/:id', api.http(api.users.read)); + router.get('/users/slug/:slug', api.http(api.users.read)); + router.get('/users/email/:email', api.http(api.users.read)); + router.put('/users/password', api.http(api.users.changePassword)); + router.put('/users/:id', api.http(api.users.edit)); + router.post('/users', api.http(api.users.invite)); + router.del('/users/:id', api.http(api.users.destroy)); // ## Tags - router.get('/ghost/api/v0.1/tags/', api.http(api.tags.browse)); + router.get('/tags', api.http(api.tags.browse)); + + // ## Slugs + router.get('/slugs/:type/:name', api.http(api.slugs.generate)); + // ## Themes - router.get('/ghost/api/v0.1/themes/', api.http(api.themes.browse)); - router.put('/ghost/api/v0.1/themes/:name', api.http(api.themes.edit)); + router.get('/themes', api.http(api.themes.browse)); + router.put('/themes/:name', api.http(api.themes.edit)); + // ## Notifications - router.get('/ghost/api/v0.1/notifications/', api.http(api.notifications.browse)); - router.post('/ghost/api/v0.1/notifications/', api.http(api.notifications.add)); - router['delete']('/ghost/api/v0.1/notifications/:id', api.http(api.notifications.destroy)); + router.get('/notifications', api.http(api.notifications.browse)); + router.post('/notifications', api.http(api.notifications.add)); + router.del('/notifications/:id', api.http(api.notifications.destroy)); + // ## DB - router.get('/ghost/api/v0.1/db/', api.http(api.db.exportContent)); - router.post('/ghost/api/v0.1/db/', middleware.busboy, api.http(api.db.importContent)); - router['delete']('/ghost/api/v0.1/db/', api.http(api.db.deleteAllContent)); + router.get('/db', api.http(api.db.exportContent)); + router.post('/db', middleware.busboy, api.http(api.db.importContent)); + router.del('/db', api.http(api.db.deleteAllContent)); + // ## Mail - router.post('/ghost/api/v0.1/mail', api.http(api.mail.send)); - router.post('/ghost/api/v0.1/mail/test', function (req, res) { + router.post('/mail', api.http(api.mail.send)); + router.post('/mail/test', function (req, res) { api.settings.read('email').then(function (result) { // attach the to: address to the request body so that it is available // to the http api handler @@ -51,15 +76,13 @@ apiRoutes = function (middleware) { api.http(api.mail.sendTest)(req, res); }); }); - // ## Slugs - router.get('/ghost/api/v0.1/slugs/:type/:name', api.http(api.slugs.generate)); + + // ## Authentication - router.post('/ghost/api/v0.1/authentication/passwordreset', api.http(api.authentication.generateResetToken)); - router.put('/ghost/api/v0.1/authentication/passwordreset', api.http(api.authentication.resetPassword)); - - router.post('/ghost/api/v0.1/authentication/invitation', api.http(api.authentication.acceptInvitation)); - - router.post('/ghost/api/v0.1/authentication/token', + router.post('/authentication/passwordreset', api.http(api.authentication.generateResetToken)); + router.put('/authentication/passwordreset', api.http(api.authentication.resetPassword)); + router.post('/authentication/invitation', api.http(api.authentication.acceptInvitation)); + router.post('/authentication/token', middleware.addClientSecret, middleware.authenticateClient, middleware.generateAccessToken diff --git a/core/server/routes/index.js b/core/server/routes/index.js index 45f6188701..0f65cf26ba 100644 --- a/core/server/routes/index.js +++ b/core/server/routes/index.js @@ -3,6 +3,7 @@ var api = require('./api'), frontend = require('./frontend'); module.exports = { + apiBaseUri: '/ghost/api/v0.1/', api: api, admin: admin, frontend: frontend diff --git a/core/test/functional/routes/api/posts_test.js b/core/test/functional/routes/api/posts_test.js index 2e3bfe623c..c3996406c9 100644 --- a/core/test/functional/routes/api/posts_test.js +++ b/core/test/functional/routes/api/posts_test.js @@ -201,7 +201,7 @@ describe('Post API', function () { }); it('can retrieve a post by slug', function (done) { - request.get(testUtils.API.getApiQuery('posts/welcome-to-ghost/')) + request.get(testUtils.API.getApiQuery('posts/slug/welcome-to-ghost/')) .set('Authorization', 'Bearer ' + accesstoken) .expect('Content-Type', /json/) .end(function (err, res) { @@ -542,7 +542,7 @@ describe('Post API', function () { return done(err); } - + var unpublishedPost = res.body; // Unpublishing a post should send x-cache-invalidate headers _.has(res.headers, 'x-cache-invalidate').should.equal(true); diff --git a/core/test/functional/routes/api/users_test.js b/core/test/functional/routes/api/users_test.js index 17e6295a40..067217d54e 100644 --- a/core/test/functional/routes/api/users_test.js +++ b/core/test/functional/routes/api/users_test.js @@ -30,7 +30,7 @@ describe('User API', function () { }) .then(function () { request.post('/ghost/api/v0.1/authentication/token/') - .send({ grant_type: "password", username: user.email, password: user.password, client_id: "ghost-admin"}) + .send({ grant_type: 'password', username: user.email, password: user.password, client_id: 'ghost-admin'}) .expect('Content-Type', /json/) .expect(200) .end(function (err, res) { @@ -53,202 +53,316 @@ describe('User API', function () { httpServer.close(); }); - it('returns dates in ISO 8601 format', function (done) { - request.get(testUtils.API.getApiQuery('users/')) - .set('Authorization', 'Bearer ' + accesstoken) - .expect('Content-Type', /json/) - .expect(200) - .end(function (err, res) { - if (err) { - return done(err); - } + describe('Browse', function () { - var jsonResponse = res.body; - jsonResponse.users.should.exist; - testUtils.API.checkResponse(jsonResponse, 'users'); + it('returns dates in ISO 8601 format', function (done) { + request.get(testUtils.API.getApiQuery('users/')) + .set('Authorization', 'Bearer ' + accesstoken) + .expect('Content-Type', /json/) + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } - jsonResponse.users.should.have.length(1); - testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); + var jsonResponse = res.body; + jsonResponse.users.should.exist; + testUtils.API.checkResponse(jsonResponse, 'users'); - testUtils.API.isISO8601(jsonResponse.users[0].last_login).should.be.true; - testUtils.API.isISO8601(jsonResponse.users[0].created_at).should.be.true; - testUtils.API.isISO8601(jsonResponse.users[0].updated_at).should.be.true; + jsonResponse.users.should.have.length(1); + testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); - done(); - }); + testUtils.API.isISO8601(jsonResponse.users[0].last_login).should.be.true; + testUtils.API.isISO8601(jsonResponse.users[0].created_at).should.be.true; + testUtils.API.isISO8601(jsonResponse.users[0].updated_at).should.be.true; + + done(); + }); + }); + + it('can retrieve all users', function (done) { + request.get(testUtils.API.getApiQuery('users/')) + .set('Authorization', 'Bearer ' + accesstoken) + .expect('Content-Type', /json/) + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + + should.not.exist(res.headers['x-cache-invalidate']); + var jsonResponse = res.body; + jsonResponse.users.should.exist; + testUtils.API.checkResponse(jsonResponse, 'users'); + + jsonResponse.users.should.have.length(1); + testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); + done(); + }); + }); }); - it('can retrieve all users', function (done) { - request.get(testUtils.API.getApiQuery('users/')) - .set('Authorization', 'Bearer ' + accesstoken) - .expect('Content-Type', /json/) - .expect(200) - .end(function (err, res) { - if (err) { - return done(err); - } + describe('Read', function () { + it('can retrieve a user by "me"', function (done) { + request.get(testUtils.API.getApiQuery('users/me/')) + .set('Authorization', 'Bearer ' + accesstoken) + .expect('Content-Type', /json/) + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } - should.not.exist(res.headers['x-cache-invalidate']); - var jsonResponse = res.body; - jsonResponse.users.should.exist; - testUtils.API.checkResponse(jsonResponse, 'users'); + should.not.exist(res.headers['x-cache-invalidate']); + var jsonResponse = res.body; + jsonResponse.users.should.exist; + testUtils.API.checkResponse(jsonResponse, 'users'); - jsonResponse.users.should.have.length(1); - testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); - done(); - }); + jsonResponse.users.should.have.length(1); + testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); + done(); + }); + }); + + it('can retrieve a user by id', function (done) { + request.get(testUtils.API.getApiQuery('users/1/')) + .set('Authorization', 'Bearer ' + accesstoken) + .expect('Content-Type', /json/) + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + + should.not.exist(res.headers['x-cache-invalidate']); + var jsonResponse = res.body; + jsonResponse.users.should.exist; + testUtils.API.checkResponse(jsonResponse, 'users'); + + jsonResponse.users.should.have.length(1); + testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); + done(); + }); + }); + + it('can retrieve a user by slug', function (done) { + request.get(testUtils.API.getApiQuery('users/slug/joe-blogs/')) + .set('Authorization', 'Bearer ' + accesstoken) + .expect('Content-Type', /json/) + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + + should.not.exist(res.headers['x-cache-invalidate']); + var jsonResponse = res.body; + jsonResponse.users.should.exist; + testUtils.API.checkResponse(jsonResponse, 'users'); + + jsonResponse.users.should.have.length(1); + testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); + done(); + }); + }); + + it('can retrieve a user by email', function (done) { + request.get(testUtils.API.getApiQuery('users/email/jbloggs%40example.com/')) + .set('Authorization', 'Bearer ' + accesstoken) + .expect('Content-Type', /json/) + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + + should.not.exist(res.headers['x-cache-invalidate']); + var jsonResponse = res.body; + jsonResponse.users.should.exist; + testUtils.API.checkResponse(jsonResponse, 'users'); + + jsonResponse.users.should.have.length(1); + testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); + done(); + }); + }); + + it('can retrieve a user with role', function (done) { + request.get(testUtils.API.getApiQuery('users/me/?include=roles')) + .set('Authorization', 'Bearer ' + accesstoken) + .expect('Content-Type', /json/) + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + + should.not.exist(res.headers['x-cache-invalidate']); + var jsonResponse = res.body; + jsonResponse.users.should.exist; + testUtils.API.checkResponse(jsonResponse, 'users'); + + jsonResponse.users.should.have.length(1); + testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); + testUtils.API.checkResponse(jsonResponse.users[0].roles[0], 'role'); + done(); + }); + }); + + it('can retrieve a user with role and permissions', function (done) { + request.get(testUtils.API.getApiQuery('users/me/?include=roles,roles.permissions')) + .set('Authorization', 'Bearer ' + accesstoken) + .expect('Content-Type', /json/) + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + + should.not.exist(res.headers['x-cache-invalidate']); + var jsonResponse = res.body; + jsonResponse.users.should.exist; + testUtils.API.checkResponse(jsonResponse, 'users'); + + jsonResponse.users.should.have.length(1); + testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); + testUtils.API.checkResponse(jsonResponse.users[0].roles[0], 'role', ['permissions']); + testUtils.API.checkResponse(jsonResponse.users[0].roles[0].permissions[0], 'permission'); + + done(); + }); + }); + + it('can retrieve a user by slug with role and permissions', function (done) { + request.get(testUtils.API.getApiQuery('users/slug/joe-blogs/?include=roles,roles.permissions')) + .set('Authorization', 'Bearer ' + accesstoken) + .expect('Content-Type', /json/) + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + + should.not.exist(res.headers['x-cache-invalidate']); + var jsonResponse = res.body; + jsonResponse.users.should.exist; + testUtils.API.checkResponse(jsonResponse, 'users'); + + jsonResponse.users.should.have.length(1); + testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); + testUtils.API.checkResponse(jsonResponse.users[0].roles[0], 'role', ['permissions']); + testUtils.API.checkResponse(jsonResponse.users[0].roles[0].permissions[0], 'permission'); + + done(); + }); + }); + + it('can\'t retrieve non existent user by id', function (done) { + request.get(testUtils.API.getApiQuery('users/99/')) + .set('Authorization', 'Bearer ' + accesstoken) + .expect('Content-Type', /json/) + .expect(404) + .end(function (err, res) { + if (err) { + return done(err); + } + + should.not.exist(res.headers['x-cache-invalidate']); + var jsonResponse = res.body; + jsonResponse.should.exist; + jsonResponse.errors.should.exist; + testUtils.API.checkResponseValue(jsonResponse.errors[0], ['message', 'type']); + done(); + }); + }); + + it('can\'t retrieve non existent user by slug', function (done) { + request.get(testUtils.API.getApiQuery('users/slug/blargh/')) + .set('Authorization', 'Bearer ' + accesstoken) + .expect('Content-Type', /json/) + .expect(404) + .end(function (err, res) { + if (err) { + return done(err); + } + + should.not.exist(res.headers['x-cache-invalidate']); + var jsonResponse = res.body; + jsonResponse.should.exist; + jsonResponse.errors.should.exist; + testUtils.API.checkResponseValue(jsonResponse.errors[0], ['message', 'type']); + done(); + }); + }); }); + describe('Edit', function () { + it('can edit a user', function (done) { + request.get(testUtils.API.getApiQuery('users/me/')) + .set('Authorization', 'Bearer ' + accesstoken) + .expect('Content-Type', /json/) + .end(function (err, res) { + if (err) { + return done(err); + } - it('can retrieve a user', function (done) { - request.get(testUtils.API.getApiQuery('users/me/')) - .set('Authorization', 'Bearer ' + accesstoken) - .expect('Content-Type', /json/) - .expect(200) - .end(function (err, res) { - if (err) { - return done(err); - } + var jsonResponse = res.body, + changedValue = 'joe-bloggs.ghost.org', + dataToSend; + jsonResponse.users[0].should.exist; + testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); - should.not.exist(res.headers['x-cache-invalidate']); - var jsonResponse = res.body; - jsonResponse.users.should.exist; - testUtils.API.checkResponse(jsonResponse, 'users'); + dataToSend = { users: [ + {website: changedValue} + ]}; - jsonResponse.users.should.have.length(1); - testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); - done(); - }); - }); + request.put(testUtils.API.getApiQuery('users/me/')) + .set('Authorization', 'Bearer ' + accesstoken) + .send(dataToSend) + .expect('Content-Type', /json/) + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } - it('can retrieve a user with role', function (done) { - request.get(testUtils.API.getApiQuery('users/me/?include=roles')) - .set('Authorization', 'Bearer ' + accesstoken) - .expect('Content-Type', /json/) - .expect(200) - .end(function (err, res) { - if (err) { - return done(err); - } + var putBody = res.body; + res.headers['x-cache-invalidate'].should.eql('/*'); + putBody.users[0].should.exist; + putBody.users[0].website.should.eql(changedValue); + putBody.users[0].email.should.eql(jsonResponse.users[0].email); + testUtils.API.checkResponse(putBody.users[0], 'user', ['roles']); + done(); + }); + }); + }); - should.not.exist(res.headers['x-cache-invalidate']); - var jsonResponse = res.body; - jsonResponse.users.should.exist; - testUtils.API.checkResponse(jsonResponse, 'users'); + it('can\'t edit a user with invalid accesstoken', function (done) { + request.get(testUtils.API.getApiQuery('users/me/')) + .set('Authorization', 'Bearer ' + accesstoken) + .expect('Content-Type', /json/) + .end(function (err, res) { + if (err) { + return done(err); + } - jsonResponse.users.should.have.length(1); - testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); - testUtils.API.checkResponse(jsonResponse.users[0].roles[0], 'role'); - done(); - }); - }); + var jsonResponse = res.body, + changedValue = 'joe-bloggs.ghost.org'; + jsonResponse.users[0].should.exist; + jsonResponse.users[0].website = changedValue; - it('can retrieve a user with role and permissions', function (done) { - request.get(testUtils.API.getApiQuery('users/me/?include=roles,roles.permissions')) - .set('Authorization', 'Bearer ' + accesstoken) - .expect('Content-Type', /json/) - .expect(200) - .end(function (err, res) { - if (err) { - return done(err); - } + request.put(testUtils.API.getApiQuery('users/me/')) + .set('Authorization', 'Bearer ' + 'invalidtoken') + .send(jsonResponse) + .expect(401) + .end(function (err, res) { + if (err) { + return done(err); + } - should.not.exist(res.headers['x-cache-invalidate']); - var jsonResponse = res.body; - jsonResponse.users.should.exist; - testUtils.API.checkResponse(jsonResponse, 'users'); + done(); + }); - jsonResponse.users.should.have.length(1); - testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); - testUtils.API.checkResponse(jsonResponse.users[0].roles[0], 'role', ['permissions']); - testUtils.API.checkResponse(jsonResponse.users[0].roles[0].permissions[0], 'permission'); - - done(); - }); - }); - - it('can\'t retrieve non existent user', function (done) { - request.get(testUtils.API.getApiQuery('users/99/')) - .set('Authorization', 'Bearer ' + accesstoken) - .expect('Content-Type', /json/) - .expect(404) - .end(function (err, res) { - if (err) { - return done(err); - } - - should.not.exist(res.headers['x-cache-invalidate']); - var jsonResponse = res.body; - jsonResponse.should.exist; - jsonResponse.errors.should.exist; - testUtils.API.checkResponseValue(jsonResponse.errors[0], ['message', 'type']); - done(); - }); - }); - - it('can edit a user', function (done) { - request.get(testUtils.API.getApiQuery('users/me/')) - .set('Authorization', 'Bearer ' + accesstoken) - .expect('Content-Type', /json/) - .end(function (err, res) { - if (err) { - return done(err); - } - - var jsonResponse = res.body, - changedValue = 'joe-bloggs.ghost.org', - dataToSend; - jsonResponse.users[0].should.exist; - testUtils.API.checkResponse(jsonResponse.users[0], 'user', ['roles']); - - dataToSend = { users: [{website: changedValue}]}; - - request.put(testUtils.API.getApiQuery('users/me/')) - .set('Authorization', 'Bearer ' + accesstoken) - .send(dataToSend) - .expect('Content-Type', /json/) - .expect(200) - .end(function (err, res) { - if (err) { - return done(err); - } - - var putBody = res.body; - res.headers['x-cache-invalidate'].should.eql('/*'); - putBody.users[0].should.exist; - putBody.users[0].website.should.eql(changedValue); - putBody.users[0].email.should.eql(jsonResponse.users[0].email); - testUtils.API.checkResponse(putBody.users[0], 'user', ['roles']); - done(); - }); - }); - }); - - it('can\'t edit a user with invalid accesstoken', function (done) { - request.get(testUtils.API.getApiQuery('users/me/')) - .set('Authorization', 'Bearer ' + accesstoken) - .expect('Content-Type', /json/) - .end(function (err, res) { - if (err) { - return done(err); - } - - var jsonResponse = res.body, - changedValue = 'joe-bloggs.ghost.org'; - jsonResponse.users[0].should.exist; - jsonResponse.users[0].website = changedValue; - - request.put(testUtils.API.getApiQuery('users/me/')) - .set('Authorization', 'Bearer ' + 'invalidtoken') - .send(jsonResponse) - .expect(401) - .end(function (err, res) { - if (err) { - return done(err); - } - - done(); - }); - - }); + }); + }); }); }); \ No newline at end of file