From 7661adfbe3e3c4537bc5d6af0c2321de63ed282c Mon Sep 17 00:00:00 2001 From: Charlotte Vermandel Date: Mon, 24 May 2021 17:29:09 +0200 Subject: [PATCH 1/4] Add snippet and highlight tests --- src/types/types.ts | 6 +- tests/assets/utils.ts | 16 +++ tests/facetsDistribution.tests.ts | 4 +- tests/highlight.tests.ts | 200 ++++++++++++++++++++++++++++++ tests/snippets.tests.ts | 183 +++++++++++++++++++++++++++ 5 files changed, 406 insertions(+), 3 deletions(-) create mode 100644 tests/highlight.tests.ts create mode 100644 tests/snippets.tests.ts diff --git a/src/types/types.ts b/src/types/types.ts index 0f925411..20171fac 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -35,7 +35,11 @@ export type IMResponse = { nbPages?: number } -export type SearchResponse = IStypes.SearchResponse & IMResponse +export type SearchResponse = Omit & + IStypes.SearchResponse & + IMResponse & { + hits: ISHits[] + } export type InstantMeiliSearchContext = { page: number diff --git a/tests/assets/utils.ts b/tests/assets/utils.ts index 2ca669fa..dd7223ba 100644 --- a/tests/assets/utils.ts +++ b/tests/assets/utils.ts @@ -37,6 +37,22 @@ const dataset = [ poster: 'https://image.tmdb.org/t/p/w500/6FfCtAuVAW8XJjZ7eWeLibRLWTw.jpg', release_date: 233366400, }, + { + id: 30, + title: 'Magnetic Rose', + overview: '', + genres: ['Animation', 'Science Fiction'], + poster: 'https://image.tmdb.org/t/p/w500/gSuHDeWemA1menrwfMRChnSmMVN.jpg', + release_date: 819676800, + }, + { + id: 24, + title: 'Kill Bill: Vol. 1', + overview: null, + genres: ['Action', 'Crime'], + poster: 'https://image.tmdb.org/t/p/w500/v7TaX8kXMXs5yFFGR41guUDNcnB.jpg', + release_date: 1065744000, + }, ] export type Movies = { diff --git a/tests/facetsDistribution.tests.ts b/tests/facetsDistribution.tests.ts index 9a575cff..10636cfb 100644 --- a/tests/facetsDistribution.tests.ts +++ b/tests/facetsDistribution.tests.ts @@ -41,7 +41,7 @@ describe('Instant MeiliSearch Browser test', () => { }, }, ]) - expect(response.results[0].facets?.genres?.Action).toEqual(2) + expect(response.results[0].facets?.genres?.Action).toEqual(3) }) test('Test non-existent facets on facetsDistribution', async () => { @@ -54,6 +54,6 @@ describe('Instant MeiliSearch Browser test', () => { }, }, ]) - expect(response.results[0].facets?.genres?.Action).toEqual(2) + expect(response.results[0].facets?.genres?.Action).toEqual(3) }) }) diff --git a/tests/highlight.tests.ts b/tests/highlight.tests.ts new file mode 100644 index 00000000..d1026c3d --- /dev/null +++ b/tests/highlight.tests.ts @@ -0,0 +1,200 @@ +import { searchClient, dataset } from './assets/utils' + +describe('Highlight Browser test', () => { + beforeAll(async () => { + try { + await searchClient.MeiliSearchClient.deleteIndex('movies') + } catch (e) { + // movies does not exist + } + await searchClient.MeiliSearchClient.index( + 'movies' + ).updateAttributesForFaceting(['genres']) + const moviesUpdate = await searchClient.MeiliSearchClient.index( + 'movies' + ).addDocuments(dataset) + await searchClient.MeiliSearchClient.index('movies').waitForPendingUpdate( + moviesUpdate.updateId + ) + }) + + test('Test one attributesToHighlight on placeholder', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: '', + attributesToHighlight: ['name'], + }, + }, + ]) + const resKeys = Object.keys(response.results[0].hits[0]._highlightResult) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + }) + + test('Test no attributesToHighlight on placeholder', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: '', + attributesToHighlight: [], + }, + }, + ]) + const resKeys = Object.keys(response.results[0].hits[0]._highlightResult) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + }) + + test('Test one attributesToHighlight on specific query', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: 'Ar', + attributesToHighlight: ['title'], + }, + }, + ]) + // + const highlightedResults = response.results[0].hits[0]._highlightResult + const resKeys = Object.keys(highlightedResults) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + expect(highlightedResults.title?.value).toEqual( + '__ais-highlight__Ar__/ais-highlight__iel' + ) + }) + + test('Test two attributesToHighlight on specific query', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: 'S', + attributesToHighlight: ['title', 'overview'], + }, + }, + ]) + + const highlightedResults = response.results[0].hits[0]._highlightResult + const resKeys = Object.keys(highlightedResults) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + expect(highlightedResults.title?.value).toEqual( + '__ais-highlight__S__/ais-highlight__tar Wars' + ) + expect(highlightedResults.overview?.value).toEqual( + expect.stringMatching('__ais-highlight__S__/ais-highlight__kywalker') + ) + }) + + test('Test two attributesToHighlight on specific query with empty string value', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: 'Magnetic', + attributesToHighlight: ['title', 'overview'], + }, + }, + ]) + + const highlightedResults = response.results[0].hits[0]._highlightResult + const resKeys = Object.keys(highlightedResults) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + expect(highlightedResults.title?.value).toEqual( + '__ais-highlight__Magnetic__/ais-highlight__ Rose' + ) + expect(highlightedResults.overview?.value).toEqual( + expect.not.stringMatching('__ais-highlight__Magnetic__/ais-highlight__') + ) + // console.log(response.results[0].hits[0]._highlightResult) + }) + + test('Test two attributesToHighlight on specific query with null value', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: 'Magnetic', + attributesToHighlight: ['title', 'overview'], + }, + }, + ]) + // console.log(response.results[0].hits[0]._highlightResult) + const highlightedResults = response.results[0].hits[0]._highlightResult + const resKeys = Object.keys(highlightedResults) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + expect(highlightedResults.title?.value).toEqual( + '__ais-highlight__Magnetic__/ais-highlight__ Rose' + ) + expect(highlightedResults.overview?.value).toEqual( + expect.not.stringMatching('__ais-highlight__Magnetic__/ais-highlight__') + ) + }) + + test('Test two attributesToHighlight on specific query with null value', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: 'Magnetic', + attributesToHighlight: ['title', 'overview'], + }, + }, + ]) + console.log(response.results[0].hits[0]._highlightResult) + const highlightedResults = response.results[0].hits[0]._highlightResult + const resKeys = Object.keys(highlightedResults) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + expect(highlightedResults.title?.value).toEqual( + '__ais-highlight__Magnetic__/ais-highlight__ Rose' + ) + expect(highlightedResults.overview?.value).toEqual( + expect.not.stringMatching('__ais-highlight__Magnetic__/ais-highlight__') + ) + }) + + test('Test two attributesToHighlight on wild card', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: 'S', + attributesToHighlight: ['title', 'overview'], + }, + }, + ]) + + const highlightedResults = response.results[0].hits[0]._highlightResult + const resKeys = Object.keys(highlightedResults) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + expect(highlightedResults.title?.value).toEqual( + '__ais-highlight__S__/ais-highlight__tar Wars' + ) + expect(highlightedResults.overview?.value).toEqual( + expect.stringMatching('__ais-highlight__S__/ais-highlight__kywalker') + ) + }) + + test('Test two attributesToHighlight with different tags', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: 'S', + attributesToHighlight: ['title', 'overview'], + highlightPreTag: '

', + highlightPostTag: '

', + }, + }, + ]) + + const highlightedResults = response.results[0].hits[0]._highlightResult + const resKeys = Object.keys(highlightedResults) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + expect(highlightedResults.title?.value).toEqual('

S

tar Wars') + expect(highlightedResults.overview?.value).toEqual( + expect.stringMatching('

S

olo') + ) + }) +}) diff --git a/tests/snippets.tests.ts b/tests/snippets.tests.ts new file mode 100644 index 00000000..810cdba5 --- /dev/null +++ b/tests/snippets.tests.ts @@ -0,0 +1,183 @@ +import { searchClient, dataset } from './assets/utils' + +describe('Snippet Browser test', () => { + beforeAll(async () => { + try { + await searchClient.MeiliSearchClient.deleteIndex('movies') + } catch (e) { + // movies does not exist + } + await searchClient.MeiliSearchClient.index( + 'movies' + ).updateAttributesForFaceting(['genres']) + const moviesUpdate = await searchClient.MeiliSearchClient.index( + 'movies' + ).addDocuments(dataset) + await searchClient.MeiliSearchClient.index('movies').waitForPendingUpdate( + moviesUpdate.updateId + ) + }) + + test('Test one attributesToSnippet on placeholder', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: '', + attributesToSnippet: ['overview:2'], + }, + }, + ]) + const snippeted = response.results[0].hits[0]._highlightResult + expect(snippeted.overview.value).toEqual('Taisto') + const resKeys = Object.keys(snippeted) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + }) + + test('Test one attributesToSnippet on specific query', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: 'judg', + attributesToSnippet: ['overview:2'], + snippetEllipsisText: '...', + }, + }, + ]) + const highlighted = response.results[0].hits[0]._highlightResult + const snippeted = response.results[0].hits[0]._snippetResult + expect(highlighted.overview.value).toEqual('While') + expect(snippeted.overview.value).toEqual('While...') + const resKeys = Object.keys(response.results[0].hits[0]._highlightResult) + + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + }) + + test('Test two attributesToSnippet on specific query with one hit empty string', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: 'r', + attributesToSnippet: ['overview:2', 'title:2'], + highlightPreTag: '

', + highlightPostTag: '

', + snippetEllipsisText: '...', + }, + }, + ]) + const firstHitHighlight = response.results[0].hits[0]._highlightResult + const firstHitSnippet = response.results[0].hits[0]._snippetResult + + expect(firstHitHighlight.title.value).toEqual('

R

ooms') + expect(firstHitHighlight.overview.value).toEqual('s

r

oom') + expect(firstHitSnippet.title.value).toEqual('

R

ooms...') + expect(firstHitSnippet.overview.value).toEqual('...s

r

oom...') + + const secondHitHighlight = response.results[0].hits[1]._highlightResult + const secondHitSnippet = response.results[0].hits[1]._snippetResult + expect(secondHitHighlight.title.value).toEqual('

R

ose') + expect(secondHitHighlight.overview.value).toEqual('') + expect(secondHitSnippet.title.value).toEqual('

R

ose...') + expect(secondHitSnippet.overview.value).toEqual('') + + const resKeys = Object.keys(response.results[0].hits[0]._highlightResult) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + }) + + test('Test snippet on a null attribute', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: 'Kill', + attributesToSnippet: ['overview:2'], + }, + }, + ]) + + const firstHit = response.results[0].hits[0]._highlightResult + expect(firstHit.overview.value).toEqual('null') + + const resKeys = Object.keys(response.results[0].hits[0]._highlightResult) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + }) + + test('Test one attributesToSnippet on placeholder w/ snippetEllipsisText', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: '', + attributesToSnippet: ['overview:2'], + }, + }, + ]) + const snippeted = response.results[0].hits[0]._highlightResult + expect(snippeted.overview.value).toEqual('Taisto') + const resKeys = Object.keys(snippeted) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + }) + + test('Test one attributesToSnippet on specific query w/ snippetEllipsisText', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: 'judg', + attributesToSnippet: ['overview:2'], + }, + }, + ]) + const snippeted = response.results[0].hits[0]._highlightResult?.overview + expect(snippeted.value).toEqual('While') + const resKeys = Object.keys(response.results[0].hits[0]._highlightResult) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + }) + + test('Test two attributesToSnippet on specific query with one hit empty string w/ snippetEllipsisText', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: 'r', + attributesToSnippet: ['overview:2', 'title:2'], + }, + }, + ]) + const firstHit = response.results[0].hits[0]._highlightResult + + expect(firstHit.title.value).toEqual( + '__ais-highlight__R__/ais-highlight__ooms' + ) + expect(firstHit.overview.value).toEqual( + 's __ais-highlight__r__/ais-highlight__oom' + ) + const secondHit = response.results[0].hits[1]._highlightResult + expect(secondHit.title.value).toEqual( + '__ais-highlight__R__/ais-highlight__ose' + ) + expect(secondHit.overview.value).toEqual('') + + const resKeys = Object.keys(response.results[0].hits[0]._highlightResult) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + }) + + test('Test snippet on a null attribute w/ snippetEllipsisText', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: 'Kill', + attributesToSnippet: ['overview:2'], + }, + }, + ]) + + const firstHit = response.results[0].hits[0]._highlightResult + expect(firstHit.overview.value).toEqual('null') + const resKeys = Object.keys(response.results[0].hits[0]._highlightResult) + expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + }) +}) From 24465e42372f61adc26398bab4bdb8e98d1ec8b5 Mon Sep 17 00:00:00 2001 From: Charlotte Vermandel Date: Mon, 24 May 2021 17:37:28 +0200 Subject: [PATCH 2/4] Remove console logs --- tests/highlight.tests.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/highlight.tests.ts b/tests/highlight.tests.ts index d1026c3d..4dccede2 100644 --- a/tests/highlight.tests.ts +++ b/tests/highlight.tests.ts @@ -107,7 +107,6 @@ describe('Highlight Browser test', () => { expect(highlightedResults.overview?.value).toEqual( expect.not.stringMatching('__ais-highlight__Magnetic__/ais-highlight__') ) - // console.log(response.results[0].hits[0]._highlightResult) }) test('Test two attributesToHighlight on specific query with null value', async () => { @@ -120,7 +119,6 @@ describe('Highlight Browser test', () => { }, }, ]) - // console.log(response.results[0].hits[0]._highlightResult) const highlightedResults = response.results[0].hits[0]._highlightResult const resKeys = Object.keys(highlightedResults) expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) @@ -142,7 +140,6 @@ describe('Highlight Browser test', () => { }, }, ]) - console.log(response.results[0].hits[0]._highlightResult) const highlightedResults = response.results[0].hits[0]._highlightResult const resKeys = Object.keys(highlightedResults) expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) From 00c4ca112f93850ab78bea901aa8f34993eb529c Mon Sep 17 00:00:00 2001 From: Charlotte Vermandel Date: Mon, 24 May 2021 17:52:52 +0200 Subject: [PATCH 3/4] Improve tests messages --- tests/snippets.tests.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/snippets.tests.ts b/tests/snippets.tests.ts index 810cdba5..059720c2 100644 --- a/tests/snippets.tests.ts +++ b/tests/snippets.tests.ts @@ -86,7 +86,7 @@ describe('Snippet Browser test', () => { expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) }) - test('Test snippet on a null attribute', async () => { + test('Test attributesToSnippet on a null attribute', async () => { const response = await searchClient.search([ { indexName: 'movies', @@ -164,7 +164,7 @@ describe('Snippet Browser test', () => { expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) }) - test('Test snippet on a null attribute w/ snippetEllipsisText', async () => { + test('Test attributesToSnippet on a null attribute w/ snippetEllipsisText', async () => { const response = await searchClient.search([ { indexName: 'movies', From ed06520b664663600606b04b5a04b3fddfb344a4 Mon Sep 17 00:00:00 2001 From: Charlotte Vermandel Date: Mon, 24 May 2021 18:00:37 +0200 Subject: [PATCH 4/4] Integration tests pagination --- tests/pagination.tests.ts | 99 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 tests/pagination.tests.ts diff --git a/tests/pagination.tests.ts b/tests/pagination.tests.ts new file mode 100644 index 00000000..5cd26a2d --- /dev/null +++ b/tests/pagination.tests.ts @@ -0,0 +1,99 @@ +import { searchClient, dataset } from './assets/utils' + +describe('Pagination browser test', () => { + beforeAll(async () => { + try { + await searchClient.MeiliSearchClient.deleteIndex('movies') + } catch (e) { + // movies does not exist + } + await searchClient.MeiliSearchClient.index( + 'movies' + ).updateAttributesForFaceting(['genres']) + const moviesUpdate = await searchClient.MeiliSearchClient.index( + 'movies' + ).addDocuments(dataset) + await searchClient.MeiliSearchClient.index('movies').waitForPendingUpdate( + moviesUpdate.updateId + ) + }) + + test('Test 1 hitsPerPage', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: '', + hitsPerPage: 1, + }, + }, + ]) + const hits = response.results[0].hits + expect(hits.length).toBe(1) + expect(hits[0].title).toBe('Ariel') + }) + + test('Test 1 hitsPerPage w/ page 0 ', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: '', + hitsPerPage: 1, + page: 0, + }, + }, + ]) + const hits = response.results[0].hits + expect(hits.length).toBe(1) + expect(hits[0].title).toBe('Ariel') + }) + + test('Test 1 hitsPerPage w/ page 1 ', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: '', + hitsPerPage: 1, + page: 1, + }, + }, + ]) + const hits = response.results[0].hits + expect(hits.length).toBe(1) + expect(hits[0].title).toBe('Four Rooms') + }) + + test('Test 100 hitsPerPage w/ page 1 ', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: '', + hitsPerPage: 100, + page: 1, + }, + }, + ]) + const hits = response.results[0].hits + expect(hits.length).toBe(0) + expect(hits).toEqual([]) + }) + + test('Test 0 hitsPerPage w/ page 0 ', async () => { + const response = await searchClient.search([ + { + indexName: 'movies', + params: { + query: '', + hitsPerPage: 0, + page: 0, + }, + }, + ]) + const hits = response.results[0].hits + expect(hits.length).toBe(0) + expect(hits).toEqual([]) + }) +})