Skip to content

Commit

Permalink
feat: ios: banana split unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
krodak committed Mar 6, 2024
1 parent 1b938c8 commit d6087d3
Show file tree
Hide file tree
Showing 4 changed files with 319 additions and 0 deletions.
19 changes: 19 additions & 0 deletions ios/PolkadotVault.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,9 @@
6DD9FF1628C8B85300FB6195 /* HorizontalActionsBottomModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DD9FF1528C8B85300FB6195 /* HorizontalActionsBottomModal.swift */; };
6DD9FF1928C8C9B000FB6195 /* Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DD9FF1828C8C9AF00FB6195 /* Animations.swift */; };
6DDD01D32B9504D1000F53B3 /* KeychainBananaSplitQueryProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DDD01D22B9504D1000F53B3 /* KeychainBananaSplitQueryProviderTests.swift */; };
6DDD01D72B958372000F53B3 /* BananaSplitPassphraseModalViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DDD01D62B958372000F53B3 /* BananaSplitPassphraseModalViewModelTests.swift */; };
6DDD01D92B958845000F53B3 /* BananaSplitActionModalViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DDD01D82B958845000F53B3 /* BananaSplitActionModalViewModelTests.swift */; };
6DDD01DB2B9589B5000F53B3 /* BananaSplitQRCodeModalViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DDD01DA2B9589B5000F53B3 /* BananaSplitQRCodeModalViewModelTests.swift */; };
6DDD38B22B11C3C2000D2B62 /* SeedsMediatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DDD38B12B11C3C2000D2B62 /* SeedsMediatorTests.swift */; };
6DDD38B72B1346C8000D2B62 /* KeyDetailsPublicKeyViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DDD38B62B1346C8000D2B62 /* KeyDetailsPublicKeyViewModelTests.swift */; };
6DDD38B92B134ADF000D2B62 /* MKeyDetails+Generate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DDD38B82B134ADF000D2B62 /* MKeyDetails+Generate.swift */; };
Expand Down Expand Up @@ -745,6 +748,9 @@
6DD9FF1528C8B85300FB6195 /* HorizontalActionsBottomModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HorizontalActionsBottomModal.swift; sourceTree = "<group>"; };
6DD9FF1828C8C9AF00FB6195 /* Animations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Animations.swift; sourceTree = "<group>"; };
6DDD01D22B9504D1000F53B3 /* KeychainBananaSplitQueryProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainBananaSplitQueryProviderTests.swift; sourceTree = "<group>"; };
6DDD01D62B958372000F53B3 /* BananaSplitPassphraseModalViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BananaSplitPassphraseModalViewModelTests.swift; sourceTree = "<group>"; };
6DDD01D82B958845000F53B3 /* BananaSplitActionModalViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BananaSplitActionModalViewModelTests.swift; sourceTree = "<group>"; };
6DDD01DA2B9589B5000F53B3 /* BananaSplitQRCodeModalViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BananaSplitQRCodeModalViewModelTests.swift; sourceTree = "<group>"; };
6DDD38B12B11C3C2000D2B62 /* SeedsMediatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedsMediatorTests.swift; sourceTree = "<group>"; };
6DDD38B62B1346C8000D2B62 /* KeyDetailsPublicKeyViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyDetailsPublicKeyViewModelTests.swift; sourceTree = "<group>"; };
6DDD38B82B134ADF000D2B62 /* MKeyDetails+Generate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MKeyDetails+Generate.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2125,6 +2131,16 @@
path = KeyDetails;
sourceTree = "<group>";
};
6DDD01D52B958365000F53B3 /* BananaSplit */ = {
isa = PBXGroup;
children = (
6DDD01D62B958372000F53B3 /* BananaSplitPassphraseModalViewModelTests.swift */,
6DDD01D82B958845000F53B3 /* BananaSplitActionModalViewModelTests.swift */,
6DDD01DA2B9589B5000F53B3 /* BananaSplitQRCodeModalViewModelTests.swift */,
);
path = BananaSplit;
sourceTree = "<group>";
};
6DDD38B42B1346BB000D2B62 /* Screens */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2976,6 +2992,7 @@
6DE48E932B1F0B96003094D5 /* AutoMockable+W.generated.swift in Sources */,
6DE48E2E2B1EB97C003094D5 /* AutoMockableHeader.swift in Sources */,
6DE48E902B1F0B96003094D5 /* AutoMockable+A.generated.swift in Sources */,
6DDD01DB2B9589B5000F53B3 /* BananaSplitQRCodeModalViewModelTests.swift in Sources */,
6D8AF88A28BCC60600CF0AB2 /* KeychainSeedsQueryProviderTests.swift in Sources */,
6DB2E7C12B4BBAF7002387DE /* SettingsViewModelTests.swift in Sources */,
6D9856542B6A6B03002358D3 /* AirgapComponentTests.swift in Sources */,
Expand Down Expand Up @@ -3008,6 +3025,7 @@
6DE48E802B1F0B96003094D5 /* AutoMockable+P.generated.swift in Sources */,
6D9856732B716564002358D3 /* CreateDerivedKeyConfirmationViewModelTests.swift in Sources */,
6D80EB502B4EAD3E009C544B /* VerifierCertificateViewModelTests.swift in Sources */,
6DDD01D72B958372000F53B3 /* BananaSplitPassphraseModalViewModelTests.swift in Sources */,
6D2C78B02B56EF55006431E3 /* SettingsBackupModalViewModelTests.swift in Sources */,
6D80EB522B4EB0B8009C544B /* MSufficientCryptoReady+Generate.swift in Sources */,
6DE48E8C2B1F0B96003094D5 /* AutoMockable+R.generated.swift in Sources */,
Expand All @@ -3028,6 +3046,7 @@
6DE48E972B1F0B96003094D5 /* AutoMockable+L.generated.swift in Sources */,
6D98566D2B716112002358D3 /* DerivationPathNameViewModelTests.swift in Sources */,
6DE48E852B1F0B96003094D5 /* AutoMockable+U.generated.swift in Sources */,
6DDD01D92B958845000F53B3 /* BananaSplitActionModalViewModelTests.swift in Sources */,
6DAFCAFA2B0AE5C000DDD165 /* KeychainSeedsAccessAdapterTests.swift in Sources */,
6DB2E7CE2B4BC7F6002387DE /* NetworkSettingDetailsViewModelTests.swift in Sources */,
6DAB52E92B5E718D005FDBA8 /* LogsListViewModelTests.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//
// BananaSplitActionModalViewModelTests.swift
// PolkadotVaultTests
//
// Created by Krzysztof Rodak on 04/03/2024.
//

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

final class BananaSplitActionModalViewModelTests: XCTestCase {
private var viewModel: BananaSplitActionModal.ViewModel!
private var isPresented: Bool = false
private var shouldPresentDeleteBackupWarningModal: Bool!
private var shouldPresentPassphraseModal: Bool!

override func setUp() {
super.setUp()
isPresented = true
shouldPresentDeleteBackupWarningModal = false
shouldPresentPassphraseModal = false
viewModel = BananaSplitActionModal.ViewModel(
isPresented: Binding(
get: { self.isPresented },

set: { self.isPresented = $0 }
),
shouldPresentDeleteBackupWarningModal: Binding(
get: { self.shouldPresentDeleteBackupWarningModal },
set: { self.shouldPresentDeleteBackupWarningModal = $0 }
),
shouldPresentPassphraseModal: Binding(
get: { self.shouldPresentPassphraseModal },
set: { self.shouldPresentPassphraseModal = $0 }
)
)
}

override func tearDown() {
shouldPresentDeleteBackupWarningModal = nil
shouldPresentPassphraseModal = nil
isPresented = false
viewModel = nil
super.tearDown()
}

func testRemoveBackup_TriggerWarningModalAndDismiss() {
// Given
let expectation = expectation(description: "RemoveBackupDismissal")

// When
viewModel.removeBackup()

// Then
XCTAssertTrue(shouldPresentDeleteBackupWarningModal)

DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
XCTAssertFalse(self.isPresented)
expectation.fulfill()
}

waitForExpectations(timeout: 2)
}

func testShowPassphrase_TriggerPassphraseModalAndDismiss() {
// Given
let expectation = expectation(description: "ShowPassphraseDismissal")

// When
viewModel.showPassphrase()

// Then
XCTAssertTrue(shouldPresentPassphraseModal)

DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
XCTAssertFalse(self.isPresented)
expectation.fulfill()
}

waitForExpectations(timeout: 2)
}

func testDismissActionSheet_TriggersAnimationAndDismissal() {
// Given
let expectation = expectation(description: "AnimateDismissal")

// When
viewModel.dismissActionSheet()

// Then
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
XCTAssertFalse(self.isPresented)
expectation.fulfill()
}

waitForExpectations(timeout: 2)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//
// BananaSplitPassphraseModalViewModelTests.swift
// PolkadotVaultTests
//
// Created by Krzysztof Rodak on 04/03/2024.
//

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

final class BananaSplitPassphraseModalViewModelTests: XCTestCase {
private var viewModel: BananaSplitPassphraseModal.ViewModel!
private var mediatorMock: KeychainBananaSplitAccessMediatingMock!
private var isPresented: Bool!
private var seedName: String!

override func setUp() {
super.setUp()
seedName = "testSeed"
mediatorMock = KeychainBananaSplitAccessMediatingMock()
isPresented = true
}

override func tearDown() {
viewModel = nil
mediatorMock = nil
seedName = nil
isPresented = nil
super.tearDown()
}

func testInit_LoadsPassphraseOnSuccess() {
// Given
let expectedPassphrase = "loadedPassphrase"
mediatorMock
.retrieveBananaSplitPassphraseWithReturnValue =
.success(BananaSplitPassphrase(passphrase: expectedPassphrase))

// When
viewModel = BananaSplitPassphraseModal.ViewModel(
seedName: seedName,
isPresented: Binding(get: { self.isPresented }, set: { self.isPresented = $0 }),
bananaSplitMediator: mediatorMock
)

// Then
XCTAssertEqual(mediatorMock.retrieveBananaSplitPassphraseWithCallsCount, 1)
XCTAssertEqual(mediatorMock.retrieveBananaSplitPassphraseWithReceivedSeedName, [seedName])
XCTAssertEqual(viewModel.passphrase, expectedPassphrase)
}

func testInit_DoesNotLoadPassphraseOnFailure() {
// Given
mediatorMock.retrieveBananaSplitPassphraseWithReturnValue = .failure(.fetchError)

// When
viewModel = BananaSplitPassphraseModal.ViewModel(
seedName: "testSeed",
isPresented: Binding(get: { self.isPresented }, set: { self.isPresented = $0 }),
bananaSplitMediator: mediatorMock
)

// Then
XCTAssertEqual(mediatorMock.retrieveBananaSplitPassphraseWithCallsCount, 1)
XCTAssertEqual(mediatorMock.retrieveBananaSplitPassphraseWithReceivedSeedName, ["testSeed"])
XCTAssertEqual(viewModel.passphrase, "")
}

func testDismissActionSheet_TriggersAnimationAndDismissal() {
// Given
let expectation = expectation(description: "AnimateDismissal")
mediatorMock.retrieveBananaSplitPassphraseWithReturnValue = .failure(.fetchError)
viewModel = BananaSplitPassphraseModal.ViewModel(
seedName: seedName,
isPresented: Binding(get: { self.isPresented }, set: { self.isPresented = $0 }),
bananaSplitMediator: mediatorMock
)

// When
viewModel.dismissActionSheet()

// Then
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
XCTAssertFalse(self.isPresented)
expectation.fulfill()
}

waitForExpectations(timeout: 2, handler: nil)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//
// BananaSplitQRCodeModalViewModelTests.swift
// PolkadotVaultTests
//
// Created by Krzysztof Rodak on 04/03/2024.
//

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

final class BananaSplitQRCodeModalViewModelTests: XCTestCase {
private var viewModel: BananaSplitQRCodeModalView.ViewModel!
private var mediatorMock: KeychainBananaSplitAccessMediatingMock!
private var completionAction: BananaSplitQRCodeModalView.OnCompletionAction?
private var testSeedName: String!
private var testBananaSplitBackup: BananaSplitBackup!

override func setUp() {
super.setUp()
testSeedName = "testSeed"
testBananaSplitBackup = BananaSplitBackup(qrCodes: [[10]])
mediatorMock = KeychainBananaSplitAccessMediatingMock()
viewModel = BananaSplitQRCodeModalView.ViewModel(
seedName: testSeedName,
bananaSplitBackup: testBananaSplitBackup,
bananaSplitMediator: mediatorMock,
onCompletion: { [weak self] action in
self?.completionAction = action
}
)
}

override func tearDown() {
testSeedName = nil
testBananaSplitBackup = nil
viewModel = nil
mediatorMock = nil
completionAction = nil
super.tearDown()
}

func testOnMoreButtonTap_PresentsActionSheet() {
// When
viewModel.onMoreButtonTap()

// Then
XCTAssertTrue(viewModel.isPresentingActionSheet)
}

func testOnCloseTap_CompletesWithClose() {
// When
viewModel.onCloseTap()

// Then
XCTAssertEqual(completionAction, .close)
}

func testCheckForActionsPresentation_PresentsPassphraseModal() {
// Given
viewModel.shouldPresentPassphraseModal = true

// When
viewModel.checkForActionsPresentation()

// Then
XCTAssertTrue(viewModel.isPresentingPassphraseModal)
}

func testCheckForActionsPresentation_PresentsDeleteBackupWarningModal() {
// Given
viewModel.shouldPresentDeleteBackupWarningModal = true

// When
viewModel.checkForActionsPresentation()

// Then
XCTAssertTrue(viewModel.isPresentingDeleteBackupWarningModal)
}

func testOnDeleteBackupTap_DeletesBackupSuccessfully() {
// Given
mediatorMock.removeBananaSplitBackupSeedNameReturnValue = .success(())

// When
viewModel.onDeleteBackupTap()

// Then
XCTAssertEqual(completionAction, .backupDeleted)
}

func testOnDeleteBackupTap_FailsToDeleteBackup() {
// Given
let expectedError = KeychainError.checkError
mediatorMock.removeBananaSplitBackupSeedNameReturnValue = .failure(expectedError)

// When
viewModel.onDeleteBackupTap()

// Then
XCTAssertTrue(viewModel.isPresentingError)
XCTAssertEqual(viewModel.presentableError, .alertError(message: expectedError.localizedDescription))
}
}

0 comments on commit d6087d3

Please sign in to comment.