Unit and ui tests

This commit is contained in:
Aleksandrs Proskurins 2022-09-26 16:56:34 +03:00
parent ffc4fcf1c7
commit d1b4b6de48
7 changed files with 71 additions and 78 deletions

View file

@ -21,6 +21,7 @@ enum MockAppScreens {
static let appScreens: [MockScreenState.Type] = [
MockUserSessionsOverviewScreenState.self,
MockUserSessionDetailsScreenState.self,
MockUserSessionOverviewScreenState.self,
MockLiveLocationLabPromotionScreenState.self,
MockLiveLocationSharingViewerScreenState.self,
MockAuthenticationLoginScreenState.self,

View file

@ -63,7 +63,7 @@ final class UserSessionOverviewCoordinator: Coordinator, Presentable {
switch result {
case .verifyCurrentSession:
break // TODO
case let .showCurrentSessionDetails(sessionInfo: sessionInfo):
case let .showSessionDetails(sessionInfo: sessionInfo):
self.completion?(.openSessionDetails(session: sessionInfo))
}
}

View file

@ -18,40 +18,19 @@ import XCTest
import RiotSwiftUI
class UserSessionOverviewUITests: MockScreenTestCase {
func testUserSessionOverviewPresenceIdle() {
let presence = UserSessionOverviewPresence.idle
app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.presence(presence).title)
let presenceText = app.staticTexts["presenceText"]
XCTAssert(presenceText.exists)
XCTAssertEqual(presenceText.label, presence.title)
func test_whenCurrentSessionSelected_correctNavTittleDisplayed() {
app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.currentSession.title)
XCTAssertTrue(app.navigationBars[VectorL10n.userSessionOverviewCurrentSessionTitle].staticTexts[VectorL10n.userSessionOverviewCurrentSessionTitle].exists)
}
func testUserSessionOverviewPresenceOffline() {
let presence = UserSessionOverviewPresence.offline
app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.presence(presence).title)
let presenceText = app.staticTexts["presenceText"]
XCTAssert(presenceText.exists)
XCTAssertEqual(presenceText.label, presence.title)
func test_whenOtherSessionSelected_correctNavTittleDisplayed() {
app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.otherSession.title)
XCTAssertTrue(app.navigationBars[VectorL10n.userSessionOverviewSessionTitle].staticTexts[VectorL10n.userSessionOverviewSessionTitle].exists)
}
func testUserSessionOverviewPresenceOnline() {
let presence = UserSessionOverviewPresence.online
app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.presence(presence).title)
let presenceText = app.staticTexts["presenceText"]
XCTAssert(presenceText.exists)
XCTAssertEqual(presenceText.label, presence.title)
func test_whenSessionOverviewPresented_sessionDetailsButtonExists() {
app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.currentSession.title)
XCTAssertTrue(app.buttons[VectorL10n.userSessionOverviewSessionDetailsButtonTitle].exists)
}
func testUserSessionOverviewLongName() {
let name = "Somebody with a super long name we would like to test"
app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.longDisplayName(name).title)
let displayNameText = app.staticTexts["displayNameText"]
XCTAssert(displayNameText.exists)
XCTAssertEqual(displayNameText.label, name)
}
}

View file

