Skip to content

Commit

Permalink
N21-2103 add config for vidis region
Browse files Browse the repository at this point in the history
  • Loading branch information
GordonNicholasCap committed Dec 20, 2024
1 parent 650cb18 commit 7a6b7f8
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ data:
NEST_LOG_LEVEL: "error"
EXIT_ON_ERROR: "true"
VIDIS_API_CLIENT_BASE_URL: "{{ VIDIS_API_CLIENT_BASE_URL }}"
VIDIS_SYNC_REGION: "{{ VIDIS_SYNC_REGION }}"
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { MediaSourceBasicAuthConfigNotFoundLoggableException } from '@modules/me
import { mediaSourceFactory } from '@modules/media-source/testing';
import { AxiosErrorLoggable } from '@src/core/error/loggable';
import { axiosErrorFactory, axiosResponseFactory } from '@shared/testing';
import { ConfigService } from '@nestjs/config';
import { Test, TestingModule } from '@nestjs/testing';
import { createMock, DeepMocked } from '@golevelup/ts-jest';
import { AxiosResponse } from 'axios';
import { AxiosResponse, RawAxiosRequestConfig } from 'axios';
import { vidisPageOfferFactory } from '../testing';
import { VidisFetchService } from './vidis-fetch.service';

Expand All @@ -30,6 +31,19 @@ describe(VidisFetchService.name, () => {
provide: DefaultEncryptionService,
useValue: createMock<EncryptionService>(),
},
{
provide: ConfigService,
useValue: createMock<ConfigService>({
getOrThrow: (key: string) => {
switch (key) {
case 'VIDIS_SYNC_REGION':
return 'test-region';
default:
throw new Error(`Unknown key: ${key}`);
}
},
}),
},
],
}).compile();

Expand Down Expand Up @@ -93,22 +107,29 @@ describe(VidisFetchService.name, () => {
});

it('should create a vidis api client', async () => {
const { mediaSource, decryptedUsername, decryptedPassword } = setup();
const { mediaSource } = setup();

await service.getOfferItemsFromVidis(mediaSource);

expect(vidisClientFactory.createVidisClient).toBeCalledWith({
username: decryptedUsername,
password: decryptedPassword,
});
expect(vidisClientFactory.createVidisClient).toBeCalledWith();
});

