diff --git a/Kickstarter-iOS/Features/Messages/Storyboard/Messages.storyboard b/Kickstarter-iOS/Features/Messages/Storyboard/Messages.storyboard index 158537aa38..110f3a4469 100644 --- a/Kickstarter-iOS/Features/Messages/Storyboard/Messages.storyboard +++ b/Kickstarter-iOS/Features/Messages/Storyboard/Messages.storyboard @@ -506,7 +506,7 @@ - + @@ -647,15 +647,15 @@ - + - + - + @@ -667,7 +667,7 @@ - + diff --git a/Library/ViewModels/MessagesViewModel.swift b/Library/ViewModels/MessagesViewModel.swift index d102c4b069..a0e88415a0 100644 --- a/Library/ViewModels/MessagesViewModel.swift +++ b/Library/ViewModels/MessagesViewModel.swift @@ -168,11 +168,17 @@ public final class MessagesViewModel: MessagesViewModelType, MessagesViewModelIn } ) - self.replyButtonIsEnabled = Signal.merge( - self.viewDidLoadProperty.signal.mapConst(false), + self.participantPreviouslyBlocked = self.project + .map { $0.creator.isBlocked } + .takeWhen(self.viewWillAppearProperty.signal) + + self.replyButtonIsEnabled = Signal.combineLatest( self.messages.map { !$0.isEmpty }, - participant.signal.map { $0.isBlocked == false } + self.participantPreviouslyBlocked ) + .map { messages, isBlocked in + messages && !isBlocked + } self.presentMessageDialog = messageThreadEnvelope .map { ($0.messageThread, .messages) } @@ -214,10 +220,6 @@ public final class MessagesViewModel: MessagesViewModelType, MessagesViewModelIn // TODO: Display proper error messaging from the backend self.didBlockUserError = blockUserEvent.errors().ignoreValues() - - self.participantPreviouslyBlocked = self.project - .map { $0.creator.isBlocked } - .takeWhen(self.viewWillAppearProperty.signal) } private let backingInfoPressedProperty = MutableProperty(()) diff --git a/Library/ViewModels/MessagesViewModelTests.swift b/Library/ViewModels/MessagesViewModelTests.swift index 394d70d598..0a333cd06f 100644 --- a/Library/ViewModels/MessagesViewModelTests.swift +++ b/Library/ViewModels/MessagesViewModelTests.swift @@ -218,8 +218,10 @@ internal final class MessagesViewModelTests: TestCase { } } - func testReplyFlow() { - let project = Project.template |> Project.lens.id .~ 42 + func testReplyFlow_participantIsNotBlocked() { + let project = Project.template + |> Project.lens.id .~ 42 + |> \.creator.isBlocked .~ false let backing = Backing.template let messageThread = .template |> MessageThread.lens.project .~ project @@ -234,15 +236,17 @@ internal final class MessagesViewModelTests: TestCase { self.emptyStateIsVisible.assertValueCount(0) self.vm.inputs.viewDidLoad() + self.vm.inputs.viewWillAppear() self.messages.assertValueCount(0) - self.replyButtonIsEnabled.assertValues([false]) + self.participantPreviouslyBlocked.assertValueCount(1) + self.replyButtonIsEnabled.assertValues([]) self.emptyStateIsVisible.assertValues([false]) self.scheduler.advance() self.messages.assertValueCount(1) - self.replyButtonIsEnabled.assertValues([false, true, true]) + self.replyButtonIsEnabled.assertValues([true]) self.emptyStateIsVisible.assertValues([false], "Empty state does not emit again.") self.vm.inputs.replyButtonPressed() @@ -257,6 +261,39 @@ internal final class MessagesViewModelTests: TestCase { } } + func testReplyFlow_participantIsBlocked() { + let project = Project.template + |> Project.lens.id .~ 42 + |> \.creator.isBlocked .~ true + let backing = Backing.template + let messageThread = .template + |> MessageThread.lens.project .~ project + |> MessageThread.lens.participant .~ .template + + let apiService = MockService(fetchMessageThreadResult: Result.success(messageThread)) + + withEnvironment(apiService: apiService, currentUser: .template) { + self.vm.inputs.configureWith(data: .right((project: project, backing: backing))) + + self.replyButtonIsEnabled.assertValueCount(0) + self.emptyStateIsVisible.assertValueCount(0) + + self.vm.inputs.viewDidLoad() + self.vm.inputs.viewWillAppear() + + self.messages.assertValueCount(0) + self.participantPreviouslyBlocked.assertValueCount(1) + self.replyButtonIsEnabled.assertValues([]) + self.emptyStateIsVisible.assertValues([false]) + + self.scheduler.advance() + + self.messages.assertValueCount(1) + self.replyButtonIsEnabled.assertValues([false]) + self.emptyStateIsVisible.assertValues([false], "Empty state does not emit again.") + } + } + func testParticipantPreviouslyBlockedFlow_True() { let creator = User.template |> \.isBlocked .~ true