Skip to content

Commit

Permalink
Merge branch 'SIMSBIOHUB-239' of github.com:bcgov/biohubbc into SIMSB…
Browse files Browse the repository at this point in the history
…IOHUB-239
  • Loading branch information
GrahamS-Quartech committed Aug 29, 2023
2 parents 6660d97 + 93d7ff0 commit 4a7fd49
Show file tree
Hide file tree
Showing 10 changed files with 267 additions and 13 deletions.
41 changes: 41 additions & 0 deletions api/src/paths/critter-data/family/{familyId}.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { expect } from 'chai';
import sinon from 'sinon';
import { CritterbaseService } from '../../../services/critterbase-service';
import { getRequestHandlerMocks } from '../../../__mocks__/db';
import { getFamilyById } from './{familyId}';

describe('getFamilyById', () => {
afterEach(() => {
sinon.restore();
});

it('gets a family by id', async () => {
const mockFamily = { id: '1', name: 'family1' };
const mockGetFamilyById = sinon.stub(CritterbaseService.prototype, 'getFamilyById').resolves(mockFamily);

const { mockReq, mockRes, mockNext } = getRequestHandlerMocks();
const requestHandler = getFamilyById();

await requestHandler(mockReq, mockRes, mockNext);

expect(mockGetFamilyById.calledOnce).to.be.true;
expect(mockRes.json.calledOnce).to.be.true;
expect(mockRes.json.args[0][0]).to.deep.equal(mockFamily);
});

it('handles errors', async () => {
const mockError = new Error('error');
const mockGetFamilyById = sinon.stub(CritterbaseService.prototype, 'getFamilyById').rejects(mockError);

const { mockReq, mockRes, mockNext } = getRequestHandlerMocks();
const requestHandler = getFamilyById();

try {
await requestHandler(mockReq, mockRes, mockNext);
expect.fail();
} catch (actualError) {
expect(actualError).to.equal(mockError);
expect(mockGetFamilyById.calledOnce).to.be.true;
}
});
});
16 changes: 12 additions & 4 deletions api/src/paths/critter-data/family/{familyId}.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import { Operation } from 'express-openapi';
import { PROJECT_PERMISSION, SYSTEM_ROLE } from '../../../constants/roles';
import { authorizeRequestHandler } from '../../../request-handlers/security/authorization';
import { CritterbaseService, ICritterbaseUser } from '../../../services/critterbase-service';
import { getLogger } from '../../../utils/logger';

// TODO: Put this all into an existing endpoint
const defaultLog = getLogger('paths/critter-data/family');

