Skip to content

Commit

Permalink
Merge pull request #16 from nestjs-community/feature/controller-e2e
Browse files Browse the repository at this point in the history
Feature/controller e2e
  • Loading branch information
bashleigh committed Sep 26, 2018
2 parents ed1cac7 + 9281d05 commit 7e7c976
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 55 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"jest": "^23.5.0",
"nestjs-config": "^1.2.2",
"prettier": "^1.14.2",
"supertest": "^3.3.0",
"ts-jest": "^23.1.4",
"typescript": "^3.0.3"
},
Expand Down
9 changes: 9 additions & 0 deletions src/__tests__/braintree.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
BraintreeSubscriptionCanceled,
BraintreeSubscriptionExpired,
} from './..';
import BraintreeProvider from '../braintree.provider';
import BraintreeWebhookProvider from '../braintree.webhook.provider';

class SubscriptionProvider {
@BraintreeSubscriptionCanceled()
Expand Down Expand Up @@ -49,4 +51,11 @@ describe('BraintreeWebhookController', async () => {

expect(provider).toBeInstanceOf(SubscriptionProvider);
});

it('wehook controller instances',() => {
const braintreeWebhookController = module.get<BraintreeWebhookController>(BraintreeWebhookController);

expect(braintreeWebhookController.braintree).toBeInstanceOf(BraintreeProvider);
expect(braintreeWebhookController.webhookProvider).toBeInstanceOf(BraintreeWebhookProvider);
});
});
70 changes: 70 additions & 0 deletions src/__tests__/e2e/braintree.controller.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { INestApplication } from "@nestjs/common";
import { TestingModule, Test } from "@nestjs/testing";
import { BraintreeWebhookModule } from "../..";
import { ConfigService, ConfigModule } from "nestjs-config";
import BraintreeModule from "../../braintree.module";
import * as path from 'path';
import * as request from 'supertest';
import * as braintree from 'braintree';
import { BraintreeWebhookHandler, BraintreeSubscriptionCanceled, BraintreeSubscriptionChargedSuccessfully } from "../../decorators";

