1
0
Fork 0

wip(backend): More tests

This commit is contained in:
joostdecock 2022-11-07 19:50:51 +01:00
parent ca064a2988
commit 080385d2bc
7 changed files with 64 additions and 37 deletions

View file

@ -4,7 +4,7 @@
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"dev": "nodemon src/index.mjs", "dev": "nodemon src/index.mjs",
"test": "npx mocha --require mocha-steps tests/*.test.mjs", "test": "npx mocha --require mocha-steps tests/index.mjs",
"initdb": "npx prisma db push", "initdb": "npx prisma db push",
"newdb": "node ./scripts/newdb.mjs", "newdb": "node ./scripts/newdb.mjs",
"rmdb": "node ./scripts/rmdb.mjs", "rmdb": "node ./scripts/rmdb.mjs",

View file

@ -20,7 +20,9 @@ const config = {
url: process.env.API_DB_URL, url: process.env.API_DB_URL,
}, },
tests: { tests: {
domain: process.env.TESTDOMAIN || 'mailtrap.freesewing.dev', allow: process.env.ALLOW_UNITTESTS || false,
domain: process.env.TESTDOMAIN || 'freesewing.dev',
sendEmail: process.env.SEND_UNITTEST_EMAILS || false,
}, },
static: process.env.API_STATIC, static: process.env.API_STATIC,
storage: process.env.API_STORAGE, storage: process.env.API_STORAGE,

View file

@ -26,7 +26,7 @@ ApikeyModel.prototype.setResponse = function (status = 200, error = false, data
}, },
} }
if (status === 201) this.response.body.result = 'created' if (status === 201) this.response.body.result = 'created'
else if (status > 201) { else if (status > 204) {
this.response.body.error = error this.response.body.error = error
this.response.body.result = 'error' this.response.body.result = 'error'
this.error = true this.error = true
@ -80,6 +80,7 @@ ApikeyModel.prototype.removeIfAllowed = async function (where, user) {
} }
} }
await this.remove(where) await this.remove(where)
this.setResponse(204)
return this.setResponse(204) return this.setResponse(204)
} }

View file

