11/// <reference types="cypress" />
22import React from 'react' ;
3- import ProjectsScreen from './ProjectsScreen' ;
3+ import ProjectsScreen , { ProjectsScreenInner } from './ProjectsScreen' ;
44import { GlobalProvider } from '../context/GlobalContext' ;
55import { Provider } from 'react-redux' ;
66import {
@@ -19,6 +19,7 @@ import localizationReducer from '../store/localization/reducers';
1919import DataProvider from '../hoc/DataProvider' ;
2020import { UnsavedProvider } from '../context/UnsavedContext' ;
2121import { TokenContext } from '../context/TokenProvider' ;
22+ import { TeamContext } from '../context/TeamContext' ;
2223
2324// Create a mock liveQuery object with subscribe and query methods
2425const createMockLiveQuery = ( ) => ( {
@@ -147,10 +148,22 @@ describe('ProjectsScreen', () => {
147148 // Helper function to mount ProjectsScreen with all required providers
148149 const mountProjectsScreen = (
149150 initialState : ReturnType < typeof createInitialState > ,
150- initialEntries : string [ ] = [ '/projects' ]
151+ initialEntries : string [ ] = [ '/projects' ] ,
152+ options ?: {
153+ isAdmin ?: ( team : any ) => boolean ;
154+ personalTeam ?: string ;
155+ teams ?: any [ ] ;
156+ }
151157 ) => {
152158 const memory = createMockMemory ( ) ;
153159
160+ // Default options
161+ const {
162+ isAdmin = ( ) => false ,
163+ personalTeam = 'personal-team-id' ,
164+ teams = [ ] ,
165+ } = options || { } ;
166+
154167 // Create mock TokenContext value
155168 const mockTokenContextValue = {
156169 state : {
@@ -166,19 +179,80 @@ describe('ProjectsScreen', () => {
166179 setState : cy . stub ( ) ,
167180 } ;
168181
182+ // Create mock TeamContext value
183+ const mockTeamContextValue = {
184+ state : {
185+ lang : 'en' ,
186+ ts : { } as any ,
187+ resetOrbitError : cy . stub ( ) ,
188+ bookSuggestions : [ ] ,
189+ bookMap : { } as any ,
190+ allBookData : [ ] ,
191+ planTypes : [ ] ,
192+ isDeleting : false ,
193+ teams : teams ,
194+ personalTeam : personalTeam ,
195+ personalProjects : [ ] ,
196+ teamProjects : ( ) => [ ] ,
197+ teamMembers : ( ) => 0 ,
198+ loadProject : ( ) => { } ,
199+ setProjectParams : ( ) => [ '' , '' ] ,
200+ projectType : ( ) => '' ,
201+ projectSections : ( ) => '' ,
202+ projectDescription : ( ) => '' ,
203+ projectLanguage : ( ) => '' ,
204+ projectCreate : async ( ) => '' ,
205+ projectUpdate : ( ) => { } ,
206+ projectDelete : ( ) => { } ,
207+ teamCreate : ( ) => { } ,
208+ teamUpdate : ( ) => { } ,
209+ teamDelete : async ( ) => { } ,
210+ isAdmin : isAdmin ,
211+ isProjectAdmin : ( ) => false ,
212+ flatAdd : async ( ) => { } ,
213+ cardStrings : mockCardStrings ,
214+ sharedStrings : { } as any ,
215+ vProjectStrings : { } as any ,
216+ pickerStrings : { } as any ,
217+ projButtonStrings : { } as any ,
218+ newProjectStrings : { } as any ,
219+ importOpen : false ,
220+ setImportOpen : ( ) => { } ,
221+ importProject : undefined ,
222+ doImport : ( ) => { } ,
223+ resetProjectPermissions : async ( ) => { } ,
224+ generalBook : ( ) => '000' ,
225+ updateGeneralBooks : async ( ) => { } ,
226+ checkScriptureBooks : ( ) => { } ,
227+ tab : 0 ,
228+ setTab : ( ) => { } ,
229+ } ,
230+ setState : cy . stub ( ) ,
231+ } ;
232+
169233 const stateWithMemory = {
170234 ...initialState ,
171235 memory,
172236 } ;
173237
238+ // If options are provided, use ProjectsScreenInner with mock TeamContext
239+ // Otherwise, use ProjectsScreen with real TeamProvider
240+ const screenElement = options ? (
241+ < TeamContext . Provider value = { mockTeamContextValue as any } >
242+ < ProjectsScreenInner />
243+ </ TeamContext . Provider >
244+ ) : (
245+ < ProjectsScreen />
246+ ) ;
247+
174248 cy . mount (
175249 < MemoryRouter initialEntries = { initialEntries } >
176250 < Provider store = { mockStore } >
177251 < GlobalProvider init = { stateWithMemory } >
178252 < DataProvider dataStore = { memory } >
179253 < UnsavedProvider >
180254 < TokenContext . Provider value = { mockTokenContextValue as any } >
181- < ProjectsScreen />
255+ { screenElement }
182256 </ TokenContext . Provider >
183257 </ UnsavedProvider >
184258 </ DataProvider >
@@ -203,22 +277,73 @@ describe('ProjectsScreen', () => {
203277 cy . contains ( 'No projects yet.' ) . should ( 'be.visible' ) ;
204278 } ) ;
205279
206- it ( 'should show "Add New Project..." button' , ( ) => {
207- mountProjectsScreen ( createInitialState ( ) ) ;
280+ it ( 'should show "Add New Project..." button when isAdmin returns true' , ( ) => {
281+ const teamId = 'test-team-id' ;
282+ const mockTeam = {
283+ id : teamId ,
284+ type : 'organization' ,
285+ attributes : { name : 'Test Team' } ,
286+ } ;
287+
288+ cy . window ( ) . then ( ( win ) => {
289+ win . localStorage . setItem ( localUserKey ( LocalKey . team ) , teamId ) ;
290+ } ) ;
291+
292+ mountProjectsScreen ( createInitialState ( ) , [ '/projects' ] , {
293+ isAdmin : ( team : any ) => team ?. id === teamId ,
294+ personalTeam : 'personal-team-id' ,
295+ teams : [ mockTeam ] ,
296+ } ) ;
208297
209298 cy . get ( '#ProjectActAdd' ) . should ( 'be.visible' ) ;
210299 cy . contains ( 'Add New Project...' ) . should ( 'be.visible' ) ;
211300 } ) ;
212301
213302 it ( 'should open ProjectDialog when "Add New Project..." button is clicked' , ( ) => {
214- mountProjectsScreen ( createInitialState ( ) ) ;
303+ const teamId = 'test-team-id' ;
304+ const mockTeam = {
305+ id : teamId ,
306+ type : 'organization' ,
307+ attributes : { name : 'Test Team' } ,
308+ } ;
309+
310+ cy . window ( ) . then ( ( win ) => {
311+ win . localStorage . setItem ( localUserKey ( LocalKey . team ) , teamId ) ;
312+ } ) ;
313+
314+ mountProjectsScreen ( createInitialState ( ) , [ '/projects' ] , {
315+ isAdmin : ( team : any ) => team ?. id === teamId ,
316+ personalTeam : 'personal-team-id' ,
317+ teams : [ mockTeam ] ,
318+ } ) ;
215319
216320 cy . get ( '#ProjectActAdd' ) . click ( ) ;
217321
218322 // ProjectDialog should open (check for dialog role or form elements)
219323 cy . get ( '[role="dialog"]' ) . should ( 'be.visible' ) ;
220324 } ) ;
221325
326+ it ( 'should not show "Add New Project..." button when isAdmin returns false' , ( ) => {
327+ const teamId = 'test-team-id' ;
328+ const mockTeam = {
329+ id : teamId ,
330+ type : 'organization' ,
331+ attributes : { name : 'Test Team' } ,
332+ } ;
333+
334+ cy . window ( ) . then ( ( win ) => {
335+ win . localStorage . setItem ( localUserKey ( LocalKey . team ) , teamId ) ;
336+ } ) ;
337+
338+ mountProjectsScreen ( createInitialState ( ) , [ '/projects' ] , {
339+ isAdmin : ( ) => false , // Not admin
340+ personalTeam : 'personal-team-id' ,
341+ teams : [ mockTeam ] ,
342+ } ) ;
343+
344+ cy . get ( '#ProjectActAdd' ) . should ( 'not.exist' ) ;
345+ } ) ;
346+
222347 it ( 'should show "Switch Teams" button' , ( ) => {
223348 mountProjectsScreen ( createInitialState ( ) ) ;
224349
0 commit comments