Skip to content

Commit

Permalink
feat: add Jest matcher for nth specific Command (#146)
Browse files Browse the repository at this point in the history
* fix: added nth specific

* test: added missing fail check for nthspecific
  • Loading branch information
sander-b-postnl authored Mar 6, 2023
1 parent 932d2a7 commit 89ef933
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 2 deletions.
88 changes: 88 additions & 0 deletions packages/aws-sdk-client-mock-jest/src/jestMatchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ interface AwsSdkJestMockBaseMatchers<R> extends Record<string, any> {
command: new (input: TCmdInput) => AwsCommand<TCmdInput, TCmdOutput>,
input: Partial<TCmdInput>,
): R;

/**
* Asserts {@link AwsStub Aws Client Mock} received a {@link command} as defined specific {@link call}
* number with matchin {@link input}
*
* @param call call number to assert
* @param command aws-sdk command constructor
* @param input
*/
toHaveReceivedNthSpecificCommandWith<TCmdInput extends object, TCmdOutput extends MetadataBearer>(
call: number,
command: new (input: TCmdInput) => AwsCommand<TCmdInput, TCmdOutput>,
input: Partial<TCmdInput>
): R;
}

interface AwsSdkJestMockAliasMatchers<R> {
Expand Down Expand Up @@ -108,6 +122,20 @@ interface AwsSdkJestMockAliasMatchers<R> {
command: new (input: TCmdInput) => AwsCommand<TCmdInput, TCmdOutput>,
input: Partial<TCmdInput>,
): R;

/**
* Asserts {@link AwsStub Aws Client Mock} received a {@link command} as defined specific {@link call}
* number with matchin {@link input}
*
* @param call call number to assert
* @param command aws-sdk command constructor
* @param input
*/
toReceiveNthSpecificCommandWith<TCmdInput extends object, TCmdOutput extends MetadataBearer>(
call: number,
command: new (input: TCmdInput) => AwsCommand<TCmdInput, TCmdOutput>,
input: Partial<TCmdInput>
): R;
}

/**
Expand Down Expand Up @@ -348,6 +376,65 @@ const baseMatchers: { [P in keyof AwsSdkJestMockBaseMatchers<unknown>]: jest.Cus
],
});
},
/**
* implementation of {@link AwsSdkJestMockMatchers.toHaveReceivedNthSpecificCommandWith} matcher
*/
toHaveReceivedNthSpecificCommandWith(
this: jest.MatcherContext,
mockClient: ClientMock,
call: number,
command: new () => AnyCommand,
input?: Record<string, unknown>,
) {
assert(
call && typeof call === 'number' && call > 0,
'Call number must be a number greater than 0',
);

return processMatch<{ received: AnyCommand | undefined }>({
ctx: this,
mockClient,
command,
check: ({commandCalls}) => {
if (commandCalls.length < call) {
return {pass: false, data: {received: undefined}};
}

const received = commandCalls[call - 1].args[0];

let pass = false;
if (received instanceof command) {
try {
expect(received.input).toEqual(
expect.objectContaining(input),
);
pass = true;
} catch (e) { // eslint-disable-line no-empty
}
}

return {
pass,
data: {received},
};
},
message: ({cmd, client, data, notPrefix}) => [
`Expected ${client} to ${notPrefix}receive ${call}. ${cmd} with ${this.utils.printExpected(input)}`,
...(data.received
? [
`${client} received ${this.utils.printReceived(data.received.constructor.name)} with input:`,
this.utils.printDiffOrStringify(
input,
data.received.input,
'Expected',
'Received',
false,
),
]
: []),
],
});
},
};

/* typing ensures keys matching */
Expand All @@ -356,6 +443,7 @@ const aliasMatchers: { [P in keyof AwsSdkJestMockAliasMatchers<unknown>]: jest.C
toReceiveCommand: baseMatchers.toHaveReceivedCommand,
toReceiveCommandWith: baseMatchers.toHaveReceivedCommandWith,
toReceiveNthCommandWith: baseMatchers.toHaveReceivedNthCommandWith,
toReceiveNthSpecificCommandWith: baseMatchers.toHaveReceivedNthSpecificCommandWith,
};

// Skip registration if jest expect does not exist
Expand Down
25 changes: 24 additions & 1 deletion packages/aws-sdk-client-mock-jest/test/jestMatchers.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {AwsClientStub, mockClient} from 'aws-sdk-client-mock';
import {PublishCommand, SNSClient} from '@aws-sdk/client-sns';
import {publishCmd1, publishCmd2} from 'aws-sdk-client-mock/test/fixtures';
import {publishCmd1, publishCmd2, subscribeCmd1} from 'aws-sdk-client-mock/test/fixtures';
import '../src';

let snsMock: AwsClientStub<SNSClient>;
Expand Down Expand Up @@ -241,3 +241,26 @@ Calls:
`);
});
});

describe('toHaveReceivedNthSpecificCommandWith', () => {
it('passes on receiving second Command with partial match', async () => {
const sns = new SNSClient({});
await sns.send(publishCmd1);
await sns.send(subscribeCmd1);
await sns.send(publishCmd2);

expect(() => expect(snsMock).toHaveReceivedNthSpecificCommandWith(2, PublishCommand, {Message: publishCmd2.input.Message})).not.toThrow();
});

it('fails on receiving less Commands than the nth expected', async () => {
const sns = new SNSClient({});
await sns.send(publishCmd1);

expect(() => expect(snsMock).toHaveReceivedNthSpecificCommandWith(2, PublishCommand, {Message: publishCmd2.input.Message})).toThrowErrorMatchingInlineSnapshot(`
"Expected SNSClient to receive 2. <green>\\"PublishCommand\\"</> with <green>{\\"Message\\": \\"second mock message\\"}</>
Calls:
1. PublishCommand: <red>{\\"Message\\": \\"mock message\\", \\"TopicArn\\": \\"arn:aws:sns:us-east-1:111111111111:MyTopic\\"}</>"
`);
});
});
6 changes: 5 additions & 1 deletion packages/aws-sdk-client-mock/test/fixtures.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {PublishCommand} from '@aws-sdk/client-sns';
import {PublishCommand, SubscribeCommand} from '@aws-sdk/client-sns';

export const topicArn = 'arn:aws:sns:us-east-1:111111111111:MyTopic';
export const topicArn2 = 'arn:aws:sns:us-east-1:111111111111:MyOtherTopic';
Expand All @@ -15,6 +15,10 @@ export const publishCmd3 = new PublishCommand({
TopicArn: topicArn2,
Message: 'third mock message',
});
export const subscribeCmd1 = new SubscribeCommand({
TopicArn: topicArn,
Protocol: 'sqs',
});

export const uuid1 = '12345678-1111-1111-1111-111122223333';
export const uuid2 = '12345678-2222-2222-2222-111122223333';
Expand Down

0 comments on commit 89ef933

Please sign in to comment.