@@ -78,9 +78,28 @@ vi.mock('./hooks/useConfigForm', () => ({
7878const mockUseStepper = vi . fn ( ) ;
7979
8080vi . mock ( './hooks/useStepper' , ( ) => ( {
81+ Step : {
82+ Config : 0 ,
83+ Payment : 1 ,
84+ CreditConfirmation : 2 ,
85+ } ,
8186 useStepper : ( ) => mockUseStepper ( ) ,
8287} ) ) ;
8388
89+ // Mock useProjectCreation hook
90+ const mockUseProjectCreation = vi . fn ( ) ;
91+
92+ vi . mock ( './hooks/useProjectCreation' , ( ) => ( {
93+ useProjectCreation : ( ) => mockUseProjectCreation ( ) ,
94+ } ) ) ;
95+
96+ // Mock useWillPayment hook
97+ const mockUseWillPayment = vi . fn ( ) ;
98+
99+ vi . mock ( './hooks/useWillPayment' , ( ) => ( {
100+ useWillPayment : ( ) => mockUseWillPayment ( ) ,
101+ } ) ) ;
102+
84103// Mock useAntiFraud hook
85104const mockUseAntiFraud = vi . fn ( ) ;
86105
@@ -129,10 +148,6 @@ vi.mock('@/components/FullPageSpinner', () => ({
129148} ) ) ;
130149
131150// Mock step components
132- vi . mock ( './steps/ConfigurationStep' , ( ) => ( {
133- default : ( ) => < div data-testid = "configuration-step" > Configuration Step</ div > ,
134- } ) ) ;
135-
136151vi . mock ( './steps/ConfigStep' , ( ) => ( {
137152 default : ( ) => < div data-testid = "config-step" > Config Step</ div > ,
138153} ) ) ;
@@ -141,6 +156,12 @@ vi.mock('./steps/PaymentStep', () => ({
141156 default : ( ) => < div data-testid = "payment-step" > Payment Step</ div > ,
142157} ) ) ;
143158
159+ vi . mock ( './components/credit/CreditConfirmation.component' , ( ) => ( {
160+ default : ( ) => (
161+ < div data-testid = "credit-confirmation" > Credit Confirmation</ div >
162+ ) ,
163+ } ) ) ;
164+
144165const renderWithProviders = ( component : ReactElement ) => {
145166 const Wrapper = createWrapper ( mockShellContext ) ;
146167
@@ -155,7 +176,7 @@ describe('Creation Page', () => {
155176 mockUseParams . mockReturnValue ( { projectId : 'test-project-id' } ) ;
156177
157178 mockUseGetCart . mockReturnValue ( {
158- cart : {
179+ data : {
159180 cartId : 'test-cart-id' ,
160181 description : 'Test Cart' ,
161182 items : [ ] ,
@@ -193,7 +214,11 @@ describe('Creation Page', () => {
193214 } ) ;
194215
195216 mockUseGetOrderProjectId . mockReturnValue ( {
196- orderId : null ,
217+ data : {
218+ itemId : 'test-project-item-id' ,
219+ cartId : 'test-cart-id' ,
220+ type : 'publicCloudProject' ,
221+ } ,
197222 isLoading : false ,
198223 error : null ,
199224 } ) ;
@@ -217,18 +242,37 @@ describe('Creation Page', () => {
217242 } ) ;
218243
219244 mockUseStepper . mockReturnValue ( {
220- currentStep : 'generalInformations' ,
221- setCurrentStep : vi . fn ( ) ,
245+ goToConfig : vi . fn ( ) ,
246+ goToPayment : vi . fn ( ) ,
247+ goToCreditConfirmation : vi . fn ( ) ,
222248 isConfigChecked : false ,
223249 isConfigLocked : false ,
224250 isPaymentOpen : false ,
225251 isPaymentChecked : false ,
226- isPaymentLocked : false ,
227- goToStep : vi . fn ( ) ,
228- nextStep : vi . fn ( ) ,
229- previousStep : vi . fn ( ) ,
230- isFirstStep : true ,
231- isLastStep : false ,
252+ isPaymentLocked : true ,
253+ isCreditConfirmationOpen : false ,
254+ isCreditConfirmationChecked : false ,
255+ isCreditConfirmationLocked : false ,
256+ } ) ;
257+
258+ mockUseProjectCreation . mockReturnValue ( {
259+ isSubmitting : false ,
260+ needToCheckCustomerInfo : false ,
261+ billingHref : '' ,
262+ handleProjectCreation : vi . fn ( ) ,
263+ handleCreditAndPay : vi . fn ( ) ,
264+ } ) ;
265+
266+ mockUseWillPayment . mockReturnValue ( {
267+ isCreditPayment : false ,
268+ creditAmount : null ,
269+ needsSave : false ,
270+ isSaved : false ,
271+ canSubmit : true ,
272+ hasDefaultPaymentMethod : false ,
273+ savePaymentMethod : vi . fn ( ) ,
274+ handlePaymentStatusChange : vi . fn ( ) ,
275+ handleRegisteredPaymentMethodSelected : vi . fn ( ) ,
232276 } ) ;
233277
234278 mockUseAttachConfigurationToCartItem . mockReturnValue ( {
@@ -261,33 +305,73 @@ describe('Creation Page', () => {
261305 expect ( screen . getByTestId ( 'payment-step' ) ) . toBeInTheDocument ( ) ;
262306 } ) ;
263307
264- it ( 'should show proper content when cart is loading' , ( ) => {
308+ it ( 'should show spinner when cart or projectItem is null' , ( ) => {
309+ // Override the default mocks to return null data
310+ mockUseCreateAndAssignCart . mockReturnValue ( {
311+ mutate : vi . fn ( ) ,
312+ data : null , // No created cart
313+ isLoading : false ,
314+ error : null ,
315+ } ) ;
316+
265317 mockUseGetCart . mockReturnValue ( {
266- cart : null ,
267- isLoading : true ,
318+ data : null , // No existing cart
319+ isLoading : false ,
320+ error : null ,
321+ } ) ;
322+
323+ mockUseOrderProjectItem . mockReturnValue ( {
324+ mutate : vi . fn ( ) ,
325+ data : null , // No created project item
326+ isLoading : false ,
327+ error : null ,
328+ } ) ;
329+
330+ mockUseGetOrderProjectId . mockReturnValue ( {
331+ data : null , // No existing project item
332+ isLoading : false ,
268333 error : null ,
269334 } ) ;
270335
271336 renderWithProviders ( < Creation /> ) ;
272337
273- // Component should still render the basic structure
274- expect ( screen . getByTestId ( 'config-step' ) ) . toBeInTheDocument ( ) ;
275- expect ( screen . getByTestId ( 'payment-step' ) ) . toBeInTheDocument ( ) ;
338+ expect ( screen . getByTestId ( 'full-page-spinner' ) ) . toBeInTheDocument ( ) ;
276339 } ) ;
277340
278341 it ( 'should handle cart loading error' , ( ) => {
279342 const error = new Error ( 'Failed to load cart' ) ;
343+
344+ // Override all cart/project related mocks to return null
345+ mockUseCreateAndAssignCart . mockReturnValue ( {
346+ mutate : vi . fn ( ) ,
347+ data : null ,
348+ isLoading : false ,
349+ error,
350+ } ) ;
351+
280352 mockUseGetCart . mockReturnValue ( {
281- cart : null ,
353+ data : null ,
354+ isLoading : false ,
355+ error,
356+ } ) ;
357+
358+ mockUseOrderProjectItem . mockReturnValue ( {
359+ mutate : vi . fn ( ) ,
360+ data : null ,
361+ isLoading : false ,
362+ error,
363+ } ) ;
364+
365+ mockUseGetOrderProjectId . mockReturnValue ( {
366+ data : null ,
282367 isLoading : false ,
283368 error,
284369 } ) ;
285370
286371 renderWithProviders ( < Creation /> ) ;
287372
288- // Component should still render even with error
289- expect ( screen . getByTestId ( 'config-step' ) ) . toBeInTheDocument ( ) ;
290- expect ( screen . getByTestId ( 'payment-step' ) ) . toBeInTheDocument ( ) ;
373+ // Should show spinner when cart/projectItem is null
374+ expect ( screen . getByTestId ( 'full-page-spinner' ) ) . toBeInTheDocument ( ) ;
291375 } ) ;
292376
293377 it ( 'should render config step by default' , ( ) => {
@@ -315,35 +399,57 @@ describe('Creation Page', () => {
315399 expect ( screen . getByTestId ( 'payment-step' ) ) . toBeInTheDocument ( ) ;
316400 } ) ;
317401
318- // Verify cart hook is called
402+ // Verify hooks are called
319403 expect ( mockUseGetCart ) . toHaveBeenCalled ( ) ;
320- expect ( mockUseAntiFraud ) . toHaveBeenCalled ( ) ;
404+ expect ( mockUseProjectCreation ) . toHaveBeenCalled ( ) ;
405+ expect ( mockUseWillPayment ) . toHaveBeenCalled ( ) ;
321406 } ) ;
322407
323- it ( 'should handle anti-fraud polling' , ( ) => {
324- mockUseAntiFraud . mockReturnValue ( {
325- checkAntiFraud : vi . fn ( ) ,
326- isPolling : true ,
327- error : null ,
408+ it ( 'should handle project creation submission' , ( ) => {
409+ const mockHandleProjectCreation = vi . fn ( ) ;
410+
411+ mockUseProjectCreation . mockReturnValue ( {
412+ isSubmitting : false ,
413+ needToCheckCustomerInfo : false ,
414+ billingHref : '' ,
415+ handleProjectCreation : mockHandleProjectCreation ,
416+ handleCreditAndPay : vi . fn ( ) ,
417+ } ) ;
418+
419+ mockUseWillPayment . mockReturnValue ( {
420+ isCreditPayment : false ,
421+ creditAmount : null ,
422+ needsSave : false ,
423+ isSaved : false ,
424+ canSubmit : true ,
425+ hasDefaultPaymentMethod : true , // Has default payment method
426+ savePaymentMethod : vi . fn ( ) ,
427+ handlePaymentStatusChange : vi . fn ( ) ,
428+ handleRegisteredPaymentMethodSelected : vi . fn ( ) ,
328429 } ) ;
329430
330431 renderWithProviders ( < Creation /> ) ;
331432
332- // Component should handle polling state appropriately
333- expect ( mockUseAntiFraud ) . toHaveBeenCalled ( ) ;
433+ expect ( mockUseProjectCreation ) . toHaveBeenCalled ( ) ;
434+ expect ( mockUseWillPayment ) . toHaveBeenCalled ( ) ;
334435 } ) ;
335436
336- it ( 'should handle anti-fraud error' , ( ) => {
337- const error = new Error ( 'Anti-fraud check failed' ) ;
338- mockUseAntiFraud . mockReturnValue ( {
339- checkAntiFraud : vi . fn ( ) ,
340- isPolling : false ,
341- error,
437+ it ( 'should handle credit payment flow' , ( ) => {
438+ mockUseWillPayment . mockReturnValue ( {
439+ isCreditPayment : true ,
440+ creditAmount : { value : 100 , currency : 'EUR' } ,
441+ needsSave : false ,
442+ isSaved : false ,
443+ canSubmit : true ,
444+ hasDefaultPaymentMethod : false ,
445+ savePaymentMethod : vi . fn ( ) ,
446+ handlePaymentStatusChange : vi . fn ( ) ,
447+ handleRegisteredPaymentMethodSelected : vi . fn ( ) ,
342448 } ) ;
343449
344450 renderWithProviders ( < Creation /> ) ;
345451
346- expect ( mockUseAntiFraud ) . toHaveBeenCalled ( ) ;
452+ expect ( mockUseWillPayment ) . toHaveBeenCalled ( ) ;
347453 } ) ;
348454
349455 it ( 'should handle order polling state' , ( ) => {
@@ -364,7 +470,7 @@ describe('Creation Page', () => {
364470
365471 it ( 'should handle cart with items' , ( ) => {
366472 mockUseGetCart . mockReturnValue ( {
367- cart : {
473+ data : {
368474 cartId : 'test-cart-id' ,
369475 description : 'Cart with items' ,
370476 items : [
@@ -386,7 +492,7 @@ describe('Creation Page', () => {
386492
387493 it ( 'should handle readonly cart' , ( ) => {
388494 mockUseGetCart . mockReturnValue ( {
389- cart : {
495+ data : {
390496 cartId : 'readonly-cart' ,
391497 description : 'Readonly Cart' ,
392498 items : [ ] ,
@@ -400,4 +506,54 @@ describe('Creation Page', () => {
400506
401507 expect ( mockUseGetCart ) . toHaveBeenCalled ( ) ;
402508 } ) ;
509+
510+ it ( 'should render credit confirmation when isCreditConfirmationOpen is true' , ( ) => {
511+ mockUseStepper . mockReturnValue ( {
512+ goToConfig : vi . fn ( ) ,
513+ goToPayment : vi . fn ( ) ,
514+ goToCreditConfirmation : vi . fn ( ) ,
515+ isConfigChecked : true ,
516+ isConfigLocked : true ,
517+ isPaymentOpen : true ,
518+ isPaymentChecked : true ,
519+ isPaymentLocked : true ,
520+ isCreditConfirmationOpen : true ,
521+ isCreditConfirmationChecked : false ,
522+ isCreditConfirmationLocked : false ,
523+ } ) ;
524+
525+ renderWithProviders ( < Creation /> ) ;
526+
527+ expect ( screen . getByTestId ( 'credit-confirmation' ) ) . toBeInTheDocument ( ) ;
528+ } ) ;
529+
530+ it ( 'should call handleProjectCreation when isSaved becomes true' , async ( ) => {
531+ const mockHandleProjectCreation = vi . fn ( ) ;
532+
533+ mockUseProjectCreation . mockReturnValue ( {
534+ isSubmitting : false ,
535+ needToCheckCustomerInfo : false ,
536+ billingHref : '' ,
537+ handleProjectCreation : mockHandleProjectCreation ,
538+ handleCreditAndPay : vi . fn ( ) ,
539+ } ) ;
540+
541+ mockUseWillPayment . mockReturnValue ( {
542+ isCreditPayment : false ,
543+ creditAmount : null ,
544+ needsSave : false ,
545+ isSaved : true , // This should trigger handleProjectCreation
546+ canSubmit : true ,
547+ hasDefaultPaymentMethod : false ,
548+ savePaymentMethod : vi . fn ( ) ,
549+ handlePaymentStatusChange : vi . fn ( ) ,
550+ handleRegisteredPaymentMethodSelected : vi . fn ( ) ,
551+ } ) ;
552+
553+ renderWithProviders ( < Creation /> ) ;
554+
555+ await waitFor ( ( ) => {
556+ expect ( mockHandleProjectCreation ) . toHaveBeenCalledWith ( { } ) ;
557+ } ) ;
558+ } ) ;
403559} ) ;
0 commit comments