diff --git a/app/src/androidTest/java/com/github/se/assocify/screens/profile/ProfileScreenTest.kt b/app/src/androidTest/java/com/github/se/assocify/screens/profile/ProfileScreenTest.kt index bb2fc9032..4c932584c 100644 --- a/app/src/androidTest/java/com/github/se/assocify/screens/profile/ProfileScreenTest.kt +++ b/app/src/androidTest/java/com/github/se/assocify/screens/profile/ProfileScreenTest.kt @@ -365,4 +365,52 @@ class ProfileScreenTest : TestCase(kaspressoBuilder = Kaspresso.Builder.withComp assert(mViewmodel.uiState.value.profileImageURI != null) } } + + @Test + fun rolePermissionTest() { + every { mockUserAPI.getCurrentUserRole(any(), any()) } answers + { + val onSuccessCallback = firstArg<(PermissionRole) -> Unit>() + onSuccessCallback(PermissionRole("1", "asso", RoleType.MEMBER)) + } + with(composeTestRule) { + mViewmodel.loadProfile() + onNodeWithTag("profileRole").assertIsDisplayed() + onNodeWithText("MEMBER").assertIsDisplayed() + onNodeWithText("Manage", true).assertIsNotDisplayed() + } + every { mockUserAPI.getCurrentUserRole(any(), any()) } answers + { + val onSuccessCallback = firstArg<(PermissionRole) -> Unit>() + onSuccessCallback(PermissionRole("1", "asso", RoleType.STAFF)) + } + with(composeTestRule) { + mViewmodel.loadProfile() + onNodeWithTag("profileRole").assertIsDisplayed() + onNodeWithText("STAFF").assertIsDisplayed() + onNodeWithText("Manage", true).assertIsNotDisplayed() + } + every { mockUserAPI.getCurrentUserRole(any(), any()) } answers + { + val onSuccessCallback = firstArg<(PermissionRole) -> Unit>() + onSuccessCallback(PermissionRole("1", "asso", RoleType.TREASURY)) + } + with(composeTestRule) { + mViewmodel.loadProfile() + onNodeWithTag("profileRole").assertIsDisplayed() + onNodeWithText("TREASURY").assertIsDisplayed() + onNodeWithText("Manage", true).assertIsDisplayed() + } + every { mockUserAPI.getCurrentUserRole(any(), any()) } answers + { + val onSuccessCallback = firstArg<(PermissionRole) -> Unit>() + onSuccessCallback(PermissionRole("1", "asso", RoleType.COMMITTEE)) + } + with(composeTestRule) { + mViewmodel.loadProfile() + onNodeWithTag("profileRole").assertIsDisplayed() + onNodeWithText("COMMITTEE").assertIsDisplayed() + onNodeWithText("Manage", true).assertIsDisplayed() + } + } } diff --git a/app/src/main/java/com/github/se/assocify/ui/screens/profile/ProfileScreen.kt b/app/src/main/java/com/github/se/assocify/ui/screens/profile/ProfileScreen.kt index db38996d6..7bce503d7 100644 --- a/app/src/main/java/com/github/se/assocify/ui/screens/profile/ProfileScreen.kt +++ b/app/src/main/java/com/github/se/assocify/ui/screens/profile/ProfileScreen.kt @@ -214,38 +214,40 @@ fun ProfileScreen(navActions: NavigationActions, viewmodel: ProfileViewModel) { } // The below part is association dependent, only available if you're an admin ! - Text( - text = "Manage ${state.selectedAssociation.name}", - style = MaterialTheme.typography.titleMedium) + if (state.isAdmin) { + Text( + text = "Manage ${state.selectedAssociation.name}", + style = MaterialTheme.typography.titleMedium) - Column( - modifier = - Modifier.fillMaxWidth() - .testTag("manageAssociationList") - .clip(RoundedCornerShape(12.dp))) { - AssociationSettings.entries.forEach { s -> - ListItem( - leadingContent = { - Icon( - imageVector = s.getIcon(), - contentDescription = "${s.name} icon") - }, - headlineContent = { Text(text = s.toString()) }, - trailingContent = { - Icon( - imageVector = Icons.AutoMirrored.Filled.ArrowRight, - contentDescription = "Go to ${s.name} settings") - }, - colors = - ListItemDefaults.colors( - containerColor = - MaterialTheme.colorScheme.primaryContainer), - modifier = - Modifier.testTag(s.name).clickable { - navActions.navigateTo(s.getDestination()) - }) + Column( + modifier = + Modifier.fillMaxWidth() + .testTag("manageAssociationList") + .clip(RoundedCornerShape(12.dp))) { + AssociationSettings.entries.forEach { s -> + ListItem( + leadingContent = { + Icon( + imageVector = s.getIcon(), + contentDescription = "${s.name} icon") + }, + headlineContent = { Text(text = s.toString()) }, + trailingContent = { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowRight, + contentDescription = "Go to ${s.name} settings") + }, + colors = + ListItemDefaults.colors( + containerColor = + MaterialTheme.colorScheme.primaryContainer), + modifier = + Modifier.testTag(s.name).clickable { + navActions.navigateTo(s.getDestination()) + }) + } } - } + } // log out button (for everyone) LogoutButton(viewmodel = viewmodel) diff --git a/app/src/main/java/com/github/se/assocify/ui/screens/profile/ProfileViewModel.kt b/app/src/main/java/com/github/se/assocify/ui/screens/profile/ProfileViewModel.kt index 2c855723f..5ad3ccc58 100644 --- a/app/src/main/java/com/github/se/assocify/ui/screens/profile/ProfileViewModel.kt +++ b/app/src/main/java/com/github/se/assocify/ui/screens/profile/ProfileViewModel.kt @@ -129,6 +129,7 @@ class ProfileViewModel( userAPI.getCurrentUserRole( { role -> _uiState.value = _uiState.value.copy(currentRole = role) + setRoleCapacities() loadSystem.end() }, { loadSystem.end("Error loading role") }) @@ -193,6 +194,7 @@ class ProfileViewModel( { role -> _uiState.value = _uiState.value.copy(selectedAssociation = association) _uiState.value = _uiState.value.copy(currentRole = role) + setRoleCapacities() }, { CurrentUser.associationUid = oldAssociationUid @@ -200,6 +202,20 @@ class ProfileViewModel( }) } + /** + * This function is used to set the role capacities of the user. It sets the user as an admin if + * they are a president, treasurer or committee of the association. + */ + private fun setRoleCapacities() { + when (_uiState.value.currentRole.type) { + RoleType.PRESIDENCY -> _uiState.value = _uiState.value.copy(isAdmin = true) + RoleType.TREASURY -> _uiState.value = _uiState.value.copy(isAdmin = true) + RoleType.COMMITTEE -> _uiState.value = _uiState.value.copy(isAdmin = true) + RoleType.STAFF -> _uiState.value = _uiState.value.copy(isAdmin = false) + RoleType.MEMBER -> _uiState.value = _uiState.value.copy(isAdmin = false) + } + } + /** * This function is used to confirm the name change of the user. It updates the user's name in the * database. It shows a snackbar if the name change was successful or not. @@ -267,6 +283,8 @@ data class ProfileUIState( val error: String? = null, // whether the profile is being refreshed val refresh: Boolean = false, + // true if the user is an admin, false if not + val isAdmin: Boolean = false, // the name of the user val myName: String = "", // the name of the user as they're editing it