Skip to content

Commit c21dec5

Browse files
authored
test(event-handler): coverage 100% for AppSync GraphQL (#4261)
1 parent b1d68bd commit c21dec5

File tree

6 files changed

+109
-31
lines changed

6 files changed

+109
-31
lines changed

packages/event-handler/src/appsync-graphql/RouteHandlerRegistry.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,13 @@ class RouteHandlerRegistry {
4040
public register(
4141
options: RouteHandlerOptions<Record<string, unknown>, boolean, boolean>
4242
): void {
43-
const { fieldName, handler, typeName, throwOnError, aggregate } = options;
43+
const {
44+
fieldName,
45+
handler,
46+
typeName,
47+
throwOnError = false,
48+
aggregate = true,
49+
} = options;
4450
this.#logger.debug(`Adding resolver for field ${typeName}.${fieldName}`);
4551
const cacheKey = this.#makeKey(typeName, fieldName);
4652
if (this.resolvers.has(cacheKey)) {

packages/event-handler/src/appsync-graphql/Router.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -531,8 +531,8 @@ class Router {
531531
fieldName,
532532
handler: handler as BatchResolverHandler,
533533
typeName,
534-
aggregate: batchResolverOptions?.aggregate ?? true,
535-
throwOnError: batchResolverOptions?.throwOnError ?? false,
534+
aggregate: batchResolverOptions?.aggregate,
535+
throwOnError: batchResolverOptions?.throwOnError,
536536
});
537537
return;
538538
}
@@ -544,8 +544,8 @@ class Router {
544544
fieldName,
545545
handler: descriptor?.value,
546546
typeName,
547-
aggregate: batchResolverOptions?.aggregate ?? true,
548-
throwOnError: batchResolverOptions?.throwOnError ?? false,
547+
aggregate: batchResolverOptions?.aggregate,
548+
throwOnError: batchResolverOptions?.throwOnError,
549549
});
550550
return descriptor;
551551
};
@@ -730,8 +730,8 @@ class Router {
730730
fieldName,
731731
handler: handlerOrOptions as BatchResolverHandler,
732732
typeName: 'Query',
733-
aggregate: options?.aggregate ?? true,
734-
throwOnError: options?.throwOnError ?? false,
733+
aggregate: options?.aggregate,
734+
throwOnError: options?.throwOnError,
735735
});
736736

737737
return;
@@ -742,8 +742,8 @@ class Router {
742742
fieldName,
743743
handler: descriptor?.value,
744744
typeName: 'Query',
745-
aggregate: handlerOrOptions?.aggregate ?? true,
746-
throwOnError: handlerOrOptions?.throwOnError ?? false,
745+
aggregate: handlerOrOptions?.aggregate,
746+
throwOnError: handlerOrOptions?.throwOnError,
747747
});
748748

749749
return descriptor;
@@ -927,8 +927,8 @@ class Router {
927927
fieldName,
928928
handler: handlerOrOptions as BatchResolverHandler,
929929
typeName: 'Mutation',
930-
aggregate: options?.aggregate ?? true,
931-
throwOnError: options?.throwOnError ?? false,
930+
aggregate: options?.aggregate,
931+
throwOnError: options?.throwOnError,
932932
});
933933

934934
return;
@@ -939,8 +939,8 @@ class Router {
939939
fieldName,
940940
handler: descriptor?.value,
941941
typeName: 'Mutation',
942-
aggregate: handlerOrOptions?.aggregate ?? true,
943-
throwOnError: handlerOrOptions?.throwOnError ?? false,
942+
aggregate: handlerOrOptions?.aggregate,
943+
throwOnError: handlerOrOptions?.throwOnError,
944944
});
945945

946946
return descriptor;

packages/event-handler/tests/unit/appsync-graphql/AppSyncGraphQLResolver.test.ts

