Skip to content

Commit

Permalink
fix(tests): resolve test synatx errors found while testing after upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
uladkasach committed Feb 10, 2023
1 parent 123208c commit feb35f6
Show file tree
Hide file tree
Showing 13 changed files with 80 additions and 55 deletions.
4 changes: 0 additions & 4 deletions jest.unit.env.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { stage, Stage } from './src/utils/environment';

jest.mock('./src/utils/config/getConfig', () => ({
getConfig: jest.fn().mockImplementation(() => require('./config/test.json')), // mock that getConfig just returns plaintext test env config in unit tests
}));

/**
* sanity check that unit tests are only run in 'test' environment
* - if they are run in prod environment, we could load a bunch of junk data into our prod databases, which would be no bueno
Expand Down
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,28 @@
"scripts": {
"generate:cli-readme": "npm run build && oclif-dev readme",
"build:ts": "tsc -p ./tsconfig.build.json",
"provision:docker:extensions": "docker-compose -f ./provision/docker/integration_test_db/docker-compose.yml exec -T postgres /root/provision-extensions.sh",
"provision:docker:extensions": "docker-compose -f ./provision/docker/integration-test-db/docker-compose.yml exec -T postgres /root/provision-extensions.sh",
"commit:with-cli": "npx cz",
"fix:format:prettier": "prettier --write '**/*.ts' --config ./prettier.config.js",
"fix:format:terraform": "echo 'no terraform'",
"fix:format": "npm run fix:format:prettier && npm run fix:format:terraform",
"fix:lint": "eslint -c ./.eslintrc.js src/**/*.ts --fix",
"build:clean": "rm dist/ -rf",
"build:compile": "tsc -p ./tsconfig.build.json",
"build:artifact": "echo 'no artifact'",
"build": "npm run build:clean && npm run build:compile && npm run build:artifact",
"provision:docker:up": "docker-compose -f ./provision/docker/integration_test_db/docker-compose.yml up -d --force-recreate --build --renew-anon-volumes",
"provision:docker:await": "docker-compose -f ./provision/docker/integration_test_db/docker-compose.yml exec -T postgres /root/wait-for-postgres.sh",
"provision:docker:down": "docker-compose -f ./provision/docker/integration_test_db/docker-compose.yml down",
"provision:docker:up": "docker-compose -f ./provision/docker/integration-test-db/docker-compose.yml up -d --force-recreate --build --renew-anon-volumes",
"provision:docker:await": "docker-compose -f ./provision/docker/integration-test-db/docker-compose.yml exec -T postgres /root/wait-for-postgres.sh",
"provision:docker:down": "docker-compose -f ./provision/docker/integration-test-db/docker-compose.yml down",
"provision:integration-test-db": "npm run provision:docker:up && npm run provision:docker:await && npm run provision:docker:extensions",
"test:commits": "LAST_TAG=$(git describe --tags --abbrev=0 @^ 2> /dev/null || git rev-list --max-parents=0 HEAD) && npx commitlint --from $LAST_TAG --to HEAD --verbose",
"test:types": "tsc -p ./tsconfig.build.json --noEmit",
"test:format:prettier": "prettier --parser typescript --check 'src/**/*.ts' --config ./prettier.config.js",
"test:format:terraform": "echo 'no terraform'",
"test:format": "npm run test:format:prettier && npm run test:format:terraform",
"test:lint": "eslint -c ./.eslintrc.js src/**/*.ts",
"test:unit": "jest -c ./jest.unit.config.ts --forceExit --coverage --verbose --passWithNoTests",
"test:integration": "jest -c ./jest.integration.config.ts --forceExit --coverage --verbose --passWithNoTests",
"test:integration": "jest -c ./jest.integration.config.ts --forceExit --coverage --verbose --passWithNoTests --runInBand",
"test:acceptance:locally": "npm run build && LOCALLY=true jest -c ./jest.acceptance.config.ts --forceExit --verbose --runInBand",
"test": "npm run test:commits && npm run test:types && npm run test:format && npm run test:lint && npm run test:unit && npm run test:integration && npm run test:acceptance:locally",
"test:acceptance": "npm run build && jest -c ./jest.acceptance.config.ts --forceExit --verbose --runInBand",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,8 @@ describe('generateEntityBackfillCurrentVersionPointers', () => {
return { name, sql: upsertSql };
};
const recreateTheBackfillMethod = async () => {
const {
name,
sql: upsertSql,
} = generateEntityBackfillCurrentVersionPointers({ entity: car });
const { name, sql: upsertSql } =
generateEntityBackfillCurrentVersionPointers({ entity: car });
await dbConnection.query({ sql: `DROP FUNCTION IF EXISTS ${name}` });
await dbConnection.query({ sql: upsertSql });
return { name, sql: upsertSql };
Expand Down Expand Up @@ -260,7 +258,7 @@ describe('generateEntityBackfillCurrentVersionPointers', () => {

// manually update each row, ensuring that ids are out of sync
await Promise.all(
idsOfNewCars.map(async id => deleteCvpRecordForCarById({ id })),
idsOfNewCars.map(async (id) => deleteCvpRecordForCarById({ id })),
);

// show that limit is respected
Expand All @@ -270,9 +268,8 @@ describe('generateEntityBackfillCurrentVersionPointers', () => {
expect(rowsAffectedByBackfillNow).toEqual(3);

// and double prove it by showing that the remainder will be backfilled on running it again
const rowsAffectedByBackfillNowAgain = await backfillCurrentVersionPointers(
{ limit: 1000 },
);
const rowsAffectedByBackfillNowAgain =
await backfillCurrentVersionPointers({ limit: 1000 });
expect(rowsAffectedByBackfillNowAgain).toEqual(2);
});

Expand Down Expand Up @@ -305,7 +302,7 @@ describe('generateEntityBackfillCurrentVersionPointers', () => {

// manually update each row, ensuring that ids are out of sync
await Promise.all(
idsOfNewCars.map(async id => manuallyChangeVersionOfCarById({ id })),
idsOfNewCars.map(async (id) => manuallyChangeVersionOfCarById({ id })),
);

// show that limit is respected
Expand All @@ -315,9 +312,8 @@ describe('generateEntityBackfillCurrentVersionPointers', () => {
expect(rowsAffectedByBackfillNow).toEqual(3);

// and double prove it by showing that the remainder will be backfilled on running it again
const rowsAffectedByBackfillNowAgain = await backfillCurrentVersionPointers(
{ limit: 1000 },
);
const rowsAffectedByBackfillNowAgain =
await backfillCurrentVersionPointers({ limit: 1000 });
expect(rowsAffectedByBackfillNowAgain).toEqual(2);
});
it('should respect the limit on combinations of inserts and updates', async () => {
Expand Down Expand Up @@ -346,12 +342,12 @@ describe('generateEntityBackfillCurrentVersionPointers', () => {

// manually update each row, ensuring that ids are out of sync
await Promise.all(
idsOfNewCarsToDeleteRecordsFor.map(async id =>
idsOfNewCarsToDeleteRecordsFor.map(async (id) =>
deleteCvpRecordForCarById({ id }),
),
);
await Promise.all(
idsOfNewCarsToUpdate.map(async id =>
idsOfNewCarsToUpdate.map(async (id) =>
manuallyChangeVersionOfCarById({ id }),
),
);
Expand All @@ -363,9 +359,8 @@ describe('generateEntityBackfillCurrentVersionPointers', () => {
expect(rowsAffectedByBackfillNow).toEqual(7);

// and double prove it by showing that the remainder will be backfilled on running it again
const rowsAffectedByBackfillNowAgain = await backfillCurrentVersionPointers(
{ limit: 1000 },
);
const rowsAffectedByBackfillNowAgain =
await backfillCurrentVersionPointers({ limit: 1000 });
expect(rowsAffectedByBackfillNowAgain).toEqual(3);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ AS $$
v_static_id bigint;
v_created_at timestamptz := now(); -- define a common created_at timestamp to use
v_matching_version_id bigint;
v_effective_at timestamptz := v_created_at; -- i.e., effective \\"now\\"
v_effective_at timestamptz := v_created_at; -- i.e., effective "now"
v_current_version_id_recorded_in_pointer_table bigint;
v_effective_at_of_current_version_recorded_in_pointer_table timestamptz;
v_array_access_index int;
Expand Down Expand Up @@ -92,7 +92,7 @@ AS $$
FROM movie_version AS v
WHERE 1=1
AND v.movie_id = v_static_id -- for this entity
AND v.effective_at = ( -- and is the version record effective at the time of \\"v_effective_at\\"
AND v.effective_at = ( -- and is the version record effective at the time of "v_effective_at"
SELECT MAX(ssv.effective_at)
FROM movie_version ssv
WHERE ssv.movie_id = v_static_id
Expand Down Expand Up @@ -142,7 +142,7 @@ AS $$
SELECT v.effective_at INTO v_effective_at_of_current_version_recorded_in_pointer_table -- grab the effective_at value of the recorded current version
FROM movie_version AS v
WHERE v.id = v_current_version_id_recorded_in_pointer_table;
IF (v_effective_at_of_current_version_recorded_in_pointer_table < v_effective_at) THEN -- update cached current version only if the version we just inserted is \\"newer\\" than the currently cached version
IF (v_effective_at_of_current_version_recorded_in_pointer_table < v_effective_at) THEN -- update cached current version only if the version we just inserted is "newer" than the currently cached version
UPDATE movie_cvp
SET
movie_version_id = v_matching_version_id,
Expand Down Expand Up @@ -177,7 +177,7 @@ AS $$
v_static_id bigint;
v_created_at timestamptz := now(); -- define a common created_at timestamp to use
v_matching_version_id bigint;
v_effective_at timestamptz := v_created_at; -- i.e., effective \\"now\\"
v_effective_at timestamptz := v_created_at; -- i.e., effective "now"
v_current_version_id_recorded_in_pointer_table bigint;
v_effective_at_of_current_version_recorded_in_pointer_table timestamptz;
BEGIN
Expand All @@ -199,7 +199,7 @@ AS $$
FROM webstore_version AS v
WHERE 1=1
AND v.webstore_id = v_static_id -- for this entity
AND v.effective_at = ( -- and is the version record effective at the time of \\"v_effective_at\\"
AND v.effective_at = ( -- and is the version record effective at the time of "v_effective_at"
SELECT MAX(ssv.effective_at)
FROM webstore_version ssv
WHERE ssv.webstore_id = v_static_id
Expand Down Expand Up @@ -233,7 +233,7 @@ AS $$
SELECT v.effective_at INTO v_effective_at_of_current_version_recorded_in_pointer_table -- grab the effective_at value of the recorded current version
FROM webstore_version AS v
WHERE v.id = v_current_version_id_recorded_in_pointer_table;
IF (v_effective_at_of_current_version_recorded_in_pointer_table < v_effective_at) THEN -- update cached current version only if the version we just inserted is \\"newer\\" than the currently cached version
IF (v_effective_at_of_current_version_recorded_in_pointer_table < v_effective_at) THEN -- update cached current version only if the version we just inserted is "newer" than the currently cached version
UPDATE webstore_cvp
SET
webstore_version_id = v_matching_version_id,
Expand Down Expand Up @@ -342,7 +342,7 @@ AS $$
v_static_id bigint;
v_created_at timestamptz := now(); -- define a common created_at timestamp to use
v_matching_version_id bigint;
v_effective_at timestamptz := v_created_at; -- i.e., effective \\"now\\"
v_effective_at timestamptz := v_created_at; -- i.e., effective "now"
v_current_version_id_recorded_in_pointer_table bigint;
v_effective_at_of_current_version_recorded_in_pointer_table timestamptz;
BEGIN
Expand All @@ -364,7 +364,7 @@ AS $$
FROM alternative_user_version AS v
WHERE 1=1
AND v.alternative_user_id = v_static_id -- for this entity
AND v.effective_at = ( -- and is the version record effective at the time of \\"v_effective_at\\"
AND v.effective_at = ( -- and is the version record effective at the time of "v_effective_at"
SELECT MAX(ssv.effective_at)
FROM alternative_user_version ssv
WHERE ssv.alternative_user_id = v_static_id
Expand Down Expand Up @@ -396,7 +396,7 @@ AS $$
SELECT v.effective_at INTO v_effective_at_of_current_version_recorded_in_pointer_table -- grab the effective_at value of the recorded current version
FROM alternative_user_version AS v
WHERE v.id = v_current_version_id_recorded_in_pointer_table;
IF (v_effective_at_of_current_version_recorded_in_pointer_table < v_effective_at) THEN -- update cached current version only if the version we just inserted is \\"newer\\" than the currently cached version
IF (v_effective_at_of_current_version_recorded_in_pointer_table < v_effective_at) THEN -- update cached current version only if the version we just inserted is "newer" than the currently cached version
UPDATE alternative_user_cvp
SET
alternative_user_version_id = v_matching_version_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ export const defineFindOrCreateStaticEntityLogic = ({

// define the static property names
const staticPropertyNames = Object.entries(entity.properties)
.filter(entry => !entry[1].updatable)
.map(entry => entry[0]);
.filter((entry) => !entry[1].updatable)
.map((entry) => entry[0]);

// define the column names and the column value references for the static properties
const staticPropertyColumnNames = staticPropertyNames.map(name =>
const staticPropertyColumnNames = staticPropertyNames.map((name) =>
castPropertyToColumnName({ name, definition: entity.properties[name]! }),
);
const staticPropertyColumnValueReferences = staticPropertyNames.map(name =>
const staticPropertyColumnValueReferences = staticPropertyNames.map((name) =>
castPropertyToTableColumnValueReference({
name,
definition: entity.properties[name]!,
Expand All @@ -46,10 +46,10 @@ export const defineFindOrCreateStaticEntityLogic = ({
}

// otherwise, define the where clause conditionals as normal
const uniqueStaticPropertyNames = staticPropertyNames.filter(name =>
const uniqueStaticPropertyNames = staticPropertyNames.filter((name) =>
entity.unique.includes(name),
);
return uniqueStaticPropertyNames.map(name =>
return uniqueStaticPropertyNames.map((name) =>
castPropertyToWhereClauseConditional({
name,
definition: entity.properties[name]!,
Expand All @@ -61,7 +61,7 @@ export const defineFindOrCreateStaticEntityLogic = ({
// define the array properties, for which we'll need to insert into a mapping table
const staticArrayProperties = pickKeysFromObject({
object: entity.properties,
keep: property => !!property.array && !property.updatable,
keep: (property) => !!property.array && !property.updatable,
});
const mappingTableInserts = Object.entries(staticArrayProperties).map(
([name, definition]) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`generateEntityTables generates tables for an entity with array properties (both updatable and static) and unique on one array, w/ the same syntax as show create 1`] = `
Object {
"currentVersionPointer": Object {
{
"currentVersionPointer": {
"name": "home_cvp",
"sql": "CREATE TABLE home_cvp (
id bigserial NOT NULL,
Expand All @@ -17,8 +17,8 @@ Object {
CREATE INDEX home_cvp_fk0_ix ON home_cvp USING btree (home_id);
CREATE INDEX home_cvp_fk1_ix ON home_cvp USING btree (home_version_id);",
},
"mappings": Array [
Object {
"mappings": [
{
"name": "home_to_host",
"sql": "CREATE TABLE home_to_host (
id bigserial NOT NULL,
Expand All @@ -34,7 +34,7 @@ CREATE INDEX home_cvp_fk1_ix ON home_cvp USING btree (home_version_id);",
CREATE INDEX home_to_host_fk0_ix ON home_to_host USING btree (home_id);
CREATE INDEX home_to_host_fk1_ix ON home_to_host USING btree (host_id);",
},
Object {
{
"name": "home_version_to_photo",
"sql": "CREATE TABLE home_version_to_photo (
id bigserial NOT NULL,
Expand All @@ -50,7 +50,7 @@ CREATE INDEX home_to_host_fk1_ix ON home_to_host USING btree (host_id);",
CREATE INDEX home_version_to_photo_fk0_ix ON home_version_to_photo USING btree (home_version_id);
CREATE INDEX home_version_to_photo_fk1_ix ON home_version_to_photo USING btree (photo_id);",
},
Object {
{
"name": "home_to_seller_uuid",
"sql": "CREATE TABLE home_to_seller_uuid (
id bigserial NOT NULL,
Expand All @@ -64,7 +64,7 @@ CREATE INDEX home_version_to_photo_fk1_ix ON home_version_to_photo USING btree (
);
CREATE INDEX home_to_seller_uuid_fk0_ix ON home_to_seller_uuid USING btree (home_id);",
},
Object {
{
"name": "home_version_to_advert_uuid",
"sql": "CREATE TABLE home_version_to_advert_uuid (
id bigserial NOT NULL,
Expand All @@ -79,7 +79,7 @@ CREATE INDEX home_to_seller_uuid_fk0_ix ON home_to_seller_uuid USING btree (home
CREATE INDEX home_version_to_advert_uuid_fk0_ix ON home_version_to_advert_uuid USING btree (home_version_id);",
},
],
"static": Object {
"static": {
"name": "home",
"sql": "CREATE TABLE home (
id bigserial NOT NULL,
Expand All @@ -92,7 +92,7 @@ CREATE INDEX home_version_to_advert_uuid_fk0_ix ON home_version_to_advert_uuid U
CONSTRAINT home_ux1 UNIQUE (name, host_ids_hash)
);",
},
"version": Object {
"version": {
"name": "home_version",
"sql": "CREATE TABLE home_version (
id bigserial NOT NULL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,10 +377,7 @@ describe('generateEntityViewCurrent', () => {
// update the entity dynamic properties
const updatedProps = {
...props,
wheel_ids: `{${wheelIds
.split(',')
.slice(1, 2)
.join(',')}}`,
wheel_ids: `{${wheelIds.split(',').slice(1, 2).join(',')}}`,
};
const idAgain = await upsertVehicle(updatedProps);
expect(idAgain).toEqual(id);
Expand Down
35 changes: 35 additions & 0 deletions src/utils/environment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export enum Stage {
PRODUCTION = 'prod',
DEVELOPMENT = 'dev',
TEST = 'test',
}

/**
* this allows us to infer what the stage should be in environments that do not have STAGE specified
* - e.g., when running locally
* - e.g., when running tests
*/
const inferStageFromNodeEnv = () => {
const nodeEnv = process.env.NODE_ENV; // default to test if not defined
if (!nodeEnv) throw new Error('process.env.NODE_ENV must be defined');
if (nodeEnv === 'production') return Stage.PRODUCTION;
if (nodeEnv === 'development') return Stage.DEVELOPMENT;
if (nodeEnv === 'test') return Stage.TEST;
throw new Error(`unexpected nodeEnv '${nodeEnv}'`);
};

/**
* a method that exposes relevant environmental variables in a standard way
*/
const getEnvironment = () => {
const stage = process.env.STAGE ?? inferStageFromNodeEnv(); // figure it out from NODE_ENV if not explicitly defined
if (!stage) throw new Error('process.env.STAGE must be defined');
return { stage };
};

// export stage immediately, since it does not change
export const { stage } = getEnvironment();

// export service client stage
export const serviceClientStage =
stage === Stage.PRODUCTION ? Stage.PRODUCTION : Stage.DEVELOPMENT; // i.e., if its prod, hit prod. otherwise, dev

0 comments on commit feb35f6

Please sign in to comment.