@ -117,18 +117,19 @@ UserModel.prototype.create = async function ({ body }) {
}) })
// Send signup email // Send signup email
await this.mailer.send({ if (!this.isUnitTest(body) || this.config.tests.sendEmail)
template: 'signup', await this.mailer.send({
language: this.language, template: 'signup',
to: this.email, language: this.language,
replacements: { to: this.email,
actionUrl: i18nUrl(this.language, `/confirm/signup/${this.Confirmation.record.id}`), replacements: {
whyUrl: i18nUrl(this.language, `/docs/faq/email/why-signup`), actionUrl: i18nUrl(this.language, `/confirm/signup/${this.Confirmation.record.id}`),
supportUrl: i18nUrl(this.language, `/patrons/join`), whyUrl: i18nUrl(this.language, `/docs/faq/email/why-signup`),
}, supportUrl: i18nUrl(this.language, `/patrons/join`),
}) },
})
return body.unittest && this.email.split('@').pop() === this.config.tests.domain return this.isUnitTest(body)
? this.setResponse(201, false, { email: this.email, confirmation: this.confirmation.record.id }) ? this.setResponse(201, false, { email: this.email, confirmation: this.confirmation.record.id })
: this.setResponse(201, false, { email: this.email }) : this.setResponse(201, false, { email: this.email })
} }
@ -268,3 +269,11 @@ UserModel.prototype.setResponse = function (status = 200, error = false, data =
UserModel.prototype.sendResponse = async function (res) { UserModel.prototype.sendResponse = async function (res) {
return res.status(this.response.status).send(this.response.body) return res.status(this.response.status).send(this.response.body)
} }
/*
* Update method to determine whether this request is
* part of a unit test
*/
UserModel.prototype.isUnitTest = function (body) {
return body.unittest && this.email.split('@').pop() === this.config.tests.domain
}

View file

@ -1,9 +1,8 @@
export const apikeyTests = async (config, store, chai) => { export const apikeyTests = async (config, store, chai) => {
const expect = chai.expect const expect = chai.expect
const icon = '🎟️ '
describe(`${icon} API Key create/read/delete`, () => { describe(`${store.icon('key')} API Key create/read/delete`, () => {
step(`${icon} Create API Key`, (done) => { step(`${store.icon('key', 'jwt')} Create API Key (jwt)`, (done) => {
chai chai
.request(config.api) .request(config.api)
.post('/apikey/jwt') .post('/apikey/jwt')
@ -27,7 +26,7 @@ export const apikeyTests = async (config, store, chai) => {
}) })
}) })
step(`${icon} Create API Key with KEY`, (done) => { step(`${store.icon('key', 'key')} Create API Key (key)`, (done) => {
chai chai
.request(config.api) .request(config.api)
.post('/apikey/key') .post('/apikey/key')
@ -51,7 +50,7 @@ export const apikeyTests = async (config, store, chai) => {
}) })
}) })
step(`${icon} Read API Key with KEY (whoami)`, (done) => { step(`${store.icon('key', 'key')} Read API key via whoami (key)`, (done) => {
chai chai
.request(config.api) .request(config.api)
.get(`/whoami/key`) .get(`/whoami/key`)
@ -67,7 +66,7 @@ export const apikeyTests = async (config, store, chai) => {
}) })
}) })
step(`${icon} Read API Key with KEY`, (done) => { step(`${store.icon('key', 'key')} Read API key (key)`, (done) => {
chai chai
.request(config.api) .request(config.api)
.get(`/apikey/${store.apikey1.key}/key`) .get(`/apikey/${store.apikey1.key}/key`)
@ -83,11 +82,11 @@ export const apikeyTests = async (config, store, chai) => {
}) })
}) })
step(`${icon} Read API Key with JWT`, (done) => { step(`${store.icon('key', 'jwt')} Read API key (jwt)`, (done) => {
chai chai
.request(config.api) .request(config.api)
.get(`/apikey/${store.apikey2.key}/jwt`) .get(`/apikey/${store.apikey2.key}/jwt`)
.set('Authorization', 'Bearer ' + store.token) .set('Authorization', 'Bearer ' + store.account.token)
.end((err, res) => { .end((err, res) => {
expect(res.status).to.equal(200) expect(res.status).to.equal(200)
expect(res.type).to.equal('application/json') expect(res.type).to.equal('application/json')
@ -99,7 +98,7 @@ export const apikeyTests = async (config, store, chai) => {
}) })
}) })
step(`${icon} Remove API Key with KEY`, (done) => { step(`${store.icon('key', 'key')} Remove API key (key)`, (done) => {
chai chai
.request(config.api) .request(config.api)
.delete(`/apikey/${store.apikey2.key}/key`) .delete(`/apikey/${store.apikey2.key}/key`)
@ -109,5 +108,16 @@ export const apikeyTests = async (config, store, chai) => {
done() done()
}) })
}) })
step(`${store.icon('key', 'jwt')} Remove API key (jwt)`, (done) => {
chai
.request(config.api)
.delete(`/apikey/${store.apikey1.key}/jwt`)
.set('Authorization', 'Bearer ' + store.account.token)
.end((err, res) => {
expect(res.status).to.equal(204)
done()
})
})
}) })
} }

View file

@ -20,12 +20,18 @@ const store = {
language: 'en', language: 'en',
password: randomString(), password: randomString(),
}, },
icons: {
user: '🧑 ',
jwt: '🎫 ',
key: '🎟️ ',
},
} }
store.icon = (icon1, icon2 = false) => store.icons[icon1] + (icon2 ? store.icons[icon2] : '')
// Run tests // Run tests
const runTests = async (config, store, chai) => { const runTests = async (config, store, chai) => {
await setup(config, store, chai) await setup(config, store, chai)
await userTests(config, store, chai) //await userTests(config, store, chai)
await apikeyTests(config, store, chai) await apikeyTests(config, store, chai)
} }

