Skip to content

Commit

Permalink
Merge pull request #1663 from serlo/staging
Browse files Browse the repository at this point in the history
Deployment
  • Loading branch information
hugotiburtino authored Jul 16, 2024
2 parents b3db9b1 + c032355 commit 7dff3f2
Show file tree
Hide file tree
Showing 82 changed files with 817 additions and 1,494 deletions.
1 change: 1 addition & 0 deletions .github/workflows/push-migration-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
jobs:
docker-image:
runs-on: ubuntu-latest
if: ${{ github.actor != 'dependabot[bot]' }}
steps:
- uses: actions/checkout@v4
- uses: serlo/configure-repositories/actions/setup-node@main
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 not shown.
Binary file removed .yarn/cache/qs-npm-6.12.1-8172168073-aa761d99e6.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.
Binary file not shown.
Binary file not shown.
1 change: 0 additions & 1 deletion __fixtures__/uuid/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export * from './course-page'
export * from './exercise'
export * from './exercise-group'
export * from './event'
export * from './page'
export * from './taxonomy-term'
export * from './thread'
export * from './user'
Expand Down
41 changes: 0 additions & 41 deletions __fixtures__/uuid/page.ts

This file was deleted.

225 changes: 1 addition & 224 deletions __tests__/__utils__/handlers.ts
Original file line number Diff line number Diff line change
@@ -1,229 +1,6 @@
import { HttpResponse, ResponseResolver, http } from 'msw'
import { HttpResponse, http } from 'msw'
import * as R from 'ramda'

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 = {
UuidQuery(uuids: Model<'AbstractUuid'>[]) {
for (const uuid of uuids) {
if (uuid.__typename === DiscriminatorType.User) {
global.kratos.identities.push(createFakeIdentity(uuid))
// db layer doesn't have user.language, it should be fetched in kratos
given('UuidQuery')
.withPayload({ id: uuid.id })
.returns({ ...uuid, language: undefined })
continue
}
given('UuidQuery').withPayload({ id: uuid.id }).returns(uuid)
}
},
}
type ForDefinitions = typeof ForDefinitions
type ForArg<M> = M extends keyof ForDefinitions
? Parameters<ForDefinitions[M]>[0][number]
: never

export function given<M extends DatabaseLayer.MessageType>(type: M) {
return {
withPayload(payload: Partial<DatabaseLayer.Payload<M>>) {
return {
returns(response: DatabaseLayer.Response<M>) {
global.server.use(
createMessageHandler({
message: { type, payload },
statusCode: 200,
body: response,
}),
)
},
returnsNotFound() {
global.server.use(
createMessageHandler({
message: { type, payload },
statusCode: 404,
body: null,
}),
)
},
hasInternalServerError() {
global.server.use(
createMessageHandler({
message: { type, payload },
statusCode: 500,
body: null,
}),
)
},
isDefinedBy(
resolver: ResponseResolver<
Record<string, unknown>,
{ payload: Payload<M> }
>,
) {
global.server.use(
createDatabaseLayerHandler({
matchType: type,
matchPayloads: [payload],
resolver,
}),
)
},
}
},
isDefinedBy(
resolver: ResponseResolver<
Record<string, unknown>,
{ payload: Payload<M> }
>,
) {
global.server.use(
createDatabaseLayerHandler({ matchType: type, resolver }),
)
},
for(...args: (ForArg<M> | ForArg<M>[])[]) {
// FIXME This is just ugly... :-(
const defs = ForDefinitions as { [K in M]?: (x: ForArg<M>[]) => void }
const func = defs[type]

if (typeof func === 'function') {
func(args.flatMap((x) => (Array.isArray(x) ? x : [x])))
}
},
returns(response: DatabaseLayer.Response<M>) {
global.server.use(
createMessageHandler({
message: { type },
statusCode: 200,
body: response,
}),
)
},
returnsNotFound() {
global.server.use(
createMessageHandler({
message: { type },
statusCode: 404,
body: null,
}),
)
},
hasInternalServerError() {
global.server.use(
createMessageHandler({ message: { type }, statusCode: 500 }),
)
},
returnsBadRequest() {
global.server.use(
createMessageHandler({
message: { type },
statusCode: 400,
body: { reason: 'bad request' },
}),
)
},
}
}

function createMessageHandler(
args: {
message: MessagePayload
body?: unknown
statusCode?: number
},
once = false,
) {
const { message, body, statusCode } = args

return createDatabaseLayerHandler({
matchType: message.type,
matchPayloads:
message.payload === undefined ? undefined : [message.payload],
resolver: () => {
return HttpResponse.json(body === undefined ? [] : body, {
status: statusCode ?? 200,
})
},
options: { once },
})
}

