Polls history (#2244)

This commit is contained in:
Nicolas Mauri
2023-12-18 16:38:39 +01:00
committed by GitHub
parent 4ac0ad51d7
commit 72a84badcb
73 changed files with 1516 additions and 202 deletions
@@ -0,0 +1,189 @@
//
// Copyright 2022 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 XCTest
@testable import ElementX
@MainActor
class RoomPollsHistoryScreenViewModelTests: XCTestCase {
var viewModel: RoomPollsHistoryScreenViewModelProtocol!
var interactionHandler: PollInteractionHandlerMock!
var timelineController: MockRoomTimelineController!
var context: RoomPollsHistoryScreenViewModelType.Context {
viewModel.context
}
override func setUpWithError() throws {
interactionHandler = PollInteractionHandlerMock()
timelineController = MockRoomTimelineController()
let roomProxyMockConfiguration = RoomProxyMockConfiguration(displayName: "Polls")
roomProxyMockConfiguration.timeline.timelineStartReached = false
viewModel = RoomPollsHistoryScreenViewModel(roomProxy: RoomProxyMock(with: roomProxyMockConfiguration),
pollInteractionHandler: interactionHandler,
roomTimelineController: timelineController,
userIndicatorController: UserIndicatorControllerMock())
}
func testBackPaginate() async throws {
timelineController.backPaginationResponses = [
[PollRoomTimelineItem.mock(poll: .emptyDisclosed, isEditable: true),
PollRoomTimelineItem.mock(poll: .disclosed(createdByAccountOwner: true)),
PollRoomTimelineItem.mock(poll: .disclosed(createdByAccountOwner: false)),
PollRoomTimelineItem.mock(poll: .endedDisclosed)]
]
let deferredViewState = deferFulfillment(viewModel.context.$viewState, keyPath: \.isBackPaginating, transitionValues: [false, true, false])
viewModel.context.send(viewAction: .loadMore)
try await deferredViewState.fulfill()
XCTAssertEqual(viewModel.context.viewState.pollTimelineItems.count, 3)
XCTAssertFalse(viewModel.context.viewState.canBackPaginate)
}
func testBackPaginateCanBackPaginate() async throws {
timelineController.backPaginationResponses = [
[PollRoomTimelineItem.mock(poll: .emptyDisclosed, isEditable: true),
PollRoomTimelineItem.mock(poll: .disclosed(createdByAccountOwner: true)),
PollRoomTimelineItem.mock(poll: .disclosed(createdByAccountOwner: false)),
PollRoomTimelineItem.mock(poll: .endedDisclosed)],
[]
]
let deferredViewState = deferFulfillment(viewModel.context.$viewState, keyPath: \.isBackPaginating, transitionValues: [false, true, false])
viewModel.context.send(viewAction: .loadMore)
try await deferredViewState.fulfill()
XCTAssertEqual(viewModel.context.viewState.pollTimelineItems.count, 3)
XCTAssert(viewModel.context.viewState.canBackPaginate)
}
func testBackPaginateTwice() async throws {
timelineController.backPaginationResponses = [
[PollRoomTimelineItem.mock(poll: .emptyDisclosed, isEditable: true),
PollRoomTimelineItem.mock(poll: .disclosed(createdByAccountOwner: true)),
PollRoomTimelineItem.mock(poll: .disclosed(createdByAccountOwner: false))],
[PollRoomTimelineItem.mock(poll: .endedDisclosed)]
]
let deferredViewState = deferFulfillment(viewModel.context.$viewState, keyPath: \.isBackPaginating, transitionValues: [false, true, false])
viewModel.context.send(viewAction: .loadMore)
viewModel.context.send(viewAction: .loadMore)
try await deferredViewState.fulfill()
XCTAssertEqual(viewModel.context.viewState.pollTimelineItems.count, 3)
XCTAssert(viewModel.context.viewState.canBackPaginate)
}
func testFilters() async throws {
timelineController.backPaginationResponses = [
[PollRoomTimelineItem.mock(poll: .emptyDisclosed, isEditable: true),
PollRoomTimelineItem.mock(poll: .disclosed(createdByAccountOwner: true)),
PollRoomTimelineItem.mock(poll: .disclosed(createdByAccountOwner: false)),
PollRoomTimelineItem.mock(poll: .endedDisclosed)],
[]
]
let deferredViewState = deferFulfillment(viewModel.context.$viewState) { value in
!value.pollTimelineItems.isEmpty
}
viewModel.context.filter = .ongoing
viewModel.context.send(viewAction: .loadMore)
try await deferredViewState.fulfill()
XCTAssertEqual(viewModel.context.viewState.pollTimelineItems.count, 3)
viewModel.context.send(viewAction: .filter(.past))
XCTAssertEqual(viewModel.context.viewState.pollTimelineItems.count, 1)
}
func testEndPoll() async throws {
let deferred = deferFulfillment(interactionHandler.publisher) { _ in true }
interactionHandler.endPollPollStartIDReturnValue = .success(())
viewModel.context.send(viewAction: .end(pollStartID: "somePollID"))
try await deferred.fulfill()
XCTAssert(interactionHandler.endPollPollStartIDCalled)
XCTAssertEqual(interactionHandler.endPollPollStartIDReceivedPollStartID, "somePollID")
}
func testEndPollFailure() async throws {
let deferred = deferFulfillment(viewModel.context.$viewState) { value in
value.bindings.alertInfo != nil
}
interactionHandler.endPollPollStartIDReturnValue = .failure(TimelineProxyError.failedEndingPoll)
viewModel.context.send(viewAction: .end(pollStartID: "somePollID"))
try await deferred.fulfill()
XCTAssert(interactionHandler.endPollPollStartIDCalled)
XCTAssertEqual(interactionHandler.endPollPollStartIDReceivedPollStartID, "somePollID")
}
func testSendPollResponse() async throws {
let deferred = deferFulfillment(interactionHandler.publisher) { _ in true }
interactionHandler.sendPollResponsePollStartIDOptionIDReturnValue = .success(())
viewModel.context.send(viewAction: .sendPollResponse(pollStartID: "somePollID", optionID: "someOptionID"))
try await deferred.fulfill()
XCTAssert(interactionHandler.sendPollResponsePollStartIDOptionIDCalled)
XCTAssertEqual(interactionHandler.sendPollResponsePollStartIDOptionIDReceivedInvocations[0].pollStartID, "somePollID")
XCTAssertEqual(interactionHandler.sendPollResponsePollStartIDOptionIDReceivedInvocations[0].optionID, "someOptionID")
}
func testSendPollResponseFailure() async throws {
let deferred = deferFulfillment(viewModel.context.$viewState) { value in
value.bindings.alertInfo != nil
}
interactionHandler.sendPollResponsePollStartIDOptionIDReturnValue = .failure(TimelineProxyError.failedSendingPollResponse)
viewModel.context.send(viewAction: .sendPollResponse(pollStartID: "somePollID", optionID: "someOptionID"))
try await deferred.fulfill()
XCTAssert(interactionHandler.sendPollResponsePollStartIDOptionIDCalled)
XCTAssertEqual(interactionHandler.sendPollResponsePollStartIDOptionIDReceivedInvocations[0].pollStartID, "somePollID")
XCTAssertEqual(interactionHandler.sendPollResponsePollStartIDOptionIDReceivedInvocations[0].optionID, "someOptionID")
}
func testEditPoll() async throws {
let expectedPoll: Poll = .emptyDisclosed
let expectedPollStartID = "someEventID"
let deferred = deferFulfillment(viewModel.actions) { action in
switch action {
case .editPoll(let pollStartID, let poll):
expectedPollStartID == pollStartID && expectedPoll == poll
}
}
viewModel.context.send(viewAction: .edit(pollStartID: expectedPollStartID, poll: expectedPoll))
try await deferred.fulfill()
}
}
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6b0c5b464a748ad0862049a76bb4f187c679034cc28898447c5058c4931789ac
size 116006
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d3e3a08b89f04a344b1eeedd42100ea950063a5cd0bab3eb944fc12f9e19951a
size 115364
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cda1d8f5b00bce67897298cfd4c8f13449c1a4925648845abea59f0b9ad95156
size 108965
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:72a22c525adf7ae1a33801dea692ce7774d285e8b1c4430167da71709e990c32
size 109045
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:72a22c525adf7ae1a33801dea692ce7774d285e8b1c4430167da71709e990c32
size 109045
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5f8d5def15c593ab91d412d432957ca8fbc73c552dc45d8940d32b6f4d512b02
size 103783
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9e0f795c81b1de86d8fd339a4a41da77e1ba5708ff7f1d353a84cd72872b85ae
size 170145
oid sha256:3385ad85711489e26d8a7bc8d4951595fbb860f78b894bbdede811b33da4e875
size 169187
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:71a9439c43fa9d524757b86286c97364fb36862f7a5baaf85195d3f6c838e9f4
size 174322
oid sha256:df5bf3bdc2a327abc5acff85eacf22da2daea56cd87edb20d166bf63ea6c65c5
size 173146
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:485b9d96a003d14cfcc81a607e1cf22277b7a6daabe14cfaf3ab817dd9ff2040
size 105327
oid sha256:1d62c100d777596fbec7d9f7d6ad03983f7963bdab029ed231667bdca5db767e
size 112041
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:283f397347f3307f448ca2a271ef6e7ec8a71e697c4929e5b8c3d3464e02cf40
size 93617
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cf0718060176eba8372ec98d6d2ceddd12a0f25e25bebda7fec9fa0ea904b482
size 201120