@searchkit/schema
Version:
Elasticsearch GraphQL Resolvers
487 lines (472 loc) • 15.8 kB
text/typescript
import nock from 'nock'
import { SearchkitConfig } from '@searchkit/sdk'
import { MultiMatchQuery, HierarchicalMenuFacet } from '@searchkit/sdk'
import { setupTestServer, callQuery } from '../support/helper'
import lvl1Mock from '../__mock-data__/HierarchicalMenuFacet/lvl1.json'
import lvl2Mock from '../__mock-data__/HierarchicalMenuFacet/lvl2.json'
import lvl3Mock from '../__mock-data__/HierarchicalMenuFacet/lvl3.json'
describe('HierarchicalMenuFacet', () => {
describe('should return as expected', () => {
const runQuery = async (gql) => {
const response = await callQuery({ gql })
return response
}
const config: SearchkitConfig = {
host: 'http://localhost:9200',
index: 'movies',
hits: {
fields: ['actors', 'writers']
},
query: new MultiMatchQuery({ fields: ['actors', 'writers', 'title^4', 'plot'] }),
facets: [
new HierarchicalMenuFacet({
fields: ['category_lvl1.keyword', 'category_lvl2.keyword', 'category_lvl3.keyword'],
identifier: 'categories',
label: 'Categories'
})
]
}
it('No filters, bring back only level 1 facets', async () => {
setupTestServer({
config,
addToQueryType: true,
typeName: 'ResultSet',
hitTypeName: 'ResultHit'
})
const gql = `
{
results(filters: []) {
hits(page: {size: 10, from: 0 }) {
items {
id
}
}
facets {
identifier
display
label
type
display
... on HierarchicalMenuFacet {
entries {
count
label
entries {
count
label
entries {
count
label
}
}
}
}
}
}
}
`
const scope = nock('http://localhost:9200')
.post('/movies/_search')
.reply((uri, body) => {
expect(body).toMatchInlineSnapshot(`
Object {
"_source": Object {
"includes": Array [
"actors",
"writers",
],
},
"aggs": Object {
"facet_bucket_all": Object {
"aggs": Object {
"categories": Object {
"aggs": Object {
"lvl_1": Object {
"aggs": Object {
"aggs": Object {
"terms": Object {
"field": "category_lvl1.keyword",
},
},
},
"filter": Object {
"match_all": Object {},
},
},
},
"filter": Object {
"match_all": Object {},
},
},
},
"filter": Object {
"bool": Object {
"must": Array [],
},
},
},
},
"from": 0,
"size": 10,
"sort": Array [
Object {
"_score": "desc",
},
],
}
`)
return [200, lvl1Mock]
})
const response = await runQuery(gql)
expect(response.body.data).toMatchSnapshot()
expect(response.status).toEqual(200)
})
it('1 lvl1 filter, bring back level 1 + lvl2 facets. Lvl2 facets have lvl1 filter applied', async () => {
setupTestServer({
config,
addToQueryType: true,
typeName: 'ResultSet',
hitTypeName: 'ResultHit'
})
const gql = `
{
results(filters: [{identifier: "categories", value: "Coats and Jackets", level: 1 }]) {
hits(page: {size: 10, from: 0 }) {
items {
id
}
}
facets {
identifier
display
label
type
display
... on HierarchicalMenuFacet {
entries {
count
label
entries {
count
label
entries {
count
label
}
}
}
}
}
}
}
`
const scope = nock('http://localhost:9200')
.post('/movies/_search')
.reply((uri, body) => {
expect(body).toMatchInlineSnapshot(`
Object {
"_source": Object {
"includes": Array [
"actors",
"writers",
],
},
"aggs": Object {
"facet_bucket_all": Object {
"aggs": Object {},
"filter": Object {
"bool": Object {
"must": Array [
Object {
"bool": Object {
"must": Array [
Object {
"term": Object {
"category_lvl1.keyword": "Coats and Jackets",
},
},
],
},
},
],
},
},
},
"facet_bucket_categories": Object {
"aggs": Object {
"categories": Object {
"aggs": Object {
"lvl_1": Object {
"aggs": Object {
"aggs": Object {
"terms": Object {
"field": "category_lvl1.keyword",
},
},
},
"filter": Object {
"match_all": Object {},
},
},
"lvl_2": Object {
"aggs": Object {
"aggs": Object {
"terms": Object {
"field": "category_lvl2.keyword",
},
},
},
"filter": Object {
"bool": Object {
"must": Array [
Object {
"term": Object {
"category_lvl1.keyword": Object {
"value": "Coats and Jackets",
},
},
},
],
},
},
},
},
"filter": Object {
"match_all": Object {},
},
},
},
"filter": Object {
"bool": Object {
"must": Array [],
},
},
},
},
"from": 0,
"post_filter": Object {
"bool": Object {
"must": Array [
Object {
"bool": Object {
"must": Array [
Object {
"term": Object {
"category_lvl1.keyword": "Coats and Jackets",
},
},
],
},
},
],
},
},
"size": 10,
"sort": Array [
Object {
"_score": "desc",
},
],
}
`)
return [200, lvl2Mock]
})
const response = await runQuery(gql)
expect(response.body.data).toMatchSnapshot()
expect(response.status).toEqual(200)
})
it('1 lvl1 filter, bring back level 1..3 facets. Lvl2 facets have lvl1 filter applied, lvl3 will have lvl 1..2 filter applied', async () => {
setupTestServer({
config,
addToQueryType: true,
typeName: 'ResultSet',
hitTypeName: 'ResultHit'
})
const gql = `
{
results(filters: [{identifier: "categories", value: "Coats and Jackets", level: 1 }, {identifier: "categories", value: "Leather jackets", level: 2 }]) {
hits(page: {size: 10, from: 0 }) {
items {
id
}
}
facets {
identifier
display
label
type
display
... on HierarchicalMenuFacet {
entries {
count
label
entries {
count
label
entries {
count
label
}
}
}
}
}
}
}
`
const scope = nock('http://localhost:9200')
.post('/movies/_search')
.reply((uri, body) => {
expect(body).toMatchInlineSnapshot(`
Object {
"_source": Object {
"includes": Array [
"actors",
"writers",
],
},
"aggs": Object {
"facet_bucket_all": Object {
"aggs": Object {},
"filter": Object {
"bool": Object {
"must": Array [
Object {
"bool": Object {
"must": Array [
Object {
"term": Object {
"category_lvl1.keyword": "Coats and Jackets",
},
},
Object {
"term": Object {
"category_lvl2.keyword": "Leather jackets",
},
},
],
},
},
],
},
},
},
"facet_bucket_categories": Object {
"aggs": Object {
"categories": Object {
"aggs": Object {
"lvl_1": Object {
"aggs": Object {
"aggs": Object {
"terms": Object {
"field": "category_lvl1.keyword",
},
},
},
"filter": Object {
"match_all": Object {},
},
},
"lvl_2": Object {
"aggs": Object {
"aggs": Object {
"terms": Object {
"field": "category_lvl2.keyword",
},
},
},
"filter": Object {
"bool": Object {
"must": Array [
Object {
"term": Object {
"category_lvl1.keyword": Object {
"value": "Coats and Jackets",
},
},
},
],
},
},
},
"lvl_3": Object {
"aggs": Object {
"aggs": Object {
"terms": Object {
"field": "category_lvl3.keyword",
},
},
},
"filter": Object {
"bool": Object {
"must": Array [
Object {
"term": Object {
"category_lvl1.keyword": Object {
"value": "Coats and Jackets",
},
},
},
Object {
"term": Object {
"category_lvl2.keyword": Object {
"value": "Leather jackets",
},
},
},
],
},
},
},
},
"filter": Object {
"match_all": Object {},
},
},
},
"filter": Object {
"bool": Object {
"must": Array [],
},
},
},
},
"from": 0,
"post_filter": Object {
"bool": Object {
"must": Array [
Object {
"bool": Object {
"must": Array [
Object {
"term": Object {
"category_lvl1.keyword": "Coats and Jackets",
},
},
Object {
"term": Object {
"category_lvl2.keyword": "Leather jackets",
},
},
],
},
},
],
},
},
"size": 10,
"sort": Array [
Object {
"_score": "desc",
},
],
}
`)
return [200, lvl3Mock]
})
const response = await runQuery(gql)
expect(response.body.data).toMatchSnapshot()
expect(response.status).toEqual(200)
})
})
})