it('should call the vidis endpoint for activated offer items', async () => {
const { mediaSource, vidisApiClientMock } = setup();
it('should call the vidis endpoint for activated offer items with basic auth', async () => {
const { mediaSource, vidisApiClientMock, decryptedUsername, decryptedPassword } = setup();

await service.getOfferItemsFromVidis(mediaSource);

expect(vidisApiClientMock.getActivatedOffersByRegion).toBeCalledWith('test-region');
const encodedBasicAuth = btoa(`${decryptedUsername}:${decryptedPassword}`);
const expectedAxiosOptions: RawAxiosRequestConfig = {
headers: { Authorization: expect.stringMatching(`Basic ${encodedBasicAuth}`) },

Check failure on line 124 in apps/server/src/infra/sync/media-licenses/service/vidis-fetch.service.spec.ts

View workflow job for this annotation

GitHub Actions / nest_lint

Unsafe assignment of an `any` value
};

expect(vidisApiClientMock.getActivatedOffersByRegion).toBeCalledWith(
'test-region',
undefined,
undefined,
expectedAxiosOptions
);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import { MediaSource, MediaSourceDataFormat } from '@modules/media-source';
import { MediaSourceBasicAuthConfigNotFoundLoggableException } from '@modules/media-source/loggable';
import { AxiosResponse, isAxiosError } from 'axios';
import { AxiosErrorLoggable } from '@src/core/error/loggable';
import { ConfigService } from '@nestjs/config';
import { VidisSyncConfig } from '../vidis-sync-config';

@Injectable()
export class VidisFetchService {
constructor(
private readonly vidisClientFactory: VidisClientFactory,
private readonly configService: ConfigService<VidisSyncConfig, true>,
@Inject(DefaultEncryptionService) private readonly encryptionService: EncryptionService
) {}

Expand All @@ -20,12 +23,12 @@ export class VidisFetchService {

const vidisClient: IDMBetreiberApiInterface = this.vidisClientFactory.createVidisClient();

// TODO: env var
const region = 'test-region';
const decryptedUsername = this.encryptionService.decrypt(mediaSource.basicAuthConfig.username);
const decryptedPassword = this.encryptionService.decrypt(mediaSource.basicAuthConfig.password);
const basicAuthEncoded = btoa(`${decryptedUsername}:${decryptedPassword}`);

const region = this.configService.getOrThrow<string>('VIDIS_SYNC_REGION');

try {
const axiosResponse: AxiosResponse<PageOfferDTO> = await vidisClient.getActivatedOffersByRegion(
region,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface VidisSyncConfig {
VIDIS_SYNC_REGION: string;
}
35 changes: 12 additions & 23 deletions apps/server/src/infra/vidis-client/vidis-client-factory.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { faker } from '@faker-js/faker';
import { DeepMocked, createMock } from '@golevelup/ts-jest';
import { ServerConfig } from '@modules/server';
import { createMock } from '@golevelup/ts-jest';
import { ConfigService } from '@nestjs/config';
import { Test, TestingModule } from '@nestjs/testing';
import { VidisClientConfig } from './vidis-client-config';
Expand All @@ -9,23 +8,28 @@ import { VidisClientFactory } from './vidis-client-factory';
describe(VidisClientFactory.name, () => {
let module: TestingModule;
let factory: VidisClientFactory;
let configService: DeepMocked<ConfigService<VidisClientConfig, true>>;

beforeAll(async () => {
module = await Test.createTestingModule({
providers: [
VidisClientFactory,
{
provide: ConfigService,
useValue: createMock<ConfigService<ServerConfig, true>>(),
useValue: createMock<ConfigService<VidisClientConfig, true>>({
getOrThrow: (key: string) => {
switch (key) {
case 'VIDIS_API_CLIENT_BASE_URL':
return faker.internet.url();
default:
throw new Error(`Unknown key: ${key}`);
}
},
}),
},
],
}).compile();

factory = module.get(VidisClientFactory);
configService = module.get(ConfigService);

configService.getOrThrow.mockReturnValueOnce(faker.internet.url());
});

afterAll(async () => {
Expand All @@ -42,23 +46,8 @@ describe(VidisClientFactory.name, () => {

describe('createVidisClient', () => {
describe('when the function is called', () => {
const setup = () => {
const username = faker.string.alpha();
const password = faker.string.alpha();

return {
username,
password,
};
};

it('should return a vidis api client as an IDMBetreiberApiInterface', () => {
const { username, password } = setup();

const result = factory.createVidisClient({
username,
password,
});
const result = factory.createVidisClient();

expect(result).toBeDefined();
});
Expand Down
5 changes: 4 additions & 1 deletion apps/server/src/modules/server/server.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import type { CoreModuleConfig } from '@src/core';
import { Algorithm } from 'jsonwebtoken';
import type { Timezone } from './types/timezone.enum';

Check failure on line 34 in apps/server/src/modules/server/server.config.ts

View workflow job for this annotation

GitHub Actions / nest_lint

`./types/timezone.enum` type import should occur after import of `@infra/sync/media-licenses/vidis-sync-config`
import { VidisClientConfig } from '@infra/vidis-client';
import { VidisSyncConfig } from '@infra/sync/media-licenses/vidis-sync-config';

export enum NodeEnvType {
TEST = 'test',
Expand Down Expand Up @@ -75,7 +76,8 @@ export interface ServerConfig
ShdConfig,
OauthConfig,
EncryptionConfig,
VidisClientConfig {
VidisClientConfig,
VidisSyncConfig {
NODE_ENV: NodeEnvType;
SC_DOMAIN: string;
HOST: string;
Expand Down Expand Up @@ -324,6 +326,7 @@ const config: ServerConfig = {
FEATURE_EXTERNAL_SYSTEM_LOGOUT_ENABLED: Configuration.get('FEATURE_EXTERNAL_SYSTEM_LOGOUT_ENABLED') as boolean,
PUBLIC_BACKEND_URL: Configuration.get('PUBLIC_BACKEND_URL') as string,
VIDIS_API_CLIENT_BASE_URL: Configuration.get('VIDIS_API_CLIENT_BASE_URL') as string,
VIDIS_SYNC_REGION: Configuration.get('VIDIS_SYNC_REGION') as string,
};

export const serverConfig = () => config;
Expand Down
5 changes: 5 additions & 0 deletions config/default.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1680,6 +1680,11 @@
"type": "string",
"default": "https://service-stage.vidis.schule/o/vidis-rest",
"description": "The VIDIS API base URL"
},
"VIDIS_SYNC_REGION": {
"type": "string",
"default": "test-region",
"description": "The region for fetching activated offers from VIDIS"
}
},
"required": []
Expand Down

0 comments on commit 7a6b7f8

Please sign in to comment.