From 52dc8768455b7cf2b2a5423fe79588529da65cde Mon Sep 17 00:00:00 2001 From: Jerko Steiner Date: Sun, 27 Jan 2019 16:07:16 +0100 Subject: [PATCH] Add ability to specify query params in tests --- packages/common/src/IRequestQuery.ts | 3 + packages/common/src/URLFormatter.ts | 14 ++++- packages/server/src/site/SiteRoutes.test.ts | 16 +++-- packages/server/src/site/SiteService.ts | 2 + packages/server/src/site/SiteTestUtils.ts | 4 +- packages/server/src/story/StoryRoutes.test.ts | 62 +++++++++++-------- packages/server/src/team/TeamRoutes.test.ts | 4 +- .../server/src/test-utils/RequestTester.ts | 28 ++++++--- 8 files changed, 92 insertions(+), 41 deletions(-) create mode 100644 packages/common/src/IRequestQuery.ts diff --git a/packages/common/src/IRequestQuery.ts b/packages/common/src/IRequestQuery.ts new file mode 100644 index 0000000..a10429d --- /dev/null +++ b/packages/common/src/IRequestQuery.ts @@ -0,0 +1,3 @@ +export interface IRequestQuery { + [key: string]: string | number +} diff --git a/packages/common/src/URLFormatter.ts b/packages/common/src/URLFormatter.ts index c383c48..0996545 100644 --- a/packages/common/src/URLFormatter.ts +++ b/packages/common/src/URLFormatter.ts @@ -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 } diff --git a/packages/server/src/site/SiteRoutes.test.ts b/packages/server/src/site/SiteRoutes.test.ts index 0fae056..406d583 100644 --- a/packages/server/src/site/SiteRoutes.test.ts +++ b/packages/server/src/site/SiteRoutes.test.ts @@ -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) }) diff --git a/packages/server/src/site/SiteService.ts b/packages/server/src/site/SiteService.ts index 8ca5481..b98a5b2 100644 --- a/packages/server/src/site/SiteService.ts +++ b/packages/server/src/site/SiteService.ts @@ -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) } diff --git a/packages/server/src/site/SiteTestUtils.ts b/packages/server/src/site/SiteTestUtils.ts index 2177e2f..401337e 100644 --- a/packages/server/src/site/SiteTestUtils.ts +++ b/packages/server/src/site/SiteTestUtils.ts @@ -6,7 +6,9 @@ export async function createSite(t: RequestTester, 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, diff --git a/packages/server/src/story/StoryRoutes.test.ts b/packages/server/src/story/StoryRoutes.test.ts index 730e92b..f05ec00 100644 --- a/packages/server/src/story/StoryRoutes.test.ts +++ b/packages/server/src/story/StoryRoutes.test.ts @@ -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 () => { -// }) -// }) + }) + }) -// }) +}) diff --git a/packages/server/src/team/TeamRoutes.test.ts b/packages/server/src/team/TeamRoutes.test.ts index 37c7ed7..162f1d4 100644 --- a/packages/server/src/team/TeamRoutes.test.ts +++ b/packages/server/src/team/TeamRoutes.test.ts @@ -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) diff --git a/packages/server/src/test-utils/RequestTester.ts b/packages/server/src/test-utils/RequestTester.ts index f17d7c0..c3b1be9 100644 --- a/packages/server/src/test-utils/RequestTester.ts +++ b/packages/server/src/test-utils/RequestTester.ts @@ -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 { } request( - method: M, path: P, params?: IRequestParams, + method: M, path: P, options: IRequestOptions = {}, ) : IRequest { - 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 { return test } - get

(path: P, params?: IRequestParams) { - return this.request('get', path, params) + get

( + path: P, + options?: IRequestOptions, + ) { + return this.request('get', path, options) } - post

(path: P, params?: IRequestParams) { - return this.request('post', path, params) + post

( + path: P, + options?: IRequestOptions, + ) { + return this.request('post', path, options) } }