Skip to content

Commit

Permalink
chore: ios: test coverage for log list / details view models (#2308)
Browse files Browse the repository at this point in the history
  • Loading branch information
krodak authored Jan 24, 2024
1 parent a1b5f53 commit 28a648c
Show file tree
Hide file tree
Showing 9 changed files with 481 additions and 8 deletions.
24 changes: 24 additions & 0 deletions ios/PolkadotVault.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@
6DA9DAE929E5831C009CC12C /* ManageNetworkDetailsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DA9DAE829E5831C009CC12C /* ManageNetworkDetailsService.swift */; };
6DAA6CB129BF482E002329A8 /* AuthenticatedStateMediator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DAA6CB029BF482E002329A8 /* AuthenticatedStateMediator.swift */; };
6DAA6CB329BF7155002329A8 /* OnboardingMediator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DAA6CB229BF7155002329A8 /* OnboardingMediator.swift */; };
6DAB52E92B5E718D005FDBA8 /* LogsListViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DAB52E82B5E718D005FDBA8 /* LogsListViewModelTests.swift */; };
6DAB52EB2B5E71FC005FDBA8 /* MLog+Generate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DAB52EA2B5E71FC005FDBA8 /* MLog+Generate.swift */; };
6DAB52ED2B5E75E7005FDBA8 /* MTransactionCardSet+Generate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DAB52EC2B5E75E7005FDBA8 /* MTransactionCardSet+Generate.swift */; };
6DAB52EF2B5E81BB005FDBA8 /* LogNoteModalViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DAB52EE2B5E81BB005FDBA8 /* LogNoteModalViewModelTests.swift */; };
6DAFCAF82B0A360600DDD165 /* CameraPermissionHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DAFCAF72B0A360600DDD165 /* CameraPermissionHandlerTests.swift */; };
6DAFCAFA2B0AE5C000DDD165 /* KeychainAccessAdapterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DAFCAF92B0AE5C000DDD165 /* KeychainAccessAdapterTests.swift */; };
6DAFCAFD2B0AE87300DDD165 /* RuntimePropertiesProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DAFCAFC2B0AE87300DDD165 /* RuntimePropertiesProviderTests.swift */; };
Expand Down Expand Up @@ -622,6 +626,10 @@
6DA9DAE829E5831C009CC12C /* ManageNetworkDetailsService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManageNetworkDetailsService.swift; sourceTree = "<group>"; };
6DAA6CB029BF482E002329A8 /* AuthenticatedStateMediator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticatedStateMediator.swift; sourceTree = "<group>"; };
6DAA6CB229BF7155002329A8 /* OnboardingMediator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingMediator.swift; sourceTree = "<group>"; };
6DAB52E82B5E718D005FDBA8 /* LogsListViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogsListViewModelTests.swift; sourceTree = "<group>"; };
6DAB52EA2B5E71FC005FDBA8 /* MLog+Generate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MLog+Generate.swift"; sourceTree = "<group>"; };
6DAB52EC2B5E75E7005FDBA8 /* MTransactionCardSet+Generate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MTransactionCardSet+Generate.swift"; sourceTree = "<group>"; };
6DAB52EE2B5E81BB005FDBA8 /* LogNoteModalViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogNoteModalViewModelTests.swift; sourceTree = "<group>"; };
6DAFCAF72B0A360600DDD165 /* CameraPermissionHandlerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraPermissionHandlerTests.swift; sourceTree = "<group>"; };
6DAFCAF92B0AE5C000DDD165 /* KeychainAccessAdapterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainAccessAdapterTests.swift; sourceTree = "<group>"; };
6DAFCAFC2B0AE87300DDD165 /* RuntimePropertiesProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimePropertiesProviderTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1618,6 +1626,8 @@
6DB2E7CB2B4BBF78002387DE /* MNetworkDetails+Generate.swift */,
6D80EB512B4EB0B8009C544B /* MSufficientCryptoReady+Generate.swift */,
6D80EB532B4EB0C8009C544B /* MAddressCard+Generate.swift */,
6DAB52EA2B5E71FC005FDBA8 /* MLog+Generate.swift */,
6DAB52EC2B5E75E7005FDBA8 /* MTransactionCardSet+Generate.swift */,
);
path = "Models+Generate";
sourceTree = "<group>";
Expand Down Expand Up @@ -1734,6 +1744,15 @@
path = Views;
sourceTree = "<group>";
};
6DAB52E72B5E7182005FDBA8 /* Logs */ = {
isa = PBXGroup;
children = (
6DAB52E82B5E718D005FDBA8 /* LogsListViewModelTests.swift */,
6DAB52EE2B5E81BB005FDBA8 /* LogNoteModalViewModelTests.swift */,
);
path = Logs;
sourceTree = "<group>";
};
6DAFCAF62B0A360600DDD165 /* Camera */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -1915,6 +1934,7 @@
6DDD38B42B1346BB000D2B62 /* Screens */ = {
isa = PBXGroup;
children = (
6DAB52E72B5E7182005FDBA8 /* Logs */,
6DB2E7BF2B4BBAEA002387DE /* Settings */,
6DDD38B52B1346C0000D2B62 /* PublicKey */,
);
Expand Down Expand Up @@ -2715,6 +2735,7 @@
6DE48E8F2B1F0B96003094D5 /* AutoMockable+Y.generated.swift in Sources */,
6DAFCB022B0AEE4900DDD165 /* ApplicationStatePublisherTests.swift in Sources */,
6DE48E842B1F0B96003094D5 /* AutoMockable+K.generated.swift in Sources */,
6DAB52EB2B5E71FC005FDBA8 /* MLog+Generate.swift in Sources */,
6DE48E962B1F0B96003094D5 /* AutoMockable+D.generated.swift in Sources */,
6DB2E7CC2B4BBF78002387DE /* MNetworkDetails+Generate.swift in Sources */,
6DE48E932B1F0B96003094D5 /* AutoMockable+W.generated.swift in Sources */,
Expand All @@ -2728,6 +2749,7 @@
6D57DC52289D68B800005C63 /* ActionResult+Generate.swift in Sources */,
6DAFCAFD2B0AE87300DDD165 /* RuntimePropertiesProviderTests.swift in Sources */,
6DB2E7C82B4BBEB0002387DE /* NetworkSelectionSettingsViewModelTests.swift in Sources */,
6DAB52ED2B5E75E7005FDBA8 /* MTransactionCardSet+Generate.swift in Sources */,
6DBD2202289A8E1F005D539B /* ErrorMock.swift in Sources */,
6DC2EDF92B11961800298F00 /* DateFormatterTests.swift in Sources */,
6DDD38B72B1346C8000D2B62 /* KeyDetailsPublicKeyViewModelTests.swift in Sources */,
Expand All @@ -2745,6 +2767,7 @@
6D2C78B02B56EF55006431E3 /* SettingsBackupModalViewModelTests.swift in Sources */,
6D80EB522B4EB0B8009C544B /* MSufficientCryptoReady+Generate.swift in Sources */,
6DE48E8C2B1F0B96003094D5 /* AutoMockable+R.generated.swift in Sources */,
6DAB52EF2B5E81BB005FDBA8 /* LogNoteModalViewModelTests.swift in Sources */,
6D5801E5289937BA006C41D8 /* ConnectivityMonitoringAssemblerTests.swift in Sources */,
6DE07B102B450EB7001AF54C /* OnboardingMediatorTests.swift in Sources */,
6DE48E882B1F0B96003094D5 /* AutoMockable+N.generated.swift in Sources */,
Expand All @@ -2758,6 +2781,7 @@
6DE48E852B1F0B96003094D5 /* AutoMockable+U.generated.swift in Sources */,
6DAFCAFA2B0AE5C000DDD165 /* KeychainAccessAdapterTests.swift in Sources */,
6DB2E7CE2B4BC7F6002387DE /* NetworkSettingDetailsViewModelTests.swift in Sources */,
6DAB52E92B5E718D005FDBA8 /* LogsListViewModelTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import Foundation
import LocalAuthentication

// sourcery: AutoMockable
protocol DevicePasscodeAuthenticatorProtocol {
/// This methods trigger passcode screen to authenticate user, if failed, will bring back "Unlock app" screen
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ struct LogEntryRenderable: Equatable, Hashable, Identifiable {
let navigationDetails: UInt32
}

final class LogEntryRenderableBuilder {
// sourcery: AutoMockable
protocol LogEntryRenderableBuilding: AnyObject {
func build(_ logs: MLog) -> [LogEntryRenderable]
}

final class LogEntryRenderableBuilder: LogEntryRenderableBuilding {
func build(_ logs: MLog) -> [LogEntryRenderable] {
var lastDate: String?
var shouldIncludeDate = false
Expand Down
6 changes: 3 additions & 3 deletions ios/PolkadotVault/Screens/Logs/Views/LogNoteModal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,13 @@ extension LogNoteModal {
@Published var note: String = ""
@Published var isActionDisabled: Bool = true
private var cancelBag = CancelBag()
private let logsService: LogsService
private let logsService: LogsServicing
@Published var isPresentingError: Bool = false
@Published var presentableError: ErrorBottomModalViewModel = .noNetworksAvailable()
@Published var presentableError: ErrorBottomModalViewModel!

init(
isPresented: Binding<Bool>,
logsService: LogsService = LogsService()
logsService: LogsServicing = LogsService()
) {
_isPresented = isPresented
self.logsService = logsService
Expand Down
8 changes: 4 additions & 4 deletions ios/PolkadotVault/Screens/Logs/Views/LogsListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ extension LogsListView {
@Published var isPresentingDetails = false
@Published var isPresentingError: Bool = false
@Published var presentableError: ErrorBottomModalViewModel = .noNetworksAvailable()
private let logsService: LogsService
private let logsService: LogsServicing
private let devicePasscodeAuthenticator: DevicePasscodeAuthenticatorProtocol
private let renderableBuilder: LogEntryRenderableBuilder
private let renderableBuilder: LogEntryRenderableBuilding

init(
logsService: LogsService = LogsService(),
logsService: LogsServicing = LogsService(),
devicePasscodeAuthenticator: DevicePasscodeAuthenticatorProtocol = ServiceLocator
.devicePasscodeAuthenticator,
renderableBuilder: LogEntryRenderableBuilder = LogEntryRenderableBuilder()
renderableBuilder: LogEntryRenderableBuilding = LogEntryRenderableBuilder()
) {
self.logsService = logsService
self.devicePasscodeAuthenticator = devicePasscodeAuthenticator
Expand Down
67 changes: 67 additions & 0 deletions ios/PolkadotVaultTests/Models+Generate/MLog+Generate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//
// MLog+Generate.swift
// PolkadotVaultTests
//
// Created by Krzysztof Rodak on 22/01/2024.
//

import Foundation
@testable import PolkadotVault

extension MLog {
static func generate(
log: [History] = [History.generate()]
) -> MLog {
MLog(
log: log
)
}
}

extension History {
static func generate(
order: UInt32 = 0,
timestamp: String = "2021-01-01T00:00:00Z",
events: [Event] = [Event.generate()]
) -> History {
History(
order: order,
timestamp: timestamp,
events: events
)
}
}

extension Event {
static func generate() -> Event {
.identitiesWiped
}
}

extension MLogDetails {
static func generate(
timestamp: String = "2021-01-01T00:00:00Z",
events: [MEventMaybeDecoded] = [MEventMaybeDecoded.generate()]
) -> MLogDetails {
MLogDetails(
timestamp: timestamp,
events: events
)
}
}

extension MEventMaybeDecoded {
static func generate(
event: Event = Event.generate(),
signedBy: MAddressCard? = .generate(),
decoded: TransactionCardSet? = .generate(),
verifierDetails: MVerifierDetails? = .generate()
) -> MEventMaybeDecoded {
MEventMaybeDecoded(
event: event,
signedBy: signedBy,
decoded: decoded,
verifierDetails: verifierDetails
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// MTransactionCardSet+Generate.swift
// PolkadotVaultTests
//
// Created by Krzysztof Rodak on 22/01/2024.
//

import Foundation
@testable import PolkadotVault

extension TransactionCardSet {
static func generate(
author: [TransactionCard]? = [TransactionCard.generate()],
error: [TransactionCard]? = [TransactionCard.generate()],
extensions: [TransactionCard]? = [TransactionCard.generate()],
importingDerivations: [TransactionCard]? = [TransactionCard.generate()],
message: [TransactionCard]? = [TransactionCard.generate()],
meta: [TransactionCard]? = [TransactionCard.generate()],
method: [TransactionCard]? = [TransactionCard.generate()],
newSpecs: [TransactionCard]? = [TransactionCard.generate()],
verifier: [TransactionCard]? = [TransactionCard.generate()],
warning: [TransactionCard]? = [TransactionCard.generate()],
typesInfo: [TransactionCard]? = [TransactionCard.generate()]
) -> TransactionCardSet {
TransactionCardSet(
author: author,
error: error,
extensions: extensions,
importingDerivations: importingDerivations,
message: message,
meta: meta,
method: method,
newSpecs: newSpecs,
verifier: verifier,
warning: warning,
typesInfo: typesInfo
)
}
}

extension TransactionCard {
static func generate(
index: UInt32 = 0,
indent: UInt32 = 0,
card: Card = Card.generate()
) -> TransactionCard {
TransactionCard(
index: index,
indent: indent,
card: card
)
}
}

extension Card {
static func generate() -> Card {
.eraImmortalCard
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//
// LogNoteModalViewModelTests.swift
// PolkadotVaultTests
//
// Created by Krzysztof Rodak on 22/01/2024.
//

import Combine
import Foundation
@testable import PolkadotVault
import SwiftUI
import XCTest

final class LogNoteModalViewModelTests: XCTestCase {
private var viewModel: LogNoteModal.ViewModel!
private var logsServiceMock: LogsServicingMock!
private var cancelBag: Set<AnyCancellable>!
private var isPresented: Bool = false

override func setUp() {
super.setUp()
logsServiceMock = LogsServicingMock()
isPresented = false
viewModel = LogNoteModal.ViewModel(
isPresented: Binding(get: { self.isPresented }, set: { self.isPresented = $0 }),
logsService: logsServiceMock
)
cancelBag = []
}

override func tearDown() {
viewModel = nil
logsServiceMock = nil
cancelBag = nil
super.tearDown()
}

func testInit_SetsIsActionDisabledToTrue() {
// Then
XCTAssertTrue(viewModel.isActionDisabled)
}

func testNoteChange_UpdatesIsActionDisabled() {
// When
viewModel.note = "new note"

// Then
XCTAssertFalse(viewModel.isActionDisabled)
}

func testOnCancelTap_SetsIsPresentedToFalse() {
// When
viewModel.onCancelTap()

// Then
XCTAssertFalse(isPresented)
}

func testOnDoneTap_WithSuccess() {
// Given
viewModel.note = "new note"

// When
viewModel.onDoneTap()
logsServiceMock.addCommentToLogsReceivedCompletion.first?(.success(()))

// Then
XCTAssertFalse(isPresented)
}

func testOnDoneTap_WithFailure() {
// Given
viewModel.note = "new note"
let error = ServiceError(message: "Error")
let presentableError: ErrorBottomModalViewModel = .alertError(message: error.localizedDescription)

// When
viewModel.onDoneTap()
logsServiceMock.addCommentToLogsReceivedCompletion.first?(.failure(error))

// Then
XCTAssertEqual(viewModel.presentableError, presentableError)
XCTAssertTrue(viewModel.isPresentingError)
}
}
Loading

0 comments on commit 28a648c

Please sign in to comment.