Skip to content

Commit 2eb7ab3

Browse files
author
Alexander Schueren
authored
chore(commons): add skip step for multiple call operations (#1583)
1 parent 5eba149 commit 2eb7ab3

File tree

2 files changed

+94
-34
lines changed

2 files changed

+94
-34
lines changed

Diff for: packages/commons/src/userAgentMiddleware.ts

+7
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ const customUserAgentMiddleware = (feature: string) => {
3333
// @ts-ignore
3434
const addUserAgentMiddleware = (client, feature: string): void => {
3535
try {
36+
if (
37+
client.middlewareStack
38+
.identify()
39+
.includes('addPowertoolsToUserAgent: POWERTOOLS,USER_AGENT')
40+
) {
41+
return;
42+
}
3643
client.middlewareStack.addRelativeTo(
3744
customUserAgentMiddleware(feature),
3845
middlewareOptions

Diff for: packages/commons/tests/unit/userAgentMiddleware.test.ts

+87-34
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,26 @@ import { InvokeCommand, LambdaClient } from '@aws-sdk/client-lambda';
33
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
44
import { ScanCommand } from '@aws-sdk/lib-dynamodb';
55
import { GetParameterCommand, SSMClient } from '@aws-sdk/client-ssm';
6-
import { version as PT_VERSION } from '../../package.json';
6+
import { PT_VERSION } from '../../src/version';
77
import { AppConfigDataClient } from '@aws-sdk/client-appconfigdata';
88
import {
99
GetSecretValueCommand,
1010
SecretsManagerClient,
1111
} 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;
1226

1327
const options = {
1428
region: 'us-east-1',
@@ -20,6 +34,57 @@ const options = {
2034
},
2135
};
2236

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+
2388
describe('Given a client of instance: ', () => {
2489
it.each([
2590
{
@@ -57,44 +122,15 @@ describe('Given a client of instance: ', () => {
57122
);
58123

59124
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
83127
);
84128

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);
94130
}
95131
);
96132

97-
it('should not throw erro, when client fails to add middleware', () => {
133+
it('should not throw error, when client fails to add middleware', () => {
98134
// create mock client that throws error when adding middleware
99135
const client = {
100136
middlewareStack: {
@@ -106,4 +142,21 @@ describe('Given a client of instance: ', () => {
106142

107143
expect(() => addUserAgentMiddleware(client, 'my-feature')).not.toThrow();
108144
});
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+
});
109162
});

0 commit comments

Comments
 (0)