@@ -205,4 +205,41 @@ describe("Profile API keys", () => {
205205 expect ( screen . getByRole ( "button" , { name : / c r e a t e a p i k e y / i } ) ) . toBeDisabled ( ) ;
206206 expect ( api . createApiKey ) . not . toHaveBeenCalled ( ) ;
207207 } ) ;
208+
209+ it ( "keeps a one-time token visible if creating another API key fails" , async ( ) => {
210+ vi . mocked ( api . createApiKey )
211+ . mockResolvedValueOnce ( {
212+ apiKey : {
213+ ...existingApiKey ,
214+ id : "key-2" ,
215+ name : "First Token" ,
216+ prefix : "exd_key_first" ,
217+ } ,
218+ token : "exd_key_first.secret-token-value" ,
219+ } )
220+ . mockRejectedValueOnce ( new Error ( "Network error" ) ) ;
221+
222+ render (
223+ < MemoryRouter >
224+ < Profile />
225+ </ MemoryRouter >
226+ ) ;
227+
228+ await screen . findByText ( "Existing Key" ) ;
229+
230+ fireEvent . change ( screen . getByLabelText ( / a p i k e y n a m e / i) , {
231+ target : { value : "First Token" } ,
232+ } ) ;
233+ fireEvent . click ( screen . getByRole ( "button" , { name : / c r e a t e a p i k e y / i } ) ) ;
234+
235+ expect ( await screen . findByDisplayValue ( "exd_key_first.secret-token-value" ) ) . toBeInTheDocument ( ) ;
236+
237+ fireEvent . change ( screen . getByLabelText ( / a p i k e y n a m e / i) , {
238+ target : { value : "Second Token" } ,
239+ } ) ;
240+ fireEvent . click ( screen . getByRole ( "button" , { name : / c r e a t e a p i k e y / i } ) ) ;
241+
242+ expect ( await screen . findByText ( / f a i l e d t o c r e a t e a p i k e y / i) ) . toBeInTheDocument ( ) ;
243+ expect ( screen . getByDisplayValue ( "exd_key_first.secret-token-value" ) ) . toBeInTheDocument ( ) ;
244+ } ) ;
208245} ) ;
0 commit comments