describe('BraintreeWebhookController', async () => {
let app: INestApplication;
let module: TestingModule;

const gateway = braintree.connect({
environment: braintree.Environment.Sandbox,
merchantId: 'merchantId',
publicKey: 'publicKey',
privateKey: 'privateKey',
});

beforeAll(async () => {

@BraintreeWebhookHandler()
class TestProvider {
@BraintreeSubscriptionCanceled()
canceled() {
return true;
}

@BraintreeSubscriptionChargedSuccessfully()
callMe() {
throw new Error('hello I am errors');
}
}

module = await Test.createTestingModule({
imports: [
ConfigModule.load(
path.resolve(__dirname, '../', '__stubs__', 'config', '*.ts'),
),
BraintreeModule.forRootAsync({
useFactory: async config => config.get('braintree'),
inject: [ConfigService],
}),
BraintreeWebhookModule,
],
providers: [TestProvider],
}).compile();

app = module.createNestApplication();
await app.init();
});

it('/braintree/webhook (POST) Canceled', async () => {
const webhook = gateway.webhookTesting.sampleNotification(
braintree.WebhookNotification.Kind.SubscriptionCanceled,
);

return await request(app.getHttpServer())
.post('/braintree/webhook')
.set('Content-Type', 'application/json')
.send(webhook)
.expect(201);
});

afterAll(async () => {
await app.close();
});
});
37 changes: 11 additions & 26 deletions src/__tests__/webhooks.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {Test, TestingModule} from '@nestjs/testing';
import {BraintreeModule, BraintreeWebhookModule} from './../';
import { Test, TestingModule } from '@nestjs/testing';
import { BraintreeModule, BraintreeWebhookModule } from './../';
import * as braintree from 'braintree';
import {
BraintreeWebhookHandler,
BraintreeSubscriptionCanceled,
BraintreeSubscriptionExpired,
BraintreeSubscriptionChargedSuccessfully,
BraintreeSubscriptionChargedUnSuccessfully,
BraintreeSubscriptionTrialEnded,
BraintreeSubscriptionWentPastDue,
import {
BraintreeWebhookHandler,
BraintreeSubscriptionCanceled,
BraintreeSubscriptionExpired,
BraintreeSubscriptionChargedSuccessfully,
BraintreeSubscriptionChargedUnSuccessfully,
BraintreeSubscriptionTrialEnded,
BraintreeSubscriptionWentPastDue,
BraintreeSubscriptionWentActive,
} from '../decorators';
import BraintreeProvider from '../braintree.provider';
Expand All @@ -19,7 +19,6 @@ describe('Braintree Webhooks', async () => {

@BraintreeWebhookHandler()
class TestProvider {

public static called = null;

@BraintreeSubscriptionCanceled()
Expand Down Expand Up @@ -83,7 +82,6 @@ describe('Braintree Webhooks', async () => {
});

it('Canceled', async () => {

const braintreeProvider = module.get(BraintreeProvider);
const braintreeWebhookProvider = module.get(BraintreeWebhookProvider);

Expand All @@ -96,11 +94,9 @@ describe('Braintree Webhooks', async () => {
braintreeWebhookProvider.handle(webhookNotification);

expect(TestProvider.called).toBe('canceled');

});

it('Expired', async () => {

const braintreeProvider = module.get(BraintreeProvider);
const braintreeWebhookProvider = module.get(BraintreeWebhookProvider);

Expand All @@ -113,11 +109,9 @@ describe('Braintree Webhooks', async () => {
braintreeWebhookProvider.handle(webhookNotification);

expect(TestProvider.called).toBe('expired');

});

it('ChargedSuccessfully', async () => {

const braintreeProvider = module.get(BraintreeProvider);
const braintreeWebhookProvider = module.get(BraintreeWebhookProvider);

Expand All @@ -130,11 +124,9 @@ describe('Braintree Webhooks', async () => {
braintreeWebhookProvider.handle(webhookNotification);

expect(TestProvider.called).toBe('chargedSuccessfully');

});

it('ChargedUnSuccessfully', async () => {

const braintreeProvider = module.get(BraintreeProvider);
const braintreeWebhookProvider = module.get(BraintreeWebhookProvider);

Expand All @@ -147,11 +139,9 @@ describe('Braintree Webhooks', async () => {
braintreeWebhookProvider.handle(webhookNotification);

expect(TestProvider.called).toBe('chargedUnsuccessfully');

});

it('TrialEnded', async () => {

const braintreeProvider = module.get(BraintreeProvider);
const braintreeWebhookProvider = module.get(BraintreeWebhookProvider);

Expand All @@ -164,11 +154,9 @@ describe('Braintree Webhooks', async () => {
braintreeWebhookProvider.handle(webhookNotification);

expect(TestProvider.called).toBe('trialEnded');

});

it('wentPastDue', async () => {

const braintreeProvider = module.get(BraintreeProvider);
const braintreeWebhookProvider = module.get(BraintreeWebhookProvider);

Expand All @@ -181,11 +169,9 @@ describe('Braintree Webhooks', async () => {
braintreeWebhookProvider.handle(webhookNotification);

expect(TestProvider.called).toBe('wentPastDue');

});

it('wentActive', async () => {

const braintreeProvider = module.get(BraintreeProvider);
const braintreeWebhookProvider = module.get(BraintreeWebhookProvider);

Expand All @@ -198,6 +184,5 @@ describe('Braintree Webhooks', async () => {
braintreeWebhookProvider.handle(webhookNotification);

expect(TestProvider.called).toBe('wentActive');

});
});
});
22 changes: 6 additions & 16 deletions src/braintree.webhook.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {Controller, HttpStatus, Req, Res, Logger, Post} from '@nestjs/common';
import {Controller, Req, Logger, Post, HttpException} from '@nestjs/common';
import BraintreeProvider from './braintree.provider';
import BraintreeWebhookProvider from './braintree.webhook.provider';
import { BraintreeWebhookNotificationInterface } from './interfaces';

//TODO make path configurable
@Controller('braintree')
Expand All @@ -9,30 +10,19 @@ export default class BraintreeWebhookController {
constructor(private readonly braintree: BraintreeProvider, private readonly webhookProvider: BraintreeWebhookProvider) {}

@Post('webhook')
async handle(@Req() request, @Res() response) {
//TODO parse the payload from braintree
//TODO get the type of webhook it is
//TODO call relative function for that type of webhook
//TODO return response code

let webhook; //TODO add webhook type
async handle(@Req() request) {
let webhook: BraintreeWebhookNotificationInterface;

try {
webhook = await this.braintree.parseWebhook({
bt_signature: request.body.bt_signature,
bt_payload: request.body.bt_payload,
});
await this.webhookProvider.handle(webhook);
} catch (e) {
//TODO log something? see braintree for correct proceedure on signature failure
response.status(HttpStatus.INTERNAL_SERVER_ERROR);
Logger.warn('Failed to process webhook', this.constructor.name);
throw new HttpException('Failed', 500);
}
console.log('webhook', webhook);

//TODO call webhookProvider
//TODO again see braintree to see how to handle errors
await this.webhookProvider.handle(webhook);

response.status(HttpStatus.OK);
}
}
6 changes: 3 additions & 3 deletions src/braintree.webhook.provider.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Injectable, Provider, Logger} from '@nestjs/common';
import {Injectable, Provider, Logger, HttpException} from '@nestjs/common';
import {
BraintreeWebhookNotificationInterface,
BraintreeWebhookMethodInterface,
Expand Down Expand Up @@ -29,13 +29,14 @@ export default class BraintreeWebhookProvider {
};

async handle(webhook: BraintreeWebhookNotificationInterface): Promise<void> {

if (Object.keys(this.methods).includes(webhook.kind)) {
this.methods[webhook.kind].forEach(async (methodProto: BraintreeWebhookMethodInterface) => {
try {
await this.providers[methodProto.provider][methodProto.method](webhook);
} catch(e) {
Logger.error(`There was an error calling ${methodProto.method} from ${methodProto.provider}`, e.stack, 'BraintreeWebhookProvider');
throw HttpException;
}
});
}
Expand All @@ -56,5 +57,4 @@ export default class BraintreeWebhookProvider {
];
Logger.log(`Added method [${method}]`, 'BraintreeWebhookProvider');
}

}
6 changes: 2 additions & 4 deletions src/decorators/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import InjectBraintreeProvider from './inject.braintree.provider';

export {
InjectBraintreeProvider,
};
export { InjectBraintreeProvider };

export * from './braintree.webhook.handler';
export * from './webhooks';
export * from './webhooks';
Loading

0 comments on commit 7e7c976

Please sign in to comment.