1- import { screen } from '@testing-library/react' ;
1+ import { screen , within } from '@testing-library/react' ;
2+ import userEvent from '@testing-library/user-event' ;
23import { renderWrapper } from '@src/setupTest' ;
4+ import { useValidateUserPermissionsNonSuspense } from '@src/data/hooks' ;
5+ import { CONTENT_COURSE_PERMISSIONS , CONTENT_LIBRARY_PERMISSIONS } from '@src/authz-module/roles-permissions' ;
36import RolesFilter from './RolesFilter' ;
47
8+ jest . mock ( '@src/data/hooks' , ( ) => ( {
9+ useValidateUserPermissionsNonSuspense : jest . fn ( ) ,
10+ } ) ) ;
11+
12+ const mockUsePermissions = useValidateUserPermissionsNonSuspense as jest . Mock ;
13+
14+ const permissionsData = ( { library, course } : { library ?: boolean ; course ?: boolean } ) => [
15+ { action : CONTENT_LIBRARY_PERMISSIONS . VIEW_LIBRARY_TEAM , allowed : ! ! library } ,
16+ { action : CONTENT_COURSE_PERMISSIONS . VIEW_COURSE_TEAM , allowed : ! ! course } ,
17+ ] ;
18+
519describe ( 'RolesFilter' , ( ) => {
620 const defaultProps = {
721 filterButtonText : 'Roles' ,
@@ -10,11 +24,17 @@ describe('RolesFilter', () => {
1024 disabled : false ,
1125 } ;
1226
27+ const openDropdown = async ( user : ReturnType < typeof userEvent . setup > ) => {
28+ await user . click ( screen . getByRole ( 'button' , { name : / R o l e s / i } ) ) ;
29+ return within ( await screen . findByRole ( 'group' , { name : 'Roles' } ) ) ;
30+ } ;
31+
1332 beforeEach ( ( ) => {
1433 jest . clearAllMocks ( ) ;
34+ mockUsePermissions . mockReturnValue ( { data : permissionsData ( { library : true , course : true } ) } ) ;
1535 } ) ;
1636
17- it ( 'renders without crashing ' , ( ) => {
37+ it ( 'renders the filter toggle ' , ( ) => {
1838 renderWrapper ( < RolesFilter { ...defaultProps } /> ) ;
1939 expect ( screen . getByText ( 'Roles' ) ) . toBeInTheDocument ( ) ;
2040 } ) ;
@@ -29,9 +49,52 @@ describe('RolesFilter', () => {
2949 expect ( screen . getByText ( 'Select Roles' ) ) . toBeInTheDocument ( ) ;
3050 } ) ;
3151
32- it ( 'calls setFilter when filter changes' , ( ) => {
33- const mockSetFilter = jest . fn ( ) ;
34- renderWrapper ( < RolesFilter { ...defaultProps } setFilter = { mockSetFilter } /> ) ;
35- expect ( screen . getByText ( 'Roles' ) ) . toBeInTheDocument ( ) ;
52+ it ( 'calls setFilter with the selected role when a role is checked' , async ( ) => {
53+ const user = userEvent . setup ( ) ;
54+ const setFilter = jest . fn ( ) ;
55+ renderWrapper ( < RolesFilter { ...defaultProps } setFilter = { setFilter } /> ) ;
56+ const menu = await openDropdown ( user ) ;
57+ await user . click ( menu . getByLabelText ( 'Course Admin' ) ) ;
58+ expect ( setFilter ) . toHaveBeenCalledWith (
59+ [ 'course_admin' ] ,
60+ expect . objectContaining ( { value : 'course_admin' , displayName : 'Course Admin' } ) ,
61+ ) ;
62+ } ) ;
63+
64+ it ( 'shows only library roles when the user can view the library scope only' , async ( ) => {
65+ const user = userEvent . setup ( ) ;
66+ mockUsePermissions . mockReturnValue ( { data : permissionsData ( { library : true } ) } ) ;
67+ renderWrapper ( < RolesFilter { ...defaultProps } /> ) ;
68+ const menu = await openDropdown ( user ) ;
69+ expect ( menu . getByText ( 'Libraries' ) ) . toBeInTheDocument ( ) ;
70+ expect ( menu . getByLabelText ( 'Library Admin' ) ) . toBeInTheDocument ( ) ;
71+ expect ( menu . queryByText ( 'Courses' ) ) . not . toBeInTheDocument ( ) ;
72+ expect ( menu . queryByLabelText ( 'Course Admin' ) ) . not . toBeInTheDocument ( ) ;
73+ } ) ;
74+
75+ it ( 'shows both course and library roles when the user can view both scopes' , async ( ) => {
76+ const user = userEvent . setup ( ) ;
77+ renderWrapper ( < RolesFilter { ...defaultProps } /> ) ;
78+ const menu = await openDropdown ( user ) ;
79+ expect ( menu . getByText ( 'Courses' ) ) . toBeInTheDocument ( ) ;
80+ expect ( menu . getByText ( 'Libraries' ) ) . toBeInTheDocument ( ) ;
81+ } ) ;
82+
83+ it ( 'shows no role options when the user cannot view any scope' , async ( ) => {
84+ const user = userEvent . setup ( ) ;
85+ mockUsePermissions . mockReturnValue ( { data : permissionsData ( { } ) } ) ;
86+ renderWrapper ( < RolesFilter { ...defaultProps } /> ) ;
87+ const menu = await openDropdown ( user ) ;
88+ expect ( menu . queryByText ( 'Courses' ) ) . not . toBeInTheDocument ( ) ;
89+ expect ( menu . queryByText ( 'Libraries' ) ) . not . toBeInTheDocument ( ) ;
90+ } ) ;
91+
92+ it ( 'shows no role options while permissions are still loading' , async ( ) => {
93+ const user = userEvent . setup ( ) ;
94+ mockUsePermissions . mockReturnValue ( { data : undefined } ) ;
95+ renderWrapper ( < RolesFilter { ...defaultProps } /> ) ;
96+ const menu = await openDropdown ( user ) ;
97+ expect ( menu . queryByText ( 'Courses' ) ) . not . toBeInTheDocument ( ) ;
98+ expect ( menu . queryByText ( 'Libraries' ) ) . not . toBeInTheDocument ( ) ;
3699 } ) ;
37100} ) ;
0 commit comments