Skip to content

Commit

Permalink
Merge pull request #77 from kekcuuuk/support-dynamic-extend-response
Browse files Browse the repository at this point in the history
Add support dynamic extend response in UserInterceptors
  • Loading branch information
Diokuz authored Mar 31, 2023
2 parents 91461f7 + d310fa1 commit e9953ff
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 31 deletions.
24 changes: 24 additions & 0 deletions __teremocks__/some_name/get-q-click.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"request": {
"url": "http://localhost:3000/api?q=click",
"method": "GET",
"headers": {
"referer": "http://localhost:3000/"
},
"body": null,
"resourceType": "fetch"
},
"response": {
"url": "http://localhost:3000/api?q=click",
"status": 200,
"headers": {
"content-type": "application/json; charset=utf-8",
"access-control-allow-origin": "*",
"connection": "keep-alive",
"keep-alive": "timeout=5"
},
"body": {
"suggest": "click"
}
}
}
54 changes: 52 additions & 2 deletions __tests__/generator.pw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import path from 'path'
import { expect, test as base } from '@playwright/test'
import rimraf from 'rimraf'
import sinon from 'sinon'
import { Teremock, parseUrl } from '../index'
import { parseUrl, Teremock, UserInterceptor } from '../index'

import type { Request } from '../src/types'

Expand All @@ -14,7 +14,7 @@ async function sleep(time: number): Promise<void> {
}

const test = base.extend<{ teremock: Teremock }, { cleanup: void }>({
teremock: async ({ page }, use) => {
teremock: async ({ page: _page }, use) => {
const teremock = new Teremock()
await use(teremock)
await teremock.stop()
Expand Down Expand Up @@ -236,6 +236,56 @@ test.describe('teremock puppeteer', async () => {
await teremock.stop()
})

test('capture GET request for /api and extend response', async ({ page }) => {
await page.goto('http://localhost:3000')

const interceptors: Record<string, UserInterceptor> = {
some_name: {
methods: new Set(['*']),
resourceTypes: new Set(['*']),
pass: false,
url: '/api',
response: async (_, res) => {
if (!res) {
return {}
}

return {
body: {
...res.body,
suggest: [res.body?.suggest, 'one more suggest'],
},
}
},
},
}

// * Starting mocker with wildcard interceptor
// @ts-ignore
const teremock = new Teremock()
await teremock.start({ page, interceptors, ci: false })

// * Invoking GET request to `/api`
await page.click('#button')
await sleep(100)

const text = await page.evaluate((element) => element?.textContent, await page.$('#button'))

// before mock we can't modify response. Check base response
expect(text).toBe('200 click')

// * Invoking GET request to `/api`
await page.click('#button')
await sleep(100)


const textAfterMock = await page.evaluate((element) => element?.textContent, await page.$('#button'))

expect(textAfterMock).toBe('200 click,one more suggest')

await teremock.stop()
})

test('dont capture GET request for /api when methods are ["post"]', async ({ page, teremock }) => {
await page.goto('http://localhost:3000')

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "teremock",
"version": "2.0.8",
"version": "2.1.0",
"description": "File-based real mocks request mocker for playwright",
"repository": {
"type": "git",
Expand Down
57 changes: 31 additions & 26 deletions src/handleRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface BeforeRespondArg {
respond: (response: Response, interceptor: Interceptor) => Promise<void>
request: Request
response: DefResponse
mockedResponse?: Response
responseOverrides?: Partial<Response>
interceptor: Interceptor
mog: Function
Expand All @@ -35,6 +36,7 @@ async function beforeRespond({
respond,
request,
response,
mockedResponse,
mog,
interceptor,
increment,
Expand All @@ -48,7 +50,7 @@ async function beforeRespond({
query: getQuery(request.url),
}
mog(`» response is a function, responding with its returns`)
partResp = await response(argRequest)
partResp = await response(argRequest, mockedResponse)
mog(`» response() returns`, partResp)
} else {
partResp = response
Expand Down Expand Up @@ -130,13 +132,21 @@ export default function createHandler(initialParams: Params) {
reqSet.add(mockId)
mog('» reqSet is', Array.from(reqSet.get()))

if (interceptor.response) {
loggerTrace(`${request.url} ← inline response`)
mog(`» interceptor.response defined, responding with it`)
// mocks from storage
mog(`» trying to get mock with id "${mockId}"`)

if (await storage.has(mockId)) {
mog(`» mock "${mockId}" exists!`)

const mock = await storage.get(mockId)

loggerTrace(`${request.url} ← mock ${mockId} found in storage`)
mog(`» successfully read from "${mockId}", responding`)

await beforeRespond({
request,
response: interceptor.response,
response: interceptor.response || mock.response,
mockedResponse: mock.response,
responseOverrides,
respond,
interceptor,
Expand All @@ -147,37 +157,32 @@ export default function createHandler(initialParams: Params) {
return
}

// mocks from storage

mog(`» trying to get mock with id "${mockId}"`)

if (await storage.has(mockId)) {
mog(`» mock "${mockId}" exists!`)

const mock = await storage.get(mockId)

loggerTrace(`${request.url} ← mock ${mockId} found in storage`)
mog(`» successfully read from "${mockId}", responding`)
const needMockInResponseFn = typeof interceptor.response === 'function' && interceptor.response.length === 2
if (interceptor.response && !needMockInResponseFn) {
loggerTrace(`${request.url} ← inline response`)
mog(`» interceptor.response defined, responding with it`)

await beforeRespond({
request,
response: mock.response,
response: interceptor.response,
responseOverrides,
respond,
interceptor,
mog,
increment,
})

return
}

loggerTrace(`${request.url} ← mock not found in storage`)
mog(`» mock does not exist!`, ci)

if (ci) {
signale.warn(`mock file not found in ci mode, url is "${request.url}"`)
} else {
loggerTrace(`${request.url} ← mock not found in storage`)
mog(`» mock does not exist!`, ci)

if (ci) {
signale.warn(`mock file not found in ci mode, url is "${request.url}"`)
} else {
mog('» about to next()...')
await next(interceptor)
}
mog('» about to next()...')
await next(interceptor)
}
}
}
4 changes: 3 additions & 1 deletion src/handleResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ export default function createHandler(initialParams: Params) {
const mockId = getMockId({ ...request, naming, name: interceptor.name, body: getBody(request.body) })
const mockExist: boolean = await storage.has(mockId)
const hasResp = !!interceptor.response
const needMockInResponseFn =
hasResp && typeof interceptor.response === 'function' && interceptor.response.length === 2
const mog = debug(`teremock:${mockId}`)

/**
Expand All @@ -58,7 +60,7 @@ export default function createHandler(initialParams: Params) {
} else if (mockExist) {
loggerTrace(`${request.url} → mock already exists`)
mog(`« mock was not stored because it exists`)
} else if (hasResp) {
} else if (hasResp && !needMockInResponseFn) {
loggerTrace(`${request.url} → interceptor.response is defined`)
mog(`« mock was not stored because matched interceptor have response property`)
} else if (interceptor.pass) {
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export default teremock

export * from './types'
export * from './utils'
export { default as getMockId } from './mock-id'
export { default as getRequestId } from './request-id'
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export interface GetMockIdParams {
headers?: Headers
}

export type ResponseFunc = (req: ArgRequest) => Promise<Partial<Response>>
export type ResponseFunc = (req: ArgRequest, mockedResponse?: Response) => Promise<Partial<Response>>
export type DefResponse = Partial<Response> | ResponseFunc

type ListItem = string | string[]
Expand Down

0 comments on commit e9953ff

Please sign in to comment.