@@ -4,6 +4,7 @@ import AcpJobOffering, { PriceType } from "../../src/acpJobOffering";
44import { BaseAcpContractClient } from "../../src" ;
55import AcpClient from "../../src/acpClient" ;
66import AcpError from "../../src/acpError" ;
7+ import { AcpAccount } from "../../src/acpAccount" ;
78
89jest . mock ( "../../src/configs/acpConfigs" , ( ) => ( {
910 baseSepoliaAcpConfig : {
@@ -77,10 +78,11 @@ describe("AcpJobOffering Unit Testing", () => {
7778 expect ( offering . requiredFunds ) . toBe ( true ) ;
7879 expect ( offering . slaMinutes ) . toBe ( 1440 ) ;
7980 expect ( offering . requirement ) . toBe ( undefined ) ;
81+ expect ( offering . deliverable ) . toBe ( undefined ) ;
8082 expect ( offering . subscriptionTiers ) . toEqual ( [ ] ) ;
8183 } ) ;
8284
83- it ( "should use priceType FIXED" , ( ) => {
85+ it ( "should use priceType FIXED and requiredFunds " , ( ) => {
8486 const offering = new AcpJobOffering (
8587 mockAcpClient ,
8688 mockContractClient ,
@@ -94,6 +96,7 @@ describe("AcpJobOffering Unit Testing", () => {
9496
9597 expect ( offering ) . toBeInstanceOf ( AcpJobOffering ) ;
9698 expect ( offering . priceType ) . toBe ( PriceType . FIXED ) ;
99+ expect ( offering . requiredFunds ) . toBe ( false ) ;
97100 } ) ;
98101
99102 it ( "should accept custom priceType" , ( ) => {
@@ -150,6 +153,44 @@ describe("AcpJobOffering Unit Testing", () => {
150153 expect ( offering . requirement ) . toBe ( requirementObject ) ;
151154 } ) ;
152155
156+ it ( "should accept deliverable as string" , ( ) => {
157+ const offering = new AcpJobOffering (
158+ mockAcpClient ,
159+ mockContractClient ,
160+ "0xProvider" as Address ,
161+ "MockJob" ,
162+ 100 ,
163+ PriceType . FIXED ,
164+ true ,
165+ 1440 ,
166+ undefined ,
167+ "custom deliverable" ,
168+ ) ;
169+
170+ expect ( offering ) . toBeInstanceOf ( AcpJobOffering ) ;
171+ expect ( offering . deliverable ) . toBe ( "custom deliverable" ) ;
172+ } ) ;
173+
174+ it ( "should accept deliverable as object" , ( ) => {
175+ const deliverableObject = { type : "image" , format : "png" } ;
176+
177+ const offering = new AcpJobOffering (
178+ mockAcpClient ,
179+ mockContractClient ,
180+ "0xProvider" as Address ,
181+ "MockJob" ,
182+ 100 ,
183+ PriceType . FIXED ,
184+ false ,
185+ 1440 ,
186+ undefined ,
187+ deliverableObject ,
188+ ) ;
189+
190+ expect ( offering ) . toBeInstanceOf ( AcpJobOffering ) ;
191+ expect ( offering . deliverable ) . toEqual ( deliverableObject ) ;
192+ } ) ;
193+
153194 it ( "should accept subscription tiers" , ( ) => {
154195 const offering = new AcpJobOffering (
155196 mockAcpClient ,
@@ -401,6 +442,67 @@ describe("AcpJobOffering Unit Testing", () => {
401442 } ) ;
402443
403444 it ( "should use createJobWithAccount for V2 contracts when account exists" , async ( ) => {
445+ const mockUserOpHash = "0xmockUserOpHash" ;
446+ const mockJobId = 12345 ;
447+ const mockCreateJobPayload = { data : "createJobWithAccountPayload" } ;
448+ const mockSetBudgetPayload = { data : "setBudgetPayload" } ;
449+ const mockMemoPayload = { data : "memoPayload" } ;
450+ const mockAccount = new AcpAccount (
451+ mockContractClient as any ,
452+ 999 ,
453+ "0xClient" as Address ,
454+ "0xProvider" as Address ,
455+ { } ,
456+ ) ;
457+
458+ // Mock getByClientAndProvider to return an account (V2 behavior)
459+ jest
460+ . spyOn ( mockAcpClient , "getByClientAndProvider" )
461+ . mockResolvedValue ( mockAccount as any ) ;
462+
463+ mockContractClient . createJobWithAccount . mockReturnValue (
464+ mockCreateJobPayload as any ,
465+ ) ;
466+ mockContractClient . handleOperation . mockResolvedValue ( {
467+ userOpHash : mockUserOpHash ,
468+ } as any ) ;
469+ mockContractClient . getJobId . mockResolvedValue ( mockJobId ) ;
470+ mockContractClient . setBudgetWithPaymentToken . mockReturnValue (
471+ mockSetBudgetPayload as any ,
472+ ) ;
473+ mockContractClient . createMemo . mockReturnValue ( mockMemoPayload as any ) ;
474+
475+ // Use a non-V1 contract address
476+ mockContractClient . config . contractAddress =
477+ "0xV2ContractAddress" as Address ;
478+
479+ const offering = new AcpJobOffering (
480+ mockAcpClient ,
481+ mockContractClient ,
482+ "0xProvider" as Address ,
483+ "Generate Image" ,
484+ 100 ,
485+ PriceType . FIXED ,
486+ true ,
487+ 1440 ,
488+ ) ;
489+
490+ const result = await offering . initiateJob (
491+ "generate an image about Virtuals" ,
492+ ) ;
493+
494+ expect ( result ) . toBe ( mockJobId ) ;
495+ expect ( mockContractClient . createJobWithAccount ) . toHaveBeenCalledTimes ( 1 ) ;
496+ expect ( mockContractClient . createJob ) . not . toHaveBeenCalled ( ) ;
497+
498+ // Verify that createJobWithAccount was called with account.id (1st parameter)
499+ const createJobCall =
500+ mockContractClient . createJobWithAccount . mock . calls [ 0 ] ;
501+ const accountIdParam = createJobCall [ 0 ] ;
502+ expect ( accountIdParam ) . toBe ( mockAccount . id ) ;
503+ } ) ;
504+
505+ it ( "should use createJobWithAccount for V2 contracts when subscription account exists" , async ( ) => {
404506 const mockUserOpHash = "0xmockUserOpHash" ;
405507 const mockJobId = 12345 ;
406508 const mockCreateJobPayload = { data : "createJobWithAccountPayload" } ;
0 commit comments