Skip to content

Commit

Permalink
Write ViewModel unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
graeme committed Dec 22, 2022
1 parent d4e3f45 commit f463f60
Show file tree
Hide file tree
Showing 2 changed files with 195 additions and 0 deletions.
12 changes: 12 additions & 0 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,7 @@
EE339228291BDEFD009F62C1 /* JSAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE339227291BDEFD009F62C1 /* JSAlertController.swift */; };
EEC111E4294D06020086524F /* JSAlert.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EEC111E3294D06020086524F /* JSAlert.storyboard */; };
EEC111E6294D06290086524F /* JSAlertViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC111E5294D06290086524F /* JSAlertViewModel.swift */; };
EEF53E182950CED5002D78F4 /* JSAlertViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF53E172950CED5002D78F4 /* JSAlertViewModelTests.swift */; };
F41D174125CB131900472416 /* NSColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41D174025CB131900472416 /* NSColorExtension.swift */; };
F44C130225C2DA0400426E3E /* NSAppearanceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F44C130125C2DA0400426E3E /* NSAppearanceExtension.swift */; };
F4A6198C283CFFBB007F2080 /* ContentScopeFeatureFlagging.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4A6198B283CFFBB007F2080 /* ContentScopeFeatureFlagging.swift */; };
Expand Down Expand Up @@ -1751,6 +1752,7 @@
EE339227291BDEFD009F62C1 /* JSAlertController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSAlertController.swift; sourceTree = "<group>"; };
EEC111E3294D06020086524F /* JSAlert.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = JSAlert.storyboard; sourceTree = "<group>"; };
EEC111E5294D06290086524F /* JSAlertViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSAlertViewModel.swift; sourceTree = "<group>"; };
EEF53E172950CED5002D78F4 /* JSAlertViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSAlertViewModelTests.swift; sourceTree = "<group>"; };
F41D174025CB131900472416 /* NSColorExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSColorExtension.swift; sourceTree = "<group>"; };
F44C130125C2DA0400426E3E /* NSAppearanceExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSAppearanceExtension.swift; sourceTree = "<group>"; };
F4A6198B283CFFBB007F2080 /* ContentScopeFeatureFlagging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentScopeFeatureFlagging.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3192,6 +3194,7 @@
B68172AC269EB415006D1092 /* Geolocation */,
AAEC74AE2642C47300C2EFBC /* History */,
4BF6961B28BE90E800D402D4 /* Home Page */,
EEF53E162950CEB6002D78F4 /* JSAlert */,
378205F9283C275E00D1D4AA /* Menus */,
AA91F83627076ED100771A0D /* Navigation Bar */,
85F487B3276A8F1B003CE668 /* Onboarding */,
Expand Down Expand Up @@ -4454,6 +4457,14 @@
path = JSAlert;
sourceTree = "<group>";
};
EEF53E162950CEB6002D78F4 /* JSAlert */ = {
isa = PBXGroup;
children = (
EEF53E172950CED5002D78F4 /* JSAlertViewModelTests.swift */,
);
path = JSAlert;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -5533,6 +5544,7 @@
37CD54B527F1AC1300F1F7B9 /* PreferencesSidebarModelTests.swift in Sources */,
AAEC74B22642C57200C2EFBC /* HistoryCoordinatingMock.swift in Sources */,
37CD54B927F1F8AC00F1F7B9 /* AppearancePreferencesTests.swift in Sources */,
EEF53E182950CED5002D78F4 /* JSAlertViewModelTests.swift in Sources */,
376C4DB928A1A48A00CC0F5B /* FirePopoverViewModelTests.swift in Sources */,
AAEC74B62642CC6A00C2EFBC /* HistoryStoringMock.swift in Sources */,
AA652CB125DD825B009059CC /* LocalBookmarkStoreTests.swift in Sources */,
Expand Down
183 changes: 183 additions & 0 deletions Unit Tests/JSAlert/JSAlertViewModelTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
//
// JSAlertViewModelTests.swift
//
// Copyright © 2022 DuckDuckGo. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import XCTest
@testable import DuckDuckGo_Privacy_Browser

final class JSAlertViewModelTests: XCTestCase {

func testIsCancelButtonHidden() {
let params: [JSAlertQuery.TestParameters] = [
.init(type: .testAlert(), result: true),
.init(type: .testConfirm(), result: false),
.init(type: .testTextInput(), result: false)
]
for param in params {
let viewModel = JSAlertViewModel(query: param.type)
XCTAssertEqual(viewModel.isCancelButtonHidden, param.result, "Expected isCancelButtonHidden for \(param.type) to equal \(param.result)")
}
}

func testIsTextFieldHidden() {
let params: [JSAlertQuery.TestParameters] = [
.init(type: .testAlert(), result: true),
.init(type: .testConfirm(), result: true),
.init(type: .testTextInput(), result: false)
]

for param in params {
let viewModel = JSAlertViewModel(query: param.type)
XCTAssertEqual(viewModel.isTextFieldHidden, param.result, "Expected isTextFieldHidden for \(param.type) to equal \(param.result)")
}
}

func testTitleText() {
let params: [JSAlertQuery.TestParameters] = [
.init(type: .testAlert(parameters: .testData(domain: "duckduckgo.com")), result: "A message from duckduckgo.com"),
.init(type: .testConfirm(parameters: .testData(domain: "wikipedia.com")), result: "A message from wikipedia.com"),
.init(type: .testTextInput(parameters: .testData(domain: "example.com")), result: "A message from example.com")
]

for param in params {
let viewModel = JSAlertViewModel(query: param.type)
XCTAssertEqual(viewModel.titleText, param.result, "Expected messageText for \(param.type) to equal \(param.result)")
}
}

func testMessageText() {
let params: [JSAlertQuery.TestParameters] = [
.init(type: .testAlert(parameters: .testData(prompt: "This is a prompt")), result: "This is a prompt"),
.init(type: .testConfirm(parameters: .testData(prompt: "This is another prompt")), result: "This is another prompt"),
.init(type: .testTextInput(parameters: .testData(prompt: "Yet another prompt")), result: "Yet another prompt")
]

for param in params {
let viewModel = JSAlertViewModel(query: param.type)
XCTAssertEqual(viewModel.messageText, param.result, "Expected messageText for \(param.type) to equal \(param.result)")
}
}

func testTextFieldDefaultText() {
let params: [JSAlertQuery.TestParameters] = [
.init(type: .testAlert(parameters: .testData(defaultInputText: "")), result: ""),
.init(type: .testConfirm(parameters: .testData(defaultInputText: nil)), result: ""),
.init(type: .testTextInput(parameters: .testData(defaultInputText: "Input text")), result: "Input text")
]

for param in params {
let viewModel = JSAlertViewModel(query: param.type)
XCTAssertEqual(viewModel.textFieldDefaultText, param.result, "Expected textFieldDefaultText for \(param.type) to equal \(param.result)")
}
}

func testConfirmAlertDialog() {
var wasCalled = false
let query = JSAlertQuery.testAlert { _ in
wasCalled = true
}
let viewModel = JSAlertViewModel(query: query)
viewModel.confirm(text: "")
XCTAssert(wasCalled, "Expected completion to be called")
}

func testConfirmConfirmDialog() {
var didConfirm = false
let anotherQuery = JSAlertQuery.testConfirm { result in
didConfirm = (try? result.get()) ?? false
}
let anotherViewModel = JSAlertViewModel(query: anotherQuery)
anotherViewModel.confirm(text: "")
XCTAssert(didConfirm, "Expected didConfirm value to be true")
}

func testConfirmTextInputDialog() {
var text: String? = ""
let anotherQuery = JSAlertQuery.testTextInput { result in
text = try? result.get()
}
let anotherViewModel = JSAlertViewModel(query: anotherQuery)

let expectedText = "expected"
anotherViewModel.confirm(text: expectedText)

XCTAssertEqual(text, expectedText, "Expected text value to be \(expectedText)")
}

func testCancelAlertDialog() {
var wasCalled = false
let query = JSAlertQuery.testAlert { _ in
wasCalled = true
}
let viewModel = JSAlertViewModel(query: query)
viewModel.cancel()
XCTAssert(wasCalled, "Expected completion to be called")
}

func testCancelConfirmDialog() {
var didConfirm: Bool?
let anotherQuery = JSAlertQuery.testConfirm { result in
switch result {
case .success(let completionResult): didConfirm = completionResult
case .failure: break
}
}
let anotherViewModel = JSAlertViewModel(query: anotherQuery)
anotherViewModel.cancel()

XCTAssertEqual(didConfirm, false)
}

func testCancelTextInputDialog() {
var text: String? = ""
let anotherQuery = JSAlertQuery.testTextInput { result in
switch result {
case .success(let string): text = string
case .failure: break
}
}
let anotherViewModel = JSAlertViewModel(query: anotherQuery)
anotherViewModel.cancel()

XCTAssertNil(text)
}
}

fileprivate extension JSAlertParameters {
static func testData(domain: String = "", prompt: String = "", defaultInputText: String? = nil) -> Self {
JSAlertParameters(domain: domain, prompt: prompt, defaultInputText: defaultInputText)
}
}

fileprivate extension JSAlertQuery {
struct TestParameters<Result> {
let type: JSAlertQuery
let result: Result
}

static func testAlert(parameters: JSAlertParameters = .testData(), callback: @escaping AlertDialogRequest.Callback = { _ in }) -> Self {
.alert(AlertDialogRequest(parameters, callback: callback))
}

static func testConfirm(parameters: JSAlertParameters = .testData(), callback: @escaping ConfirmDialogRequest.Callback = { _ in }) -> Self {
.confirm(ConfirmDialogRequest(parameters, callback: callback))
}

static func testTextInput(parameters: JSAlertParameters = .testData(), callback: @escaping TextInputDialogRequest.Callback = { _ in }) -> Self {
.textInput(TextInputDialogRequest(parameters, callback: callback))
}
}

0 comments on commit f463f60

Please sign in to comment.