Skip to content

Commit

Permalink
update table stream tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Courey committed Dec 12, 2024
1 parent 22554bb commit b7b818f
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 84 deletions.
142 changes: 65 additions & 77 deletions __tests__/table-streams/synonyms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
import { tables } from '@architect/functions'
import { search } from '@nasa-gcn/architect-functions-search'
import type { DynamoDBRecord } from 'aws-lambda'
import crypto from 'crypto'

import type { Synonym } from '~/routes/synonyms/synonyms.lib'
import { handler } from '~/table-streams/synonyms/index'

const synonymId = 'abcde-abcde-abcde-abcde-abcde'
const synonymId = crypto.randomUUID()
const eventId = 'GRB 123'
const existingEventId = 'GRB 99999999'
const previousSynonymId = crypto.randomUUID()

const putData = {
index: 'synonym-groups',
Expand Down Expand Up @@ -48,6 +49,7 @@ const mockIndex = jest.fn()
const mockDelete = jest.fn()
const mockQuery = jest.fn()

const eventSlug = eventId.replace(' ', '-').toLowerCase()
const mockStreamEvent = {
Records: [
{
Expand All @@ -64,6 +66,9 @@ const mockStreamEvent = {
eventId: {
S: eventId,
},
slug: {
S: eventSlug,
},
},
NewImage: {
synonymId: {
Expand All @@ -72,6 +77,9 @@ const mockStreamEvent = {
eventId: {
S: eventId,
},
slug: {
S: eventSlug,
},
},
SequenceNumber: '111',
SizeBytes: 26,
Expand All @@ -88,8 +96,12 @@ afterEach(() => {
})

describe('testing put synonymGroup table-stream', () => {
test('insert new synonym group', async () => {
const mockItems = [{ synonymId, eventId }]
test('insert initial synonym record where no existing opensearch record exists', async () => {
const mockSearch = jest
.fn()
.mockReturnValue({ body: { hits: { hits: [] } } })
const slug = eventId.replace(' ', '-').toLowerCase()
const mockItems = [{ synonymId, eventId, slug }]
const mockClient = {
synonyms: {
query: mockQuery,
Expand All @@ -101,103 +113,79 @@ describe('testing put synonymGroup table-stream', () => {
;(search as unknown as jest.Mock).mockReturnValue({
index: mockIndex,
delete: mockDelete,
search: mockSearch,
})

await handler(mockStreamEvent)

putData.body.slugs.push(slug)
expect(mockIndex).toHaveBeenCalledWith(putData)
})

test('insert into existing synonym group', async () => {
const mockItems = [
{ synonymId, eventId: existingEventId },
{ synonymId, eventId },
]
const mockClient = {
synonyms: {
query: mockQuery,
},
test('insert into existing synonym group with removal of now unused group', async () => {
const existingEventSlug = existingEventId.replace(' ', '-').toLowerCase()
const deleteData = {
index: 'synonym-groups',
id: previousSynonymId,
}
mockQuery.mockResolvedValue({ Items: mockItems })
;(tables as unknown as jest.Mock).mockResolvedValue(mockClient)
putData.body.eventIds = [existingEventId, eventId]
;(search as unknown as jest.Mock).mockReturnValue({
index: mockIndex,
delete: mockDelete,
})

await handler(mockStreamEvent)

expect(mockIndex).toHaveBeenCalledWith(putData)
})

test('insert only once', async () => {
const mockItems = [
{ synonymId, eventId: existingEventId },
{ synonymId, eventId },
]
const mockClient = {
synonyms: {
query: mockQuery,
const mockSearch = jest.fn().mockReturnValue({
body: {
hits: {
hits: [
{
_source: {
synonymId: previousSynonymId,
eventIds: [eventId],
slugs: [eventSlug],
},
},
],
},
},
}
mockQuery.mockResolvedValue({ Items: mockItems })
;(tables as unknown as jest.Mock).mockResolvedValue(mockClient)
putData.body.eventIds = [existingEventId, eventId]
;(search as unknown as jest.Mock).mockReturnValue({
index: mockIndex,
delete: mockDelete,
})

await handler(mockStreamEvent)
const mockItems = [
{ synonymId, eventId: existingEventId, slug: existingEventSlug },
{ synonymId, eventId, slug: eventSlug },
]

expect(mockIndex).toHaveBeenCalledWith(putData)
})
})
const mockPreviousItems = [
{ synonymId: previousSynonymId, eventId, slug: eventSlug },
]

describe('testing delete synonymGroup table-stream', () => {
test('remove one eventId while leaving others', async () => {
const mockItems = [{ synonymId, eventId: existingEventId }]
const mockClient = {
synonyms: {
query: mockQuery,
},
}
mockQuery.mockResolvedValue({ Items: mockItems })
;(tables as unknown as jest.Mock).mockResolvedValue(mockClient)
mockStreamEvent.Records[0].eventName = 'REMOVE'
putData.body.eventIds = [existingEventId]
const implementedMockQuery = mockQuery.mockImplementation((query) => {
if (query.ExpressionAttributeValues[':synonymId'] == previousSynonymId) {
return { Items: mockPreviousItems }
} else {
return { Items: mockItems }
}
})
;(search as unknown as jest.Mock).mockReturnValue({
index: mockIndex,
delete: mockDelete,
search: mockSearch,
})

await handler(mockStreamEvent)

expect(mockIndex).toHaveBeenCalledWith(putData)
})

test('remove final synonym and delete synonym group', async () => {
const mockItems = [] as Synonym[]
const mockClient = {
synonyms: {
query: mockQuery,
query: implementedMockQuery,
},
}
mockQuery.mockResolvedValue({ Items: mockItems })

;(tables as unknown as jest.Mock).mockResolvedValue(mockClient)
mockStreamEvent.Records[0].eventName = 'REMOVE'
const deleteData = {
index: 'synonym-groups',
id: synonymId,
}
;(search as unknown as jest.Mock).mockReturnValue({
index: mockIndex,
delete: mockDelete,
putData.body.eventIds = [existingEventId, eventId]
putData.body.slugs = [existingEventSlug, eventSlug]

mockQuery.mockImplementation((query) => {
if (query.ExpressionAttributeValues[':synonymId'] == previousSynonymId) {
return { Items: mockPreviousItems }
} else {
return { Items: mockItems }
}
})

await handler(mockStreamEvent)

// the new group opensearch record is updated
expect(mockIndex).toHaveBeenCalledWith(putData)
// the old group opensearch record is deleted
expect(mockDelete).toHaveBeenCalledWith(deleteData)
})
})
3 changes: 1 addition & 2 deletions app/routes/synonyms/synonyms.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ export async function searchSynonymsByEventId({
fields: { eventIds: string[]; synonymId: string; slugs: string[] }
}) => body
)

return {
items: results,
totalItems,
Expand Down Expand Up @@ -139,7 +138,7 @@ export async function opensearchKeywordSearch({
if (response.body.hits.hits.length > 0) {
return response.body.hits.hits[0]._source
} else {
return null
return []
}
}

Expand Down
22 changes: 17 additions & 5 deletions app/table-streams/synonyms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,24 @@ export const handler = createTriggerHandler(
) as Synonym
const dynamoSynonyms = await getSynonymsByUuid(synonymId)
const opensearchSynonym = await opensearchKeywordSearch({ eventId })
const previousSynonymId = opensearchSynonym.synonymId
const dynamoPreviousGroup = (
await getSynonymsByUuid(previousSynonymId)
).filter((synonym) => synonym.eventId != eventId)
const previousSynonymId = opensearchSynonym
? opensearchSynonym.synonymId
: null
const dynamoPreviousGroup = previousSynonymId
? (await getSynonymsByUuid(previousSynonymId)).filter(
(synonym) => synonym.eventId != eventId
)
: []

if (dynamoPreviousGroup.length === 0) await removeIndex(previousSynonymId)
if (dynamoPreviousGroup.length === 0 && previousSynonymId) {
await removeIndex(previousSynonymId)
} else {
await putIndex({
synonymId: previousSynonymId,
eventIds: dynamoPreviousGroup.map((synonym) => synonym.eventId),
slugs: dynamoPreviousGroup.map((synonym) => synonym.slug),

Check warning on line 68 in app/table-streams/synonyms/index.ts

View check run for this annotation

Codecov / codecov/patch

app/table-streams/synonyms/index.ts#L67-L68

Added lines #L67 - L68 were not covered by tests
})
}

if (dynamoSynonyms.length > 0) {
await putIndex({
Expand Down

0 comments on commit b7b818f

Please sign in to comment.