1- import { describe , it , expect , vi , beforeEach } from 'vitest'
1+ import { describe , it , expect , vi } from 'vitest'
22import { render , screen } from '@testing-library/react'
33import { ClusterAuthBadges , ClusterIAMRefreshHint } from './ClusterAuthBadges'
44import type { ClusterInfo } from '../../../hooks/useMCP'
@@ -8,145 +8,176 @@ vi.mock('react-i18next', () => ({
88 useTranslation : ( ) => ( { t : ( key : string ) => key } ) ,
99} ) )
1010
11- vi . mock ( '../../../lib/clipboard' , ( ) => ( {
12- copyToClipboard : vi . fn ( ) ,
13- } ) )
14-
1511describe ( 'ClusterAuthBadges' , ( ) => {
16- it ( 'renders IAM badge and exec login hint in the title' , ( ) => {
17- const cluster = { authMethod : 'exec' , name : 'eks-prod' , user : 'aws-user' } as ClusterInfo
18-
12+ it ( 'renders IAM badge for exec auth method' , ( ) => {
13+ const cluster = { authMethod : 'exec' , name : 'test' , user : 'test' } as ClusterInfo
1914 render ( < ClusterAuthBadges cluster = { cluster } className = "test-class" /> )
2015
2116 const badge = screen . getByText ( 'IAM' )
17+ expect ( badge ) . toBeInTheDocument ( )
2218 expect ( badge ) . toHaveClass ( 'test-class' )
23- expect ( badge ) . toHaveAttribute ( 'title' , expect . stringContaining ( 'aws sso login' ) )
2419 } )
2520
26- it ( 'renders token and certificate badges for supported auth methods' , ( ) => {
27- const { rerender } = render (
28- < ClusterAuthBadges
29- cluster = { { authMethod : 'token' , name : 'demo' , user : 'demo' } as ClusterInfo }
30- className = "token-class"
31- /> ,
32- )
21+ it ( 'renders token badge for token auth method' , ( ) => {
22+ const cluster = { authMethod : 'token' , name : 'test' , user : 'test' } as ClusterInfo
23+ render ( < ClusterAuthBadges cluster = { cluster } className = "test-class" /> )
3324
3425 expect ( screen . getByText ( 'token' ) ) . toBeInTheDocument ( )
26+ } )
3527
36- rerender (
37- < ClusterAuthBadges
38- cluster = { { authMethod : 'certificate' , name : 'demo' , user : 'demo' } as ClusterInfo }
39- className = "cert-class"
40- /> ,
41- )
28+ it ( 'renders cert badge for certificate auth method' , ( ) => {
29+ const cluster = { authMethod : 'certificate' , name : 'test' , user : 'test' } as ClusterInfo
30+ render ( < ClusterAuthBadges cluster = { cluster } className = "test-class" /> )
4231
4332 expect ( screen . getByText ( 'cert' ) ) . toBeInTheDocument ( )
4433 } )
4534
46- it ( 'returns null for missing or unsupported auth methods' , ( ) => {
47- const { container, rerender } = render (
48- < ClusterAuthBadges cluster = { { name : 'demo' } as ClusterInfo } className = "ignored" /> ,
49- )
35+ it ( 'renders IAM badge for auth-provider auth method' , ( ) => {
36+ const cluster = { authMethod : 'auth-provider' , name : 'test' , user : 'test' } as ClusterInfo
37+ render ( < ClusterAuthBadges cluster = { cluster } className = "test-class" /> )
38+
39+ expect ( screen . getByText ( 'IAM' ) ) . toBeInTheDocument ( )
40+ } )
41+
42+ it ( 'returns null when authMethod is not set' , ( ) => {
43+ const cluster = { name : 'test' } as ClusterInfo
44+ const { container } = render ( < ClusterAuthBadges cluster = { cluster } className = "test-class" /> )
5045
5146 expect ( container . firstChild ) . toBeNull ( )
47+ } )
5248
53- rerender (
54- < ClusterAuthBadges
55- cluster = { { authMethod : 'custom' , name : 'demo' } as ClusterInfo }
56- className = "ignored"
57- /> ,
58- )
49+ it ( 'returns null when authMethod is unknown' , ( ) => {
50+ const cluster = { authMethod : 'unknown-method' , name : 'test' } as ClusterInfo
51+ const { container } = render ( < ClusterAuthBadges cluster = { cluster } className = "test-class" /> )
5952
6053 expect ( container . firstChild ) . toBeNull ( )
6154 } )
55+
56+ it ( 'includes login hint in title for exec auth with AWS' , ( ) => {
57+ const cluster = { authMethod : 'exec' , user : 'aws-user' , name : 'test' } as ClusterInfo
58+ render ( < ClusterAuthBadges cluster = { cluster } className = "test-class" /> )
59+
60+ const badge = screen . getByText ( 'IAM' )
61+ expect ( badge ) . toHaveAttribute ( 'title' , expect . stringContaining ( 'aws sso login' ) )
62+ } )
63+
64+ it ( 'does not include login hint in title for exec auth without provider detection' , ( ) => {
65+ const cluster = { authMethod : 'exec' , user : 'unknown' , name : 'test' } as ClusterInfo
66+ render ( < ClusterAuthBadges cluster = { cluster } className = "test-class" /> )
67+
68+ const badge = screen . getByText ( 'IAM' )
69+ expect ( badge ) . toHaveAttribute ( 'title' , 'Auth: IAM (exec plugin)' )
70+ } )
6271} )
6372
6473describe ( 'ClusterIAMRefreshHint' , ( ) => {
6574 beforeEach ( ( ) => {
66- vi . clearAllMocks ( )
67- } )
68-
69- it ( 'renders an IAM login hint for expired exec tokens' , ( ) => {
70- render (
71- < ClusterIAMRefreshHint
72- cluster = { {
73- authMethod : 'exec' ,
74- user : 'aws-user' ,
75- name : 'demo ' ,
76- errorType : 'auth ' ,
77- reachable : false ,
78- } as ClusterInfo }
79- className = "hint-class"
80- /> ,
81- )
75+ Object . assign ( navigator , {
76+ clipboard : {
77+ writeText : vi . fn ( ) . mockResolvedValue ( undefined ) ,
78+ } ,
79+ } )
80+ } )
81+
82+ it ( 'renders login hint for exec auth with expired token' , ( ) => {
83+ const cluster = {
84+ authMethod : 'exec ' ,
85+ user : 'aws-user ' ,
86+ name : 'test' ,
87+ errorType : 'auth' ,
88+ reachable : false ,
89+ } as ClusterInfo
90+ render ( < ClusterIAMRefreshHint cluster = { cluster } className = "test-class" /> )
8291
83- expect ( screen . getByText ( / L o g i n : / ) ) . toBeInTheDocument ( )
8492 expect ( screen . getByText ( 'aws sso login' ) ) . toBeInTheDocument ( )
85- expect ( screen . getByLabelText ( 'Copy command to clipboard' ) ) . toBeInTheDocument ( )
93+ expect ( screen . getByText ( / L o g i n : / ) ) . toBeInTheDocument ( )
8694 } )
8795
88- it ( 'supports custom and omitted labels' , ( ) => {
89- const { rerender } = render (
90- < ClusterIAMRefreshHint
91- cluster = { {
92- authMethod : 'exec' ,
93- user : 'az-user' ,
94- name : 'demo' ,
95- errorType : 'auth' ,
96- reachable : false ,
97- } as ClusterInfo }
98- className = "hint-class"
99- label = "Custom:"
100- /> ,
101- )
96+ it ( 'renders login hint for unreachable exec cluster' , ( ) => {
97+ const cluster = {
98+ authMethod : 'exec' ,
99+ user : 'gke-user' ,
100+ name : 'test' ,
101+ reachable : false ,
102+ } as ClusterInfo
103+ render ( < ClusterIAMRefreshHint cluster = { cluster } className = "test-class" /> )
102104
103- expect ( screen . getByText ( / C u s t o m : / ) ) . toBeInTheDocument ( )
105+ expect ( screen . getByText ( 'gcloud auth login' ) ) . toBeInTheDocument ( )
106+ } )
104107
105- rerender (
106- < ClusterIAMRefreshHint
107- cluster = { {
108- authMethod : 'exec' ,
109- user : 'az-user' ,
110- name : 'demo' ,
111- errorType : 'auth' ,
112- reachable : false ,
113- } as ClusterInfo }
114- className = "hint-class"
115- label = { null }
116- /> ,
117- )
108+ it ( 'does not render for non-exec auth' , ( ) => {
109+ const cluster = {
110+ authMethod : 'token' ,
111+ errorType : 'auth' ,
112+ reachable : false ,
113+ } as ClusterInfo
114+ const { container } = render ( < ClusterIAMRefreshHint cluster = { cluster } className = "test-class" /> )
118115
119- expect ( screen . queryByText ( / L o g i n : / ) ) . not . toBeInTheDocument ( )
120- expect ( screen . getByText ( 'az login' ) ) . toBeInTheDocument ( )
116+ expect ( container . firstChild ) . toBeNull ( )
121117 } )
122118
123- it ( 'returns null when the cluster does not need or cannot infer refresh help' , ( ) => {
124- const { container, rerender } = render (
125- < ClusterIAMRefreshHint
126- cluster = { {
127- authMethod : 'token' ,
128- errorType : 'auth' ,
129- reachable : false ,
130- } as ClusterInfo }
131- className = "hint-class"
132- /> ,
133- )
119+ it ( 'does not render for reachable cluster with valid token' , ( ) => {
120+ const cluster = {
121+ authMethod : 'exec' ,
122+ user : 'aws-user' ,
123+ name : 'test' ,
124+ reachable : true ,
125+ } as ClusterInfo
126+ const { container } = render ( < ClusterIAMRefreshHint cluster = { cluster } className = "test-class" /> )
134127
135128 expect ( container . firstChild ) . toBeNull ( )
129+ } )
136130
137- rerender (
138- < ClusterIAMRefreshHint
139- cluster = { {
140- authMethod : 'exec' ,
141- user : 'custom-user' ,
142- name : 'custom-cluster' ,
143- errorType : 'auth' ,
144- reachable : false ,
145- } as ClusterInfo }
146- className = "hint-class"
147- /> ,
148- )
131+ it ( 'does not render when no IAM hint is available' , ( ) => {
132+ const cluster = {
133+ authMethod : 'exec' ,
134+ user : 'unknown' ,
135+ name : 'test' ,
136+ errorType : 'auth' ,
137+ reachable : false ,
138+ } as ClusterInfo
139+ const { container } = render ( < ClusterIAMRefreshHint cluster = { cluster } className = "test-class" /> )
149140
150141 expect ( container . firstChild ) . toBeNull ( )
151142 } )
143+
144+ it ( 'renders custom label when provided' , ( ) => {
145+ const cluster = {
146+ authMethod : 'exec' ,
147+ user : 'az-user' ,
148+ name : 'test' ,
149+ errorType : 'auth' ,
150+ reachable : false ,
151+ } as ClusterInfo
152+ render ( < ClusterIAMRefreshHint cluster = { cluster } className = "test-class" label = "Custom:" /> )
153+
154+ expect ( screen . getByText ( / C u s t o m : / ) ) . toBeInTheDocument ( )
155+ } )
156+
157+ it ( 'renders without label when label is null' , ( ) => {
158+ const cluster = {
159+ authMethod : 'exec' ,
160+ user : 'az-user' ,
161+ name : 'test' ,
162+ errorType : 'auth' ,
163+ reachable : false ,
164+ } as ClusterInfo
165+ render ( < ClusterIAMRefreshHint cluster = { cluster } className = "test-class" label = { null } /> )
166+
167+ expect ( screen . queryByText ( / L o g i n : / ) ) . not . toBeInTheDocument ( )
168+ expect ( screen . getByText ( 'az login' ) ) . toBeInTheDocument ( )
169+ } )
170+
171+ it ( 'includes copy button' , ( ) => {
172+ const cluster = {
173+ authMethod : 'exec' ,
174+ user : 'aws-user' ,
175+ name : 'test' ,
176+ errorType : 'auth' ,
177+ reachable : false ,
178+ } as ClusterInfo
179+ render ( < ClusterIAMRefreshHint cluster = { cluster } className = "test-class" /> )
180+
181+ expect ( screen . getByLabelText ( 'Copy command to clipboard' ) ) . toBeInTheDocument ( )
182+ } )
152183} )
0 commit comments