Skip to content

Commit

Permalink
fix: do not assume related model or field is in datastore schema (#621)
Browse files Browse the repository at this point in the history
Co-authored-by: Hein Jeong <heinje@amazon.com>
  • Loading branch information
hein-j and Hein Jeong authored Sep 2, 2022
1 parent c8c9689 commit b6c5750
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 4 deletions.
81 changes: 81 additions & 0 deletions packages/codegen-ui/lib/__tests__/__utils__/mock-schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -783,3 +783,84 @@ export const schemaWithNonModels: Schema = {
},
version: '38a1a46479c6cd75d21439d7f3122c1d',
};

export const schemaWithAssumptions: Schema = {
models: {
User: {
name: 'User',
fields: {
friends: {
name: 'friends',
isArray: true,
type: {
model: 'Friend',
},
isRequired: false,
attributes: [],
isArrayNullable: true,
association: {
connectionType: 'HAS_MANY',
associatedWith: 'friendId',
},
},
posts: {
name: 'posts',
isArray: true,
type: {
model: 'Post',
},
isRequired: false,
attributes: [],
isArrayNullable: true,
association: {
connectionType: 'HAS_MANY',
associatedWith: 'userPostsId',
},
},
},
syncable: true,
pluralName: 'Users',
attributes: [
{
type: 'model',
properties: {},
},
{
type: 'key',
properties: {
fields: ['id'],
},
},
],
},
Event: {
name: 'Post',
fields: {
name: {
name: 'name',
isArray: false,
type: 'String',
isRequired: false,
attributes: [],
},
},
syncable: true,
pluralName: 'Posts',
attributes: [
{
type: 'model',
properties: {},
},
{
type: 'key',
properties: {
fields: ['id'],
},
},
],
},
},
enums: {},
nonModels: {},
version: 'version',
};
24 changes: 23 additions & 1 deletion packages/codegen-ui/lib/__tests__/generic-from-datastore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
*/
import { getGenericFromDataStore } from '../generic-from-datastore';
import { HasManyRelationshipType } from '../types';
import { schemaWithEnums, schemaWithNonModels, schemaWithRelationships } from './__utils__/mock-schemas';
import {
schemaWithEnums,
schemaWithNonModels,
schemaWithRelationships,
schemaWithAssumptions,
} from './__utils__/mock-schemas';

describe('getGenericFromDataStore', () => {
it('should map fields', () => {
Expand Down Expand Up @@ -118,4 +123,21 @@ describe('getGenericFromDataStore', () => {
Misc: { fields: { quotes: { dataType: 'String', required: false, readOnly: false, isArray: true } } },
});
});

it('should handle schema with assumed associated fields and modldkjld', () => {
const genericSchema = getGenericFromDataStore(schemaWithAssumptions);
const userFields = genericSchema.models.User.fields;

expect(userFields.friends.relationship).toStrictEqual({
type: 'HAS_MANY',
relatedModelName: 'Friend',
relatedModelField: 'friendId',
});

expect(userFields.posts.relationship).toStrictEqual({
type: 'HAS_MANY',
relatedModelName: 'Post',
relatedModelField: 'userPostsId',
});
});
});
7 changes: 4 additions & 3 deletions packages/codegen-ui/lib/generic-from-datastore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,12 @@ export function getGenericFromDataStore(dataStoreSchema: DataStoreSchema): Gener
let modelRelationship: GenericDataRelationshipType | undefined;

if (relationshipType === 'HAS_MANY' && 'associatedWith' in field.association) {
const associatedModel = dataStoreSchema.models[field.type.model];
const associatedModel = dataStoreSchema.models[relatedModelName];
const associatedFieldName = field.association.associatedWith;
const associatedField = associatedModel.fields[associatedFieldName];
const associatedField = associatedModel?.fields[associatedFieldName];
// if the associated model is a join table, update relatedModelName to the actual related model
if (
associatedField &&
typeof associatedField.type === 'object' &&
'model' in associatedField.type &&
associatedField.type.model === model.name
Expand All @@ -95,7 +96,7 @@ export function getGenericFromDataStore(dataStoreSchema: DataStoreSchema): Gener
}
// if the associated model is not a join table, note implicit relationship for associated field
} else {
addRelationship(fieldsWithImplicitRelationships, associatedModel.name, associatedFieldName, {
addRelationship(fieldsWithImplicitRelationships, relatedModelName, associatedFieldName, {
type: 'HAS_ONE',
relatedModelName: model.name,
});
Expand Down

0 comments on commit b6c5750

Please sign in to comment.