Skip to content

Commit f8f3725

Browse files
bors[bot]bidoubiwa
andauthored
Merge #390
390: Tests on Attributes to retrieve Configuration r=bidoubiwa a=bidoubiwa Co-authored-by: Charlotte Vermandel <[email protected]>
2 parents 8adca26 + 477645a commit f8f3725

File tree

7 files changed

+272
-19
lines changed

7 files changed

+272
-19
lines changed

jest.config.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,38 @@ module.exports = {
66
],
77
projects: [
88
{
9+
globals: {
10+
'ts-jest': {
11+
tsconfig: 'tsconfig.test.json',
12+
},
13+
},
914
preset: 'ts-jest',
1015
displayName: 'dom',
1116
// We are using jest-environment-jsdom 25 until we stop supporting node 10
1217
// jest-environment-jsdom 25 uses jsdom 15 which still supports node 10
1318
testEnvironment: 'jest-environment-jsdom',
14-
testPathIgnorePatterns: ['<rootDir>/tests/env', '<rootDir>/playgrounds'],
15-
testMatch: ['**/*.tests.ts'],
19+
testPathIgnorePatterns: [
20+
'<rootDir>/tests/env',
21+
'<rootDir>/playgrounds',
22+
'<rootDir>/tests/assets',
23+
],
24+
testMatch: ['**/*.tests.ts', '/tests/**/*.ts'],
1625
},
1726
{
27+
globals: {
28+
'ts-jest': {
29+
tsconfig: 'tsconfig.test.json',
30+
},
31+
},
1832
preset: 'ts-jest',
1933
displayName: 'node',
2034
testEnvironment: 'node',
21-
testPathIgnorePatterns: ['<rootDir>/tests/env', '<rootDir>/playgrounds'],
22-
testMatch: ['**/*.tests.ts'],
35+
testPathIgnorePatterns: [
36+
'<rootDir>/tests/env',
37+
'<rootDir>/playgrounds',
38+
'<rootDir>/tests/assets',
39+
],
40+
testMatch: ['**/*.tests.ts', '/tests/**/*.ts'],
2341
},
2442
],
2543
}

