mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Ignore User UI (#737)
* generated files * Revert "generated files" This reverts commit f62c1dbcd9e505083ad4ff17532e2c054e253187. * renaming files to RoomMembersList * completed the renaming of the list files * added generated files * basic setup of the view and the mock * added a new mock with a avatar * share/copy link * copyUserLink implemented * removed unimplemented tests * block user UI * navigation to room member details added * implemented but we require a sync from the Rust side * adjusted some UI test screens * alert for unblocking * completed * some tests * changelog * ignore user ui enabled * loader inside the button when the request is fetching * removed unused code * blocking the button while loading * improved the code * changelog * UI tests * unit tests * added collection concurrency kit * Revert "added collection concurrency kit" This reverts commit 499fbe129f73a75e903d9f4952fe2ad672930f04. * replaced the asyncMap with a @MainActor builder function * pr comments * added localazy to setup * sdk bump to 1.0.49
This commit is contained in:
@@ -111,8 +111,8 @@
|
|||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/matrix-org/matrix-rust-components-swift",
|
"location" : "https://github.com/matrix-org/matrix-rust-components-swift",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "9eee9ba2f14eaa4981759295790bcbdbdebca747",
|
"revision" : "9650501c92a1ed802a757f2c6807a36d59619f43",
|
||||||
"version" : "1.0.48-alpha"
|
"version" : "1.0.49-alpha"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ struct A11yIdentifiers {
|
|||||||
static let sessionVerificationScreen = SessionVerificationScreen()
|
static let sessionVerificationScreen = SessionVerificationScreen()
|
||||||
static let softLogoutScreen = SoftLogoutScreen()
|
static let softLogoutScreen = SoftLogoutScreen()
|
||||||
static let startChatScreen = StartChatScreen()
|
static let startChatScreen = StartChatScreen()
|
||||||
|
static let roomMemberDetailsScreen = RoomMemberDetailsScreen()
|
||||||
|
|
||||||
struct BugReportScreen {
|
struct BugReportScreen {
|
||||||
let report = "bug_report-report"
|
let report = "bug_report-report"
|
||||||
@@ -98,4 +99,9 @@ struct A11yIdentifiers {
|
|||||||
let closeStartChat = "start_chat-close"
|
let closeStartChat = "start_chat-close"
|
||||||
let inviteFriends = "start_chat-invite_friends"
|
let inviteFriends = "start_chat-invite_friends"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RoomMemberDetailsScreen {
|
||||||
|
let ignore = "room_member_details-ignore"
|
||||||
|
let unignore = "room_member_details-unignore"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2023 New Vector Ltd
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
extension Sequence {
|
|
||||||
func asyncMap<T>(_ transform: @escaping (Element) async -> T) async -> [T] {
|
|
||||||
await withTaskGroup(of: T.self) { group in
|
|
||||||
var transformedElements = [T]()
|
|
||||||
|
|
||||||
for element in self {
|
|
||||||
group.addTask {
|
|
||||||
await transform(element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for await transformedElement in group {
|
|
||||||
transformedElements.append(transformedElement)
|
|
||||||
}
|
|
||||||
|
|
||||||
return transformedElements
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -19,13 +19,16 @@ import SwiftUI
|
|||||||
/// A view to be added on the trailing edge of a form row.
|
/// A view to be added on the trailing edge of a form row.
|
||||||
enum FormRowAccessory: View {
|
enum FormRowAccessory: View {
|
||||||
case navigationLink
|
case navigationLink
|
||||||
|
case progressView
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
switch self {
|
switch self {
|
||||||
case .navigationLink:
|
case .navigationLink:
|
||||||
return Image(systemName: "chevron.forward")
|
Image(systemName: "chevron.forward")
|
||||||
.font(.element.subheadlineBold)
|
.font(.element.subheadlineBold)
|
||||||
.foregroundColor(.element.quaternaryContent)
|
.foregroundColor(.element.quaternaryContent)
|
||||||
|
case .progressView:
|
||||||
|
ProgressView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ struct RoomMemberDetailsViewState: BindableState {
|
|||||||
let isAccountOwner: Bool
|
let isAccountOwner: Bool
|
||||||
let permalink: URL?
|
let permalink: URL?
|
||||||
var isIgnored: Bool
|
var isIgnored: Bool
|
||||||
|
var isProcessingIgnoreRequest = false
|
||||||
|
|
||||||
var bindings: RoomMemberDetailsViewStateBindings
|
var bindings: RoomMemberDetailsViewStateBindings
|
||||||
}
|
}
|
||||||
@@ -34,7 +35,7 @@ struct RoomMemberDetailsViewStateBindings {
|
|||||||
var errorAlert: ErrorAlertItem?
|
var errorAlert: ErrorAlertItem?
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IgnoreUserAlertItem: AlertItem {
|
struct IgnoreUserAlertItem: AlertItem, Equatable {
|
||||||
enum Action {
|
enum Action {
|
||||||
case ignore
|
case ignore
|
||||||
case unignore
|
case unignore
|
||||||
@@ -73,8 +74,8 @@ struct IgnoreUserAlertItem: AlertItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum RoomMemberDetailsViewAction {
|
enum RoomMemberDetailsViewAction {
|
||||||
case showUnblockAlert
|
case showUnignoreAlert
|
||||||
case showBlockAlert
|
case showIgnoreAlert
|
||||||
case ignoreConfirmed
|
case ignoreConfirmed
|
||||||
case unignoreConfirmed
|
case unignoreConfirmed
|
||||||
case copyUserLink
|
case copyUserLink
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ class RoomMemberDetailsViewModel: RoomMemberDetailsViewModelType, RoomMemberDeta
|
|||||||
|
|
||||||
override func process(viewAction: RoomMemberDetailsViewAction) async {
|
override func process(viewAction: RoomMemberDetailsViewAction) async {
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .showUnblockAlert:
|
case .showUnignoreAlert:
|
||||||
state.bindings.ignoreUserAlert = .init(action: .unignore)
|
state.bindings.ignoreUserAlert = .init(action: .unignore)
|
||||||
case .showBlockAlert:
|
case .showIgnoreAlert:
|
||||||
state.bindings.ignoreUserAlert = .init(action: .ignore)
|
state.bindings.ignoreUserAlert = .init(action: .ignore)
|
||||||
case .copyUserLink:
|
case .copyUserLink:
|
||||||
copyUserLink()
|
copyUserLink()
|
||||||
@@ -64,7 +64,10 @@ class RoomMemberDetailsViewModel: RoomMemberDetailsViewModelType, RoomMemberDeta
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func ignoreUser() async {
|
private func ignoreUser() async {
|
||||||
switch await roomMemberProxy.ignoreUser() {
|
state.isProcessingIgnoreRequest = true
|
||||||
|
let result = await roomMemberProxy.ignoreUser()
|
||||||
|
state.isProcessingIgnoreRequest = false
|
||||||
|
switch result {
|
||||||
case .success:
|
case .success:
|
||||||
state.isIgnored = true
|
state.isIgnored = true
|
||||||
case .failure:
|
case .failure:
|
||||||
@@ -73,7 +76,10 @@ class RoomMemberDetailsViewModel: RoomMemberDetailsViewModelType, RoomMemberDeta
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func unignoreUser() async {
|
private func unignoreUser() async {
|
||||||
switch await roomMemberProxy.unignoreUser() {
|
state.isProcessingIgnoreRequest = true
|
||||||
|
let result = await roomMemberProxy.unignoreUser()
|
||||||
|
state.isProcessingIgnoreRequest = false
|
||||||
|
switch result {
|
||||||
case .success:
|
case .success:
|
||||||
state.isIgnored = false
|
state.isIgnored = false
|
||||||
case .failure:
|
case .failure:
|
||||||
|
|||||||
@@ -23,10 +23,9 @@ struct RoomMemberDetailsScreen: View {
|
|||||||
Form {
|
Form {
|
||||||
headerSection
|
headerSection
|
||||||
|
|
||||||
// TODO: Uncomment when the feature is ready
|
if !context.viewState.isAccountOwner {
|
||||||
// if !context.viewState.isAccountOwner {
|
blockUserSection
|
||||||
// blockUserSection
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(Color.element.formBackground.ignoresSafeArea())
|
.background(Color.element.formBackground.ignoresSafeArea())
|
||||||
@@ -77,18 +76,22 @@ struct RoomMemberDetailsScreen: View {
|
|||||||
Section {
|
Section {
|
||||||
if context.viewState.isIgnored {
|
if context.viewState.isIgnored {
|
||||||
Button {
|
Button {
|
||||||
context.send(viewAction: .showUnblockAlert)
|
context.send(viewAction: .showUnignoreAlert)
|
||||||
} label: {
|
} label: {
|
||||||
Label(L10n.screenRoomMemberDetailsUnblockUser, systemImage: "slash.circle")
|
Label(L10n.screenRoomMemberDetailsUnblockUser, systemImage: "slash.circle")
|
||||||
}
|
}
|
||||||
.buttonStyle(FormButtonStyle(accessory: nil))
|
.accessibilityIdentifier(A11yIdentifiers.roomMemberDetailsScreen.unignore)
|
||||||
|
.buttonStyle(FormButtonStyle(accessory: context.viewState.isProcessingIgnoreRequest ? .progressView : nil))
|
||||||
|
.disabled(context.viewState.isProcessingIgnoreRequest)
|
||||||
} else {
|
} else {
|
||||||
Button(role: .destructive) {
|
Button(role: .destructive) {
|
||||||
context.send(viewAction: .showBlockAlert)
|
context.send(viewAction: .showIgnoreAlert)
|
||||||
} label: {
|
} label: {
|
||||||
Label(L10n.screenRoomMemberDetailsBlockUser, systemImage: "slash.circle")
|
Label(L10n.screenRoomMemberDetailsBlockUser, systemImage: "slash.circle")
|
||||||
}
|
}
|
||||||
.buttonStyle(FormButtonStyle(accessory: nil))
|
.accessibilityIdentifier(A11yIdentifiers.roomMemberDetailsScreen.ignore)
|
||||||
|
.buttonStyle(FormButtonStyle(accessory: context.viewState.isProcessingIgnoreRequest ? .progressView : nil))
|
||||||
|
.disabled(context.viewState.isProcessingIgnoreRequest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.formSectionStyle()
|
.formSectionStyle()
|
||||||
|
|||||||
@@ -278,13 +278,18 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return members
|
return members
|
||||||
}
|
}
|
||||||
|
|
||||||
let proxiedMembers = await members.asyncMap { RoomMemberProxy(member: $0, backgroundTaskService: self.backgroundTaskService) }
|
let proxiedMembers = buildRoomMemberProxies(members: members)
|
||||||
return .success(proxiedMembers)
|
return .success(proxiedMembers)
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedRetrievingMembers)
|
return .failure(.failedRetrievingMembers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
private func buildRoomMemberProxies(members: [RoomMember]) -> [RoomMemberProxy] {
|
||||||
|
members.map { RoomMemberProxy(member: $0, backgroundTaskService: backgroundTaskService) }
|
||||||
|
}
|
||||||
|
|
||||||
func retryDecryption(for sessionID: String) async {
|
func retryDecryption(for sessionID: String) async {
|
||||||
await Task.dispatch(on: .global()) { [weak self] in
|
await Task.dispatch(on: .global()) { [weak self] in
|
||||||
self?.room.retryDecryption(sessionIds: [sessionID])
|
self?.room.retryDecryption(sessionIds: [sessionID])
|
||||||
|
|||||||
@@ -318,6 +318,16 @@ class MockScreen: Identifiable {
|
|||||||
let coordinator = RoomMemberDetailsCoordinator(parameters: .init(roomMemberProxy: RoomMemberProxyMock.mockMe, mediaProvider: MockMediaProvider()))
|
let coordinator = RoomMemberDetailsCoordinator(parameters: .init(roomMemberProxy: RoomMemberProxyMock.mockMe, mediaProvider: MockMediaProvider()))
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
|
case .roomMemberDetails:
|
||||||
|
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
|
let coordinator = RoomMemberDetailsCoordinator(parameters: .init(roomMemberProxy: RoomMemberProxyMock.mockAlice, mediaProvider: MockMediaProvider()))
|
||||||
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
|
return navigationStackCoordinator
|
||||||
|
case .roomMemberDetailsIgnoredUser:
|
||||||
|
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
|
let coordinator = RoomMemberDetailsCoordinator(parameters: .init(roomMemberProxy: RoomMemberProxyMock.mockIgnored, mediaProvider: MockMediaProvider()))
|
||||||
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
|
return navigationStackCoordinator
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ enum UITestsScreenIdentifier: String {
|
|||||||
case roomDetailsScreenWithRoomAvatar
|
case roomDetailsScreenWithRoomAvatar
|
||||||
case roomMembersListScreen
|
case roomMembersListScreen
|
||||||
case roomMemberDetailsAccountOwner
|
case roomMemberDetailsAccountOwner
|
||||||
|
case roomMemberDetails
|
||||||
|
case roomMemberDetailsIgnoredUser
|
||||||
case reportContent
|
case reportContent
|
||||||
case startChat
|
case startChat
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ struct SetupProject: ParsableCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func brewBundleInstall() throws {
|
func brewBundleInstall() throws {
|
||||||
try Utilities.zsh("brew install xcodegen swiftgen swiftlint swiftformat git-lfs sourcery kiliankoe/formulae/swift-outdated")
|
try Utilities.zsh("brew install xcodegen swiftgen swiftlint swiftformat git-lfs sourcery kiliankoe/formulae/swift-outdated localazy/tools/localazy")
|
||||||
}
|
}
|
||||||
|
|
||||||
func xcodegen() throws {
|
func xcodegen() throws {
|
||||||
|
|||||||
@@ -20,6 +20,25 @@ import XCTest
|
|||||||
class RoomMemberDetailsScreenUITests: XCTestCase {
|
class RoomMemberDetailsScreenUITests: XCTestCase {
|
||||||
func testInitialStateComponentsForAccountOwner() {
|
func testInitialStateComponentsForAccountOwner() {
|
||||||
let app = Application.launch(.roomMemberDetailsAccountOwner)
|
let app = Application.launch(.roomMemberDetailsAccountOwner)
|
||||||
|
|
||||||
|
XCTAssertFalse(app.buttons[A11yIdentifiers.roomMemberDetailsScreen.ignore].exists)
|
||||||
|
XCTAssertFalse(app.buttons[A11yIdentifiers.roomMemberDetailsScreen.unignore].exists)
|
||||||
app.assertScreenshot(.roomMemberDetailsAccountOwner)
|
app.assertScreenshot(.roomMemberDetailsAccountOwner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testInitialStateComponents() {
|
||||||
|
let app = Application.launch(.roomMemberDetails)
|
||||||
|
|
||||||
|
XCTAssert(app.buttons[A11yIdentifiers.roomMemberDetailsScreen.ignore].waitForExistence(timeout: 1))
|
||||||
|
XCTAssertFalse(app.buttons[A11yIdentifiers.roomMemberDetailsScreen.unignore].exists)
|
||||||
|
app.assertScreenshot(.roomMemberDetails)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testInitialStateComponentsForIgnoredUser() {
|
||||||
|
let app = Application.launch(.roomMemberDetailsIgnoredUser)
|
||||||
|
|
||||||
|
XCTAssertFalse(app.buttons[A11yIdentifiers.roomMemberDetailsScreen.ignore].exists)
|
||||||
|
XCTAssert(app.buttons[A11yIdentifiers.roomMemberDetailsScreen.unignore].waitForExistence(timeout: 1))
|
||||||
|
app.assertScreenshot(.roomMemberDetailsIgnoredUser)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:fa29d51f482c87a93da7fd8c059215fcc3da9ef6c980a301e9507ed1f7c3c7a5
|
||||||
|
size 79947
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:20e6382f3e6befa47d6a343b63fd5e5094e66e216b50853d35555b1e1b9e86ba
|
||||||
|
size 81051
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:9718639645f9d3d1c198a8c3322e7c52c23722d1020a8ee9d1009fc6312d965e
|
||||||
|
size 92445
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:f698182d7eb30b43799b99e49f59422c601387ac4ddc675feecb939ff32e099d
|
||||||
|
size 94597
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:fa29d51f482c87a93da7fd8c059215fcc3da9ef6c980a301e9507ed1f7c3c7a5
|
||||||
|
size 79947
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:20e6382f3e6befa47d6a343b63fd5e5094e66e216b50853d35555b1e1b9e86ba
|
||||||
|
size 81051
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:9718639645f9d3d1c198a8c3322e7c52c23722d1020a8ee9d1009fc6312d965e
|
||||||
|
size 92445
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:f698182d7eb30b43799b99e49f59422c601387ac4ddc675feecb939ff32e099d
|
||||||
|
size 94597
|
||||||
@@ -38,6 +38,92 @@ class RoomMemberDetailsViewModelTests: XCTestCase {
|
|||||||
XCTAssertNil(context.errorAlert)
|
XCTAssertNil(context.errorAlert)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testIgnoreSuccess() async throws {
|
||||||
|
roomMemberProxyMock = RoomMemberProxyMock.mockAlice
|
||||||
|
roomMemberProxyMock.ignoreUserClosure = {
|
||||||
|
try? await Task.sleep(for: .milliseconds(10))
|
||||||
|
return .success(())
|
||||||
|
}
|
||||||
|
viewModel = RoomMemberDetailsViewModel(roomMemberProxy: roomMemberProxyMock, mediaProvider: MockMediaProvider())
|
||||||
|
|
||||||
|
context.send(viewAction: .showIgnoreAlert)
|
||||||
|
await Task.yield()
|
||||||
|
XCTAssertEqual(context.ignoreUserAlert, IgnoreUserAlertItem(action: .ignore))
|
||||||
|
|
||||||
|
context.send(viewAction: .ignoreConfirmed)
|
||||||
|
await Task.yield()
|
||||||
|
XCTAssertTrue(context.viewState.isProcessingIgnoreRequest)
|
||||||
|
XCTAssertFalse(context.viewState.isIgnored)
|
||||||
|
try await Task.sleep(for: .milliseconds(10))
|
||||||
|
XCTAssertFalse(context.viewState.isProcessingIgnoreRequest)
|
||||||
|
XCTAssertTrue(context.viewState.isIgnored)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testIgnoreFailure() async throws {
|
||||||
|
roomMemberProxyMock = RoomMemberProxyMock.mockAlice
|
||||||
|
roomMemberProxyMock.ignoreUserClosure = {
|
||||||
|
try? await Task.sleep(for: .milliseconds(10))
|
||||||
|
return .failure(.ignoreUserFailed)
|
||||||
|
}
|
||||||
|
viewModel = RoomMemberDetailsViewModel(roomMemberProxy: roomMemberProxyMock, mediaProvider: MockMediaProvider())
|
||||||
|
|
||||||
|
context.send(viewAction: .showIgnoreAlert)
|
||||||
|
await Task.yield()
|
||||||
|
XCTAssertEqual(context.ignoreUserAlert, IgnoreUserAlertItem(action: .ignore))
|
||||||
|
|
||||||
|
context.send(viewAction: .ignoreConfirmed)
|
||||||
|
await Task.yield()
|
||||||
|
XCTAssertTrue(context.viewState.isProcessingIgnoreRequest)
|
||||||
|
XCTAssertFalse(context.viewState.isIgnored)
|
||||||
|
try await Task.sleep(for: .milliseconds(10))
|
||||||
|
XCTAssertFalse(context.viewState.isProcessingIgnoreRequest)
|
||||||
|
XCTAssertNotNil(context.errorAlert)
|
||||||
|
XCTAssertFalse(context.viewState.isIgnored)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testUnignoreSuccess() async throws {
|
||||||
|
roomMemberProxyMock = RoomMemberProxyMock.mockIgnored
|
||||||
|
roomMemberProxyMock.unignoreUserClosure = {
|
||||||
|
try? await Task.sleep(for: .milliseconds(10))
|
||||||
|
return .success(())
|
||||||
|
}
|
||||||
|
viewModel = RoomMemberDetailsViewModel(roomMemberProxy: roomMemberProxyMock, mediaProvider: MockMediaProvider())
|
||||||
|
|
||||||
|
context.send(viewAction: .showUnignoreAlert)
|
||||||
|
await Task.yield()
|
||||||
|
XCTAssertEqual(context.ignoreUserAlert, IgnoreUserAlertItem(action: .unignore))
|
||||||
|
|
||||||
|
context.send(viewAction: .unignoreConfirmed)
|
||||||
|
await Task.yield()
|
||||||
|
XCTAssertTrue(context.viewState.isProcessingIgnoreRequest)
|
||||||
|
XCTAssertTrue(context.viewState.isIgnored)
|
||||||
|
try await Task.sleep(for: .milliseconds(10))
|
||||||
|
XCTAssertFalse(context.viewState.isProcessingIgnoreRequest)
|
||||||
|
XCTAssertFalse(context.viewState.isIgnored)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testUnignoreFailure() async throws {
|
||||||
|
roomMemberProxyMock = RoomMemberProxyMock.mockIgnored
|
||||||
|
roomMemberProxyMock.unignoreUserClosure = {
|
||||||
|
try? await Task.sleep(for: .milliseconds(10))
|
||||||
|
return .failure(.unignoreUserFailed)
|
||||||
|
}
|
||||||
|
viewModel = RoomMemberDetailsViewModel(roomMemberProxy: roomMemberProxyMock, mediaProvider: MockMediaProvider())
|
||||||
|
|
||||||
|
context.send(viewAction: .showUnignoreAlert)
|
||||||
|
await Task.yield()
|
||||||
|
XCTAssertEqual(context.ignoreUserAlert, IgnoreUserAlertItem(action: .unignore))
|
||||||
|
|
||||||
|
context.send(viewAction: .unignoreConfirmed)
|
||||||
|
await Task.yield()
|
||||||
|
XCTAssertTrue(context.viewState.isProcessingIgnoreRequest)
|
||||||
|
XCTAssertTrue(context.viewState.isIgnored)
|
||||||
|
try await Task.sleep(for: .milliseconds(10))
|
||||||
|
XCTAssertFalse(context.viewState.isProcessingIgnoreRequest)
|
||||||
|
XCTAssertTrue(context.viewState.isIgnored)
|
||||||
|
XCTAssertNotNil(context.errorAlert)
|
||||||
|
}
|
||||||
|
|
||||||
func testInitialStateAccountOwner() async {
|
func testInitialStateAccountOwner() async {
|
||||||
roomMemberProxyMock = RoomMemberProxyMock.mockMe
|
roomMemberProxyMock = RoomMemberProxyMock.mockMe
|
||||||
viewModel = RoomMemberDetailsViewModel(roomMemberProxy: roomMemberProxyMock, mediaProvider: MockMediaProvider())
|
viewModel = RoomMemberDetailsViewModel(roomMemberProxy: roomMemberProxyMock, mediaProvider: MockMediaProvider())
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
Ignore User functionality added in the Room Member Details View.
|
||||||
+1
-1
@@ -42,7 +42,7 @@ include:
|
|||||||
packages:
|
packages:
|
||||||
MatrixRustSDK:
|
MatrixRustSDK:
|
||||||
url: https://github.com/matrix-org/matrix-rust-components-swift
|
url: https://github.com/matrix-org/matrix-rust-components-swift
|
||||||
exactVersion: 1.0.48-alpha
|
exactVersion: 1.0.49-alpha
|
||||||
# path: ../matrix-rust-sdk
|
# path: ../matrix-rust-sdk
|
||||||
DesignKit:
|
DesignKit:
|
||||||
path: DesignKit
|
path: DesignKit
|
||||||
|
|||||||
Reference in New Issue
Block a user