vector-im/element-ios/issues/5298 - Added build setting + ui and unit tests.

This commit is contained in:
Stefan Ceriu
2021-12-22 14:12:42 +02:00
committed by Stefan Ceriu
parent 0a852eb371
commit e1505d70c5
9 changed files with 149 additions and 18 deletions
@@ -53,7 +53,7 @@ struct LocationSharingViewState: BindableState {
var showLoadingIndicator: Bool = false
var shareButtonVisible: Bool {
(location == nil)
return location == nil
}
var shareButtonEnabled: Bool {
@@ -17,19 +17,28 @@
import Foundation
import SwiftUI
import Keys
import CoreLocation
@available(iOS 14.0, *)
enum MockLocationSharingScreenState: MockScreenState, CaseIterable {
case standard
case shareUserLocation
case displayExistingLocation
var screenType: Any.Type {
MockLocationSharingScreenState.self
}
var screenView: ([Any], AnyView) {
var location: CLLocationCoordinate2D?
if self == .displayExistingLocation {
location = CLLocationCoordinate2D(latitude: 51.4932641, longitude: -0.257096)
}
let mapURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=" + RiotKeys().mapTilerAPIKey)!
let viewModel = LocationSharingViewModel(tileServerMapURL: mapURL,
avatarData: AvatarInput(mxContentUri: "", matrixItemId: "", displayName: "Alice"))
avatarData: AvatarInput(mxContentUri: "", matrixItemId: "", displayName: "Alice"),
location: location)
return ([viewModel],
AnyView(LocationSharingView(context: viewModel.context)
.addDependency(MockAvatarService.example)))
@@ -24,13 +24,30 @@ class LocationSharingUITests: XCTestCase {
override func setUp() {
continueAfterFailure = false
app = XCUIApplication()
app.launch()
app.buttons[MockLocationSharingScreenState.screenStateKeys.first!].tap()
}
func testInitialStateComponents() {
func testInitialUserLocation() {
goToScreenWithIdentifier(MockLocationSharingScreenState.shareUserLocation.title)
XCTAssertTrue(app.buttons["Cancel"].exists)
XCTAssertTrue(app.buttons["Share"].exists)
XCTAssertTrue(app.otherElements["Map"].exists)
}
func testInitialExistingLocation() {
goToScreenWithIdentifier(MockLocationSharingScreenState.displayExistingLocation.title)
XCTAssertTrue(app.buttons["Cancel"].exists)
XCTAssertTrue(app.buttons["location share icon"].exists)
XCTAssertTrue(app.otherElements["Map"].exists)
}
// Need a delay when showing the map otherwise the simulator breaks
private func goToScreenWithIdentifier(_ identifier: String) {
app.goToScreenWithIdentifier(identifier)
sleep(2)
}
}
@@ -16,20 +16,113 @@
import XCTest
import Combine
import CoreLocation
@testable import RiotSwiftUI
@available(iOS 14.0, *)
class LocationSharingViewModelTests: XCTestCase {
var viewModel: LocationSharingViewModel!
var context: LocationSharingViewModelType.Context!
var cancellables = Set<AnyCancellable>()
override func setUpWithError() throws {
func testInitialState() {
let viewModel = buildViewModel(withLocation: false)
XCTAssertTrue(viewModel.context.viewState.shareButtonEnabled)
XCTAssertTrue(viewModel.context.viewState.shareButtonVisible)
XCTAssertFalse(viewModel.context.viewState.showLoadingIndicator)
XCTAssertNotNil(viewModel.context.viewState.tileServerMapURL)
XCTAssertNotNil(viewModel.context.viewState.avatarData)
XCTAssertNil(viewModel.context.viewState.location)
XCTAssertNil(viewModel.context.viewState.bindings.userLocation)
XCTAssertNil(viewModel.context.viewState.bindings.alertInfo)
}
func testInitialState() {
func testCancellation() {
let viewModel = buildViewModel(withLocation: false)
let expectation = self.expectation(description: "Cancellation completion should be invoked")
viewModel.completion = { result in
switch result {
case .share:
XCTFail()
case .cancel:
expectation.fulfill()
}
}
viewModel.context.send(viewAction: .cancel)
waitForExpectations(timeout: 3)
}
func testShareNoUserLocation() {
let viewModel = buildViewModel(withLocation: false)
XCTAssertNil(viewModel.context.viewState.bindings.userLocation)
XCTAssertNil(viewModel.context.viewState.location)
viewModel.context.send(viewAction: .share)
XCTAssertNotNil(viewModel.context.viewState.bindings.alertInfo)
XCTAssertEqual(viewModel.context.viewState.bindings.alertInfo?.id, .userLocatingError)
}
func testShareExistingLocation() {
let viewModel = buildViewModel(withLocation: true)
let expectation = self.expectation(description: "Share completion should be invoked")
viewModel.completion = { result in
switch result {
case .share(let latitude, let longitude):
XCTAssertEqual(latitude, viewModel.context.viewState.location?.latitude)
XCTAssertEqual(longitude, viewModel.context.viewState.location?.longitude)
expectation.fulfill()
case .cancel:
XCTFail()
}
}
XCTAssertNil(viewModel.context.viewState.bindings.userLocation)
XCTAssertNotNil(viewModel.context.viewState.location)
viewModel.context.send(viewAction: .share)
XCTAssertNil(viewModel.context.viewState.bindings.alertInfo)
waitForExpectations(timeout: 3)
}
func testLoading() {
let viewModel = buildViewModel(withLocation: false)
viewModel.dispatch(action: .startLoading)
XCTAssertFalse(viewModel.context.viewState.shareButtonEnabled)
XCTAssertTrue(viewModel.context.viewState.showLoadingIndicator)
viewModel.dispatch(action: .stopLoading(nil))
XCTAssertTrue(viewModel.context.viewState.shareButtonEnabled)
XCTAssertFalse(viewModel.context.viewState.showLoadingIndicator)
}
func testInvalidLocationAuthorization() {
let viewModel = buildViewModel(withLocation: false)
viewModel.context.viewState.errorSubject.send(.invalidLocationAuthorization)
XCTAssertNotNil(viewModel.context.alertInfo)
XCTAssertEqual(viewModel.context.viewState.bindings.alertInfo?.id, .authorizationError)
}
private func buildViewModel(withLocation: Bool) -> LocationSharingViewModel {
LocationSharingViewModel(tileServerMapURL: URL(string: "http://empty.com")!,
avatarData: AvatarInput(mxContentUri: "", matrixItemId: "", displayName: ""),
location: (withLocation ? CLLocationCoordinate2D(latitude: 51.4932641, longitude: -0.257096) : nil))
}
}