Skip to content

Commit

Permalink
Merge pull request #1097 from serlo/dependabot/npm_and_yarn/msw-2.0.3
Browse files Browse the repository at this point in the history
build(deps-dev): bump msw from 1.3.2 to 2.0.3
  • Loading branch information
kulla authored Nov 13, 2023
2 parents 6347fa3 + be8bdc0 commit 75f4ec8
Show file tree
Hide file tree
Showing 57 changed files with 443 additions and 393 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
"allow": [
"@pact-foundation/pact/src/dsl/matchers",
"msw/node",
"msw/lib/**",
"io-ts/lib/*",
"io-ts-types/lib/*",
"fp-ts/lib/*",
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed .yarn/cache/msw-npm-1.3.2-572bf57281-c2d4f7747f.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
31 changes: 9 additions & 22 deletions __config__/jest.setup-pacts-serlo-org-database-layer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Pact } from '@pact-foundation/pact'
import { rest } from 'msw'
import { http } from 'msw'
import path from 'path'

import {
Expand Down Expand Up @@ -36,31 +36,18 @@ beforeAll(async () => {
beforeEach(async () => {
await createBeforeEach()
global.server.use(
rest.get(
http.get(
new RegExp(process.env.SERLO_ORG_DATABASE_LAYER_HOST.replace('.', '\\.')),
async (req, res, ctx) => {
const url = req.url
const pactRes = await fetch(`http://127.0.0.1:${port}${url.pathname}`)
return res(ctx.status(pactRes.status), ctx.json(await pactRes.json()))
async ({ request }) => {
const url = new URL(request.url)
return fetch(`http://127.0.0.1:${port}${url.pathname}`)
},
),
rest.post(
http.post(
new RegExp(process.env.SERLO_ORG_DATABASE_LAYER_HOST.replace('.', '\\.')),
async (req, res, ctx) => {
const url = req.url
const pactRes = await fetch(`http://127.0.0.1:${port}${url.pathname}`, {
method: 'POST',
body:
typeof req.body === 'object'
? JSON.stringify(req.body)
: (req.body as string),
headers: {
'Content-Type': req.headers.get('Content-Type')!,
},
})
return pactRes.headers.get('Content-Type')
? res(ctx.status(pactRes.status), ctx.json(await pactRes.json()))
: res(ctx.status(pactRes.status))
async ({ request }) => {
const url = new URL(request.url)
return fetch(`http://127.0.0.1:${port}${url.pathname}`, request)
},
),
)
Expand Down
4 changes: 2 additions & 2 deletions __config__/jest.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ beforeAll(async () => {
onUnhandledRequest(req) {
if (
req.method === 'POST' &&
req.url.href.includes(process.env.SERLO_ORG_DATABASE_LAYER_HOST)
req.url.includes(process.env.SERLO_ORG_DATABASE_LAYER_HOST)
) {
console.error('Found an unhandled request for message %s', req.text())
} else {
console.error(
'Found an unhandled %s request to %s',
req.method,
req.url.href,
req.url,
)
}
},
Expand Down
20 changes: 8 additions & 12 deletions __config__/setup.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { rest } from 'msw'
import { http, HttpResponse } from 'msw'
import { SetupServer, setupServer } from 'msw/node'

import {
Expand Down Expand Up @@ -63,17 +63,13 @@ export async function createBeforeEach() {
givenSpreadheetApi(defaultSpreadsheetApi())

global.server.use(
rest.post<Sentry.Event>(
'https://127.0.0.1/api/0/envelope',
async (req, res, ctx) => {
global.sentryEvents.push(
...(await req.text())
.split('\n')
.map((x) => JSON.parse(x) as Sentry.Event),
)
return res(ctx.status(200))
},
),
http.post('https://127.0.0.1/api/0/envelope', async ({ request }) => {
const text = await request.text()
global.sentryEvents.push(
...text.split('\n').map((x) => JSON.parse(x) as Sentry.Event),
)
return new HttpResponse(null, { status: 200 })
}),
)

await global.cache.flush()
Expand Down
143 changes: 100 additions & 43 deletions __tests__/__utils__/handlers.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { MockedRequest, rest } from 'msw'
import {
DefaultBodyType,
HttpResponse,
PathParams,
ResponseResolver,
StrictRequest,
http,
} from 'msw'
import { HttpRequestResolverExtras } from 'msw/lib/core/handlers/HttpHandler'
import { ResponseResolverInfo } from 'msw/lib/core/handlers/RequestHandler'
import * as R from 'ramda'

import { createFakeIdentity, RestResolver } from './services'
import { createFakeIdentity } from './services'
import { Model } from '~/internals/graphql'
import { DatabaseLayer } from '~/model'
import { Payload } from '~/model/database-layer'
import { DiscriminatorType } from '~/model/decoder'

const ForDefinitions = {
Expand Down Expand Up @@ -45,8 +55,9 @@ const ForDefinitions = {
return { ...entity, trashed: true }
}),
)
given('DeletedEntitiesQuery').isDefinedBy((req, res, ctx) => {
const { first, after, instance } = req.body.payload
given('DeletedEntitiesQuery').isDefinedBy(async ({ request }) => {
const body = await request.json()
const { first, after, instance } = body.payload

const entitiesByInstance = instance
? entities.filter((entity) => entity.instance === instance)
Expand All @@ -66,7 +77,7 @@ const ForDefinitions = {
dateOfDeletion: entity.date,
}
})
return res(ctx.json({ deletedEntities }))
return HttpResponse.json({ deletedEntities })
})
},
}
Expand Down Expand Up @@ -106,7 +117,7 @@ export function given<M extends DatabaseLayer.MessageType>(type: M) {
}),
)
},
isDefinedBy(resolver: MessageResolver<M, DatabaseLayer.Payload<M>>) {
isDefinedBy(resolver: ResponseResolver) {
global.server.use(
createDatabaseLayerHandler({
matchType: type,
Expand All @@ -117,7 +128,12 @@ export function given<M extends DatabaseLayer.MessageType>(type: M) {
},
}
},
isDefinedBy(resolver: MessageResolver<M, DatabaseLayer.Payload<M>>) {
isDefinedBy(
resolver: ResponseResolver<
Record<string, unknown>,
{ payload: Payload<M> }
>,
) {
global.server.use(
createDatabaseLayerHandler({ matchType: type, resolver }),
)
Expand Down Expand Up @@ -206,14 +222,12 @@ function createMessageHandler(
matchType: message.type,
matchPayloads:
message.payload === undefined ? undefined : [message.payload],
resolver: (_req, res, ctx) => {
return (once ? res.once : res)(
ctx.status(statusCode ?? 200),
...(body === undefined
? []
: [ctx.json(body as Record<string, unknown>)]),
)
resolver: () => {
return HttpResponse.json(body === undefined ? [] : body, {
status: statusCode ?? 200,
})
},
options: { once },
})
}

Expand All @@ -223,36 +237,70 @@ function createDatabaseLayerHandler<
>(args: {
matchType: MessageType
matchPayloads?: Partial<Payload>[]
resolver: MessageResolver<MessageType, Payload>
resolver: ResponseResolver<Record<string, unknown>, { payload: Payload }>
options?: { once: boolean }
}) {
const { matchType, matchPayloads, resolver } = args
const { matchType, matchPayloads, resolver, options } = args

const handler = rest.post(getDatabaseLayerUrl({ path: '/' }), resolver)
return http.post(
getDatabaseLayerUrl({ path: '/' }),
withTypeAndPayload(resolver, matchType, matchPayloads) as ResponseResolver<
HttpRequestResolverExtras<PathParams>,
{ payload: Payload },
undefined
>,
options,
)
}

// Only use this handler if message matches
handler.predicate = (req: MockedRequest<BodyType<MessageType, Payload>>) =>
req?.body?.type === matchType &&
(matchPayloads === undefined ||
matchPayloads.some((payload) =>
R.equals({ ...req.body.payload, ...payload }, req.body.payload),
))
function withTypeAndPayload<
MessageType extends string = string,
Payload = DefaultPayloadType,
>(
resolver: ResponseResolver<Record<string, unknown>, { payload: Payload }>,
expectedType: MessageType,
expectedPayloads?: Partial<Payload>[],
) {
return async (
args: ResponseResolverInfo<
HttpRequestResolverExtras<PathParams>,
{ payload: Payload }
>,
) => {
const { request } = args

return handler
// Ignore requests that have a non-JSON body.
const contentType = request.headers.get('Content-Type') || ''
if (!contentType.includes('application/json')) {
return
}

// Clone the request and read it as JSON.
const actualBody = (await request.clone().json()) as {
type: string
payload: DefaultPayloadType[]
}

const isTypeMatching = actualBody.type === expectedType
const isPayloadMatching =
expectedPayloads === undefined ||
expectedPayloads.some((payload) =>
R.equals({ ...actualBody.payload, ...payload }, actualBody.payload),
)

// Compare two objects using "lodash".
if (!isTypeMatching || !isPayloadMatching) {
return
}

return resolver(args)
}
}

function getDatabaseLayerUrl({ path }: { path: string }) {
return `http://${process.env.SERLO_ORG_DATABASE_LAYER_HOST}${path}`
}

type MessageResolver<
MessageType extends string = string,
Payload = DefaultPayloadType,
> = RestResolver<BodyType<MessageType, Payload>>
type BodyType<
MessageType extends string = string,
Payload = DefaultPayloadType,
> = Required<MessagePayload<MessageType, Payload>>

interface MessagePayload<
MessageType extends string = string,
Payload = DefaultPayloadType,
Expand Down Expand Up @@ -287,20 +335,29 @@ function createCommunityChatHandler({
body: Record<string, unknown>
}) {
const url = `${process.env.ROCKET_CHAT_URL}api/v1/${endpoint}`
const handler = rest.get(url, (req, res, ctx) => {
const handler = http.get(url, ({ request }) => {
if (
req.headers.get('X-User-Id') !== process.env.ROCKET_CHAT_API_USER_ID ||
req.headers.get('X-Auth-Token') !== process.env.ROCKET_CHAT_API_AUTH_TOKEN
request.headers.get('X-User-Id') !==
process.env.ROCKET_CHAT_API_USER_ID ||
request.headers.get('X-Auth-Token') !==
process.env.ROCKET_CHAT_API_AUTH_TOKEN
)
return res(ctx.status(403))
return new HttpResponse(null, {
status: 403,
})

return res(ctx.json(body))
return HttpResponse.json(body)
})

handler.predicate = (req: MockedRequest) => {
return R.toPairs(parameters).every(
([name, value]) => req.url.searchParams.get(name) === value,
)
handler.predicate = ({
request,
}: {
request: StrictRequest<DefaultBodyType>
}) => {
return R.toPairs(parameters).every(([name, value]) => {
const url = new URL(request.url)
return url.searchParams.get(name) === value
})
}

return handler
Expand Down
Loading

0 comments on commit 75f4ec8

Please sign in to comment.