Skip to content

Commit

Permalink
Add tests for user permissions interactor and push token repo
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexey Naumov committed Apr 26, 2020
1 parent 82044c2 commit 79c6771
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 7 deletions.
8 changes: 8 additions & 0 deletions CountriesSwiftUI.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
F695DF972455F4CB00A65A04 /* PushNotificationsHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F695DF962455F4CB00A65A04 /* PushNotificationsHandlerTests.swift */; };
F695DF992456111300A65A04 /* DeepLinksHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F695DF982456111300A65A04 /* DeepLinksHandlerTests.swift */; };
F6B6212423B52AE600CD00C7 /* ViewInspector in Frameworks */ = {isa = PBXBuildFile; productRef = F6B6212323B52AE600CD00C7 /* ViewInspector */; };
F6B8832124561C5E00EA4067 /* PushTokenWebRepositoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6B8832024561C5E00EA4067 /* PushTokenWebRepositoryTests.swift */; };
F6B8832324561DDB00EA4067 /* UserPermissionsInteractorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6B8832224561DDB00EA4067 /* UserPermissionsInteractorTests.swift */; };
F6BDB91623636865003E69F2 /* DetailRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6BDB91523636865003E69F2 /* DetailRow.swift */; };
F6BDB91823637C5F003E69F2 /* ActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6BDB91723637C5F003E69F2 /* ActivityIndicatorView.swift */; };
F6BDB91A236382E7003E69F2 /* SVGImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6BDB919236382E7003E69F2 /* SVGImageView.swift */; };
Expand Down Expand Up @@ -177,6 +179,8 @@
F695DF942455F2BB00A65A04 /* SceneDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegateTests.swift; sourceTree = "<group>"; };
F695DF962455F4CB00A65A04 /* PushNotificationsHandlerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushNotificationsHandlerTests.swift; sourceTree = "<group>"; };
F695DF982456111300A65A04 /* DeepLinksHandlerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinksHandlerTests.swift; sourceTree = "<group>"; };
F6B8832024561C5E00EA4067 /* PushTokenWebRepositoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushTokenWebRepositoryTests.swift; sourceTree = "<group>"; };
F6B8832224561DDB00EA4067 /* UserPermissionsInteractorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPermissionsInteractorTests.swift; sourceTree = "<group>"; };
F6BDB91523636865003E69F2 /* DetailRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailRow.swift; sourceTree = "<group>"; };
F6BDB91723637C5F003E69F2 /* ActivityIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorView.swift; sourceTree = "<group>"; };
F6BDB919236382E7003E69F2 /* SVGImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SVGImageView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -216,6 +220,7 @@
F6F003AE236A290E00AAC7C6 /* WebRepositoryTests.swift */,
F661F2BB237757040014E142 /* ImageWebRepositoryTests.swift */,
F60829752369D58A00DB292E /* CountriesWebRepositoryTests.swift */,
F6B8832024561C5E00EA4067 /* PushTokenWebRepositoryTests.swift */,
F67D1271244C7AA2006A8CC4 /* CountriesDBRepositoryTests.swift */,
);
path = Repositories;
Expand Down Expand Up @@ -480,6 +485,7 @@
children = (
F6F003B5236B036800AAC7C6 /* CountriesInteractorTests.swift */,
F661F2C4237772CE0014E142 /* ImagesInteractorTests.swift */,
F6B8832224561DDB00EA4067 /* UserPermissionsInteractorTests.swift */,
);
path = Interactors;
sourceTree = "<group>";
Expand Down Expand Up @@ -675,6 +681,7 @@
F60829712369CE0100DB292E /* RequestMocking.swift in Sources */,
F67D1274244CA019006A8CC4 /* MockedPersistentStore.swift in Sources */,
F67451F5243A4CC200A4B498 /* RootViewAppearanceTests.swift in Sources */,
F6B8832124561C5E00EA4067 /* PushTokenWebRepositoryTests.swift in Sources */,
F661F2C5237772CE0014E142 /* ImagesInteractorTests.swift in Sources */,
F6F003B3236AF9F100AAC7C6 /* LoadableTests.swift in Sources */,
F695DF992456111300A65A04 /* DeepLinksHandlerTests.swift in Sources */,
Expand Down Expand Up @@ -702,6 +709,7 @@
F67B3B22244C5B8700DA7FA6 /* CoreDataStackTests.swift in Sources */,
F661F2CA23777D440014E142 /* SVGImageViewTests.swift in Sources */,
F6F606A823CF25EC00F36F5D /* SearchBarTests.swift in Sources */,
F6B8832324561DDB00EA4067 /* UserPermissionsInteractorTests.swift in Sources */,
F695DF952455F2BB00A65A04 /* SceneDelegateTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
1 change: 1 addition & 0 deletions UnitTests/Interactors/CountriesInteractorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ final class LoadCountryDetailsTests: CountriesInteractorTests {

func test_stubInteractor() {
let sut = StubCountriesInteractor()
sut.refreshCountriesList().sinkToResult({ _ in }).store(in: &subscriptions)
let countries = BindingWithPublisher(value: Loadable<LazyList<Country>>.notRequested)
sut.load(countries: countries.binding, search: "", locale: .backendDefault)
let details = BindingWithPublisher(value: Loadable<Country.Details>.notRequested)
Expand Down
109 changes: 109 additions & 0 deletions UnitTests/Interactors/UserPermissionsInteractorTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
//
// UserPermissionsInteractorTests.swift
// UnitTests
//
// Created by Alexey Naumov on 26.04.2020.
// Copyright © 2020 Alexey Naumov. All rights reserved.
//

import XCTest
import Combine
@testable import CountriesSwiftUI

class UserPermissionsInteractorTests: XCTestCase {

var state = Store<AppState>(AppState())
var sut: RealUserPermissionsInteractor!

override func setUp() {
state.bulkUpdate { $0 = AppState() }
}

func delay(_ closure: @escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: closure)
}

func test_noSideEffectOnInit() {
let exp = XCTestExpectation(description: #function)
sut = RealUserPermissionsInteractor(appState: state) {
XCTFail()
}
delay {
XCTAssertEqual(self.state.value, AppState())
exp.fulfill()
}
wait(for: [exp], timeout: 0.3)
}

// MARK: - Push

func test_pushFirstResolveStatus() {
XCTAssertEqual(AppState().permissions.push, .unknown)
let exp = XCTestExpectation(description: #function)
sut = RealUserPermissionsInteractor(appState: state) {
XCTFail()
}
sut.resolveStatus(for: .pushNotifications)
delay {
XCTAssertNotEqual(self.state.value.permissions.push, .unknown)
exp.fulfill()
}
wait(for: [exp], timeout: 0.3)
}

func test_pushSecondResolveStatus() {
XCTAssertEqual(AppState().permissions.push, .unknown)
let exp = XCTestExpectation(description: #function)
sut = RealUserPermissionsInteractor(appState: state) {
XCTFail()
}
sut.resolveStatus(for: .pushNotifications)
delay {
self.sut.resolveStatus(for: .pushNotifications)
XCTAssertNotEqual(self.state.value.permissions.push, .unknown)
exp.fulfill()
}
wait(for: [exp], timeout: 0.3)
}

func test_pushRequestPermissionNotDetermined() {
state[\.permissions.push] = .notRequested
let exp = XCTestExpectation(description: #function)
sut = RealUserPermissionsInteractor(appState: state) {
XCTFail()
}
sut.request(permission: .pushNotifications)
delay {
XCTAssertNotEqual(self.state.value.permissions.push, .unknown)
exp.fulfill()
}
wait(for: [exp], timeout: 0.3)
}

func test_pushRequestPermissionDenied() {
state[\.permissions.push] = .denied
let exp = XCTestExpectation(description: #function)
sut = RealUserPermissionsInteractor(appState: state) {
XCTAssertEqual(self.state.value.permissions.push, .denied)
exp.fulfill()
}
sut.request(permission: .pushNotifications)
wait(for: [exp], timeout: 0.3)
}

func test_authorizationStatusMapping() {
XCTAssertEqual(UNAuthorizationStatus.notDetermined.map, .notRequested)
XCTAssertEqual(UNAuthorizationStatus.provisional.map, .notRequested)
XCTAssertEqual(UNAuthorizationStatus.denied.map, .denied)
XCTAssertEqual(UNAuthorizationStatus.authorized.map, .granted)
XCTAssertEqual(UNAuthorizationStatus(rawValue: 10)?.map, .notRequested)
}

// MARK: - Stub

func test_stubUserPermissionsInteractor() {
let sut = StubUserPermissionsInteractor()
sut.request(permission: .pushNotifications)
sut.resolveStatus(for: .pushNotifications)
}
}
3 changes: 1 addition & 2 deletions UnitTests/Mocks/MockedWebRepositories.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,13 @@ final class MockedPushTokenWebRepository: TestWebRepository, Mock, PushTokenWebR
case register(Data)
}
var actions = MockActions<Action>(expected: [])
var registerTokenResponse: Result<Void, Error> = .failure(MockError.valueNotSet)

init(expected: [Action]) {
self.actions = .init(expected: expected)
}

func register(devicePushToken: Data) -> AnyPublisher<Void, Error> {
register(.register(devicePushToken))
return registerTokenResponse.publish()
return Just<Void>.withErrorType(Error.self)
}
}
37 changes: 37 additions & 0 deletions UnitTests/Repositories/PushTokenWebRepositoryTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// PushTokenWebRepositoryTests.swift
// UnitTests
//
// Created by Alexey Naumov on 26.04.2020.
// Copyright © 2020 Alexey Naumov. All rights reserved.
//

import XCTest
import Combine
@testable import CountriesSwiftUI

class PushTokenWebRepositoryTests: XCTestCase {

private var sut: RealPushTokenWebRepository!
private var cancelBag = CancelBag()

override func setUp() {
sut = RealPushTokenWebRepository(session: .mockedResponsesOnly,
baseURL: "https://test.com")
}

override func tearDown() {
cancelBag = CancelBag()
}

func test_register() {
let exp = XCTestExpectation(description: #function)
sut.register(devicePushToken: Data())
.sinkToResult { result in
result.assertSuccess()
exp.fulfill()
}
.store(in: cancelBag)
wait(for: [exp], timeout: 0.1)
}
}
8 changes: 5 additions & 3 deletions UnitTests/System/PushNotificationsHandlerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,20 @@ import UserNotifications
@testable import CountriesSwiftUI

class PushNotificationsHandlerTests: XCTestCase {

var sut: RealPushNotificationsHandler!

func test_isCenterDelegate() {
let mockedHandler = MockedDeepLinksHandler(expected: [])
let sut = RealPushNotificationsHandler(deepLinksHandler: mockedHandler)
sut = RealPushNotificationsHandler(deepLinksHandler: mockedHandler)
let center = UNUserNotificationCenter.current()
XCTAssertTrue(center.delegate === sut)
mockedHandler.verify()
}

func test_emptyPayload() {
let mockedHandler = MockedDeepLinksHandler(expected: [])
let sut = RealPushNotificationsHandler(deepLinksHandler: mockedHandler)
sut = RealPushNotificationsHandler(deepLinksHandler: mockedHandler)
let exp = XCTestExpectation(description: #function)
sut.handleNotification(userInfo: [:]) {
mockedHandler.verify()
Expand All @@ -35,7 +37,7 @@ class PushNotificationsHandlerTests: XCTestCase {
let mockedHandler = MockedDeepLinksHandler(expected: [
.open(.showCountryFlag(alpha3Code: "USA"))
])
let sut = RealPushNotificationsHandler(deepLinksHandler: mockedHandler)
sut = RealPushNotificationsHandler(deepLinksHandler: mockedHandler)
let exp = XCTestExpectation(description: #function)
let userInfo: [String: Any] = [
"aps": ["country": "USA"]
Expand Down
19 changes: 17 additions & 2 deletions UnitTests/System/SystemEventsHandlerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,22 @@ final class SystemEventsHandlerTests: XCTestCase {
pushNotificationsHandler: pushNotificationsHandler,
pushTokenWebRepository: pushTokenWebRepository)
}

func test_noSideEffectOnInit() {
setupSut()
sut.container.appState[\.permissions.push] = .denied
let reference = sut.container.appState.value
verify(appState: reference)
}

func test_subscribesOnPushIfGranted() {
setupSut(permissions: [
.request(.pushNotifications)
])
sut.container.appState[\.permissions.push] = .granted
let reference = sut.container.appState.value
verify(appState: reference)
}

func test_didBecomeActive() {
setupSut(permissions: [
Expand Down Expand Up @@ -123,11 +139,10 @@ final class SystemEventsHandlerTests: XCTestCase {
verify()
}

func test_silentRemoteNotification() {
func test_silentRemoteNotificationSuccess() {
setupSut(countries: [
.refreshCountriesList
])
pushTokenWebRepository?.registerTokenResponse = .success(())
let exp = XCTestExpectation(description: #function)
sut.appDidReceiveRemoteNotification(payload: [:]) { result in
XCTAssertEqual(result, .newData)
Expand Down

0 comments on commit 79c6771

Please sign in to comment.