Lines changed: 78 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -506,15 +506,11 @@ describe('Class: AppSyncGraphQLResolver', () => {
506506
setupHandler(handler);
507507

508508
if (aggregate) {
509-
app.batchResolver(handler, {
510-
fieldName: 'batchGet',
511-
typeName: 'Query',
509+
app.onBatchQuery('batchGet', handler, {
512510
aggregate: true,
513511
});
514512
} else {
515-
app.batchResolver(handler, {
516-
fieldName: 'batchGet',
517-
typeName: 'Query',
513+
app.onBatchQuery('batchGet', handler, {
518514
aggregate: false,
519515
throwOnError: true,
520516
});
@@ -596,16 +592,14 @@ describe('Class: AppSyncGraphQLResolver', () => {
596592
.mockResolvedValueOnce({ id: '1', value: 'A' })
597593
.mockRejectedValueOnce(new Error('fail'))
598594
.mockResolvedValueOnce({ id: '3', value: 'C' });
599-
app.batchResolver(handler, {
600-
fieldName: 'batchGet',
601-
typeName: 'Query',
595+
app.onBatchMutation('batchPut', handler, {
602596
aggregate: false,
603597
throwOnError: true,
604598
});
605599
const events = [
606-
onGraphqlEventFactory('batchGet', 'Query', { id: '1' }),
607-
onGraphqlEventFactory('batchGet', 'Query', { id: '2' }),
608-
onGraphqlEventFactory('batchGet', 'Query', { id: '3' }),
600+
onGraphqlEventFactory('batchPut', 'Mutation', { id: '1' }),
601+
onGraphqlEventFactory('batchPut', 'Mutation', { id: '2' }),
602+
onGraphqlEventFactory('batchPut', 'Mutation', { id: '3' }),
609603
];
610604

611605
// Act
@@ -640,4 +634,76 @@ describe('Class: AppSyncGraphQLResolver', () => {
640634
)
641635
);
642636
});
637+
638+
it.each([
639+
{
640+
throwOnError: true,
641+
description: 'throwOnError=true',
642+
},
643+
{
644+
throwOnError: false,
645+
description: 'throwOnError=false',
646+
},
647+
])(
648+
'preserves the scope when using `onBatchQuery` & `onBatchMutation` decorators when aggregate=false and $description',
649+
async ({ throwOnError }) => {
650+
// Prepare
651+
const app = new AppSyncGraphQLResolver({ logger: console });
652+
653+
class Lambda {
654+
public readonly scope = 'scoped';
655+
656+
@app.onBatchQuery('batchGet', {
657+
throwOnError,
658+
})
659+
public async handleBatchGet(
660+
events: AppSyncResolverEvent<{ id: number }>[]
661+
) {
662+
const ids = events.map((event) => event.arguments.id);
663+
return ids.map((id) => ({
664+
id,
665+
scope: this.scope,
666+
}));
667+
}
668+
669+
@app.onBatchMutation('batchPut', {
670+
throwOnError,
671+
})
672+
public async handleBatchPut(
673+
_events: AppSyncResolverEvent<{ id: number }>[]
674+
) {
675+
return [this.scope, this.scope];
676+
}
677+
678+
public async handler(event: unknown, context: Context) {
679+
return app.resolve(event, context, { scope: this });
680+
}
681+
}
682+
const lambda = new Lambda();
683+
const handler = lambda.handler.bind(lambda);
684+
685+
// Act
686+
const resultQuery = await handler(
687+
[
688+
onGraphqlEventFactory('batchGet', 'Query', { id: 1 }),
689+
onGraphqlEventFactory('batchGet', 'Query', { id: 2 }),
690+
],
691+
context
692+
);
693+
const resultMutation = await handler(
694+
[
695+
onGraphqlEventFactory('batchPut', 'Mutation', { id: 1 }),
696+
onGraphqlEventFactory('batchPut', 'Mutation', { id: 2 }),
697+
],
698+
context
699+
);
700+
701+
// Assess
702+
expect(resultQuery).toEqual([
703+
{ id: 1, scope: 'scoped' },
704+
{ id: 2, scope: 'scoped' },
705+
]);
706+
expect(resultMutation).toEqual(['scoped', 'scoped']);
707+
}
708+
);
643709
});

packages/event-handler/tests/unit/appsync-graphql/RouteHandlerRegistry.test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,18 @@ describe('Class: RouteHandlerRegistry', () => {
5959
// Assess
6060
expect(registry.resolvers.size).toBe(1);
6161
expect(registry.resolvers.get('Query.getPost')).toEqual({
62+
aggregate: true,
6263
fieldName: 'getPost',
6364
typeName: 'Query',
65+
throwOnError: false,
6466
handler: otherHandler,
6567
});
6668
expect(console.warn).toHaveBeenCalledWith(
6769
"A resolver for field 'getPost' is already registered for 'Query'. The previous resolver will be replaced."
6870
);
6971
});
7072

71-
it('will not replace the resolver if the event type is different', () => {
73+
it("doesn't replace the resolver if the event type is different", () => {
7274
// Prepare
7375
const registry = getRegistry();
7476
const originalHandler = vi.fn();
@@ -89,13 +91,17 @@ describe('Class: RouteHandlerRegistry', () => {
8991
// Assess
9092
expect(registry.resolvers.size).toBe(2);
9193
expect(registry.resolvers.get('Query.getPost')).toEqual({
94+
aggregate: true,
9295
fieldName: 'getPost',
9396
typeName: 'Query',
97+
throwOnError: false,
9498
handler: originalHandler,
9599
});
96100
expect(registry.resolvers.get('Mutation.getPost')).toEqual({
101+
aggregate: true,
97102
fieldName: 'getPost',
98103
typeName: 'Mutation',
104+
throwOnError: false,
99105
handler: otherHandler,
100106
});
101107
});

vitest.config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ export default defineConfig({
1919
'packages/testing/**',
2020
],
2121
},
22+
projects: [
23+
'packages/*/vitest.config.ts',
24+
'examples/app/vitest.config.ts',
25+
'layers/vitest.config.ts',
26+
],
2227
setupFiles: ['./packages/testing/src/setupEnv.ts'],
2328
hookTimeout: 1_000 * 60 * 10, // 10 minutes
2429
testTimeout: 1_000 * 60 * 3, // 3 minutes

vitest.workspace.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)