Skip to content

Commit

Permalink
[MBL-1095] Disable Message Reply Button When User Is Blocked (#1905)
Browse files Browse the repository at this point in the history
  • Loading branch information
scottkicks authored Dec 13, 2023
1 parent d98e4fe commit 19d4ab9
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 16 deletions.
10 changes: 5 additions & 5 deletions Kickstarter-iOS/Features/Messages/Storyboard/Messages.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@
</connections>
</tableView>
<navigationItem key="navigationItem" id="pUe-X9-gXs">
<barButtonItem key="rightBarButtonItem" id="mFf-pV-0Nc">
<barButtonItem key="rightBarButtonItem" enabled="NO" id="mFf-pV-0Nc">
<connections>
<action selector="replyButtonPressed" destination="KOm-AI-SFW" id="Cxt-yR-ytl"/>
</connections>
Expand Down Expand Up @@ -647,15 +647,15 @@
</tableView>
<navigationItem key="navigationItem" id="OMa-kG-hIb">
<nil key="title"/>
<view key="titleView" contentMode="scaleToFill" misplaced="YES" id="3ac-Dg-U5u" userLabel="Title view">
<view key="titleView" contentMode="scaleToFill" id="3ac-Dg-U5u" userLabel="Title view">
<rect key="frame" x="16" y="5.5" width="343" height="33"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="DrS-Lz-KGw">
<rect key="frame" x="12" y="0.0" width="335" height="33"/>
<rect key="frame" x="12" y="0.0" width="319" height="33"/>
<subviews>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" minimumFontSize="17" clearButtonMode="always" translatesAutoresizingMaskIntoConstraints="NO" id="E9A-bD-5Mg" userLabel="Search">
<rect key="frame" x="0.0" y="5.5" width="307" height="22"/>
<rect key="frame" x="0.0" y="5.5" width="291" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits"/>
<userDefinedRuntimeAttributes>
Expand All @@ -667,7 +667,7 @@
</connections>
</textField>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="Kwa-lS-ZfK" userLabel="Loading">
<rect key="frame" x="315" y="6.5" width="20" height="20"/>
<rect key="frame" x="299" y="6.5" width="20" height="20"/>
</activityIndicatorView>
</subviews>
</stackView>
Expand Down
16 changes: 9 additions & 7 deletions Library/ViewModels/MessagesViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
Expand Down Expand Up @@ -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(())
Expand Down
45 changes: 41 additions & 4 deletions Library/ViewModels/MessagesViewModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()
Expand All @@ -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
Expand Down

0 comments on commit 19d4ab9

Please sign in to comment.