@@ -757,4 +757,78 @@ test.describe('api keys component @machine', () => {
757757 }
758758 } ) ;
759759 } ) ;
760+
761+ test ( 'shows error when creating API key with duplicate name' , async ( { page, context } ) => {
762+ const u = createTestUtils ( { app, page, context } ) ;
763+ await u . po . signIn . goTo ( ) ;
764+ await u . po . signIn . waitForMounted ( ) ;
765+ await u . po . signIn . signInWithEmailAndInstantPassword ( { email : fakeAdmin . email , password : fakeAdmin . password } ) ;
766+ await u . po . expect . toBeSignedIn ( ) ;
767+
768+ await u . po . page . goToRelative ( '/api-keys' ) ;
769+ await u . po . apiKeys . waitForMounted ( ) ;
770+
771+ const duplicateName = `${ fakeAdmin . firstName } -duplicate-${ Date . now ( ) } ` ;
772+
773+ // Create the first API key
774+ await u . po . apiKeys . clickAddButton ( ) ;
775+ await u . po . apiKeys . waitForFormOpened ( ) ;
776+ await u . po . apiKeys . typeName ( duplicateName ) ;
777+ await u . po . apiKeys . selectExpiration ( '1d' ) ;
778+ await u . po . apiKeys . clickSaveButton ( ) ;
779+
780+ await u . po . apiKeys . waitForCopyModalOpened ( ) ;
781+ await u . po . apiKeys . clickCopyAndCloseButton ( ) ;
782+ await u . po . apiKeys . waitForCopyModalClosed ( ) ;
783+ await u . po . apiKeys . waitForFormClosed ( ) ;
784+
785+ // Try to create another API key with the same name
786+ await u . po . apiKeys . clickAddButton ( ) ;
787+ await u . po . apiKeys . waitForFormOpened ( ) ;
788+ await u . po . apiKeys . typeName ( duplicateName ) ;
789+ await u . po . apiKeys . selectExpiration ( '1d' ) ;
790+ await u . po . apiKeys . clickSaveButton ( ) ;
791+
792+ // Verify error message is displayed
793+ await expect ( u . page . getByText ( 'API Key name already exists.' ) ) . toBeVisible ( { timeout : 5000 } ) ;
794+ } ) ;
795+
796+ test ( 'shows error when API key usage is exceeded for free plan' , async ( { page, context } ) => {
797+ const u = createTestUtils ( { app, page, context } ) ;
798+ await u . po . signIn . goTo ( ) ;
799+ await u . po . signIn . waitForMounted ( ) ;
800+ await u . po . signIn . signInWithEmailAndInstantPassword ( { email : fakeAdmin . email , password : fakeAdmin . password } ) ;
801+ await u . po . expect . toBeSignedIn ( ) ;
802+
803+ // Mock the API keys create endpoint to return 403 for free plan users who exceed free tier limits
804+ await page . route ( '*/**/api_keys*' , async route => {
805+ if ( route . request ( ) . method ( ) === 'POST' ) {
806+ await route . fulfill ( {
807+ status : 403 ,
808+ contentType : 'application/json' ,
809+ body : JSON . stringify ( {
810+ errors : [ { code : 'token_quota_exceeded' , message : 'Token quota exceeded' } ] ,
811+ } ) ,
812+ } ) ;
813+ } else {
814+ await route . continue ( ) ;
815+ }
816+ } ) ;
817+
818+ await u . po . page . goToRelative ( '/api-keys' ) ;
819+ await u . po . apiKeys . waitForMounted ( ) ;
820+
821+ await u . po . apiKeys . clickAddButton ( ) ;
822+ await u . po . apiKeys . waitForFormOpened ( ) ;
823+ await u . po . apiKeys . typeName ( `${ fakeAdmin . firstName } -test-usage-exceeded` ) ;
824+ await u . po . apiKeys . selectExpiration ( '1d' ) ;
825+ await u . po . apiKeys . clickSaveButton ( ) ;
826+
827+ // Verify error message is displayed
828+ await expect (
829+ u . page . getByText ( 'You have reached your usage limit. You can remove the limit by upgrading to a paid plan.' ) ,
830+ ) . toBeVisible ( { timeout : 5000 } ) ;
831+
832+ await u . page . unrouteAll ( ) ;
833+ } ) ;
760834} ) ;
0 commit comments