@@ -21,9 +21,11 @@ const mockPermissions = vi.hoisted(() => ({
2121 ref : undefined as { value : { canTopUp : boolean } } | undefined
2222} ) )
2323const mockShouldUseWorkspaceBilling = vi . hoisted ( ( ) => ( { value : true } ) )
24- const mockIsAddingCredits = vi . hoisted ( ( ) => ( { value : false } ) )
25- const mockTopupActionOperation = vi . hoisted ( ( ) => ( {
26- value : undefined as { actionUrl : string } | undefined
24+ const mockBillingOperationState = vi . hoisted ( ( ) => ( {
25+ isAddingCredits : undefined as { value : boolean } | undefined ,
26+ topupActionOperation : undefined as
27+ | { value : { actionUrl : string } | undefined }
28+ | undefined
2729} ) )
2830
2931vi . mock ( '@/composables/billing/useBillingContext' , ( ) => ( {
@@ -34,18 +36,23 @@ vi.mock('@/composables/billing/useBillingContext', () => ({
3436 } )
3537} ) )
3638
37- vi . mock ( '@/platform/workspace/stores/billingOperationStore' , ( ) => ( {
38- useBillingOperationStore : ( ) => ( {
39- hasPendingOperations : true ,
40- get isAddingCredits ( ) {
41- return mockIsAddingCredits . value
42- } ,
43- get topupActionOperation ( ) {
44- return mockTopupActionOperation . value
45- } ,
46- startOperation : mockStartOperation
47- } )
48- } ) )
39+ vi . mock ( '@/platform/workspace/stores/billingOperationStore' , async ( ) => {
40+ const { ref } = await import ( 'vue' )
41+ mockBillingOperationState . isAddingCredits = ref ( false )
42+ mockBillingOperationState . topupActionOperation = ref ( undefined )
43+ return {
44+ useBillingOperationStore : ( ) => ( {
45+ hasPendingOperations : true ,
46+ get isAddingCredits ( ) {
47+ return mockBillingOperationState . isAddingCredits ?. value ?? false
48+ } ,
49+ get topupActionOperation ( ) {
50+ return mockBillingOperationState . topupActionOperation ?. value
51+ } ,
52+ startOperation : mockStartOperation
53+ } )
54+ }
55+ } )
4956
5057vi . mock ( '@/platform/workspace/composables/useWorkspaceUI' , async ( ) => {
5158 const { ref } = await import ( 'vue' )
@@ -176,6 +183,20 @@ function setCanTopUp(canTopUp: boolean) {
176183 mockPermissions . ref . value = { canTopUp }
177184}
178185
186+ function setIsAddingCredits ( isAddingCredits : boolean ) {
187+ if ( ! mockBillingOperationState . isAddingCredits ) {
188+ throw new Error ( 'Billing operation mock not initialized' )
189+ }
190+ mockBillingOperationState . isAddingCredits . value = isAddingCredits
191+ }
192+
193+ function setTopupActionOperation ( operation : { actionUrl : string } | undefined ) {
194+ if ( ! mockBillingOperationState . topupActionOperation ) {
195+ throw new Error ( 'Billing operation mock not initialized' )
196+ }
197+ mockBillingOperationState . topupActionOperation . value = operation
198+ }
199+
179200async function clickAddCredits ( ) {
180201 const user = userEvent . setup ( )
181202 await user . click ( screen . getByRole ( 'button' , { name : 'Add credits' } ) )
@@ -186,12 +207,12 @@ describe('TopUpCreditsDialogContentWorkspace', () => {
186207 vi . clearAllMocks ( )
187208 setCanTopUp ( true )
188209 mockShouldUseWorkspaceBilling . value = true
189- mockIsAddingCredits . value = false
190- mockTopupActionOperation . value = undefined
210+ setIsAddingCredits ( false )
211+ setTopupActionOperation ( undefined )
191212 mockFetchBalance . mockResolvedValue ( undefined )
192213 mockFetchStatus . mockResolvedValue ( undefined )
193214 mockStartOperation . mockImplementation ( ( ) => {
194- mockIsAddingCredits . value = true
215+ setIsAddingCredits ( true )
195216 return new Promise ( ( ) => { } )
196217 } )
197218 } )
@@ -226,7 +247,7 @@ describe('TopUpCreditsDialogContentWorkspace', () => {
226247 it ( 'reopens in verification without exposing the action URL' , async ( ) => {
227248 const actionUrl = 'https://verify.example/sensitive-token'
228249 const open = vi . spyOn ( window , 'open' ) . mockReturnValue ( { } as Window )
229- mockTopupActionOperation . value = { actionUrl }
250+ setTopupActionOperation ( { actionUrl } )
230251
231252 const { container } = renderDialog ( )
232253
@@ -245,7 +266,7 @@ describe('TopUpCreditsDialogContentWorkspace', () => {
245266 } )
246267
247268 it ( 'reopens in verification while the action URL is loading' , ( ) => {
248- mockIsAddingCredits . value = true
269+ setIsAddingCredits ( true )
249270
250271 renderDialog ( )
251272
@@ -256,11 +277,24 @@ describe('TopUpCreditsDialogContentWorkspace', () => {
256277 expect ( screen . queryByText ( 'Select amount' ) ) . not . toBeInTheDocument ( )
257278 } )
258279
280+ it ( 'returns to amount selection when a reopened operation ends' , async ( ) => {
281+ setIsAddingCredits ( true )
282+
283+ renderDialog ( )
284+ expect ( screen . getByText ( 'Verify your payment' ) ) . toBeInTheDocument ( )
285+
286+ setIsAddingCredits ( false )
287+ await nextTick ( )
288+
289+ expect ( screen . getByText ( 'Select amount' ) ) . toBeInTheDocument ( )
290+ expect ( screen . queryByText ( 'Verify your payment' ) ) . not . toBeInTheDocument ( )
291+ } )
292+
259293 it ( 'hides topup verification after permission is revoked' , ( ) => {
260294 setCanTopUp ( false )
261- mockTopupActionOperation . value = {
295+ setTopupActionOperation ( {
262296 actionUrl : 'https://verify.example/sensitive-token'
263- }
297+ } )
264298
265299 renderDialog ( )
266300
0 commit comments