Skip to content

Commit

Permalink
test: add unit tests for health controller
Browse files Browse the repository at this point in the history
  • Loading branch information
dnechay committed Oct 25, 2024
1 parent d7f2bce commit a216c38
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 1 deletion.
2 changes: 2 additions & 0 deletions packages/apps/human-app/server/jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
process.env['GIT_HASH'] = 'test_value_hardcoded_in_jest_config';

module.exports = {
coverageDirectory: '../coverage',
collectCoverageFrom: ['**/*.(t|j)s'],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Test } from '@nestjs/testing';
import { HealthController } from './health.controller';
import { TerminusModule } from '@nestjs/terminus';
import { RedisHealthIndicator } from './indicators/redis.health';
import { EnvironmentConfigService } from '../../common/config/environment-config.service';
import { ConfigModule } from '@nestjs/config';
import { ServiceUnavailableException } from '@nestjs/common';

const redisClientMock = {
ping: jest.fn(),
};

const cacheManagerMock = {
store: {
getClient: () => redisClientMock,
},
};

describe('HealthController', () => {
let healthController: HealthController;

beforeAll(async () => {
const moduleRef = await Test.createTestingModule({
imports: [
TerminusModule,
ConfigModule.forRoot({
envFilePath: '.env',
isGlobal: true,
}),
],
controllers: [HealthController],
providers: [
RedisHealthIndicator,
EnvironmentConfigService,
{ provide: CACHE_MANAGER, useValue: cacheManagerMock },
],
}).compile();

healthController = moduleRef.get(HealthController);
});

it('/ping should return proper info', async () => {
await expect(healthController.ping()).resolves.toEqual({
appName: '@human-protocol/human-app-server',
gitHash: 'test_value_hardcoded_in_jest_config',
});
});

describe('/check', () => {
afterEach(() => {
redisClientMock.ping.mockReset();
});

it(`returns 'up' status when cache-manager redis is up`, async () => {
await expect(healthController.check()).resolves.toEqual(
expect.objectContaining({
status: 'ok',
info: {
'cache-manager-redis': {
status: 'up',
},
},
}),
);
});

it(`returns 'down' status when cache-manager redis is down`, async () => {
redisClientMock.ping.mockRejectedValueOnce(new Error());

let thrownError;
try {
await healthController.check();
} catch (error) {
thrownError = error;
}

expect(thrownError).toBeInstanceOf(ServiceUnavailableException);
expect(thrownError.response).toEqual(
expect.objectContaining({
status: 'error',
info: {},
error: {
'cache-manager-redis': {
status: 'down',
},
},
}),
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class HealthController {
description: 'Service is not reachable/running',
})
@Get('/ping')
ping(): PingResponseDto {
async ping(): Promise<PingResponseDto> {
return {
appName: packageJson.name,
gitHash: this.environmentConfigService.gitHash,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { HealthCheckError } from '@nestjs/terminus';
import { RedisHealthIndicator } from './redis.health';

describe('RedisHealthIndicator', () => {
const redisClientMock = {
ping: jest.fn(),
};

const redisHealthIndicator = new RedisHealthIndicator();

afterEach(() => {
redisClientMock.ping.mockReset();
});

describe('isHealty', () => {
it('should return healthy status if can ping', async () => {
redisClientMock.ping.mockResolvedValueOnce('PONG');

const testKey = 'test-key-1';

const healthIndicatorResult = await redisHealthIndicator.isHealthy(
testKey,
redisClientMock,
);

expect(healthIndicatorResult).toEqual({
[testKey]: { status: 'up' },
});
});

it(`should throw with unhealthy status if can't ping`, async () => {
const mockNetworkError = new Error('Ooops! Redis network error');
redisClientMock.ping.mockRejectedValueOnce(mockNetworkError);

const testKey = 'test-key-2';

let thrownError;
try {
await redisHealthIndicator.isHealthy(testKey, redisClientMock);
} catch (error) {
thrownError = error;
}

expect(thrownError).toBeInstanceOf(HealthCheckError);
expect(thrownError.causes).toEqual({
[testKey]: { status: 'down' },
});
});
});
});

0 comments on commit a216c38

Please sign in to comment.