From 36081b2a6ce090278b2223b9e5db282fd831730e Mon Sep 17 00:00:00 2001 From: "fabian.patzwall" Date: Fri, 8 Mar 2024 17:00:02 +0100 Subject: [PATCH] Add canChangeHistoryVisibility to UserService --- .../trixnity/client/user/UserService.kt | 15 ++++ .../trixnity/client/mocks/UserServiceMock.kt | 4 + .../trixnity/client/user/UserServiceTest.kt | 88 +++++++++++++++++++ 3 files changed, 107 insertions(+) diff --git a/trixnity-client/src/commonMain/kotlin/net/folivo/trixnity/client/user/UserService.kt b/trixnity-client/src/commonMain/kotlin/net/folivo/trixnity/client/user/UserService.kt index e273a51b1..2b775bdf6 100644 --- a/trixnity-client/src/commonMain/kotlin/net/folivo/trixnity/client/user/UserService.kt +++ b/trixnity-client/src/commonMain/kotlin/net/folivo/trixnity/client/user/UserService.kt @@ -55,6 +55,7 @@ interface UserService { fun canSendEvent(roomId: RoomId, eventClass: KClass): Flow + fun canChangeHistoryVisibility(roomId: RoomId): Flow fun getAccountData( eventContentClass: KClass, @@ -234,6 +235,20 @@ class UserServiceImpl( } else false }.distinctUntilChanged() + override fun canChangeHistoryVisibility(roomId: RoomId): Flow = + combine( + roomStore.get(roomId).map { it?.membership }.filterNotNull(), + roomStateStore.getContentByStateKey(roomId), + roomStateStore.getByStateKey(roomId).filterNotNull(), + ) { membership, powerLevels, createEvent -> + if (membership == Membership.JOIN) { + val ownPowerLevel = getPowerLevel(ownUserId, createEvent.sender, powerLevels) + val historyVisibilityLevel = powerLevels?.events?.get() + ?: powerLevels?.stateDefault ?: STATE_DEFAULT + ownPowerLevel >= historyVisibilityLevel + } else false + }.distinctUntilChanged() + override fun canSetPowerLevelToMax( roomId: RoomId, userId: UserId diff --git a/trixnity-client/src/commonTest/kotlin/net/folivo/trixnity/client/mocks/UserServiceMock.kt b/trixnity-client/src/commonTest/kotlin/net/folivo/trixnity/client/mocks/UserServiceMock.kt index dd4cada00..3fefe4ae1 100644 --- a/trixnity-client/src/commonTest/kotlin/net/folivo/trixnity/client/mocks/UserServiceMock.kt +++ b/trixnity-client/src/commonTest/kotlin/net/folivo/trixnity/client/mocks/UserServiceMock.kt @@ -81,6 +81,10 @@ class UserServiceMock : UserService { throw NotImplementedError() } + override fun canChangeHistoryVisibility(roomId: RoomId): Flow { + throw NotImplementedError() + } + override fun getPowerLevel(roomId: RoomId, userId: UserId): Flow { throw NotImplementedError() } diff --git a/trixnity-client/src/commonTest/kotlin/net/folivo/trixnity/client/user/UserServiceTest.kt b/trixnity-client/src/commonTest/kotlin/net/folivo/trixnity/client/user/UserServiceTest.kt index 17181bce1..613723695 100644 --- a/trixnity-client/src/commonTest/kotlin/net/folivo/trixnity/client/user/UserServiceTest.kt +++ b/trixnity-client/src/commonTest/kotlin/net/folivo/trixnity/client/user/UserServiceTest.kt @@ -1376,4 +1376,92 @@ class UserServiceTest : ShouldSpec({ } } } + context("canChangeHistoryVisibility") { + should("return false when not member of room") { + roomStore.update(roomId) { Room(roomId, membership = LEAVE) } + val powerLevelsEvent = getPowerLevelsEvent( + PowerLevelsEventContent( + users = mapOf( + me to 55, + alice to 50 + ), + events = mapOf(EventType(HistoryVisibilityEventContent::class, "m.room.history_visibility") to 55), + stateDefault = 60L + ) + ) + roomStateStore.save(powerLevelsEvent) + cut.canChangeHistoryVisibility(roomId).first() shouldBe false + } + context("events-map is not null") { + should("not allow to change the historyVisibility when (events power_levels value > own power level") { + val powerLevelsEvent = getPowerLevelsEvent( + PowerLevelsEventContent( + users = mapOf( + me to 45, + ), + events = mapOf(EventType(HistoryVisibilityEventContent::class, "m.room.history_visibility") to 56), + stateDefault = 40L + ) + ) + roomStateStore.save(powerLevelsEvent) + cut.canChangeHistoryVisibility(roomId).first() shouldBe false + } + + should("return true when (events power_levels value == own power level") { + val powerLevelsEvent = getPowerLevelsEvent( + PowerLevelsEventContent( + users = mapOf( + me to 55, + ), + events = mapOf(EventType(HistoryVisibilityEventContent::class, "m.room.history_visibility") to 55), + stateDefault = 60L + ) + ) + roomStateStore.save(powerLevelsEvent) + cut.canChangeHistoryVisibility(roomId).first() shouldBe true + } + + should("return true when (events power_levels value < own power level") { + val powerLevelsEvent = getPowerLevelsEvent( + PowerLevelsEventContent( + users = mapOf( + me to 55, + ), + events = mapOf(EventType(HistoryVisibilityEventContent::class, "m.room.history_visibility") to 54), + stateDefault = 60L + ) + ) + roomStateStore.save(powerLevelsEvent) + cut.canChangeHistoryVisibility(roomId).first() shouldBe true + } + } + + context("events-map is null") { + should("not allow to change the historyVisibility when (stateDefault value > own power level") { + val powerLevelsEvent = getPowerLevelsEvent( + PowerLevelsEventContent( + users = mapOf( + me to 55, + ), + stateDefault = 56 + ) + ) + roomStateStore.save(powerLevelsEvent) + cut.canChangeHistoryVisibility(roomId).first() shouldBe false + } + + should("return true when (stateDefault value == own power level") { + val powerLevelsEvent = getPowerLevelsEvent( + PowerLevelsEventContent( + users = mapOf( + me to 55, + ), + stateDefault = 55 + ) + ) + roomStateStore.save(powerLevelsEvent) + cut.canChangeHistoryVisibility(roomId).first() shouldBe true + } + } + } }) \ No newline at end of file -- GitLab