diff --git a/tasks/gulp-tests.js b/tasks/gulp-tests.js index c0d18c99b0..9fb029366a 100644 --- a/tasks/gulp-tests.js +++ b/tasks/gulp-tests.js @@ -36,8 +36,8 @@ let testCount = (stdout, regexp) => { return parseInt(match && match[1] || 0); } -let testBin = (string) => { - return `NODE_ENV=testing ./node_modules/.bin/${string}`; +let testBin = (string, additionalEnvVariables = '') => { + return `NODE_ENV=testing ${additionalEnvVariables} ./node_modules/.bin/${string}`; }; gulp.task('test:prepare:mongo', (cb) => { @@ -354,7 +354,7 @@ gulp.task('test:api-v3:integration:watch', ['test:prepare:server'], () => { gulp.task('test:api-v3:safe', ['test:prepare:server'], (done) => { awaitPort(TEST_SERVER_PORT).then(() => { let runner = exec( - testBin(API_V3_TEST_COMMAND), + testBin(API_V3_TEST_COMMAND, 'API_VERSION=v3'), (err, stdout, stderr) => { testResults.push({ suite: 'API V3 Specs\t', diff --git a/test/api/v3/integration/user/auth/POST-register_local.test.js b/test/api/v3/integration/user/auth/POST-register_local.test.js new file mode 100644 index 0000000000..a8fa55f095 --- /dev/null +++ b/test/api/v3/integration/user/auth/POST-register_local.test.js @@ -0,0 +1,249 @@ +import { + generateUser, + requester, + translate as t, +} from '../../../../../helpers/api-integration.helper'; +import { v4 as generateRandomUserName } from 'uuid'; +import { each } from 'lodash'; + +describe.skip('POST /user/register/local', () => { + context('username and email are free', () => { + it('registers a new user', () => { + let api = requester(); + let username = generateRandomUserName(); + let email = `${username}@example.com`; + let password = 'password'; + + return api.post('/user/register/local', { + username: username, + email: email, + password: password, + confirmPassword: password, + }).then((user) => { + expect(user._id).to.exist; + expect(user.apiToken).to.exist; + expect(user.auth.local.username).to.eql(username); + }); + }); + + it('requires password and confirmPassword to match', () => { + let api = requester(); + let username = generateRandomUserName(); + let email = `${username}@example.com`; + let password = 'password'; + let confirmPassword = 'not password'; + + return expect(api.post('/user/register/local', { + username: username, + email: email, + password: password, + confirmPassword: confirmPassword, + })).to.eventually.be.rejected.and.eql({ + code: 401, + error: 'NotAuthorized', + message: t('passwordConfirmationMatch'), + }); + }); + + it('requires a username', () => { + let api = requester(); + let email = `${generateRandomUserName()}@example.com`; + let password = 'password'; + let confirmPassword = 'password'; + + return expect(api.post('/user/register/local', { + email: email, + password: password, + confirmPassword: confirmPassword, + })).to.eventually.be.rejected.and.eql({ + code: 401, + error: 'NotAuthorized', + message: t('missingUsernameEmail'), + }); + }); + + it('requires an email', () => { + let api = requester(); + let username = generateRandomUserName(); + let password = 'password'; + let confirmPassword = 'password'; + + return expect(api.post('/user/register/local', { + username: username, + password: password, + confirmPassword: confirmPassword, + })).to.eventually.be.rejected.and.eql({ + code: 401, + error: 'NotAuthorized', + message: t('missingUsernameEmail'), + }); + }); + + it('requires a password', () => { + let api = requester(); + let username = generateRandomUserName(); + let email = `${username}@example.com`; + let confirmPassword = 'password'; + + return expect(api.post('/user/register/local', { + username: username, + email: email, + confirmPassword: confirmPassword, + })).to.eventually.be.rejected.and.eql({ + code: 401, + error: 'NotAuthorized', + message: t('missingPassword'), + }); + }); + }); + + context('login is already taken', () => { + let username, email; + + beforeEach(() => { + username = generateRandomUserName(); + email = `${username}@example.com`; + return generateUser({ + 'auth.local.username': username, + 'auth.local.lowerCaseUsername': username, + 'auth.local.email': email + }); + }); + + it('rejects if username is already taken', () => { + let api = requester(); + let uniqueEmail = `${generateRandomUserName()}@exampe.com`; + let password = 'password'; + + return expect(api.post('/user/register/local', { + username: username, + email: uniqueEmail, + password: password, + confirmPassword: password, + })).to.eventually.be.rejected.and.eql({ + code: 401, + error: 'NotAuthorized', + message: t('usernameTake'), + }); + }); + + it('rejects if email is already taken', () => { + let api = requester(); + let uniqueUsername = generateRandomUserName(); + let password = 'password'; + + return expect(api.post('/user/register/local', { + username: uniqueUsername, + email: email, + password: password, + confirmPassword: password, + })).to.eventually.be.rejected.and.eql({ + code: 401, + error: 'NotAuthorized', + message: t('emailTaken'), + }); + }); + }); + + context('successful login via api', () => { + let api, username, email, password; + + beforeEach(() => { + api = requester(); + username = generateRandomUserName(); + email = `${username}@example.com`; + password = 'password'; + }); + + it('sets all site tour values to -2 (already seen)', () => { + return api.post('/user/register/local', { + username: username, + email: email, + password: password, + confirmPassword: password, + }).then((user) => { + expect(user.flags.tour).to.not.be.empty; + + each(user.flags.tour, (value, attribute) => { + expect(value).to.eql(-2); + }); + }); + }); + + it('populates user with default todos, not no other task types', () => { + return api.post('/user/register/local', { + username: username, + email: email, + password: password, + confirmPassword: password, + }).then((user) => { + expect(user.todos).to.not.be.empty; + expect(user.dailys).to.be.empty; + expect(user.habits).to.be.empty; + expect(user.rewards).to.be.empty; + }); + }); + + it('populates user with default tags', () => { + return api.post('/user/register/local', { + username: username, + email: email, + password: password, + confirmPassword: password, + }).then((user) => { + expect(user.tags).to.not.be.empty; + }); + }); + }); + + context('successful login with habitica-web header', () => { + let api, username, email, password; + + beforeEach(() => { + api = requester({}, {'x-client': 'habitica-web'}); + username = generateRandomUserName(); + email = `${username}@example.com`; + password = 'password'; + }); + + it('sets all common tutorial flags to true', () => { + return api.post('/user/register/local', { + username: username, + email: email, + password: password, + confirmPassword: password, + }).then((user) => { + expect(user.flags.tour).to.not.be.empty; + + each(user.flags.tutorial.common, (value, attribute) => { + expect(value).to.eql(true); + }); + }); + }); + + it('populates user with default todos, habits, and rewards', () => { + return api.post('/user/register/local', { + username: username, + email: email, + password: password, + confirmPassword: password, + }).then((user) => { + expect(user.todos).to.not.be.empty; + expect(user.dailys).to.be.empty; + expect(user.habits).to.not.be.empty; + expect(user.rewards).to.not.be.empty; + }); + }); + + it('populates user with default tags', () => { + return api.post('/user/register/local', { + username: username, + email: email, + password: password, + confirmPassword: password, + }).then((user) => { + expect(user.tags).to.not.be.empty; + }); + }); + }); +}); diff --git a/website/src/controllers/api-v3/user.js b/website/src/controllers/api-v3/user.js index 3cda3fd66a..0d347b17fb 100644 --- a/website/src/controllers/api-v3/user.js +++ b/website/src/controllers/api-v3/user.js @@ -5,7 +5,7 @@ import { NotAuthorized, } from '../../libs/api-v3/errors'; import passwordUtils from '../../libs/api-v3/password'; -import User from '../../models/user'; +import { model as User } from '../../models/user'; import EmailUnsubscription from '../../models/emailUnsubscription'; import { sendTxn as sendTxnEmail } from '../../libs/api-v3/email';