@ -20,37 +20,38 @@ import Combine
@testable import RiotSwiftUI
class UserSessionOverviewViewModelTests: XCTestCase {
private enum Constants {
static let presenceInitialValue: UserSessionOverviewPresence = .offline
static let displayName = "Alice"
}
var service: MockUserSessionOverviewService!
var viewModel: UserSessionOverviewViewModelProtocol!
var context: UserSessionOverviewViewModelType.Context!
var cancellables = Set<AnyCancellable>()
override func setUpWithError() throws {
service = MockUserSessionOverviewService(displayName: Constants.displayName, presence: Constants.presenceInitialValue)
viewModel = UserSessionOverviewViewModel.makeUserSessionOverviewViewModel(userSessionOverviewService: service)
context = viewModel.context
}
func testInitialState() {
XCTAssertEqual(context.viewState.displayName, Constants.displayName)
XCTAssertEqual(context.viewState.presence, Constants.presenceInitialValue)
}
var sut: UserSessionOverviewViewModel!
func testFirstPresenceReceived() throws {
let presencePublisher = context.$viewState.map(\.presence).removeDuplicates().collect(1).first()
XCTAssertEqual(try xcAwait(presencePublisher), [Constants.presenceInitialValue])
func test_whenVerifyCurrentSessionProcessed_completionWithVerifyCurrentSessionCalled() {
sut = UserSessionOverviewViewModel(userSessionInfo: createUserSessionInfo(), isCurrentSession: true)
var modelResult: UserSessionOverviewViewModelResult?
sut.completion = { result in
modelResult = result
}
sut.process(viewAction: .verifyCurrentSession)
XCTAssertEqual(modelResult, .verifyCurrentSession)
}
func test_whenViewSessionDetailsProcessed_completionWithShowSessionDetailsCalled() {
let session = createUserSessionInfo()
sut = UserSessionOverviewViewModel(userSessionInfo: session, isCurrentSession: true)
func testPresenceUpdatesReceived() throws {
let presencePublisher = context.$viewState.map(\.presence).removeDuplicates().collect(3).first()
let awaitDeferred = xcAwaitDeferred(presencePublisher)
let newPresenceValue1: UserSessionOverviewPresence = .online
let newPresenceValue2: UserSessionOverviewPresence = .idle
service.simulateUpdate(presence: newPresenceValue1)
service.simulateUpdate(presence: newPresenceValue2)
XCTAssertEqual(try awaitDeferred(), [Constants.presenceInitialValue, newPresenceValue1, newPresenceValue2])
var modelResult: UserSessionOverviewViewModelResult?
sut.completion = { result in
modelResult = result
}
sut.process(viewAction: .viewSessionDetails)
XCTAssertEqual(modelResult, .showSessionDetails(sessionInfo: session))
}
private func createUserSessionInfo() -> UserSessionInfo {
UserSessionInfo(sessionId: "session",
sessionName: "iOS",
deviceType: .mobile,
isVerified: false,
lastSeenIP: "10.0.0.10",
lastSeenTimestamp: Date().timeIntervalSince1970 - 100)
}
}

View file

@ -24,11 +24,24 @@ enum UserSessionOverviewCoordinatorResult {
// MARK: View model
enum UserSessionOverviewViewModelResult {
case showCurrentSessionDetails(sessionInfo: UserSessionInfo)
enum UserSessionOverviewViewModelResult: Equatable {
case showSessionDetails(sessionInfo: UserSessionInfo)
case verifyCurrentSession
}
extension UserSessionOverviewViewModelResult {
static func == (lhs: UserSessionOverviewViewModelResult, rhs: UserSessionOverviewViewModelResult) -> Bool {
switch (lhs, rhs) {
case (.verifyCurrentSession, .verifyCurrentSession):
return true
case (let .showSessionDetails(session), let .showSessionDetails(session2)):
return session.id == session2.id
default:
return false
}
}
}
// MARK: View
struct UserSessionOverviewViewState: BindableState {

View file

@ -47,7 +47,7 @@ class UserSessionOverviewViewModel: UserSessionOverviewViewModelType, UserSessio
case .verifyCurrentSession:
completion?(.verifyCurrentSession)
case .viewSessionDetails:
completion?(.showCurrentSessionDetails(sessionInfo: userSessionInfo))
completion?(.showSessionDetails(sessionInfo: userSessionInfo))
}
}
}

View file

@ -24,22 +24,21 @@ struct UserSessionOverviewDisclosureCell: View {
var onBackgroundTap: (() -> (Void))? = nil
var body: some View {
VStack(spacing: 0) {
SeparatorLine()
HStack() {
Text(title)
.font(theme.fonts.body)
.foregroundColor(theme.colors.primaryContent)
.frame(maxWidth: .infinity, alignment: .leading)
Image(Asset.Images.chevron.name)
Button(action: { onBackgroundTap?()}) {
VStack(spacing: 0) {
SeparatorLine()
HStack() {
Text(title)
.font(theme.fonts.body)
.foregroundColor(theme.colors.primaryContent)
.frame(maxWidth: .infinity, alignment: .leading)
Image(Asset.Images.chevron.name)
}
.padding(.vertical, 12)
.padding(.horizontal, 16)
SeparatorLine()
}
.padding(.vertical, 12)
.padding(.horizontal, 16)
SeparatorLine()
}
.background(theme.colors.background)
.onTapGesture {
onBackgroundTap?()
.background(theme.colors.background)
}
}
}