diff --git a/apps/staff/src/WorkflowsStore/__fixtures__/index.ts b/apps/staff/src/WorkflowsStore/__fixtures__/index.ts index 59d2c5cd2..1ad5f6fa5 100644 --- a/apps/staff/src/WorkflowsStore/__fixtures__/index.ts +++ b/apps/staff/src/WorkflowsStore/__fixtures__/index.ts @@ -17,59 +17,125 @@ import { ClientRecord, - incarcerationStaffFixtures, IncarcerationStaffRecord, + incarcerationStaffRecordSchema, + makeRecordFixture, OpportunityType, outputFixtureArray, - supervisionStaffFixtures, SupervisionStaffRecord, + supervisionStaffRecordSchema, } from "~datatypes"; import { CombinedUserRecord, - isUserRecord, LocationRecord, UserRecord, WorkflowsResidentRecord, } from "../../FirestoreStore"; import { dateToTimestamp } from "../utils"; -const userInfoFixtures = outputFixtureArray(supervisionStaffFixtures).filter( - isUserRecord, - // asserting because despite the typeguard, TS can't seem to figure this one out -) as Array; +// INCARCERATION -export const mockOfficer: CombinedUserRecord = { - info: { - ...userInfoFixtures[0], +const incarcerationStaffTestFixtures: Array = [ + makeRecordFixture(incarcerationStaffRecordSchema, { + email: "test-officer-1@example.com", + id: "INCARCERATION_OFFICER1", stateCode: "US_XX", - hasCaseload: true, + givenNames: "TestIncarcerationOfficer1", + surname: "", + pseudonymizedId: "p001", + }), +]; + +export const mockIncarcerationOfficers: Array< + IncarcerationStaffRecord["output"] +> = outputFixtureArray(incarcerationStaffTestFixtures); + +export const mockResidents: WorkflowsResidentRecord[] = [ + { + recordId: "999", + personType: "RESIDENT", + admissionDate: "2023-03-23", + allEligibleOpportunities: ["usMeSCCP"], + custodyLevel: "MINIMUM", + facilityId: "MOUNTAIN VIEW CORRECTIONAL FACILITY", + officerId: "1", + stateCode: "US_ME", + gender: "MALE", + personName: { + givenNames: "Bernie", + surname: "Sanders", + }, + pseudonymizedId: "p999", + releaseDate: "2023-09-22", + unitId: "UNIT E", + personExternalId: "999", + displayId: "d999", + metadata: {}, }, -}; +]; -export const mockOfficer2: CombinedUserRecord = { - info: { - ...userInfoFixtures[1], +export const mockLocations: LocationRecord[] = [ + { + id: "FAC1", + stateCode: "US_MO", + idType: "facilityId", + name: "Facility 1", + system: "INCARCERATION", + }, + { + id: "FAC2", + stateCode: "US_MO", + idType: "facilityId", + name: "Facility 2", + system: "INCARCERATION", + }, +]; + +// SUPERVISION STAFF + +const supervisionStaffTestFixtures = [ + { + email: "test-officer-1@example.com", + district: "DISTRICT 1", + id: "XX_OFFICER1", stateCode: "US_XX", - hasCaseload: true, + givenNames: "TestOfficer", + surname: "AlphabeticallySecond", + supervisorExternalId: null, + pseudonymizedId: "p001", }, -}; + { + email: "test-officer-1@example.com", + district: "DISTRICT 1", + id: "XX_OFFICER2", + stateCode: "US_XX", + givenNames: "TestOfficer", + surname: "AlphabeticallyFirst", + supervisorExternalId: null, + pseudonymizedId: "p002", + }, +].map((r) => makeRecordFixture(supervisionStaffRecordSchema, r)); -export const mockSupervisor: CombinedUserRecord = { +export const mockSupervisionOfficers: Array = + outputFixtureArray(supervisionStaffTestFixtures); + +export const mockOfficer: CombinedUserRecord = { info: { - ...userInfoFixtures[2], - stateCode: "US_XX", - hasCaseload: false, + ...(mockSupervisionOfficers[0] as UserRecord), + hasCaseload: true, }, }; -export const mockSupervisor2: CombinedUserRecord = { +export const mockOfficer2: CombinedUserRecord = { info: { - ...userInfoFixtures.filter((user) => user.id === "SUPERVISOR1")[0], - hasCaseload: false, + ...(mockSupervisionOfficers[1] as UserRecord), + hasCaseload: true, }, }; +// CLIENTS + export const ineligibleClient: ClientRecord = { recordId: "us_xx_100", personName: { @@ -81,7 +147,7 @@ export const ineligibleClient: ClientRecord = { displayId: "d100", pseudonymizedId: "p100", stateCode: "US_XX", - officerId: "OFFICER1", + officerId: "XX_OFFICER1", supervisionType: "TN PAROLEE", supervisionLevel: "MEDIUM", supervisionLevelStart: new Date("2020-12-20"), @@ -140,7 +206,7 @@ export const eligibleClient: ClientRecord = { displayId: "d101", pseudonymizedId: "p101", stateCode: "US_XX", - officerId: "OFFICER1", + officerId: "XX_OFFICER1", supervisionType: "TN PROBATIONER", supervisionLevel: "MEDIUM", supervisionLevelStart: new Date("2019-12-20"), @@ -180,7 +246,7 @@ export const lsuEligibleClient: ClientRecord = { displayId: "d102", pseudonymizedId: "p102", stateCode: "US_XX", - officerId: "OFFICER1", + officerId: "XX_OFFICER1", supervisionType: "MISDEMEANOR PROBATIONER", supervisionLevel: "STANDARD: MINIMUM", supervisionLevelStart: new Date("2021-07-05"), @@ -220,7 +286,7 @@ export const lsuAlmostEligibleClient: ClientRecord = { displayId: "d103", pseudonymizedId: "p103", stateCode: "US_XX", - officerId: "OFFICER1", + officerId: "XX_OFFICER1", supervisionType: "MISDEMEANOR PROBATIONER", supervisionLevel: "STANDARD: MINIMUM", supervisionLevelStart: new Date("2021-07-05"), @@ -256,72 +322,33 @@ export const lsuAlmostEligibleClient: ClientRecord = { ], }; -export const milestonesClient: ClientRecord = { - ...eligibleClient, - recordId: "us_xx_104", - personName: { givenNames: "Mickey", surname: "Mouse" }, - personExternalId: "104", - displayId: "d104", - pseudonymizedId: "p104", -}; - export const mockClients = [ ineligibleClient, eligibleClient, lsuEligibleClient, ]; -export const mockResidents: WorkflowsResidentRecord[] = [ - { - recordId: "999", - personType: "RESIDENT", - admissionDate: "2023-03-23", - allEligibleOpportunities: ["usMeSCCP"], - custodyLevel: "MINIMUM", - facilityId: "MOUNTAIN VIEW CORRECTIONAL FACILITY", - officerId: "1", - stateCode: "US_ME", - gender: "MALE", - personName: { - givenNames: "Bernie", - surname: "Sanders", - }, - pseudonymizedId: "p999", - releaseDate: "2023-09-22", - unitId: "UNIT E", - personExternalId: "999", - displayId: "d999", - metadata: {}, - }, -]; +// SUPERVISORS -export const mockSupervisionOfficers: Array = - outputFixtureArray(supervisionStaffFixtures.slice(0, 2)); - -const mockSelectSupervisionOfficerFixtures: Array = - supervisionStaffFixtures.filter( - (staff) => staff.output.stateCode === "US_TN", - ); -export const mockSupervisionOfficers2: Array = - outputFixtureArray(mockSelectSupervisionOfficerFixtures); +export const mockSupervisor: CombinedUserRecord = { + info: { + email: "test-supervisor@example.com", + id: "XX_SUPERVISOR1", + stateCode: "US_XX", + givenNames: "TestSupervisorWithStaff", + surname: "", + pseudonymizedId: "s001", + recordType: "supervisionStaff", + }, +}; -export const mockIncarcerationOfficers: Array< - IncarcerationStaffRecord["output"] -> = outputFixtureArray(incarcerationStaffFixtures.slice(0, 2)); +// MILESTONES -export const mockLocations: LocationRecord[] = [ - { - id: "FAC1", - stateCode: "US_MO", - idType: "facilityId", - name: "Facility 1", - system: "INCARCERATION", - }, - { - id: "FAC2", - stateCode: "US_MO", - idType: "facilityId", - name: "Facility 2", - system: "INCARCERATION", - }, -]; +export const milestonesClient: ClientRecord = { + ...eligibleClient, + recordId: "us_xx_104", + personName: { givenNames: "Mickey", surname: "Mouse" }, + personExternalId: "104", + displayId: "d104", + pseudonymizedId: "p104", +}; diff --git a/apps/staff/src/WorkflowsStore/__tests__/WorkflowsStore.test.ts b/apps/staff/src/WorkflowsStore/__tests__/WorkflowsStore.test.ts index 17b3d9ed7..5faa59e34 100644 --- a/apps/staff/src/WorkflowsStore/__tests__/WorkflowsStore.test.ts +++ b/apps/staff/src/WorkflowsStore/__tests__/WorkflowsStore.test.ts @@ -21,9 +21,7 @@ import { IDisposer, keepAlive } from "mobx-utils"; import { ClientRecord, - incarcerationStaffFixtures, OpportunityType, - outputFixture, SupervisionStaffRecord, } from "~datatypes"; import { HydrationState } from "~hydration-utils"; @@ -32,7 +30,6 @@ import { mockOpportunityConfigs } from "../../core/__tests__/testUtils"; import { SystemId } from "../../core/models/types"; import FirestoreStore, { CombinedUserRecord, - isUserRecord, MilestonesMessage, TextMessageStatus, UserRecord, @@ -55,9 +52,7 @@ import { mockOfficer2, mockResidents, mockSupervisionOfficers, - mockSupervisionOfficers2, mockSupervisor, - mockSupervisor2, } from "../__fixtures__"; import { Client } from "../Client"; import { CompliantReportingOpportunity, LSUOpportunity } from "../Opportunity"; @@ -163,7 +158,6 @@ vi.mock("../../tenants", async (importOriginal) => ({ let rootStore: RootStore; let workflowsStore: WorkflowsStore; let testObserver: IDisposer; -let testUserData: UserRecord; function mockAuthedUser() { // mock successful authentication from Auth0 @@ -232,13 +226,6 @@ beforeEach(() => { runInAction(() => { workflowsStore.updateActiveSystem("SUPERVISION"); }); - - const staffFixture = outputFixture(incarcerationStaffFixtures[0]); - if (isUserRecord(staffFixture)) { - testUserData = { ...staffFixture }; - } else { - throw new Error("Invalid user data fixture"); - } }); afterEach(() => { @@ -292,7 +279,7 @@ test("hydration reflects subscriptions", async () => { expect(workflowsStore.hydrationState.status).toBe("needs hydration"); runInAction(() => { - workflowsStore.userSubscription.data = [testUserData]; + workflowsStore.userSubscription.data = [mockOfficer.info]; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion workflowsStore.userUpdatesSubscription!.hydrationState = { status: "hydrated", @@ -422,90 +409,231 @@ test("user data reflects subscriptions", async () => { expect(workflowsStore.user?.info).toEqual(mockOfficer.info); }); -test("caseload defaults to self", async () => { - await waitForHydration(); +const populateSupervisedStaff = () => { runInAction(() => { workflowsStore.updateActiveSystem("SUPERVISION"); + workflowsStore.supervisionStaffSubscription.data = [ + // two officers supervised by mockSupervisor, one supervised by someone else + { + id: "XX_SUPERVISED_OFFICER1", + stateCode: "US_XX", + givenNames: "TestSupervisedOfficer1", + surname: "AlphabeticallySecond", + supervisorExternalId: mockSupervisor.info.id, + pseudonymizedId: "p001", + recordType: "supervisionStaff", + }, + { + id: "XX_SUPERVISED_OFFICER2", + stateCode: "US_XX", + givenNames: "TestSupervisedOfficer2", + surname: "AlphabeticallyFirst", + supervisorExternalId: mockSupervisor.info.id, + pseudonymizedId: "p002", + recordType: "supervisionStaff", + }, + { + id: "XX_SUPERVISED_OFFICER3", + stateCode: "US_XX", + givenNames: "TestSupervisedOfficer3", + surname: "SupervisedBySomeoneElse", + supervisorExternalId: "XX_SUPERVISOR_OTHER", + pseudonymizedId: "p003", + recordType: "supervisionStaff", + }, + ]; }); - expect(workflowsStore.selectedSearchIds).toEqual([mockOfficer.info.id]); - expect(rootStore.analyticsStore.trackCaseloadSearch).toHaveBeenCalledWith({ - searchCount: 1, - isDefault: true, - searchType: "OFFICER", - }); -}); +}; -test("caseload defaults to no selected search if the user has no saved search and the state is not search-by-officer", async () => { - runInAction(() => { - rootStore.tenantStore.currentTenantId = "US_MO"; - workflowsStore.updateActiveSystem("INCARCERATION"); - }); - await waitForHydration(); - expect(workflowsStore.selectedSearchIds).toEqual([]); -}); +describe("selectedSearchIds", () => { + describe("for non-supervisors", () => { + test("defaults to self", async () => { + await waitForHydration(); + runInAction(() => { + workflowsStore.updateActiveSystem("SUPERVISION"); + }); + expect(workflowsStore.selectedSearchIds).toEqual([mockOfficer.info.id]); + expect(rootStore.analyticsStore.trackCaseloadSearch).toHaveBeenCalledWith( + { + searchCount: 1, + isDefault: true, + searchType: "OFFICER", + }, + ); + }); -test("caseload defaults to no selected search if user has no caseload and no saved search", async () => { - await waitForHydration(mockSupervisor); + test("defaults to no selected search if the user has no saved search and the state is not search-by-officer", async () => { + runInAction(() => { + // arbitrary state code; the only incarceration officers are in US_XX + rootStore.tenantStore.currentTenantId = "US_MO"; + workflowsStore.updateActiveSystem("INCARCERATION"); + }); + await waitForHydration(); + expect(workflowsStore.selectedSearchIds).toEqual([]); + }); - expect(workflowsStore.selectedSearchIds).toEqual([]); -}); + test("defaults to stored value", async () => { + const mockStoredOfficers = ["OFFICER1", "OFFICER3"]; -test("caseload defaults to stored value", async () => { - const mockStoredOfficers = ["OFFICER1", "OFFICER3"]; + await waitForHydration({ + ...mockOfficer, + updates: { + ...(mockOfficer.updates as UserUpdateRecord), + selectedSearchIds: mockStoredOfficers, + }, + }); - await waitForHydration({ - ...mockOfficer, - updates: { - ...(mockOfficer.updates as UserUpdateRecord), - selectedSearchIds: mockStoredOfficers, - }, - }); + expect(workflowsStore.selectedSearchIds).toEqual(mockStoredOfficers); + }); - expect(workflowsStore.selectedSearchIds).toEqual(mockStoredOfficers); -}); + test("defaults to stored value for states that are not search-by-officer", async () => { + runInAction(() => { + rootStore.tenantStore.currentTenantId = "US_MO"; + }); + const mockStoredLocations = ["LOC1", "LOC3"]; -test("caseload defaults to stored value for states that are not search-by-officer", async () => { - runInAction(() => { - rootStore.tenantStore.currentTenantId = "US_MO"; - }); - const mockStoredLocations = ["LOC1", "LOC3"]; + await waitForHydration({ + ...mockOfficer, + updates: { + ...(mockOfficer.updates as UserUpdateRecord), + selectedSearchIds: mockStoredLocations, + }, + }); - await waitForHydration({ - ...mockOfficer, - updates: { - ...(mockOfficer.updates as UserUpdateRecord), - selectedSearchIds: mockStoredLocations, - }, + expect(workflowsStore.selectedSearchIds).toEqual(mockStoredLocations); + }); + + test("default caseload does not override empty stored value", async () => { + await waitForHydration({ + ...mockOfficer, + updates: { + ...(mockOfficer.updates as UserUpdateRecord), + selectedSearchIds: [], + }, + }); + expect(workflowsStore.selectedSearchIds).toEqual([]); + }); + + test("caseload syncs with stored value changes", async () => { + const mockStoredOfficers = ["OFFICER1", "OFFICER3"]; + + await waitForHydration(); + + runInAction(() => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + rootStore.workflowsStore.userUpdatesSubscription!.data = { + stateCode: mockOfficer.info.stateCode, + selectedSearchIds: mockStoredOfficers, + }; + }); + + expect(workflowsStore.selectedSearchIds).toEqual(mockStoredOfficers); + }); + + test("reflects updated list after impersonated user makes new search updates", async () => { + // simulate an impersonated user + runInAction(() => { + rootStore.userStore.user = { + ...rootStore.userStore.user, + impersonator: true, + }; + + // impersonated users do not have write access to firebase + // so we patch the firebase write to a no-op + rootStore.firestoreStore.updateSelectedSearchIds = () => undefined; + }); + + await waitForHydration({ ...mockOfficer }); + + runInAction(() => { + workflowsStore.updateSelectedSearch(["OFFICER2"]); + }); + + expect(workflowsStore.selectedSearchIds).toEqual(["OFFICER2"]); + }); }); - expect(workflowsStore.selectedSearchIds).toEqual(mockStoredLocations); -}); + describe("for supervisors with no caseload", () => { + beforeEach(async () => { + setUser({ workflowsSupervisorSearch: {} }); + // without a caseload, this supervisor won't show up as a search id + await waitForHydration({ + ...mockSupervisor, + info: { ...(mockSupervisor.info as UserRecord), hasCaseload: false }, + }); + }); -test("default caseload does not override empty stored value", async () => { - await waitForHydration({ - ...mockOfficer, - updates: { - ...(mockOfficer.updates as UserUpdateRecord), - selectedSearchIds: [], - }, + test("defaults to no selected search if user has no supervised staff", async () => { + // no supervised people are populated + expect(workflowsStore.selectedSearchIds).toEqual([]); + }); + + test("defaults to current user's supervised staff", async () => { + populateSupervisedStaff(); + expect(workflowsStore.selectedSearchIds).toEqual([ + "XX_SUPERVISED_OFFICER2", + "XX_SUPERVISED_OFFICER1", + ]); + }); }); - expect(workflowsStore.selectedSearchIds).toEqual([]); -}); -test("caseload syncs with stored value changes", async () => { - const mockStoredOfficers = ["OFFICER1", "OFFICER3"]; + describe("for supervisors with a caseload", () => { + beforeEach(async () => { + setUser({ workflowsSupervisorSearch: {} }); + await waitForHydration({ + ...mockSupervisor, + info: { ...(mockSupervisor.info as UserRecord), hasCaseload: true }, + }); + populateSupervisedStaff(); + }); - await waitForHydration(); + test("includes current user", async () => { + expect(workflowsStore.selectedSearchIds).toEqual([ + "XX_SUPERVISOR1", + "XX_SUPERVISED_OFFICER2", + "XX_SUPERVISED_OFFICER1", + ]); + }); - runInAction(() => { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - rootStore.workflowsStore.userUpdatesSubscription!.data = { - stateCode: mockOfficer.info.stateCode, - selectedSearchIds: mockStoredOfficers, - }; + test("reflects updated list after user makes new search updates", async () => { + runInAction(() => { + // user deselects officers 1 and 2 + workflowsStore.updateSelectedSearch([ + workflowsStore.selectedSearchIds[0], + ]); + }); + + expect(workflowsStore.selectedSearchIds).toEqual(["XX_SUPERVISOR1"]); + + runInAction(() => { + // user reselects officer 1 + workflowsStore.updateSelectedSearch([ + ...workflowsStore.selectedSearchIds, + "XX_SUPERVISED_OFFICER1", + ]); + }); + + expect(workflowsStore.selectedSearchIds).toEqual([ + "XX_SUPERVISOR1", + "XX_SUPERVISED_OFFICER1", + ]); + }); }); +}); + +test("staffSupervisedByCurrentUser provides a list of users supervised by currently logged in user", async () => { + await waitForHydration(mockSupervisor); + populateSupervisedStaff(); + + const staffSupervisedByCurrentUser = + workflowsStore.staffSupervisedByCurrentUser; + const staffSupervisorExternalIds = staffSupervisedByCurrentUser.map( + (staff) => (staff as SupervisionStaffRecord["output"]).supervisorExternalId, + ); - expect(workflowsStore.selectedSearchIds).toEqual(mockStoredOfficers); + expect(staffSupervisedByCurrentUser).toBeArrayOfSize(2); + expect(staffSupervisorExternalIds[0]).toEqual(mockSupervisor.info.id); + expect(staffSupervisorExternalIds[1]).toEqual(mockSupervisor.info.id); }); describe("staffSubscription", () => { @@ -593,19 +721,19 @@ test("available searchables for search by officer", async () => { }, ); - expect(workflowsStore.availableSearchables.length).toBe(1); + expect(workflowsStore.availableSearchables).toBeArrayOfSize(1); expect(workflowsStore.availableSearchables[0].groupLabel).toBe( "All Officers", ); expect(actual).toMatchInlineSnapshot(` [ { - "searchId": "OFFICER1", - "searchLabel": "Maia Douglas", + "searchId": "XX_OFFICER2", + "searchLabel": "TestOfficer AlphabeticallyFirst", }, { - "searchId": "OFFICER2", - "searchLabel": "Eloise Rocha", + "searchId": "XX_OFFICER1", + "searchLabel": "TestOfficer AlphabeticallySecond", }, ] `); @@ -613,15 +741,12 @@ test("available searchables for search by officer", async () => { test("available searchables for search by officer when user has staff they supervise", async () => { setUser({ workflowsSupervisorSearch: {} }); - await waitForHydration(mockSupervisor2); + await waitForHydration(mockSupervisor); + populateSupervisedStaff(); - runInAction(() => { - workflowsStore.updateActiveSystem("SUPERVISION"); - workflowsStore.incarcerationStaffSubscription.data = - mockIncarcerationOfficers; - workflowsStore.supervisionStaffSubscription.data = mockSupervisionOfficers2; - workflowsStore.locationsSubscription.data = mockLocations; - }); + expect(workflowsStore.availableSearchables).toBeArrayOfSize(2); + expect(workflowsStore.availableSearchables[0].groupLabel).toBe("Your Team"); + expect(workflowsStore.availableSearchables[1].groupLabel).toBe("All Staff"); const yourTeamSearchableIds = workflowsStore.availableSearchables[0].searchables.map( @@ -632,12 +757,12 @@ test("available searchables for search by officer when user has staff they super (officer) => officer.searchId, ); - expect(workflowsStore.availableSearchables.length).toBe(2); - expect(workflowsStore.availableSearchables[0].groupLabel).toBe("Your Team"); - expect(workflowsStore.availableSearchables[1].groupLabel).toBe("All Staff"); - // alphabetically, Eloise (Officer2) comes before Maia (Officer1) - expect(yourTeamSearchableIds).toEqual(["OFFICER2", "OFFICER1"]); - expect(allStaffSearchableIds).toEqual(["OFFICER3"]); + // alphabetically, Officer2 comes before Officer1 + expect(yourTeamSearchableIds).toEqual([ + "XX_SUPERVISED_OFFICER2", + "XX_SUPERVISED_OFFICER1", + ]); + expect(allStaffSearchableIds).toEqual(["XX_SUPERVISED_OFFICER3"]); }); test("available searchables for search by location", async () => { @@ -791,7 +916,7 @@ test("setting overrideDistrictIds in UserUpdates overrides user district", async test("setting overrideDistrictIds in UserUpdates overrides undefined workflowsStaffFilterFn", async () => { runInAction(() => { - rootStore.tenantStore.currentTenantId = "US_YY" as any; + rootStore.tenantStore.currentTenantId = "US_XX" as any; }); const myOfficer = { ...mockOfficer }; @@ -1400,128 +1525,3 @@ describe("user data observer", () => { expect(workflowsStore.userKeepAliveDisposer).toBeUndefined(); }); }); - -test("staffSupervisedByCurrentUser provides a list of users supervised by currently logged in user", async () => { - const mockSupervisorID = "SUPERVISOR1"; - const customMockSupervisor = { - info: { ...mockSupervisor.info, id: mockSupervisorID }, - }; - await waitForHydration({ ...customMockSupervisor }); - runInAction(() => { - workflowsStore.updateActiveSystem("SUPERVISION"); - workflowsStore.supervisionStaffSubscription.data = mockSupervisionOfficers2; - }); - - const staffSupervisedByCurrentUser = - workflowsStore.staffSupervisedByCurrentUser; - const staffSupervisorExternalIds = staffSupervisedByCurrentUser.map( - (staff) => (staff as SupervisionStaffRecord["output"]).supervisorExternalId, - ); - - expect(staffSupervisedByCurrentUser.length).toEqual(2); - expect(staffSupervisorExternalIds[0]).toEqual(mockSupervisorID); - expect(staffSupervisorExternalIds[1]).toEqual(mockSupervisorID); -}); - -test("caseload (`selectedSearchIds`) default to current user's supervised staff (if user is supervisor with at least one staff) after login", async () => { - setUser({ workflowsSupervisorSearch: {} }); - await waitForHydration({ - ...mockSupervisor2, // this supervisor does not have a caseload - updates: { stateCode: "US_TN" }, - }); - - runInAction(() => { - workflowsStore.updateActiveSystem("SUPERVISION"); - workflowsStore.supervisionStaffSubscription.data = mockSupervisionOfficers2; - }); - - // Eloise (2) before Maia (1) - expect(workflowsStore.selectedSearchIds).toEqual(["OFFICER2", "OFFICER1"]); -}); - -test("caseload (`selectedSearchIds`) reflects updated list after user with supervised staff makes new search updates", async () => { - setUser({ workflowsSupervisorSearch: {} }); - await waitForHydration({ - ...mockSupervisor2, - updates: { stateCode: "US_TN" }, - info: { - ...mockSupervisor2.info, - hasCaseload: true, - }, - }); - - runInAction(() => { - workflowsStore.updateActiveSystem("SUPERVISION"); - workflowsStore.supervisionStaffSubscription.data = mockSupervisionOfficers2; - }); - - expect(workflowsStore.selectedSearchIds).toEqual([ - "SUPERVISOR1", - // Eloise (2) before Maia (1) - "OFFICER2", - "OFFICER1", - ]); - - runInAction(() => { - // user deselects OFFICER1 and OFFICER2 - workflowsStore.updateSelectedSearch([workflowsStore.selectedSearchIds[0]]); - }); - - expect(workflowsStore.selectedSearchIds).toEqual(["SUPERVISOR1"]); - - runInAction(() => { - // user reselects OFFICER1 - workflowsStore.updateSelectedSearch([ - ...workflowsStore.selectedSearchIds, - "OFFICER1", - ]); - }); - - expect(workflowsStore.selectedSearchIds).toEqual(["SUPERVISOR1", "OFFICER1"]); -}); - -test("caseload (`selectedSearchIds`) include current user's caseload if current user has caseloads", async () => { - setUser({ workflowsSupervisorSearch: {} }); - await waitForHydration({ - ...mockSupervisor2, - updates: { stateCode: "US_TN" }, - info: { - ...mockSupervisor2.info, - hasCaseload: true, - }, - }); - - runInAction(() => { - workflowsStore.updateActiveSystem("SUPERVISION"); - workflowsStore.supervisionStaffSubscription.data = mockSupervisionOfficers2; - }); - - expect(workflowsStore.selectedSearchIds).toEqual([ - "SUPERVISOR1", - // Eloise (2) before Maia (1) - "OFFICER2", - "OFFICER1", - ]); -}); - -test("caseload (`selectedSearchIds`) reflects updated list after impersonated user makes new search updates", async () => { - // simulate an impersonated user - runInAction(() => { - rootStore.userStore.user = { - ...rootStore.userStore.user, - impersonator: true, - }; - - // impersonated users do not have write access to firebase - // so we patch the firebase write to a no-op - rootStore.firestoreStore.updateSelectedSearchIds = () => undefined; - }); - - await waitForHydration({ ...mockOfficer }); - - runInAction(() => { - workflowsStore.updateSelectedSearch(["OFFICER2"]); - }); - - expect(workflowsStore.selectedSearchIds).toEqual(["OFFICER2"]); -}); diff --git a/apps/staff/tools/fixtures/locations.ts b/apps/staff/tools/fixtures/locations.ts index 126562453..eedaaaf8d 100644 --- a/apps/staff/tools/fixtures/locations.ts +++ b/apps/staff/tools/fixtures/locations.ts @@ -71,14 +71,14 @@ const data: LocationRecord[] = [ system: "INCARCERATION", idType: "facilityId", id: "FACILITY1", - name: "TEST FACILITY 1", + name: "Facility #1", }, { stateCode: "US_MI", system: "INCARCERATION", idType: "facilityId", id: "FACILITY2", - name: "TEST FACILITY 2", + name: "Facility #2", }, // diff --git a/apps/staff/tools/fixtures/residents/usMoResidents.ts b/apps/staff/tools/fixtures/residents/usMoResidents.ts index 260ab7992..fc187e166 100644 --- a/apps/staff/tools/fixtures/residents/usMoResidents.ts +++ b/apps/staff/tools/fixtures/residents/usMoResidents.ts @@ -29,7 +29,7 @@ export const usMoResidents: ResidentFixture[] = [ }, gender: "MALE", pseudonymizedId: "anonres007", - facilityId: "FACILITY2", + facilityId: "FACILITY1", unitId: "UNIT E", custodyLevel: "MINIMUM", // Resident record query doesn't currently write start/end dates for MO @@ -63,7 +63,7 @@ export const usMoResidents: ResidentFixture[] = [ }, gender: "MALE", pseudonymizedId: "anonres009", - facilityId: "FACILITY2", + facilityId: "FACILITY1", unitId: "UNIT G", custodyLevel: "MINIMUM", // Resident record query doesn't currently write start/end dates for MO @@ -97,7 +97,7 @@ export const usMoResidents: ResidentFixture[] = [ }, gender: "FEMALE", pseudonymizedId: "anonres011", - facilityId: "FACILITY2", + facilityId: "FACILITY1", unitId: "UNIT E", custodyLevel: "MINIMUM", // Resident record query doesn't currently write start/end dates for MO @@ -131,7 +131,7 @@ export const usMoResidents: ResidentFixture[] = [ }, gender: "MALE", pseudonymizedId: "anonres013", - facilityId: "FACILITY2", + facilityId: "FACILITY1", unitId: "UNIT G", custodyLevel: "MINIMUM", // Resident record query doesn't currently write start/end dates for MO @@ -165,7 +165,7 @@ export const usMoResidents: ResidentFixture[] = [ }, gender: "MALE", pseudonymizedId: "anonres015", - facilityId: "FACILITY2", + facilityId: "FACILITY1", unitId: "UNIT E", custodyLevel: "MINIMUM", // Resident record query doesn't currently write start/end dates for MO @@ -199,7 +199,7 @@ export const usMoResidents: ResidentFixture[] = [ }, gender: "MALE", pseudonymizedId: "anonres017", - facilityId: "FACILITY2", + facilityId: "FACILITY1", unitId: "UNIT G", custodyLevel: "MINIMUM", // Resident record query doesn't currently write start/end dates for MO diff --git a/libs/datatypes/src/people/Staff/Incarceration/Workflows/__snapshots__/schema.test.ts.snap b/libs/datatypes/src/people/Staff/Incarceration/Workflows/__snapshots__/schema.test.ts.snap index 5aedbdf13..87fc4e823 100644 --- a/libs/datatypes/src/people/Staff/Incarceration/Workflows/__snapshots__/schema.test.ts.snap +++ b/libs/datatypes/src/people/Staff/Incarceration/Workflows/__snapshots__/schema.test.ts.snap @@ -36,18 +36,6 @@ exports[`incarceration staff schema for 'US_AZ' 'OFFICER3' 1`] = ` } `; -exports[`incarceration staff schema for 'US_ID' 'OFFICER6' 1`] = ` -{ - "email": "test-officer-6@example.com", - "givenNames": "Ross", - "id": "OFFICER6", - "pseudonymizedId": "p006", - "recordType": "incarcerationStaff", - "stateCode": "US_ID", - "surname": "Moyer", -} -`; - exports[`incarceration staff schema for 'US_ME' 'OFFICER5' 1`] = ` { "email": "test-officer-5@example.com", diff --git a/libs/datatypes/src/people/Staff/Incarceration/Workflows/fixture.ts b/libs/datatypes/src/people/Staff/Incarceration/Workflows/fixture.ts index 5b2b00b9d..ee6acc808 100644 --- a/libs/datatypes/src/people/Staff/Incarceration/Workflows/fixture.ts +++ b/libs/datatypes/src/people/Staff/Incarceration/Workflows/fixture.ts @@ -21,6 +21,7 @@ import { incarcerationStaffRecordSchema, } from "./schema"; +/* These fixtures are used for Workflows Demo Mode and Offline Mode. */ export const incarcerationStaffFixtures: Array = [ // US_AZ - ARIZONA { @@ -47,15 +48,6 @@ export const incarcerationStaffFixtures: Array = [ surname: "Vang", pseudonymizedId: "p003", }, - // US_ID - IDAHO - { - email: "test-officer-6@example.com", - id: "OFFICER6", - stateCode: "US_ID", - givenNames: "Ross", - surname: "Moyer", - pseudonymizedId: "p006", - }, // US_ME - MAINE { diff --git a/libs/datatypes/src/people/Staff/Supervision/Workflows/__snapshots__/schema.test.ts.snap b/libs/datatypes/src/people/Staff/Supervision/Workflows/__snapshots__/schema.test.ts.snap index ecf7e1cff..2b92e8947 100644 --- a/libs/datatypes/src/people/Staff/Supervision/Workflows/__snapshots__/schema.test.ts.snap +++ b/libs/datatypes/src/people/Staff/Supervision/Workflows/__snapshots__/schema.test.ts.snap @@ -14,20 +14,6 @@ exports[`supervision staff schema for 'US_CA' 'OFFICER1' 1`] = ` } `; -exports[`supervision staff schema for 'US_CA' 'OFFICER2' 1`] = ` -{ - "district": "DISTRICT 1", - "email": "test-officer-1@example.com", - "givenNames": "Eloise", - "id": "OFFICER2", - "pseudonymizedId": "p002", - "recordType": "supervisionStaff", - "stateCode": "US_CA", - "supervisorExternalId": null, - "surname": "Rocha", -} -`; - exports[`supervision staff schema for 'US_ID' 'OFFICER4' 1`] = ` { "district": "DISTRICT 1", @@ -166,40 +152,12 @@ exports[`supervision staff schema for 'US_TN' 'OFFICER2' 1`] = ` { "district": "DISTRICT 50", "email": null, - "givenNames": "Hollie", + "givenNames": "Raihan", "id": "OFFICER2", "pseudonymizedId": "p002", "recordType": "supervisionStaff", "stateCode": "US_TN", "supervisorExternalId": "SUPERVISOR1", - "surname": "Monroe", -} -`; - -exports[`supervision staff schema for 'US_TN' 'OFFICER3' 1`] = ` -{ - "district": "DISTRICT 50", - "email": null, - "givenNames": "Luis", - "id": "OFFICER3", - "pseudonymizedId": "p003", - "recordType": "supervisionStaff", - "stateCode": "US_TN", - "supervisorExternalId": null, - "surname": "Levy", -} -`; - -exports[`supervision staff schema for 'US_TN' 'SUPERVISOR1' 1`] = ` -{ - "district": "DISTRICT 50", - "email": "test-supervisor@example.com", - "givenNames": "Raihan", - "id": "SUPERVISOR1", - "pseudonymizedId": "p001", - "recordType": "supervisionStaff", - "stateCode": "US_TN", - "supervisorExternalId": null, "surname": "Phelpa", } `; diff --git a/libs/datatypes/src/people/Staff/Supervision/Workflows/fixture.ts b/libs/datatypes/src/people/Staff/Supervision/Workflows/fixture.ts index 5024151e9..1288c314d 100644 --- a/libs/datatypes/src/people/Staff/Supervision/Workflows/fixture.ts +++ b/libs/datatypes/src/people/Staff/Supervision/Workflows/fixture.ts @@ -18,6 +18,8 @@ import { makeRecordFixture } from "../../../../utils/zod/object/makeRecordFixture"; import { SupervisionStaffRecord, supervisionStaffRecordSchema } from "./schema"; +/* These Idaho fixtures are used for Workflows in Demo Mode and Offline Mode, + as well as for Demo Mode and tests for various parts of Insights. */ export const usIdSupervisionStaffFixtures: Array< SupervisionStaffRecord["input"] > = [ @@ -43,6 +45,7 @@ export const usIdSupervisionStaffFixtures: Array< }, ]; +/* These fixtures are used for Workflows Demo Mode and Offline Mode. */ export const supervisionStaffFixtures: Array = [ // US_CA - CALIFORNIA { @@ -55,16 +58,6 @@ export const supervisionStaffFixtures: Array = [ supervisorExternalId: "SUPERVISOR1", pseudonymizedId: "p001", }, - { - email: "test-officer-1@example.com", - district: "DISTRICT 1", - id: "OFFICER2", - stateCode: "US_CA", - givenNames: "Eloise", - surname: "Rocha", - supervisorExternalId: null, - pseudonymizedId: "p002", - }, // US_ID - IDAHO ...usIdSupervisionStaffFixtures, @@ -158,29 +151,9 @@ export const supervisionStaffFixtures: Array = [ district: "DISTRICT 50", id: "OFFICER2", stateCode: "US_TN", - givenNames: "Hollie", - surname: "Monroe", - supervisorExternalId: "SUPERVISOR1", - pseudonymizedId: "p002", - }, - { - email: "test-supervisor@example.com", - district: "DISTRICT 50", - id: "SUPERVISOR1", - stateCode: "US_TN", givenNames: "Raihan", surname: "Phelpa", - supervisorExternalId: null, - pseudonymizedId: "p001", - }, - { - email: null, - district: "DISTRICT 50", - id: "OFFICER3", - stateCode: "US_TN", - givenNames: "Luis", - surname: "Levy", - supervisorExternalId: null, - pseudonymizedId: "p003", + supervisorExternalId: "SUPERVISOR1", + pseudonymizedId: "p002", }, ].map((r) => makeRecordFixture(supervisionStaffRecordSchema, r));