99 mockCreateCustomerAccountClient ,
1010 mockCreateStorefrontClient ,
1111} from './cart-test-helper' ;
12- import { Storefront } from '../storefront' ;
12+ import type { Storefront , StorefrontApiErrors } from '../storefront' ;
13+ import type { CartQueryDataReturn } from './queries/cart-types' ;
1314
1415type MockCarthandler = {
1516 cartId ?: string ;
@@ -20,6 +21,17 @@ type MockCarthandler = {
2021 storefront ?: Storefront ;
2122} ;
2223
24+ type CustomCart = {
25+ id : string ;
26+ checkoutUrl : string ;
27+ totalQuantity : number ;
28+ customField ?: string ;
29+ } ;
30+
31+ type ExtraCartGetVariables = {
32+ customVariable ?: string ;
33+ } ;
34+
2335function getCartHandler ( options : MockCarthandler = { } ) {
2436 const { cartId, ...rest } = options ;
2537 return createCartHandler ( {
@@ -78,6 +90,73 @@ describe('createCartHandler', () => {
7890 expect ( cart . foo ( ) ) . toBe ( 'bar' ) ;
7991 } ) ;
8092
93+ it ( 'can type cart methods with a custom cart fragment type' , ( ) => {
94+ const cart = createCartHandler < CustomCart > ( {
95+ storefront : mockCreateStorefrontClient ( ) ,
96+ getCartId : ( ) => undefined ,
97+ setCartId : ( ) => new Headers ( ) ,
98+ cartQueryFragment : 'cartQueryFragmentOverride' ,
99+ cartMutateFragment : 'cartMutateFragmentOverride' ,
100+ } ) ;
101+
102+ expectTypeOf ( cart ) . toEqualTypeOf < HydrogenCart < CustomCart > > ( ) ;
103+ expectTypeOf < Awaited < ReturnType < typeof cart . get > > > ( ) . toEqualTypeOf <
104+ ( CustomCart & { errors ?: StorefrontApiErrors } ) | null
105+ > ( ) ;
106+ expectTypeOf < Awaited < ReturnType < typeof cart . create > > > ( ) . toEqualTypeOf <
107+ CartQueryDataReturn < CustomCart >
108+ > ( ) ;
109+ expectTypeOf < Awaited < ReturnType < typeof cart . addLines > > > ( ) . toEqualTypeOf <
110+ CartQueryDataReturn < CustomCart >
111+ > ( ) ;
112+ } ) ;
113+
114+ it ( 'can type custom cart get variables' , ( ) => {
115+ const cart = createCartHandler < CustomCart , ExtraCartGetVariables > ( {
116+ storefront : mockCreateStorefrontClient ( ) ,
117+ getCartId : ( ) => undefined ,
118+ setCartId : ( ) => new Headers ( ) ,
119+ cartQueryFragment : 'cartQueryFragmentOverride' ,
120+ } ) ;
121+
122+ expectTypeOf < Parameters < typeof cart . get > [ 0 ] > ( ) . toMatchTypeOf <
123+ ExtraCartGetVariables | undefined
124+ > ( ) ;
125+
126+ if ( false ) {
127+ void cart . get ( { customVariable : 'value' } ) ;
128+ // @ts -expect-error customVariable must be a string.
129+ void cart . get ( { customVariable : 123 } ) ;
130+ }
131+ } ) ;
132+
133+ it ( 'can combine custom cart typing with custom methods' , ( ) => {
134+ const cart = createCartHandler <
135+ CustomCart ,
136+ ExtraCartGetVariables ,
137+ { foo : ( ) => 'bar' }
138+ > ( {
139+ storefront : mockCreateStorefrontClient ( ) ,
140+ getCartId : ( ) => undefined ,
141+ setCartId : ( ) => new Headers ( ) ,
142+ cartQueryFragment : 'cartQueryFragmentOverride' ,
143+ cartMutateFragment : 'cartMutateFragmentOverride' ,
144+ customMethods : {
145+ foo ( ) {
146+ return 'bar' ;
147+ } ,
148+ } ,
149+ } ) ;
150+
151+ expectTypeOf ( cart ) . toEqualTypeOf <
152+ HydrogenCartCustom < { foo : ( ) => 'bar' } , CustomCart , ExtraCartGetVariables >
153+ > ( ) ;
154+ expectTypeOf < Awaited < ReturnType < typeof cart . get > > > ( ) . toEqualTypeOf <
155+ ( CustomCart & { errors ?: StorefrontApiErrors } ) | null
156+ > ( ) ;
157+ expect ( cart . foo ( ) ) . toBe ( 'bar' ) ;
158+ } ) ;
159+
81160 it ( 'can override default methods' , async ( ) => {
82161 const cart = getCartHandler ( {
83162 customMethods : {
@@ -322,6 +401,45 @@ describe('createCartHandler', () => {
322401 expect ( result . cart ) . toHaveProperty ( 'id' , 'c1-new-cart-id' ) ;
323402 } ) ;
324403
404+ it ( 'function updateBuyerIdentity returns cart create errors when cart is not created' , async ( ) => {
405+ const storefront = {
406+ ...mockCreateStorefrontClient ( ) ,
407+ mutate : vi . fn ( ) . mockResolvedValueOnce ( {
408+ cartCreate : {
409+ cart : null ,
410+ userErrors : [ { message : 'Cannot create cart' } ] ,
411+ } ,
412+ } ) ,
413+ } as unknown as Storefront ;
414+ const cart = getCartHandler ( { storefront} ) ;
415+
416+ const result = await cart . updateBuyerIdentity ( {
417+ companyLocationId : 'gid://shopify/CompanyLocation/1' ,
418+ } ) ;
419+
420+ expect ( result . cart ) . toBeNull ( ) ;
421+ expect ( result . userErrors ?. [ 0 ] ) . toHaveProperty (
422+ 'message' ,
423+ 'Cannot create cart' ,
424+ ) ;
425+ } ) ;
426+
427+ it ( 'function create throws when a returned cart is missing id' , async ( ) => {
428+ const storefront = {
429+ ...mockCreateStorefrontClient ( ) ,
430+ mutate : vi . fn ( ) . mockResolvedValueOnce ( {
431+ cartCreate : {
432+ cart : { totalQuantity : 0 } ,
433+ } ,
434+ } ) ,
435+ } as unknown as Storefront ;
436+ const cart = getCartHandler ( { storefront} ) ;
437+
438+ await expect ( cart . create ( { } ) ) . rejects . toThrow (
439+ 'Cart created but response is missing a valid `id` field.' ,
440+ ) ;
441+ } ) ;
442+
325443 it ( 'function updateNote has a working default implementation' , async ( ) => {
326444 const cart = getCartHandler ( { cartId : 'c1-123' } ) ;
327445
0 commit comments