658 lines
22 KiB
Swift
658 lines
22 KiB
Swift
//
|
|
// RecoveryPhraseValidationTests.swift
|
|
// secantTests
|
|
//
|
|
// Created by Francisco Gindre on 10/29/21.
|
|
//
|
|
// swiftlint:disable type_body_length
|
|
import XCTest
|
|
import ComposableArchitecture
|
|
@testable import secant_testnet
|
|
|
|
class RecoveryPhraseValidationTests: XCTestCase {
|
|
static let testScheduler = DispatchQueue.test
|
|
|
|
let testEnvironment = BackupPhraseEnvironment(
|
|
mainQueue: testScheduler.eraseToAnyScheduler(),
|
|
newPhrase: { Effect(value: .init(words: RecoveryPhrase.placeholder.words)) },
|
|
pasteboard: .test
|
|
)
|
|
|
|
func testPickWordsFromMissingIndices() throws {
|
|
let words = [
|
|
"bring", "salute", "thank",
|
|
"require", "spirit", "toe",
|
|
// second chunk
|
|
"boil", "hill", "casino",
|
|
"trophy", "drink", "frown",
|
|
// third chunk
|
|
"bird", "grit", "close",
|
|
"morning", "bind", "cancel",
|
|
// Fourth chunk
|
|
"daughter", "salon", "quit",
|
|
"pizza", "just", "garlic"
|
|
]
|
|
|
|
let phrase = RecoveryPhrase(words: words)
|
|
|
|
let indices = [1, 0, 5, 3]
|
|
|
|
let expected = ["salute", "boil", "cancel", "pizza"].map({ PhraseChip.Kind.unassigned(word: $0) })
|
|
|
|
let result = phrase.words(fromMissingIndices: indices)
|
|
|
|
XCTAssertEqual(expected, result)
|
|
}
|
|
|
|
func testWhenInInitialStepChipIsDraggedIntoGroup1FollowingStepIsIncomplete() {
|
|
let words = [
|
|
"bring", "salute", "thank",
|
|
"require", "spirit", "toe",
|
|
// second chunk
|
|
"boil", "hill", "casino",
|
|
"trophy", "drink", "frown",
|
|
// third chunk
|
|
"bird", "grit", "close",
|
|
"morning", "bind", "cancel",
|
|
// Fourth chunk
|
|
"daughter", "salon", "quit",
|
|
"pizza", "just", "garlic"
|
|
]
|
|
|
|
let missingIndices = [1, 0, 5, 3]
|
|
|
|
let phrase = RecoveryPhrase(words: words)
|
|
|
|
let missingWordChips: [PhraseChip.Kind] = ["salute", "boil", "cancel", "pizza"].map({ PhraseChip.Kind.unassigned(word: $0) })
|
|
|
|
let initialStep = RecoveryPhraseValidationState(
|
|
phrase: phrase,
|
|
missingIndices: missingIndices,
|
|
missingWordChips: missingWordChips,
|
|
validationWords: []
|
|
)
|
|
|
|
let store = TestStore(initialState: initialStep, reducer: RecoveryPhraseValidationReducer.default, environment: testEnvironment)
|
|
|
|
let expectedMissingChips = [
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.unassigned(word: "boil"),
|
|
PhraseChip.Kind.unassigned(word: "cancel"),
|
|
PhraseChip.Kind.unassigned(word: "pizza")
|
|
]
|
|
|
|
let expectedValidationWords = [ValidationWord(groupIndex: 1, word: "salute")]
|
|
|
|
store.send(.move(wordChip: .unassigned(word: "salute"), intoGroup: 1)) {
|
|
$0.validationWords = expectedValidationWords
|
|
$0.missingWordChips = expectedMissingChips
|
|
|
|
XCTAssertFalse($0.isComplete)
|
|
}
|
|
}
|
|
|
|
func testWhenInInitialStepChipIsDraggedIntoGroup0FollowingStepIsIncompleteNextStateIsIncomplete() {
|
|
let words = [
|
|
"bring", "salute", "thank",
|
|
"require", "spirit", "toe",
|
|
// second chunk
|
|
"boil", "hill", "casino",
|
|
"trophy", "drink", "frown",
|
|
// third chunk
|
|
"bird", "grit", "close",
|
|
"morning", "bind", "cancel",
|
|
// Fourth chunk
|
|
"daughter", "salon", "quit",
|
|
"pizza", "just", "garlic"
|
|
]
|
|
|
|
let missingIndices = [1, 0, 5, 3]
|
|
|
|
let phrase = RecoveryPhrase(words: words)
|
|
|
|
let missingWordChips = ["salute", "boil", "cancel", "pizza"].map({ PhraseChip.Kind.unassigned(word: $0) })
|
|
|
|
let initialStep = RecoveryPhraseValidationState.initial(
|
|
phrase: phrase,
|
|
missingIndices: missingIndices,
|
|
missingWordsChips: missingWordChips
|
|
)
|
|
|
|
let store = TestStore(initialState: initialStep, reducer: RecoveryPhraseValidationReducer.default, environment: testEnvironment)
|
|
|
|
let expectedMissingChips = [
|
|
PhraseChip.Kind.unassigned(word: "salute"),
|
|
PhraseChip.Kind.unassigned(word: "boil"),
|
|
PhraseChip.Kind.unassigned(word: "cancel"),
|
|
PhraseChip.Kind.empty
|
|
]
|
|
|
|
let expectedValidationWords = [ValidationWord(groupIndex: 0, word: "pizza")]
|
|
|
|
store.send(.move(wordChip: missingWordChips[3], intoGroup: 0)) {
|
|
$0.missingWordChips = expectedMissingChips
|
|
$0.validationWords = expectedValidationWords
|
|
|
|
XCTAssertFalse($0.isComplete)
|
|
}
|
|
}
|
|
|
|
func testWhenInIncompleteWith2CompletionsAndAChipIsDroppedInGroup3NextStateIsIncomplete() {
|
|
let words = [
|
|
"bring", "salute", "thank",
|
|
"require", "spirit", "toe",
|
|
// second chunk
|
|
"boil", "hill", "casino",
|
|
"trophy", "drink", "frown",
|
|
// third chunk
|
|
"bird", "grit", "close",
|
|
"morning", "bind", "cancel",
|
|
// Fourth chunk
|
|
"daughter", "salon", "quit",
|
|
"pizza", "just", "garlic"
|
|
]
|
|
|
|
let missingIndices = [1, 0, 5, 3]
|
|
|
|
let phrase = RecoveryPhrase(words: words)
|
|
|
|
let currentStep = RecoveryPhraseValidationState(
|
|
phrase: phrase,
|
|
missingIndices: missingIndices,
|
|
missingWordChips: [
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.unassigned(word: "boil"),
|
|
PhraseChip.Kind.unassigned(word: "cancel"),
|
|
PhraseChip.Kind.unassigned(word: "pizza")
|
|
],
|
|
validationWords: [ValidationWord(groupIndex: 0, word: "salute")]
|
|
)
|
|
|
|
let store = TestStore(initialState: currentStep, reducer: RecoveryPhraseValidationReducer.default, environment: testEnvironment)
|
|
|
|
let expectedMissingWordChips = [
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.unassigned(word: "cancel"),
|
|
PhraseChip.Kind.unassigned(word: "pizza")
|
|
]
|
|
|
|
let expectedValidationWords = [
|
|
ValidationWord(groupIndex: 0, word: "salute"),
|
|
ValidationWord(groupIndex: 1, word: "boil")
|
|
]
|
|
|
|
store.send(.move(wordChip: PhraseChip.Kind.unassigned(word: "boil"), intoGroup: 1)) {
|
|
$0.missingWordChips = expectedMissingWordChips
|
|
$0.validationWords = expectedValidationWords
|
|
|
|
XCTAssertFalse($0.isComplete)
|
|
}
|
|
}
|
|
|
|
func testWhenInIncompleteWith2CompletionsAndAChipIsDroppedInGroup2NextStateIsIncomplete() {
|
|
let words = [
|
|
"bring", "salute", "thank",
|
|
"require", "spirit", "toe",
|
|
// second chunk
|
|
"boil", "hill", "casino",
|
|
"trophy", "drink", "frown",
|
|
// third chunk
|
|
"bird", "grit", "close",
|
|
"morning", "bind", "cancel",
|
|
// Fourth chunk
|
|
"daughter", "salon", "quit",
|
|
"pizza", "just", "garlic"
|
|
]
|
|
|
|
let missingIndices = [1, 0, 5, 3]
|
|
|
|
let phrase = RecoveryPhrase(words: words)
|
|
|
|
let currentStep = RecoveryPhraseValidationState(
|
|
phrase: phrase,
|
|
missingIndices: missingIndices,
|
|
missingWordChips: [
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.unassigned(word: "cancel"),
|
|
PhraseChip.Kind.unassigned(word: "pizza")
|
|
],
|
|
validationWords: [
|
|
ValidationWord(groupIndex: 0, word: "salute"),
|
|
ValidationWord(groupIndex: 1, word: "boil")
|
|
]
|
|
)
|
|
|
|
let store = TestStore(initialState: currentStep, reducer: RecoveryPhraseValidationReducer.default, environment: testEnvironment)
|
|
|
|
let expectedMissingWordChips = [
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.unassigned(word: "pizza")
|
|
]
|
|
|
|
let expectedValidationWords = [
|
|
ValidationWord(groupIndex: 0, word: "salute"),
|
|
ValidationWord(groupIndex: 1, word: "boil"),
|
|
ValidationWord(groupIndex: 2, word: "cancel")
|
|
]
|
|
|
|
store.send(.move(wordChip: PhraseChip.Kind.unassigned(word: "cancel"), intoGroup: 2)) {
|
|
$0.missingWordChips = expectedMissingWordChips
|
|
$0.validationWords = expectedValidationWords
|
|
|
|
XCTAssertFalse($0.isComplete)
|
|
}
|
|
}
|
|
|
|
func testWhenInIncompleteWith3CompletionsAndAChipIsDroppedInGroup3NextStateIsComplete() {
|
|
let words = [
|
|
"bring", "salute", "thank",
|
|
"require", "spirit", "toe",
|
|
// second chunk
|
|
"boil", "hill", "casino",
|
|
"trophy", "drink", "frown",
|
|
// third chunk
|
|
"bird", "grit", "close",
|
|
"morning", "bind", "cancel",
|
|
// Fourth chunk
|
|
"daughter", "salon", "quit",
|
|
"pizza", "just", "garlic"
|
|
]
|
|
|
|
let missingIndices = [1, 0, 5, 3]
|
|
|
|
let phrase = RecoveryPhrase(words: words)
|
|
|
|
let currentStep = RecoveryPhraseValidationState(
|
|
phrase: phrase,
|
|
missingIndices: missingIndices,
|
|
missingWordChips: [
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.unassigned(word: "pizza")
|
|
],
|
|
validationWords: [
|
|
ValidationWord(groupIndex: 0, word: "salute"),
|
|
ValidationWord(groupIndex: 1, word: "boil"),
|
|
ValidationWord(groupIndex: 2, word: "cancel")
|
|
]
|
|
)
|
|
|
|
let store = TestStore(initialState: currentStep, reducer: RecoveryPhraseValidationReducer.default, environment: testEnvironment)
|
|
|
|
let expectedMissingWordChips = [
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty
|
|
]
|
|
|
|
let expectedValidationWords = [
|
|
ValidationWord(groupIndex: 0, word: "salute"),
|
|
ValidationWord(groupIndex: 1, word: "boil"),
|
|
ValidationWord(groupIndex: 2, word: "cancel"),
|
|
ValidationWord(groupIndex: 3, word: "pizza")
|
|
]
|
|
|
|
store.send(.move(wordChip: PhraseChip.Kind.unassigned(word: "pizza"), intoGroup: 3)) {
|
|
$0.missingWordChips = expectedMissingWordChips
|
|
$0.validationWords = expectedValidationWords
|
|
|
|
XCTAssertTrue($0.isComplete)
|
|
XCTAssertTrue($0.isValid)
|
|
}
|
|
|
|
Self.testScheduler.advance(by: 2)
|
|
|
|
store.receive(.succeed) {
|
|
XCTAssertTrue($0.isComplete)
|
|
$0.route = .success
|
|
}
|
|
}
|
|
|
|
func testWhenInIncompleteWith3CompletionsAndAChipIsDroppedInGroup3NextStateIsFailure() {
|
|
let words = [
|
|
"bring", "salute", "thank",
|
|
"require", "spirit", "toe",
|
|
// second chunk
|
|
"boil", "hill", "casino",
|
|
"trophy", "drink", "frown",
|
|
// third chunk
|
|
"bird", "grit", "close",
|
|
"morning", "bind", "cancel",
|
|
// Fourth chunk
|
|
"daughter", "salon", "quit",
|
|
"pizza", "just", "garlic"
|
|
]
|
|
|
|
let missingIndices = [1, 0, 5, 3]
|
|
|
|
let phrase = RecoveryPhrase(words: words)
|
|
|
|
let currentStep = RecoveryPhraseValidationState(
|
|
phrase: phrase,
|
|
missingIndices: missingIndices,
|
|
missingWordChips: [
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.unassigned(word: "pizza")
|
|
],
|
|
validationWords: [
|
|
ValidationWord(groupIndex: 0, word: "salute"),
|
|
ValidationWord(groupIndex: 2, word: "boil"),
|
|
ValidationWord(groupIndex: 1, word: "cancel")
|
|
]
|
|
)
|
|
|
|
let store = TestStore(initialState: currentStep, reducer: RecoveryPhraseValidationReducer.default, environment: testEnvironment)
|
|
|
|
let expectedMissingWordChips = [
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty
|
|
]
|
|
|
|
let expectedValidationWords = [
|
|
ValidationWord(groupIndex: 0, word: "salute"),
|
|
ValidationWord(groupIndex: 2, word: "boil"),
|
|
ValidationWord(groupIndex: 1, word: "cancel"),
|
|
ValidationWord(groupIndex: 3, word: "pizza")
|
|
]
|
|
|
|
store.send(.move(wordChip: PhraseChip.Kind.unassigned(word: "pizza"), intoGroup: 3)) {
|
|
$0.missingWordChips = expectedMissingWordChips
|
|
$0.validationWords = expectedValidationWords
|
|
|
|
XCTAssertTrue($0.isComplete)
|
|
}
|
|
|
|
Self.testScheduler.advance(by: 2)
|
|
|
|
store.receive(.fail) {
|
|
$0.route = .failure
|
|
XCTAssertFalse($0.isValid)
|
|
}
|
|
}
|
|
|
|
func testWhenAWordGroupDoesNotHaveACompletionItHasAnEmptyChipInTheGivenMissingIndex() {
|
|
let words = [
|
|
"bring", "salute", "thank",
|
|
"require", "spirit", "toe",
|
|
// second chunk
|
|
"boil", "hill", "casino",
|
|
"trophy", "drink", "frown",
|
|
// third chunk
|
|
"bird", "grit", "close",
|
|
"morning", "bind", "cancel",
|
|
// Fourth chunk
|
|
"daughter", "salon", "quit",
|
|
"pizza", "just", "garlic"
|
|
]
|
|
|
|
let missingIndices = [1, 0, 5, 3]
|
|
|
|
let phrase = RecoveryPhrase(words: words)
|
|
|
|
let currentStep = RecoveryPhraseValidationState(
|
|
phrase: phrase,
|
|
missingIndices: missingIndices,
|
|
missingWordChips: [
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.unassigned(word: "pizza")
|
|
],
|
|
validationWords: [
|
|
ValidationWord(groupIndex: 1, word: "boil"),
|
|
ValidationWord(groupIndex: 2, word: "cancel")
|
|
]
|
|
)
|
|
|
|
let result = currentStep.wordsChips(
|
|
for: 0,
|
|
groupSize: 6,
|
|
from: phrase.toGroups()[0]
|
|
)
|
|
|
|
let expected = [
|
|
PhraseChip.Kind.ordered(position: 1, word: "bring"),
|
|
.empty,
|
|
.ordered(position: 3, word: "thank"),
|
|
.ordered(position: 4, word: "require"),
|
|
.ordered(position: 5, word: "spirit"),
|
|
.ordered(position: 6, word: "toe")
|
|
]
|
|
|
|
XCTAssertEqual(expected, result)
|
|
}
|
|
|
|
func testWhenAWordGroupHasACompletionItHasABlueChipWithTheCompletedWordInTheGivenMissingIndex() {
|
|
let words = [
|
|
"bring", "salute", "thank",
|
|
"require", "spirit", "toe",
|
|
// second chunk
|
|
"boil", "hill", "casino",
|
|
"trophy", "drink", "frown",
|
|
// third chunk
|
|
"bird", "grit", "close",
|
|
"morning", "bind", "cancel",
|
|
// Fourth chunk
|
|
"daughter", "salon", "quit",
|
|
"pizza", "just", "garlic"
|
|
]
|
|
|
|
let missingIndices = [1, 0, 5, 3]
|
|
|
|
let phrase = RecoveryPhrase(words: words)
|
|
|
|
let currentStep = RecoveryPhraseValidationState(
|
|
phrase: phrase,
|
|
missingIndices: missingIndices,
|
|
missingWordChips: [
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.unassigned(word: "pizza")
|
|
],
|
|
validationWords: [
|
|
ValidationWord(groupIndex: 0, word: "salute"),
|
|
ValidationWord(groupIndex: 1, word: "boil"),
|
|
ValidationWord(groupIndex: 2, word: "cancel")
|
|
]
|
|
)
|
|
|
|
let result = currentStep.wordsChips(
|
|
for: 0,
|
|
groupSize: 6,
|
|
from: phrase.toGroups()[0]
|
|
)
|
|
|
|
let expected = [
|
|
PhraseChip.Kind.ordered(position: 1, word: "bring"),
|
|
.unassigned(word: "salute"),
|
|
.ordered(position: 3, word: "thank"),
|
|
.ordered(position: 4, word: "require"),
|
|
.ordered(position: 5, word: "spirit"),
|
|
.ordered(position: 6, word: "toe")
|
|
]
|
|
|
|
XCTAssertEqual(expected, result)
|
|
}
|
|
|
|
func testWhenRecoveryPhraseValidationStateIsNotCompleteResultingPhraseIsNil() {
|
|
let words = [
|
|
"bring", "salute", "thank",
|
|
"require", "spirit", "toe",
|
|
// second chunk
|
|
"boil", "hill", "casino",
|
|
"trophy", "drink", "frown",
|
|
// third chunk
|
|
"bird", "grit", "close",
|
|
"morning", "bind", "cancel",
|
|
// Fourth chunk
|
|
"daughter", "salon", "quit",
|
|
"pizza", "just", "garlic"
|
|
]
|
|
|
|
let missingIndices = [1, 0, 5, 3]
|
|
|
|
let phrase = RecoveryPhrase(words: words)
|
|
|
|
let currentStep = RecoveryPhraseValidationState(
|
|
phrase: phrase,
|
|
missingIndices: missingIndices,
|
|
missingWordChips: [
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.unassigned(word: "pizza")
|
|
],
|
|
validationWords: [
|
|
ValidationWord(groupIndex: 0, word: "salute"),
|
|
ValidationWord(groupIndex: 1, word: "boil"),
|
|
ValidationWord(groupIndex: 2, word: "cancel")
|
|
]
|
|
)
|
|
|
|
XCTAssertNil(currentStep.resultingPhrase)
|
|
}
|
|
|
|
func testRecoveryPhraseValidationStateIsNotCompleteAndNotValidWhenNotCompleted() {
|
|
let words = [
|
|
"bring", "salute", "thank",
|
|
"require", "spirit", "toe",
|
|
// second chunk
|
|
"boil", "hill", "casino",
|
|
"trophy", "drink", "frown",
|
|
// third chunk
|
|
"bird", "grit", "close",
|
|
"morning", "bind", "cancel",
|
|
// Fourth chunk
|
|
"daughter", "salon", "quit",
|
|
"pizza", "just", "garlic"
|
|
]
|
|
|
|
let missingIndices = [1, 0, 5, 3]
|
|
|
|
let phrase = RecoveryPhrase(words: words)
|
|
|
|
let currentStep = RecoveryPhraseValidationState(
|
|
phrase: phrase,
|
|
missingIndices: missingIndices,
|
|
missingWordChips: [
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.empty,
|
|
PhraseChip.Kind.unassigned(word: "pizza")
|
|
],
|
|
validationWords: [
|
|
ValidationWord(groupIndex: 0, word: "salute"),
|
|
ValidationWord(groupIndex: 1, word: "boil"),
|
|
ValidationWord(groupIndex: 2, word: "cancel")
|
|
]
|
|
)
|
|
|
|
XCTAssertFalse(currentStep.isComplete)
|
|
XCTAssertFalse(currentStep.isValid)
|
|
}
|
|
|
|
func testCreateResultPhraseFromCompletion() {
|
|
let words = [
|
|
"bring", "salute", "thank",
|
|
"require", "spirit", "toe",
|
|
// second chunk
|
|
"boil", "hill", "casino",
|
|
"trophy", "drink", "frown",
|
|
// third chunk
|
|
"bird", "grit", "close",
|
|
"morning", "bind", "cancel",
|
|
// Fourth chunk
|
|
"daughter", "salon", "quit",
|
|
"pizza", "just", "garlic"
|
|
]
|
|
|
|
let missingIndices = [1, 0, 5, 3]
|
|
|
|
let phrase = RecoveryPhrase(words: words)
|
|
|
|
let completion = [
|
|
ValidationWord(groupIndex: 0, word: "salute"),
|
|
ValidationWord(groupIndex: 1, word: "boil"),
|
|
ValidationWord(groupIndex: 2, word: "cancel"),
|
|
ValidationWord(groupIndex: 3, word: "pizza")
|
|
]
|
|
|
|
let result = RecoveryPhraseValidationState(
|
|
phrase: phrase,
|
|
missingIndices: missingIndices,
|
|
missingWordChips: phrase.words(fromMissingIndices: missingIndices),
|
|
validationWords: completion,
|
|
route: nil
|
|
)
|
|
|
|
XCTAssertTrue(result.isValid)
|
|
XCTAssertTrue(result.isComplete)
|
|
XCTAssertEqual(words, result.resultingPhrase)
|
|
}
|
|
|
|
func testCreateResultPhraseInvalidPhraseFromCompletion() {
|
|
let words = [
|
|
"bring", "salute", "thank",
|
|
"require", "spirit", "toe",
|
|
// second chunk
|
|
"boil", "hill", "casino",
|
|
"trophy", "drink", "frown",
|
|
// third chunk
|
|
"bird", "grit", "close",
|
|
"morning", "bind", "cancel",
|
|
// Fourth chunk
|
|
"daughter", "salon", "quit",
|
|
"pizza", "just", "garlic"
|
|
]
|
|
|
|
let missingIndices = [1, 0, 5, 3]
|
|
|
|
let phrase = RecoveryPhrase(words: words)
|
|
|
|
let completion = [
|
|
ValidationWord(groupIndex: 3, word: "salute"),
|
|
ValidationWord(groupIndex: 1, word: "boil"),
|
|
ValidationWord(groupIndex: 0, word: "cancel"),
|
|
ValidationWord(groupIndex: 2, word: "pizza")
|
|
]
|
|
|
|
let result = RecoveryPhraseValidationState(
|
|
phrase: phrase,
|
|
missingIndices: missingIndices,
|
|
missingWordChips: phrase.words(fromMissingIndices: missingIndices),
|
|
validationWords: completion,
|
|
route: nil
|
|
)
|
|
|
|
XCTAssertFalse(result.isValid)
|
|
XCTAssertTrue(result.isComplete)
|
|
XCTAssertNotEqual(words, result.resultingPhrase)
|
|
}
|
|
}
|
|
|
|
extension RecoveryPhraseValidationState {
|
|
static func initial(
|
|
phrase: RecoveryPhrase,
|
|
missingIndices: [Int],
|
|
missingWordsChips: [PhraseChip.Kind]
|
|
) -> Self {
|
|
RecoveryPhraseValidationState(
|
|
phrase: phrase,
|
|
missingIndices: missingIndices,
|
|
missingWordChips: missingWordsChips,
|
|
validationWords: []
|
|
)
|
|
}
|
|
}
|