From 98b4d7b67281bd9d7cbebbf7e0652d6389f60eff Mon Sep 17 00:00:00 2001 From: Jaclyn Chen Date: Fri, 4 Jul 2025 11:59:09 -0400 Subject: [PATCH 1/5] Fetch storage system plugin by plugin file path instead of plugin name that is more likely to change. --- .../Yosemite/Tools/Plugins/PluginsService.swift | 17 +++++++++++------ .../Tools/Plugins/PluginsServiceTests.swift | 14 ++++++++++---- .../Settings/POS/POSTabEligibilityChecker.swift | 3 ++- .../POS/POSTabEligibilityCheckerTests.swift | 4 ++-- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/Modules/Sources/Yosemite/Tools/Plugins/PluginsService.swift b/Modules/Sources/Yosemite/Tools/Plugins/PluginsService.swift index e5ecbd5a649..2025f286417 100644 --- a/Modules/Sources/Yosemite/Tools/Plugins/PluginsService.swift +++ b/Modules/Sources/Yosemite/Tools/Plugins/PluginsService.swift @@ -5,7 +5,12 @@ import protocol Storage.StorageManagerType /// A service for system plugins. public protocol PluginsServiceProtocol { /// Waits for a specific plugin to be available in storage. - func waitForPluginInStorage(siteID: Int64, pluginName: String, isActive: Bool) async -> SystemPlugin + /// - Parameters: + /// - siteID: The site ID to search for the plugin. + /// - plugin: The plugin's file path (e.g., "woocommerce/woocommerce.php" for WooCommerce). + /// - isActive: Whether to wait for the plugin to be active or inactive. + /// - Returns: The SystemPlugin when found in storage. + func waitForPluginInStorage(siteID: Int64, plugin: String, isActive: Bool) async -> SystemPlugin } public class PluginsService: PluginsServiceProtocol { @@ -16,20 +21,20 @@ public class PluginsService: PluginsServiceProtocol { } @MainActor - public func waitForPluginInStorage(siteID: Int64, pluginName: String, isActive: Bool) async -> SystemPlugin { - let predicate = \StorageSystemPlugin.siteID == siteID && \StorageSystemPlugin.name == pluginName && \StorageSystemPlugin.active == isActive - let nameDescriptor = NSSortDescriptor(keyPath: \StorageSystemPlugin.name, ascending: true) + public func waitForPluginInStorage(siteID: Int64, plugin: String, isActive: Bool) async -> SystemPlugin { + let predicate = \StorageSystemPlugin.siteID == siteID && \StorageSystemPlugin.plugin == plugin && \StorageSystemPlugin.active == isActive + let pluginDescriptor = NSSortDescriptor(keyPath: \StorageSystemPlugin.plugin, ascending: true) let resultsController = ResultsController(storageManager: storageManager, matching: predicate, fetchLimit: 1, - sortedBy: [nameDescriptor]) + sortedBy: [pluginDescriptor]) do { try resultsController.performFetch() if let plugin = resultsController.fetchedObjects.first { return plugin } } catch { - DDLogError("Error loading plugin \(pluginName) for site \(siteID) initially: \(error.localizedDescription)") + DDLogError("Error loading plugin \(plugin) for site \(siteID) initially: \(error.localizedDescription)") } return await withCheckedContinuation { continuation in diff --git a/Modules/Tests/YosemiteTests/Tools/Plugins/PluginsServiceTests.swift b/Modules/Tests/YosemiteTests/Tools/Plugins/PluginsServiceTests.swift index 50f3d800caa..8fbaf127b03 100644 --- a/Modules/Tests/YosemiteTests/Tools/Plugins/PluginsServiceTests.swift +++ b/Modules/Tests/YosemiteTests/Tools/Plugins/PluginsServiceTests.swift @@ -18,11 +18,11 @@ struct PluginsServiceTests { storageManager.insertWCPlugin(siteID: siteID, isActive: true, version: "1.0.0") // When - let result = await sut.waitForPluginInStorage(siteID: siteID, pluginName: PluginConstants.pluginName, isActive: true) + let result = await sut.waitForPluginInStorage(siteID: siteID, plugin: PluginConstants.plugin, isActive: true) // Then #expect(result.siteID == siteID) - #expect(result.name == PluginConstants.pluginName) + #expect(result.plugin == PluginConstants.plugin) #expect(result.active == true) #expect(result.version == "1.0.0") } @@ -33,7 +33,7 @@ struct PluginsServiceTests { await storageManager.reset() // When - async let plugin = sut.waitForPluginInStorage(siteID: siteID, pluginName: PluginConstants.pluginName, isActive: true) + async let plugin = sut.waitForPluginInStorage(siteID: siteID, plugin: PluginConstants.plugin, isActive: true) #expect(storageManager.viewStorage.loadSystemPlugins(siteID: siteID).count == 0) storageManager.insertWCPlugin(siteID: siteID, isActive: true, version: "2.0.0") #expect(storageManager.viewStorage.loadSystemPlugins(siteID: siteID).count == 1) @@ -41,6 +41,7 @@ struct PluginsServiceTests { // Then let result = await plugin #expect(result.siteID == siteID) + #expect(result.plugin == PluginConstants.plugin) #expect(result.name == PluginConstants.pluginName) #expect(result.active == true) #expect(result.version == "2.0.0") @@ -50,7 +51,11 @@ struct PluginsServiceTests { private extension MockStorageManager { func insertWCPlugin(siteID: Int64, isActive: Bool, version: String? = nil) { performAndSave({ storage in - let plugin = SystemPlugin.fake().copy(siteID: siteID, name: PluginConstants.pluginName, version: version, active: isActive) + let plugin = SystemPlugin.fake().copy(siteID: siteID, + plugin: PluginConstants.plugin, + name: PluginConstants.pluginName, + version: version, + active: isActive) let newPlugin = storage.insertNewObject(ofType: StorageSystemPlugin.self) newPlugin.update(with: plugin) }, completion: nil, on: .main) @@ -67,5 +72,6 @@ private extension MockStorageManager { // MARK: - Constants private enum PluginConstants { + static let plugin = "example-plugin/example-plugin.php" static let pluginName = "Example Plugin" } diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift index 653d977aa01..7a328dcac56 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift @@ -195,7 +195,7 @@ private extension POSTabEligibilityChecker { @MainActor func fetchWooCommercePlugin(siteID: Int64) async -> SystemPlugin { - await pluginsService.waitForPluginInStorage(siteID: siteID, pluginName: Constants.wcPluginName, isActive: true) + await pluginsService.waitForPluginInStorage(siteID: siteID, plugin: Constants.wcPlugin, isActive: true) } @MainActor @@ -304,6 +304,7 @@ private extension POSTabEligibilityChecker { private extension POSTabEligibilityChecker { enum Constants { static let wcPluginName = "WooCommerce" + static let wcPlugin = "woocommerce/woocommerce.php" static let wcPluginMinimumVersion = "9.6.0-beta" static let wcPluginMinimumVersionWithFeatureSwitch = "10.0.0" } diff --git a/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/POSTabEligibilityCheckerTests.swift b/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/POSTabEligibilityCheckerTests.swift index 9706b1319b2..a227756f22a 100644 --- a/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/POSTabEligibilityCheckerTests.swift +++ b/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/POSTabEligibilityCheckerTests.swift @@ -595,7 +595,7 @@ private extension POSTabEligibilityCheckerTests { func setupWooCommerceVersion(_ version: String = "9.6.0-beta") { pluginsService.pluginToReturn = .fake().copy( siteID: siteID, - plugin: "WooCommerce", + plugin: "woocommerce/woocommerce.php", version: version, active: true ) @@ -656,7 +656,7 @@ private extension POSTabEligibilityCheckerTests { private final class MockPluginsService: PluginsServiceProtocol { var pluginToReturn: SystemPlugin = .fake() - func waitForPluginInStorage(siteID: Int64, pluginName: String, isActive: Bool) async -> SystemPlugin { + func waitForPluginInStorage(siteID: Int64, plugin: String, isActive: Bool) async -> SystemPlugin { pluginToReturn } } From 26cb6ec2b2a21ecbd840ae60b1a1c60b35df2a31 Mon Sep 17 00:00:00 2001 From: Jaclyn Chen Date: Fri, 4 Jul 2025 16:08:37 -0400 Subject: [PATCH 2/5] Update `pluginsService.waitForPluginInStorage` in legacy eligibility checker. Remove plugin name constants. --- .../Settings/POS/LegacyPOSTabEligibilityChecker.swift | 4 ++-- .../Dashboard/Settings/POS/POSTabEligibilityChecker.swift | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/LegacyPOSTabEligibilityChecker.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/LegacyPOSTabEligibilityChecker.swift index 2d18286a44f..3e490c0d126 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/LegacyPOSTabEligibilityChecker.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/LegacyPOSTabEligibilityChecker.swift @@ -154,7 +154,7 @@ private extension LegacyPOSTabEligibilityChecker { @MainActor func fetchWooCommercePlugin(siteID: Int64) async -> SystemPlugin { - await pluginsService.waitForPluginInStorage(siteID: siteID, pluginName: Constants.wcPluginName, isActive: true) + await pluginsService.waitForPluginInStorage(siteID: siteID, plugin: Constants.wcPlugin, isActive: true) } @MainActor @@ -254,7 +254,7 @@ private extension LegacyPOSTabEligibilityChecker { private extension LegacyPOSTabEligibilityChecker { enum Constants { - static let wcPluginName = "WooCommerce" + static let wcPlugin = "woocommerce/woocommerce.php" static let wcPluginMinimumVersion = "9.6.0-beta" static let wcPluginMinimumVersionWithFeatureSwitch = "10.0.0" } diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift index 072f9278573..8f7a906caaa 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift @@ -279,7 +279,6 @@ private extension POSTabEligibilityChecker { private extension POSTabEligibilityChecker { enum Constants { - static let wcPluginName = "WooCommerce" static let wcPlugin = "woocommerce/woocommerce.php" static let wcPluginMinimumVersion = "9.6.0-beta" static let wcPluginMinimumVersionWithFeatureSwitch = "10.0.0" From 6542f828a262b50ace36242161fb11617e962f94 Mon Sep 17 00:00:00 2001 From: Jaclyn Chen Date: Fri, 4 Jul 2025 16:17:38 -0400 Subject: [PATCH 3/5] Update unit tests for `LegacyPOSTabEligibilityCheckerTests`. --- .../Settings/POS/LegacyPOSTabEligibilityCheckerTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/LegacyPOSTabEligibilityCheckerTests.swift b/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/LegacyPOSTabEligibilityCheckerTests.swift index a5e2d58d586..beebcc24e5c 100644 --- a/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/LegacyPOSTabEligibilityCheckerTests.swift +++ b/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/LegacyPOSTabEligibilityCheckerTests.swift @@ -365,7 +365,7 @@ private extension LegacyPOSTabEligibilityCheckerTests { func setupWooCommerceVersion(_ version: String = "9.6.0-beta") { pluginsService.pluginToReturn = .fake().copy( siteID: siteID, - plugin: "WooCommerce", + plugin: "woocommerce/woocommerce.php", version: version, active: true ) @@ -426,7 +426,7 @@ private extension LegacyPOSTabEligibilityCheckerTests { private final class MockPluginsService: PluginsServiceProtocol { var pluginToReturn: SystemPlugin = .fake() - func waitForPluginInStorage(siteID: Int64, pluginName: String, isActive: Bool) async -> SystemPlugin { + func waitForPluginInStorage(siteID: Int64, plugin: String, isActive: Bool) async -> SystemPlugin { pluginToReturn } } From 5f83b824d005582fba1c9ff8621ed597ab1787d2 Mon Sep 17 00:00:00 2001 From: Jaclyn Chen Date: Thu, 10 Jul 2025 14:37:22 -0400 Subject: [PATCH 4/5] Update comment to match what it does better. --- Modules/Sources/Yosemite/Tools/Plugins/PluginsService.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Sources/Yosemite/Tools/Plugins/PluginsService.swift b/Modules/Sources/Yosemite/Tools/Plugins/PluginsService.swift index 2025f286417..7c90a62bde2 100644 --- a/Modules/Sources/Yosemite/Tools/Plugins/PluginsService.swift +++ b/Modules/Sources/Yosemite/Tools/Plugins/PluginsService.swift @@ -8,7 +8,7 @@ public protocol PluginsServiceProtocol { /// - Parameters: /// - siteID: The site ID to search for the plugin. /// - plugin: The plugin's file path (e.g., "woocommerce/woocommerce.php" for WooCommerce). - /// - isActive: Whether to wait for the plugin to be active or inactive. + /// - isActive: Whether the plugin is active or not. /// - Returns: The SystemPlugin when found in storage. func waitForPluginInStorage(siteID: Int64, plugin: String, isActive: Bool) async -> SystemPlugin } From c6488a1918c4a84f2e08ab9fd859df5e8d89af39 Mon Sep 17 00:00:00 2001 From: Jaclyn Chen Date: Thu, 10 Jul 2025 14:43:09 -0400 Subject: [PATCH 5/5] Rename `plugin` to `pluginPath` parameter in `PluginsServiceProtocol.waitForPluginInStorage` to improve readability. --- .../Yosemite/Tools/Plugins/PluginsService.swift | 10 +++++----- .../Tools/Plugins/PluginsServiceTests.swift | 4 ++-- .../Settings/POS/LegacyPOSTabEligibilityChecker.swift | 2 +- .../Settings/POS/POSTabEligibilityChecker.swift | 2 +- .../POS/LegacyPOSTabEligibilityCheckerTests.swift | 2 +- .../Settings/POS/POSTabEligibilityCheckerTests.swift | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Modules/Sources/Yosemite/Tools/Plugins/PluginsService.swift b/Modules/Sources/Yosemite/Tools/Plugins/PluginsService.swift index 7c90a62bde2..8c8f0f74236 100644 --- a/Modules/Sources/Yosemite/Tools/Plugins/PluginsService.swift +++ b/Modules/Sources/Yosemite/Tools/Plugins/PluginsService.swift @@ -7,10 +7,10 @@ public protocol PluginsServiceProtocol { /// Waits for a specific plugin to be available in storage. /// - Parameters: /// - siteID: The site ID to search for the plugin. - /// - plugin: The plugin's file path (e.g., "woocommerce/woocommerce.php" for WooCommerce). + /// - pluginPath: The plugin's file path (e.g., "woocommerce/woocommerce.php" for WooCommerce). /// - isActive: Whether the plugin is active or not. /// - Returns: The SystemPlugin when found in storage. - func waitForPluginInStorage(siteID: Int64, plugin: String, isActive: Bool) async -> SystemPlugin + func waitForPluginInStorage(siteID: Int64, pluginPath: String, isActive: Bool) async -> SystemPlugin } public class PluginsService: PluginsServiceProtocol { @@ -21,8 +21,8 @@ public class PluginsService: PluginsServiceProtocol { } @MainActor - public func waitForPluginInStorage(siteID: Int64, plugin: String, isActive: Bool) async -> SystemPlugin { - let predicate = \StorageSystemPlugin.siteID == siteID && \StorageSystemPlugin.plugin == plugin && \StorageSystemPlugin.active == isActive + public func waitForPluginInStorage(siteID: Int64, pluginPath: String, isActive: Bool) async -> SystemPlugin { + let predicate = \StorageSystemPlugin.siteID == siteID && \StorageSystemPlugin.plugin == pluginPath && \StorageSystemPlugin.active == isActive let pluginDescriptor = NSSortDescriptor(keyPath: \StorageSystemPlugin.plugin, ascending: true) let resultsController = ResultsController(storageManager: storageManager, matching: predicate, @@ -34,7 +34,7 @@ public class PluginsService: PluginsServiceProtocol { return plugin } } catch { - DDLogError("Error loading plugin \(plugin) for site \(siteID) initially: \(error.localizedDescription)") + DDLogError("Error loading plugin \(pluginPath) for site \(siteID) initially: \(error.localizedDescription)") } return await withCheckedContinuation { continuation in diff --git a/Modules/Tests/YosemiteTests/Tools/Plugins/PluginsServiceTests.swift b/Modules/Tests/YosemiteTests/Tools/Plugins/PluginsServiceTests.swift index 8fbaf127b03..4f277eba69b 100644 --- a/Modules/Tests/YosemiteTests/Tools/Plugins/PluginsServiceTests.swift +++ b/Modules/Tests/YosemiteTests/Tools/Plugins/PluginsServiceTests.swift @@ -18,7 +18,7 @@ struct PluginsServiceTests { storageManager.insertWCPlugin(siteID: siteID, isActive: true, version: "1.0.0") // When - let result = await sut.waitForPluginInStorage(siteID: siteID, plugin: PluginConstants.plugin, isActive: true) + let result = await sut.waitForPluginInStorage(siteID: siteID, pluginPath: PluginConstants.plugin, isActive: true) // Then #expect(result.siteID == siteID) @@ -33,7 +33,7 @@ struct PluginsServiceTests { await storageManager.reset() // When - async let plugin = sut.waitForPluginInStorage(siteID: siteID, plugin: PluginConstants.plugin, isActive: true) + async let plugin = sut.waitForPluginInStorage(siteID: siteID, pluginPath: PluginConstants.plugin, isActive: true) #expect(storageManager.viewStorage.loadSystemPlugins(siteID: siteID).count == 0) storageManager.insertWCPlugin(siteID: siteID, isActive: true, version: "2.0.0") #expect(storageManager.viewStorage.loadSystemPlugins(siteID: siteID).count == 1) diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/LegacyPOSTabEligibilityChecker.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/LegacyPOSTabEligibilityChecker.swift index 3e490c0d126..c0e3976f043 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/LegacyPOSTabEligibilityChecker.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/LegacyPOSTabEligibilityChecker.swift @@ -154,7 +154,7 @@ private extension LegacyPOSTabEligibilityChecker { @MainActor func fetchWooCommercePlugin(siteID: Int64) async -> SystemPlugin { - await pluginsService.waitForPluginInStorage(siteID: siteID, plugin: Constants.wcPlugin, isActive: true) + await pluginsService.waitForPluginInStorage(siteID: siteID, pluginPath: Constants.wcPlugin, isActive: true) } @MainActor diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift index 8f7a906caaa..702da488032 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift @@ -140,7 +140,7 @@ private extension POSTabEligibilityChecker { @MainActor func fetchWooCommercePlugin(siteID: Int64) async -> SystemPlugin { - await pluginsService.waitForPluginInStorage(siteID: siteID, plugin: Constants.wcPlugin, isActive: true) + await pluginsService.waitForPluginInStorage(siteID: siteID, pluginPath: Constants.wcPlugin, isActive: true) } @MainActor diff --git a/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/LegacyPOSTabEligibilityCheckerTests.swift b/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/LegacyPOSTabEligibilityCheckerTests.swift index beebcc24e5c..5968b4f7639 100644 --- a/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/LegacyPOSTabEligibilityCheckerTests.swift +++ b/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/LegacyPOSTabEligibilityCheckerTests.swift @@ -426,7 +426,7 @@ private extension LegacyPOSTabEligibilityCheckerTests { private final class MockPluginsService: PluginsServiceProtocol { var pluginToReturn: SystemPlugin = .fake() - func waitForPluginInStorage(siteID: Int64, plugin: String, isActive: Bool) async -> SystemPlugin { + func waitForPluginInStorage(siteID: Int64, pluginPath: String, isActive: Bool) async -> SystemPlugin { pluginToReturn } } diff --git a/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/POSTabEligibilityCheckerTests.swift b/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/POSTabEligibilityCheckerTests.swift index 1c3b727354a..aec31f8ceb4 100644 --- a/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/POSTabEligibilityCheckerTests.swift +++ b/WooCommerce/WooCommerceTests/ViewRelated/Settings/POS/POSTabEligibilityCheckerTests.swift @@ -648,7 +648,7 @@ private extension POSTabEligibilityCheckerTests { private final class MockPluginsService: PluginsServiceProtocol { var pluginToReturn: SystemPlugin = .fake() - func waitForPluginInStorage(siteID: Int64, plugin: String, isActive: Bool) async -> SystemPlugin { + func waitForPluginInStorage(siteID: Int64, pluginPath: String, isActive: Bool) async -> SystemPlugin { pluginToReturn } }