Skip to content

Commit 14536d1

Browse files
authored
Update WC plugin matching to use the file name in plugin path: use cases that match plugin by name - part 1 (#15938)
2 parents 12600d4 + 9289da7 commit 14536d1

File tree

20 files changed

+288
-215
lines changed

20 files changed

+288
-215
lines changed

Modules/Sources/Storage/Tools/StorageType+Extensions.swift

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -839,13 +839,6 @@ public extension StorageType {
839839
return allObjects(ofType: SystemPlugin.self, matching: predicate, sortedBy: [descriptor])
840840
}
841841

842-
/// Returns a system plugin with a specified `siteID` and `name`
843-
///
844-
func loadSystemPlugin(siteID: Int64, name: String) -> SystemPlugin? {
845-
let predicate = \SystemPlugin.siteID == siteID && \SystemPlugin.name == name
846-
return firstObject(ofType: SystemPlugin.self, matching: predicate)
847-
}
848-
849842
/// Returns a system plugin with a specified `siteID` and `path`.
850843
///
851844
/// - Parameters:

Modules/Sources/Yosemite/Actions/SystemStatusAction.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ public enum SystemStatusAction: Action {
1212
///
1313
case fetchSystemPlugin(siteID: Int64, systemPluginName: String, onCompletion: (SystemPlugin?) -> Void)
1414

15-
/// Fetch an specific systemPlugin by siteID and name list.
16-
///
17-
case fetchSystemPluginListWithNameList(siteID: Int64, systemPluginNameList: [String], onCompletion: (SystemPlugin?) -> Void)
18-
1915
/// Fetch a specific systemPlugin by path.
2016
///
2117
case fetchSystemPluginWithPath(siteID: Int64, pluginPath: String, onCompletion: (SystemPlugin?) -> Void)

Modules/Sources/Yosemite/Model/Mocks/ActionHandlers/MockSystemStatusActionHandler.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ struct MockSystemStatusActionHandler: MockActionHandler {
1919
let filteredSystemPlugin = systemPlugins.first { $0.name == systemPluginName }
2020
let matchingPlugin = systemPlugins.first { $0.name == systemPluginName && $0.active } ?? filteredSystemPlugin
2121
onCompletion(matchingPlugin)
22-
case .fetchSystemPluginListWithNameList(let siteID, let systemPluginNameList, let onCompletion):
23-
let systemPlugins = objectGraph.systemPlugins(for: siteID)
24-
let filteredSystemPlugins = systemPlugins.first { systemPluginNameList.contains($0.name) }
25-
onCompletion(filteredSystemPlugins)
2622
case .fetchSystemPluginWithPath(let siteID, let pluginPath, let onCompletion):
2723
let systemPlugins = objectGraph.systemPlugins(for: siteID)
2824
let matchingPlugin = systemPlugins.first { $0.plugin == pluginPath }

Modules/Sources/Yosemite/PointOfSale/Eligibility/POSSystemStatusService.swift

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,20 @@ public struct POSPluginAndFeatureInfo {
2525
public final class POSSystemStatusService: POSSystemStatusServiceProtocol {
2626
private let remote: SystemStatusRemote
2727
private let storageManager: StorageManagerType
28+
private let pluginsService: PluginsServiceProtocol
2829

2930
public init(credentials: Credentials?, storageManager: StorageManagerType) {
3031
let network = AlamofireNetwork(credentials: credentials)
3132
self.remote = SystemStatusRemote(network: network)
3233
self.storageManager = storageManager
34+
self.pluginsService = PluginsService(storageManager: storageManager)
3335
}
3436

3537
/// Test-friendly initializer that accepts a network implementation.
3638
init(network: Network, storageManager: StorageManagerType) {
3739
self.remote = SystemStatusRemote(network: network)
3840
self.storageManager = storageManager
41+
self.pluginsService = PluginsService(storageManager: storageManager)
3942
}
4043

4144
@MainActor
@@ -54,9 +57,7 @@ public final class POSSystemStatusService: POSSystemStatusServiceProtocol {
5457
})
5558

5659
// Loads WooCommerce plugin from storage.
57-
guard let wcPlugin = storageManager.viewStorage.loadSystemPlugin(siteID: siteID,
58-
fileNameWithoutExtension: Constants.wcPluginFileNameWithoutExtension,
59-
active: true)?.toReadOnly() else {
60+
guard let wcPlugin = pluginsService.loadPluginInStorage(siteID: siteID, plugin: .wooCommerce, isActive: true) else {
6061
return POSPluginAndFeatureInfo(wcPlugin: nil, featureValue: nil)
6162
}
6263

@@ -66,12 +67,6 @@ public final class POSSystemStatusService: POSSystemStatusServiceProtocol {
6667
}
6768
}
6869

69-
private extension POSSystemStatusService {
70-
enum Constants {
71-
static let wcPluginFileNameWithoutExtension = "woocommerce"
72-
}
73-
}
74-
7570
// MARK: - Network Response Structs
7671

7772
private struct POSPluginEligibilitySystemStatus: Decodable {

Modules/Sources/Yosemite/Stores/SystemStatusStore.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ public final class SystemStatusStore: Store {
3131
synchronizeSystemInformation(siteID: siteID, completionHandler: onCompletion)
3232
case .fetchSystemPlugin(let siteID, let systemPluginName, let onCompletion):
3333
fetchSystemPlugin(siteID: siteID, systemPluginNameList: [systemPluginName], completionHandler: onCompletion)
34-
case .fetchSystemPluginListWithNameList(let siteID, let systemPluginNameList, let onCompletion):
35-
fetchSystemPlugin(siteID: siteID, systemPluginNameList: systemPluginNameList, completionHandler: onCompletion)
3634
case .fetchSystemPluginWithPath(let siteID, let pluginPath, let onCompletion):
3735
fetchSystemPluginWithPath(siteID: siteID,
3836
pluginPath: pluginPath,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import Foundation
2+
3+
public enum Plugin: Equatable, CaseIterable {
4+
case wooCommerce
5+
case wooSubscriptions
6+
case wooShipmentTracking
7+
case wooSquare
8+
9+
/// File name without extension in the plugin path.
10+
/// Full plugin path is like `woocommerce/woocommerce.php`.
11+
var fileNameWithoutExtension: String {
12+
switch self {
13+
case .wooCommerce:
14+
return "woocommerce"
15+
case .wooSubscriptions:
16+
return "woocommerce-subscriptions"
17+
case .wooShipmentTracking:
18+
return "woocommerce-shipment-tracking"
19+
case .wooSquare:
20+
return "woocommerce-square"
21+
}
22+
}
23+
}

Modules/Sources/Yosemite/Tools/Plugins/PluginsService.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,21 @@ public protocol PluginsServiceProtocol {
1111
/// - isActive: Whether the plugin is active or not.
1212
/// - Returns: The SystemPlugin when found in storage.
1313
func waitForPluginInStorage(siteID: Int64, pluginPath: String, isActive: Bool) async -> SystemPlugin
14+
15+
/// Loads a specific plugin from storage synchronously.
16+
/// - Parameters:
17+
/// - siteID: The site ID to search for the plugin.
18+
/// - plugin: The plugin to load.
19+
/// - isActive: Whether the plugin is active, inactive, or nil for any state.
20+
/// - Returns: The SystemPlugin if found in storage, nil otherwise.
21+
func loadPluginInStorage(siteID: Int64, plugin: Plugin, isActive: Bool?) -> SystemPlugin?
22+
}
23+
24+
public extension PluginsServiceProtocol {
25+
func isPluginActiveInStorage(siteID: Int64, plugin: Plugin) -> Bool {
26+
let plugin = loadPluginInStorage(siteID: siteID, plugin: plugin, isActive: true)
27+
return plugin != nil && plugin?.active == true
28+
}
1429
}
1530

1631
public class PluginsService: PluginsServiceProtocol {
@@ -49,4 +64,10 @@ public class PluginsService: PluginsServiceProtocol {
4964
}
5065
}
5166
}
67+
68+
public func loadPluginInStorage(siteID: Int64, plugin: Plugin, isActive: Bool?) -> SystemPlugin? {
69+
storageManager.viewStorage.loadSystemPlugin(siteID: siteID,
70+
fileNameWithoutExtension: plugin.fileNameWithoutExtension,
71+
active: isActive)?.toReadOnly()
72+
}
5273
}

Modules/Tests/StorageTests/Tools/StorageTypeExtensionsTests.swift

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,23 +1432,6 @@ final class StorageTypeExtensionsTests: XCTestCase {
14321432
XCTAssertEqual(storedSystemPlugins, [systemPlugin1, systemPlugin4])
14331433
}
14341434

1435-
func test_loadSystemPlugin_by_siteID_and_name() throws {
1436-
// Given
1437-
let systemPlugin1 = storage.insertNewObject(ofType: SystemPlugin.self)
1438-
systemPlugin1.name = "Plugin 1"
1439-
systemPlugin1.siteID = sampleSiteID
1440-
1441-
let systemPlugin2 = storage.insertNewObject(ofType: SystemPlugin.self)
1442-
systemPlugin2.name = "Plugin 2"
1443-
systemPlugin2.siteID = sampleSiteID
1444-
1445-
// When
1446-
let foundSystemPlugin = try XCTUnwrap(storage.loadSystemPlugin(siteID: sampleSiteID, name: "Plugin 2"))
1447-
1448-
// Then
1449-
XCTAssertEqual(foundSystemPlugin, systemPlugin2)
1450-
}
1451-
14521435
func test_loadSystemPlugin_by_siteID_and_path() throws {
14531436
// Given
14541437
let systemPlugin1 = storage.insertNewObject(ofType: SystemPlugin.self)

Modules/Tests/YosemiteTests/Stores/SystemStatusStoreTests.swift

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ final class SystemStatusStoreTests: XCTestCase {
7979

8080
func test_synchronizeSystemInformation_removes_stale_systemPlugins_correctly() {
8181
// Given
82-
let staleSystemPluginName = "Stale System Plugin"
83-
let staleSystemPlugin = SystemPlugin.fake().copy(siteID: sampleSiteID, name: staleSystemPluginName)
82+
let staleSystemPluginPath = "folder/stale-plugin.php"
83+
let staleSystemPlugin = SystemPlugin.fake().copy(siteID: sampleSiteID, plugin: staleSystemPluginPath)
8484
let storedStaleSystemPlugin = viewStorage.insertNewObject(ofType: StorageSystemPlugin.self)
8585
storedStaleSystemPlugin.update(with: staleSystemPlugin)
8686
XCTAssertEqual(viewStorage.countObjects(ofType: StorageSystemPlugin.self), 1)
@@ -98,7 +98,7 @@ final class SystemStatusStoreTests: XCTestCase {
9898
// Then
9999
XCTAssertTrue(result.isSuccess)
100100
XCTAssertEqual(viewStorage.countObjects(ofType: StorageSystemPlugin.self), 6) // number of systemPlugins in json file
101-
XCTAssertNil(viewStorage.loadSystemPlugin(siteID: sampleSiteID, name: staleSystemPluginName))
101+
XCTAssertNil(viewStorage.loadSystemPlugin(siteID: sampleSiteID, fileNameWithoutExtension: "stale-plugin"))
102102
}
103103

104104
func test_fetchSystemPlugins_return_systemPlugins_correctly() {
@@ -194,31 +194,6 @@ final class SystemStatusStoreTests: XCTestCase {
194194
XCTAssertNil(fetchedPlugin)
195195
}
196196

197-
func test_fetchSystemPluginsList_return_systemPlugins_correctly() {
198-
// Given
199-
let systemPlugin1 = viewStorage.insertNewObject(ofType: SystemPlugin.self)
200-
systemPlugin1.name = "Plugin 1"
201-
systemPlugin1.siteID = sampleSiteID
202-
203-
let systemPlugin3 = viewStorage.insertNewObject(ofType: SystemPlugin.self)
204-
systemPlugin3.name = "Plugin 3"
205-
systemPlugin3.siteID = sampleSiteID
206-
207-
let store = SystemStatusStore(dispatcher: dispatcher, storageManager: storageManager, network: network)
208-
209-
// When
210-
let systemPluginResult: Yosemite.SystemPlugin? = waitFor { promise in
211-
let action = SystemStatusAction.fetchSystemPluginListWithNameList(siteID: self.sampleSiteID,
212-
systemPluginNameList: ["Plugin 2", "Plugin 3"]) { result in
213-
promise(result)
214-
}
215-
store.onAction(action)
216-
}
217-
218-
// Then
219-
XCTAssertEqual(systemPluginResult?.name, "Plugin 3")
220-
}
221-
222197
func test_fetchSystemPluginWithPath_returns_plugin_when_matching_plugin_is_in_storage() {
223198
// Given
224199
let systemPlugin1 = viewStorage.insertNewObject(ofType: SystemPlugin.self)

Modules/Tests/YosemiteTests/Tools/Plugins/PluginsServiceTests.swift

Lines changed: 90 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ struct PluginsServiceTests {
1515
@Test func waitForPluginInStorage_returns_plugin_when_already_in_storage() async {
1616
// Given
1717
await storageManager.reset()
18-
storageManager.insertWCPlugin(siteID: siteID, isActive: true, version: "1.0.0")
18+
storageManager.insertPlugin(siteID: siteID, plugin: .wooCommerce, isActive: true, version: "1.0.0")
1919

2020
// When
21-
let result = await sut.waitForPluginInStorage(siteID: siteID, pluginPath: PluginConstants.plugin, isActive: true)
21+
let result = await sut.waitForPluginInStorage(siteID: siteID, pluginPath: "woocommerce/woocommerce.php", isActive: true)
2222

2323
// Then
2424
#expect(result.siteID == siteID)
25-
#expect(result.plugin == PluginConstants.plugin)
25+
#expect(result.plugin == "woocommerce/woocommerce.php")
2626
#expect(result.active == true)
2727
#expect(result.version == "1.0.0")
2828
}
@@ -33,31 +33,103 @@ struct PluginsServiceTests {
3333
await storageManager.reset()
3434

3535
// When
36-
async let plugin = sut.waitForPluginInStorage(siteID: siteID, pluginPath: PluginConstants.plugin, isActive: true)
36+
async let plugin = sut.waitForPluginInStorage(siteID: siteID, pluginPath: "woocommerce/woocommerce.php", isActive: true)
3737
#expect(storageManager.viewStorage.loadSystemPlugins(siteID: siteID).count == 0)
38-
storageManager.insertWCPlugin(siteID: siteID, isActive: true, version: "2.0.0")
38+
storageManager.insertPlugin(siteID: siteID, plugin: .wooCommerce, isActive: true, version: "2.0.0")
3939
#expect(storageManager.viewStorage.loadSystemPlugins(siteID: siteID).count == 1)
4040

4141
// Then
4242
let result = await plugin
4343
#expect(result.siteID == siteID)
44-
#expect(result.plugin == PluginConstants.plugin)
45-
#expect(result.name == PluginConstants.pluginName)
44+
#expect(result.plugin == "woocommerce/woocommerce.php")
4645
#expect(result.active == true)
4746
#expect(result.version == "2.0.0")
4847
}
48+
49+
// MARK: - `loadPluginInStorage`
50+
51+
@Test(arguments: [(Plugin.wooCommerce, true, "1.5.0"),
52+
(Plugin.wooCommerce, false, "2.1.0"),
53+
(Plugin.wooSubscriptions, true, "3.0.0"),
54+
(Plugin.wooShipmentTracking, false, "3.0.0")])
55+
func loadPluginInStorage_returns_plugin_when_exists_in_storage(plugin: Plugin, isActive: Bool, version: String) async throws {
56+
// Given
57+
await storageManager.reset()
58+
storageManager.insertPlugin(siteID: siteID, plugin: plugin, isActive: isActive, version: version)
59+
60+
// When
61+
let result = sut.loadPluginInStorage(siteID: siteID, plugin: plugin, isActive: isActive)
62+
63+
// Then
64+
let unwrappedResult = try #require(result)
65+
#expect(unwrappedResult.siteID == siteID)
66+
#expect(unwrappedResult.plugin == plugin.pluginPath)
67+
#expect(unwrappedResult.active == isActive)
68+
#expect(unwrappedResult.version == version)
69+
}
70+
71+
@Test func loadPluginInStorage_returns_plugin_when_exists_in_storage_with_any_active_state() async throws {
72+
// Given
73+
await storageManager.reset()
74+
storageManager.insertPlugin(siteID: siteID, plugin: .wooCommerce, isActive: true, version: "3.0.0")
75+
76+
// When
77+
let result = sut.loadPluginInStorage(siteID: siteID, plugin: .wooCommerce, isActive: nil)
78+
79+
// Then
80+
let unwrappedResult = try #require(result)
81+
#expect(unwrappedResult.siteID == siteID)
82+
#expect(unwrappedResult.plugin == "woocommerce/woocommerce.php")
83+
#expect(unwrappedResult.active == true)
84+
#expect(unwrappedResult.version == "3.0.0")
85+
}
86+
87+
@Test func loadPluginInStorage_returns_nil_when_plugin_does_not_exist() async {
88+
// Given
89+
await storageManager.reset()
90+
91+
// When
92+
let result = sut.loadPluginInStorage(siteID: siteID, plugin: .wooCommerce, isActive: true)
93+
94+
// Then
95+
#expect(result == nil)
96+
}
97+
98+
@Test func loadPluginInStorage_returns_nil_when_plugin_exists_but_active_state_does_not_match() async {
99+
// Given
100+
await storageManager.reset()
101+
storageManager.insertPlugin(siteID: siteID, plugin: .wooCommerce, isActive: true, version: "1.0.0")
102+
103+
// When
104+
let result = sut.loadPluginInStorage(siteID: siteID, plugin: .wooCommerce, isActive: false)
105+
106+
// Then
107+
#expect(result == nil)
108+
}
109+
110+
@Test func loadPluginInStorage_returns_nil_when_plugin_exists_for_different_site() async {
111+
// Given
112+
await storageManager.reset()
113+
let differentSiteID: Int64 = 999
114+
storageManager.insertPlugin(siteID: differentSiteID, plugin: .wooCommerce, isActive: true, version: "1.0.0")
115+
116+
// When
117+
let result = sut.loadPluginInStorage(siteID: siteID, plugin: .wooCommerce, isActive: true)
118+
119+
// Then
120+
#expect(result == nil)
121+
}
49122
}
50123

51124
private extension MockStorageManager {
52-
func insertWCPlugin(siteID: Int64, isActive: Bool, version: String? = nil) {
125+
func insertPlugin(siteID: Int64, plugin: Plugin, isActive: Bool, version: String? = nil) {
53126
performAndSave({ storage in
54-
let plugin = SystemPlugin.fake().copy(siteID: siteID,
55-
plugin: PluginConstants.plugin,
56-
name: PluginConstants.pluginName,
57-
version: version,
58-
active: isActive)
127+
let systemPlugin = SystemPlugin.fake().copy(siteID: siteID,
128+
plugin: plugin.pluginPath,
129+
version: version,
130+
active: isActive)
59131
let newPlugin = storage.insertNewObject(ofType: StorageSystemPlugin.self)
60-
newPlugin.update(with: plugin)
132+
newPlugin.update(with: systemPlugin)
61133
}, completion: nil, on: .main)
62134
}
63135

@@ -70,8 +142,8 @@ private extension MockStorageManager {
70142
}
71143
}
72144

73-
// MARK: - Constants
74-
private enum PluginConstants {
75-
static let plugin = "example-plugin/example-plugin.php"
76-
static let pluginName = "Example Plugin"
145+
extension Plugin {
146+
var pluginPath: String {
147+
"\(fileNameWithoutExtension)/\(fileNameWithoutExtension).php"
148+
}
77149
}

0 commit comments

Comments
 (0)