Files
omnivore/packages/api/test/resolvers/labels.test.ts
Hongbo Wu ae0d1dd2ee Feature/search highlights backend (#395)
* add highlight mappings

* return highlight in resolvers

* temporarily skip highlight tests

* add test for getting highlights

* update merge highlight

* separate elastic methods

* roll back merge highlight test

* add highlight to elastic script

* update delete highlight in elastic

* migrate highlight data from postgres to elastic

* rescue not found exception when page is not found in the migration script

* exclude highlights in searching pages results

* search pages with highlights only with has:highlight query

* add search endpoint to search pages or highlights

* reduce code smell in search api

* fix rebase error

* fix tests

* add test for search highlight

* add test for new search endpoint

* add labels to search results

* update schema

* update search query

* fix update/share highlights

* fix rebase error

* fix tests

* add highlight model in elastic

* add savedAt and publishedAt date range in search query

* add sort by updated and recently read

* fix tests

* close db connection when tests are done

* test github action

* revert github action test

* fix rebase error

* add docker-compose for api-test

* remove unused env

* remove highlights with no page attached to

* allow get_articles resolver to search for query so we can merge it without web changes
2022-04-12 12:31:08 +08:00

323 lines
8.1 KiB
TypeScript

import { createTestLabel, createTestUser, deleteTestUser } from '../db'
import {
createTestElasticPage,
generateFakeUuid,
graphqlRequest,
request,
} from '../util'
import { Label } from '../../src/entity/label'
import { expect } from 'chai'
import 'mocha'
import { User } from '../../src/entity/user'
import { Page } from '../../src/elastic/types'
import { getRepository } from '../../src/entity/utils'
import { getPageById } from '../../src/elastic/pages'
describe('Labels API', () => {
const username = 'fakeUser'
let user: User
let authToken: string
let page: Page
let labels: Label[]
before(async () => {
// create test user and login
user = await createTestUser(username)
const res = await request
.post('/local/debug/fake-user-login')
.send({ fakeEmail: user.email })
authToken = res.body.authToken
// create testing labels
const label1 = await createTestLabel(user, 'label_1', '#ffffff')
const label2 = await createTestLabel(user, 'label_2', '#eeeeee')
labels = [label1, label2]
// create a page with label
const existingLabelOfLink = await createTestLabel(
user,
'different_label',
'#dddddd'
)
page = await createTestElasticPage(user, [existingLabelOfLink])
})
after(async () => {
// clean up
await deleteTestUser(username)
})
describe('GET labels', () => {
let query: string
beforeEach(() => {
query = `
query {
labels {
... on LabelsSuccess {
labels {
id
name
color
description
createdAt
}
}
... on LabelsError {
errorCodes
}
}
}
`
})
it('should return labels', async () => {
const res = await graphqlRequest(query, authToken).expect(200)
const labels = await getRepository(Label).findBy({
user: { id: user.id },
})
expect(res.body.data.labels.labels).to.eql(
labels.reverse().map((label) => ({
id: label.id,
name: label.name,
color: label.color,
description: label.description,
createdAt: new Date(label.createdAt.setMilliseconds(0)).toISOString(),
}))
)
})
it('responds status code 400 when invalid query', async () => {
const invalidQuery = `
query {
labels {}
}
`
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)
})
})
describe('Create label', () => {
let query: string
let name: string
beforeEach(() => {
query = `
mutation {
createLabel(
input: {
color: "#ffffff"
name: "${name}"
}
) {
... on CreateLabelSuccess {
label {
id
name
}
}
... on CreateLabelError {
errorCodes
}
}
}
`
})
context('when name not exists', () => {
before(() => {
name = 'label3'
})
it('should create label', async () => {
const res = await graphqlRequest(query, authToken).expect(200)
const label = await getRepository(Label).findOneBy({
id: res.body.data.createLabel.label.id,
})
expect(label).to.exist
})
})
context('when name exists', () => {
before(() => {
name = labels[0].name
})
it('should return error code LABEL_ALREADY_EXISTS', async () => {
const res = await graphqlRequest(query, authToken).expect(200)
expect(res.body.data.createLabel.errorCodes).to.eql([
'LABEL_ALREADY_EXISTS',
])
})
})
it('responds status code 400 when invalid query', async () => {
const invalidQuery = `
mutation {
createLabel {}
}
`
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)
})
})
describe('Delete label', () => {
let query: string
let labelId: string
beforeEach(() => {
query = `
mutation {
deleteLabel(id: "${labelId}") {
... on DeleteLabelSuccess {
label {
id
name
}
}
... on DeleteLabelError {
errorCodes
}
}
}
`
})
context('when label exists', () => {
before(async () => {
const toDeleteLabel = await createTestLabel(user, 'label4', '#ffffff')
labelId = toDeleteLabel.id
})
it('should delete label', async () => {
await graphqlRequest(query, authToken).expect(200)
const label = await getRepository(Label).findOneBy({ id: labelId })
expect(label).to.not.exist
})
})
context('when label not exist', () => {
before(() => {
labelId = generateFakeUuid()
})
it('should return error code NOT_FOUND', async () => {
const res = await graphqlRequest(query, authToken).expect(200)
expect(res.body.data.deleteLabel.errorCodes).to.eql(['NOT_FOUND'])
})
})
it('responds status code 400 when invalid query', async () => {
const invalidQuery = `
mutation {
deleteLabel {}
}
`
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)
})
})
describe('Set labels', () => {
let query: string
let pageId: string
let labelIds: string[] = []
beforeEach(() => {
query = `
mutation {
setLabels(
input: {
linkId: "${pageId}",
labelIds: [
"${labelIds[0]}",
"${labelIds[1]}"
]
}
) {
... on SetLabelsSuccess {
labels {
id
name
}
}
... on SetLabelsError {
errorCodes
}
}
}
`
})
context('when labels exists', () => {
before(() => {
pageId = page.id
labelIds = [labels[0].id, labels[1].id]
})
it('should set labels', async () => {
await graphqlRequest(query, authToken).expect(200)
const page = await getPageById(pageId)
expect(page?.labels?.map((l) => l.id)).to.eql(labelIds)
})
})
context('when labels not exist', () => {
before(() => {
pageId = page.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(() => {
pageId = 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)
})
})
})