@@ -3,12 +3,26 @@ import { InvokeCommand, LambdaClient } from '@aws-sdk/client-lambda';
3
3
import { DynamoDBClient } from '@aws-sdk/client-dynamodb' ;
4
4
import { ScanCommand } from '@aws-sdk/lib-dynamodb' ;
5
5
import { GetParameterCommand , SSMClient } from '@aws-sdk/client-ssm' ;
6
- import { version as PT_VERSION } from '../../package.json ' ;
6
+ import { PT_VERSION } from '../../src/version ' ;
7
7
import { AppConfigDataClient } from '@aws-sdk/client-appconfigdata' ;
8
8
import {
9
9
GetSecretValueCommand ,
10
10
SecretsManagerClient ,
11
11
} from '@aws-sdk/client-secrets-manager' ;
12
+ import { RelativeMiddlewareOptions } from '@aws-sdk/types/dist-types/middleware' ;
13
+
14
+ type SupportedSdkClients =
15
+ | LambdaClient
16
+ | DynamoDBClient
17
+ | SSMClient
18
+ | SecretsManagerClient
19
+ | AppConfigDataClient ;
20
+
21
+ type SupportedSdkCommands =
22
+ | InvokeCommand
23
+ | ScanCommand
24
+ | GetParameterCommand
25
+ | GetSecretValueCommand ;
12
26
13
27
const options = {
14
28
region : 'us-east-1' ,
@@ -20,6 +34,57 @@ const options = {
20
34
} ,
21
35
} ;
22
36
37
+ const assertMiddleware = ( feature : string ) => {
38
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
39
+ // @ts -ignore
40
+ return ( next ) => ( args ) => {
41
+ const userAgent = args ?. request ?. headers [ 'user-agent' ] ;
42
+ expect ( userAgent ) . toContain ( `PT/${ feature } /${ PT_VERSION } PTEnv/NA` ) ;
43
+ // make sure it's at the end of the user agent
44
+ expect (
45
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
46
+ // @ts -ignore
47
+ userAgent
48
+ ?. split ( ' ' )
49
+ . slice ( userAgent ?. split ( ' ' ) . length - 2 ) // take the last to entries of the user-agent header
50
+ . join ( ' ' )
51
+ ) . toEqual ( `PT/${ feature } /${ PT_VERSION } PTEnv/NA` ) ;
52
+
53
+ return next ( args ) ;
54
+ } ;
55
+ } ;
56
+
57
+ const assertMiddlewareOptions : RelativeMiddlewareOptions = {
58
+ relation : 'after' ,
59
+ toMiddleware : 'addPowertoolsToUserAgent' ,
60
+ name : 'testUserAgentHeader' ,
61
+ tags : [ 'TEST' ] ,
62
+ } ;
63
+
64
+ const runCommand = async (
65
+ client : SupportedSdkClients ,
66
+ command : SupportedSdkCommands
67
+ ) : Promise < unknown > => {
68
+ try {
69
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
70
+ // @ts -ignore
71
+ return await client . send ( command ) ;
72
+ } catch ( e ) {
73
+ // throw only jest errors and swallow the SDK client errors like credentials or connection issues
74
+ if (
75
+ e instanceof Error &&
76
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
77
+ // @ts -ignore
78
+ e . matcherResult !== undefined &&
79
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
80
+ // @ts -ignore
81
+ e . matcherResult . pass === false
82
+ ) {
83
+ throw e ;
84
+ }
85
+ }
86
+ } ;
87
+
23
88
describe ( 'Given a client of instance: ' , ( ) => {
24
89
it . each ( [
25
90
{
@@ -57,44 +122,15 @@ describe('Given a client of instance: ', () => {
57
122
) ;
58
123
59
124
client . middlewareStack . addRelativeTo (
60
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
61
- // @ts -ignore
62
- ( next ) => ( args ) => {
63
- const userAgent = args ?. request ?. headers [ 'user-agent' ] ;
64
- expect ( userAgent ) . toContain ( `PT/my-feature/${ PT_VERSION } PTEnv/NA` ) ;
65
- // make sure it's at the end of the user agent
66
- expect (
67
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
68
- // @ts -ignore
69
- userAgent
70
- ?. split ( ' ' )
71
- . slice ( userAgent ?. split ( ' ' ) . length - 2 ) // take the last to entries of the user-agent header
72
- . join ( ' ' )
73
- ) . toEqual ( `PT/my-feature/${ PT_VERSION } PTEnv/NA` ) ;
74
-
75
- return next ( args ) ;
76
- } ,
77
- {
78
- relation : 'after' ,
79
- toMiddleware : 'addPowertoolsToUserAgent' ,
80
- name : 'testUserAgentHeader' ,
81
- tags : [ 'TEST' ] ,
82
- }
125
+ assertMiddleware ( 'my-feature' ) ,
126
+ assertMiddlewareOptions
83
127
) ;
84
128
85
- try {
86
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
87
- // @ts -ignore
88
- await client . send ( command ) ;
89
- } catch ( e ) {
90
- if ( e instanceof Error && e . name === 'JestAssertionError' ) {
91
- throw e ;
92
- }
93
- }
129
+ await runCommand ( client , command ) ;
94
130
}
95
131
) ;
96
132
97
- it ( 'should not throw erro , when client fails to add middleware' , ( ) => {
133
+ it ( 'should not throw error , when client fails to add middleware' , ( ) => {
98
134
// create mock client that throws error when adding middleware
99
135
const client = {
100
136
middlewareStack : {
@@ -106,4 +142,21 @@ describe('Given a client of instance: ', () => {
106
142
107
143
expect ( ( ) => addUserAgentMiddleware ( client , 'my-feature' ) ) . not . toThrow ( ) ;
108
144
} ) ;
145
+
146
+ it ( 'should no-op if we add the middleware twice' , async ( ) => {
147
+ const client = new LambdaClient ( options ) ;
148
+ const command = new InvokeCommand ( { FunctionName : 'test' , Payload : '' } ) ;
149
+ addUserAgentMiddleware ( client , 'my-feature' ) ;
150
+ addUserAgentMiddleware ( client , 'your-feature' ) ;
151
+
152
+ client . middlewareStack . addRelativeTo (
153
+ assertMiddleware ( 'my-feature' ) ,
154
+ assertMiddlewareOptions
155
+ ) ;
156
+ await runCommand ( client , command ) ;
157
+
158
+ expect ( client . middlewareStack . identify ( ) ) . toContain (
159
+ 'addPowertoolsToUserAgent: POWERTOOLS,USER_AGENT'
160
+ ) ;
161
+ } ) ;
109
162
} ) ;
0 commit comments