View file

@ -1,9 +1,8 @@
export const userTests = async (config, store, chai) => { export const userTests = async (config, store, chai) => {
const expect = chai.expect const expect = chai.expect
const icon = '🧑'
describe(`${icon} Signup flow and authentication`, async function () { describe(`${store.icon('user')} Signup flow and authentication`, async function () {
it(`${icon} Should return 400 on signup without body`, function (done) { it(`${store.icon('user')} Should return 400 on signup without body`, function (done) {
this.store = store this.store = store
chai chai
.request(config.api) .request(config.api)
@ -24,7 +23,7 @@ export const userTests = async (config, store, chai) => {
language: 'fr', language: 'fr',
} }
Object.keys(fields).map((key) => { Object.keys(fields).map((key) => {
it(`${icon} Should not allow signup without ${key}`, (done) => { it(`${store.icon('user')} Should not allow signup without ${key}`, (done) => {
chai chai
.request(config.api) .request(config.api)
.post('/signup') .post('/signup')
@ -47,7 +46,7 @@ export const userTests = async (config, store, chai) => {
}) })
}) })
step(`${icon} Should fail to signup an existing email address`, (done) => { step(`${store.icon('user')} Should fail to signup an existing email address`, (done) => {
chai chai
.request(config.api) .request(config.api)
.post('/signup') .post('/signup')
@ -62,7 +61,7 @@ export const userTests = async (config, store, chai) => {
}) })
}) })
step(`${icon} Should not login with the wrong password`, (done) => { step(`${store.icon('user')} Should not login with the wrong password`, (done) => {
chai chai
.request(config.api) .request(config.api)
.post('/login') .post('/login')
@ -80,7 +79,7 @@ export const userTests = async (config, store, chai) => {
}) })
}) })
step(`${icon} Should login with username and password`, (done) => { step(`${store.icon('user')} Should login with username and password`, (done) => {
chai chai
.request(config.api) .request(config.api)
.post('/login') .post('/login')
@ -103,7 +102,7 @@ export const userTests = async (config, store, chai) => {
}) })
}) })
step(`${icon} Should login with USERNAME and password`, (done) => { step(`${store.icon('user')} Should login with USERNAME and password`, (done) => {
chai chai
.request(config.api) .request(config.api)
.post('/login') .post('/login')
@ -126,7 +125,7 @@ export const userTests = async (config, store, chai) => {
}) })
}) })
step(`${icon} Should login with email and password`, (done) => { step(`${store.icon('user')} Should login with email and password`, (done) => {
chai chai
.request(config.api) .request(config.api)
.post('/login') .post('/login')
@ -149,7 +148,7 @@ export const userTests = async (config, store, chai) => {
}) })
}) })
step(`${icon} Should login with EMAIL and password`, (done) => { step(`${store.icon('user')} Should login with EMAIL and password`, (done) => {
chai chai
.request(config.api) .request(config.api)
.post('/login') .post('/login')
@ -172,7 +171,7 @@ export const userTests = async (config, store, chai) => {
}) })
}) })
step(`${icon} Should login with userid and password`, (done) => { step(`${store.icon('user')} Should login with userid and password`, (done) => {
chai chai
.request(config.api) .request(config.api)
.post('/login') .post('/login')
@ -195,7 +194,7 @@ export const userTests = async (config, store, chai) => {
}) })
}) })
step(`${icon} Should load account with JWT`, (done) => { step(`${store.icon('user', 'jwt')} Should load account (jwt)`, (done) => {
chai chai
.request(config.api) .request(config.api)
.get('/account/jwt') .get('/account/jwt')
@ -213,7 +212,7 @@ export const userTests = async (config, store, chai) => {
}) })
}) })
step(`${icon} Should load account with JWT (whoami)`, (done) => { step(`${store.icon('user', 'jwt')} Should load account via whoami (jwt)`, (done) => {
chai chai
.request(config.api) .request(config.api)
.get('/whoami/jwt') .get('/whoami/jwt')