1
0
Fork 0

wip(backend): Fixed async issues with tests

This commit is contained in:
joostdecock 2022-11-10 20:09:30 +01:00
parent 73ee7cceb3
commit f8e1fed09a
9 changed files with 116 additions and 135 deletions

View file

@ -1,4 +1,5 @@
{ {
"verbose": true, "verbose": true,
"ignore": ["tests/**.test.mjs"] "ignore": ["tests/**.test.mjs"],
"watch": ["src/**"]
} }

View file

@ -48,6 +48,7 @@ model User {
email String email String
github String @default("") github String @default("")
ihash String ihash String
img String @default("https://freesewing.org/avatar.svg")
initial String initial String
imperial Boolean @default(false) imperial Boolean @default(false)
language String @default("en") language String @default("en")

Binary file not shown.

View file

@ -306,6 +306,7 @@ UserModel.prototype.safeUpdate = async function (data) {
process.exit() process.exit()
return this.setResponse(500, 'updateUserFailed') return this.setResponse(500, 'updateUserFailed')
} }
await this.reveal()
return this.setResponse(200) return this.setResponse(200)
} }
@ -331,8 +332,6 @@ UserModel.prototype.unsafeUpdate = async function (body) {
if ([true, false].includes(body.newsletter)) data.newsletter = body.newsletter if ([true, false].includes(body.newsletter)) data.newsletter = body.newsletter
// Password // Password
if (typeof body.password === 'string') data.password = body.password // Will be cloaked below if (typeof body.password === 'string') data.password = body.password // Will be cloaked below
// Patron
if ([0, 2, 4, 8].includes(body.patron)) data.patron = body.patron
// Username // Username
if (typeof body.username === 'string') { if (typeof body.username === 'string') {
const available = await this.isLusernameAvailable(body.username) const available = await this.isLusernameAvailable(body.username)
@ -410,11 +409,15 @@ UserModel.prototype.unsafeUpdate = async function (body) {
UserModel.prototype.asAccount = function () { UserModel.prototype.asAccount = function () {
return { return {
id: this.record.id, id: this.record.id,
bio: this.clear.bio,
consent: this.record.consent, consent: this.record.consent,
createdAt: this.record.createdAt, createdAt: this.record.createdAt,
data: this.clear.data, data: this.clear.data,
email: this.clear.email, email: this.clear.email,
github: this.clear.github,
imperial: this.record.imperial,
initial: this.clear.initial, initial: this.clear.initial,
language: this.record.language,
lastLogin: this.record.lastLogin, lastLogin: this.record.lastLogin,
newsletter: this.record.newsletter, newsletter: this.record.newsletter,
patron: this.record.patron, patron: this.record.patron,

View file

@ -1,6 +1,4 @@
export const accountTests = async (config, store, chai) => { export const accountTests = async (chai, config, expect, store) => {
const expect = chai.expect
/* /*
consent Int @default(0) consent Int @default(0)
data String @default("{}") data String @default("{}")

View file

@ -1,6 +1,4 @@
export const apikeyTests = async (config, store, chai) => { export const apikeyTests = async (chai, config, expect, store) => {
const expect = chai.expect
describe(`${store.icon('key')} API Key create/read/delete`, () => { describe(`${store.icon('key')} API Key create/read/delete`, () => {
step(`${store.icon('key', 'jwt')} Create API Key (jwt)`, (done) => { step(`${store.icon('key', 'jwt')} Create API Key (jwt)`, (done) => {
chai chai

View file

@ -1,41 +1,16 @@
import dotenv from 'dotenv'
import chai from 'chai'
import http from 'chai-http'
import { verifyConfig } from '../src/config.mjs'
import { randomString } from '../src/utils/crypto.mjs'
import { userTests } from './user.mjs' import { userTests } from './user.mjs'
import { accountTests } from './account.mjs' import { accountTests } from './account.mjs'
import { apikeyTests } from './apikey.mjs' import { apikeyTests } from './apikey.mjs'
import { setup } from './shared.mjs' import { setup } from './shared.mjs'
dotenv.config() const runTests = async (...params) => {
await userTests(...params)
const config = verifyConfig() await apikeyTests(...params)
const expect = chai.expect await accountTests(...params)
chai.use(http)
// Account data
const store = {
account: {
email: `test_${randomString()}@${config.tests.domain}`,
language: 'en',
password: randomString(),
},
icons: {
user: '🧑 ',
jwt: '🎫 ',
key: '🎟️ ',
},
}
store.icon = (icon1, icon2 = false) => store.icons[icon1] + (icon2 ? store.icons[icon2] : '')
// Run tests
const runTests = async (config, store, chai) => {
await setup(config, store, chai)
await userTests(config, store, chai)
await apikeyTests(config, store, chai)
//await accountTests(config, store, chai)
} }
// Do the work // Load initial data required for tests
runTests(config, store, chai) const { chai, config, expect, store } = await setup()
// Note run the tests using this data
runTests(chai, config, expect, store)

View file

@ -1,94 +1,84 @@
export const setup = async function (config, store, chai) { import dotenv from 'dotenv'
const expect = chai.expect import axios from 'axios'
const icon = '🚀' import chai from 'chai'
import http from 'chai-http'
import { verifyConfig } from '../src/config.mjs'
import { randomString } from '../src/utils/crypto.mjs'
// Shared state dotenv.config()
describe(`${icon} Initial setup of user accounts`, async function () {
step(`${icon} Should signup new user ${store.account.email}`, (done) => {
chai
.request(config.api)
.post('/signup')
.send({
email: store.account.email,
language: store.account.language,
unittest: true,
})
.end((err, res) => {
expect(res.status).to.equal(201)
expect(res.type).to.equal('application/json')
expect(res.charset).to.equal('utf-8')
expect(res.body.result).to.equal(`success`)
expect(res.body.email).to.equal(store.account.email)
store.account.confirmation = res.body.confirmation
done()
})
})
step(`${icon} Should confirm new user (${store.account.email})`, (done) => { const config = verifyConfig()
chai const expect = chai.expect
.request(config.api) chai.use(http)
.post(`/confirm/signup/${store.account.confirmation}`)
.send({ consent: 1 })
.end((err, res) => {
expect(res.status).to.equal(200)
expect(res.type).to.equal('application/json')
expect(res.charset).to.equal('utf-8')
expect(res.body.result).to.equal(`success`)
expect(typeof res.body.token).to.equal(`string`)
expect(typeof res.body.account.id).to.equal(`number`)
store.account.token = res.body.token
store.account.username = res.body.account.username
store.account.userid = res.body.account.id
done()
})
})
step(`${icon} Should create API Key`, (done) => { export const setup = async () => {
chai // Initial store contents
.request(config.api) const store = {
.post('/apikey/jwt') chai,
.set('Authorization', 'Bearer ' + store.account.token) expect,
.send({ config,
name: 'Test API key', account: {
level: 4, email: `test_${randomString()}@${config.tests.domain}`,
expiresIn: 60, language: 'en',
}) password: randomString(),
.end((err, res) => { },
expect(res.status).to.equal(201) icons: {
expect(res.type).to.equal('application/json') user: '🧑 ',
expect(res.charset).to.equal('utf-8') jwt: '🎫 ',
expect(res.body.result).to.equal(`created`) key: '🎟️ ',
expect(typeof res.body.apikey.key).to.equal('string') },
expect(typeof res.body.apikey.secret).to.equal('string') }
expect(typeof res.body.apikey.expiresAt).to.equal('string') store.icon = (icon1, icon2 = false) => store.icons[icon1] + (icon2 ? store.icons[icon2] : '')
expect(res.body.apikey.level).to.equal(4)
store.apikey = res.body.apikey
done()
})
})
step(`${store.icon('user')} Should set the initial password`, (done) => { // Get confirmation ID
chai let result
.request(config.api) try {
.put('/account/jwt') result = await axios.post(`${store.config.api}/signup`, {
.set('Authorization', 'Bearer ' + store.account.token) email: store.account.email,
.send({ language: store.account.language,
password: store.account.password, unittest: true,
})
.end((err, res) => {
expect(res.status).to.equal(200)
expect(res.type).to.equal('application/json')
expect(res.charset).to.equal('utf-8')
expect(res.body.result).to.equal(`success`)
expect(res.body.account.email).to.equal(store.account.email)
expect(res.body.account.username).to.equal(store.account.username)
expect(res.body.account.lusername).to.equal(store.account.username.toLowerCase())
expect(typeof res.body.account.id).to.equal(`number`)
store.token = res.body.token
done()
})
}) })
}) } catch (err) {
console.log('Failed at first setup request', err)
process.exit()
}
store.account.confirmation = result.data.confirmation
// Confirm account
try {
result = await axios.post(`${store.config.api}/confirm/signup/${store.account.confirmation}`, {
consent: 1,
})
} catch (err) {
console.log('Failed at account confirmation request', err)
process.exit()
}
store.account.token = result.data.token
store.account.username = result.data.account.username
store.account.userid = result.data.account.id
// Create API key
try {
result = await axios.post(
`${store.config.api}/apikey/jwt`,
{
name: 'Test API key',
level: 4,
expiresIn: 60,
},
{
headers: {
authorization: `Bearer ${store.account.token}`,
},
}
)
} catch (err) {
console.log('Failed at API key creation request', err)
process.exit()
}
store.account.apikey = result.data.apikey
return { chai, config, expect, store }
} }
export const teardown = async function (store) { export const teardown = async function (store) {

View file

@ -1,9 +1,6 @@
export const userTests = async (config, store, chai) => { export const userTests = async (chai, config, expect, store) => {
const expect = chai.expect describe(`${store.icon('user')} Signup flow and authentication`, () => {
it(`${store.icon('user')} Should return 400 on signup without body`, (done) => {
describe(`${store.icon('user')} Signup flow and authentication`, async function () {
it(`${store.icon('user')} Should return 400 on signup without body`, function (done) {
this.store = store
chai chai
.request(config.api) .request(config.api)
.post('/signup') .post('/signup')
@ -78,6 +75,23 @@ export const userTests = async (config, store, chai) => {
}) })
}) })
// Note that password was not set at account creation
step(`${store.icon('user')} Should set the password`, (done) => {
chai
.request(config.api)
.put('/account/jwt')
.set('Authorization', 'Bearer ' + store.account.token)
.send({
password: store.account.password,
})
.end((err, res) => {
expect(res.status).to.equal(200)
expect(res.type).to.equal('application/json')
expect(res.charset).to.equal('utf-8')
done()
})
})
step(`${store.icon('user')} 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)
@ -192,6 +206,7 @@ export const userTests = async (config, store, chai) => {
done() done()
}) })
}) })
step(`${store.icon('user', 'jwt')} Should load account (jwt)`, (done) => { step(`${store.icon('user', 'jwt')} Should load account (jwt)`, (done) => {
chai chai
.request(config.api) .request(config.api)