mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
add setLabels api and tests
This commit is contained in:
parent
138c9682cd
commit
d33b213092
10 changed files with 333 additions and 28 deletions
|
|
@ -4,13 +4,10 @@ import {
|
|||
CreateDateColumn,
|
||||
Entity,
|
||||
JoinColumn,
|
||||
JoinTable,
|
||||
ManyToMany,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
} from 'typeorm'
|
||||
import { User } from './user'
|
||||
import { Link } from './link'
|
||||
|
||||
@Entity({ name: 'labels' })
|
||||
export class Label extends BaseEntity {
|
||||
|
|
@ -24,10 +21,6 @@ export class Label extends BaseEntity {
|
|||
@JoinColumn({ name: 'user_id' })
|
||||
user!: User
|
||||
|
||||
@ManyToMany(() => Link, (link) => link.labels)
|
||||
@JoinTable({ name: 'link_labels' })
|
||||
link?: Link
|
||||
|
||||
@Column('text')
|
||||
color!: string
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,11 @@ export class Link extends BaseEntity {
|
|||
@UpdateDateColumn()
|
||||
updatedAt?: Date
|
||||
|
||||
@ManyToMany(() => Label, (label) => label.link)
|
||||
@JoinTable({ name: 'link_labels' })
|
||||
@ManyToMany(() => Label)
|
||||
@JoinTable({
|
||||
name: 'link_labels',
|
||||
joinColumn: { name: 'link_id' },
|
||||
inverseJoinColumn: { name: 'label_id' },
|
||||
})
|
||||
labels?: Label[]
|
||||
}
|
||||
|
|
|
|||
27
packages/api/src/entity/link_label.ts
Normal file
27
packages/api/src/entity/link_label.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import {
|
||||
BaseEntity,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
} from 'typeorm'
|
||||
import { Link } from './link'
|
||||
import { Label } from './label'
|
||||
|
||||
@Entity({ name: 'link_labels' })
|
||||
export class LinkLabel extends BaseEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string
|
||||
|
||||
@ManyToOne(() => Link)
|
||||
@JoinColumn({ name: 'link_id' })
|
||||
link!: Link
|
||||
|
||||
@ManyToOne(() => Label)
|
||||
@JoinColumn({ name: 'label_id' })
|
||||
label!: Label
|
||||
|
||||
@CreateDateColumn()
|
||||
createdAt!: Date
|
||||
}
|
||||
|
|
@ -778,6 +778,7 @@ export type Mutation = {
|
|||
setBookmarkArticle: SetBookmarkArticleResult;
|
||||
setDeviceToken: SetDeviceTokenResult;
|
||||
setFollow: SetFollowResult;
|
||||
setLabels: SetLabelsResult;
|
||||
setLinkArchived: ArchiveLinkResult;
|
||||
setShareArticle: SetShareArticleResult;
|
||||
setShareHighlight: SetShareHighlightResult;
|
||||
|
|
@ -919,6 +920,11 @@ export type MutationSetFollowArgs = {
|
|||
};
|
||||
|
||||
|
||||
export type MutationSetLabelsArgs = {
|
||||
input: SetLabelsInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationSetLinkArchivedArgs = {
|
||||
input: ArchiveLinkInput;
|
||||
};
|
||||
|
|
@ -1350,6 +1356,29 @@ export type SetFollowSuccess = {
|
|||
updatedUser: User;
|
||||
};
|
||||
|
||||
export type SetLabelsError = {
|
||||
__typename?: 'SetLabelsError';
|
||||
errorCodes: Array<SetLabelsErrorCode>;
|
||||
};
|
||||
|
||||
export enum SetLabelsErrorCode {
|
||||
BadRequest = 'BAD_REQUEST',
|
||||
NotFound = 'NOT_FOUND',
|
||||
Unauthorized = 'UNAUTHORIZED'
|
||||
}
|
||||
|
||||
export type SetLabelsInput = {
|
||||
labelIds: Array<Scalars['ID']>;
|
||||
linkId: Scalars['ID'];
|
||||
};
|
||||
|
||||
export type SetLabelsResult = SetLabelsError | SetLabelsSuccess;
|
||||
|
||||
export type SetLabelsSuccess = {
|
||||
__typename?: 'SetLabelsSuccess';
|
||||
labels: Array<Label>;
|
||||
};
|
||||
|
||||
export type SetShareArticleError = {
|
||||
__typename?: 'SetShareArticleError';
|
||||
errorCodes: Array<SetShareArticleErrorCode>;
|
||||
|
|
@ -2014,6 +2043,11 @@ export type ResolversTypes = {
|
|||
SetFollowInput: SetFollowInput;
|
||||
SetFollowResult: ResolversTypes['SetFollowError'] | ResolversTypes['SetFollowSuccess'];
|
||||
SetFollowSuccess: ResolverTypeWrapper<SetFollowSuccess>;
|
||||
SetLabelsError: ResolverTypeWrapper<SetLabelsError>;
|
||||
SetLabelsErrorCode: SetLabelsErrorCode;
|
||||
SetLabelsInput: SetLabelsInput;
|
||||
SetLabelsResult: ResolversTypes['SetLabelsError'] | ResolversTypes['SetLabelsSuccess'];
|
||||
SetLabelsSuccess: ResolverTypeWrapper<SetLabelsSuccess>;
|
||||
SetShareArticleError: ResolverTypeWrapper<SetShareArticleError>;
|
||||
SetShareArticleErrorCode: SetShareArticleErrorCode;
|
||||
SetShareArticleInput: SetShareArticleInput;
|
||||
|
|
@ -2250,6 +2284,10 @@ export type ResolversParentTypes = {
|
|||
SetFollowInput: SetFollowInput;
|
||||
SetFollowResult: ResolversParentTypes['SetFollowError'] | ResolversParentTypes['SetFollowSuccess'];
|
||||
SetFollowSuccess: SetFollowSuccess;
|
||||
SetLabelsError: SetLabelsError;
|
||||
SetLabelsInput: SetLabelsInput;
|
||||
SetLabelsResult: ResolversParentTypes['SetLabelsError'] | ResolversParentTypes['SetLabelsSuccess'];
|
||||
SetLabelsSuccess: SetLabelsSuccess;
|
||||
SetShareArticleError: SetShareArticleError;
|
||||
SetShareArticleInput: SetShareArticleInput;
|
||||
SetShareArticleResult: ResolversParentTypes['SetShareArticleError'] | ResolversParentTypes['SetShareArticleSuccess'];
|
||||
|
|
@ -2878,6 +2916,7 @@ export type MutationResolvers<ContextType = ResolverContext, ParentType extends
|
|||
setBookmarkArticle?: Resolver<ResolversTypes['SetBookmarkArticleResult'], ParentType, ContextType, RequireFields<MutationSetBookmarkArticleArgs, 'input'>>;
|
||||
setDeviceToken?: Resolver<ResolversTypes['SetDeviceTokenResult'], ParentType, ContextType, RequireFields<MutationSetDeviceTokenArgs, 'input'>>;
|
||||
setFollow?: Resolver<ResolversTypes['SetFollowResult'], ParentType, ContextType, RequireFields<MutationSetFollowArgs, 'input'>>;
|
||||
setLabels?: Resolver<ResolversTypes['SetLabelsResult'], ParentType, ContextType, RequireFields<MutationSetLabelsArgs, 'input'>>;
|
||||
setLinkArchived?: Resolver<ResolversTypes['ArchiveLinkResult'], ParentType, ContextType, RequireFields<MutationSetLinkArchivedArgs, 'input'>>;
|
||||
setShareArticle?: Resolver<ResolversTypes['SetShareArticleResult'], ParentType, ContextType, RequireFields<MutationSetShareArticleArgs, 'input'>>;
|
||||
setShareHighlight?: Resolver<ResolversTypes['SetShareHighlightResult'], ParentType, ContextType, RequireFields<MutationSetShareHighlightArgs, 'input'>>;
|
||||
|
|
@ -3084,6 +3123,20 @@ export type SetFollowSuccessResolvers<ContextType = ResolverContext, ParentType
|
|||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type SetLabelsErrorResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['SetLabelsError'] = ResolversParentTypes['SetLabelsError']> = {
|
||||
errorCodes?: Resolver<Array<ResolversTypes['SetLabelsErrorCode']>, ParentType, ContextType>;
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type SetLabelsResultResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['SetLabelsResult'] = ResolversParentTypes['SetLabelsResult']> = {
|
||||
__resolveType: TypeResolveFn<'SetLabelsError' | 'SetLabelsSuccess', ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type SetLabelsSuccessResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['SetLabelsSuccess'] = ResolversParentTypes['SetLabelsSuccess']> = {
|
||||
labels?: Resolver<Array<ResolversTypes['Label']>, ParentType, ContextType>;
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type SetShareArticleErrorResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['SetShareArticleError'] = ResolversParentTypes['SetShareArticleError']> = {
|
||||
errorCodes?: Resolver<Array<ResolversTypes['SetShareArticleErrorCode']>, ParentType, ContextType>;
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
|
|
@ -3460,6 +3513,9 @@ export type Resolvers<ContextType = ResolverContext> = {
|
|||
SetFollowError?: SetFollowErrorResolvers<ContextType>;
|
||||
SetFollowResult?: SetFollowResultResolvers<ContextType>;
|
||||
SetFollowSuccess?: SetFollowSuccessResolvers<ContextType>;
|
||||
SetLabelsError?: SetLabelsErrorResolvers<ContextType>;
|
||||
SetLabelsResult?: SetLabelsResultResolvers<ContextType>;
|
||||
SetLabelsSuccess?: SetLabelsSuccessResolvers<ContextType>;
|
||||
SetShareArticleError?: SetShareArticleErrorResolvers<ContextType>;
|
||||
SetShareArticleResult?: SetShareArticleResultResolvers<ContextType>;
|
||||
SetShareArticleSuccess?: SetShareArticleSuccessResolvers<ContextType>;
|
||||
|
|
|
|||
|
|
@ -691,6 +691,7 @@ type Mutation {
|
|||
setBookmarkArticle(input: SetBookmarkArticleInput!): SetBookmarkArticleResult!
|
||||
setDeviceToken(input: SetDeviceTokenInput!): SetDeviceTokenResult!
|
||||
setFollow(input: SetFollowInput!): SetFollowResult!
|
||||
setLabels(input: SetLabelsInput!): SetLabelsResult!
|
||||
setLinkArchived(input: ArchiveLinkInput!): ArchiveLinkResult!
|
||||
setShareArticle(input: SetShareArticleInput!): SetShareArticleResult!
|
||||
setShareHighlight(input: SetShareHighlightInput!): SetShareHighlightResult!
|
||||
|
|
@ -989,6 +990,27 @@ type SetFollowSuccess {
|
|||
updatedUser: User!
|
||||
}
|
||||
|
||||
type SetLabelsError {
|
||||
errorCodes: [SetLabelsErrorCode!]!
|
||||
}
|
||||
|
||||
enum SetLabelsErrorCode {
|
||||
BAD_REQUEST
|
||||
NOT_FOUND
|
||||
UNAUTHORIZED
|
||||
}
|
||||
|
||||
input SetLabelsInput {
|
||||
labelIds: [ID!]!
|
||||
linkId: ID!
|
||||
}
|
||||
|
||||
union SetLabelsResult = SetLabelsError | SetLabelsSuccess
|
||||
|
||||
type SetLabelsSuccess {
|
||||
labels: [Label!]!
|
||||
}
|
||||
|
||||
type SetShareArticleError {
|
||||
errorCodes: [SetShareArticleErrorCode!]!
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ import {
|
|||
setBookmarkArticleResolver,
|
||||
setDeviceTokenResolver,
|
||||
setFollowResolver,
|
||||
setLabelsResolver,
|
||||
setLinkArchivedResolver,
|
||||
setShareArticleResolver,
|
||||
setShareHighlightResolver,
|
||||
|
|
@ -135,6 +136,7 @@ export const functionResolvers = {
|
|||
deleteLabel: deleteLabelResolver,
|
||||
login: loginResolver,
|
||||
signup: signupResolver,
|
||||
setLabels: setLabelsResolver,
|
||||
},
|
||||
Query: {
|
||||
me: getMeUserResolver,
|
||||
|
|
@ -525,4 +527,5 @@ export const functionResolvers = {
|
|||
...resultResolveTypeResolver('DeleteLabel'),
|
||||
...resultResolveTypeResolver('Login'),
|
||||
...resultResolveTypeResolver('Signup'),
|
||||
...resultResolveTypeResolver('SetLabels'),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ import {
|
|||
LabelsSuccess,
|
||||
MutationCreateLabelArgs,
|
||||
MutationDeleteLabelArgs,
|
||||
MutationSetLabelsArgs,
|
||||
SetLabelsError,
|
||||
SetLabelsErrorCode,
|
||||
SetLabelsSuccess,
|
||||
} from '../../generated/graphql'
|
||||
import { analytics } from '../../utils/analytics'
|
||||
import { env } from '../../env'
|
||||
|
|
@ -18,6 +22,8 @@ import { User } from '../../entity/user'
|
|||
import { Label } from '../../entity/label'
|
||||
import { getManager, getRepository } from 'typeorm'
|
||||
import { setClaims } from '../../entity/utils'
|
||||
import { Link } from '../../entity/link'
|
||||
import { LinkLabel } from '../../entity/link_label'
|
||||
|
||||
export const labelsResolver = authorized<LabelsSuccess, LabelsError>(
|
||||
async (_obj, _params, { claims: { uid }, log }) => {
|
||||
|
|
@ -172,3 +178,70 @@ export const deleteLabelResolver = authorized<
|
|||
}
|
||||
}
|
||||
})
|
||||
|
||||
export const setLabelsResolver = authorized<
|
||||
SetLabelsSuccess,
|
||||
SetLabelsError,
|
||||
MutationSetLabelsArgs
|
||||
>(async (_, { input }, { claims: { uid }, log }) => {
|
||||
log.info('setLabelsResolver')
|
||||
|
||||
const { linkId, labelIds } = input
|
||||
|
||||
try {
|
||||
const user = await getRepository(User).findOne(uid)
|
||||
if (!user) {
|
||||
return {
|
||||
errorCodes: [SetLabelsErrorCode.Unauthorized],
|
||||
}
|
||||
}
|
||||
|
||||
const link = await getRepository(Link).findOne(linkId)
|
||||
if (!link) {
|
||||
return {
|
||||
errorCodes: [SetLabelsErrorCode.NotFound],
|
||||
}
|
||||
}
|
||||
|
||||
const labels = await getRepository(Label).findByIds(labelIds, {
|
||||
where: {
|
||||
user,
|
||||
},
|
||||
relations: ['user'],
|
||||
})
|
||||
if (labels.length !== labelIds.length) {
|
||||
return {
|
||||
errorCodes: [SetLabelsErrorCode.NotFound],
|
||||
}
|
||||
}
|
||||
|
||||
// delete all existing labels of the link
|
||||
await getManager().transaction(async (t) => {
|
||||
await t.getRepository(LinkLabel).delete({ link })
|
||||
|
||||
// add new labels
|
||||
await t
|
||||
.getRepository(LinkLabel)
|
||||
.save(labels.map((label) => ({ link, label })))
|
||||
})
|
||||
|
||||
analytics.track({
|
||||
userId: uid,
|
||||
event: 'setLabels',
|
||||
properties: {
|
||||
linkId,
|
||||
labelIds,
|
||||
env: env.server.apiEnv,
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
labels,
|
||||
}
|
||||
} catch (error) {
|
||||
log.error(error)
|
||||
return {
|
||||
errorCodes: [SetLabelsErrorCode.BadRequest],
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1326,6 +1326,27 @@ const schema = gql`
|
|||
|
||||
union SignupResult = SignupSuccess | SignupError
|
||||
|
||||
input SetLabelsInput {
|
||||
linkId: ID!
|
||||
labelIds: [ID!]!
|
||||
}
|
||||
|
||||
union SetLabelsResult = SetLabelsSuccess | SetLabelsError
|
||||
|
||||
type SetLabelsSuccess {
|
||||
labels: [Label!]!
|
||||
}
|
||||
|
||||
type SetLabelsError {
|
||||
errorCodes: [SetLabelsErrorCode!]!
|
||||
}
|
||||
|
||||
enum SetLabelsErrorCode {
|
||||
UNAUTHORIZED
|
||||
BAD_REQUEST
|
||||
NOT_FOUND
|
||||
}
|
||||
|
||||
# Mutations
|
||||
type Mutation {
|
||||
googleLogin(input: GoogleLoginInput!): LoginResult!
|
||||
|
|
@ -1384,6 +1405,7 @@ const schema = gql`
|
|||
deleteLabel(id: ID!): DeleteLabelResult!
|
||||
login(input: LoginInput!): LoginResult!
|
||||
signup(input: SignupInput!): SignupResult!
|
||||
setLabels(input: SetLabelsInput!): SetLabelsResult!
|
||||
}
|
||||
|
||||
# FIXME: remove sort from feedArticles after all cahced tabs are closed
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { Link } from '../src/entity/link'
|
|||
import { Reminder } from '../src/entity/reminder'
|
||||
import { NewsletterEmail } from '../src/entity/newsletter_email'
|
||||
import { UserDeviceToken } from '../src/entity/user_device_tokens'
|
||||
import { Label } from '../src/entity/label'
|
||||
|
||||
const runMigrations = async () => {
|
||||
const migrationDirectory = __dirname + '/../../db/migrations'
|
||||
|
|
@ -200,3 +201,17 @@ export const getUser = async (id: string): Promise<User | undefined> => {
|
|||
export const getLink = async (id: string): Promise<Link | undefined> => {
|
||||
return getRepository(Link).findOne(id)
|
||||
}
|
||||
|
||||
export const createTestLabel = async (
|
||||
user: User,
|
||||
name: string,
|
||||
color: string
|
||||
): Promise<Label> => {
|
||||
return getRepository(Label)
|
||||
.create({
|
||||
user: user,
|
||||
name: name,
|
||||
color: color,
|
||||
})
|
||||
.save()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import {
|
||||
createTestLabel,
|
||||
createTestLink,
|
||||
createTestPage,
|
||||
createTestUser,
|
||||
|
|
@ -11,10 +12,13 @@ import { expect } from 'chai'
|
|||
import { Page } from '../../src/entity/page'
|
||||
import { getRepository } from 'typeorm'
|
||||
import 'mocha'
|
||||
import { LinkLabel } from '../../src/entity/link_label'
|
||||
import { User } from '../../src/entity/user'
|
||||
|
||||
describe('Labels API', () => {
|
||||
const username = 'fakeUser'
|
||||
|
||||
let user: User
|
||||
let authToken: string
|
||||
let page: Page
|
||||
let link: Link
|
||||
|
|
@ -22,31 +26,30 @@ describe('Labels API', () => {
|
|||
|
||||
before(async () => {
|
||||
// create test user and login
|
||||
const user = await createTestUser(username)
|
||||
user = await createTestUser(username)
|
||||
const res = await request
|
||||
.post('/local/debug/fake-user-login')
|
||||
.send({ fakeEmail: user.email })
|
||||
|
||||
authToken = res.body.authToken
|
||||
|
||||
// create test label
|
||||
// create testing labels
|
||||
const label1 = await createTestLabel(user, 'label_1', '#ffffff')
|
||||
const label2 = await createTestLabel(user, 'label_2', '#eeeeee')
|
||||
labels = [label1, label2]
|
||||
|
||||
page = await createTestPage()
|
||||
link = await createTestLink(user, page)
|
||||
const label1 = await getRepository(Label)
|
||||
.create({
|
||||
name: 'label1',
|
||||
user: user,
|
||||
color: '#ffffff',
|
||||
})
|
||||
.save()
|
||||
const label2 = await getRepository(Label)
|
||||
.create({
|
||||
name: 'label2',
|
||||
user: user,
|
||||
color: '#eeeeee',
|
||||
})
|
||||
.save()
|
||||
labels = [label1, label2]
|
||||
const existingLabelOfLink = await createTestLabel(
|
||||
user,
|
||||
'different_label',
|
||||
'#dddddd'
|
||||
)
|
||||
// set another label to link
|
||||
await getRepository(LinkLabel).save({
|
||||
link,
|
||||
label: existingLabelOfLink,
|
||||
})
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
|
|
@ -81,6 +84,7 @@ describe('Labels API', () => {
|
|||
it('should return labels', async () => {
|
||||
const res = await graphqlRequest(query, authToken).expect(200)
|
||||
|
||||
const labels = await getRepository(Label).find({ where: { user } })
|
||||
expect(res.body.data.labels.labels).to.eql(
|
||||
labels.map((label) => ({
|
||||
id: label.id,
|
||||
|
|
@ -200,8 +204,9 @@ describe('Labels API', () => {
|
|||
})
|
||||
|
||||
context('when label exists', () => {
|
||||
before(() => {
|
||||
labelId = labels[0].id
|
||||
before(async () => {
|
||||
const toDeleteLabel = await createTestLabel(user, 'label4', '#ffffff')
|
||||
labelId = toDeleteLabel.id
|
||||
})
|
||||
|
||||
it('should delete label', async () => {
|
||||
|
|
@ -237,4 +242,89 @@ describe('Labels API', () => {
|
|||
return graphqlRequest(query, invalidAuthToken).expect(500)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Set labels', () => {
|
||||
let query: string
|
||||
let linkId: string
|
||||
let labelIds: string[] = []
|
||||
|
||||
beforeEach(() => {
|
||||
query = `
|
||||
mutation {
|
||||
setLabels(
|
||||
input: {
|
||||
linkId: "${linkId}",
|
||||
labelIds: [
|
||||
"${labelIds[0]}",
|
||||
"${labelIds[1]}"
|
||||
]
|
||||
}
|
||||
) {
|
||||
... on SetLabelsSuccess {
|
||||
labels {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
... on SetLabelsError {
|
||||
errorCodes
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
})
|
||||
|
||||
context('when labels exists', () => {
|
||||
before(() => {
|
||||
linkId = link.id
|
||||
labelIds = [labels[0].id, labels[1].id]
|
||||
})
|
||||
|
||||
it('should set labels', async () => {
|
||||
await graphqlRequest(query, authToken).expect(200)
|
||||
const link = await getRepository(Link).findOne(linkId, {
|
||||
relations: ['labels'],
|
||||
})
|
||||
expect(link?.labels?.map((l) => l.id)).to.eql(labelIds)
|
||||
})
|
||||
})
|
||||
|
||||
context('when labels not exist', () => {
|
||||
before(() => {
|
||||
linkId = link.id
|
||||
labelIds = [generateFakeUuid(), generateFakeUuid()]
|
||||
})
|
||||
|
||||
it('should return error code NOT_FOUND', async () => {
|
||||
const res = await graphqlRequest(query, authToken).expect(200)
|
||||
expect(res.body.data.setLabels.errorCodes).to.eql(['NOT_FOUND'])
|
||||
})
|
||||
})
|
||||
|
||||
context('when link not exist', () => {
|
||||
before(() => {
|
||||
linkId = generateFakeUuid()
|
||||
labelIds = [labels[0].id, labels[1].id]
|
||||
})
|
||||
|
||||
it('should return error code NOT_FOUND', async () => {
|
||||
const res = await graphqlRequest(query, authToken).expect(200)
|
||||
expect(res.body.data.setLabels.errorCodes).to.eql(['NOT_FOUND'])
|
||||
})
|
||||
})
|
||||
|
||||
it('responds status code 400 when invalid query', async () => {
|
||||
const invalidQuery = `
|
||||
mutation {
|
||||
setLabels {}
|
||||
}
|
||||
`
|
||||
return graphqlRequest(invalidQuery, authToken).expect(400)
|
||||
})
|
||||
|
||||
it('responds status code 500 when invalid user', async () => {
|
||||
const invalidAuthToken = 'Fake token'
|
||||
return graphqlRequest(query, invalidAuthToken).expect(500)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue