Skip to content

Commit

Permalink
fix: make verifier a nestjs provider again
Browse files Browse the repository at this point in the history
  • Loading branch information
lennartquerter committed Oct 13, 2022
1 parent 5cab2ac commit df4249d
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 31 deletions.
1 change: 1 addition & 0 deletions src/common/pact-module-providers.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export enum PactModuleProviders {
ProviderOptions = 'PROVIDER_OPTIONS',
PublicationOptions = 'PUBLICATION_OPTIONS',
PactPublisher = 'PACT_PUBLISHER',
PactVerifier = 'PACT_VERIFIER',
Pact = 'PACT_INSTANCE',
}
5 changes: 1 addition & 4 deletions src/interfaces/pact-provider-module-options.interface.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { ModuleMetadata, Type } from '@nestjs/common/interfaces';
import { VerifierOptions } from '@pact-foundation/pact/src/dsl/verifier/types';

export type PactProviderOptions = Omit<VerifierOptions, 'providerBaseUrl'> & {
providerPort?: number;
providerHost?: string;
};
export type PactProviderOptions = VerifierOptions;

export interface PactProviderOptionsFactory {
createPactProviderOptions(): Promise<PactProviderOptions> | PactProviderOptions;
Expand Down
9 changes: 5 additions & 4 deletions src/modules/pact-provider-core.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
import { PactVerifierService } from '../services/pact-verifier.service';
import { PactModuleProviders } from '../common/pact-module-providers.enum';
import { ProviderFactory } from '../common/provider-factory';
import { PactVerifierProvider } from '../providers/pact-verifier.provider';

@Module({})
export class PactProviderCoreModule {
Expand All @@ -15,17 +16,17 @@ export class PactProviderCoreModule {

return {
module: PactProviderCoreModule,
exports: [PactVerifierService],
providers: [optionsProvider, PactVerifierService],
exports: [PactVerifierService, PactVerifierProvider],
providers: [optionsProvider, PactVerifierService, PactVerifierProvider],
};
}

public static registerAsync(options: PactProviderModuleAsyncOptions): DynamicModule {
return {
exports: [PactVerifierService],
exports: [PactVerifierService, PactVerifierProvider],
imports: options.imports,
module: PactProviderCoreModule,
providers: [...this.createAsyncProviders(options), PactVerifierService],
providers: [...this.createAsyncProviders(options), PactVerifierService, PactVerifierProvider],
};
}

Expand Down
4 changes: 3 additions & 1 deletion src/modules/pact-provider-module.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { PactProviderOptions, PactProviderOptionsFactory } from '../interfaces/p
import { PactVerifierService } from '../services/pact-verifier.service';

describe("Given a 'PactProviderModule' module", () => {
const config = {};
const config: PactProviderOptions = {
providerBaseUrl: 'http://127.0.0.1:80',
};

class PactProviderConfigTestService implements PactProviderOptionsFactory {
createPactProviderOptions(): PactProviderOptions {
Expand Down
7 changes: 6 additions & 1 deletion src/providers/pact-publisher-provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ import { Test } from '@nestjs/testing';
import { Publisher } from '@pact-foundation/pact-core';
import { PactModuleProviders } from '../common/pact-module-providers.enum';
import { PactPublisherProvider } from './pact-publisher.provider';
import { PactPublicationOptions } from '../interfaces/pact-consumer-module-options.interface';

const mockPublisher = jest.createMockFromModule<Publisher>('@pact-foundation/pact-core');

mockPublisher.publish = jest.fn();

describe('PactPublisherProvider', () => {
const publicationOptions = { pactBroker: 'example-broker', pactFilesOrDirs: ['./'], consumerVersion: '1' };
const publicationOptions: PactPublicationOptions = {
pactBroker: 'example-broker',
pactFilesOrDirs: ['./'],
consumerVersion: '1',
};

beforeAll(async () => {
await Test.createTestingModule({
Expand Down
31 changes: 31 additions & 0 deletions src/providers/pact-verifier-provider.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Test } from '@nestjs/testing';
import { Verifier } from '@pact-foundation/pact-core';
import { PactModuleProviders } from '../common/pact-module-providers.enum';
import { PactVerifierProvider } from './pact-verifier.provider';
import { PactProviderOptions } from '../interfaces/pact-provider-module-options.interface';

const mockVerifier = jest.createMockFromModule<Verifier>('@pact-foundation/pact-core');

mockVerifier.verify = jest.fn();

describe('PactVerifierProvider', () => {
const providerOptions: PactProviderOptions = { providerBaseUrl: 'http://127.0.0.1:80' };

beforeAll(async () => {
await Test.createTestingModule({
providers: [
PactVerifierProvider,
{
provide: PactModuleProviders.ProviderOptions,
useValue: providerOptions,
},
],
}).compile();
});

describe('When calling the provider (in any module)', () => {
test('then call Verifier with the exact options', () => {
expect(Verifier).toHaveBeenCalledWith(providerOptions);
});
});
});
10 changes: 10 additions & 0 deletions src/providers/pact-verifier.provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Provider } from '@nestjs/common';
import { Verifier } from '@pact-foundation/pact';
import { PactModuleProviders } from '../common/pact-module-providers.enum';
import { PactProviderOptions } from '../interfaces/pact-provider-module-options.interface';

export const PactVerifierProvider: Provider<Verifier> = {
provide: PactModuleProviders.PactVerifier,
useFactory: (config: PactProviderOptions) => new Verifier(config),
inject: [PactModuleProviders.ProviderOptions],
};
13 changes: 10 additions & 3 deletions src/services/pact-verifier-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Test, TestingModule } from '@nestjs/testing';
import { PactModuleProviders } from '../common/pact-module-providers.enum';
import { PactVerifierService } from './pact-verifier.service';
import { INestApplication } from '@nestjs/common';
import { Verifier } from '@pact-foundation/pact';
import { PactProviderOptions } from '../interfaces/pact-provider-module-options.interface';

jest.mock('get-port', () => () => 80);

Expand All @@ -10,13 +12,18 @@ describe('PactVerifierService', () => {
let pactVerifierService: PactVerifierService;

const appMock = jest.createMockFromModule<INestApplication>('');
const pactVerifierMock = jest.createMockFromModule<Verifier>('');

let options = { some: true, keys: true, to: true, check: true, providerHost: '0.0.0.0' } as any;
let options: PactProviderOptions = { providerBaseUrl: 'http://127.0.0.1:80' };

beforeAll(async () => {
moduleRef = await Test.createTestingModule({
providers: [
PactVerifierService,
{
provide: PactModuleProviders.PactVerifier,
useValue: pactVerifierMock,
},
{
provide: PactModuleProviders.ProviderOptions,
useValue: options,
Expand All @@ -37,11 +44,11 @@ describe('PactVerifierService', () => {

describe('when configuring the providerBaseHost', () => {
beforeEach(async () => {
options = { ...options, providerHost: '0.0.0.0' };
options = { ...options, providerBaseUrl: 'http://127.0.0.1:80' };
await pactVerifierService.verify(appMock);
});
test('allows configuring hosts', async () => {
expect(appMock.listen).toHaveBeenCalledWith(80, '0.0.0.0');
expect(appMock.listen).toHaveBeenCalledWith(80, '127.0.0.1');
});
test('then call the application methods', () => {
expect(appMock.close).toHaveBeenCalled();
Expand Down
34 changes: 16 additions & 18 deletions src/services/pact-verifier.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,24 @@ import { PactProviderOptions } from '../interfaces/pact-provider-module-options.

@Injectable()
export class PactVerifierService {
private verifier: Verifier | undefined = undefined;

public constructor(@Inject(PactModuleProviders.ProviderOptions) private readonly options: PactProviderOptions) {}
public constructor(
@Inject(PactModuleProviders.PactVerifier) private readonly verifier: Verifier,
@Inject(PactModuleProviders.ProviderOptions) private readonly options: PactProviderOptions
) {}

public async verify(app: INestApplication): Promise<any> {
const host = this.options.providerHost || 'localhost';
const port = this.options.providerPort || 9123;

await app.listen(port, host);

const appUrl = await app.getUrl();

this.verifier = new Verifier({
providerBaseUrl: appUrl,
...this.options,
});

const results = await this.verifier.verifyProvider();

await app.close();
const providerUrl = new URL(this.options.providerBaseUrl);
let results: string;

await app.listen(providerUrl.port || 80, providerUrl.hostname);

try {
results = await this.verifier.verifyProvider();
} catch (e) {
// do nothing
} finally {
await app.close();
}

return results;
}
Expand Down

0 comments on commit df4249d

Please sign in to comment.