Skip to content

Commit 60adab0

Browse files
authored
Merge pull request #276 from lazpavel/has-one-directive
fix(amplify-codegen): fix v2 has one process connection directive
2 parents 5e855a6 + fc4046e commit 60adab0

File tree

2 files changed

+128
-87
lines changed

2 files changed

+128
-87
lines changed

packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-visitor.test.ts

Lines changed: 82 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,11 @@ const createAndGenerateVisitor = (schema: string, usePipelinedTransformer: boole
2020
return visitor;
2121
};
2222

23-
const createAndGeneratePipelinedTransformerVisitor = (
24-
schema: string
25-
) => {
23+
const createAndGeneratePipelinedTransformerVisitor = (schema: string) => {
2624
return createAndGenerateVisitor(schema, true);
2725
};
2826

2927
describe('AppSyncModelVisitor', () => {
30-
3128
it('should support schema with id', () => {
3229
const schema = /* GraphQL */ `
3330
type Post @model {
@@ -177,14 +174,14 @@ describe('AppSyncModelVisitor', () => {
177174
describe('with connection name', () => {
178175
const schema = /* GraphQL */ `
179176
type Post @model {
180-
id: ID!,
177+
id: ID!
181178
title: String!
182179
content: String
183180
comments: [Comment] @connection(name: "PostComment")
184181
}
185182
186183
type Comment @model {
187-
id: ID!,
184+
id: ID!
188185
comment: String!
189186
post: Post @connection(name: "PostComment")
190187
}
@@ -223,14 +220,14 @@ describe('AppSyncModelVisitor', () => {
223220
describe('connection with fields argument', () => {
224221
const schema = /* GraphQL */ `
225222
type Post @model {
226-
id: ID!,
223+
id: ID!
227224
title: String!
228225
content: String
229226
comments: [Comment] @connection(fields: ["id"])
230227
}
231228
232229
type Comment @model {
233-
id: ID!,
230+
id: ID!
234231
comment: String!
235232
postId: ID!
236233
post: Post @connection(fields: ["postId"])
@@ -275,14 +272,14 @@ describe('AppSyncModelVisitor', () => {
275272
it('should not include a comments in Post when comments field does not have connection directive', () => {
276273
const schema = /* GraphQL */ `
277274
type Post @model {
278-
id: ID!,
275+
id: ID!
279276
title: String!
280277
content: String
281278
comments: [Comment]
282279
}
283280
284281
type Comment @model {
285-
id: ID!,
282+
id: ID!
286283
comment: String!
287284
post: Post @connection
288285
}
@@ -299,14 +296,14 @@ describe('AppSyncModelVisitor', () => {
299296
it('should not include a post when post field in Comment when post does not have connection directive', () => {
300297
const schema = /* GraphQL */ `
301298
type Post @model {
302-
id: ID!,
299+
id: ID!
303300
title: String!
304301
content: String
305302
comments: [Comment] @connection
306303
}
307304
308305
type Comment @model {
309-
id: ID!,
306+
id: ID!
310307
comment: String!
311308
post: Post
312309
}
@@ -320,12 +317,39 @@ describe('AppSyncModelVisitor', () => {
320317
expect(commentsField).not.toContain('post');
321318
expect(commentsField).toContain('postCommentsId'); // because of connection from Post.comments
322319
});
320+
321+
it('should not generate projectTeamId connection field for hasOne directive', () => {
322+
const schema = /* GraphQL */ `
323+
type Project @model {
324+
id: ID!
325+
name: String
326+
team: Team @hasOne
327+
}
328+
329+
type Team @model {
330+
id: ID!
331+
name: String!
332+
}
333+
`;
334+
const ast = parse(schema);
335+
const builtSchema = buildSchemaWithDirectives(schema);
336+
const visitor = new AppSyncModelVisitor(
337+
builtSchema,
338+
{ directives, target: 'typescript', generate: CodeGenGenerateEnum.code, usePipelinedTransformer: true },
339+
{},
340+
);
341+
visit(ast, { leave: visitor });
342+
visitor.generate();
343+
const teamFields = visitor.models.Team.fields.map(field => field.name);
344+
expect(teamFields).not.toContain('projectTeamId');
345+
});
323346
});
347+
324348
describe('auth directive', () => {
325349
it('should process auth with owner authorization', () => {
326350
const schema = /* GraphQL */ `
327351
type Post @searchable @model @auth(rules: [{ allow: owner }]) {
328-
id: ID!,
352+
id: ID!
329353
title: String!
330354
content: String
331355
}
@@ -353,7 +377,7 @@ describe('AppSyncModelVisitor', () => {
353377
it('should process group with owner authorization', () => {
354378
const schema = /* GraphQL */ `
355379
type Post @model @searchable @auth(rules: [{ allow: groups, groups: ["admin", "moderator"] }]) {
356-
id: ID!,
380+
id: ID!
357381
title: String!
358382
content: String
359383
}
@@ -577,16 +601,16 @@ describe('AppSyncModelVisitor', () => {
577601

578602
beforeEach(() => {
579603
simpleManyToManySchema = /* GraphQL */ `
580-
type Human @model {
581-
governmentID: ID! @primaryKey
582-
pets: [Animal] @manyToMany(relationName: "PetFriend")
583-
}
584-
585-
type Animal @model {
586-
animalTag: ID!
587-
humanFriend: [Human] @manyToMany(relationName: "PetFriend")
588-
}
589-
`;
604+
type Human @model {
605+
governmentID: ID! @primaryKey
606+
pets: [Animal] @manyToMany(relationName: "PetFriend")
607+
}
608+
609+
type Animal @model {
610+
animalTag: ID!
611+
humanFriend: [Human] @manyToMany(relationName: "PetFriend")
612+
}
613+
`;
590614

591615
simpleManyModelMap = {
592616
Human: {
@@ -599,16 +623,16 @@ describe('AppSyncModelVisitor', () => {
599623
isNullable: false,
600624
isList: false,
601625
name: 'governmentID',
602-
directives: [{ name: 'primaryKey', arguments: {} }]
626+
directives: [{ name: 'primaryKey', arguments: {} }],
603627
},
604628
{
605629
type: 'Animal',
606630
isNullable: true,
607631
isList: true,
608632
name: 'pets',
609-
directives: [{ name: 'manyToMany', arguments: { relationName: 'PetFriend' } }]
610-
}
611-
]
633+
directives: [{ name: 'manyToMany', arguments: { relationName: 'PetFriend' } }],
634+
},
635+
],
612636
},
613637
Animal: {
614638
name: 'Animal',
@@ -627,39 +651,39 @@ describe('AppSyncModelVisitor', () => {
627651
isNullable: true,
628652
isList: true,
629653
name: 'postID',
630-
directives: [{ name: 'manyToMany', arguments: { relationName: 'PetFriend' } }]
631-
}
654+
directives: [{ name: 'manyToMany', arguments: { relationName: 'PetFriend' } }],
655+
},
632656
],
633-
}
657+
},
634658
};
635659
});
636660

637661
transformedSimpleManyModelMap = {
638662
Human: {
639663
name: 'Human',
640664
type: 'model',
641-
directives: [{name: 'model', arguments: {}}],
665+
directives: [{ name: 'model', arguments: {} }],
642666
fields: [
643667
{
644668
type: 'ID',
645669
isNullable: false,
646670
isList: false,
647671
name: 'governmentID',
648-
directives: [{ name: 'primaryKey', arguments: {} }]
672+
directives: [{ name: 'primaryKey', arguments: {} }],
649673
},
650674
{
651675
type: 'PetFriend',
652676
isNullable: true,
653677
isList: true,
654678
name: 'pets',
655-
directives: [{ name: 'hasMany', arguments: { fields: ['governmentID'] } }]
656-
}
657-
]
679+
directives: [{ name: 'hasMany', arguments: { fields: ['governmentID'] } }],
680+
},
681+
],
658682
},
659683
Animal: {
660684
name: 'Animal',
661685
type: 'model',
662-
directives: [{name: 'model', arguments: {}}],
686+
directives: [{ name: 'model', arguments: {} }],
663687
fields: [
664688
{
665689
type: 'ID',
@@ -673,74 +697,74 @@ describe('AppSyncModelVisitor', () => {
673697
isNullable: true,
674698
isList: true,
675699
name: 'postID',
676-
directives: [{ name: 'hasMany', arguments: { fields: ['id'] } }]
677-
}
700+
directives: [{ name: 'hasMany', arguments: { fields: ['id'] } }],
701+
},
678702
],
679703
},
680704
PetFriend: {
681705
name: 'PetFriend',
682706
type: 'model',
683-
directives: [{name: 'model', arguments: {}}],
707+
directives: [{ name: 'model', arguments: {} }],
684708
fields: [
685709
{
686710
type: 'ID',
687711
isNullable: false,
688712
isList: false,
689713
name: 'id',
690-
directives: []
714+
directives: [],
691715
},
692716
{
693717
type: 'ID',
694718
isNullable: false,
695719
isList: false,
696720
name: 'humanID',
697-
directives: [{ name: 'index', arguments: { name: 'byHuman', sortKeyFields: ['animalID'] } }]
721+
directives: [{ name: 'index', arguments: { name: 'byHuman', sortKeyFields: ['animalID'] } }],
698722
},
699723
{
700724
type: 'ID',
701725
isNullable: false,
702726
isList: false,
703727
name: 'animalID',
704-
directives: [{ name: 'index', arguments: { name: 'byAnimal', sortKeyFields: ['humanID'] } }]
728+
directives: [{ name: 'index', arguments: { name: 'byAnimal', sortKeyFields: ['humanID'] } }],
705729
},
706730
{
707731
type: 'Human',
708732
isNullable: false,
709733
isList: false,
710734
name: 'human',
711-
directives: [{ name: 'belongsTo', arguments: { fields: ['humanID'] } }]
735+
directives: [{ name: 'belongsTo', arguments: { fields: ['humanID'] } }],
712736
},
713737
{
714738
type: 'Animal',
715739
isNullable: false,
716740
isList: false,
717741
name: 'animal',
718-
directives: [{ name: 'belongsTo', arguments: { fields: ['humanID'] } }]
719-
}
720-
]
721-
}
742+
directives: [{ name: 'belongsTo', arguments: { fields: ['humanID'] } }],
743+
},
744+
],
745+
},
722746
};
723747

724748
it('Should correctly convert the model map of a simple manyToMany', () => {
725749
const visitor = createAndGeneratePipelinedTransformerVisitor(simpleManyToManySchema);
726750

727751
expect(visitor.models.Human.fields.length).toEqual(5);
728-
expect(visitor.models.Human.fields[2].directives[0].name).toEqual('hasMany')
729-
expect(visitor.models.Human.fields[2].directives[0].arguments.fields.length).toEqual(1)
730-
expect(visitor.models.Human.fields[2].directives[0].arguments.fields[0]).toEqual('governmentID')
731-
expect(visitor.models.Human.fields[2].directives[0].arguments.indexName).toEqual('byHuman')
752+
expect(visitor.models.Human.fields[2].directives[0].name).toEqual('hasMany');
753+
expect(visitor.models.Human.fields[2].directives[0].arguments.fields.length).toEqual(1);
754+
expect(visitor.models.Human.fields[2].directives[0].arguments.fields[0]).toEqual('governmentID');
755+
expect(visitor.models.Human.fields[2].directives[0].arguments.indexName).toEqual('byHuman');
732756
expect(visitor.models.PetFriend).toBeDefined();
733757
expect(visitor.models.PetFriend.fields.length).toEqual(5);
734-
expect(visitor.models.PetFriend.fields[2].directives[0].name).toEqual('belongsTo')
735-
expect(visitor.models.PetFriend.fields[2].directives[0].arguments.fields.length).toEqual(1)
736-
expect(visitor.models.PetFriend.fields[2].directives[0].arguments.fields[0]).toEqual('animalID')
758+
expect(visitor.models.PetFriend.fields[2].directives[0].name).toEqual('belongsTo');
759+
expect(visitor.models.PetFriend.fields[2].directives[0].arguments.fields.length).toEqual(1);
760+
expect(visitor.models.PetFriend.fields[2].directives[0].arguments.fields[0]).toEqual('animalID');
737761
expect(visitor.models.Animal.fields.length).toEqual(5);
738762
expect(visitor.models.Animal.fields[2].type).toEqual('PetFriend');
739763
expect(visitor.models.Animal.fields[2].directives.length).toEqual(1);
740764
expect(visitor.models.Animal.fields[2].directives[0].name).toEqual('hasMany');
741-
expect(visitor.models.Animal.fields[2].directives[0].arguments.fields.length).toEqual(1)
742-
expect(visitor.models.Animal.fields[2].directives[0].arguments.fields[0]).toEqual('id')
743-
expect(visitor.models.Animal.fields[2].directives[0].arguments.indexName).toEqual('byAnimal')
765+
expect(visitor.models.Animal.fields[2].directives[0].arguments.fields.length).toEqual(1);
766+
expect(visitor.models.Animal.fields[2].directives[0].arguments.fields[0]).toEqual('id');
767+
expect(visitor.models.Animal.fields[2].directives[0].arguments.indexName).toEqual('byAnimal');
744768
});
745769
});
746770
});

0 commit comments

Comments
 (0)