[PM-26060] Consolidate Router to BitwardenKit (#2112)

This commit is contained in:
Katherine Bertelsen 2025-11-07 08:02:41 -06:00 committed by GitHub
parent 73fc2d84b8
commit 5e39f4ffbe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 45 additions and 135 deletions

View File

@ -1,43 +0,0 @@
import XCTest
@testable import AuthenticatorShared
// MARK: - AnyRouterTests
class AnyRouterTests: BitwardenTestCase {
// MARK: Properties
var router: MockRouter<AuthEvent, AuthRoute>!
var subject: AnyRouter<AuthEvent, AuthRoute>!
// MARK: Setup & Teardown
override func setUp() {
super.setUp()
router = MockRouter(routeForEvent: { _ in .vaultUnlock })
subject = router.asAnyRouter()
}
override func tearDown() {
super.tearDown()
router = nil
subject = nil
}
// MARK: Tests
/// `handleAndRoute()` calls the `handleAndRoute()` method on the wrapped router.
@MainActor
func test_handleAndRoute() async {
var didStart = false
router.routeForEvent = { event in
guard case .didStart = event else { return .vaultUnlock }
didStart = true
return .complete
}
let route = await subject.handleAndRoute(.didStart)
XCTAssertEqual(router.events, [.didStart])
XCTAssertEqual(route, .complete)
XCTAssertTrue(didStart)
}
}

View File

@ -1,14 +1,25 @@
import BitwardenKit
import BitwardenKitMocks
import XCTest
@testable import BitwardenShared
// MARK: - AnyRouterTests
class AnyRouterTests: BitwardenTestCase {
// MARK: Types
enum TestEvent: Equatable {
case didStart
}
enum TestRoute: Equatable {
case complete
case landing
}
// MARK: Properties
var router: MockRouter<AuthEvent, AuthRoute>!
var subject: AnyRouter<AuthEvent, AuthRoute>!
var router: MockRouter<TestEvent, TestRoute>!
var subject: AnyRouter<TestEvent, TestRoute>!
// MARK: Setup & Teardown

View File

@ -0,0 +1,26 @@
import BitwardenKit
import XCTest
/// A mock implementation of `Router` for testing purposes.
///
/// This mock records all events passed to `handleAndRoute(_:)` and returns
/// routes based on the provided closure.
public class MockRouter<Event, Route>: Router {
/// The events that have been handled by this router.
public var events = [Event]()
/// A closure that maps events to routes.
public var routeForEvent: (Event) -> Route
/// Initialize a mock router with a route mapping closure.
///
/// - Parameter routeForEvent: A closure that determines which route to return for a given event.
public init(routeForEvent: @escaping (Event) -> Route) {
self.routeForEvent = routeForEvent
}
public func handleAndRoute(_ event: Event) async -> Route {
events.append(event)
return routeForEvent(event)
}
}

View File

@ -1,3 +1,5 @@
import BitwardenKit
// MARK: AuthRouterRedirects
extension AuthRouter {

View File

@ -1,39 +0,0 @@
// MARK: - AnyRouter
/// A type erased wrapper for a router.
///
open class AnyRouter<Event, Route>: Router {
// MARK: Properties
/// A closure that wraps the `handleAndRoute()` method.
private let doHandleAndRoute: (Event) async -> Route
// MARK: Initialization
/// Initializes an `AnyRouter`.
///
/// - Parameter router: The router to wrap.
///
public init<R: Router>(_ router: R) where R.Route == Route, R.Event == Event {
doHandleAndRoute = { event in
await router.handleAndRoute(event)
}
}
// MARK: Router
open func handleAndRoute(_ event: Event) async -> Route {
await doHandleAndRoute(event)
}
}
// MARK: - Router Extensions
public extension Router {
/// Wraps this router in an instance of `AnyRouter`.
///
/// - Returns: An `AnyRouter` instance wrapping this router.
func asAnyRouter() -> AnyRouter<Event, Route> {
AnyRouter(self)
}
}

View File

@ -1,15 +0,0 @@
// MARK: - Router
/// A protocol for an object that configures state for a given event and outputs a redirected route.
@MainActor
public protocol Router<Event, Route>: AnyObject {
associatedtype Event
associatedtype Route
/// Prepare the coordinator for a given route and redirect if needed.
///
/// - Parameter route: The route for which the coordinator should prepare itself.
/// - Returns: A redirected route for which the Coordinator is prepared.
///
func handleAndRoute(_ event: Event) async -> Route
}

View File

@ -1,5 +1,6 @@
@testable import AuthenticatorShared
import BitwardenKit
import BitwardenKitMocks
// MARK: - MockAppModule

View File

@ -1,17 +0,0 @@
import XCTest
@testable import AuthenticatorShared
class MockRouter<Event, Route>: Router {
var events = [Event]()
var routeForEvent: (Event) -> Route
init(routeForEvent: @escaping (Event) -> Route) {
self.routeForEvent = routeForEvent
}
func handleAndRoute(_ event: Event) async -> Route {
events.append(event)
return routeForEvent(event)
}
}

View File

@ -1,4 +1,5 @@
import BitwardenKit
import BitwardenKitMocks
import UIKit
@testable import BitwardenShared

View File

@ -1,17 +0,0 @@
import XCTest
@testable import BitwardenShared
class MockRouter<Event, Route>: Router {
var events = [Event]()
var routeForEvent: (Event) -> Route
init(routeForEvent: @escaping (Event) -> Route) {
self.routeForEvent = routeForEvent
}
func handleAndRoute(_ event: Event) async -> Route {
events.append(event)
return routeForEvent(event)
}
}