@@ -36,6 +36,10 @@ jest.mock('src/shared/access-control/access-control.service', () => ({
3636 AccessControlService : class { } ,
3737} ) ) ;
3838
39+ jest . mock ( 'src/shared/topcoder/members.service' , ( ) => ( {
40+ TopcoderMembersService : class { } ,
41+ } ) ) ;
42+
3943import { AdminService } from './admin.service' ;
4044
4145describe ( 'AdminService' , ( ) => {
@@ -54,6 +58,9 @@ describe('AdminService', () => {
5458 getAssignmentContextById : jest . Mock ;
5559 getEngagementById : jest . Mock ;
5660 } ;
61+ let tcMembersService : {
62+ getHandlesByUserIds : jest . Mock ;
63+ } ;
5764
5865 beforeEach ( ( ) => {
5966 prisma = {
@@ -70,20 +77,27 @@ describe('AdminService', () => {
7077 getAssignmentContextById : jest . fn ( ) ,
7178 getEngagementById : jest . fn ( ) ,
7279 } ;
80+ tcMembersService = {
81+ getHandlesByUserIds : jest . fn ( ) . mockResolvedValue ( {
82+ '654321' : 'payment-manager' ,
83+ } ) ,
84+ } ;
7385
7486 service = new AdminService (
7587 prisma as any ,
7688 paymentsService as any ,
7789 baService as any ,
7890 accessControlService as any ,
7991 topcoderEngagementsService as any ,
92+ tcMembersService as any ,
8093 ) ;
8194 } ) ;
8295
8396 it ( 'returns work-log and engagement details for engagement payments' , async ( ) => {
8497 prisma . winnings . findFirst . mockResolvedValue ( {
8598 winning_id : 'winning-1' ,
8699 category : 'ENGAGEMENT_PAYMENT' ,
100+ created_by : '654321' ,
87101 external_id : 'assignment-1' ,
88102 attributes : {
89103 hoursWorked : 12.5 ,
@@ -117,6 +131,9 @@ describe('AdminService', () => {
117131 expect (
118132 topcoderEngagementsService . getAssignmentContextById ,
119133 ) . toHaveBeenCalledWith ( 'assignment-1' ) ;
134+ expect ( tcMembersService . getHandlesByUserIds ) . toHaveBeenCalledWith ( [
135+ '654321' ,
136+ ] ) ;
120137 expect ( result . data ) . toEqual ( {
121138 engagementDetails : {
122139 assignmentId : 'assignment-1' ,
@@ -130,6 +147,7 @@ describe('AdminService', () => {
130147 ratePerHour : '75.50' ,
131148 standardHoursPerWeek : 40 ,
132149 } ,
150+ paymentCreatorHandle : 'payment-manager' ,
133151 workLog : {
134152 hoursWorked : 12.5 ,
135153 remarks : 'Completed sprint support and bug triage.' ,
@@ -141,6 +159,7 @@ describe('AdminService', () => {
141159 prisma . winnings . findFirst . mockResolvedValue ( {
142160 winning_id : 'winning-1' ,
143161 category : 'ENGAGEMENT_PAYMENT' ,
162+ created_by : '654321' ,
144163 external_id : 'assignment-1' ,
145164 attributes : {
146165 hoursWorked : 8 ,
@@ -158,6 +177,7 @@ describe('AdminService', () => {
158177 ) ;
159178
160179 expect ( result . data ) . toEqual ( {
180+ paymentCreatorHandle : 'payment-manager' ,
161181 workLog : {
162182 hoursWorked : 8 ,
163183 remarks : 'Weekly support work.' ,
@@ -170,6 +190,7 @@ describe('AdminService', () => {
170190 winning_id : 'winning-1' ,
171191 winner_id : '123456' ,
172192 category : 'ENGAGEMENT_PAYMENT' ,
193+ created_by : '654321' ,
173194 external_id : 'engagement-1' ,
174195 attributes : {
175196 hoursWorked : 10 ,
@@ -222,13 +243,44 @@ describe('AdminService', () => {
222243 ratePerHour : '82.50' ,
223244 standardHoursPerWeek : 35 ,
224245 } ,
246+ paymentCreatorHandle : 'payment-manager' ,
225247 workLog : {
226248 hoursWorked : 10 ,
227249 remarks : 'Covered support hours.' ,
228250 } ,
229251 } ) ;
230252 } ) ;
231253
254+ it ( 'falls back to the creator id when the handle lookup misses' , async ( ) => {
255+ tcMembersService . getHandlesByUserIds . mockResolvedValue ( { } ) ;
256+ prisma . winnings . findFirst . mockResolvedValue ( {
257+ winning_id : 'winning-1' ,
258+ category : 'ENGAGEMENT_PAYMENT' ,
259+ created_by : '654321' ,
260+ external_id : 'assignment-1' ,
261+ attributes : {
262+ hoursWorked : 8 ,
263+ } ,
264+ } ) ;
265+ topcoderEngagementsService . getAssignmentContextById . mockRejectedValue (
266+ new Error ( 'upstream unavailable' ) ,
267+ ) ;
268+
269+ const result = await service . getWinningPaymentDetails (
270+ 'winning-1' ,
271+ '123456' ,
272+ [ 'Payment Admin' ] ,
273+ ) ;
274+
275+ expect ( result . data ) . toEqual ( {
276+ paymentCreatorHandle : '654321' ,
277+ workLog : {
278+ hoursWorked : 8 ,
279+ remarks : undefined ,
280+ } ,
281+ } ) ;
282+ } ) ;
283+
232284 it ( 'prefers a numeric assignmentId stored in winning attributes' , async ( ) => {
233285 prisma . winnings . findFirst . mockResolvedValue ( {
234286 winning_id : 'winning-1' ,
0 commit comments