diff --git a/packages/api/src/entity/search_history.ts b/packages/api/src/entity/search_history.ts index e10a79dff..ab0e051ab 100644 --- a/packages/api/src/entity/search_history.ts +++ b/packages/api/src/entity/search_history.ts @@ -5,10 +5,12 @@ import { JoinColumn, ManyToOne, PrimaryGeneratedColumn, + Unique, } from 'typeorm' import { User } from './user' @Entity({ name: 'search_history' }) +@Unique('search_history_user_id_term_key', ['user', 'term']) export class SearchHistory { @PrimaryGeneratedColumn('uuid') id!: string diff --git a/packages/api/src/services/search_history.ts b/packages/api/src/services/search_history.ts index 561d04782..59da78836 100644 --- a/packages/api/src/services/search_history.ts +++ b/packages/api/src/services/search_history.ts @@ -16,11 +16,16 @@ export const saveSearchHistory = async ( userId: string, term: string ): Promise => { - const searchHistory = new SearchHistory() - searchHistory.user.id = userId - searchHistory.term = term - searchHistory.createdAt = new Date() - await getRepository(SearchHistory).save(searchHistory) + await getRepository(SearchHistory).upsert( + { + user: { id: userId }, + term, + createdAt: new Date(), + }, + { + conflictPaths: ['user', 'term'], + } + ) } export const deleteSearchHistory = async (userId: string): Promise => { diff --git a/packages/api/test/resolvers/article.test.ts b/packages/api/test/resolvers/article.test.ts index d64a23d4e..950bd85c0 100644 --- a/packages/api/test/resolvers/article.test.ts +++ b/packages/api/test/resolvers/article.test.ts @@ -34,6 +34,7 @@ import { } from '../../src/elastic/pages' import { addHighlightToPage } from '../../src/elastic/highlights' import { refreshIndex } from '../../src/elastic' +import { SearchHistory } from '../../src/entity/search_history' chai.use(chaiString) @@ -842,6 +843,33 @@ describe('Article API', () => { after(async () => { await deletePagesByParam({ userId: user.id }, ctx) + await getRepository(SearchHistory).delete({ user: { id: user.id } }) + }) + + context('when we search for a keyword', () => { + before(() => { + keyword = 'search' + }) + + it('saves the term in search history', async () => { + await graphqlRequest(query, authToken).expect(200) + const searchHistories = await getRepository(SearchHistory).findBy({ + user: { id: user.id }, + }) + expect(searchHistories.length).to.eq(1) + expect(searchHistories[0].term).to.eq(keyword) + const searchHistory = searchHistories[0] + + // Check that the search history is updated + await graphqlRequest(query, authToken).expect(200) + const newSearchHistories = await getRepository(SearchHistory).findBy({ + user: { id: user.id }, + }) + expect(newSearchHistories.length).to.eq(1) + expect(newSearchHistories[0].createdAt).to.be.greaterThan( + searchHistory.createdAt + ) + }) }) context('when type:highlights is not in the query', () => {