@@ -11,9 +11,6 @@ const mockedDeps: jest.Mocked<Deps> = {
1111 CLIENT_CERTIFICATE_EXPIRATION_ALERT_DAYS : 14 ,
1212 APIM_APPLICATION_ID_HEADER : 'apim-application-id'
1313 } as unknown as EnvVars ,
14- cloudWatchClient : {
15- send : jest . fn ( ) . mockResolvedValue ( { } ) ,
16- } as any ,
1714 supplierRepo : {
1815 getSupplierByApimId : jest . fn ( ) ,
1916 } as any ,
@@ -49,49 +46,48 @@ describe('Authorizer Lambda Function', () => {
4946 jest . useRealTimers ( ) ;
5047 } )
5148
52- // it('Should not send CloudWatch metric when certificate is null', async () => {
53- // mockEvent.requestContext.identity.clientCert = null;
49+ it ( 'Should not log CloudWatch metric when certificate is null' , async ( ) => {
50+ mockEvent . requestContext . identity . clientCert = null ;
5451
55- // const handler = createAuthorizerHandler(mockedDeps);
56- // handler(mockEvent, mockContext, mockCallback);
57- // await new Promise(process.nextTick);
52+ const handler = createAuthorizerHandler ( mockedDeps ) ;
53+ handler ( mockEvent , mockContext , mockCallback ) ;
54+ await new Promise ( process . nextTick ) ;
5855
59- // expect(mockedDeps.cloudWatchClient.send).not.toHaveBeenCalled();
60- // });
56+ const mockedInfo = mockedDeps . logger . info as jest . Mock ;
57+ expect ( mockedInfo . mock . calls ) . not . toContainEqual (
58+ expect . stringContaining ( 'CloudWatchMetrics' ) ) ;
59+ } ) ;
6160
62- it ( 'Should send CloudWatch metric when the certificate expiry threshold is reached' , async ( ) => {
61+ it ( 'Should log CloudWatch metric when the certificate expiry threshold is reached' , async ( ) => {
6362 mockEvent . requestContext . identity . clientCert = buildCertWithExpiry ( '2025-11-17T14:19:00Z' ) ;
6463
6564 const handler = createAuthorizerHandler ( mockedDeps ) ;
6665 handler ( mockEvent , mockContext , mockCallback ) ;
6766 await new Promise ( process . nextTick ) ;
6867
69- expect ( mockedDeps . cloudWatchClient . send ) . toHaveBeenCalledWith (
70- expect . objectContaining ( {
71- input : {
68+ const mockedInfo = mockedDeps . logger . info as jest . Mock ;
69+ expect ( mockedInfo . mock . calls . map ( call => call [ 0 ] ) ) . toContain ( JSON . stringify (
70+ { _aws : { Timestamp : 1762179540000 ,
71+ CloudWatchMetrics : [ {
7272 Namespace : 'cloudwatch-namespace' ,
73- MetricData : [
74- {
75- MetricName : 'apim-client-certificate-near-expiry' ,
76- Dimensions : [
77- { Name : 'SUBJECT_DN' , Value : 'CN=test-subject' } ,
78- { Name : 'NOT_AFTER' , Value : '2025-11-17T14:19:00Z' } ,
79- ] ,
80- } ,
81- ] ,
82- } ,
83- } )
84- ) ;
73+ Dimensions : [ 'SUBJECT_DN' , 'NOT_AFTER' ] ,
74+ Metrics : [ { Name : 'apim-client-certificate-near-expiry' , Unit : 'Count' , Value : 1 } ]
75+ } ] } ,
76+ SUBJECT_DN : 'CN=test-subject' ,
77+ NOT_AFTER : '2025-11-17T14:19:00Z' ,
78+ 'apim-client-certificate-near-expiry' : 1 } ) ) ;
8579 } ) ;
8680
87- it ( 'Should not send CloudWatch metric when the certificate expiry threshold is not yet reached' , async ( ) => {
81+ it ( 'Should not log CloudWatch metric when the certificate expiry threshold is not yet reached' , async ( ) => {
8882 mockEvent . requestContext . identity . clientCert = buildCertWithExpiry ( '2025-11-18T14:19:00Z' ) ;
8983
9084 const handler = createAuthorizerHandler ( mockedDeps ) ;
9185 handler ( mockEvent , mockContext , mockCallback ) ;
9286 await new Promise ( process . nextTick ) ;
9387
94- expect ( mockedDeps . cloudWatchClient . send ) . not . toHaveBeenCalled ( ) ;
88+ const mockedInfo = mockedDeps . logger . info as jest . Mock ;
89+ expect ( mockedInfo . mock . calls ) . not . toContainEqual (
90+ expect . stringContaining ( 'CloudWatchMetrics' ) ) ;
9591 } ) ;
9692 } ) ;
9793
@@ -105,110 +101,110 @@ describe('Authorizer Lambda Function', () => {
105101 } as APIGatewayEventClientCertificate ;
106102 }
107103
108- describe ( 'Supplier ID lookup' , ( ) => {
104+ describe ( 'Supplier ID lookup' , ( ) => {
109105
110- it ( 'Should deny the request when no headers are present' , async ( ) => {
111- mockEvent . headers = null ;
106+ it ( 'Should deny the request when no headers are present' , async ( ) => {
107+ mockEvent . headers = null ;
112108
113- const handler = createAuthorizerHandler ( mockedDeps ) ;
114- handler ( mockEvent , mockContext , mockCallback ) ;
115- await new Promise ( process . nextTick ) ;
109+ const handler = createAuthorizerHandler ( mockedDeps ) ;
110+ handler ( mockEvent , mockContext , mockCallback ) ;
111+ await new Promise ( process . nextTick ) ;
116112
117- expect ( mockCallback ) . toHaveBeenCalledWith ( null , expect . objectContaining ( {
118- policyDocument : expect . objectContaining ( {
119- Statement : [
120- expect . objectContaining ( {
121- Effect : 'Deny' ,
122- } ) ,
123- ] ,
124- } ) ,
125- } ) ) ;
126- } ) ;
113+ expect ( mockCallback ) . toHaveBeenCalledWith ( null , expect . objectContaining ( {
114+ policyDocument : expect . objectContaining ( {
115+ Statement : [
116+ expect . objectContaining ( {
117+ Effect : 'Deny' ,
118+ } ) ,
119+ ] ,
120+ } ) ,
121+ } ) ) ;
122+ } ) ;
127123
128- it ( 'Should deny the request when the APIM application ID header is absent' , async ( ) => {
129- mockEvent . headers = { 'x-apim-correlation-id' : 'correlation-id' } ;
124+ it ( 'Should deny the request when the APIM application ID header is absent' , async ( ) => {
125+ mockEvent . headers = { 'x-apim-correlation-id' : 'correlation-id' } ;
130126
131- const handler = createAuthorizerHandler ( mockedDeps ) ;
132- handler ( mockEvent , mockContext , mockCallback ) ;
133- await new Promise ( process . nextTick ) ;
127+ const handler = createAuthorizerHandler ( mockedDeps ) ;
128+ handler ( mockEvent , mockContext , mockCallback ) ;
129+ await new Promise ( process . nextTick ) ;
134130
135- expect ( mockCallback ) . toHaveBeenCalledWith ( null , expect . objectContaining ( {
136- policyDocument : expect . objectContaining ( {
137- Statement : [
138- expect . objectContaining ( {
139- Effect : 'Deny' ,
140- } ) ,
141- ] ,
142- } ) ,
143- } ) ) ;
144- } ) ;
131+ expect ( mockCallback ) . toHaveBeenCalledWith ( null , expect . objectContaining ( {
132+ policyDocument : expect . objectContaining ( {
133+ Statement : [
134+ expect . objectContaining ( {
135+ Effect : 'Deny' ,
136+ } ) ,
137+ ] ,
138+ } ) ,
139+ } ) ) ;
140+ } ) ;
145141
146- it ( 'Should deny the request when no supplier ID is found' , async ( ) => {
147- mockEvent . headers = { 'apim-application-id' : 'unknown-apim-id' } ;
148- ( mockedDeps . supplierRepo . getSupplierByApimId as jest . Mock ) . mockRejectedValue ( new Error ( 'Supplier not found' ) ) ;
149-
150- const handler = createAuthorizerHandler ( mockedDeps ) ;
151- handler ( mockEvent , mockContext , mockCallback ) ;
152- await new Promise ( process . nextTick ) ;
153-
154- expect ( mockCallback ) . toHaveBeenCalledWith ( null , expect . objectContaining ( {
155- policyDocument : expect . objectContaining ( {
156- Statement : [
157- expect . objectContaining ( {
158- Effect : 'Deny' ,
159- } ) ,
160- ] ,
161- } ) ,
162- } ) ) ;
163- } ) ;
142+ it ( 'Should deny the request when no supplier ID is found' , async ( ) => {
143+ mockEvent . headers = { 'apim-application-id' : 'unknown-apim-id' } ;
144+ ( mockedDeps . supplierRepo . getSupplierByApimId as jest . Mock ) . mockRejectedValue ( new Error ( 'Supplier not found' ) ) ;
164145
165- it ( 'Should allow the request when the supplier ID is found' , async ( ) => {
166- mockEvent . headers = { 'apim-application-id' : 'valid-apim-id' } ;
167- ( mockedDeps . supplierRepo . getSupplierByApimId as jest . Mock ) . mockResolvedValue ( {
168- id : 'supplier-123' ,
169- apimApplicationId : 'valid-apim-id' ,
170- name : 'Test Supplier' ,
171- status : 'ENABLED'
172- } ) ;
173-
174- const handler = createAuthorizerHandler ( mockedDeps ) ;
175- handler ( mockEvent , mockContext , mockCallback ) ;
176- await new Promise ( process . nextTick ) ;
177-
178- expect ( mockCallback ) . toHaveBeenCalledWith ( null , expect . objectContaining ( {
179- policyDocument : expect . objectContaining ( {
180- Statement : [
181- expect . objectContaining ( {
182- Effect : 'Allow' ,
183- } ) ,
184- ] ,
185- } ) ,
186- principalId : 'supplier-123' ,
187- } ) ) ;
146+ const handler = createAuthorizerHandler ( mockedDeps ) ;
147+ handler ( mockEvent , mockContext , mockCallback ) ;
148+ await new Promise ( process . nextTick ) ;
149+
150+ expect ( mockCallback ) . toHaveBeenCalledWith ( null , expect . objectContaining ( {
151+ policyDocument : expect . objectContaining ( {
152+ Statement : [
153+ expect . objectContaining ( {
154+ Effect : 'Deny' ,
155+ } ) ,
156+ ] ,
157+ } ) ,
158+ } ) ) ;
159+ } ) ;
160+
161+ it ( 'Should allow the request when the supplier ID is found' , async ( ) => {
162+ mockEvent . headers = { 'apim-application-id' : 'valid-apim-id' } ;
163+ ( mockedDeps . supplierRepo . getSupplierByApimId as jest . Mock ) . mockResolvedValue ( {
164+ id : 'supplier-123' ,
165+ apimApplicationId : 'valid-apim-id' ,
166+ name : 'Test Supplier' ,
167+ status : 'ENABLED'
188168 } ) ;
169+
170+ const handler = createAuthorizerHandler ( mockedDeps ) ;
171+ handler ( mockEvent , mockContext , mockCallback ) ;
172+ await new Promise ( process . nextTick ) ;
173+
174+ expect ( mockCallback ) . toHaveBeenCalledWith ( null , expect . objectContaining ( {
175+ policyDocument : expect . objectContaining ( {
176+ Statement : [
177+ expect . objectContaining ( {
178+ Effect : 'Allow' ,
179+ } ) ,
180+ ] ,
181+ } ) ,
182+ principalId : 'supplier-123' ,
183+ } ) ) ;
189184 } ) ;
185+ } ) ;
190186
191- it ( 'Should deny the request the supplier is disabled' , async ( ) => {
192- mockEvent . headers = { 'apim-application-id' : 'unknown-apim-id' } ;
193- ( mockedDeps . supplierRepo . getSupplierByApimId as jest . Mock ) . mockResolvedValue ( {
194- id : 'supplier-123' ,
195- apimApplicationId : 'valid-apim-id' ,
196- name : 'Test Supplier' ,
197- status : 'DISABLED'
198- } ) ;
199-
200- const handler = createAuthorizerHandler ( mockedDeps ) ;
201- handler ( mockEvent , mockContext , mockCallback ) ;
202- await new Promise ( process . nextTick ) ;
203-
204- expect ( mockCallback ) . toHaveBeenCalledWith ( null , expect . objectContaining ( {
205- policyDocument : expect . objectContaining ( {
206- Statement : [
207- expect . objectContaining ( {
208- Effect : 'Deny' ,
209- } ) ,
210- ] ,
187+ it ( 'Should deny the request the supplier is disabled' , async ( ) => {
188+ mockEvent . headers = { 'apim-application-id' : 'unknown-apim-id' } ;
189+ ( mockedDeps . supplierRepo . getSupplierByApimId as jest . Mock ) . mockResolvedValue ( {
190+ id : 'supplier-123' ,
191+ apimApplicationId : 'valid-apim-id' ,
192+ name : 'Test Supplier' ,
193+ status : 'DISABLED'
194+ } ) ;
195+
196+ const handler = createAuthorizerHandler ( mockedDeps ) ;
197+ handler ( mockEvent , mockContext , mockCallback ) ;
198+ await new Promise ( process . nextTick ) ;
199+
200+ expect ( mockCallback ) . toHaveBeenCalledWith ( null , expect . objectContaining ( {
201+ policyDocument : expect . objectContaining ( {
202+ Statement : [
203+ expect . objectContaining ( {
204+ Effect : 'Deny' ,
211205 } ) ,
212- } ) ) ;
213- } ) ;
206+ ] ,
207+ } ) ,
208+ } ) ) ;
209+ } ) ;
214210} ) ;
0 commit comments