@@ -608,7 +608,10 @@ describe("challenge service unit tests", () => {
608608 createdChallengeData . id ,
609609 ) ;
610610
611- should . equal ( result . billing . billingAccountId , createdChallengeData . billing . billingAccountId ) ;
611+ should . equal (
612+ result . billing . billingAccountId ,
613+ createdChallengeData . billing . billingAccountId ,
614+ ) ;
612615 should . equal ( _ . isUndefined ( result . billing . markup ) , true ) ;
613616 } finally {
614617 helper . userHasProjectWriteAccess = originalUserHasProjectWriteAccess ;
@@ -1656,6 +1659,118 @@ describe("challenge service unit tests", () => {
16561659 should . equal ( testHelper . getDatesDiff ( result . startDate , testChallengeData . startDate ) , 0 ) ;
16571660 } ) ;
16581661
1662+ it ( "backfills missing billing and locks draft budget including copilot prizes" , async ( ) => {
1663+ const challengeData = _ . cloneDeep ( testChallengeData ) ;
1664+ challengeData . name = `${ challengeData . name } Billing Lock ${ Date . now ( ) } ` ;
1665+ challengeData . legacyId = Math . floor ( Math . random ( ) * 1000000 ) ;
1666+ challengeData . status = ChallengeStatusEnum . NEW ;
1667+ challengeData . prizeSets = [
1668+ {
1669+ type : PrizeSetTypeEnum . PLACEMENT ,
1670+ description : "placement prizes" ,
1671+ prizes : [
1672+ {
1673+ description : "placement 1" ,
1674+ type : constants . prizeTypes . USD ,
1675+ value : 1000 ,
1676+ } ,
1677+ ] ,
1678+ } ,
1679+ {
1680+ type : PrizeSetTypeEnum . COPILOT ,
1681+ description : "copilot payment" ,
1682+ prizes : [
1683+ {
1684+ description : "copilot" ,
1685+ type : constants . prizeTypes . USD ,
1686+ value : 150 ,
1687+ } ,
1688+ ] ,
1689+ } ,
1690+ ] ;
1691+
1692+ const originalGetProject = projectHelper . getProject ;
1693+ const originalGetProjectBillingInformation = projectHelper . getProjectBillingInformation ;
1694+ let billingLookupCount = 0 ;
1695+ let createdChallengeId ;
1696+
1697+ projectHelper . getProject = async ( ) => ( { directProjectId : "33541" } ) ;
1698+ projectHelper . getProjectBillingInformation = async ( ) => {
1699+ billingLookupCount += 1 ;
1700+
1701+ if ( billingLookupCount === 1 ) {
1702+ return {
1703+ billingAccountId : null ,
1704+ markup : null ,
1705+ } ;
1706+ }
1707+
1708+ return {
1709+ billingAccountId : "80001012" ,
1710+ markup : 0.1 ,
1711+ } ;
1712+ } ;
1713+
1714+ try {
1715+ const created = await service . createChallenge (
1716+ { isMachine : true , sub : "sub-billing-lock-create" , userId : "testuser" } ,
1717+ challengeData ,
1718+ config . M2M_FULL_ACCESS_TOKEN ,
1719+ ) ;
1720+ createdChallengeId = created . id ;
1721+ should . equal ( billingLockRequests . length , 0 ) ;
1722+
1723+ const draft = await service . updateChallenge (
1724+ { isMachine : true , sub : "sub-billing-lock-update" , userId : 22838965 } ,
1725+ created . id ,
1726+ {
1727+ status : ChallengeStatusEnum . DRAFT ,
1728+ } ,
1729+ ) ;
1730+
1731+ should . equal ( draft . billing . billingAccountId , "80001012" ) ;
1732+ should . equal ( billingLockRequests . length , 1 ) ;
1733+ billingLockRequests [ 0 ] . should . deep . equal ( {
1734+ billingAccountId : "80001012" ,
1735+ challengeId : created . id ,
1736+ markup : 0.1 ,
1737+ memberPaymentAmount : 1150 ,
1738+ } ) ;
1739+
1740+ const updatedPrizeSets = _ . cloneDeep ( draft . prizeSets ) ;
1741+ const copilotPrizeSet = _ . find (
1742+ updatedPrizeSets ,
1743+ ( prizeSet ) => _ . toString ( prizeSet . type ) . toUpperCase ( ) === PrizeSetTypeEnum . COPILOT ,
1744+ ) ;
1745+ should . exist ( copilotPrizeSet ) ;
1746+ copilotPrizeSet . prizes [ 0 ] . value = 225 ;
1747+ billingLockRequests = [ ] ;
1748+
1749+ await service . updateChallenge (
1750+ { isMachine : true , sub : "sub-billing-lock-prize-update" , userId : 22838965 } ,
1751+ created . id ,
1752+ {
1753+ prizeSets : updatedPrizeSets ,
1754+ } ,
1755+ ) ;
1756+
1757+ should . equal ( billingLockRequests . length , 1 ) ;
1758+ billingLockRequests [ 0 ] . should . deep . equal ( {
1759+ billingAccountId : "80001012" ,
1760+ challengeId : created . id ,
1761+ markup : 0.1 ,
1762+ memberPaymentAmount : 1225 ,
1763+ } ) ;
1764+ } finally {
1765+ projectHelper . getProject = originalGetProject ;
1766+ projectHelper . getProjectBillingInformation = originalGetProjectBillingInformation ;
1767+
1768+ if ( createdChallengeId ) {
1769+ await prisma . challenge . deleteMany ( { where : { id : createdChallengeId } } ) ;
1770+ }
1771+ }
1772+ } ) . timeout ( 10000 ) ;
1773+
16591774 it ( "preserves existing terms when update payload omits the terms field" , async ( ) => {
16601775 const challengeData = _ . cloneDeep ( testChallengeData ) ;
16611776 challengeData . name = `${ challengeData . name } Terms ${ Date . now ( ) } ` ;
0 commit comments