Skip to content

Commit

Permalink
test: fix and add more e2e tests for mock
Browse files Browse the repository at this point in the history
  • Loading branch information
yuth committed Feb 1, 2021
1 parent a2fee2f commit da22b5b
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 4 deletions.
4 changes: 2 additions & 2 deletions packages/amplify-appsync-simulator/src/velocity/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ export class VelocityTemplate {
try {
templateResult = this.compiler.render(context);
} catch (e) {
const lastError = context.util.errors.pop();
const lastError = context.util.errors.length && context.util.errors[context.util.errors.length - 1];
if (lastError && lastError instanceof ValidateError) {
return { result: lastError.data, errors: [...context.util.errors, lastError], isReturn: false, stash: context.ctx.stash.toJSON() };
return { result: lastError.data, errors: [...context.util.errors], isReturn: true, stash: context.ctx.stash.toJSON() };
}
return { result: null, errors: [...context.util.errors], isReturn: false, stash: context.ctx.stash.toJSON() };
}
Expand Down
138 changes: 138 additions & 0 deletions packages/amplify-util-mock/src/__e2e__/util-method-e2e.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { AmplifyAppSyncSimulator } from 'amplify-appsync-simulator';
import { ModelAuthTransformer } from 'graphql-auth-transformer';
import { DynamoDBModelTransformer } from 'graphql-dynamodb-transformer';
import { not } from 'graphql-mapping-template';
import { GraphQLTransform } from 'graphql-transformer-core';
import { values } from 'lodash';
import { GraphQLClient } from './utils/graphql-client';
import { deploy, launchDDBLocal, terminateDDB, logDebug, reDeploy } from './utils/index';

let GRAPHQL_ENDPOINT = undefined;
let GRAPHQL_CLIENT = undefined;
let ddbEmulator = null;
let dbPath = null;
let server: AmplifyAppSyncSimulator;
jest.setTimeout(2000000);

const runTransformer = async (validSchema: string) => {
const transformer = new GraphQLTransform({
transformers: [new DynamoDBModelTransformer()],
});
const out = await transformer.transform(validSchema);
return out;
};
let ddbClient;
const validSchema = /* GraphQL */ `
type Post @model {
id: ID!
title: String!
}
`;

beforeAll(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

try {
const out = await runTransformer(validSchema);
({ dbPath, emulator: ddbEmulator, client: ddbClient } = await launchDDBLocal());
const result = await deploy(out, ddbClient);
server = result.simulator;

GRAPHQL_ENDPOINT = server.url + '/graphql';
logDebug(`Using graphql url: ${GRAPHQL_ENDPOINT}`);

const apiKey = result.config.appSync.apiKey;
logDebug(apiKey);
GRAPHQL_CLIENT = new GraphQLClient(GRAPHQL_ENDPOINT, {
'x-api-key': apiKey,
});
} catch (e) {
logDebug('error when setting up test');
logDebug(e);
expect(true).toEqual(false);
}
});

afterEach(async () => {
const out = await runTransformer(validSchema);
await reDeploy(out, server, ddbClient);
});

afterAll(async () => {
if (server) {
await server.stop();
}
await terminateDDB(ddbEmulator, dbPath);
});

