Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions __tests__/unit/PDFHelper.planVersionDates.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { describe, expect, it, vi } from 'vitest';

vi.mock('../../src/libs/db2/model/agreement.js', () => ({ default: {} }));

describe('formatPlanVersionDates', () => {
it('uses the BC timezone for dates near UTC midnight', async () => {
const { formatPlanVersionDates } = await import('../../src/router/helpers/PDFHelper.ts');

const plan = {
originalApproval: { date: '2024-03-16T06:30:00.000Z' },
amendmentSubmissions: [
{
createdAt: '2024-03-16T06:30:00.000Z',
approvedAt: '2024-03-16T07:30:00.000Z',
},
],
};

expect(formatPlanVersionDates(plan)).toEqual({
originalApproval: { date: '2024-03-15' },
amendmentSubmissions: [{ createdAt: '2024-03-15', approvedAt: '2024-03-16' }],
});
});
});
1 change: 1 addition & 0 deletions __tests__/unit/config.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ describe('config', () => {
process.env.POSTGRESQL_USER = 'test_user';
process.env.POSTGRESQL_PASSWORD = 'test_pass';
process.env.POSTGRESQL_DATABASE = 'test_db';
process.env.POSTGRESQL_DATABASE_TEST = 'test_db';
process.env.POSTGRESQL_HOST = 'test_host';
process.env.POSTGRESQL_PORT = '5432';
process.env.SSO_URL = 'https://sso.example.com';
Expand Down
8 changes: 8 additions & 0 deletions __tests__/unit/dayjs.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ describe('dayjs', () => {
dayjs = (await import('dayjs')).default;
const isBetween = (await import('dayjs/plugin/isBetween.js')).default;
const advancedFormat = (await import('dayjs/plugin/advancedFormat.js')).default;
const utc = (await import('dayjs/plugin/utc.js')).default;
const timezone = (await import('dayjs/plugin/timezone.js')).default;
dayjs.extend(isBetween);
dayjs.extend(advancedFormat);
dayjs.extend(utc);
dayjs.extend(timezone);
});

it('formats dates', () => {
Expand All @@ -17,6 +21,10 @@ describe('dayjs', () => {
expect(d.format('MMMM D')).toBe('March 15');
});

it('formats plan version dates in the BC timezone', () => {
expect(dayjs.utc('2024-03-16T06:30:00.000Z').tz('America/Vancouver').format('YYYY-MM-DD')).toBe('2024-03-15');
});

it('formats with ordinal Do', () => {
const d = dayjs('2024-03-15');
expect(d.format('MMMM Do')).toBe('March 15th');
Expand Down
19 changes: 19 additions & 0 deletions __tests__/unit/migrate.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { afterEach, describe, expect, it } from 'vitest';
import { createDb } from '../../src/libs/db2/migrate.ts';

const originalNodeEnv = process.env.NODE_ENV;
const originalTestDatabase = process.env.POSTGRESQL_DATABASE_TEST;

afterEach(() => {
process.env.NODE_ENV = originalNodeEnv;
process.env.POSTGRESQL_DATABASE_TEST = originalTestDatabase;
});

describe('createDb', () => {
it.each(['test', 'unit_test'])('rejects %s when the test database is not configured', (nodeEnv) => {
process.env.NODE_ENV = nodeEnv;
delete process.env.POSTGRESQL_DATABASE_TEST;

expect(() => createDb()).toThrow('POSTGRESQL_DATABASE_TEST must be set');
});
});
7 changes: 6 additions & 1 deletion src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const env = process.env.NODE_ENV || 'development';
const isTestEnvironment = env === 'test' || env === 'unit_test';

if (env === 'development') {
dotenv.config();
Expand All @@ -16,6 +17,10 @@ if (!process.env.SSO_URL) {
throw new Error('SSO_URL is not set');
}

if (isTestEnvironment && !process.env.POSTGRESQL_DATABASE_TEST) {
throw new Error('POSTGRESQL_DATABASE_TEST must be set when running tests');
}
Comment thread
brijesh-amin marked this conversation as resolved.

interface DBConfig {
user: string;
password: string;
Expand Down Expand Up @@ -63,7 +68,7 @@ const config: Config = {
user: process.env.POSTGRESQL_USER || '',
password: process.env.POSTGRESQL_PASSWORD || '',
database:
env === 'test' && process.env.POSTGRESQL_DATABASE_TEST
isTestEnvironment && process.env.POSTGRESQL_DATABASE_TEST
? process.env.POSTGRESQL_DATABASE_TEST
: process.env.POSTGRESQL_DATABASE || '',
host: process.env.POSTGRESQL_HOST || '',
Expand Down
4 changes: 4 additions & 0 deletions src/libs/bcgov-shim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import pino from 'pino';
import _dayjs from 'dayjs';
import isBetween from 'dayjs/plugin/isBetween.js';
import advancedFormat from 'dayjs/plugin/advancedFormat.js';
import utc from 'dayjs/plugin/utc.js';
import timezone from 'dayjs/plugin/timezone.js';

_dayjs.extend(isBetween);
_dayjs.extend(advancedFormat);
_dayjs.extend(utc);
_dayjs.extend(timezone);

export const dayjs = _dayjs;

Expand Down
12 changes: 7 additions & 5 deletions src/libs/db2/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,17 @@ function parseUpSql(content: string): string {

const { Pool } = pg;

function createDb(): Kysely<unknown> {
export function createDb(): Kysely<unknown> {
const isTestEnvironment = process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'unit_test';
if (isTestEnvironment && !process.env.POSTGRESQL_DATABASE_TEST) {
throw new Error('POSTGRESQL_DATABASE_TEST must be set when running migrations in a test environment');
}

const dialect = new PostgresDialect({
pool: new Pool({
host: process.env.POSTGRESQL_HOST,
port: parseInt(process.env.POSTGRESQL_PORT || '5432', 10),
database:
process.env.NODE_ENV === 'test' && process.env.POSTGRESQL_DATABASE_TEST
? process.env.POSTGRESQL_DATABASE_TEST
: process.env.POSTGRESQL_DATABASE,
database: isTestEnvironment ? process.env.POSTGRESQL_DATABASE_TEST : process.env.POSTGRESQL_DATABASE,
user: process.env.POSTGRESQL_USER,
password: process.env.POSTGRESQL_PASSWORD,
max: 10,
Expand Down
3 changes: 2 additions & 1 deletion src/router/controllers_v1/PDFGeneration.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// @ts-nocheck
import Cdogs from '../../libs/cdogs.js';
import Agreement from '../../libs/db2/model/agreement.js';
import { AdditionalDetailsGenerator } from '../helpers/PDFHelper.js';
import { AdditionalDetailsGenerator, formatPlanVersionDates } from '../helpers/PDFHelper.js';

export const generatePlanPDF = async (plan) => {
formatPlanVersionDates(plan);
const templateFile = Agreement.isGrazingSchedule(plan.agreement)
? './planTemplate_GrazingSchedule.docx'
: './planTemplate_HaycuttingSchedule.docx';
Expand Down
18 changes: 18 additions & 0 deletions src/router/helpers/PDFHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,24 @@ import { dayjs as moment } from '../../libs/bcgov-shim.js';
import { DAYS_ON_THE_AVERAGE, NOT_PROVIDED } from '../../constants.js';
import Agreement from '../../libs/db2/model/agreement.js';

export const formatPlanVersionDate = (date) =>
date ? moment.utc(date).tz('America/Vancouver').format('YYYY-MM-DD') : date;

export const formatPlanVersionDates = (plan) => {
if (plan.originalApproval) {
plan.originalApproval.date = formatPlanVersionDate(plan.originalApproval.date);
}

if (plan.amendmentSubmissions) {
plan.amendmentSubmissions.forEach((submission) => {
submission.createdAt = formatPlanVersionDate(submission.createdAt);
submission.approvedAt = formatPlanVersionDate(submission.approvedAt);
});
}

return plan;
};

const shift = (number, precision) => {
const numArray = `${number}`.split('e');
return +`${numArray[0]}e${numArray[1] ? +numArray[1] + precision : precision}`;
Expand Down
Loading