Skip to content

Commit 1b32faa

Browse files
authored
Merge pull request DouglasNeuroInformatics#1519 from DouglasNeuroInformatics/fix/demo-mode-accessible-instruments
fix(api): connect uploaded instruments when a group is created
2 parents e869a55 + 5b866a5 commit 1b32faa

3 files changed

Lines changed: 37 additions & 7 deletions

File tree

apps/api/src/groups/__tests__/groups.service.spec.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,15 @@ describe('GroupsService', () => {
4242
expect(groupModel.create.mock.lastCall?.[0]).toMatchObject({ data: { name: 'Test Group' } });
4343
});
4444

45-
it('should connect only shared non-repo instruments', async () => {
45+
it('should connect only shared non-repo instruments, matching an absent field as well as a null one, so an uploaded instrument is not skipped', async () => {
4646
instrumentModel.findMany.mockResolvedValueOnce([{ id: 'manual-1' }, { id: 'manual-2' }]);
4747
await groupsService.create({ name: 'Test Group', type: 'CLINICAL' });
4848
expect(instrumentModel.findMany).toHaveBeenCalledWith({
4949
where: {
50-
OR: [{ seriesGroupId: null }, { seriesGroupId: { isSet: false } }],
51-
sourceRepoId: null
50+
AND: [
51+
{ OR: [{ seriesGroupId: null }, { seriesGroupId: { isSet: false } }] },
52+
{ OR: [{ sourceRepoId: null }, { sourceRepoId: { isSet: false } }] }
53+
]
5254
}
5355
});
5456
expect(groupModel.create.mock.lastCall?.[0]).toMatchObject({

apps/api/src/groups/groups.service.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,16 @@ export class GroupsService {
2525
}
2626
// Connect only instruments that did not come from an instrument repository. Repo-sourced
2727
// instruments are opt-in: a group manager must select them manually after a repo is assigned.
28+
//
29+
// Both fields need the `isSet` fallback: `InstrumentsService.create` writes neither, so on an
30+
// instrument that was never imported from a repository the key is absent rather than null, and
31+
// Prisma's `null` filter does not match an absent key.
2832
const nonRepoInstruments = await this.instrumentModel.findMany({
2933
where: {
30-
OR: [{ seriesGroupId: null }, { seriesGroupId: { isSet: false } }],
31-
sourceRepoId: null
34+
AND: [
35+
{ OR: [{ seriesGroupId: null }, { seriesGroupId: { isSet: false } }] },
36+
{ OR: [{ sourceRepoId: null }, { sourceRepoId: { isSet: false } }] }
37+
]
3238
}
3339
});
3440
return this.groupModel.create({

testing/src/specs/group-manage.spec.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,25 @@ import { GroupManagePage } from '../pages/_app/group/manage.page';
22
import { expect, test } from '../support/fixtures';
33

44
test.describe('group manage', () => {
5+
test('should give a newly created group access to every uploaded instrument, so a manager has something to administer', async ({
6+
adminToken,
7+
apiRequestContext,
8+
uniqueId
9+
}) => {
10+
// Deliberately not the `api.createGroup` fixture: that helper PATCHes the accessible instruments
11+
// in after creating the group, so it passes whether or not creation connected anything itself.
12+
// An uploaded instrument has no `sourceRepoId` key at all, and the selection query has to match
13+
// that as well as an explicit null.
14+
const response = await apiRequestContext.post('/api/v1/groups', {
15+
data: { name: `RawGroup${uniqueId}`, type: 'CLINICAL' },
16+
headers: { Authorization: `Bearer ${adminToken}` }
17+
});
18+
expect(response.status()).toBe(201);
19+
20+
const group = (await response.json()) as { accessibleInstrumentIds: string[] };
21+
expect(group.accessibleInstrumentIds.length).toBeGreaterThan(0);
22+
});
23+
524
test('should let a group manager preview an accessible instrument', async ({ getPageModel }) => {
625
const groupManagePage = await getPageModel('/group/manage');
726

@@ -31,8 +50,11 @@ test.describe('group manage', () => {
3150
await expect(page).toHaveURL('/group/manage');
3251

3352
const groupManagePage = new GroupManagePage(page);
34-
// A freshly created group has every non-repo instrument accessible already, so uncheck one to
35-
// produce an observable, reversible change.
53+
// `api.createGroup` grants access to every instrument, so uncheck one to produce an observable,
54+
// reversible change. Assert it starts checked first: `uncheck()` is a no-op on an already-
55+
// unchecked box, so without this the rest of the test would still pass if the precondition
56+
// silently stopped holding.
57+
await expect(groupManagePage.instrumentCheckbox('Happiness Questionnaire')).toBeChecked();
3658
await groupManagePage.instrumentCheckbox('Happiness Questionnaire').uncheck();
3759
await groupManagePage.subjectIdDisplayLengthInput.fill('6');
3860
await groupManagePage.submitButton.click();

0 commit comments

Comments
 (0)