From 6af023590ec5751aaca24826eccdb3f631cd8df6 Mon Sep 17 00:00:00 2001 From: ZiZouet <91062845+zizouet@users.noreply.github.com> Date: Sun, 2 Jun 2024 18:32:57 +0200 Subject: [PATCH] feat: everything, everywhere, all at once --- .../se/assocify/model/database/UserAPI.kt | 93 +++++++++++++++++++ .../se/assocify/model/database/UserAPITest.kt | 56 +++++++++++ 2 files changed, 149 insertions(+) diff --git a/app/src/main/java/com/github/se/assocify/model/database/UserAPI.kt b/app/src/main/java/com/github/se/assocify/model/database/UserAPI.kt index 8441cb316..c2efb3fd7 100644 --- a/app/src/main/java/com/github/se/assocify/model/database/UserAPI.kt +++ b/app/src/main/java/com/github/se/assocify/model/database/UserAPI.kt @@ -328,4 +328,97 @@ class UserAPI(private val db: SupabaseClient, cachePath: Path) : SupabaseApi() { return PermissionRole(roleId, associationId, type) } } + + fun changeRoleOfUser( + userId: String, + associationId: String, + roleType: RoleType, + onSuccess: () -> Unit, + onFailure: (Exception) -> Unit + ) { + // Determine which roleId of the user to change + var roleIDs: List + tryAsync(onFailure) { + db.from("member_of") + .select { filter { eq("user_id", userId) } } + .decodeList() + .let { roleIDs = it } + + var roleIDToChange: JsonObject? = null + roleIDs + .map { it["role_id"].toString().drop(1).dropLast(1) } + .forEach { + val result = + db.from("role") + .select { + filter { + eq("uid", it) + eq("association_id", associationId) + } + } + .decodeSingleOrNull() + if (result != null) { + roleIDToChange = result + } + } + + // Find the role to change to + val roleToChangeTo = + db.from("role") + .select { + filter { + eq("type", roleType.name.lowercase()) + eq("association_id", associationId) + } + } + .decodeSingle() + + // Update the role of the user + db.from("member_of").update({ + Membership::roleId setTo roleToChangeTo["uid"].toString().drop(1).dropLast(1) + }) { + filter { + eq("user_id", userId) + eq("role_id", roleIDToChange.toString().drop(1).dropLast(1)) + } + } + onSuccess() + } + } + + /** + * Removes a user from an association + * + * @param userId the id of the user to remove + * @param associationId the id of the association to remove the user from + * @param onSuccess called on success + * @param onFailure called on failure + */ + fun removeUserFromAssociation( + userId: String, + associationId: String, + onSuccess: () -> Unit, + onFailure: (Exception) -> Unit + ) { + var roleIDs: List + tryAsync(onFailure) { + // Get all the role ids the user have + roleIDs = + db.from("member_of").select { filter { eq("user_id", userId) } }.decodeList() + + // Delete the role id from the user which corresponds to the association + roleIDs + .map { it["role_id"].toString().drop(1).dropLast(1) } + .forEach { + println("Role ID: $it") + db.from("role").delete { + filter { + eq("uid", it) + eq("association_id", associationId) + } + } + } + onSuccess() + } + } } diff --git a/app/src/test/java/com/github/se/assocify/model/database/UserAPITest.kt b/app/src/test/java/com/github/se/assocify/model/database/UserAPITest.kt index cbfa3d7e8..483cff4df 100644 --- a/app/src/test/java/com/github/se/assocify/model/database/UserAPITest.kt +++ b/app/src/test/java/com/github/se/assocify/model/database/UserAPITest.kt @@ -331,4 +331,60 @@ class UserAPITest { userAPI.setProfilePicture(uuid1.toString(), mockk(), { fail("Should not succeed") }, onFailure) verify(timeout = 1000) { onFailure(any()) } } + + @Test + fun testChangeRoleOfUser() { + val onSuccess: () -> Unit = mockk(relaxed = true) + val onFailure: (Exception) -> Unit = mockk(relaxed = true) + error = false + response = + """ + [{ + "user_id": "${APITestUtils.USER.uid}", + "role_id": "${APITestUtils.PERMISSION_ROLE.uid}" + }] + + """ + .trimIndent() + + userAPI.changeRoleOfUser( + APITestUtils.USER.uid, + APITestUtils.ASSOCIATION.uid, + RoleType.PRESIDENCY, + onSuccess, + onFailure) + verify(timeout = 1000) { onSuccess() } + error = true + userAPI.changeRoleOfUser( + APITestUtils.USER.uid, + APITestUtils.ASSOCIATION.uid, + RoleType.PRESIDENCY, + onSuccess, + onFailure) + verify(timeout = 1000) { onFailure(any()) } + } + + @Test + fun testRemoveUserFromAssociation() { + val onSuccess: () -> Unit = mockk(relaxed = true) + val onFailure: (Exception) -> Unit = mockk(relaxed = true) + error = false + response = + """ + [{ + "user_id": "${APITestUtils.USER.uid}", + "role_id": "${APITestUtils.PERMISSION_ROLE.uid}" + }] + + """ + .trimIndent() + + userAPI.removeUserFromAssociation( + APITestUtils.USER.uid, APITestUtils.ASSOCIATION.uid, onSuccess, onFailure) + verify(timeout = 1000) { onSuccess() } + error = true + userAPI.removeUserFromAssociation( + APITestUtils.USER.uid, APITestUtils.ASSOCIATION.uid, onSuccess, onFailure) + verify(timeout = 1000) { onFailure(any()) } + } }