@@ -9,14 +9,12 @@ import { cleanup, render, waitFor } from 'test-helpers/test-utils';
99import { Mock } from 'vitest' ;
1010import { ITeamPoliciesContainerProps , TeamPoliciesContainer } from './TeamPoliciesContainer' ;
1111
12- // Types for DataGrid mock
1312interface MockDataGridProps {
1413 rows : ITeamPolicyDetails [ ] ;
1514 columns : GridColDef [ ] ;
1615 localeText ?: { noRowsLabel ?: string } ;
1716}
1817
19- // Simple DataGrid mock - just renders rows as divs
2018vi . mock ( '@mui/x-data-grid' , ( ) => ( {
2119 DataGrid : ( { rows, columns, localeText } : MockDataGridProps ) => (
2220 < div data-testid = "mock-data-grid" >
@@ -27,7 +25,6 @@ vi.mock('@mui/x-data-grid', () => ({
2725 < div key = { row . team_policy_id } data-testid = { `row-${ row . team_policy_id } ` } >
2826 < span > { row . team_name } </ span >
2927 < span > { row . policy_name } </ span >
30- { /* Render actions column */ }
3128 { columns . find ( ( c ) => c . field === 'actions' ) ?. renderCell ?.( { row } as never ) }
3229 </ div >
3330 ) )
@@ -70,11 +67,19 @@ const mockPolicies: IPolicy[] = [
7067
7168const mockCreateTeamPolicy = vi . fn ( ) ;
7269const mockDeleteTeamPolicy = vi . fn ( ) ;
70+ const mockGetTeams = vi . fn ( ) ;
71+ const mockGetPolicies = vi . fn ( ) ;
7372
7473const mockUseApi = {
7574 teamPolicies : {
7675 createTeamPolicy : mockCreateTeamPolicy ,
7776 deleteTeamPolicy : mockDeleteTeamPolicy
77+ } ,
78+ teams : {
79+ getTeams : mockGetTeams
80+ } ,
81+ policies : {
82+ getPolicies : mockGetPolicies
7883 }
7984} ;
8085
@@ -100,6 +105,8 @@ const renderComponent = (props: Partial<ITeamPoliciesContainerProps> = {}) => {
100105
101106describe ( 'TeamPoliciesContainer' , ( ) => {
102107 beforeEach ( ( ) => {
108+ mockGetTeams . mockResolvedValue ( { teams : mockTeams } ) ;
109+ mockGetPolicies . mockResolvedValue ( { policies : mockPolicies } ) ;
103110 mockBiohubApi . mockImplementation ( ( ) => mockUseApi ) ;
104111 } ) ;
105112
@@ -108,154 +115,80 @@ describe('TeamPoliciesContainer', () => {
108115 vi . clearAllMocks ( ) ;
109116 } ) ;
110117
111- describe ( 'Header' , ( ) => {
112- it ( 'displays rowCount in header' , async ( ) => {
113- // Step 1: Render with default props (rowCount: 2)
114- const { getByText } = renderComponent ( ) ;
118+ it ( 'displays rowCount in header' , async ( ) => {
119+ const { getByText } = renderComponent ( ) ;
115120
116- // Step 2: Verify dynamic rowCount appears in header
117- await waitFor ( ( ) => {
118- expect ( getByText ( '(2)' ) ) . toBeVisible ( ) ;
119- } ) ;
121+ await waitFor ( ( ) => {
122+ expect ( getByText ( '(2)' ) ) . toBeVisible ( ) ;
120123 } ) ;
124+ } ) ;
121125
122- it ( 'shows team-specific header when team is selected' , async ( ) => {
123- // Step 1: Render with selectedTeam prop
124- const { getByText } = renderComponent ( { selectedTeam : mockTeams [ 0 ] } ) ;
126+ it ( 'opens Add Assignment dialog when Add is clicked' , async ( ) => {
127+ const { getByRole, getByText } = renderComponent ( ) ;
125128
126- // Step 2: Verify header shows team-specific text
127- await waitFor ( ( ) => {
128- expect ( getByText ( 'Policies for "Alpha Team"' ) ) . toBeVisible ( ) ;
129- } ) ;
129+ await waitFor ( ( ) => {
130+ expect ( getByRole ( 'button' , { name : / a d d / i } ) ) . toBeEnabled ( ) ;
130131 } ) ;
131132
132- it ( 'shows policy-specific header when policy is selected' , async ( ) => {
133- // Step 1: Render with selectedPolicy prop
134- const { getByText } = renderComponent ( { selectedPolicy : mockPolicies [ 0 ] } ) ;
133+ fireEvent . click ( getByRole ( 'button' , { name : / a d d / i } ) ) ;
135134
136- // Step 2: Verify header shows policy-specific text
137- await waitFor ( ( ) => {
138- expect ( getByText ( 'Teams with "Data Access Policy"' ) ) . toBeVisible ( ) ;
139- } ) ;
140- } ) ;
141-
142- it ( 'shows combined header when both team and policy are selected' , async ( ) => {
143- // Step 1: Render with both selectedTeam and selectedPolicy props
144- const { getByText } = renderComponent ( {
145- selectedTeam : mockTeams [ 0 ] ,
146- selectedPolicy : mockPolicies [ 0 ]
147- } ) ;
148-
149- // Step 2: Verify header shows combined assignment text
150- await waitFor ( ( ) => {
151- expect ( getByText ( 'Assignment: Alpha Team + Data Access Policy' ) ) . toBeVisible ( ) ;
152- } ) ;
135+ await waitFor ( ( ) => {
136+ expect ( getByText ( 'Add Assignment' ) ) . toBeVisible ( ) ;
153137 } ) ;
154138 } ) ;
155139
156- describe ( 'Assign Button' , ( ) => {
157- it ( 'does not show Assign button when no selection' , async ( ) => {
158- // Step 1: Render with no selection (default props)
159- const { queryByRole } = renderComponent ( ) ;
140+ it ( 'calls createTeamPolicy API when Add dialog is saved' , async ( ) => {
141+ mockCreateTeamPolicy . mockResolvedValueOnce ( { } ) ;
142+ const mockRefresh = vi . fn ( ) ;
160143
161- // Step 2: Verify Assign button is NOT visible
162- await waitFor ( ( ) => {
163- expect ( queryByRole ( 'button' , { name : / a s s i g n / i } ) ) . toBeNull ( ) ;
164- } ) ;
144+ const { getByRole , getByTestId } = renderComponent ( {
145+ selectedTeam : mockTeams [ 2 ] ,
146+ selectedPolicy : mockPolicies [ 2 ] ,
147+ refresh : mockRefresh
165148 } ) ;
166149
167- it ( 'does not show Assign button when only team is selected' , async ( ) => {
168- // Step 1: Render with only selectedTeam (no policy)
169- const { queryByRole } = renderComponent ( { selectedTeam : mockTeams [ 0 ] } ) ;
170-
171- // Step 2: Verify Assign button is NOT visible (needs both)
172- await waitFor ( ( ) => {
173- expect ( queryByRole ( 'button' , { name : / a s s i g n / i } ) ) . toBeNull ( ) ;
174- } ) ;
150+ await waitFor ( ( ) => {
151+ expect ( getByRole ( 'button' , { name : / a d d / i } ) ) . toBeEnabled ( ) ;
175152 } ) ;
176153
177- it ( 'does not show Assign button when only policy is selected' , async ( ) => {
178- // Step 1: Render with only selectedPolicy (no team)
179- const { queryByRole } = renderComponent ( { selectedPolicy : mockPolicies [ 0 ] } ) ;
154+ fireEvent . click ( getByRole ( 'button' , { name : / a d d / i } ) ) ;
155+ fireEvent . click ( getByTestId ( 'edit-dialog-save-button' ) ) ;
180156
181- // Step 2: Verify Assign button is NOT visible (needs both)
182- await waitFor ( ( ) => {
183- expect ( queryByRole ( 'button' , { name : / a s s i g n / i } ) ) . toBeNull ( ) ;
157+ await waitFor ( ( ) => {
158+ expect ( mockCreateTeamPolicy ) . toHaveBeenCalledWith ( {
159+ team_id : 'team-3' ,
160+ policy_id : 'policy-3'
184161 } ) ;
185162 } ) ;
186163
187- it ( 'shows Assign button when both selected and assignment does not exist' , async ( ) => {
188- // Step 1: Render with team + policy that are NOT already assigned
189- const { getByRole } = renderComponent ( {
190- selectedTeam : mockTeams [ 2 ] , // Gamma Team - not in mockTeamPolicies
191- selectedPolicy : mockPolicies [ 2 ] // Admin Policy - not in mockTeamPolicies
192- } ) ;
193-
194- // Step 2: Verify Assign button IS visible (can create new assignment)
195- await waitFor ( ( ) => {
196- expect ( getByRole ( 'button' , { name : / a s s i g n / i } ) ) . toBeVisible ( ) ;
197- } ) ;
164+ await waitFor ( ( ) => {
165+ expect ( mockRefresh ) . toHaveBeenCalled ( ) ;
198166 } ) ;
167+ } ) ;
199168
200- it ( 'does not show Assign button when assignment already exists' , async ( ) => {
201- // Step 1: Render with team + policy that ARE already assigned
202- const { queryByRole } = renderComponent ( {
203- selectedTeam : mockTeams [ 0 ] , // Alpha Team
204- selectedPolicy : mockPolicies [ 0 ] // Data Access Policy - already assigned
205- } ) ;
169+ it ( 'opens Edit Assignment dialog from row action' , async ( ) => {
170+ const { getByTestId, getByText } = renderComponent ( ) ;
206171
207- // Step 2: Verify Assign button is NOT visible (duplicate prevention)
208- await waitFor ( ( ) => {
209- expect ( queryByRole ( 'button' , { name : / a s s i g n / i } ) ) . toBeNull ( ) ;
210- } ) ;
172+ await waitFor ( ( ) => {
173+ expect ( getByTestId ( 'row-tp-1' ) ) . toBeVisible ( ) ;
211174 } ) ;
212175
213- it ( 'calls createTeamPolicy API when Assign is clicked' , async ( ) => {
214- // Step 1: Setup - make createTeamPolicy return {} (simulates successful API response)
215- mockCreateTeamPolicy . mockResolvedValueOnce ( { } ) ;
216-
217- // Step 2: Create mock refresh function to verify it's called after submit
218- const mockRefresh = vi . fn ( ) ;
219-
220- // Step 3: Render component with selected team + policy (enables Assign button)
221- const { getByRole } = renderComponent ( {
222- selectedTeam : mockTeams [ 2 ] ,
223- selectedPolicy : mockPolicies [ 2 ] ,
224- refresh : mockRefresh
225- } ) ;
176+ const firstRow = getByTestId ( 'row-tp-1' ) ;
177+ const rowActionButton = firstRow . querySelector ( '[data-testid="custom-menu-icon-Actions"]' ) ;
178+ expect ( rowActionButton ) . toBeTruthy ( ) ;
179+ fireEvent . click ( rowActionButton as Element ) ;
180+ fireEvent . click ( getByTestId ( 'custom-menu-icon-item-Editassignment' ) ) ;
226181
227- // Step 4: Wait for Assign button to appear
228- await waitFor ( ( ) => {
229- expect ( getByRole ( 'button' , { name : / a s s i g n / i } ) ) . toBeVisible ( ) ;
230- } ) ;
231-
232- // Step 5: Click Assign button
233- fireEvent . click ( getByRole ( 'button' , { name : / a s s i g n / i } ) ) ;
234-
235- // Step 6: Verify API was called with correct params
236- await waitFor ( ( ) => {
237- expect ( mockCreateTeamPolicy ) . toHaveBeenCalledWith ( {
238- team_id : 'team-3' ,
239- policy_id : 'policy-3'
240- } ) ;
241- } ) ;
242-
243- // Step 7: Verify refresh was called after success
244- await waitFor ( ( ) => {
245- expect ( mockRefresh ) . toHaveBeenCalled ( ) ;
246- } ) ;
182+ await waitFor ( ( ) => {
183+ expect ( getByText ( 'Edit Assignment' ) ) . toBeVisible ( ) ;
247184 } ) ;
248185 } ) ;
249186
250- describe ( 'Empty State' , ( ) => {
251- it ( 'shows empty state message' , async ( ) => {
252- // Step 1: Render with empty teamPolicies array
253- const { getByText } = renderComponent ( { teamPolicies : [ ] , rowCount : 0 } ) ;
187+ it ( 'shows empty state message' , async ( ) => {
188+ const { getByText } = renderComponent ( { teamPolicies : [ ] , rowCount : 0 } ) ;
254189
255- // Step 2: Verify empty state message appears (from DataGrid localeText)
256- await waitFor ( ( ) => {
257- expect ( getByText ( 'No Team-Policy Assignments' ) ) . toBeVisible ( ) ;
258- } ) ;
190+ await waitFor ( ( ) => {
191+ expect ( getByText ( 'No Team-Policy Assignments' ) ) . toBeVisible ( ) ;
259192 } ) ;
260193 } ) ;
261194} ) ;
0 commit comments