Skip to content

Commit

Permalink
fix: export lottery with sorted preferences by ordinal (#4464)
Browse files Browse the repository at this point in the history
* fix: export lottery with sorted preferences by ordinal

* feat: ensure the preferences ordinals are coming from the particular listing

* test: add a unit test for listing preferences sorted by ordinal

* chore: add comments above method definition
  • Loading branch information
jaredcwhite authored Dec 5, 2024
1 parent e836da8 commit e415120
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 6 deletions.
51 changes: 45 additions & 6 deletions api/src/services/application-exporter.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { join } from 'path';
import { view } from './application.service';
import { Application } from '../dtos/applications/application.dto';
import { ApplicationCsvQueryParams } from '../dtos/applications/application-csv-query-params.dto';
import { MultiselectQuestion } from '../dtos/multiselect-questions/multiselect-question.dto';
import { ApplicationMultiselectQuestion } from '../dtos/applications/application-multiselect-question.dto';
import { IdDTO } from '../dtos/shared/id.dto';
import { User } from '../dtos/users/user.dto';
Expand Down Expand Up @@ -464,18 +465,18 @@ export class ApplicationExporterService {
);

if (forLottery) {
const preferences = multiSelectQuestions.filter(
(question) =>
question.applicationSection ===
MultiselectQuestionsApplicationSectionEnum.preferences,
const sortedPreferences = await this.sortPreferencesByOrdinal(
multiSelectQuestions,
queryParams.id,
);
for (const preference of preferences) {

for (const preference of sortedPreferences) {
await this.generateSpreadsheetData(
workbook,
mappedApps,
columns,
queryParams,
forLottery,
true,
{
id: preference.id,
name: preference.text,
Expand Down Expand Up @@ -718,6 +719,44 @@ export class ApplicationExporterService {
return res;
}

/**
*
* @param questions a collection of questions which can include more than preferences, the rest will be filtered out
* @param listingId the id of the listing
* @returns listing preferences sorted in ordinal order
*/
async sortPreferencesByOrdinal(
questions: MultiselectQuestion[],
listingId: string,
) {
const preferences = questions.filter(
(question) =>
question.applicationSection ===
MultiselectQuestionsApplicationSectionEnum.preferences,
);

// pull in the preference questions by ordinal
const listingPreferencesByOrdinal =
await this.prisma.listingMultiselectQuestions.findMany({
where: {
listingId: listingId,
multiselectQuestionId: {
in: [...preferences.map((preference) => preference.id)],
},
},
orderBy: {
ordinal: 'asc',
},
});

// get a sorted list of preferences via listing preference ordinal
return listingPreferencesByOrdinal.map((item) =>
preferences.find(
(preference) => preference.id === item.multiselectQuestionId,
),
);
}

// shared functions
/**
*
Expand Down
53 changes: 53 additions & 0 deletions api/test/unit/services/application-exporter.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Request as ExpressRequest, Response } from 'express';
import { PrismaService } from '../../../src/services/prisma.service';
import { ApplicationCsvQueryParams } from '../../../src/dtos/applications/application-csv-query-params.dto';
import { User } from '../../../src/dtos/users/user.dto';
import MultiselectQuestion from '../../../src/dtos/multiselect-questions/multiselect-question.dto';
import { ApplicationExporterService } from '../../../src/services/application-exporter.service';
import { MultiselectQuestionService } from '../../../src/services/multiselect-question.service';
import { mockApplicationSet } from './application.service.spec';
Expand Down Expand Up @@ -381,4 +382,56 @@ describe('Testing application export service', () => {

expect(readable).toContain('EST');
});

it('should sort listing preferences by ordinal', async () => {
jest.useFakeTimers();
jest.setSystemTime(new Date('2024-01-01'));

const unsortedPreferences = [
{
...mockMultiselectQuestion(
0,
new Date(),
MultiselectQuestionsApplicationSectionEnum.preferences,
),
},
{
...mockMultiselectQuestion(
1,
new Date(),
MultiselectQuestionsApplicationSectionEnum.preferences,
),
},
{
...mockMultiselectQuestion(
2,
new Date(),
MultiselectQuestionsApplicationSectionEnum.programs,
),
options: [{ id: 1, text: 'text' }],
},
] as MultiselectQuestion[];

const listingId = randomUUID();

prisma.listingMultiselectQuestions.findMany = jest.fn().mockReturnValue([
{
listingId,
multiselectQuestionId: unsortedPreferences[1].id,
ordinal: 1,
},
{
listingId,
multiselectQuestionId: unsortedPreferences[0].id,
ordinal: 2,
},
]);

const sortedPreferences = await service.sortPreferencesByOrdinal(
unsortedPreferences,
listingId,
);
expect(sortedPreferences[0].text).toEqual('text 1');
expect(sortedPreferences[1].text).toEqual('text 0');
});
});

0 comments on commit e415120

Please sign in to comment.