Skip to content

Commit

Permalink
test: moving unmatching integration tests to unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
almog8k committed Aug 6, 2024
1 parent 06bacf5 commit b60ee9a
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 207 deletions.
8 changes: 4 additions & 4 deletions tests/configurations/integration/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ module.exports = {
testEnvironment: 'node',
coverageThreshold: {
global: {
branches: 50,
functions: 50,
lines: 50,
statements: 0,
branches: 80,
functions: 80,
lines: 80,
statements: -10,
},
},
};
13 changes: 9 additions & 4 deletions tests/configurations/unit/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ module.exports = {
'!**/routes/**',
'!<rootDir>/src/*',
],
modulePathIgnorePatterns: [
'<rootDir>/src/models/newJobHandler.ts',
'<rootDir>/src/models/swapJobHandler.ts',
'<rootDir>/src/models/updateJobHandler.ts',
],
coverageDirectory: '<rootDir>/coverage',
reporters: [
'default',
Expand All @@ -25,10 +30,10 @@ module.exports = {
testEnvironment: 'node',
coverageThreshold: {
global: {
branches: 50,
functions: 50,
lines: 50,
statements: 0,
branches: 80,
functions: 80,
lines: 80,
statements: -10,
},
},
};
43 changes: 43 additions & 0 deletions tests/helpers/containerConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import jsLogger from '@map-colonies/js-logger';
import { container, instancePerContainerCachingFactory } from 'tsyringe';
import { trace } from '@opentelemetry/api';
import { InjectionObject } from '../../src/common/dependencyRegistration';
import { configMock, getMock, hasMock, registerDefaultConfig } from '../unit/mocks/configMock';
import { SERVICES } from '../../src/common/constants';
import { queueClientFactory } from '../../src/containerConfig';
import { IngestionJobsConfig } from '../../src/common/interfaces';
import { validateAndGetHandlersTokens } from '../../src/utils/configUtil';
import { NewJobHandler } from '../../src/models/newJobHandler';
import { UpdateJobHandler } from '../../src/models/updateJobHandler';
import { SwapJobHandler } from '../../src/models/swapJobHandler';
import { JOB_HANDLER_FACTORY_SYMBOL, jobHandlerFactory } from '../../src/models/jobHandlerFactory';

function getTestContainerConfig(): InjectionObject<unknown>[] {
registerDefaultConfig();

const ingestionConfig = configMock.get<IngestionJobsConfig>('jobManagement.ingestion.jobs');

const handlersTokens = validateAndGetHandlersTokens(ingestionConfig);

return [
{ token: SERVICES.LOGGER, provider: { useValue: jsLogger({ enabled: false }) } },
{ token: SERVICES.CONFIG, provider: { useValue: configMock } },
{ token: SERVICES.TRACER, provider: { useValue: trace.getTracer('testTracer') } },
{ token: SERVICES.QUEUE_CLIENT, provider: { useFactory: instancePerContainerCachingFactory(queueClientFactory) } },
{ token: JOB_HANDLER_FACTORY_SYMBOL, provider: { useFactory: instancePerContainerCachingFactory(jobHandlerFactory) } },
{ token: handlersTokens.Ingestion_New, provider: { useClass: NewJobHandler } },
{ token: handlersTokens.Ingestion_Update, provider: { useClass: UpdateJobHandler } },
{ token: handlersTokens.Ingestion_Swap_Update, provider: { useClass: SwapJobHandler } },
];
}

const resetContainer = (clearInstances = true): void => {
if (clearInstances) {
container.clearInstances();
}

getMock.mockReset();
hasMock.mockReset();
};

export { getTestContainerConfig, resetContainer };
6 changes: 3 additions & 3 deletions tests/integration/helpers/containerConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { container, instancePerContainerCachingFactory } from 'tsyringe';
import { trace } from '@opentelemetry/api';
import { InjectionObject } from '../../../src/common/dependencyRegistration';
import { configMock, getMock, hasMock, registerDefaultConfig } from '../../unit/mocks/configMock';
import { SERVICES } from '../../../src/common/constants';
import { queueClientFactory } from '../../../src/containerConfig';
import { IngestionJobsConfig } from '../../../src/common/interfaces';
import { validateAndGetHandlersTokens } from '../../../src/utils/configUtil';
import { SERVICES } from '../../../src/common/constants';
import { JOB_HANDLER_FACTORY_SYMBOL, jobHandlerFactory } from '../../../src/models/jobHandlerFactory';
import { queueClientFactory } from '../../../src/containerConfig';
import { NewJobHandler } from '../../../src/models/newJobHandler';
import { UpdateJobHandler } from '../../../src/models/updateJobHandler';
import { SwapJobHandler } from '../../../src/models/swapJobHandler';
import { JOB_HANDLER_FACTORY_SYMBOL, jobHandlerFactory } from '../../../src/models/jobHandlerFactory';

function getTestContainerConfig(): InjectionObject<unknown>[] {
registerDefaultConfig();
Expand Down
144 changes: 0 additions & 144 deletions tests/integration/jobProcessor.spec.ts

This file was deleted.

100 changes: 50 additions & 50 deletions tests/unit/jobProcessor/JobProcessor.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import nock from 'nock';
import { IJobResponse, ITaskResponse } from '@map-colonies/mc-priority-queue';
import { registerDefaultConfig } from '../mocks/configMock';
import { ingestionNewJob, ingestionUpdateJob } from '../mocks/jobsMockData';
import {
finalizeTaskForIngestionNew,
finalizeTaskForIngestionSwapUpdate,
finalizeTaskForIngestionUpdate,
initTaskForIngestionNew,
initTaskForIngestionUpdate,
} from '../mocks/tasksMockData';
import { IJobHandler, IngestionConfig } from '../../../src/common/interfaces';
import { finalizeTestCases, initTestCases } from '../mocks/testCasesData';
import { JobProcessorTestContext, setupJobProcessorTest } from './jobProcessorSetup';

jest.mock('timers/promises', () => ({
Expand All @@ -29,15 +23,17 @@ describe('JobProcessor', () => {
beforeEach(() => {
jest.clearAllMocks();
registerDefaultConfig();
testContext = setupJobProcessorTest();
});

afterEach(() => {
jest.clearAllTimers();
nock.cleanAll();
});

describe('start', () => {
it('should start polling and stop when stop is called', async () => {
testContext = setupJobProcessorTest({ useMockQueueClient: true });

const { jobProcessor, mockDequeue, configMock } = testContext;
const ingestionConfig = configMock.get<IngestionConfig>('jobManagement.ingestion');
const dequeueIntervalMs = configMock.get<number>('jobManagement.config.dequeueIntervalMs');
Expand All @@ -56,48 +52,8 @@ describe('JobProcessor', () => {
});

describe('consumeAndProcess', () => {
const initTestCases = [
{
jobType: ingestionNewJob.type,
taskType: initTaskForIngestionNew.type,
job: ingestionNewJob,
task: initTaskForIngestionNew,
},
{
jobType: ingestionUpdateJob.type,
taskType: initTaskForIngestionNew.type,
job: ingestionUpdateJob,
task: initTaskForIngestionUpdate,
},
{
jobType: ingestionUpdateJob.type,
taskType: initTaskForIngestionNew.type,
job: ingestionUpdateJob,
task: initTaskForIngestionUpdate,
},
];
const finalizeTestCases = [
{
jobType: ingestionNewJob.type,
taskType: finalizeTaskForIngestionNew.type,
job: ingestionNewJob,
task: finalizeTaskForIngestionNew,
},
{
jobType: ingestionUpdateJob.type,
taskType: finalizeTaskForIngestionUpdate.type,
job: ingestionUpdateJob,
task: finalizeTaskForIngestionUpdate,
},
{
jobType: ingestionUpdateJob.type,
taskType: finalizeTaskForIngestionSwapUpdate.type,
job: ingestionUpdateJob,
task: finalizeTaskForIngestionSwapUpdate,
},
];

test.each(initTestCases)('should process job of type $jobType and init task successfully', async ({ job, task }) => {
testContext = setupJobProcessorTest({ useMockQueueClient: true });
const { jobProcessor, mockDequeue, mockGetJob, mockJobHandlerFactory, configMock } = testContext;
const dequeueIntervalMs = configMock.get<number>('jobManagement.config.dequeueIntervalMs');

Expand All @@ -121,6 +77,7 @@ describe('JobProcessor', () => {
});

test.each(finalizeTestCases)('should process job of type $jobType and finalize task successfully', async ({ job, task }) => {
testContext = setupJobProcessorTest({ useMockQueueClient: true });
const { jobProcessor, mockDequeue, mockGetJob, mockJobHandlerFactory, configMock } = testContext;
const dequeueIntervalMs = configMock.get<number>('jobManagement.config.dequeueIntervalMs');

Expand All @@ -143,4 +100,47 @@ describe('JobProcessor', () => {
expect(mockHandler.handleJobFinalize).toHaveBeenCalledWith(job);
});
});

describe('getJobWithTaskType', () => {
test.each([...initTestCases, ...finalizeTestCases])(
'dequeue $taskType task and get $jobType job with corresponding taskType',
async ({ jobType, taskType, job, task }) => {
jest.useRealTimers();

testContext = setupJobProcessorTest({ useMockQueueClient: false });

const { jobProcessor, configMock, queueClient } = testContext;
const jobManagerBaseUrl = configMock.get<string>('jobManagement.config.jobManagerBaseUrl');
const heartbeatBaseUrl = configMock.get<string>('jobManagement.config.heartbeat.baseUrl');
const consumeTaskUrl = `/tasks/${jobType}/${taskType}/startPending`;
const misMatchRegex = /^\/tasks\/[^/]+\/[^/]+\/startPending$/;

nock.emitter.on('no match', () => {
nock(jobManagerBaseUrl).post(misMatchRegex).reply(404, undefined).persist();
});

nock(jobManagerBaseUrl)
.post(consumeTaskUrl)
.reply(200, { ...task })
.persist()
.get(`/jobs/${task.jobId}?shouldReturnTasks=false`)
.reply(200, { ...job })
.persist();

nock(heartbeatBaseUrl).post(`/heartbeat/${task.id}`).reply(200, 'ok').persist();

const dequeueSpy = jest.spyOn(queueClient, 'dequeue');
const getJobSpy = jest.spyOn(queueClient.jobManagerClient, 'getJob');

const jobAndTaskType = await jobProcessor['getJobWithTaskType']();

expect(dequeueSpy).toHaveBeenCalledWith(jobType, taskType);
expect(getJobSpy).toHaveBeenCalledWith(task.jobId);
expect(jobAndTaskType?.taskType).toEqual(taskType);
expect(jobAndTaskType?.job).toEqual(job);

await queueClient.heartbeatClient.stop(task.id);
}
);
});
});
Loading

0 comments on commit b60ee9a

Please sign in to comment.