describe('$util.validate', () => {
let transformerOutput;
const queryString = /* GraphQL */ `
query getPost {
getPost(id: "10") {
id
title
}
}
`;
beforeEach(async () => {
transformerOutput = await runTransformer(validSchema);
});
test('it should not throw error when validation condition is true', async () => {
transformerOutput.resolvers[
'Query.getPost.res.vtl'
] = `$util.validate(true, "Validation Error", "ValidationError", { "id": "11", "title": "Title Sent from Error" })\n$util.toJson({"id": 11, "title": "Non Error title"})`;
await reDeploy(transformerOutput, server, ddbClient);
const response = await GRAPHQL_CLIENT.query(queryString, {});
expect(response.data).toBeDefined();
expect(response.data.getPost.id).toEqual('11');
expect(response.data.getPost.title).toEqual('Non Error title');

expect(response.errors).not.toBeDefined();
});

test('$util.validate should throw error and pass the data along with error message and error type when the condition fails', async () => {
transformerOutput.resolvers[
'Query.getPost.req.vtl'
] = `$util.validate(false, "Validation Error", "ValidationError", { "id": "10", "title": "Title Sent from Error" })`;
await reDeploy(transformerOutput, server, ddbClient);

const response = await GRAPHQL_CLIENT.query(queryString, {});
expect(response.data).toBeDefined();
expect(response.data.getPost.id).toEqual('10');
expect(response.data.getPost.title).toEqual('Title Sent from Error');

expect(response.errors).toBeDefined();
expect(response.errors).toHaveLength(1);
expect(response.errors[0].message).toEqual('Validation Error');
expect(response.errors[0].errorType).toEqual('ValidationError');
});

test('$util.validate should return error message and CustomTemplateException when error type is not passed', async () => {
transformerOutput.resolvers['Query.getPost.req.vtl'] = `$util.validate(false, "Validation Error")`;
await reDeploy(transformerOutput, server, ddbClient);

const response = await GRAPHQL_CLIENT.query(queryString, {});
expect(response.data).toBeDefined();
expect(response.data.getPost).toBe(null);

expect(response.errors).toBeDefined();
expect(response.errors).toHaveLength(1);
expect(response.errors[0].message).toEqual('Validation Error');
expect(response.errors[0].errorType).toEqual('CustomTemplateException');
});

test('$util.validate should allow overriding the error type', async () => {
transformerOutput.resolvers['Query.getPost.req.vtl'] = `$util.validate(false, "Validation Error", "MyErrorType")`;
await reDeploy(transformerOutput, server, ddbClient);

const response = await GRAPHQL_CLIENT.query(queryString, {});
expect(response.data).toBeDefined();
expect(response.data.getPost).toBe(null);

expect(response.errors).toBeDefined();
expect(response.errors).toHaveLength(1);
expect(response.errors[0].message).toEqual('Validation Error');
expect(response.errors[0].errorType).toEqual('MyErrorType');
});
});
22 changes: 20 additions & 2 deletions packages/amplify-util-mock/src/__e2e__/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export async function launchDDBLocal() {
return { emulator, dbPath, client };
}

export async function deploy(transformerOutput: any, client?: DynamoDB) {
export async function deploy(transformerOutput: any, client?: DynamoDB): Promise<{ config: any; simulator: AmplifyAppSyncSimulator }> {
let config: any = processTransformerStacks(transformerOutput);
config.appSync.apiKey = 'da-fake-api-key';

Expand All @@ -44,6 +44,24 @@ export async function deploy(transformerOutput: any, client?: DynamoDB) {
const simulator = await runAppSyncSimulator(config);
return { simulator, config };
}

export async function reDeploy(
transformerOutput: any,
simulator: AmplifyAppSyncSimulator,
client?: DynamoDB,
): Promise<{ config: any; simulator: AmplifyAppSyncSimulator }> {
let config: any = processTransformerStacks(transformerOutput);
config.appSync.apiKey = 'da-fake-api-key';

if (client) {
await createAndUpdateTable(client, config);
config = configureDDBDataSource(config, client.config);
}
configureLambdaDataSource(config);
simulator?.reload(config);
return { simulator, config };
}

async function configureLambdaDataSource(config) {
config.dataSources
.filter(d => d.type === 'AWS_LAMBDA')
Expand Down Expand Up @@ -77,7 +95,7 @@ export async function terminateDDB(emulator, dbPath) {
}
}

export async function runAppSyncSimulator(config, port?: number, wsPort?: number) {
export async function runAppSyncSimulator(config, port?: number, wsPort?: number): Promise<AmplifyAppSyncSimulator> {
const appsyncSimulator = new AmplifyAppSyncSimulator({ port, wsPort });
await appsyncSimulator.start();
await appsyncSimulator.init(config);
Expand Down

0 comments on commit da22b5b

Please sign in to comment.