Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/reports/sfdc/sfdc-reports.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ import {
import { SfdcReportsController } from "./sfdc-reports.controller";
import { SfdcReportsService } from "./sfdc-reports.service";
import {
mockChallengeData,
mockChallengeQueryDto,
mockBaFeesData,
mockBaFeesQueryDto,
mockPaymentData,
mockPaymentQueryDto,
normalizedChallengeData,
normalizedPaymentData,
mockTaasJobsData,
mockTaasJobsQueryDto,
mockTaasMemberVerificationData,
Expand Down Expand Up @@ -71,7 +71,7 @@ describe("SfdcReportsController", () => {

it("returns the challenges report on success", async () => {
mockSfdcReportsService.getChallengesReport.mockResolvedValue(
mockChallengeData,
normalizedChallengeData,
);

const result = await controller.getChallengesReport(
Expand All @@ -81,7 +81,7 @@ describe("SfdcReportsController", () => {
expect(mockSfdcReportsService.getChallengesReport).toHaveBeenCalledWith(
mockChallengeQueryDto.billingAccount,
);
expect(result).toEqual(mockChallengeData);
expect(result).toEqual(normalizedChallengeData);
});

it("returns an empty array when no results are found", async () => {
Expand Down Expand Up @@ -129,7 +129,7 @@ describe("SfdcReportsController", () => {
describe("getPaymentsReport", () => {
it("returns the payments report on success", async () => {
mockSfdcReportsService.getPaymentsReport.mockResolvedValue(
mockPaymentData,
normalizedPaymentData,
);

const result = await controller.getPaymentsReport(
Expand All @@ -139,7 +139,7 @@ describe("SfdcReportsController", () => {
expect(mockSfdcReportsService.getPaymentsReport).toHaveBeenCalledWith(
mockPaymentQueryDto.billingAccount,
);
expect(result).toEqual(mockPaymentData);
expect(result).toEqual(normalizedPaymentData);
});

it("returns an empty array when no results are found", async () => {
Expand Down
6 changes: 4 additions & 2 deletions src/reports/sfdc/sfdc-reports.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
mockBaFeesQueryDto,
mockPaymentData,
mockPaymentQueryDto,
normalizedChallengeData,
normalizedPaymentData,
mockSqlQuery,
mockTaasJobsData,
mockTaasJobsQueryDto,
Expand Down Expand Up @@ -81,7 +83,7 @@ describe("SfdcReportsService - getChallengesReport", () => {
undefined,
undefined,
]);
expect(result).toEqual(mockChallengeData);
expect(result).toEqual(normalizedChallengeData);
});

it("runs a challengeId query successfully", async () => {
Expand Down Expand Up @@ -315,7 +317,7 @@ describe("SfdcReportsService - getPaymentsReport", () => {
undefined,
undefined,
]);
expect(result).toEqual(mockPaymentData);
expect(result).toEqual(normalizedPaymentData);
});

it("splits include/exclude billing account filters", async () => {
Expand Down
11 changes: 9 additions & 2 deletions src/reports/sfdc/sfdc-reports.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
} from "./sfdc-reports.dto";
import { SqlLoaderService } from "src/common/sql-loader.service";
import { multiValueArrayFilter } from "src/common/filtering";
import { normalizeChallengeStatus } from "./status-normalizer";

@Injectable()
export class SfdcReportsService {
Expand Down Expand Up @@ -96,7 +97,10 @@ export class SfdcReportsService {

this.logger.debug("Mapped challenges to the final report format");

return challenges;
return challenges.map((challenge) => ({
...challenge,
challengeStatus: normalizeChallengeStatus(challenge.challengeStatus),

Choose a reason for hiding this comment

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

[⚠️ correctness]
Ensure that normalizeChallengeStatus handles all possible values of challenge.challengeStatus correctly. If there are any unexpected values, consider adding a default case or error handling to avoid potential runtime issues.

}));
}

async getPaymentsReport(filters: PaymentsReportQueryDto) {
Expand All @@ -122,7 +126,10 @@ export class SfdcReportsService {

this.logger.debug("Mapped payments to the final report format");

return payments;
return payments.map((payment) => ({
...payment,
challengeStatus: normalizeChallengeStatus(payment.challengeStatus),

Choose a reason for hiding this comment

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

[⚠️ correctness]
Verify that normalizeChallengeStatus can handle all possible values of payment.challengeStatus. Consider adding validation or error handling for unexpected values to prevent potential issues.

}));
}

async getTaasJobsReport(filters: TaasJobsReportQueryDto) {
Expand Down
28 changes: 28 additions & 0 deletions src/reports/sfdc/status-normalizer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const CHALLENGE_STATUS_LABELS: Record<string, string> = {
NEW: "New",
DRAFT: "Draft",
APPROVED: "Approved",
ACTIVE: "Active",
COMPLETED: "Completed",
DELETED: "Deleted",
CANCELLED: "Cancelled",
CANCELLED_FAILED_REVIEW: "Cancelled - Failed Review",
CANCELLED_FAILED_SCREENING: "Cancelled - Failed Screening",
CANCELLED_ZERO_SUBMISSIONS: "Cancelled - Zero Submissions",
CANCELLED_WINNER_UNRESPONSIVE: "Cancelled - Winner Unresponsive",
CANCELLED_CLIENT_REQUEST: "Cancelled - Client Request",
CANCELLED_REQUIREMENTS_INFEASIBLE: "Cancelled - Requirements Infeasible",
CANCELLED_ZERO_REGISTRATIONS: "Cancelled - Zero Registrations",
CANCELLED_PAYMENT_FAILED: "Cancelled - Payment Failed",
};

export const normalizeChallengeStatus = (
status: string | null | undefined,
): string | null | undefined => {
if (status === null || status === undefined) return status;

Choose a reason for hiding this comment

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

[💡 style]
Consider using status == null instead of status === null || status === undefined for a more concise check for both null and undefined.

const trimmed = String(status).trim();

Choose a reason for hiding this comment

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

[💡 readability]
The conversion String(status) is unnecessary here since status is already a string type due to the function signature. Consider removing it for clarity.

if (!trimmed) return status;

Choose a reason for hiding this comment

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

[⚠️ correctness]
Returning status here might be misleading because status could be a string with only whitespace. Consider returning null or undefined explicitly to indicate an invalid or empty status.

const normalized = CHALLENGE_STATUS_LABELS[trimmed.toUpperCase()];

return normalized ?? status;
};
13 changes: 13 additions & 0 deletions src/reports/sfdc/test-helpers/mock-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
WesternUnionPaymentsReportQueryDto,
WesternUnionPaymentsReportResponse,
} from "../sfdc-reports.dto";
import { normalizeChallengeStatus } from "../status-normalizer";

export const mockChallengeData: ChallengesReportResponse[] = [
{
Expand Down Expand Up @@ -154,6 +155,18 @@ export const mockPaymentQueryDto: Record<string, PaymentsReportQueryDto> = {
},
};

export const normalizedChallengeData = mockChallengeData.map((challenge) => ({
...challenge,
challengeStatus: normalizeChallengeStatus(
challenge.challengeStatus,
) as string,
}));

export const normalizedPaymentData = mockPaymentData.map((payment) => ({
...payment,
challengeStatus: normalizeChallengeStatus(payment.challengeStatus) as string,

Choose a reason for hiding this comment

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

[❗❗ correctness]
Consider handling the case where payment.challengeStatus might be null or undefined before passing it to normalizeChallengeStatus. This could prevent potential runtime errors if normalizeChallengeStatus does not handle such cases internally.

}));

export const mockBaFeesData: BaFeesReportResponse[] = [
{
billingAccountId: "80001012",
Expand Down
Loading