diff --git a/Gemfile b/Gemfile index 01038ec25ad..4b40ce94f86 100644 --- a/Gemfile +++ b/Gemfile @@ -15,7 +15,11 @@ gem 'fastlane-plugin-sentry', '~> 1.0' # This comment avoids typing to switch to a development version for testing. # # gem 'fastlane-plugin-wpmreleasetoolkit', git: 'git@github.com:wordpress-mobile/release-toolkit', branch: '' -gem 'fastlane-plugin-wpmreleasetoolkit', '~> 13.0' +# +# The '>= 13.3.1' aftre '~> 13.3' ensures that we resolve to any version compatible with 13.3 starting from 13.3.1 +# Using '~> 13.3.1' would constrain us to 13.3.2, 13.3.3, etc. without ever going up to 13.4 +# We need 13.3.1 because of a fix in screenshots generation we depend upon. +gem 'fastlane-plugin-wpmreleasetoolkit', '~> 13.3', '>= 13.3.1' gem 'rake', '~> 12.3' gem 'rubocop', '~> 1.65' gem 'rubocop-rake', '~> 0.6' diff --git a/Gemfile.lock b/Gemfile.lock index 50bf2f30b11..befe6479747 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,7 +5,7 @@ GEM base64 nkf rexml - activesupport (7.2.2.1) + activesupport (8.0.2) base64 benchmark (>= 0.3) bigdecimal @@ -17,6 +17,7 @@ GEM minitest (>= 5.1) securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) artifactory (3.0.17) @@ -40,8 +41,8 @@ GEM aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) base64 (0.2.0) - benchmark (0.4.0) - bigdecimal (3.1.9) + benchmark (0.4.1) + bigdecimal (3.2.2) buildkit (1.6.1) sawyer (>= 0.6) chroma (0.2.0) @@ -54,8 +55,8 @@ GEM colored2 (3.1.2) commander (4.6.0) highline (~> 2.0.0) - concurrent-ruby (1.3.4) - connection_pool (2.4.1) + concurrent-ruby (1.3.5) + connection_pool (2.5.3) cork (0.3.0) colored2 (~> 3.1) danger (9.5.1) @@ -83,12 +84,12 @@ GEM danger rubocop (~> 1.0) declarative (0.0.20) - diffy (3.4.3) + diffy (3.4.4) digest-crc (0.6.5) rake (>= 12.0.0, < 14.0.0) domain_name (0.6.20240107) dotenv (2.8.1) - drb (2.2.1) + drb (2.2.3) emoji_regex (3.2.3) excon (0.112.0) faraday (1.10.4) @@ -169,7 +170,7 @@ GEM google-apis-firebaseappdistribution_v1alpha (~> 0.2.0) fastlane-plugin-sentry (1.25.1) os (~> 1.1, >= 1.1.4) - fastlane-plugin-wpmreleasetoolkit (13.0.0) + fastlane-plugin-wpmreleasetoolkit (13.3.1) activesupport (>= 6.1.7.1) buildkit (~> 1.5) chroma (= 0.2.0) @@ -236,7 +237,7 @@ GEM http-cookie (1.0.8) domain_name (~> 0.5) httpclient (2.8.3) - i18n (1.14.6) + i18n (1.14.7) concurrent-ruby (~> 1.0) java-properties (0.3.0) jmespath (1.6.2) @@ -248,21 +249,21 @@ GEM kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) language_server-protocol (3.17.0.3) - logger (1.6.4) + logger (1.7.0) mini_magick (4.13.2) mini_mime (1.1.5) - mini_portile2 (2.8.8) - minitest (5.25.4) + mini_portile2 (2.8.9) + minitest (5.25.5) multi_json (1.15.0) multipart-post (2.4.1) nanaimo (0.4.0) nap (1.1.0) naturally (2.2.1) nkf (0.2.0) - nokogiri (1.18.3) + nokogiri (1.18.8) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.18.3-x86_64-darwin) + nokogiri (1.18.8-x86_64-darwin) racc (~> 1.4) octokit (6.1.1) faraday (>= 1, < 3) @@ -284,7 +285,7 @@ GEM racc (1.8.1) rainbow (3.1.1) rake (12.3.3) - rake-compiler (1.2.9) + rake-compiler (1.3.0) rake rchardet (1.8.0) regexp_parser (2.9.2) @@ -339,6 +340,7 @@ GEM concurrent-ruby (~> 1.0) uber (0.1.0) unicode-display_width (2.6.0) + uri (1.0.3) word_wrap (1.0.0) xcode-install (2.8.1) claide (>= 0.9.1) @@ -367,7 +369,7 @@ DEPENDENCIES fastlane (~> 2.217) fastlane-plugin-firebase_app_distribution (~> 0.10) fastlane-plugin-sentry (~> 1.0) - fastlane-plugin-wpmreleasetoolkit (~> 13.0) + fastlane-plugin-wpmreleasetoolkit (~> 13.3, >= 13.3.1) rake (~> 12.3) rmagick (~> 4.1) rubocop (~> 1.65) diff --git a/Modules/Sources/Yosemite/Model/Mocks/ActionHandlers/MockSettingActionHandler.swift b/Modules/Sources/Yosemite/Model/Mocks/ActionHandlers/MockSettingActionHandler.swift index 9d020a1c6bc..e7bee452747 100644 --- a/Modules/Sources/Yosemite/Model/Mocks/ActionHandlers/MockSettingActionHandler.swift +++ b/Modules/Sources/Yosemite/Model/Mocks/ActionHandlers/MockSettingActionHandler.swift @@ -25,6 +25,18 @@ struct MockSettingActionHandler: MockActionHandler { synchronizeGeneralSiteSettings(siteID: siteID, onCompletion: onCompletion) case .retrieveTaxBasedOnSetting(_, let onCompletion): onCompletion(.success(objectGraph.taxBasedOnSetting)) + case .isFeatureEnabled(_, let feature, let onCompletion): + switch feature { + case .pointOfSale: + // Only enables POS feature for eligible locales (US and UK variants). + let locale = Locale.current + let localeIdentifier = locale.identifier + let isEligibleCountry = localeIdentifier.hasPrefix("en_US") || + localeIdentifier.hasPrefix("en_GB") || + localeIdentifier == "en-US" || + localeIdentifier == "en-GB" + onCompletion(.success(isEligibleCountry)) + } default: unimplementedAction(action: action) } } diff --git a/Modules/Sources/Yosemite/Model/Mocks/ActionHandlers/MockSystemStatusActionHandler.swift b/Modules/Sources/Yosemite/Model/Mocks/ActionHandlers/MockSystemStatusActionHandler.swift index 4f3a7feed98..42dfaa70dc0 100644 --- a/Modules/Sources/Yosemite/Model/Mocks/ActionHandlers/MockSystemStatusActionHandler.swift +++ b/Modules/Sources/Yosemite/Model/Mocks/ActionHandlers/MockSystemStatusActionHandler.swift @@ -14,12 +14,22 @@ struct MockSystemStatusActionHandler: MockActionHandler { synchronizeSystemPlugins(siteID: siteID) { result in onCompletion(result.map { SystemInformation(systemPlugins: $0) }) } + case .fetchSystemPlugin(let siteID, let systemPluginName, let onCompletion): + let systemPlugins = objectGraph.systemPlugins(for: siteID) + let filteredSystemPlugin = systemPlugins.first { $0.name == systemPluginName } + let matchingPlugin = systemPlugins.first { $0.name == systemPluginName && $0.active } ?? filteredSystemPlugin + onCompletion(matchingPlugin) case .fetchSystemPluginListWithNameList(let siteID, let systemPluginNameList, let onCompletion): let systemPlugins = objectGraph.systemPlugins(for: siteID) let filteredSystemPlugins = systemPlugins.first { systemPluginNameList.contains($0.name) } onCompletion(filteredSystemPlugins) - default: - break + case .fetchSystemPluginWithPath(let siteID, let pluginPath, let onCompletion): + let systemPlugins = objectGraph.systemPlugins(for: siteID) + let matchingPlugin = systemPlugins.first { $0.plugin == pluginPath } + onCompletion(matchingPlugin) + case .fetchSystemStatusReport(_, let onCompletion): + // For now, returns a failure since this mock doesn't implement system status report fetching. + onCompletion(.failure(NSError(domain: "MockSystemStatusActionHandler", code: 1, userInfo: [:]))) } } diff --git a/Modules/Sources/Yosemite/Model/Mocks/Graphs/ScreenshotsObjectGraph.swift b/Modules/Sources/Yosemite/Model/Mocks/Graphs/ScreenshotsObjectGraph.swift index 13c3b348692..56e560c2cb1 100644 --- a/Modules/Sources/Yosemite/Model/Mocks/Graphs/ScreenshotsObjectGraph.swift +++ b/Modules/Sources/Yosemite/Model/Mocks/Graphs/ScreenshotsObjectGraph.swift @@ -1,5 +1,6 @@ import Foundation import Storage +import enum WooFoundation.CurrencyCode struct Defaults { struct Account { @@ -72,13 +73,22 @@ struct ScreenshotObjectGraph: MockObjectGraph { label: "Country and State", settingDescription: "The country and state or province, if any, in which your business is located.", value: "US:CA", + settingGroupKey: "general"), + createSiteSetting(settingID: "woocommerce_currency", + label: "Currency", + settingDescription: "This controls what currency prices are listed at in the catalog and which currency gateways will take payments in.", + value: CurrencyCode.USD.rawValue, settingGroupKey: "general") ] var systemPlugins: [SystemPlugin] = [ createSystemPlugin(plugin: "woocommerce-payments", name: "WooCommerce Payments", - version: "3.2.1") + version: "3.2.1"), + // One of the requirements for the POS tab to show up. + createSystemPlugin(plugin: "woocommerce", + name: "WooCommerce", + version: "10.0.0") ] var paymentGatewayAccounts: [PaymentGatewayAccount] = [ diff --git a/Modules/Sources/Yosemite/Model/Mocks/MockStoresManager.swift b/Modules/Sources/Yosemite/Model/Mocks/MockStoresManager.swift index 924c7351bfb..c947842ec13 100644 --- a/Modules/Sources/Yosemite/Model/Mocks/MockStoresManager.swift +++ b/Modules/Sources/Yosemite/Model/Mocks/MockStoresManager.swift @@ -162,6 +162,11 @@ public class MockStoresManager: StoresManager { shippingMethodActionHandler.handle(action: action) case let action as CouponAction: couponActionHandler.handle(action: action) + case let action as FeatureFlagAction: + switch action { + case let .isRemoteFeatureFlagEnabled(_, _, completion): + completion(true) + } default: fatalError("Unable to handle action: \(action.identifier) \(String(describing: action))") } diff --git a/WooCommerce/WooCommerceScreenshots/WooCommerceScreenshots.swift b/WooCommerce/WooCommerceScreenshots/WooCommerceScreenshots.swift index 957c2a63404..412d45fa493 100644 --- a/WooCommerce/WooCommerceScreenshots/WooCommerceScreenshots.swift +++ b/WooCommerce/WooCommerceScreenshots/WooCommerceScreenshots.swift @@ -42,6 +42,10 @@ class WooCommerceScreenshots: XCTestCase { return false } + // Triggers any pending system dialogs (like push notification permissions). + // The interruption monitor above only activates when the app receives user interaction. + app.tap() + // My Store try TabNavComponent() .goToMyStoreScreen() diff --git a/fastlane/screenshots.json b/fastlane/screenshots.json index 4e6f449ff64..6a88d38d027 100644 --- a/fastlane/screenshots.json +++ b/fastlane/screenshots.json @@ -17,7 +17,7 @@ "device_frame_offset": [161, 595] }, { - "name": "iPad Pro 12.9 (3rd Generation)", + "name": "iPad Pro 13-inch (M4)", "canvas_size": [2048,2732], "text_size": [1848, 559], "text_offset": [100, 0], @@ -74,45 +74,45 @@ }, - /// iPad Pro 12.9 (3rd Generation) + /// iPad Pro 13-inch (M4) // Track sales and bestselling products { - "device": "iPad Pro 12.9 (3rd Generation)", - "filename": "iPad Pro (12.9-inch) (3rd generation)-01.png", + "device": "iPad Pro 13-inch (M4)", + "filename": "iPad Pro 13-inch (M4)-01.png", "background": "appstoreres/assets/ipad-background-1.png", - "screenshot": "iPad Pro (12.9-inch) (3rd generation)-1-dark-order-dashboard.png", + "screenshot": "iPad Pro 13-inch (M4)-1-dark-order-dashboard.png", "text": "metadata/{locale}/app_store_screenshot_1.txt" }, // Create orders on the fly { - "device": "iPad Pro 12.9 (3rd Generation)", - "filename": "iPad Pro (12.9-inch) (3rd generation)-02.png", + "device": "iPad Pro 13-inch (M4)", + "filename": "iPad Pro 13-inch (M4)-02.png", "background": "appstoreres/assets/ipad-background-2.png", - "screenshot": "iPad Pro (12.9-inch) (3rd generation)-2-light-order-creation.png", + "screenshot": "iPad Pro 13-inch (M4)-2-light-order-creation.png", "text": "metadata/{locale}/app_store_screenshot_2.txt" }, // Take payments in person { - "device": "iPad Pro 12.9 (3rd Generation)", - "filename": "iPad Pro (12.9-inch) (3rd generation)-03.png", + "device": "iPad Pro 13-inch (M4)", + "filename": "iPad Pro 13-inch (M4)-03.png", "background": "appstoreres/assets/ipad-background-1.png", - "screenshot": "iPad Pro (12.9-inch) (3rd generation)-3-dark-order-payment.png", + "screenshot": "iPad Pro 13-inch (M4)-3-dark-order-payment.png", "text": "metadata/{locale}/app_store_screenshot_3.txt" }, // Add and edit products with a touch { - "device": "iPad Pro 12.9 (3rd Generation)", - "filename": "iPad Pro (12.9-inch) (3rd generation)-04.png", + "device": "iPad Pro 13-inch (M4)", + "filename": "iPad Pro 13-inch (M4)-04.png", "background": "appstoreres/assets/ipad-background-2.png", - "screenshot": "iPad Pro (12.9-inch) (3rd generation)-4-light-product-add.png", + "screenshot": "iPad Pro 13-inch (M4)-4-light-product-add.png", "text": "metadata/{locale}/app_store_screenshot_4.txt" }, // Get notified of every sale { - "device": "iPad Pro 12.9 (3rd Generation)", - "filename": "iPad Pro (12.9-inch) (3rd generation)-05.png", + "device": "iPad Pro 13-inch (M4)", + "filename": "iPad Pro 13-inch (M4)-05.png", "background": "appstoreres/assets/ipad-background-1.png", - "screenshot": "iPad Pro (12.9-inch) (3rd generation)-5-dark-order-notification.png", + "screenshot": "iPad Pro 13-inch (M4)-5-dark-order-notification.png", "text": "metadata/{locale}/app_store_screenshot_5.txt" } ]