src/client/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,13 @@ export function instantMeiliSearch(
4545
.search(msSearchParams.q, msSearchParams)
4646

4747
// Parses the MeiliSearch response and returns it for InstantSearch
48-
return transformToISResponse(
48+
const ISresponse = transformToISResponse(
4949
indexUid,
5050
searchResponse,
5151
instantSearchParams,
5252
context
5353
)
54+
return ISresponse
5455
} catch (e) {
5556
console.error(e)
5657
throw new Error(e)

src/transformers/to-instantsearch-hits.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,22 @@ export const transformToISHits: TransformToISHitsm = function (
1414
const paginatedHits = paginateHits(meiliSearchHits, instantMeiliSearchContext)
1515

1616
return paginatedHits.map((hit: any) => {
17-
const { _formatted: formattedHit, ...restOfHit } = hit
18-
1917
// Creates Hit object compliant with InstantSearch
20-
return {
21-
...restOfHit,
22-
_highlightResult: createHighlighResult({
23-
formattedHit,
24-
...instantSearchParams,
25-
}),
26-
_snippetResult: createSnippetResult({
27-
formattedHit,
28-
...instantSearchParams,
29-
}),
30-
...(primaryKey && { objectID: hit[primaryKey] }),
18+
if (Object.keys(hit).length > 0) {
19+
const { _formatted: formattedHit, _matchesInfo, ...restOfHit } = hit
20+
return {
21+
...restOfHit,
22+
_highlightResult: createHighlighResult({
23+
formattedHit,
24+
...instantSearchParams,
25+
}),
26+
_snippetResult: createSnippetResult({
27+
formattedHit,
28+
...instantSearchParams,
29+
}),
30+
...(primaryKey && { objectID: hit[primaryKey] }),
31+
}
3132
}
33+
return hit
3234
})
3335
}

src/types/instantsearch-types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ export type SearchRequest = {
9494
params: SearchRequestParameters
9595
}
9696

97-
export type Hit = {
97+
export type Hit<T = {}> = T & {
98+
[key: string]: any
9899
_highlightResult?: object
99100
}
100101

tests/assets/utils.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { instantMeiliSearch } from '../../src'
2+
3+
const dataset = [
4+
{
5+
id: 2,
6+
title: 'Ariel',
7+
overview:
8+
"Taisto Kasurinen is a Finnish coal miner whose father has just committed suicide and who is framed for a crime he did not commit. In jail, he starts to dream about leaving the country and starting a new life. He escapes from prison but things don't go as planned...",
9+
genres: ['Drama', 'Crime', 'Comedy'],
10+
poster: 'https://image.tmdb.org/t/p/w500/ojDg0PGvs6R9xYFodRct2kdI6wC.jpg',
11+
release_date: 593395200,
12+
},
13+
{
14+
id: 5,
15+
title: 'Four Rooms',
16+
overview:
17+
"It's Ted the Bellhop's first night on the job...and the hotel's very unusual guests are about to place him in some outrageous predicaments. It seems that this evening's room service is serving up one unbelievable happening after another.",
18+
genres: ['Crime', 'Comedy'],
19+
poster: 'https://image.tmdb.org/t/p/w500/75aHn1NOYXh4M7L5shoeQ6NGykP.jpg',
20+
release_date: 818467200,
21+
},
22+
{
23+
id: 6,
24+
title: 'Judgment Night',
25+
overview:
26+
'While racing to a boxing match, Frank, Mike, John and Rey get more than they bargained for. A wrong turn lands them directly in the path of Fallon, a vicious, wise-cracking drug lord. After accidentally witnessing Fallon murder a disloyal henchman, the four become his unwilling prey in a savage game of cat & mouse as they are mercilessly stalked through the urban jungle in this taut suspense drama',
27+
genres: ['Action', 'Thriller', 'Crime'],
28+
poster: 'https://image.tmdb.org/t/p/w500/rYFAvSPlQUCebayLcxyK79yvtvV.jpg',
29+
release_date: 750643200,
30+
},
31+
{
32+
id: 11,
33+
title: 'Star Wars',
34+
overview:
35+
'Princess Leia is captured and held hostage by the evil Imperial forces in their effort to take over the galactic Empire. Venturesome Luke Skywalker and dashing captain Han Solo team together with the loveable robot duo R2-D2 and C-3PO to rescue the beautiful princess and restore peace and justice in the Empire.',
36+
genres: ['Adventure', 'Action', 'Science Fiction'],
37+
poster: 'https://image.tmdb.org/t/p/w500/6FfCtAuVAW8XJjZ7eWeLibRLWTw.jpg',
38+
release_date: 233366400,
39+
},
40+
]
41+
42+
export type Movies = {
43+
id?: number
44+
title?: string
45+
overview?: string
46+
genres?: string[]
47+
release_date?: number // eslint-disable-line
48+
_highlightResult?: Movies
49+
}
50+
51+
const searchClient = instantMeiliSearch('http://localhost:7700', 'masterKey')
52+
const wrongSearchClient = instantMeiliSearch(
53+
'http://localhost:7777',
54+
'masterKey'
55+
)
56+
57+
export { searchClient, dataset, wrongSearchClient }
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
import { searchClient, dataset, Movies } from './assets/utils'
2+
3+
describe('Instant MeiliSearch Browser test', () => {
4+
beforeAll(async () => {
5+
try {
6+
await searchClient.MeiliSearchClient.deleteIndex('movies')
7+
} catch (e) {
8+
// movies does not exist
9+
}
10+
const moviesUpdate = await searchClient.MeiliSearchClient.index(
11+
'movies'
12+
).addDocuments(dataset)
13+
await searchClient.MeiliSearchClient.index('movies').waitForPendingUpdate(
14+
moviesUpdate.updateId
15+
)
16+
})
17+
18+
test('Test attributesToRetrieve on no attributes', async () => {
19+
const response = await searchClient.search([
20+
{
21+
indexName: 'movies',
22+
params: {
23+
attributesToRetrieve: [],
24+
query: 'ariel',
25+
},
26+
},
27+
])
28+
const notRetrieved = [
29+
'id',
30+
'overview',
31+
'genres',
32+
'poster',
33+
'release_date',
34+
'title',
35+
'_highlightResult',
36+
]
37+
const hit = <Movies>response.results[0].hits[0]
38+
notRetrieved.map((attribute: string) =>
39+
expect(hit[<any>attribute]).not.toBeDefined()
40+
)
41+
})
42+
43+
test('Test attributesToRetrieve on null', async () => {
44+
const response = await searchClient.search([
45+
{
46+
indexName: 'movies',
47+
params: {
48+
attributesToRetrieve: [],
49+
query: 'ariel',
50+
},
51+
},
52+
])
53+
const notRetrieved = [
54+
'id',
55+
'overview',
56+
'genres',
57+
'poster',
58+
'release_date',
59+
'title',
60+
'_highlightResult',
61+
]
62+
const hit = <Movies>response.results[0].hits[0]
63+
notRetrieved.map((attribute: string) =>
64+
expect(hit[attribute]).not.toBeDefined()
65+
)
66+
})
67+
68+
test('Test attributesToRetrieve on one non existing attribute', async () => {
69+
const response = await searchClient.search([
70+
{
71+
indexName: 'movies',
72+
params: {
73+
attributesToRetrieve: ['test'],
74+
query: 'ariel',
75+
},
76+
},
77+
])
78+
const notRetrieved = [
79+
'id',
80+
'overview',
81+
'genres',
82+
'poster',
83+
'release_date',
84+
'title',
85+
'_highlightResult',
86+
]
87+
const hit = <Movies>response.results[0].hits[0]
88+
notRetrieved.map(
89+
(attribute: string) =>
90+
hit._highlightResult &&
91+
expect(hit._highlightResult[attribute]).toBeDefined()
92+
)
93+
})
94+
95+
test('Test attributesToRetrieve on one existing attribute', async () => {
96+
const response = await searchClient.search([
97+
{
98+
indexName: 'movies',
99+
params: {
100+
attributesToRetrieve: ['title'],
101+
query: 'ariel',
102+
},
103+
},
104+
])
105+
const notRetrieved = ['id', 'overview', 'genres', 'poster', 'release_date']
106+
const hit = <Movies>response.results[0].hits[0]
107+
expect(hit.title).toEqual('Ariel')
108+
notRetrieved.map((attribute: string) =>
109+
expect(hit[attribute]).not.toBeDefined()
110+
)
111+
notRetrieved.map(
112+
(attribute: string) =>
113+
hit._highlightResult &&
114+
expect(hit._highlightResult[attribute]).not.toBeDefined()
115+
)
116+
})
117+
118+
test('Test attributesToRetrieve on default value', async () => {
119+
const response = await searchClient.search([
120+
{
121+
indexName: 'movies',
122+
params: {
123+
query: 'ariel',
124+
},
125+
},
126+
])
127+
const notRetrieved = ['id', 'overview', 'genres', 'poster', 'release_date']
128+
const hit = <Movies>response.results[0].hits[0]
129+
expect(hit.title).toEqual('Ariel')
130+
expect(hit._highlightResult).toBeDefined()
131+
notRetrieved.map((attribute: string) =>
132+
expect(hit[attribute]).toBeDefined()
133+
)
134+
notRetrieved.map(
135+
(attribute: string) =>
136+
hit._highlightResult &&
137+
expect(hit._highlightResult[attribute]).toBeDefined()
138+
)
139+
})
140+
141+
test('Test attributesToRetrieve on wild card', async () => {
142+
const response = await searchClient.search([
143+
{
144+
indexName: 'movies',
145+
params: {
146+
query: 'ariel',
147+
attributesToRetrieve: ['*'],
148+
},
149+
},
150+
])
151+
const retrieved = [
152+
'id',
153+
'overview',
154+
'genres',
155+
'poster',
156+
'release_date',
157+
'title',
158+
]
159+
const hit = <Movies>response.results[0].hits[0]
160+
expect(hit.title).toEqual('Ariel')
161+
retrieved.map((attribute: string) => expect(hit[attribute]).toBeDefined())
162+
retrieved.map(
163+
(attribute: string) =>
164+
hit._highlightResult &&
165+
expect(hit._highlightResult[attribute]).toBeDefined()
166+
)
167+
})
168+
})

tsconfig.test.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"compilerOptions": {
4+
"suppressImplicitAnyIndexErrors": true,
5+
}
6+
}

0 commit comments

Comments
 (0)