@@ -330,6 +330,50 @@ describe('CloudPaymentsWebhooks', () => {
330330 } ) ;
331331 } ) ;
332332
333+ it ( 'should keep card-link checksum data when unsigned Data contains plan payment fields' , async ( ) => {
334+ const checksum = await checksumService . generateChecksum ( {
335+ isCardLinkOperation : true ,
336+ workspaceId : 'signed-workspace' ,
337+ userId : 'signed-user' ,
338+ nextPaymentDate : new Date ( ) . toISOString ( ) ,
339+ } ) ;
340+ const webhooks = new CloudPaymentsWebhooks ( ) as any ;
341+
342+ const data = await webhooks . getDataFromRequest ( {
343+ body : {
344+ Data : JSON . stringify ( {
345+ checksum,
346+ tariffPlanId : 'unsigned-plan' ,
347+ shouldSaveCard : true ,
348+ promo : {
349+ id : new ObjectId ( ) . toString ( ) ,
350+ } ,
351+ cloudPayments : {
352+ recurrent : {
353+ interval : 'Month' ,
354+ period : 1 ,
355+ } ,
356+ } ,
357+ } ) ,
358+ } ,
359+ } ) ;
360+
361+ expect ( data ) . toMatchObject ( {
362+ workspaceId : 'signed-workspace' ,
363+ userId : 'signed-user' ,
364+ tariffPlanId : '' ,
365+ shouldSaveCard : false ,
366+ isCardLinkOperation : true ,
367+ cloudPayments : {
368+ recurrent : {
369+ interval : 'Month' ,
370+ period : 1 ,
371+ } ,
372+ } ,
373+ } ) ;
374+ expect ( data . promo ) . toBeUndefined ( ) ;
375+ } ) ;
376+
333377 it ( 'should restore subscription renewal data by SubscriptionId without promo' , async ( ) => {
334378 const webhooks = new CloudPaymentsWebhooks ( ) as any ;
335379 const workspaceId = new ObjectId ( ) . toString ( ) ;
@@ -398,6 +442,40 @@ describe('CloudPaymentsWebhooks', () => {
398442 expect ( res . json ) . toHaveBeenCalledWith ( { code : CheckCodes . SUCCESS } ) ;
399443 } ) ;
400444
445+ it ( 'should validate amount against signed plan when unsigned Data tries to replace tariffPlanId' , async ( ) => {
446+ const webhooks = new CloudPaymentsWebhooks ( ) as any ;
447+ const workspaceId = new ObjectId ( ) . toString ( ) ;
448+ const userId = new ObjectId ( ) . toString ( ) ;
449+ const signedPlan = createPlan ( 1000 ) ;
450+ const unsignedPlan = createPlan ( 500 ) ;
451+ const { context } = createWebhookContext ( {
452+ workspaceId,
453+ userId,
454+ plan : signedPlan ,
455+ } ) ;
456+ const res = createMockResponse ( ) ;
457+ const checksum = await checksumService . generateChecksum ( {
458+ workspaceId,
459+ userId,
460+ tariffPlanId : signedPlan . _id . toString ( ) ,
461+ shouldSaveCard : false ,
462+ nextPaymentDate : new Date ( ) . toISOString ( ) ,
463+ } ) ;
464+ const Data = JSON . stringify ( {
465+ checksum,
466+ tariffPlanId : unsignedPlan . _id . toString ( ) ,
467+ } ) ;
468+
469+ context . factories . plansFactory . findById = jest . fn ( ) . mockImplementation ( ( planId : string ) => {
470+ return Promise . resolve ( planId === signedPlan . _id . toString ( ) ? signedPlan : unsignedPlan ) ;
471+ } ) ;
472+
473+ await webhooks . check ( { context, body : createCheckBody ( 1001 , '500' , Data ) } , res ) ;
474+
475+ expect ( context . factories . plansFactory . findById ) . toHaveBeenCalledWith ( signedPlan . _id . toString ( ) ) ;
476+ expect ( res . json ) . toHaveBeenCalledWith ( { code : CheckCodes . WRONG_AMOUNT } ) ;
477+ } ) ;
478+
401479 it ( 'should reject wrong amount when promo id is in checksum' , async ( ) => {
402480 const webhooks = new CloudPaymentsWebhooks ( ) as any ;
403481 const workspaceId = new ObjectId ( ) . toString ( ) ;
0 commit comments