function createDatabaseLayerHandler<
MessageType extends string = string,
Payload = DefaultPayloadType,
>(args: {
matchType: MessageType
matchPayloads?: Partial<Payload>[]
resolver: ResponseResolver<Record<string, unknown>, { payload: Payload }>
options?: { once: boolean }
}) {
const { matchType, matchPayloads, resolver, options } = args

return http.post(
getDatabaseLayerUrl({ path: '/' }),
withTypeAndPayload(resolver, matchType, matchPayloads),
options,
)
}

function withTypeAndPayload<
MessageType extends string = string,
Payload = DefaultPayloadType,
>(
resolver: ResponseResolver<Record<string, unknown>, { payload: Payload }>,
expectedType: MessageType,
expectedPayloads?: Partial<Payload>[],
): ResponseResolver<Record<string, unknown>, { payload: Payload }> {
return async (args) => {
const { request } = args

// 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: Payload
}

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
}

// Without the `as` we get a TypeScript error which is a bug in
// `msw` itself. Let's fix it at some point in the future :-)
return resolver(args) as HttpResponse
}
}

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

interface MessagePayload<
MessageType extends string = string,
Payload = DefaultPayloadType,
> {
type: MessageType
payload?: Payload
}

type DefaultPayloadType = Record<string, unknown>

export function createChatUsersInfoHandler({
username,
success,
Expand Down
19 changes: 19 additions & 0 deletions __tests__/__utils__/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ export const entityQuery = new Client().prepareQuery({
}
}
}
... on ThreadAware {
threads {
nodes {
status
}
}
}
}
}
`,
Expand Down Expand Up @@ -203,3 +210,15 @@ export const subscriptionsQuery = new Client({ userId: 27393 }).prepareQuery({
}
`,
})

export const commentQuery = new Client().prepareQuery({
query: gql`
query ($id: Int!) {
uuid(id: $id) {
... on Comment {
content
}
}
}
`,
})
4 changes: 1 addition & 3 deletions __tests__/schema/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { HttpResponse, ResponseResolver, http } from 'msw'
import type { OpenAI } from 'openai'

import { user as baseUser } from '../../__fixtures__'
import { Client, given, hasInternalServerError } from '../__utils__'
import { Client, hasInternalServerError } from '../__utils__'

interface ChoicesFromChatCompletion {
choices: OpenAI.ChatCompletion['choices']
Expand Down Expand Up @@ -70,8 +70,6 @@ beforeEach(() => {
mockOpenAIServer(() => {
return HttpResponse.json(mockedOpenAiResponse)
})

given('UuidQuery').for(user)
})

afterEach(() => {
Expand Down
9 changes: 9 additions & 0 deletions __tests__/schema/entity/checkout-revision.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ test('checks out a revision', async () => {
})
})

test('allows to checkout a revision for pages for static pages builder', async () => {
const newMutation = await mutation
.changeInput({ revisionId: 35476 })
.forUser('de_static_pages_builder')
await newMutation.shouldReturnData({
entity: { checkoutRevision: { success: true } },
})
})

test('checkout revision has trashed == false for following queries', async () => {
await databaseForTests.mutate('update uuid set trashed = 1 where id = ?', [
input.revisionId,
Expand Down
13 changes: 13 additions & 0 deletions __tests__/schema/entity/set-abstract-entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,19 @@ test('creates a new entity when "parentId" is set', async () => {
)
})

test('creates a new entity when "parentId" is set (for static pages)', async () => {
const newMutation = await mutation
.changeInput({
parentId: 282309,
entityType: 'Page',
})
.forUser('de_static_pages_builder')

await newMutation.shouldReturnData({
entity: { setAbstractEntity: { success: true } },
})
})

test('creates a subscription', async () => {
await subscriptionsQuery.withContext({ userId: 15491 }).shouldReturnData({
subscription: { getSubscriptions: { nodes: [] } },
Expand Down
6 changes: 1 addition & 5 deletions __tests__/schema/notification.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import gql from 'graphql-tag'

import { user } from '../../__fixtures__'
import { Client, given } from '../__utils__'
import { Client } from '../__utils__'
import { Service } from '~/context/service'

const query = new Client({ userId: 1194 }).prepareQuery({
Expand Down Expand Up @@ -162,10 +162,6 @@ describe('mutation notification setState', () => {
})
.withVariables({ input: { id: [11599, 11551], unread: false } })

beforeEach(() => {
given('UuidQuery').for(user)
})

test('authenticated with array of ids', async () => {
await query.shouldReturnData({
notifications: {
Expand Down
Loading

0 comments on commit 7dff3f2

Please sign in to comment.