Skip to content

Commit

Permalink
test: add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dpilch committed Jul 15, 2024
1 parent 6668967 commit c09f5d1
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 26 deletions.
8 changes: 8 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 36 additions & 20 deletions packages/backend-data/src/convert_schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,13 @@ export const extractImportedModels = (
importedSchemas: { schema: string; importedTableName: string }[];
nonImportedSchema: string;
} => {
if (importedAmplifyDynamoDBTableMap && Object.keys(importedAmplifyDynamoDBTableMap).length) {
Object.keys(importedAmplifyDynamoDBTableMap).forEach((modelName) => {
if (!importedModels?.includes(modelName)) {
throw new Error(`Imported table defined in importedAmplifyDynamoDBTableMap not found in importedModels list: ${modelName}`);
}
});
}
if (importedModels?.length) {
// TODO: maybe provide exported function from construct
const parsedSchema = parse(schema);
Expand All @@ -273,28 +280,37 @@ export const extractImportedModels = (
);
}
);
// ok to cast as ObjectTypeDefinitionNode because the type was checked in the partition function
const importedObjectTypeDefinitionNodes = importedDefinitionNodes as ObjectTypeDefinitionNode[];

importedModels.forEach((modelName) => {
if (!importedObjectTypeDefinitionNodes.some((definitionNode) => definitionNode.name.value === modelName)) {
throw new Error(`Imported model not found in schema: ${modelName}`)
}
});

const importedSchemas =
importedObjectTypeDefinitionNodes
.map((definitionNode) => {
const importedTableName = (importedAmplifyDynamoDBTableMap ?? {})[
definitionNode.name.value
];
if (!importedTableName) {
throw new Error(
`No table found for imported model ${definitionNode.name.value}.`
);
}
return {
schema: print({
definitions: [definitionNode],
kind: 'Document' as const,
}),
importedTableName,
};
});

return {
// ok to cast as ObjectTypeDefinitionNode because the type was checked in the partition function
importedSchemas: (
importedDefinitionNodes as ObjectTypeDefinitionNode[]
).map((definitionNode) => {
const importedTableName = (importedAmplifyDynamoDBTableMap ?? {})[
definitionNode.name.value
];
if (!importedTableName) {
throw new Error(
`No table found for imported model ${definitionNode.name.value}.`
);
}
return {
schema: print({
definitions: [definitionNode],
kind: 'Document' as const,
}),
importedTableName,
};
}),
importedSchemas,
nonImportedSchema: print({
definitions: nonImportedDefinitionNodes,
kind: 'Document' as const,
Expand Down
150 changes: 144 additions & 6 deletions packages/backend-data/src/factory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { a } from '@aws-amplify/data-schema';
import { AmplifyDataError } from './types.js';

const CUSTOM_DDB_CFN_TYPE = 'Custom::AmplifyDynamoDBTable';
const CUSTOM_IMPORTED_DDB_CFN_TYPE = 'Custom::ImportedAmplifyDynamoDBTable';

const testSchema = /* GraphQL */ `
type Todo @model {
Expand Down Expand Up @@ -856,14 +857,151 @@ void describe('Table Import', () => {
const getInstanceProps = createInstancePropsBySetupCDKApp({
isSandboxMode: true,
});
dataFactory.getInstance(getInstanceProps);
// TODO: add assertions
const instance = dataFactory.getInstance(getInstanceProps);
const blogStack = Template.fromStack(
Stack.of(instance.resources.nestedStacks['Blog'])
);
const importedModelStack = Template.fromStack(
Stack.of(instance.resources.nestedStacks['ImportedModel'])
);
importedModelStack.hasResourceProperties(CUSTOM_IMPORTED_DDB_CFN_TYPE, {
isImported: true,
tableName: 'ImportedModel-1234-dev',
});
blogStack.hasResource(CUSTOM_DDB_CFN_TYPE, {});
});

void it('fails when importedModels is not supplied', () => {
const schema = /* GraphQL */ `
type Blog @model {
title: String
content: String
authors: [String]
}
type ImportedModel @model {
description: String
}
`;
const dataFactory = defineData({
schema,
importedAmplifyDynamoDBTableMap: {
ImportedModel: 'ImportedModel-1234-dev',
},
});
const getInstanceProps = createInstancePropsBySetupCDKApp({
isSandboxMode: true,
});
assert.throws(() => dataFactory.getInstance(getInstanceProps), {
message: 'importedAmplifyDynamoDBTableMap is defined but importedModels is not defined.',
});
});

void it('fails when importedAmplifyDynamoDBTableMap is not supplied', () => {
const schema = /* GraphQL */ `
type Blog @model {
title: String
content: String
authors: [String]
}
type ImportedModel @model {
description: String
}
`;
const dataFactory = defineData({
schema,
importedModels: ['ImportedModel'],
});
const getInstanceProps = createInstancePropsBySetupCDKApp({
isSandboxMode: true,
});
assert.throws(() => dataFactory.getInstance(getInstanceProps), {
message: 'importedModels is defined but importedAmplifyDynamoDBTableMap is not defined.',
});
});

void it('fails when imported model is missing from the schema', () => {
const schema = /* GraphQL */ `
type Blog @model {
title: String
content: String
authors: [String]
}
`;
const dataFactory = defineData({
schema,
importedAmplifyDynamoDBTableMap: {
ImportedModel: 'ImportedModel-1234-dev',
},
importedModels: ['ImportedModel'],
});
const getInstanceProps = createInstancePropsBySetupCDKApp({
isSandboxMode: true,
});
assert.throws(() => dataFactory.getInstance(getInstanceProps), {
message: 'Imported model not found in schema: ImportedModel',
});
});

// TODO: add tests for error cases
// 1. importedModels or importedAmplifyDynamoDBTableMap not supplied
// 2. models missing in schema
// 3. models missing in table map
void it('throws when model missing in imported models list', () => {
const schema = /* GraphQL */ `
type Blog @model {
title: String
content: String
authors: [String]
}
type ImportedModel @model {
description: String
}
type Foo @model {
description: String
}
`;
const dataFactory = defineData({
schema,
importedAmplifyDynamoDBTableMap: {
ImportedModel: 'ImportedModel-1234-dev',
Foo: 'Foo-1234-dev',
},
importedModels: ['Foo'],
});
const getInstanceProps = createInstancePropsBySetupCDKApp({
isSandboxMode: true,
});
assert.throws(() => dataFactory.getInstance(getInstanceProps), {
message: 'Imported table defined in importedAmplifyDynamoDBTableMap not found in importedModels list: ImportedModel',
});
});


void it('throws when model missing in imported models map', () => {
const schema = /* GraphQL */ `
type Blog @model {
title: String
content: String
authors: [String]
}
type ImportedModel @model {
description: String
}
`;
const dataFactory = defineData({
schema,
importedAmplifyDynamoDBTableMap: {
},
importedModels: ['ImportedModel'],
});
const getInstanceProps = createInstancePropsBySetupCDKApp({
isSandboxMode: true,
});
assert.throws(() => dataFactory.getInstance(getInstanceProps), {
message: 'No table found for imported model ImportedModel.',
});
});
});

const resetFactoryCount = () => {
Expand Down

0 comments on commit c09f5d1

Please sign in to comment.