Skip to content

Commit

Permalink
Merge pull request #1518 from serlo/migrate-add-role
Browse files Browse the repository at this point in the history
Migrate add role incl. user description bugfix and test updates
  • Loading branch information
AndreasHuber committed May 31, 2024
2 parents 610cf4d + fc8accd commit f85bb5b
Show file tree
Hide file tree
Showing 23 changed files with 281 additions and 1,141 deletions.
9 changes: 4 additions & 5 deletions __fixtures__/uuid/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const user: Model<'User'> = {
trashed: false,
alias: '/user/1/admin',
username: 'admin',
date: '2014-03-01T20:36:21Z',
date: '2014-03-01T20:36:21.000Z',
lastLogin: '2020-03-24T09:40:55Z',
description: null,
roles: ['login', 'german_horizonhelper', 'sysadmin'],
Expand All @@ -17,10 +17,9 @@ export const user2: Model<'User'> = {
__typename: DiscriminatorType.User,
id: 23,
trashed: false,
alias: '/user/23/sandra',
username: 'sandra',
date: '2015-02-01T20:35:21Z',
lastLogin: '2019-03-23T09:20:55Z',
alias: '/user/23/1229902f',
username: '1229902f',
date: '2014-03-01T20:36:32.000Z',
description: null,
roles: ['login'],
}
Expand Down
37 changes: 28 additions & 9 deletions __tests__/__utils__/assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import { DocumentNode } from 'graphql'
import gql from 'graphql-tag'
import * as R from 'ramda'

import { given, nextUuid } from '.'
import { user } from '../../__fixtures__'
import { Context } from '~/context'
import { Service } from '~/context/service'
import { ModelDataSource } from '~/internals/data-source'
Expand Down Expand Up @@ -98,16 +96,37 @@ export class Query<
return new Query(new Client(context), this.query)
}

forLoginUser(...additionalRoles: string[]) {
const loginUser = {
...user,
id: nextUuid(user.id),
roles: [...additionalRoles, 'login'],
async forUser(...additionalRoles: string[]) {
const userWithoutRolesId = 35478

for (const role of additionalRoles) {
const result = await databaseForTests.fetchOptional<{ id: number }>(
'select id from role where name = ?',
[role],
)

let roleId = result?.id

if (roleId == null) {
const result = await databaseForTests.mutate(
'insert into role (name) values (?)',
[role],
)

roleId = result.insertId
}

await databaseForTests.mutate(
'insert into role_user (user_id, role_id) values (?, ?)',
[userWithoutRolesId, roleId],
)
}

given('UuidQuery').for(loginUser)
return this.withContext({ userId: userWithoutRolesId })
}

return this.withContext({ userId: loginUser.id })
forLoginUser() {
return this.withContext({ userId: 9 })
}

forUnauthenticatedUser() {
Expand Down
19 changes: 19 additions & 0 deletions __tests__/__utils__/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,25 @@ export const taxonomyTermQuery = new Client().prepareQuery({
`,
})

export const userQuery = new Client().prepareQuery({
query: gql`
query ($id: Int!) {
uuid(id: $id) {
id
__typename
... on User {
roles {
nodes {
role
scope
}
}
}
}
}
`,
})

export const threadsQuery = new Client().prepareQuery({
query: gql`
query thread($id: Int!, $archived: Boolean) {
Expand Down
6 changes: 4 additions & 2 deletions __tests__/schema/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ test('successfully generate content for student (not logged in) - staging', asyn
})

test('successfully generate content for architect - staging', async () => {
await query.forLoginUser('de_architect').shouldReturnData({
const newQuery = await query.forUser('de_architect')
await newQuery.shouldReturnData({
ai: {
executePrompt: {
success: true,
Expand All @@ -152,7 +153,8 @@ test('fails for unauthenticated user in production', async () => {
test('fails for unauthorized user (wrong role) in production', async () => {
const previousEnvironment = process.env.ENVIRONMENT
process.env.ENVIRONMENT = 'production'
await query.forLoginUser('de_architect').shouldFailWithError('FORBIDDEN')
const newQuery = await query.forUser('de_moderator')
await newQuery.shouldFailWithError('FORBIDDEN')
process.env.ENVIRONMENT = previousEnvironment
})

Expand Down
21 changes: 11 additions & 10 deletions __tests__/schema/authorization.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Scope, Thread } from '@serlo/authorization'
import gql from 'graphql-tag'

import { user } from '../../__fixtures__'
import { given, Client } from '../__utils__'
import { Client } from '../__utils__'
import { resolveRolesPayload, RolesPayload } from '~/schema/authorization/roles'
import { Role } from '~/types'

Expand All @@ -22,9 +21,7 @@ describe('authorization', () => {
})

test('Authenticated Users (no special roles)', async () => {
given('UuidQuery').for({ ...user, roles: ['login'] })

await new Client({ userId: user.id })
await new Client({ userId: 20 })
.prepareQuery({
query: gql`
{
Expand All @@ -38,9 +35,7 @@ describe('authorization', () => {
})

test('Authenticated Users (filter old legacy roles)', async () => {
given('UuidQuery').for({ ...user, roles: ['login', 'german_moderator'] })

await new Client({ userId: user.id })
await new Client({ userId: 33931 })
.prepareQuery({
query: gql`
{
Expand All @@ -54,9 +49,15 @@ describe('authorization', () => {
})

test('Authenticated Users (map new legacy roles)', async () => {
given('UuidQuery').for({ ...user, roles: ['login', 'de_moderator'] })
const { insertId } = await databaseForTests.mutate(
"insert into role (name) values ('de_moderator')",
)
await databaseForTests.mutate(
`insert into role_user (user_id, role_id) values (33931, ?)`,
[insertId],
)

await new Client({ userId: user.id })
await new Client({ userId: 33931 })
.prepareQuery({
query: gql`
{
Expand Down
3 changes: 2 additions & 1 deletion __tests__/schema/entity/checkout-revision.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ test('fails when user is not authenticated', async () => {
})

test('fails when user does not have role "reviewer"', async () => {
await mutation.forLoginUser('de_moderator').shouldFailWithError('FORBIDDEN')
const newMutation = await mutation.forUser('de_moderator')
await newMutation.shouldFailWithError('FORBIDDEN')
})

test('fails when database layer returns a 400er response', async () => {
Expand Down
3 changes: 2 additions & 1 deletion __tests__/schema/entity/reject-revision.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ test('fails when user is not authenticated', async () => {
})

test('fails when user does not have role "reviewer"', async () => {
await mutation.forLoginUser('de_moderator').shouldFailWithError('FORBIDDEN')
const newMutation = await mutation.forUser('de_moderator')
await newMutation.shouldFailWithError('FORBIDDEN')
})

test('fails when database layer returns a 400er response', async () => {
Expand Down
Loading

0 comments on commit f85bb5b

Please sign in to comment.