mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2026-04-06 01:25:38 +00:00
fix(backend): fix backend tests & increase coverage (#9514)
This commit is contained in:
parent
700aaaf0b2
commit
306f21cc20
@ -27,7 +27,7 @@ export default {
|
|||||||
],
|
],
|
||||||
coverageThreshold: {
|
coverageThreshold: {
|
||||||
global: {
|
global: {
|
||||||
lines: 93,
|
lines: 94,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
testMatch: ['**/src/**/?(*.)+(spec|test).ts?(x)'],
|
testMatch: ['**/src/**/?(*.)+(spec|test).ts?(x)'],
|
||||||
|
|||||||
@ -7,6 +7,8 @@ mutation ChangeGroupMemberRole($groupId: ID!, $userId: ID!, $roleInGroup: GroupM
|
|||||||
}
|
}
|
||||||
membership {
|
membership {
|
||||||
role
|
role
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,6 +27,7 @@ query Group($isMember: Boolean, $id: ID, $slug: String) {
|
|||||||
name
|
name
|
||||||
}
|
}
|
||||||
myRole
|
myRole
|
||||||
|
currentlyPinnedPostsCount
|
||||||
inviteCodes {
|
inviteCodes {
|
||||||
code
|
code
|
||||||
redeemedByCount
|
redeemedByCount
|
||||||
|
|||||||
3
backend/src/graphql/queries/groups/GroupCount.gql
Normal file
3
backend/src/graphql/queries/groups/GroupCount.gql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
query GroupCount($isMember: Boolean) {
|
||||||
|
GroupCount(isMember: $isMember)
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
mutation UpdatePost(
|
mutation UpdatePost(
|
||||||
$id: ID!
|
$id: ID!
|
||||||
$title: String!
|
$title: String!
|
||||||
|
$slug: String
|
||||||
$content: String!
|
$content: String!
|
||||||
$image: ImageInput
|
$image: ImageInput
|
||||||
$categoryIds: [ID]
|
$categoryIds: [ID]
|
||||||
@ -10,6 +11,7 @@ mutation UpdatePost(
|
|||||||
UpdatePost(
|
UpdatePost(
|
||||||
id: $id
|
id: $id
|
||||||
title: $title
|
title: $title
|
||||||
|
slug: $slug
|
||||||
content: $content
|
content: $content
|
||||||
image: $image
|
image: $image
|
||||||
categoryIds: $categoryIds
|
categoryIds: $categoryIds
|
||||||
@ -18,6 +20,7 @@ mutation UpdatePost(
|
|||||||
) {
|
) {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
|
slug
|
||||||
content
|
content
|
||||||
author {
|
author {
|
||||||
id
|
id
|
||||||
|
|||||||
@ -10,10 +10,13 @@ import Factory, { cleanDatabase } from '@db/factories'
|
|||||||
import ChangeGroupMemberRole from '@graphql/queries/groups/ChangeGroupMemberRole.gql'
|
import ChangeGroupMemberRole from '@graphql/queries/groups/ChangeGroupMemberRole.gql'
|
||||||
import CreateGroup from '@graphql/queries/groups/CreateGroup.gql'
|
import CreateGroup from '@graphql/queries/groups/CreateGroup.gql'
|
||||||
import groupQuery from '@graphql/queries/groups/Group.gql'
|
import groupQuery from '@graphql/queries/groups/Group.gql'
|
||||||
|
import GroupCount from '@graphql/queries/groups/GroupCount.gql'
|
||||||
import groupMembersQuery from '@graphql/queries/groups/GroupMembers.gql'
|
import groupMembersQuery from '@graphql/queries/groups/GroupMembers.gql'
|
||||||
import JoinGroup from '@graphql/queries/groups/JoinGroup.gql'
|
import JoinGroup from '@graphql/queries/groups/JoinGroup.gql'
|
||||||
import LeaveGroup from '@graphql/queries/groups/LeaveGroup.gql'
|
import LeaveGroup from '@graphql/queries/groups/LeaveGroup.gql'
|
||||||
|
import muteGroupMutation from '@graphql/queries/groups/muteGroup.gql'
|
||||||
import RemoveUserFromGroup from '@graphql/queries/groups/RemoveUserFromGroup.gql'
|
import RemoveUserFromGroup from '@graphql/queries/groups/RemoveUserFromGroup.gql'
|
||||||
|
import unmuteGroupMutation from '@graphql/queries/groups/unmuteGroup.gql'
|
||||||
import UpdateGroup from '@graphql/queries/groups/UpdateGroup.gql'
|
import UpdateGroup from '@graphql/queries/groups/UpdateGroup.gql'
|
||||||
import { createApolloTestSetup } from '@root/test/helpers'
|
import { createApolloTestSetup } from '@root/test/helpers'
|
||||||
|
|
||||||
@ -1740,8 +1743,17 @@ describe('in mode', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// the GQL mutation needs this fields in the result for testing
|
it('has "updatedAt" newer than or equal to "createdAt"', async () => {
|
||||||
it.todo('has "updatedAt" newer as "createdAt"')
|
const result = await mutate({
|
||||||
|
mutation: ChangeGroupMemberRole,
|
||||||
|
variables,
|
||||||
|
})
|
||||||
|
const { createdAt, updatedAt }: { createdAt: string; updatedAt: string } =
|
||||||
|
result.data.ChangeGroupMemberRole.membership
|
||||||
|
expect(new Date(updatedAt).getTime()).toBeGreaterThanOrEqual(
|
||||||
|
new Date(createdAt).getTime(),
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -3308,4 +3320,200 @@ describe('in mode', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('clean db after each – additional coverage', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await seedBasicsAndClearAuthentication()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await cleanDatabase()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('GroupCount', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
authenticatedUser = await user.toJson()
|
||||||
|
await mutate({
|
||||||
|
mutation: CreateGroup,
|
||||||
|
variables: {
|
||||||
|
name: 'Count Test Group',
|
||||||
|
about: 'A group for counting',
|
||||||
|
description:
|
||||||
|
'This is a test group for counting purposes, with enough description length to pass validation',
|
||||||
|
groupType: 'public',
|
||||||
|
actionRadius: 'national',
|
||||||
|
categoryIds: ['cat9'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns count of all visible groups when isMember is not set', async () => {
|
||||||
|
const result = await query({ query: GroupCount })
|
||||||
|
expect(result).toMatchObject({
|
||||||
|
data: { GroupCount: 1 },
|
||||||
|
errors: undefined,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns count of groups the user is a member of', async () => {
|
||||||
|
const result = await query({ query: GroupCount, variables: { isMember: true } })
|
||||||
|
expect(result).toMatchObject({
|
||||||
|
data: { GroupCount: 1 },
|
||||||
|
errors: undefined,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('muteGroup and unmuteGroup', () => {
|
||||||
|
let groupId: string
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
authenticatedUser = await user.toJson()
|
||||||
|
const result = await mutate({
|
||||||
|
mutation: CreateGroup,
|
||||||
|
variables: {
|
||||||
|
name: 'Mute Test Group',
|
||||||
|
about: 'A group for muting',
|
||||||
|
description:
|
||||||
|
'This is a test group for muting purposes, with enough description length to pass validation',
|
||||||
|
groupType: 'public',
|
||||||
|
actionRadius: 'national',
|
||||||
|
categoryIds: ['cat9'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
groupId = result.data.CreateGroup.id
|
||||||
|
})
|
||||||
|
|
||||||
|
it('mutes a group', async () => {
|
||||||
|
await expect(
|
||||||
|
mutate({ mutation: muteGroupMutation, variables: { groupId } }),
|
||||||
|
).resolves.toMatchObject({
|
||||||
|
data: {
|
||||||
|
muteGroup: {
|
||||||
|
id: groupId,
|
||||||
|
isMutedByMe: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors: undefined,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('unmutes a group', async () => {
|
||||||
|
await mutate({ mutation: muteGroupMutation, variables: { groupId } })
|
||||||
|
await expect(
|
||||||
|
mutate({ mutation: unmuteGroupMutation, variables: { groupId } }),
|
||||||
|
).resolves.toMatchObject({
|
||||||
|
data: {
|
||||||
|
unmuteGroup: {
|
||||||
|
id: groupId,
|
||||||
|
isMutedByMe: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors: undefined,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('muteGroup throws for unauthenticated user', async () => {
|
||||||
|
authenticatedUser = null
|
||||||
|
await expect(
|
||||||
|
mutate({ mutation: muteGroupMutation, variables: { groupId } }),
|
||||||
|
).resolves.toMatchObject({
|
||||||
|
errors: [expect.objectContaining({ message: 'Not Authorized!' })],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('unmuteGroup throws for unauthenticated user', async () => {
|
||||||
|
authenticatedUser = null
|
||||||
|
await expect(
|
||||||
|
mutate({ mutation: unmuteGroupMutation, variables: { groupId } }),
|
||||||
|
).resolves.toMatchObject({
|
||||||
|
errors: [expect.objectContaining({ message: 'Not Authorized!' })],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('UpdateGroup slug conflict', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
authenticatedUser = await user.toJson()
|
||||||
|
await mutate({
|
||||||
|
mutation: CreateGroup,
|
||||||
|
variables: {
|
||||||
|
id: 'group-a',
|
||||||
|
name: 'Group A',
|
||||||
|
slug: 'group-a',
|
||||||
|
about: 'About A',
|
||||||
|
description:
|
||||||
|
'A test group with enough description length to pass the validation requirement check',
|
||||||
|
groupType: 'public',
|
||||||
|
actionRadius: 'national',
|
||||||
|
categoryIds: ['cat9'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await mutate({
|
||||||
|
mutation: CreateGroup,
|
||||||
|
variables: {
|
||||||
|
id: 'group-b',
|
||||||
|
name: 'Group B',
|
||||||
|
slug: 'group-b',
|
||||||
|
about: 'About B',
|
||||||
|
description:
|
||||||
|
'A test group with enough description length to pass the validation requirement check',
|
||||||
|
groupType: 'public',
|
||||||
|
actionRadius: 'national',
|
||||||
|
categoryIds: ['cat9'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws error when updating slug to conflict with existing group', async () => {
|
||||||
|
await expect(
|
||||||
|
mutate({
|
||||||
|
mutation: UpdateGroup,
|
||||||
|
variables: { id: 'group-b', slug: 'group-a' },
|
||||||
|
}),
|
||||||
|
).resolves.toMatchObject({
|
||||||
|
errors: [expect.objectContaining({ message: 'Group with this slug already exists!' })],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('CreateGroup slug conflict', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
authenticatedUser = await user.toJson()
|
||||||
|
await mutate({
|
||||||
|
mutation: CreateGroup,
|
||||||
|
variables: {
|
||||||
|
name: 'Existing Group',
|
||||||
|
slug: 'existing-group',
|
||||||
|
about: 'About',
|
||||||
|
description:
|
||||||
|
'A test group with enough description length to pass the validation requirement check',
|
||||||
|
groupType: 'public',
|
||||||
|
actionRadius: 'national',
|
||||||
|
categoryIds: ['cat9'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws error when creating group with duplicate slug', async () => {
|
||||||
|
await expect(
|
||||||
|
mutate({
|
||||||
|
mutation: CreateGroup,
|
||||||
|
variables: {
|
||||||
|
name: 'Another Group',
|
||||||
|
slug: 'existing-group',
|
||||||
|
about: 'About',
|
||||||
|
description:
|
||||||
|
'A test group with enough description length to pass the validation requirement check',
|
||||||
|
groupType: 'public',
|
||||||
|
actionRadius: 'national',
|
||||||
|
categoryIds: ['cat9'],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).resolves.toMatchObject({
|
||||||
|
errors: [expect.objectContaining({ message: 'Group with this slug already exists!' })],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -167,7 +167,7 @@ export default {
|
|||||||
MERGE (owner)-[membership:MEMBER_OF]->(group)
|
MERGE (owner)-[membership:MEMBER_OF]->(group)
|
||||||
SET
|
SET
|
||||||
membership.createdAt = toString(datetime()),
|
membership.createdAt = toString(datetime()),
|
||||||
membership.updatedAt = null,
|
membership.updatedAt = toString(datetime()),
|
||||||
membership.role = 'owner'
|
membership.role = 'owner'
|
||||||
${categoriesCypher}
|
${categoriesCypher}
|
||||||
RETURN group {.*, myRole: membership.role}
|
RETURN group {.*, myRole: membership.role}
|
||||||
@ -280,7 +280,7 @@ export default {
|
|||||||
MERGE (user)-[membership:MEMBER_OF]->(group)
|
MERGE (user)-[membership:MEMBER_OF]->(group)
|
||||||
ON CREATE SET
|
ON CREATE SET
|
||||||
membership.createdAt = toString(datetime()),
|
membership.createdAt = toString(datetime()),
|
||||||
membership.updatedAt = null,
|
membership.updatedAt = toString(datetime()),
|
||||||
membership.role =
|
membership.role =
|
||||||
CASE WHEN group.groupType = 'public'
|
CASE WHEN group.groupType = 'public'
|
||||||
THEN 'usual'
|
THEN 'usual'
|
||||||
@ -339,7 +339,7 @@ export default {
|
|||||||
MERGE (member)-[membership:MEMBER_OF]->(group)
|
MERGE (member)-[membership:MEMBER_OF]->(group)
|
||||||
ON CREATE SET
|
ON CREATE SET
|
||||||
membership.createdAt = toString(datetime()),
|
membership.createdAt = toString(datetime()),
|
||||||
membership.updatedAt = null,
|
membership.updatedAt = toString(datetime()),
|
||||||
membership.role = $roleInGroup
|
membership.role = $roleInGroup
|
||||||
ON MATCH SET
|
ON MATCH SET
|
||||||
membership.updatedAt = toString(datetime()),
|
membership.updatedAt = toString(datetime()),
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
/* eslint-disable jest/expect-expect */
|
|
||||||
|
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import currentUser from '@graphql/queries/auth/currentUser.gql'
|
import currentUser from '@graphql/queries/auth/currentUser.gql'
|
||||||
@ -234,23 +233,6 @@ describe('validateInviteCode', () => {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
// eslint-disable-next-line jest/no-disabled-tests
|
|
||||||
it.skip('throws authorization error when querying extended fields', async () => {
|
|
||||||
await expect(
|
|
||||||
query({ query: authenticatedValidateInviteCode, variables: { code: 'PERSNL' } }),
|
|
||||||
).resolves.toMatchObject({
|
|
||||||
data: {
|
|
||||||
validateInviteCode: {
|
|
||||||
code: 'PERSNL',
|
|
||||||
generatedBy: null,
|
|
||||||
invitedTo: null,
|
|
||||||
isValid: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
errors: [{ message: 'Not Authorized!' }],
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('as authenticated user', () => {
|
describe('as authenticated user', () => {
|
||||||
@ -307,27 +289,6 @@ describe('validateInviteCode', () => {
|
|||||||
errors: undefined,
|
errors: undefined,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// This doesn't work because group permissions are fucked
|
|
||||||
// eslint-disable-next-line jest/no-disabled-tests
|
|
||||||
it.skip('throws authorization error when querying extended hidden group fields', async () => {
|
|
||||||
await expect(
|
|
||||||
query({ query: authenticatedValidateInviteCode, variables: { code: 'GRPHDN' } }),
|
|
||||||
).resolves.toMatchObject({
|
|
||||||
data: {
|
|
||||||
validateInviteCode: {
|
|
||||||
code: 'GRPHDN',
|
|
||||||
generatedBy: null,
|
|
||||||
invitedTo: null,
|
|
||||||
isValid: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
errors: [{ message: 'Not Authorized!' }],
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// eslint-disable-next-line jest/no-disabled-tests
|
|
||||||
it.skip('throws no authorization error when querying extended hidden group fields as member', async () => {})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -494,9 +455,6 @@ describe('generatePersonalInviteCode', () => {
|
|||||||
errors: undefined,
|
errors: undefined,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// eslint-disable-next-line jest/no-disabled-tests
|
|
||||||
it.skip('returns a new invite code when colliding with an existing one', () => {})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -762,9 +720,6 @@ describe('generateGroupInviteCode', () => {
|
|||||||
errors: undefined,
|
errors: undefined,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// eslint-disable-next-line jest/no-disabled-tests
|
|
||||||
it.skip('returns a new group invite code when colliding with an existing one', () => {})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('as authenticated not-member', () => {
|
describe('as authenticated not-member', () => {
|
||||||
|
|||||||
@ -118,7 +118,7 @@ export const redeemInviteCode = async (context: Context, code, newUser = false)
|
|||||||
MERGE (user)-[membership:MEMBER_OF]->(group)
|
MERGE (user)-[membership:MEMBER_OF]->(group)
|
||||||
ON CREATE SET
|
ON CREATE SET
|
||||||
membership.createdAt = toString(datetime()),
|
membership.createdAt = toString(datetime()),
|
||||||
membership.updatedAt = null,
|
membership.updatedAt = toString(datetime()),
|
||||||
membership.role = $role
|
membership.role = $role
|
||||||
`,
|
`,
|
||||||
variables: { user: context.user, code, role },
|
variables: { user: context.user, code, role },
|
||||||
|
|||||||
@ -69,7 +69,7 @@ describe('Filter Posts', () => {
|
|||||||
content: 'Elli wird fünf. Wir feiern ihren Geburtstag.',
|
content: 'Elli wird fünf. Wir feiern ihren Geburtstag.',
|
||||||
postType: 'Event',
|
postType: 'Event',
|
||||||
eventInput: {
|
eventInput: {
|
||||||
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
|
eventStart: new Date(now.getFullYear(), now.getMonth() + 1, 15).toISOString(),
|
||||||
eventVenue: 'Garten der Familie Maier',
|
eventVenue: 'Garten der Familie Maier',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -174,7 +174,7 @@ describe('Filter Posts', () => {
|
|||||||
expect(result).toEqual([
|
expect(result).toEqual([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: 'e1',
|
id: 'e1',
|
||||||
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
|
eventStart: new Date(now.getFullYear(), now.getMonth() + 1, 15).toISOString(),
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: 'e2',
|
id: 'e2',
|
||||||
@ -184,9 +184,7 @@ describe('Filter Posts', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// Does not work on months end
|
describe('order events by event start ascending', () => {
|
||||||
// eslint-disable-next-line jest/no-disabled-tests
|
|
||||||
describe.skip('order events by event start ascending', () => {
|
|
||||||
it('finds the events ordered accordingly', async () => {
|
it('finds the events ordered accordingly', async () => {
|
||||||
const {
|
const {
|
||||||
data: { Post: result },
|
data: { Post: result },
|
||||||
@ -202,15 +200,13 @@ describe('Filter Posts', () => {
|
|||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: 'e1',
|
id: 'e1',
|
||||||
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
|
eventStart: new Date(now.getFullYear(), now.getMonth() + 1, 15).toISOString(),
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// Does not work on months end
|
describe('filter events by event start date', () => {
|
||||||
// eslint-disable-next-line jest/no-disabled-tests
|
|
||||||
describe.skip('filter events by event start date', () => {
|
|
||||||
it('finds only events after given date', async () => {
|
it('finds only events after given date', async () => {
|
||||||
const {
|
const {
|
||||||
data: { Post: result },
|
data: { Post: result },
|
||||||
@ -231,7 +227,7 @@ describe('Filter Posts', () => {
|
|||||||
expect(result).toEqual([
|
expect(result).toEqual([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: 'e1',
|
id: 'e1',
|
||||||
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
|
eventStart: new Date(now.getFullYear(), now.getMonth() + 1, 15).toISOString(),
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|||||||
@ -20,7 +20,6 @@ import unpushPost from '@graphql/queries/posts/unpushPost.gql'
|
|||||||
import UpdatePost from '@graphql/queries/posts/UpdatePost.gql'
|
import UpdatePost from '@graphql/queries/posts/UpdatePost.gql'
|
||||||
import { createApolloTestSetup } from '@root/test/helpers'
|
import { createApolloTestSetup } from '@root/test/helpers'
|
||||||
|
|
||||||
import type Image from '@db/models/Image'
|
|
||||||
import type { ApolloTestSetup } from '@root/test/helpers'
|
import type { ApolloTestSetup } from '@root/test/helpers'
|
||||||
import type { Context } from '@src/context'
|
import type { Context } from '@src/context'
|
||||||
|
|
||||||
@ -885,50 +884,6 @@ describe('UpdatePost', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// eslint-disable-next-line jest/no-disabled-tests
|
|
||||||
describe.skip('params.image', () => {
|
|
||||||
describe('is object', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
variables = { ...variables, image: { sensitive: true } }
|
|
||||||
})
|
|
||||||
it('updates the image', async () => {
|
|
||||||
await expect(
|
|
||||||
database.neode.first<typeof Image>('Image', { sensitive: true }, undefined),
|
|
||||||
).resolves.toBeFalsy()
|
|
||||||
await mutate({ mutation: UpdatePost, variables })
|
|
||||||
await expect(
|
|
||||||
database.neode.first<typeof Image>('Image', { sensitive: true }, undefined),
|
|
||||||
).resolves.toBeTruthy()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('is null', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
variables = { ...variables, image: null }
|
|
||||||
})
|
|
||||||
it('deletes the image', async () => {
|
|
||||||
await expect(database.neode.all('Image')).resolves.toHaveLength(6)
|
|
||||||
await mutate({ mutation: UpdatePost, variables })
|
|
||||||
await expect(database.neode.all('Image')).resolves.toHaveLength(5)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('is undefined', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
delete variables.image
|
|
||||||
})
|
|
||||||
it('keeps the image unchanged', async () => {
|
|
||||||
await expect(
|
|
||||||
database.neode.first<typeof Image>('Image', { sensitive: true }, undefined),
|
|
||||||
).resolves.toBeFalsy()
|
|
||||||
await mutate({ mutation: UpdatePost, variables })
|
|
||||||
await expect(
|
|
||||||
database.neode.first<typeof Image>('Image', { sensitive: true }, undefined),
|
|
||||||
).resolves.toBeFalsy()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -219,7 +219,7 @@ export default {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.code === 'Neo.ClientError.Schema.ConstraintValidationFailed')
|
if (e.code === 'Neo.ClientError.Schema.ConstraintValidationFailed')
|
||||||
throw new UserInputError('Post with this slug already exists!')
|
throw new UserInputError('Post with this slug already exists!')
|
||||||
throw new Error(e)
|
throw e
|
||||||
} finally {
|
} finally {
|
||||||
await session.close()
|
await session.close()
|
||||||
}
|
}
|
||||||
@ -286,6 +286,10 @@ export default {
|
|||||||
await createOrUpdateLocations('Post', post.id, locationName, session, context)
|
await createOrUpdateLocations('Post', post.id, locationName, session, context)
|
||||||
}
|
}
|
||||||
return post
|
return post
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code === 'Neo.ClientError.Schema.ConstraintValidationFailed')
|
||||||
|
throw new UserInputError('Post with this slug already exists!')
|
||||||
|
throw e
|
||||||
} finally {
|
} finally {
|
||||||
await session.close()
|
await session.close()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -239,7 +239,30 @@ describe('reports', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it.todo('creates multiple filed reports')
|
it('creates separate reports for different resources', async () => {
|
||||||
|
await Factory.build(
|
||||||
|
'user',
|
||||||
|
{
|
||||||
|
id: 'second-abusive-user-id',
|
||||||
|
role: 'user',
|
||||||
|
name: 'second-abusive-user',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
email: 'second-abusive@example.org',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
const firstReport = await mutate({
|
||||||
|
mutation: fileReport,
|
||||||
|
variables: { ...variables, resourceId: 'abusive-user-id' },
|
||||||
|
})
|
||||||
|
const secondReport = await mutate({
|
||||||
|
mutation: fileReport,
|
||||||
|
variables: { ...variables, resourceId: 'second-abusive-user-id' },
|
||||||
|
})
|
||||||
|
expect(firstReport.data.fileReport.reportId).not.toEqual(
|
||||||
|
secondReport.data.fileReport.reportId,
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('reported resource is a user', () => {
|
describe('reported resource is a user', () => {
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import SignupVerification from '@graphql/queries/auth/SignupVerification.gql'
|
|||||||
import CreateGroup from '@graphql/queries/groups/CreateGroup.gql'
|
import CreateGroup from '@graphql/queries/groups/CreateGroup.gql'
|
||||||
import UpdateGroup from '@graphql/queries/groups/UpdateGroup.gql'
|
import UpdateGroup from '@graphql/queries/groups/UpdateGroup.gql'
|
||||||
import CreatePost from '@graphql/queries/posts/CreatePost.gql'
|
import CreatePost from '@graphql/queries/posts/CreatePost.gql'
|
||||||
|
import UpdatePost from '@graphql/queries/posts/UpdatePost.gql'
|
||||||
import { createApolloTestSetup } from '@root/test/helpers'
|
import { createApolloTestSetup } from '@root/test/helpers'
|
||||||
|
|
||||||
import type { ApolloTestSetup } from '@root/test/helpers'
|
import type { ApolloTestSetup } from '@root/test/helpers'
|
||||||
@ -424,7 +425,100 @@ describe('slugifyMiddleware', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it.todo('UpdatePost')
|
describe('UpdatePost', () => {
|
||||||
|
let createPostResult
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
createPostResult = await mutate({
|
||||||
|
mutation: CreatePost,
|
||||||
|
variables: {
|
||||||
|
title: 'I am a brand new post',
|
||||||
|
content: 'Some content',
|
||||||
|
categoryIds,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('if new slug not exists', () => {
|
||||||
|
describe('setting slug explicitly', () => {
|
||||||
|
it('has the new slug', async () => {
|
||||||
|
await expect(
|
||||||
|
mutate({
|
||||||
|
mutation: UpdatePost,
|
||||||
|
variables: {
|
||||||
|
id: createPostResult.data.CreatePost.id,
|
||||||
|
title: 'I am a brand new post',
|
||||||
|
content: 'Some content',
|
||||||
|
slug: 'my-brand-new-post',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).resolves.toMatchObject({
|
||||||
|
data: {
|
||||||
|
UpdatePost: {
|
||||||
|
slug: 'my-brand-new-post',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors: undefined,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('if new slug exists in another post', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await Factory.build(
|
||||||
|
'post',
|
||||||
|
{
|
||||||
|
title: 'Pre-existing post',
|
||||||
|
slug: 'pre-existing-post',
|
||||||
|
content: 'Someone else content',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
categoryIds,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('setting slug explicitly', () => {
|
||||||
|
it('rejects UpdatePost', async () => {
|
||||||
|
try {
|
||||||
|
await expect(
|
||||||
|
mutate({
|
||||||
|
mutation: UpdatePost,
|
||||||
|
variables: {
|
||||||
|
id: createPostResult.data.CreatePost.id,
|
||||||
|
title: 'I am a brand new post',
|
||||||
|
content: 'Some content',
|
||||||
|
slug: 'pre-existing-post',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).resolves.toMatchObject({
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message: 'Post with this slug already exists!',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`
|
||||||
|
${error}
|
||||||
|
|
||||||
|
Probably your database has no unique constraints!
|
||||||
|
|
||||||
|
To see all constraints go to http://localhost:7474/browser/ and
|
||||||
|
paste the following:
|
||||||
|
\`\`\`
|
||||||
|
CALL db.constraints();
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
Learn how to setup the database here:
|
||||||
|
https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/backend/README.md#database-indices-and-constraints
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('SignupVerification', () => {
|
describe('SignupVerification', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user