mirror of
https://github.com/bitwarden/ios.git
synced 2025-12-10 15:57:30 -06:00
[PM-26060] Create LanguageStateService in BWK (#2148)
This commit is contained in:
parent
26c158b2e5
commit
b5e7033d54
@ -62,6 +62,9 @@ public class ServiceContainer: Services {
|
||||
/// The service used to import items.
|
||||
let importItemsService: ImportItemsService
|
||||
|
||||
/// The state service that handles language state.
|
||||
public let languageStateService: LanguageStateService
|
||||
|
||||
/// The service used to perform app data migrations.
|
||||
let migrationService: MigrationService
|
||||
|
||||
@ -105,6 +108,7 @@ public class ServiceContainer: Services {
|
||||
/// - exportItemsService: The service to export items.
|
||||
/// - flightRecorder: The service used by the application for recording temporary debug logs.
|
||||
/// - importItemsService: The service to import items.
|
||||
/// - languageStateService: The service for handling language state.
|
||||
/// - migrationService: The service to do data migrations
|
||||
/// - notificationCenterService: The service used to receive foreground and background notifications.
|
||||
/// - pasteboardService: The service used by the application for sharing data with other apps.
|
||||
@ -129,6 +133,7 @@ public class ServiceContainer: Services {
|
||||
exportItemsService: ExportItemsService,
|
||||
flightRecorder: FlightRecorder,
|
||||
importItemsService: ImportItemsService,
|
||||
languageStateService: LanguageStateService,
|
||||
migrationService: MigrationService,
|
||||
notificationCenterService: NotificationCenterService,
|
||||
pasteboardService: PasteboardService,
|
||||
@ -152,6 +157,7 @@ public class ServiceContainer: Services {
|
||||
self.exportItemsService = exportItemsService
|
||||
self.flightRecorder = flightRecorder
|
||||
self.importItemsService = importItemsService
|
||||
self.languageStateService = languageStateService
|
||||
self.migrationService = migrationService
|
||||
self.notificationCenterService = notificationCenterService
|
||||
self.pasteboardService = pasteboardService
|
||||
@ -336,6 +342,7 @@ public class ServiceContainer: Services {
|
||||
exportItemsService: exportItemsService,
|
||||
flightRecorder: flightRecorder,
|
||||
importItemsService: importItemsService,
|
||||
languageStateService: stateService,
|
||||
migrationService: migrationService,
|
||||
notificationCenterService: notificationCenterService,
|
||||
pasteboardService: pasteboardService,
|
||||
|
||||
@ -15,6 +15,7 @@ typealias Services = HasAppInfoService
|
||||
& HasExportItemsService
|
||||
& HasFlightRecorder
|
||||
& HasImportItemsService
|
||||
& HasLanguageStateService
|
||||
& HasNotificationCenterService
|
||||
& HasPasteboardService
|
||||
& HasStateService
|
||||
|
||||
@ -154,7 +154,7 @@ enum StateServiceError: Error {
|
||||
|
||||
/// A default implementation of `StateService`.
|
||||
///
|
||||
actor DefaultStateService: StateService, ActiveAccountStateProvider, ConfigStateService, FlightRecorderStateService {
|
||||
actor DefaultStateService: StateService, ActiveAccountStateProvider, ConfigStateService, FlightRecorderStateService, LanguageStateService {
|
||||
// MARK: Properties
|
||||
|
||||
/// The language option currently selected for the app.
|
||||
|
||||
@ -22,6 +22,7 @@ extension ServiceContainer {
|
||||
exportItemsService: ExportItemsService = MockExportItemsService(),
|
||||
flightRecorder: FlightRecorder = MockFlightRecorder(),
|
||||
importItemsService: ImportItemsService = MockImportItemsService(),
|
||||
languageStateService: LanguageStateService = MockLanguageStateService(),
|
||||
migrationService: MigrationService = MockMigrationService(),
|
||||
notificationCenterService: NotificationCenterService = MockNotificationCenterService(),
|
||||
pasteboardService: PasteboardService = MockPasteboardService(),
|
||||
@ -46,6 +47,7 @@ extension ServiceContainer {
|
||||
exportItemsService: exportItemsService,
|
||||
flightRecorder: flightRecorder,
|
||||
importItemsService: importItemsService,
|
||||
languageStateService: languageStateService,
|
||||
migrationService: migrationService,
|
||||
notificationCenterService: notificationCenterService,
|
||||
pasteboardService: pasteboardService,
|
||||
|
||||
@ -15,7 +15,7 @@ protocol SelectLanguageDelegate: AnyObject {
|
||||
final class SelectLanguageProcessor: StateProcessor<SelectLanguageState, SelectLanguageAction, Void> {
|
||||
// MARK: Types
|
||||
|
||||
typealias Services = HasStateService
|
||||
typealias Services = HasLanguageStateService
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
@ -71,7 +71,7 @@ final class SelectLanguageProcessor: StateProcessor<SelectLanguageState, SelectL
|
||||
|
||||
// Save the value.
|
||||
state.currentLanguage = languageOption
|
||||
services.stateService.appLanguage = languageOption
|
||||
services.languageStateService.appLanguage = languageOption
|
||||
delegate?.languageSelected(languageOption)
|
||||
|
||||
// Show the confirmation alert and close the view after the user clicks ok.
|
||||
|
||||
@ -11,7 +11,7 @@ class SelectLanguageProcessorTests: BitwardenTestCase {
|
||||
|
||||
var coordinator: MockCoordinator<SettingsRoute, SettingsEvent>!
|
||||
var delegate: MockSelectLanguageDelegate!
|
||||
var stateService: MockStateService!
|
||||
var languageStateService: MockLanguageStateService!
|
||||
var subject: SelectLanguageProcessor!
|
||||
|
||||
// MARK: Setup & Teardown
|
||||
@ -21,9 +21,9 @@ class SelectLanguageProcessorTests: BitwardenTestCase {
|
||||
|
||||
coordinator = MockCoordinator()
|
||||
delegate = MockSelectLanguageDelegate()
|
||||
stateService = MockStateService()
|
||||
languageStateService = MockLanguageStateService()
|
||||
let services = ServiceContainer.withMocks(
|
||||
stateService: stateService,
|
||||
languageStateService: languageStateService,
|
||||
)
|
||||
|
||||
subject = SelectLanguageProcessor(
|
||||
@ -39,7 +39,7 @@ class SelectLanguageProcessorTests: BitwardenTestCase {
|
||||
|
||||
coordinator = nil
|
||||
delegate = nil
|
||||
stateService = nil
|
||||
languageStateService = nil
|
||||
subject = nil
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ class SelectLanguageProcessorTests: BitwardenTestCase {
|
||||
subject.receive(.languageTapped(.custom(languageCode: "th")))
|
||||
|
||||
XCTAssertEqual(subject.state.currentLanguage, .custom(languageCode: "th"))
|
||||
XCTAssertEqual(stateService.appLanguage, .custom(languageCode: "th"))
|
||||
XCTAssertEqual(languageStateService.appLanguage, .custom(languageCode: "th"))
|
||||
XCTAssertEqual(delegate.selectedLanguage, .custom(languageCode: "th"))
|
||||
XCTAssertEqual(coordinator.alertShown.last, .languageChanged(to: LanguageOption("th").title) {})
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ final class SettingsCoordinator: Coordinator, HasStackNavigator {
|
||||
& HasExportItemsService
|
||||
& HasFlightRecorder
|
||||
& HasImportItemsService
|
||||
& HasLanguageStateService
|
||||
& HasPasteboardService
|
||||
& HasStateService
|
||||
& HasTimeProvider
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
/// A protocol for a State Service that handles language state.
|
||||
public protocol LanguageStateService: AnyObject { // sourcery: AutoMockable
|
||||
/// The language option currently selected for the app.
|
||||
var appLanguage: LanguageOption { get set }
|
||||
}
|
||||
@ -35,6 +35,13 @@ public protocol HasFlightRecorder {
|
||||
var flightRecorder: FlightRecorder { get }
|
||||
}
|
||||
|
||||
/// Protocol for an object that provides a `LanguageStateService`.
|
||||
///
|
||||
public protocol HasLanguageStateService {
|
||||
/// The service used by the application to manage language state.
|
||||
var languageStateService: LanguageStateService { get }
|
||||
}
|
||||
|
||||
/// Protocol for an object that provides a `TimeProvider`.
|
||||
///
|
||||
public protocol HasTimeProvider {
|
||||
|
||||
@ -112,6 +112,9 @@ public class ServiceContainer: Services { // swiftlint:disable:this type_body_le
|
||||
/// The repository used to manage keychain items.
|
||||
let keychainRepository: KeychainRepository
|
||||
|
||||
/// The state service that handles language state.
|
||||
public let languageStateService: LanguageStateService
|
||||
|
||||
/// The service used by the application to evaluate local auth policies.
|
||||
let localAuthService: LocalAuthService
|
||||
|
||||
@ -233,6 +236,7 @@ public class ServiceContainer: Services { // swiftlint:disable:this type_body_le
|
||||
/// in Credential Exhange flow.
|
||||
/// - keychainRepository: The repository used to manages keychain items.
|
||||
/// - keychainService: The service used to access & store data on the device keychain.
|
||||
/// - languageStateService: The service for handling language state.
|
||||
/// - localAuthService: The service used by the application to evaluate local auth policies.
|
||||
/// - migrationService: The serviced used to perform app data migrations.
|
||||
/// - nfcReaderService: The service used by the application to read NFC tags.
|
||||
@ -291,6 +295,7 @@ public class ServiceContainer: Services { // swiftlint:disable:this type_body_le
|
||||
importCiphersRepository: ImportCiphersRepository,
|
||||
keychainRepository: KeychainRepository,
|
||||
keychainService: KeychainService,
|
||||
languageStateService: LanguageStateService,
|
||||
localAuthService: LocalAuthService,
|
||||
migrationService: MigrationService,
|
||||
nfcReaderService: NFCReaderService,
|
||||
@ -348,6 +353,7 @@ public class ServiceContainer: Services { // swiftlint:disable:this type_body_le
|
||||
self.importCiphersRepository = importCiphersRepository
|
||||
self.keychainService = keychainService
|
||||
self.keychainRepository = keychainRepository
|
||||
self.languageStateService = languageStateService
|
||||
self.localAuthService = localAuthService
|
||||
self.migrationService = migrationService
|
||||
self.nfcReaderService = nfcReaderService
|
||||
@ -936,6 +942,7 @@ public class ServiceContainer: Services { // swiftlint:disable:this type_body_le
|
||||
importCiphersRepository: importCiphersRepository,
|
||||
keychainRepository: keychainRepository,
|
||||
keychainService: keychainService,
|
||||
languageStateService: stateService,
|
||||
localAuthService: localAuthService,
|
||||
migrationService: migrationService,
|
||||
nfcReaderService: nfcReaderService ?? NoopNFCReaderService(),
|
||||
|
||||
@ -32,6 +32,7 @@ typealias Services = HasAPIService
|
||||
& HasFlightRecorder
|
||||
& HasGeneratorRepository
|
||||
& HasImportCiphersRepository
|
||||
& HasLanguageStateService
|
||||
& HasLocalAuthService
|
||||
& HasNFCReaderService
|
||||
& HasNotificationCenterService
|
||||
|
||||
@ -1437,7 +1437,7 @@ enum StateServiceError: LocalizedError {
|
||||
|
||||
/// A default implementation of `StateService`.
|
||||
///
|
||||
actor DefaultStateService: StateService, ActiveAccountStateProvider, ConfigStateService, FlightRecorderStateService { // swiftlint:disable:this type_body_length line_length
|
||||
actor DefaultStateService: StateService, ActiveAccountStateProvider, ConfigStateService, FlightRecorderStateService, LanguageStateService { // swiftlint:disable:this type_body_length line_length
|
||||
// MARK: Properties
|
||||
|
||||
/// The language option currently selected for the app.
|
||||
|
||||
@ -39,6 +39,7 @@ extension ServiceContainer {
|
||||
httpClient: HTTPClient = MockHTTPClient(),
|
||||
keychainRepository: KeychainRepository = MockKeychainRepository(),
|
||||
keychainService: KeychainService = MockKeychainService(),
|
||||
languageStateService: LanguageStateService = MockLanguageStateService(),
|
||||
localAuthService: LocalAuthService = MockLocalAuthService(),
|
||||
migrationService: MigrationService = MockMigrationService(),
|
||||
nfcReaderService: NFCReaderService = MockNFCReaderService(),
|
||||
@ -100,6 +101,7 @@ extension ServiceContainer {
|
||||
importCiphersRepository: importCiphersRepository,
|
||||
keychainRepository: keychainRepository,
|
||||
keychainService: keychainService,
|
||||
languageStateService: languageStateService,
|
||||
localAuthService: localAuthService,
|
||||
migrationService: migrationService,
|
||||
nfcReaderService: nfcReaderService,
|
||||
|
||||
@ -16,7 +16,7 @@ protocol SelectLanguageDelegate: AnyObject {
|
||||
final class SelectLanguageProcessor: StateProcessor<SelectLanguageState, SelectLanguageAction, Void> {
|
||||
// MARK: Types
|
||||
|
||||
typealias Services = HasStateService
|
||||
typealias Services = HasLanguageStateService
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
@ -72,7 +72,7 @@ final class SelectLanguageProcessor: StateProcessor<SelectLanguageState, SelectL
|
||||
|
||||
// Save the value.
|
||||
state.currentLanguage = languageOption
|
||||
services.stateService.appLanguage = languageOption
|
||||
services.languageStateService.appLanguage = languageOption
|
||||
delegate?.languageSelected(languageOption)
|
||||
|
||||
// Show the confirmation alert and close the view after the user clicks ok.
|
||||
|
||||
@ -11,7 +11,7 @@ class SelectLanguageProcessorTests: BitwardenTestCase {
|
||||
|
||||
var coordinator: MockCoordinator<SettingsRoute, SettingsEvent>!
|
||||
var delegate: MockSelectLanguageDelegate!
|
||||
var stateService: MockStateService!
|
||||
var languageStateService: MockLanguageStateService!
|
||||
var subject: SelectLanguageProcessor!
|
||||
|
||||
// MARK: Setup & Teardown
|
||||
@ -21,9 +21,9 @@ class SelectLanguageProcessorTests: BitwardenTestCase {
|
||||
|
||||
coordinator = MockCoordinator()
|
||||
delegate = MockSelectLanguageDelegate()
|
||||
stateService = MockStateService()
|
||||
languageStateService = MockLanguageStateService()
|
||||
let services = ServiceContainer.withMocks(
|
||||
stateService: stateService,
|
||||
languageStateService: languageStateService,
|
||||
)
|
||||
|
||||
subject = SelectLanguageProcessor(
|
||||
@ -39,7 +39,7 @@ class SelectLanguageProcessorTests: BitwardenTestCase {
|
||||
|
||||
coordinator = nil
|
||||
delegate = nil
|
||||
stateService = nil
|
||||
languageStateService = nil
|
||||
subject = nil
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ class SelectLanguageProcessorTests: BitwardenTestCase {
|
||||
subject.receive(.languageTapped(.custom(languageCode: "th")))
|
||||
|
||||
XCTAssertEqual(subject.state.currentLanguage, .custom(languageCode: "th"))
|
||||
XCTAssertEqual(stateService.appLanguage, .custom(languageCode: "th"))
|
||||
XCTAssertEqual(languageStateService.appLanguage, .custom(languageCode: "th"))
|
||||
XCTAssertEqual(delegate.selectedLanguage, .custom(languageCode: "th"))
|
||||
XCTAssertEqual(coordinator.alertShown.last, .languageChanged(to: LanguageOption("th").title) {})
|
||||
|
||||
|
||||
@ -75,6 +75,7 @@ final class SettingsCoordinator: Coordinator, HasStackNavigator { // swiftlint:d
|
||||
& HasExportCXFCiphersRepository
|
||||
& HasExportVaultService
|
||||
& HasFlightRecorder
|
||||
& HasLanguageStateService
|
||||
& HasNotificationCenterService
|
||||
& HasPasteboardService
|
||||
& HasPolicyService
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user