search specs refactored

This commit is contained in:
Moriz Wahl 2020-03-13 22:34:51 +01:00 committed by mattwr18
parent 3d25ec5b4e
commit 46fca229ec

View File

@ -3,15 +3,12 @@ import { gql } from '../../helpers/jest'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
import { createTestClient } from 'apollo-server-testing'
import cloneDeep from 'lodash/cloneDeep'
let query, authenticatedUser
const driver = getDriver()
const neode = getNeode()
jest.setTimeout(30000)
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
@ -48,104 +45,34 @@ const searchQuery = gql`
}
`
const addBrAfterNewline = array => {
return array.map(obj => {
const tmp = cloneDeep(obj)
if (tmp.__typename === 'Post') {
tmp.content = tmp.content.replace(/\n/g, '<br>\n')
}
return tmp
})
}
const createExpectedObject = array => {
return { data: { findResources: addBrAfterNewline(array) } }
}
const addPostToDB = post => {
return Factory.build(
'post',
{
id: post.id,
title: post.title,
content: post.content,
},
{
authorId: 'a-user',
},
)
}
const addUserToDB = user => {
return Factory.build('user', {
id: user.id,
name: user.name,
slug: user.slug,
})
}
const dumpToDB = array => {
const result = []
array.forEach(obj => {
obj.__typename === 'Post' ? result.push(addPostToDB(obj)) : result.push(addUserToDB(obj))
})
return result
}
const createDataObject = (obj, type) => {
return { __typename: type, ...obj }
}
const createPostObject = post => {
return createDataObject(post, 'Post')
}
const createUserObject = user => {
return createDataObject(user, 'User')
}
// see data at the end of the file
let user
describe('resolvers', () => {
describe('searches', () => {
let variables
describe('given one post and one user', () => {
describe('given one user', () => {
beforeAll(async () => {
user = await addUserToDB(aUser)
await addPostToDB(aPost)
const user = await Factory.build('user', {
id: 'a-user',
name: 'John Doe',
slug: 'john-doe',
})
authenticatedUser = await user.toJson()
})
it('finds the post', async () => {
variables = { query: 'beitrag' }
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
data: {
findResources: [
{
__typename: 'Post',
id: 'a-post',
title: 'Beitrag',
content: 'Ein erster Beitrag',
},
],
},
})
})
const factoryOptions = {
authorId: 'a-user',
}
describe('casing', () => {
it('does not matter', async () => {
variables = { query: 'BEITRAG' }
describe('query contains first name of user', () => {
it('finds the user', async () => {
variables = { query: 'John' }
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
data: {
findResources: [
{
__typename: 'Post',
id: 'a-post',
title: 'Beitrag',
content: 'Ein erster Beitrag',
id: 'a-user',
name: 'John Doe',
slug: 'john-doe',
},
],
},
@ -153,208 +80,333 @@ describe('resolvers', () => {
})
})
describe('query contains first name of user', () => {
it('finds the user', async () => {
variables = { query: 'John' }
const expected = createExpectedObject([aUser])
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject(expected)
})
})
describe('query consists of words not present in the corpus', () => {
it('returns empty search results', async () => {
await expect(
query({ query: searchQuery, variables: { query: 'Unfug' } }),
).resolves.toMatchObject({ data: { findResources: [] } })
})
})
describe('given more posts and users', () => {
describe('adding one post', () => {
beforeAll(async () => {
const factoryOptions = {
authorId: 'a-user',
}
await Promise.all([
Factory.build(
await Factory.build(
'post',
{
id: 'a-post',
title: 'Beitrag',
content: 'Ein erster Beitrag',
},
factoryOptions,
)
})
describe('query contains title of post', () => {
it('finds the post', async () => {
variables = { query: 'beitrag' }
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
data: {
findResources: [
{
__typename: 'Post',
id: 'a-post',
title: 'Beitrag',
content: 'Ein erster Beitrag',
},
],
},
})
})
})
describe('casing', () => {
it('does not matter', async () => {
variables = { query: 'BEITRAG' }
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
data: {
findResources: [
{
__typename: 'Post',
id: 'a-post',
title: 'Beitrag',
content: 'Ein erster Beitrag',
},
],
},
})
})
})
describe('query consists of words not present in the corpus', () => {
it('returns empty search results', async () => {
await expect(
query({ query: searchQuery, variables: { query: 'Unfug' } }),
).resolves.toMatchObject({ data: { findResources: [] } })
})
})
describe('testing different post content', () => {
const addPost = post => {
return Factory.build(
'post',
{
id: 'b-post',
title: 'Aufruf',
content: 'Jeder sollte seinen Beitrag leisten.',
id: post.id,
title: post.title,
content: post.content,
},
factoryOptions,
),
...dumpToDB([
cPost,
dPost,
ePost,
fPost,
gPost,
bUser,
cUser,
dUser,
eUser,
fUser,
gUser,
]),
])
})
)
}
describe('hyphens in query', () => {
it('will be treated as ordinary characters', async () => {
variables = { query: 'AK-47' }
const expected = createExpectedObject([gPost])
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject(expected)
describe('adding a post which content contains the title of the first post', () => {
describe('query contains the title of the first post', () => {
it('finds both posts', async () => {
await addPost({
__typename: 'Post',
id: 'b-post',
title: 'Aufruf',
content: 'Jeder sollte seinen Beitrag leisten.',
})
variables = { query: 'beitrag' }
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
data: {
findResources: expect.arrayContaining([
{
__typename: 'Post',
id: 'a-post',
title: 'Beitrag',
content: 'Ein erster Beitrag',
},
{
__typename: 'Post',
id: 'b-post',
title: 'Aufruf',
content: 'Jeder sollte seinen Beitrag leisten.',
},
]),
},
})
})
})
})
describe('adding a post that contains a hyphen between two words and German quotation marks', () => {
describe('hyphens in query', () => {
it('will be treated as ordinary characters', async () => {
await addPost({
id: 'g-post',
title: 'Zusammengesetzte Wörter',
content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
})
variables = { query: 'tee-ei' }
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
data: {
findResources: [
{
__typename: 'Post',
id: 'g-post',
title: 'Zusammengesetzte Wörter',
content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
},
],
},
})
})
})
describe('German quotation marks in query', () => {
it('will be treated as ordinary characters', async () => {
variables = { query: '„teeei“' }
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
data: {
findResources: [
{
__typename: 'Post',
id: 'g-post',
title: 'Zusammengesetzte Wörter',
content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
},
],
},
})
})
})
})
describe('adding a post that contains a simple mathematical exprssion and linebreaks', () => {
describe('query a part of the mathematical expression', () => {
it('finds that post', async () => {
await addPost({
id: 'c-post',
title: 'Die binomischen Formeln',
content: `1. binomische Formel: (a + b)² = a² + 2ab + b²
2. binomische Formel: (a - b)² = - 2ab +
3. binomische Formel: (a + b)(a - b) = - `,
})
variables = { query: '(a - b)²' }
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
data: {
findResources: [
{
__typename: 'Post',
id: 'c-post',
title: 'Die binomischen Formeln',
content: `1. binomische Formel: (a + b)² = a² + 2ab + b²<br>
2. binomische Formel: (a - b)² = - 2ab + <br>
3. binomische Formel: (a + b)(a - b) = - `,
},
],
},
})
})
})
describe('query the same part of the mathematical expression without spaces', () => {
it('finds that post', async () => {
variables = { query: '(a-b)²' }
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
data: {
findResources: [
{
__typename: 'Post',
id: 'c-post',
title: 'Die binomischen Formeln',
content: `1. binomische Formel: (a + b)² = a² + 2ab + b²<br>
2. binomische Formel: (a - b)² = - 2ab + <br>
3. binomische Formel: (a + b)(a - b) = - `,
},
],
},
})
})
})
describe('query the mathematical expression over linebreak', () => {
it('finds that post', async () => {
variables = { query: '+ b² 2.' }
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
data: {
findResources: [
{
__typename: 'Post',
id: 'c-post',
title: 'Die binomischen Formeln',
content: `1. binomische Formel: (a + b)² = a² + 2ab + b²<br>
2. binomische Formel: (a - b)² = - 2ab + <br>
3. binomische Formel: (a + b)(a - b) = - `,
},
],
},
})
})
})
})
describe('adding a post that contains a poem', () => {
describe('query for more than one word, e.g. the title of the poem', () => {
it('finds the poem and another post that contains only one word but with lower score', async () => {
await addPost({
id: 'd-post',
title: 'Der Panther',
content: `Sein Blick ist vom Vorübergehn der Stäbe
so müd geworden, daß er nichts mehr hält.
Ihm ist, als ob es tausend Stäbe gäbe
und hinter tausend Stäben keine Welt.`,
})
variables = { query: 'der panther' }
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
data: {
findResources: [
{
__typename: 'Post',
id: 'd-post',
title: 'Der Panther',
content: `Sein Blick ist vom Vorübergehn der Stäbe<br>
so müd geworden, daß er nichts mehr hält.<br>
Ihm ist, als ob es tausend Stäbe gäbe<br>
und hinter tausend Stäben keine Welt.`,
},
{
__typename: 'Post',
id: 'g-post',
title: 'Zusammengesetzte Wörter',
content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
},
],
},
})
})
})
describe('query for the first four letters of two longer words', () => {
it('finds the posts that contain words starting with these four letters', async () => {
variables = { query: 'Vorü Subs' }
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
data: {
findResources: expect.arrayContaining([
{
__typename: 'Post',
id: 'd-post',
title: 'Der Panther',
content: `Sein Blick ist vom Vorübergehn der Stäbe<br>
so müd geworden, daß er nichts mehr hält.<br>
Ihm ist, als ob es tausend Stäbe gäbe<br>
und hinter tausend Stäben keine Welt.`,
},
{
__typename: 'Post',
id: 'g-post',
title: 'Zusammengesetzte Wörter',
content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
},
]),
},
})
})
})
})
})
it('finds more than one post', async () => {
variables = { query: 'Beitrag' }
const expected = createExpectedObject([aPost, bPost])
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject(expected)
})
describe('adding two users that have the same word in their slugs', () => {
beforeAll(async () => {
await Promise.all([
Factory.build('user', {
id: 'c-user',
name: 'Rainer Maria Rilke',
slug: 'rainer-maria-rilke',
}),
Factory.build('user', {
id: 'd-user',
name: 'Erich Maria Remarque',
slug: 'erich-maria-remarque',
}),
])
})
it('finds more than one user by slug', async () => {
variables = { query: '-maria-' }
const expected = [cUser, dUser]
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
data: {
findResources: expect.arrayContaining(expected),
},
describe('query the word that both slugs contain', () => {
it('finds both users', async () => {
variables = { query: '-maria-' }
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
data: {
findResources: expect.arrayContaining([
{
__typename: 'User',
id: 'c-user',
name: 'Rainer Maria Rilke',
slug: 'rainer-maria-rilke',
},
{
__typename: 'User',
id: 'd-user',
name: 'Erich Maria Remarque',
slug: 'erich-maria-remarque',
},
]),
},
})
})
})
})
})
it('finds the binomial formula', async () => {
variables = { query: '(a - b)² = a² - 2ab + b²' }
const expected = createExpectedObject([cPost])
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject(expected)
})
it('finds text over linebreak', async () => {
variables = { query: 'dreht, ist' }
const expected = createExpectedObject([dPost])
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject(expected)
})
it('finds single words with lower score', async () => {
variables = { query: 'der Panther' }
const expected = createExpectedObject([dPost, ePost, fPost, bUser])
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject(expected)
})
it('finds something that starts with the given text', async () => {
variables = { query: 'john' }
const expected = createExpectedObject([aUser, bUser])
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject(expected)
})
/*
/*
it('finds Russian text', async () => {
variables = { query: 'Калашникова' }
const expected = createExpectedObject([gPost])
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject(expected)
}) */
})
}) */
})
})
})
// data section
const aPost = createPostObject({
id: 'a-post',
title: 'Beitrag',
content: 'Ein erster Beitrag',
})
const bPost = createPostObject({
id: 'b-post',
title: 'Aufruf',
content: 'Jeder sollte seinen Beitrag leisten.',
})
const cPost = createPostObject({
id: 'c-post',
title: 'Die binomischen Formeln',
content: `1. binomische Formel: (a + b)² = a² + 2ab + b²
2. binomische Formel: (a - b)² = - 2ab +
3. binomische Formel: (a + b)(a - b) = - `,
})
const dPost = createPostObject({
id: 'd-post',
title: 'Der Panther',
content: `Sein Blick ist vom Vorübergehn der Stäbe
so müd geworden, daß er nichts mehr hält.
Ihm ist, als ob es tausend Stäbe gäbe
und hinter tausend Stäben keine Welt.
Der weiche Gang geschmeidig starker Schritte,
der sich im allerkleinsten Kreise dreht,
ist wie ein Tanz von Kraft um eine Mitte,
in der betäubt ein großer Wille steht.
Nur manchmal schiebt der Vorhang der Pupille
sich lautlos auf . Dann geht ein Bild hinein,
geht durch der Glieder angespannte Stille
und hört im Herzen auf zu sein.`,
})
const ePost = createPostObject({
id: 'e-post',
title: 'Typographie',
content: `Gelegentlich können sowohl der angeführte Text als auch der Begleitsatz mit Frage- oder Ausrufezeichen enden (§ 91):
Gefällt dir der Roman Quo vadis?? Lass doch dieses ewige Ich will nicht!!`,
})
const fPost = createPostObject({
id: 'f-post',
title: 'Typographie II',
content: `Der Gedankenstrich kann als Auslassungszeichen (Auslassungsstrich) eine längere Pause oder eine Ellipse darstellen: „Du willst doch wohl nicht etwa –“, „Mein Gott, woher nehm ich bloß ?“`,
})
const gPost = createPostObject({
id: 'g-post',
title: 'AK-47',
content: `Vom AK-47 Typ I existiert eine Version mit unter die Waffe klappbarer Schulterstütze, das AKS-47 (russisch Автомат Калашникова складной образца 1947 года, transkr.: Avtomat Kalašnikova skladnoj obrazca 1947 goda, dt. Automat Kalaschnikow klappbar Modell 1947tes Jahr) genannt wird, seltener auch AK-47s.`,
})
const aUser = createUserObject({
id: 'a-user',
name: 'John Doe',
slug: 'john-doe',
})
const bUser = createUserObject({
id: 'b-user',
name: 'Johnannes der Täufer',
slug: 'johnannes-der-taufer',
})
const cUser = createUserObject({
id: 'c-user',
name: 'Rainer Maria Rilke',
slug: 'rainer-maria-rilke',
})
const dUser = createUserObject({
id: 'd-user',
name: 'Erich Maria Remarque',
slug: 'erich-maria-remarque',
})
const eUser = createUserObject({
id: 'e-user',
name: 'Klaus Dieter',
slug: 'kd',
})
const fUser = createUserObject({
id: 'f-user',
name: 'Sluggy',
slug: '_',
})
const gUser = createUserObject({
id: 'g-user',
name: 'AKK',
slug: 'akk',
})