Add ability to specify query params in tests

This commit is contained in:
Jerko Steiner 2019-01-27 16:07:16 +01:00
parent 04b3a7ca90
commit 52dc876845
8 changed files with 92 additions and 41 deletions

View File

@ -0,0 +1,3 @@
export interface IRequestQuery {
[key: string]: string | number
}

View File

@ -1,5 +1,6 @@
import assert from 'assert'
import {IRequestParams} from './IRequestParams'
import {IRequestQuery} from './IRequestQuery'
export interface IURLFormatterOptions {
readonly baseURL: string
@ -12,7 +13,11 @@ export class URLFormatter {
regex: /:[a-zA-Z0-9-]+/g,
}) {}
format(url: string, params?: IRequestParams) {
format(
url: string,
params?: IRequestParams,
query?: IRequestQuery,
) {
if (!params) {
return url
}
@ -21,6 +26,13 @@ export class URLFormatter {
assert(params.hasOwnProperty(key))
return String(params![key])
})
if (query) {
Object.keys(query).reduce((queryString, key) => {
return queryString +
encodeURIComponent(key) + '=' +
encodeURIComponent(String(query[key])) + '&'
}, '?')
}
return this.params.baseURL + formattedUrl
}

View File

@ -40,7 +40,11 @@ describe('team', () => {
it('results with 403 when user does not have team access ', async () => {
await t
.post('/teams/:teamId/sites', {teamId: team.id})
.post('/teams/:teamId/sites', {
params: {
teamId: team.id,
},
})
.send({
domain: 'test.example.com',
name: 'test',
@ -55,8 +59,10 @@ describe('team', () => {
it('fetches a site belonging to a team', async () => {
const site = await createSite(t, 'test.example.com')
const response = await t.get('/teams/:teamId/sites/:id', {
teamId: site.teamId,
id: site.id,
params: {
teamId: site.teamId,
id: site.id,
},
})
.expect(200)
expect(response.body!.id).toEqual(site.id)
@ -67,7 +73,9 @@ describe('team', () => {
it('fetches all sites belonging to a team', async () => {
const site = await createSite(t, 'test.example.com')
const response = await t.get('/teams/:teamId/sites', {
teamId: site.teamId,
params: {
teamId: site.teamId,
},
})
expect(response.body.map(s => s.id)).toContain(site.id)
})

View File

@ -5,6 +5,8 @@ import {Site} from '../entities/Site'
export class SiteService extends BaseService implements ISiteService {
async create(params: ISiteCreateParams) {
// TODO validate params.domain
// TODO check site limit per user
return this.getRepository(Site).save(params)
}

View File

@ -6,7 +6,9 @@ export async function createSite(t: RequestTester<IAPIDef>, domain: string) {
const team = await createTeam(t, 'test')
const response = await t
.post('/teams/:teamId/sites', {
teamId: team.id,
params: {
teamId: team.id,
},
})
.send({
domain,

View File

@ -1,40 +1,48 @@
// import {ISite, IStory} from '@rondo/common'
// import {createTeam} from '../team/TeamTestUtils'
// import {test} from '../test'
import {ISite/*, IStory*/} from '@rondo/common'
import {createSite} from '../site/SiteTestUtils'
import {test} from '../test'
// describe('team', () => {
describe('story', () => {
// test.withDatabase()
// const t = test.request('/api')
test.withDatabase()
const t = test.request('/api')
// let cookie!: string
// let token!: string
// let team!: ITeam
// beforeEach(async () => {
// const session = await test.registerAccount()
// cookie = session.cookie
// token = session.token
// t.setHeaders({ cookie, 'x-csrf-token': token })
let cookie!: string
let token!: string
let team!: ISite
beforeEach(async () => {
const session = await test.registerAccount()
cookie = session.cookie
token = session.token
t.setHeaders({ cookie, 'x-csrf-token': token })
// team = await createTeam(t, 'test')
// })
team = await createSite(t, 'test.example.com')
})
// describe('/stories/by-url', () => {
// it('returns undefined when a site is not configured', async () => {
const invalidUrl = 'https://invalid.example.com/test'
// const validUrl = 'https://test.example.com/test'
// })
describe('/stories/by-url', () => {
it('returns undefined when a site is not configured', async () => {
const response = await t
.get('/stories/by-url', {
query: { url: invalidUrl },
})
.expect(200)
expect(response.body).toEqual('')
})
// it('creates a story when it does not exist', async () => {
it('creates a story when it does not exist', async () => {
// })
})
// it('retrieves existing story after it is created', async () => {
it('retrieves existing story after it is created', async () => {
// })
})
// it('prevents unique exceptions', async () => {
it('prevents unique exceptions', async () => {
// })
// })
})
})
// })
})

View File

@ -27,7 +27,9 @@ describe('team', () => {
const team = await createTeam(t, 'test')
const response = await t
.get('/teams/:id', {
id: team.id,
params: {
id: team.id,
},
})
.expect(200)
expect(response.body).toEqual(team)

View File

@ -1,7 +1,6 @@
import supertest from 'supertest'
import {
IMethod,
IRequestParams,
IRoutes,
URLFormatter,
} from '@rondo/common'
@ -35,6 +34,15 @@ interface IRequest<
// type definition
}
interface IRequestOptions<
R extends IRoutes,
P extends keyof R,
M extends IMethod,
> {
params?: R[P][M]['params'],
query?: R[P][M]['query'],
}
export interface IHeaders {
[key: string]: string
}
@ -55,10 +63,10 @@ export class RequestTester<R extends IRoutes> {
}
request<M extends IMethod, P extends keyof R & string>(
method: M, path: P, params?: IRequestParams,
method: M, path: P, options: IRequestOptions<R, P, 'post'> = {},
)
: IRequest<R, P, M> {
const url = this.formatter.format(path, params)
const url = this.formatter.format(path, options.params, options.query)
const test = supertest(this.app)[method](`${this.baseUrl}${url}`)
Object.keys(this.headers).forEach(key => {
test.set(key, this.headers[key])
@ -66,11 +74,17 @@ export class RequestTester<R extends IRoutes> {
return test
}
get<P extends keyof R & string>(path: P, params?: IRequestParams) {
return this.request('get', path, params)
get<P extends keyof R & string>(
path: P,
options?: IRequestOptions<R, P, 'get'>,
) {
return this.request('get', path, options)
}
post<P extends keyof R & string>(path: P, params?: IRequestParams) {
return this.request('post', path, params)
post<P extends keyof R & string>(
path: P,
options?: IRequestOptions<R, P, 'post'>,
) {
return this.request('post', path, options)
}
}