Cleanup
This commit is contained in:
parent
b0d0792014
commit
83bce93225
|
@ -5,7 +5,7 @@ import Combine
|
||||||
import Foundation
|
import Foundation
|
||||||
import HTTP
|
import HTTP
|
||||||
|
|
||||||
public struct InstanceFilterService {
|
public struct InstanceURLService {
|
||||||
private let httpClient: HTTPClient
|
private let httpClient: HTTPClient
|
||||||
private var userDefaultsClient: UserDefaultsClient
|
private var userDefaultsClient: UserDefaultsClient
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ public struct InstanceFilterService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension InstanceFilterService {
|
public extension InstanceURLService {
|
||||||
func isFiltered(url: URL) -> Bool {
|
func isFiltered(url: URL) -> Bool {
|
||||||
guard let host = url.host else { return true }
|
guard let host = url.host else { return true }
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ private struct UpdatedFilterTarget: DecodableTarget {
|
||||||
let headers: HTTPHeaders? = nil
|
let headers: HTTPHeaders? = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension InstanceFilterService {
|
private extension InstanceURLService {
|
||||||
var filter: BloomFilter<String> {
|
var filter: BloomFilter<String> {
|
||||||
userDefaultsClient.updatedInstanceFilter ?? Self.defaultFilter
|
userDefaultsClient.updatedInstanceFilter ?? Self.defaultFilter
|
||||||
}
|
}
|
|
@ -8,9 +8,9 @@ import CombineExpectations
|
||||||
import Stubbing
|
import Stubbing
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
class InstanceFilterServiceTests: XCTestCase {
|
class InstanceURLServiceTests: XCTestCase {
|
||||||
func testFiltering() throws {
|
func testFiltering() throws {
|
||||||
let sut = InstanceFilterService(environment: .mock())
|
let sut = InstanceURLService(environment: .mock())
|
||||||
let unfilteredInstanceURL = URL(string: "https://unfiltered.instance")!
|
let unfilteredInstanceURL = URL(string: "https://unfiltered.instance")!
|
||||||
let filteredInstanceURL = URL(string: "https://filtered.instance")!
|
let filteredInstanceURL = URL(string: "https://filtered.instance")!
|
||||||
let subdomainFilteredInstanceURL = URL(string: "https://subdomain.filtered.instance")!
|
let subdomainFilteredInstanceURL = URL(string: "https://subdomain.filtered.instance")!
|
||||||
|
@ -22,7 +22,7 @@ class InstanceFilterServiceTests: XCTestCase {
|
||||||
|
|
||||||
func testUpdating() throws {
|
func testUpdating() throws {
|
||||||
let environment = AppEnvironment.mock()
|
let environment = AppEnvironment.mock()
|
||||||
var sut = InstanceFilterService(environment: environment)
|
var sut = InstanceURLService(environment: environment)
|
||||||
let previouslyFilteredInstanceURL = URL(string: "https://filtered.instance")!
|
let previouslyFilteredInstanceURL = URL(string: "https://filtered.instance")!
|
||||||
let newlyFilteredInstanceURL = URL(string: "https://instance.filtered")!
|
let newlyFilteredInstanceURL = URL(string: "https://instance.filtered")!
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ class InstanceFilterServiceTests: XCTestCase {
|
||||||
XCTAssertFalse(sut.isFiltered(url: previouslyFilteredInstanceURL))
|
XCTAssertFalse(sut.isFiltered(url: previouslyFilteredInstanceURL))
|
||||||
XCTAssertTrue(sut.isFiltered(url: newlyFilteredInstanceURL))
|
XCTAssertTrue(sut.isFiltered(url: newlyFilteredInstanceURL))
|
||||||
|
|
||||||
sut = InstanceFilterService(environment: environment)
|
sut = InstanceURLService(environment: environment)
|
||||||
|
|
||||||
XCTAssertFalse(sut.isFiltered(url: previouslyFilteredInstanceURL))
|
XCTAssertFalse(sut.isFiltered(url: previouslyFilteredInstanceURL))
|
||||||
XCTAssertTrue(sut.isFiltered(url: newlyFilteredInstanceURL))
|
XCTAssertTrue(sut.isFiltered(url: newlyFilteredInstanceURL))
|
|
@ -15,13 +15,13 @@ public final class AddIdentityViewModel: ObservableObject {
|
||||||
public let addedIdentityID: AnyPublisher<UUID, Never>
|
public let addedIdentityID: AnyPublisher<UUID, Never>
|
||||||
|
|
||||||
private let allIdentitiesService: AllIdentitiesService
|
private let allIdentitiesService: AllIdentitiesService
|
||||||
private let instanceFilterService: InstanceFilterService
|
private let instanceURLService: InstanceURLService
|
||||||
private let addedIdentityIDSubject = PassthroughSubject<UUID, Never>()
|
private let addedIdentityIDSubject = PassthroughSubject<UUID, Never>()
|
||||||
private var cancellables = Set<AnyCancellable>()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
init(allIdentitiesService: AllIdentitiesService, instanceFilterService: InstanceFilterService) {
|
init(allIdentitiesService: AllIdentitiesService, instanceURLService: InstanceURLService) {
|
||||||
self.allIdentitiesService = allIdentitiesService
|
self.allIdentitiesService = allIdentitiesService
|
||||||
self.instanceFilterService = instanceFilterService
|
self.instanceURLService = instanceURLService
|
||||||
addedIdentityID = addedIdentityIDSubject.eraseToAnyPublisher()
|
addedIdentityID = addedIdentityIDSubject.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ public extension AddIdentityViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
func refreshFilter() {
|
func refreshFilter() {
|
||||||
instanceFilterService.updateFilter()
|
instanceURLService.updateFilter()
|
||||||
.sink { _ in }
|
.sink { _ in }
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
@ -46,21 +46,26 @@ private extension AddIdentityViewModel {
|
||||||
private static let filteredURL = URL(string: "https://filtered")!
|
private static let filteredURL = URL(string: "https://filtered")!
|
||||||
private static let HTTPSPrefix = "https://"
|
private static let HTTPSPrefix = "https://"
|
||||||
|
|
||||||
|
static func url(fieldText: String) -> URL? {
|
||||||
|
if fieldText.hasPrefix(HTTPSPrefix), let prefixedURL = URL(string: fieldText) {
|
||||||
|
return prefixedURL
|
||||||
|
} else if let unprefixedURL = URL(string: HTTPSPrefix + fieldText) {
|
||||||
|
return unprefixedURL
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func addIdentity(authenticated: Bool) {
|
func addIdentity(authenticated: Bool) {
|
||||||
let identityID = UUID()
|
let identityID = UUID()
|
||||||
let url: URL
|
|
||||||
|
|
||||||
if urlFieldText.hasPrefix(Self.HTTPSPrefix), let prefixedURL = URL(string: urlFieldText) {
|
guard let url = Self.url(fieldText: urlFieldText) else {
|
||||||
url = prefixedURL
|
|
||||||
} else if let unprefixedURL = URL(string: Self.HTTPSPrefix + urlFieldText) {
|
|
||||||
url = unprefixedURL
|
|
||||||
} else {
|
|
||||||
alertItem = AlertItem(error: AddIdentityError.unableToConnectToInstance)
|
alertItem = AlertItem(error: AddIdentityError.unableToConnectToInstance)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if instanceFilterService.isFiltered(url: url) {
|
if instanceURLService.isFiltered(url: url) {
|
||||||
loading = true
|
loading = true
|
||||||
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + .random(in: 0.01...0.1)) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + .random(in: 0.01...0.1)) {
|
||||||
|
|
|
@ -51,7 +51,7 @@ public extension RootViewModel {
|
||||||
func addIdentityViewModel() -> AddIdentityViewModel {
|
func addIdentityViewModel() -> AddIdentityViewModel {
|
||||||
AddIdentityViewModel(
|
AddIdentityViewModel(
|
||||||
allIdentitiesService: allIdentitiesService,
|
allIdentitiesService: allIdentitiesService,
|
||||||
instanceFilterService: InstanceFilterService(environment: environment))
|
instanceURLService: InstanceURLService(environment: environment))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ class AddIdentityViewModelTests: XCTestCase {
|
||||||
let environment = AppEnvironment.mock()
|
let environment = AppEnvironment.mock()
|
||||||
let sut = AddIdentityViewModel(
|
let sut = AddIdentityViewModel(
|
||||||
allIdentitiesService: try AllIdentitiesService(environment: environment),
|
allIdentitiesService: try AllIdentitiesService(environment: environment),
|
||||||
instanceFilterService: InstanceFilterService(environment: environment))
|
instanceURLService: InstanceURLService(environment: environment))
|
||||||
let addedIDRecorder = sut.addedIdentityID.record()
|
let addedIDRecorder = sut.addedIdentityID.record()
|
||||||
|
|
||||||
sut.urlFieldText = "https://mastodon.social"
|
sut.urlFieldText = "https://mastodon.social"
|
||||||
|
@ -28,7 +28,7 @@ class AddIdentityViewModelTests: XCTestCase {
|
||||||
let environment = AppEnvironment.mock()
|
let environment = AppEnvironment.mock()
|
||||||
let sut = AddIdentityViewModel(
|
let sut = AddIdentityViewModel(
|
||||||
allIdentitiesService: try AllIdentitiesService(environment: environment),
|
allIdentitiesService: try AllIdentitiesService(environment: environment),
|
||||||
instanceFilterService: InstanceFilterService(environment: environment))
|
instanceURLService: InstanceURLService(environment: environment))
|
||||||
let addedIDRecorder = sut.addedIdentityID.record()
|
let addedIDRecorder = sut.addedIdentityID.record()
|
||||||
|
|
||||||
sut.urlFieldText = "mastodon.social"
|
sut.urlFieldText = "mastodon.social"
|
||||||
|
@ -41,7 +41,7 @@ class AddIdentityViewModelTests: XCTestCase {
|
||||||
let environment = AppEnvironment.mock()
|
let environment = AppEnvironment.mock()
|
||||||
let sut = AddIdentityViewModel(
|
let sut = AddIdentityViewModel(
|
||||||
allIdentitiesService: try AllIdentitiesService(environment: environment),
|
allIdentitiesService: try AllIdentitiesService(environment: environment),
|
||||||
instanceFilterService: InstanceFilterService(environment: environment))
|
instanceURLService: InstanceURLService(environment: environment))
|
||||||
let recorder = sut.$alertItem.record()
|
let recorder = sut.$alertItem.record()
|
||||||
|
|
||||||
XCTAssertNil(try wait(for: recorder.next(), timeout: 1))
|
XCTAssertNil(try wait(for: recorder.next(), timeout: 1))
|
||||||
|
@ -51,14 +51,14 @@ class AddIdentityViewModelTests: XCTestCase {
|
||||||
|
|
||||||
let alertItem = try wait(for: recorder.next(), timeout: 1)
|
let alertItem = try wait(for: recorder.next(), timeout: 1)
|
||||||
|
|
||||||
XCTAssertEqual((alertItem?.error as? URLError)?.code, URLError.badURL)
|
XCTAssertEqual((alertItem?.error as? AddIdentityError), AddIdentityError.unableToConnectToInstance)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDoesNotAlertCanceledLogin() throws {
|
func testDoesNotAlertCanceledLogin() throws {
|
||||||
let environment = AppEnvironment.mock(webAuthSessionType: CanceledLoginMockWebAuthSession.self)
|
let environment = AppEnvironment.mock(webAuthSessionType: CanceledLoginMockWebAuthSession.self)
|
||||||
let sut = AddIdentityViewModel(
|
let sut = AddIdentityViewModel(
|
||||||
allIdentitiesService: try AllIdentitiesService(environment: environment),
|
allIdentitiesService: try AllIdentitiesService(environment: environment),
|
||||||
instanceFilterService: InstanceFilterService(environment: environment))
|
instanceURLService: InstanceURLService(environment: environment))
|
||||||
let recorder = sut.$alertItem.record()
|
let recorder = sut.$alertItem.record()
|
||||||
|
|
||||||
XCTAssertNil(try wait(for: recorder.next(), timeout: 1))
|
XCTAssertNil(try wait(for: recorder.next(), timeout: 1))
|
||||||
|
|
|
@ -14,7 +14,7 @@ class RootViewModelTests: XCTestCase {
|
||||||
let sut = try RootViewModel(
|
let sut = try RootViewModel(
|
||||||
environment: .mock(),
|
environment: .mock(),
|
||||||
registerForRemoteNotifications: { Empty().setFailureType(to: Error.self).eraseToAnyPublisher() })
|
registerForRemoteNotifications: { Empty().setFailureType(to: Error.self).eraseToAnyPublisher() })
|
||||||
let recorder = sut.$identification.record()
|
let recorder = sut.$navigationViewModel.record()
|
||||||
|
|
||||||
XCTAssertNil(try wait(for: recorder.next(), timeout: 1))
|
XCTAssertNil(try wait(for: recorder.next(), timeout: 1))
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@ class RootViewModelTests: XCTestCase {
|
||||||
addIdentityViewModel.urlFieldText = "https://mastodon.social"
|
addIdentityViewModel.urlFieldText = "https://mastodon.social"
|
||||||
addIdentityViewModel.logInTapped()
|
addIdentityViewModel.logInTapped()
|
||||||
|
|
||||||
let mainNavigationViewModel = try wait(for: recorder.next(), timeout: 1)!
|
let navigationViewModel = try wait(for: recorder.next(), timeout: 1)!
|
||||||
|
|
||||||
XCTAssertNotNil(mainNavigationViewModel)
|
XCTAssertNotNil(navigationViewModel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue