@@ -26,15 +26,18 @@ jest.mock("crypto", () => ({
2626 randomBytes : ( size : number ) => randomBytes [ String ( size ) ] ,
2727} ) ) ;
2828
29- describe ( "letter-updates-transformer Lambda" , ( ) => {
30- const mockedDeps : jest . Mocked < Deps > = {
31- snsClient : { send : jest . fn ( ) } as unknown as SNSClient ,
32- logger : { info : jest . fn ( ) , error : jest . fn ( ) } as unknown as pino . Logger ,
33- env : {
34- EVENTPUB_SNS_TOPIC_ARN : "arn:aws:sns:region:account:topic" ,
35- } as unknown as EnvVars ,
36- } as Deps ;
29+ const eventSource =
30+ "/data-plane/supplier-api/nhs-supplier-api-dev/main/letters" ;
31+ const mockedDeps : jest . Mocked < Deps > = {
32+ snsClient : { send : jest . fn ( ) } as unknown as SNSClient ,
33+ logger : { info : jest . fn ( ) , error : jest . fn ( ) } as unknown as pino . Logger ,
34+ env : {
35+ EVENTPUB_SNS_TOPIC_ARN : "arn:aws:sns:region:account:topic" ,
36+ EVENT_SOURCE : eventSource ,
37+ } as unknown as EnvVars ,
38+ } as Deps ;
3739
40+ describe ( "letter-updates-transformer Lambda" , ( ) => {
3841 beforeEach ( ( ) => {
3942 jest . useFakeTimers ( ) ;
4043 } ) ;
@@ -50,7 +53,9 @@ describe("letter-updates-transformer Lambda", () => {
5053 const newLetter = generateLetter ( "PRINTED" ) ;
5154 const expectedEntries = [
5255 expect . objectContaining ( {
53- Message : JSON . stringify ( mapLetterToCloudEvent ( newLetter ) ) ,
56+ Message : JSON . stringify (
57+ mapLetterToCloudEvent ( newLetter , eventSource ) ,
58+ ) ,
5459 } ) ,
5560 ] ;
5661
@@ -76,7 +81,9 @@ describe("letter-updates-transformer Lambda", () => {
7681 newLetter . reasonCode = "R1" ;
7782 const expectedEntries = [
7883 expect . objectContaining ( {
79- Message : JSON . stringify ( mapLetterToCloudEvent ( newLetter ) ) ,
84+ Message : JSON . stringify (
85+ mapLetterToCloudEvent ( newLetter , eventSource ) ,
86+ ) ,
8087 } ) ,
8188 ] ;
8289
@@ -103,7 +110,9 @@ describe("letter-updates-transformer Lambda", () => {
103110 newLetter . reasonCode = "R2" ;
104111 const expectedEntries = [
105112 expect . objectContaining ( {
106- Message : JSON . stringify ( mapLetterToCloudEvent ( newLetter ) ) ,
113+ Message : JSON . stringify (
114+ mapLetterToCloudEvent ( newLetter , eventSource ) ,
115+ ) ,
107116 } ) ,
108117 ] ;
109118
@@ -135,14 +144,28 @@ describe("letter-updates-transformer Lambda", () => {
135144 expect ( mockedDeps . snsClient . send ) . not . toHaveBeenCalled ( ) ;
136145 } ) ;
137146
138- it ( "does not publish non-modify events" , async ( ) => {
147+ it ( "publishes INSERT events" , async ( ) => {
139148 const handler = createHandler ( mockedDeps ) ;
140149 const newLetter = generateLetter ( "ACCEPTED" ) ;
150+ const expectedEntries = [
151+ expect . objectContaining ( {
152+ Message : JSON . stringify (
153+ mapLetterToCloudEvent ( newLetter , eventSource ) ,
154+ ) ,
155+ } ) ,
156+ ] ;
141157
142158 const testData = generateKinesisEvent ( [ generateInsertRecord ( newLetter ) ] ) ;
143159 await handler ( testData , mockDeep < Context > ( ) , jest . fn ( ) ) ;
144160
145- expect ( mockedDeps . snsClient . send ) . not . toHaveBeenCalled ( ) ;
161+ expect ( mockedDeps . snsClient . send ) . toHaveBeenCalledWith (
162+ expect . objectContaining ( {
163+ input : expect . objectContaining ( {
164+ TopicArn : "arn:aws:sns:region:account:topic" ,
165+ PublishBatchRequestEntries : expectedEntries ,
166+ } ) ,
167+ } ) ,
168+ ) ;
146169 } ) ;
147170
148171 it ( "does not publish invalid letter data" , async ( ) => {
@@ -159,6 +182,55 @@ describe("letter-updates-transformer Lambda", () => {
159182
160183 expect ( mockedDeps . snsClient . send ) . not . toHaveBeenCalled ( ) ;
161184 } ) ;
185+
186+ it ( "throws error when kinesis data contains malformed JSON" , async ( ) => {
187+ const handler = createHandler ( mockedDeps ) ;
188+
189+ // Create a Kinesis event with malformed JSON data
190+ const malformedKinesisEvent : KinesisStreamEvent = {
191+ Records : [
192+ {
193+ kinesis : {
194+ data : Buffer . from ( "invalid-json-data" ) . toString ( "base64" ) ,
195+ sequenceNumber : "12345" ,
196+ } ,
197+ } as any ,
198+ ] ,
199+ } ;
200+
201+ await expect (
202+ handler ( malformedKinesisEvent , mockDeep < Context > ( ) , jest . fn ( ) ) ,
203+ ) . rejects . toThrow ( ) ;
204+
205+ expect ( mockedDeps . logger . error ) . toHaveBeenCalledWith (
206+ expect . objectContaining ( {
207+ description : "Error extracting payload" ,
208+ error : expect . any ( Error ) ,
209+ record : expect . objectContaining ( {
210+ kinesis : expect . objectContaining ( {
211+ data : Buffer . from ( "invalid-json-data" ) . toString ( "base64" ) ,
212+ } ) ,
213+ } ) ,
214+ } ) ,
215+ ) ;
216+ } ) ;
217+
218+ it ( "handles events with no records" , async ( ) => {
219+ const handler = createHandler ( mockedDeps ) ;
220+
221+ // Create a Kinesis event with empty Records array
222+ const emptyKinesisEvent : KinesisStreamEvent = { Records : [ ] } ;
223+
224+ await handler ( emptyKinesisEvent , mockDeep < Context > ( ) , jest . fn ( ) ) ;
225+
226+ expect ( mockedDeps . logger . info ) . toHaveBeenCalledWith (
227+ expect . objectContaining ( {
228+ description : "Number of records" ,
229+ count : 0 ,
230+ } ) ,
231+ ) ;
232+ expect ( mockedDeps . snsClient . send ) . not . toHaveBeenCalled ( ) ;
233+ } ) ;
162234 } ) ;
163235
164236 describe ( "Batching" , ( ) => {
@@ -168,7 +240,7 @@ describe("letter-updates-transformer Lambda", () => {
168240 const newLetters = generateLetters ( 10 , "PRINTED" ) ;
169241 const expectedEntries = newLetters . map ( ( letter ) =>
170242 expect . objectContaining ( {
171- Message : JSON . stringify ( mapLetterToCloudEvent ( letter ) ) ,
243+ Message : JSON . stringify ( mapLetterToCloudEvent ( letter , eventSource ) ) ,
172244 } ) ,
173245 ) ;
174246
@@ -197,19 +269,19 @@ describe("letter-updates-transformer Lambda", () => {
197269 newLetters . slice ( 0 , 10 ) . map ( ( letter , index ) =>
198270 expect . objectContaining ( {
199271 Id : expect . stringMatching ( new RegExp ( `-${ index } $` ) ) ,
200- Message : JSON . stringify ( mapLetterToCloudEvent ( letter ) ) ,
272+ Message : JSON . stringify ( mapLetterToCloudEvent ( letter , eventSource ) ) ,
201273 } ) ,
202274 ) ,
203275 newLetters . slice ( 10 , 20 ) . map ( ( letter , index ) =>
204276 expect . objectContaining ( {
205277 Id : expect . stringMatching ( new RegExp ( `-${ index } $` ) ) ,
206- Message : JSON . stringify ( mapLetterToCloudEvent ( letter ) ) ,
278+ Message : JSON . stringify ( mapLetterToCloudEvent ( letter , eventSource ) ) ,
207279 } ) ,
208280 ) ,
209281 newLetters . slice ( 20 ) . map ( ( letter , index ) =>
210282 expect . objectContaining ( {
211283 Id : expect . stringMatching ( new RegExp ( `-${ index } $` ) ) ,
212- Message : JSON . stringify ( mapLetterToCloudEvent ( letter ) ) ,
284+ Message : JSON . stringify ( mapLetterToCloudEvent ( letter , eventSource ) ) ,
213285 } ) ,
214286 ) ,
215287 ] ;
0 commit comments