export const GET: Operation = [
authorizeRequestHandler((req) => {
Expand Down Expand Up @@ -95,9 +97,15 @@ export function getFamilyById(): RequestHandler {
keycloak_guid: req['system_user']?.user_guid,
username: req['system_user']?.user_identifier
};
const key: string = req.params.familyId;
const cb = new CritterbaseService(user);
const result = await cb.getFamilyById(key);
return res.status(200).json(result);

try {
const key: string = req.params.familyId;
const cb = new CritterbaseService(user);
const result = await cb.getFamilyById(key);
return res.status(200).json(result);
} catch (error) {
defaultLog.error({ label: 'getFamilyById', message: 'error', error });
throw error;
}
};
}
40 changes: 40 additions & 0 deletions api/src/paths/critter-data/signup.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { expect } from 'chai';
import sinon from 'sinon';
import { CritterbaseService } from '../../services/critterbase-service';
import { getRequestHandlerMocks } from '../../__mocks__/db';
import { signUp } from './signup';

describe('signUp', () => {
afterEach(() => {
sinon.restore();
});
it('adds a user to critterbase and returns status 200', async () => {
const mockAddUser = sinon.stub(CritterbaseService.prototype, 'signUp').resolves({ message: 'User created' });

const { mockReq, mockRes, mockNext } = getRequestHandlerMocks();
const requestHandler = signUp();

await requestHandler(mockReq, mockRes, mockNext);

expect(mockAddUser.calledOnce).to.be.true;
expect(mockRes.status.calledOnce).to.be.true;
expect(mockRes.status.args[0][0]).to.equal(200);
expect(mockRes.json.calledOnce).to.be.true;
expect(mockRes.json.args[0][0]).to.deep.equal({ message: 'User created' });
});
it('catches and re-throws error', async () => {
const mockError = new Error('mockError');
const mockAddUser = sinon.stub(CritterbaseService.prototype, 'signUp').rejects(mockError);

const { mockReq, mockRes, mockNext } = getRequestHandlerMocks();
const requestHandler = signUp();

try {
await requestHandler(mockReq, mockRes, mockNext);
expect.fail();
} catch (actualError) {
expect(actualError).to.equal(mockError);
expect(mockAddUser.calledOnce).to.be.true;
}
});
});
11 changes: 9 additions & 2 deletions api/src/paths/critter-data/signup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import { Operation } from 'express-openapi';
import { PROJECT_PERMISSION, SYSTEM_ROLE } from '../../constants/roles';
import { authorizeRequestHandler } from '../../request-handlers/security/authorization';
import { CritterbaseService, ICritterbaseUser } from '../../services/critterbase-service';
import { getLogger } from '../../utils/logger';

// TODO: Put this all into an existing endpoint
const defaultLog = getLogger('paths/critter-data/signup');

export const POST: Operation = [
authorizeRequestHandler((req) => {
Expand Down Expand Up @@ -70,7 +72,12 @@ export function signUp(): RequestHandler {
username: req['system_user']?.user_identifier
};
const cb = new CritterbaseService(user);
const result = await cb.signUp();
return res.status(200).json(result);
try {
const result = await cb.signUp();
return res.status(200).json(result);
} catch (error) {
defaultLog.error({ label: 'signUp', message: 'error', error });
throw error;
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { expect } from 'chai';
import sinon from 'sinon';
import { CritterbaseService } from '../../../services/critterbase-service';
import { getRequestHandlerMocks } from '../../../__mocks__/db';
import { getTaxonBodyLocations } from './taxon-marking-body-locations';

describe('getTaxonBodyLocations', () => {
afterEach(() => {
sinon.restore();
});

it('gets taxon body locations', async () => {
const mockTaxonBodyLocations = ['bodyLocation1', 'bodyLocation2'];
const mockGetTaxonBodyLocations = sinon
.stub(CritterbaseService.prototype, 'getTaxonBodyLocations')
.resolves(mockTaxonBodyLocations);

const { mockReq, mockRes, mockNext } = getRequestHandlerMocks();
const requestHandler = getTaxonBodyLocations();

await requestHandler(mockReq, mockRes, mockNext);

expect(mockGetTaxonBodyLocations.calledOnce).to.be.true;
expect(mockRes.status.calledOnceWith(200)).to.be.true;
expect(mockRes.json.calledOnceWith(mockTaxonBodyLocations)).to.be.true;
});

it('handles errors', async () => {
const mockError = new Error('mock error');
const mockGetTaxonBodyLocations = sinon
.stub(CritterbaseService.prototype, 'getTaxonBodyLocations')
.rejects(mockError);

const { mockReq, mockRes, mockNext } = getRequestHandlerMocks();
const requestHandler = getTaxonBodyLocations();

try {
await requestHandler(mockReq, mockRes, mockNext);
expect.fail();
} catch (actualError) {
expect(actualError).to.equal(mockError);
expect(mockGetTaxonBodyLocations.calledOnce).to.be.true;
}
});
});
12 changes: 10 additions & 2 deletions api/src/paths/critter-data/xref/taxon-marking-body-locations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import { Operation } from 'express-openapi';
import { PROJECT_PERMISSION, SYSTEM_ROLE } from '../../../constants/roles';
import { authorizeRequestHandler } from '../../../request-handlers/security/authorization';
import { CritterbaseService, ICritterbaseUser } from '../../../services/critterbase-service';
import { getLogger } from '../../../utils/logger';
import { critterbaseCommonLookupResponse } from '../../../utils/shared-api-docs';

// TODO: Put this all into an existing endpoint
const defaultLog = getLogger('paths/critter-data/xref');

export const GET: Operation = [
authorizeRequestHandler((req) => {
Expand Down Expand Up @@ -78,7 +80,13 @@ export function getTaxonBodyLocations(): RequestHandler {
};
const taxon_id = String(req.query.taxon_id);
const cb = new CritterbaseService(user);
const result = await cb.getTaxonBodyLocations(taxon_id);
return res.status(200).json(result);

try {
const result = await cb.getTaxonBodyLocations(taxon_id);
return res.status(200).json(result);
} catch (error) {
defaultLog.error({ label: 'getTaxonBodyLocations', message: 'error', error });
throw error;
}
};
}
45 changes: 45 additions & 0 deletions api/src/paths/critter-data/xref/taxon-measurements.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { expect } from 'chai';
import sinon from 'sinon';
import { CritterbaseService } from '../../../services/critterbase-service';
import { getRequestHandlerMocks } from '../../../__mocks__/db';
import { getTaxonMeasurements } from './taxon-measurements';

describe('getTaxonMeasurements', () => {
afterEach(() => {
sinon.restore();
});

it('gets taxon measurements', async () => {
const mockTaxonMeasurements = ['measurement1', 'measurement2'];
const mockGetTaxonMeasurements = sinon
.stub(CritterbaseService.prototype, 'getTaxonMeasurements')
.resolves(mockTaxonMeasurements);

const { mockReq, mockRes, mockNext } = getRequestHandlerMocks();
const requestHandler = getTaxonMeasurements();

await requestHandler(mockReq, mockRes, mockNext);

expect(mockGetTaxonMeasurements.calledOnce).to.be.true;
expect(mockRes.statusValue).to.equal(200);
expect(mockRes.json.calledWith(mockTaxonMeasurements)).to.be.true;
});

it('handles errors', async () => {
const mockError = new Error('mock error');
const mockGetTaxonMeasurements = sinon
.stub(CritterbaseService.prototype, 'getTaxonMeasurements')
.rejects(mockError);

const { mockReq, mockRes, mockNext } = getRequestHandlerMocks();
const requestHandler = getTaxonMeasurements();

try {
await requestHandler(mockReq, mockRes, mockNext);
expect.fail();
} catch (actualError) {
expect(actualError).to.equal(mockError);
expect(mockGetTaxonMeasurements.calledOnce).to.be.true;
}
});
});
12 changes: 9 additions & 3 deletions api/src/paths/critter-data/xref/taxon-measurements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import { Operation } from 'express-openapi';
import { PROJECT_PERMISSION, SYSTEM_ROLE } from '../../../constants/roles';
import { authorizeRequestHandler } from '../../../request-handlers/security/authorization';
import { CritterbaseService, ICritterbaseUser } from '../../../services/critterbase-service';
import { getLogger } from '../../../utils/logger';

// TODO: Put this all into an existing endpoint
const defaultLog = getLogger('paths/critter-data/xref');

export const GET: Operation = [
authorizeRequestHandler((req) => {
Expand Down Expand Up @@ -83,9 +85,13 @@ export function getTaxonMeasurements(): RequestHandler {
username: req['system_user']?.user_identifier
};
const taxon_id = String(req.query.taxon_id);

const cb = new CritterbaseService(user);
const result = await cb.getTaxonMeasurements(taxon_id);
return res.status(200).json(result);
try {
const result = await cb.getTaxonMeasurements(taxon_id);
return res.status(200).json(result);
} catch (error) {
defaultLog.error({ label: 'getTaxonMeasurements', message: 'error', error });
throw error;
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { expect } from 'chai';
import sinon from 'sinon';
import { CritterbaseService } from '../../../services/critterbase-service';
import { getRequestHandlerMocks } from '../../../__mocks__/db';
import { getQualMeasurementOptions } from './taxon-qualitative-measurement-options';

describe('getQualMeasurementOptions', () => {
afterEach(() => {
sinon.restore();
});

it('gets qualitative measurement options', async () => {
const mockQualMeasurementOptions = ['qualMeasurementOption1', 'qualMeasurementOption2'];
const mockGetQualMeasurementOptions = sinon
.stub(CritterbaseService.prototype, 'getQualitativeOptions')
.resolves(mockQualMeasurementOptions);

const { mockReq, mockRes, mockNext } = getRequestHandlerMocks();
const requestHandler = getQualMeasurementOptions();

await requestHandler(mockReq, mockRes, mockNext);

expect(mockGetQualMeasurementOptions.calledOnce).to.be.true;
expect(mockRes.status.calledOnce).to.be.true;
expect(mockRes.status.getCall(0).args[0]).to.equal(200);
expect(mockRes.json.calledOnce).to.be.true;
expect(mockRes.json.getCall(0).args[0]).to.deep.equal(mockQualMeasurementOptions);
});

it('handles errors', async () => {
const mockError = new Error('mockError');
const mockGetQualMeasurementOptions = sinon
.stub(CritterbaseService.prototype, 'getQualitativeOptions')
.rejects(mockError);

const { mockReq, mockRes, mockNext } = getRequestHandlerMocks();
const requestHandler = getQualMeasurementOptions();

try {
await requestHandler(mockReq, mockRes, mockNext);
expect.fail();
} catch (actualError) {
expect(actualError).to.equal(mockError);
expect(mockGetQualMeasurementOptions.calledOnce).to.be.true;
}
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import { Operation } from 'express-openapi';
import { PROJECT_PERMISSION, SYSTEM_ROLE } from '../../../constants/roles';
import { authorizeRequestHandler } from '../../../request-handlers/security/authorization';
import { CritterbaseService, ICritterbaseUser } from '../../../services/critterbase-service';
import { getLogger } from '../../../utils/logger';
import { critterbaseCommonLookupResponse } from '../../../utils/shared-api-docs';

// TODO: Put this all into an existing endpoint
const defaultLog = getLogger('paths/critter-data/xref');

export const GET: Operation = [
authorizeRequestHandler((req) => {
Expand Down Expand Up @@ -85,7 +87,12 @@ export function getQualMeasurementOptions(): RequestHandler {
};
const taxon_id = String(req.query.taxon_measurement_id);
const cb = new CritterbaseService(user);
const result = await cb.getQualitativeOptions(taxon_id);
return res.status(200).json(result);
try {
const result = await cb.getQualitativeOptions(taxon_id);
return res.status(200).json(result);
} catch (error) {
defaultLog.error({ label: 'getTaxonMeasurements', message: 'error', error });
throw error;
}
};
}

0 comments on commit 4a7fd49

Please sign in to comment.