Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(grants-collaboration): expose notes retrieval #3395

Merged
merged 9 commits into from
Aug 22, 2024
60 changes: 57 additions & 3 deletions packages/server/__tests__/api/grants.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const { getSessionCookie, makeTestServer, knex } = require('./utils');
const { TABLES } = require('../../src/db/constants');
const db = require('../../src/db');
const email = require('../../src/lib/email');
const users = require('../../seeds/dev/ref/users');
const { seed } = require('../../seeds/dev/01_main');

/*
In general, these tests ...
Expand All @@ -20,6 +22,9 @@ describe('`/api/grants` endpoint', () => {
dallasAdmin: 386,
};

const adminUser = users.find((usr) => usr.email === '[email protected]');
const staffUser = users.find((usr) => usr.email === '[email protected]');

const fetchOptions = {
admin: {
headers: {
Expand Down Expand Up @@ -52,13 +57,15 @@ describe('`/api/grants` endpoint', () => {
testServer = await makeTestServer();
fetchApi = testServer.fetchApi;
});

after(() => {
testServer.stop();
});

const sandbox = sinon.createSandbox();
afterEach(() => {
afterEach(async () => {
sandbox.restore();
await seed(knex);
});

context('PUT api/grants/:grantId/view/:agencyId', () => {
Expand Down Expand Up @@ -616,7 +623,6 @@ describe('`/api/grants` endpoint', () => {
}
const extraRowCount = Object.keys(rowsHash).length;
if (extraRowCount > 0) {
console.log(JSON.stringify(rowsHash, null, 2));
expect(extraRowCount).to.equal(0);
}
});
Expand Down Expand Up @@ -724,7 +730,6 @@ HHS-2021-IHS-TPI-0001,Community Health Aide Program: Tribal Planning &`;
}
const extraRowCount = Object.keys(rowsHash).length;
if (extraRowCount > 0) {
console.log(JSON.stringify(rowsHash, null, 2));
expect(extraRowCount).to.equal(0);
}
});
Expand Down Expand Up @@ -873,4 +878,53 @@ HHS-2021-IHS-TPI-0001,Community Health Aide Program: Tribal Planning &`;
});
});
});

context('GET api/grants/:grantId/notes', () => {
const GRANT_ID = '335255';

let notes;
beforeEach(async () => {
notes = await knex('grant_notes')
.returning('id')
.insert([
{ grant_id: GRANT_ID, user_id: adminUser.id },
{ grant_id: GRANT_ID, user_id: staffUser.id },
]);

await knex('grant_notes_revisions')
.insert({ grant_note_id: notes[0].id, text: 'Test note 1.' });

await knex('grant_notes_revisions')
.insert({ grant_note_id: notes[1].id, text: 'Test note 2.' });
});

it('returns ALL notes for a given grant in DESC order', async () => {
const resp = await fetchApi(`/grants/${GRANT_ID}/notes`, agencies.own, fetchOptions.staff);
const respBody = await resp.json();

expect(respBody.notes.length).to.equal(2);
expect(respBody.notes[0].text).to.equal('Test note 2.');
});

it('returns notes with LIMIT', async () => {
const resp = await fetchApi(`/grants/${GRANT_ID}/notes?limit=1`, agencies.own, fetchOptions.staff);
const respBody = await resp.json();

expect(respBody.notes.length).to.equal(1);
});

it('returns 400 for invalid LIMIT', async () => {
const resp = await fetchApi(`/grants/${GRANT_ID}/notes?limit=500`, agencies.own, fetchOptions.staff);

expect(resp.status).to.equal(400);
});

it('returns notes with PAGINATION', async () => {
const resp = await fetchApi(`/grants/${GRANT_ID}/notes?paginateFrom=${notes[0].id}`, agencies.own, fetchOptions.staff);
const respBody = await resp.json();

expect(respBody.notes.length).to.equal(1);
expect(respBody.notes[0].text).to.equal('Test note 2.');
});
});
});
2 changes: 1 addition & 1 deletion packages/server/seeds/dev/01_main.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const globalCodes = [
];

exports.seed = async (knex) => {
const tables = ['agency_eligibility_codes', 'keywords', 'eligibility_codes', 'grants', 'assigned_grants_agency', 'grants_interested', 'grants_saved_searches'];
const tables = ['agency_eligibility_codes', 'grant_notes_revisions', 'grant_notes', 'keywords', 'eligibility_codes', 'grants', 'assigned_grants_agency', 'grants_interested', 'grants_saved_searches'];

// eslint-disable-next-line no-restricted-syntax
for (const table of tables) {
Expand Down
8 changes: 6 additions & 2 deletions packages/server/src/db/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const knex = require('./connection');
const { TABLES } = require('./constants');
const emailConstants = require('../lib/email/constants');
const { fundingActivityCategoriesByCode } = require('../lib/fieldConfigs/fundingActivityCategories');
const grantsCollaboration = require('../lib/grantsCollaboration');
Fixed Show fixed Hide fixed
const helpers = require('./helpers');

async function getUsers(tenantId) {
Expand Down Expand Up @@ -714,8 +715,6 @@ function addCsvData(qb) {
agencyId: number
*/
async function getGrantsNew(filters, paginationParams, orderingParams, tenantId, agencyId, toCsv) {
console.log(JSON.stringify([filters, paginationParams, orderingParams, tenantId, agencyId, toCsv]));

const errors = validateSearchFilters(filters);
if (errors.length > 0) {
throw new Error(`Invalid filters: ${errors.join(', ')}`);
Expand Down Expand Up @@ -1606,6 +1605,10 @@ function close() {
return knex.destroy();
}

function getOrganizationNotesForGrant(...args) {
return grantsCollaboration.getOrganizationNotesForGrant(knex, ...args);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be cleaner to skip this db/index.js file altogether and just import directly from the lib/grantsCollaboration module in src/routes/grants.js.

Suggested change
function getOrganizationNotesForGrant(...args) {
return grantsCollaboration.getOrganizationNotesForGrant(knex, ...args);
}

module.exports = {
knex,
createSavedSearch,
Expand Down Expand Up @@ -1667,6 +1670,7 @@ module.exports = {
markGrantAsInterested,
unmarkGrantAsInterested,
getGrantAssignedAgencies,
getOrganizationNotesForGrant,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(See above)

Suggested change
getOrganizationNotesForGrant,

assignGrantsToAgencies,
createAgency,
deleteAgency,
Expand Down
16 changes: 16 additions & 0 deletions packages/server/src/routes/grants.js
Original file line number Diff line number Diff line change
Expand Up @@ -422,4 +422,20 @@ router.delete('/:grantId/interested/:agencyId', requireUser, async (req, res) =>
res.json({});
});

router.get('/:grantId/notes', requireUser, async (req, res) => {
const { grantId } = req.params;
const { user } = req.session;
const { paginateFrom, limit } = req.query;
const limitInt = limit ? parseInt(limit, 10) : undefined;

if (limit && (!Number.isInteger(limitInt) || limitInt < 1 || limitInt > 100)) {
res.sendStatus(400);
return;
}

const rows = await db.getOrganizationNotesForGrant(grantId, user.tenant_id, { afterRevision: paginateFrom, limit: limitInt });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted in my db/index.js comments, I think it would be preferable to require('../lib/grantsCollaboration') in this file and call its exported getOrganizationNotesForGrant() function directly rather than going through the db module.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated!


res.json(rows);
});

module.exports = router;
Loading