From b4ad27dfbd8d2663cc5ba17526e6b05901171bdb Mon Sep 17 00:00:00 2001 From: flopez7 Date: Tue, 2 Jun 2026 13:06:23 +0200 Subject: [PATCH] Refactor reward amount sorting in JobsDiscoveryService and add tests for handling valid and invalid amounts --- .../jobs-discovery/jobs-discovery.service.ts | 7 +- .../spec/jobs-discovery.fixtures.ts | 40 +++++++++++ .../spec/jobs-discovery.service.spec.ts | 67 +++++++++++++++++++ 3 files changed, 112 insertions(+), 2 deletions(-) diff --git a/packages/apps/human-app/server/src/modules/jobs-discovery/jobs-discovery.service.ts b/packages/apps/human-app/server/src/modules/jobs-discovery/jobs-discovery.service.ts index 8a62cad6b2..ee87a582cb 100644 --- a/packages/apps/human-app/server/src/modules/jobs-discovery/jobs-discovery.service.ts +++ b/packages/apps/human-app/server/src/modules/jobs-discovery/jobs-discovery.service.ts @@ -16,7 +16,6 @@ import { JobDiscoveryFieldName, JobDiscoverySortField, } from '../../common/enums/global-common'; -import { ethers } from 'ethers'; @Injectable() export class JobsDiscoveryService { @@ -39,7 +38,11 @@ export class JobsDiscoveryService { let iteratee: JobDiscoverySortField | Iteratee; if (sortField === JobDiscoverySortField.REWARD_AMOUNT) { - iteratee = (job: DiscoveredJob) => ethers.parseUnits(job[sortField], 18); + iteratee = (job: DiscoveredJob) => { + const rewardAmount = Number(job[sortField].trim()); + + return Number.isFinite(rewardAmount) ? rewardAmount : 0; + }; } else { iteratee = sortField; } diff --git a/packages/apps/human-app/server/src/modules/jobs-discovery/spec/jobs-discovery.fixtures.ts b/packages/apps/human-app/server/src/modules/jobs-discovery/spec/jobs-discovery.fixtures.ts index f86b8bcd3f..bdd0b0fcb6 100644 --- a/packages/apps/human-app/server/src/modules/jobs-discovery/spec/jobs-discovery.fixtures.ts +++ b/packages/apps/human-app/server/src/modules/jobs-discovery/spec/jobs-discovery.fixtures.ts @@ -5,6 +5,7 @@ import { JobsDiscoveryParamsDto, JobsDiscoveryResponse, JobsDiscoveryResponseItem, + DiscoveredJob, } from '../model/jobs-discovery.model'; import { JobDiscoveryFieldName, @@ -17,6 +18,9 @@ const EXCHANGE_ORACLE_URL = 'https://www.test_url.org'; const ESCROW_ADDRESS1 = 'test_address1'; const ESCROW_ADDRESS2 = 'test_address2'; const ESCROW_ADDRESS3 = 'test_address3'; +const JOB_DESCRIPTION = 'Test job description'; +const REWARD_TOKEN_HMT = 'HMT'; +const REWARD_TOKEN_USDC = 'USDC'; const CHAIN_ID = 1; const PAGE_SIZE = 10; const PAGE = 0; @@ -101,6 +105,42 @@ export const responseItemsFixture: JobsDiscoveryResponseItem[] = [ responseItemFixture2, responseItemFixture3, ]; +export const hmtRewardAmountResponseItemFixture: DiscoveredJob = { + ...responseItemFixture1, + escrow_address: ESCROW_ADDRESS1, + created_at: responseItemFixture1.created_at ?? '', + job_description: JOB_DESCRIPTION, + reward_amount: '1', + reward_token: REWARD_TOKEN_HMT, + updated_at: '2025-03-18T01:00:00.000Z', +}; +export const usdcRewardAmountResponseItemFixture: DiscoveredJob = { + ...responseItemFixture1, + escrow_address: ESCROW_ADDRESS1, + created_at: responseItemFixture1.created_at ?? '', + job_description: JOB_DESCRIPTION, + reward_amount: '2', + reward_token: REWARD_TOKEN_USDC, + updated_at: '2025-03-18T01:00:00.000Z', +}; +export const invalidRewardAmountResponseItemFixture: DiscoveredJob = { + ...responseItemFixture1, + escrow_address: ESCROW_ADDRESS1, + created_at: responseItemFixture1.created_at ?? '', + job_description: JOB_DESCRIPTION, + reward_amount: 'NaN', + reward_token: REWARD_TOKEN_HMT, + updated_at: '2025-03-18T01:00:00.000Z', +}; +export const validRewardAmountResponseItemFixture: DiscoveredJob = { + ...responseItemFixture1, + escrow_address: ESCROW_ADDRESS1, + created_at: responseItemFixture1.created_at ?? '', + job_description: JOB_DESCRIPTION, + reward_amount: '1', + reward_token: REWARD_TOKEN_HMT, + updated_at: '2025-03-18T01:00:00.000Z', +}; export const responseFixture: JobsDiscoveryResponse = { results: responseItemsFixture, page: PAGE, diff --git a/packages/apps/human-app/server/src/modules/jobs-discovery/spec/jobs-discovery.service.spec.ts b/packages/apps/human-app/server/src/modules/jobs-discovery/spec/jobs-discovery.service.spec.ts index 566a1f0734..d3d45b6cff 100644 --- a/packages/apps/human-app/server/src/modules/jobs-discovery/spec/jobs-discovery.service.spec.ts +++ b/packages/apps/human-app/server/src/modules/jobs-discovery/spec/jobs-discovery.service.spec.ts @@ -4,12 +4,21 @@ import { JobsDiscoveryService } from '../jobs-discovery.service'; import { ExchangeOracleGateway } from '../../../integrations/exchange-oracle/exchange-oracle.gateway'; import { Test, TestingModule } from '@nestjs/testing'; import { + hmtRewardAmountResponseItemFixture, + invalidRewardAmountResponseItemFixture, jobsDiscoveryParamsCommandFixture, responseItemsFixture, responseItemFixture1, responseItemFixture3, + usdcRewardAmountResponseItemFixture, + validRewardAmountResponseItemFixture, } from './jobs-discovery.fixtures'; import { EnvironmentConfigService } from '../../../common/config/environment-config.service'; +import { + JobDiscoveryFieldName, + JobDiscoverySortField, + SortOrder, +} from '../../../common/enums/global-common'; describe('JobsDiscoveryService', () => { let service: JobsDiscoveryService; @@ -62,5 +71,63 @@ describe('JobsDiscoveryService', () => { responseItemFixture1, ]); }); + + it('should sort reward amounts using human-readable units', async () => { + const command = { + ...jobsDiscoveryParamsCommandFixture, + data: { + ...jobsDiscoveryParamsCommandFixture.data, + fields: [ + JobDiscoveryFieldName.RewardAmount, + JobDiscoveryFieldName.RewardToken, + ], + sort: SortOrder.DESC, + sortField: JobDiscoverySortField.REWARD_AMOUNT, + }, + }; + + jest + .spyOn(service as any, 'getCachedJobs') + .mockReturnValue([ + hmtRewardAmountResponseItemFixture, + usdcRewardAmountResponseItemFixture, + ]); + + const result = await service.processJobsDiscovery(command); + + expect(result.results).toEqual([ + usdcRewardAmountResponseItemFixture, + hmtRewardAmountResponseItemFixture, + ]); + }); + + it('should use zero for invalid reward amounts', async () => { + const command = { + ...jobsDiscoveryParamsCommandFixture, + data: { + ...jobsDiscoveryParamsCommandFixture.data, + fields: [ + JobDiscoveryFieldName.RewardAmount, + JobDiscoveryFieldName.RewardToken, + ], + sort: SortOrder.DESC, + sortField: JobDiscoverySortField.REWARD_AMOUNT, + }, + }; + + jest + .spyOn(service as any, 'getCachedJobs') + .mockReturnValue([ + invalidRewardAmountResponseItemFixture, + validRewardAmountResponseItemFixture, + ]); + + const result = await service.processJobsDiscovery(command); + + expect(result.results).toEqual([ + validRewardAmountResponseItemFixture, + invalidRewardAmountResponseItemFixture, + ]); + }); }); });