Use the Emoji/Map/Poll view models. (#4458)

* Toggle emojis in the EmojiPickerScreenViewModel.

* Send locations in the StaticLocationScreen.

* Send polls in the PollFormScreen.
This commit is contained in:
Doug
2025-09-03 16:52:28 +01:00
committed by GitHub
parent 34088f8423
commit 811f02962d
21 changed files with 398 additions and 255 deletions

View File

@@ -11,17 +11,14 @@ import XCTest
@MainActor
class PollFormScreenViewModelTests: XCTestCase {
let timelineProxy = TimelineProxyMock(.init())
var viewModel: PollFormScreenViewModelProtocol!
var context: PollFormScreenViewModelType.Context {
viewModel.context
}
override func setUpWithError() throws {
viewModel = PollFormScreenViewModel(mode: .new)
}
var context: PollFormScreenViewModelType.Context { viewModel.context }
func testNewPollInitialState() async throws {
setupViewModel()
XCTAssertEqual(context.options.count, 2)
XCTAssertTrue(context.options.allSatisfy(\.text.isEmpty))
XCTAssertTrue(context.question.isEmpty)
@@ -33,11 +30,12 @@ class PollFormScreenViewModelTests: XCTestCase {
context.send(viewAction: .cancel)
let action = try await deferred.fulfill()
XCTAssertNil(context.alertInfo)
XCTAssertEqual(action, .cancel)
XCTAssertEqual(action, .close)
}
func testEditPollInitialState() async throws {
setupViewModel(mode: .edit(eventID: "foo", poll: .emptyDisclosed))
XCTAssertEqual(context.options.count, 3)
XCTAssertTrue(context.options.allSatisfy { !$0.text.isEmpty })
XCTAssertFalse(context.question.isEmpty)
@@ -49,10 +47,12 @@ class PollFormScreenViewModelTests: XCTestCase {
context.send(viewAction: .cancel)
let action = try await deferred.fulfill()
XCTAssertNil(context.alertInfo)
XCTAssertEqual(action, .cancel)
XCTAssertEqual(action, .close)
}
func testNewPollInvalidEmptyOption() {
setupViewModel()
context.question = "foo"
context.options[0].text = "bla"
context.options[1].text = "bla"
@@ -62,6 +62,7 @@ class PollFormScreenViewModelTests: XCTestCase {
func testEditPollInvalidEmptyOption() {
setupViewModel(mode: .edit(eventID: "foo", poll: .emptyDisclosed))
context.send(viewAction: .addOption)
XCTAssertTrue(context.viewState.isSubmitButtonDisabled)
@@ -72,6 +73,7 @@ class PollFormScreenViewModelTests: XCTestCase {
func testEditPollSubmitButtonState() {
setupViewModel(mode: .edit(eventID: "foo", poll: .emptyDisclosed))
XCTAssertTrue(context.viewState.isSubmitButtonDisabled)
context.options[0].text = "foo"
XCTAssertFalse(context.viewState.isSubmitButtonDisabled)
@@ -82,68 +84,89 @@ class PollFormScreenViewModelTests: XCTestCase {
}
func testNewPollSubmit() async throws {
setupViewModel()
context.question = "foo"
context.options[0].text = "bla1"
context.options[1].text = "bla2"
XCTAssertFalse(context.viewState.isSubmitButtonDisabled)
let deferred = deferFulfillment(viewModel.actions) { action in
switch action {
case .submit:
return true
default:
return false
}
let deferred = deferFulfillment(viewModel.actions) { $0 == .close }
let expectation = XCTestExpectation(description: "Create poll")
timelineProxy.createPollQuestionAnswersPollKindClosure = { question, options, kind in
XCTAssertEqual(question, "foo")
XCTAssertEqual(options.count, 2)
XCTAssertEqual(options[0], "bla1")
XCTAssertEqual(options[1], "bla2")
XCTAssertEqual(kind, .disclosed)
expectation.fulfill()
return .success(())
}
context.send(viewAction: .submit)
let action = try await deferred.fulfill()
guard case .submit(let question, let options, let kind) = action else {
XCTFail("Unexpected action")
return
}
XCTAssertEqual(question, "foo")
XCTAssertEqual(options.count, 2)
XCTAssertEqual(options[0], "bla1")
XCTAssertEqual(options[1], "bla2")
XCTAssertEqual(kind, .disclosed)
await fulfillment(of: [expectation], timeout: 1)
try await deferred.fulfill()
}
func testEditPollSubmit() async throws {
setupViewModel(mode: .edit(eventID: "foo", poll: .emptyDisclosed))
context.question = "What is your favorite country?"
context.options.append(.init(text: "France 🇫🇷"))
XCTAssertFalse(context.viewState.isSubmitButtonDisabled)
let deferred = deferFulfillment(viewModel.actions) { action in
switch action {
case .submit:
return true
default:
return false
}
let deferred = deferFulfillment(viewModel.actions) { $0 == .close }
let expectation = XCTestExpectation(description: "Edit poll")
timelineProxy.editPollOriginalQuestionAnswersPollKindClosure = { eventID, question, options, kind in
XCTAssertEqual(eventID, "foo")
XCTAssertEqual(question, "What is your favorite country?")
XCTAssertEqual(options.count, 4)
XCTAssertEqual(options[0], "Italy 🇮🇹")
XCTAssertEqual(options[1], "China 🇨🇳")
XCTAssertEqual(options[2], "USA 🇺🇸")
XCTAssertEqual(options[3], "France 🇫🇷")
XCTAssertEqual(kind, .disclosed)
expectation.fulfill()
return .success(())
}
context.send(viewAction: .submit)
let action = try await deferred.fulfill()
guard case .submit(let question, let options, let kind) = action else {
XCTFail("Unexpected action")
return
}
XCTAssertEqual(question, "What is your favorite country?")
XCTAssertEqual(options.count, 4)
XCTAssertEqual(options[0], "Italy 🇮🇹")
XCTAssertEqual(options[1], "China 🇨🇳")
XCTAssertEqual(options[2], "USA 🇺🇸")
XCTAssertEqual(options[3], "France 🇫🇷")
XCTAssertEqual(kind, .disclosed)
await fulfillment(of: [expectation], timeout: 1)
try await deferred.fulfill()
}
private func setupViewModel(mode: PollFormMode) {
viewModel = PollFormScreenViewModel(mode: mode)
func testDeletePoll() async throws {
setupViewModel(mode: .edit(eventID: "foo", poll: .emptyDisclosed))
context.question = "What is your favorite country?"
context.options.append(.init(text: "France 🇫🇷"))
XCTAssertFalse(context.viewState.isSubmitButtonDisabled)
let deferredFailure = deferFailure(viewModel.actions, timeout: 1, message: "The alert should be shown.") { $0 == .close }
context.send(viewAction: .delete)
try await deferredFailure.fulfill()
XCTAssertNotNil(context.alertInfo, "An alert should be shown before deleting the poll.")
let deferred = deferFulfillment(viewModel.actions) { $0 == .close }
let expectation = XCTestExpectation(description: "Delete poll")
timelineProxy.redactReasonClosure = { eventID, _ in
XCTAssertEqual(eventID, .eventID("foo"))
expectation.fulfill()
return .success(())
}
context.alertInfo?.secondaryButton?.action?()
await fulfillment(of: [expectation], timeout: 1)
try await deferred.fulfill()
}
// MARK: - Helpers
private func setupViewModel(mode: PollFormMode = .new) {
viewModel = PollFormScreenViewModel(mode: mode,
timelineController: MockTimelineController(timelineProxy: timelineProxy),
analytics: ServiceLocator.shared.analytics,
userIndicatorController: UserIndicatorControllerMock())
}
}