[quick_actions] add custom modulemap with test submodule (#6169)

diff --git a/packages/quick_actions/quick_actions_ios/CHANGELOG.md b/packages/quick_actions/quick_actions_ios/CHANGELOG.md
index 35f9c9f..9235afa 100644
--- a/packages/quick_actions/quick_actions_ios/CHANGELOG.md
+++ b/packages/quick_actions/quick_actions_ios/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.6.0+12
+
+* Adds a custom module map with a Test submodule for unit tests on iOS platform.
+
 ## 0.6.0+11
 
 * Updates references to the obsolete master branch.
diff --git a/packages/quick_actions/quick_actions_ios/example/ios/Podfile b/packages/quick_actions/quick_actions_ios/example/ios/Podfile
index 3924e59..b528052 100644
--- a/packages/quick_actions/quick_actions_ios/example/ios/Podfile
+++ b/packages/quick_actions/quick_actions_ios/example/ios/Podfile
@@ -31,6 +31,7 @@
   flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
   target 'RunnerTests' do
     inherit! :search_paths
+    pod 'OCMock', '~> 3.9.1'
   end
 end
 
diff --git a/packages/quick_actions/quick_actions_ios/example/ios/Runner.xcodeproj/project.pbxproj b/packages/quick_actions/quick_actions_ios/example/ios/Runner.xcodeproj/project.pbxproj
index 36dc0d8..a517b09 100644
--- a/packages/quick_actions/quick_actions_ios/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/packages/quick_actions/quick_actions_ios/example/ios/Runner.xcodeproj/project.pbxproj
@@ -3,16 +3,16 @@
 	archiveVersion = 1;
 	classes = {
 	};
-	objectVersion = 50;
+	objectVersion = 54;
 	objects = {
 
 /* Begin PBXBuildFile section */
 		1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+		2632072169FF635893D8EB4D /* libPods-RunnerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 436668746754BEEA28B76E55 /* libPods-RunnerTests.a */; };
 		33E20B3526EFCDFC00A4A191 /* RunnerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E20B3426EFCDFC00A4A191 /* RunnerTests.m */; };
 		3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
-		50EB54C1FE43DB743F5DEC7C /* libPods-RunnerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D1A69703A518C37D73BF8B91 /* libPods-RunnerTests.a */; };
 		686BE83025E58CCF00862533 /* RunnerUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 686BE82F25E58CCF00862533 /* RunnerUITests.m */; };
-		83C36CAF23D629E5ABE75B2A /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CCC799F2B0AB50A9C34344F0 /* libPods-Runner.a */; };
+		6A841C2B6AED5CF8DB2A1894 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C35AD3650AB6BF850E016715 /* libPods-Runner.a */; };
 		978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
 		97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
 		97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
@@ -57,6 +57,7 @@
 		33E20B3426EFCDFC00A4A191 /* RunnerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RunnerTests.m; sourceTree = "<group>"; };
 		33E20B3626EFCDFC00A4A191 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
+		436668746754BEEA28B76E55 /* libPods-RunnerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RunnerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		5278439583922091276A37C9 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
 		686BE82D25E58CCF00862533 /* RunnerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
 		686BE82F25E58CCF00862533 /* RunnerUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RunnerUITests.m; sourceTree = "<group>"; };
@@ -74,8 +75,7 @@
 		97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
 		97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		9D27FE1F0F21D4D47DDA16DE /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
-		CCC799F2B0AB50A9C34344F0 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
-		D1A69703A518C37D73BF8B91 /* libPods-RunnerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RunnerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+		C35AD3650AB6BF850E016715 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		F0609304FBCAEC2289164BD5 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
@@ -84,7 +84,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				50EB54C1FE43DB743F5DEC7C /* libPods-RunnerTests.a in Frameworks */,
+				2632072169FF635893D8EB4D /* libPods-RunnerTests.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -99,7 +99,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				83C36CAF23D629E5ABE75B2A /* libPods-Runner.a in Frameworks */,
+				6A841C2B6AED5CF8DB2A1894 /* libPods-Runner.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -185,8 +185,8 @@
 		A44AD0D63DEF785A2A2DEE28 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
-				CCC799F2B0AB50A9C34344F0 /* libPods-Runner.a */,
-				D1A69703A518C37D73BF8B91 /* libPods-RunnerTests.a */,
+				C35AD3650AB6BF850E016715 /* libPods-Runner.a */,
+				436668746754BEEA28B76E55 /* libPods-RunnerTests.a */,
 			);
 			name = Frameworks;
 			sourceTree = "<group>";
@@ -337,6 +337,7 @@
 /* Begin PBXShellScriptBuildPhase section */
 		3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
 			isa = PBXShellScriptBuildPhase;
+			alwaysOutOfDate = 1;
 			buildActionMask = 2147483647;
 			files = (
 			);
@@ -373,6 +374,7 @@
 		};
 		9740EEB61CF901F6004384FC /* Run Script */ = {
 			isa = PBXShellScriptBuildPhase;
+			alwaysOutOfDate = 1;
 			buildActionMask = 2147483647;
 			files = (
 			);
@@ -473,7 +475,11 @@
 			buildSettings = {
 				BUNDLE_LOADER = "$(TEST_HOST)";
 				INFOPLIST_FILE = RunnerTests/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+					"@loader_path/Frameworks",
+				);
 				PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner";
@@ -486,7 +492,11 @@
 			buildSettings = {
 				BUNDLE_LOADER = "$(TEST_HOST)";
 				INFOPLIST_FILE = RunnerTests/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+					"@loader_path/Frameworks",
+				);
 				PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner";
@@ -506,7 +516,11 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = RunnerUITests/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+					"@loader_path/Frameworks",
+				);
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.google.RunnerUITests;
@@ -529,7 +543,11 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = RunnerUITests/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+					"@loader_path/Frameworks",
+				);
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.google.RunnerUITests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -655,7 +673,10 @@
 					"$(PROJECT_DIR)/Flutter",
 				);
 				INFOPLIST_FILE = Runner/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/Flutter",
@@ -676,7 +697,10 @@
 					"$(PROJECT_DIR)/Flutter",
 				);
 				INFOPLIST_FILE = Runner/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/Flutter",
diff --git a/packages/quick_actions/quick_actions_ios/example/ios/Runner/Info.plist b/packages/quick_actions/quick_actions_ios/example/ios/Runner/Info.plist
index d6bca84..2128c14 100644
--- a/packages/quick_actions/quick_actions_ios/example/ios/Runner/Info.plist
+++ b/packages/quick_actions/quick_actions_ios/example/ios/Runner/Info.plist
@@ -45,5 +45,9 @@
 	</array>
 	<key>UIViewControllerBasedStatusBarAppearance</key>
 	<false/>
+	<key>CADisableMinimumFrameDurationOnPhone</key>
+	<true/>
+	<key>UIApplicationSupportsIndirectInputEvents</key>
+	<true/>
 </dict>
 </plist>
diff --git a/packages/quick_actions/quick_actions_ios/example/ios/RunnerTests/RunnerTests.m b/packages/quick_actions/quick_actions_ios/example/ios/RunnerTests/RunnerTests.m
index 4a96d05..3e35e2d 100644
--- a/packages/quick_actions/quick_actions_ios/example/ios/RunnerTests/RunnerTests.m
+++ b/packages/quick_actions/quick_actions_ios/example/ios/RunnerTests/RunnerTests.m
@@ -2,8 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+@import Flutter;
 @import quick_actions_ios;
+@import quick_actions_ios.Test;
 @import XCTest;
+#import <OCMock/OCMock.h>
 
 @interface QuickActionsTests : XCTestCase
 @end
@@ -11,7 +14,8 @@
 @implementation QuickActionsTests
 
 - (void)testPlugin {
-  FLTQuickActionsPlugin *plugin = [[FLTQuickActionsPlugin alloc] init];
+  FLTQuickActionsPlugin *plugin =
+      [[FLTQuickActionsPlugin alloc] initWithChannel:OCMClassMock([FlutterMethodChannel class])];
   XCTAssertNotNil(plugin);
 }
 
diff --git a/packages/quick_actions/quick_actions_ios/ios/Classes/FLTQuickActionsPlugin.h b/packages/quick_actions/quick_actions_ios/ios/Classes/FLTQuickActionsPlugin.h
index 8f98cc3..6eb6e2b 100644
--- a/packages/quick_actions/quick_actions_ios/ios/Classes/FLTQuickActionsPlugin.h
+++ b/packages/quick_actions/quick_actions_ios/ios/Classes/FLTQuickActionsPlugin.h
@@ -2,7 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import <Flutter/Flutter.h>
+@import Flutter;
 
 @interface FLTQuickActionsPlugin : NSObject <FlutterPlugin>
+
+/// Unavailable. Please use `initWithChannel:` instead.
+- (instancetype)init NS_UNAVAILABLE;
+
+/// Unavailable. Please use `initWithChannel:` instead.
++ (instancetype)new NS_UNAVAILABLE;
 @end
diff --git a/packages/quick_actions/quick_actions_ios/ios/Classes/FLTQuickActionsPlugin.m b/packages/quick_actions/quick_actions_ios/ios/Classes/FLTQuickActionsPlugin.m
index 883352c..dc1c866 100644
--- a/packages/quick_actions/quick_actions_ios/ios/Classes/FLTQuickActionsPlugin.m
+++ b/packages/quick_actions/quick_actions_ios/ios/Classes/FLTQuickActionsPlugin.m
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #import "FLTQuickActionsPlugin.h"
+#import "FLTQuickActionsPlugin_Test.h"
 
 static NSString *const kChannelName = @"plugins.flutter.io/quick_actions_ios";
 
@@ -17,12 +18,18 @@
   FlutterMethodChannel *channel =
       [FlutterMethodChannel methodChannelWithName:kChannelName
                                   binaryMessenger:[registrar messenger]];
-  FLTQuickActionsPlugin *instance = [[FLTQuickActionsPlugin alloc] init];
-  instance.channel = channel;
+  FLTQuickActionsPlugin *instance = [[FLTQuickActionsPlugin alloc] initWithChannel:channel];
   [registrar addMethodCallDelegate:instance channel:channel];
   [registrar addApplicationDelegate:instance];
 }
 
+- (instancetype)initWithChannel:(FlutterMethodChannel *)channel {
+  if ((self = [super init])) {
+    _channel = channel;
+  }
+  return self;
+}
+
 - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
   if ([call.method isEqualToString:@"setShortcutItems"]) {
     _setShortcutItems(call.arguments);
diff --git a/packages/quick_actions/quick_actions_ios/ios/Classes/PrivateHeaders/FLTQuickActionsPlugin_Test.h b/packages/quick_actions/quick_actions_ios/ios/Classes/PrivateHeaders/FLTQuickActionsPlugin_Test.h
new file mode 100644
index 0000000..c5fa43d
--- /dev/null
+++ b/packages/quick_actions/quick_actions_ios/ios/Classes/PrivateHeaders/FLTQuickActionsPlugin_Test.h
@@ -0,0 +1,20 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+@import Flutter;
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// APIs exposed for unit tests.
+@interface FLTQuickActionsPlugin (Test)
+
+/// Initializes a FLTQuickActionsPlugin with the given method channel.
+/// API exposed for unit tests.
+/// @param channel A method channel.
+/// @return The initialized FLTQuickActionsPlugin.
+- (instancetype)initWithChannel:(FlutterMethodChannel *)channel;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/packages/quick_actions/quick_actions_ios/ios/Classes/QuickActionsPlugin.modulemap b/packages/quick_actions/quick_actions_ios/ios/Classes/QuickActionsPlugin.modulemap
new file mode 100644
index 0000000..e8371cb
--- /dev/null
+++ b/packages/quick_actions/quick_actions_ios/ios/Classes/QuickActionsPlugin.modulemap
@@ -0,0 +1,10 @@
+framework module quick_actions_ios {
+  umbrella header "quick_actions_ios-umbrella.h"
+
+  export *
+  module * { export * }
+
+  explicit module Test {
+    header "FLTQuickActionsPlugin_Test.h"
+  }
+}
diff --git a/packages/quick_actions/quick_actions_ios/ios/Classes/quick_actions_ios-umbrella.h b/packages/quick_actions/quick_actions_ios/ios/Classes/quick_actions_ios-umbrella.h
new file mode 100644
index 0000000..d099a04
--- /dev/null
+++ b/packages/quick_actions/quick_actions_ios/ios/Classes/quick_actions_ios-umbrella.h
@@ -0,0 +1,10 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Foundation/Foundation.h>
+
+FOUNDATION_EXPORT double quickActionsIOSVersionNumber;
+FOUNDATION_EXPORT const unsigned char quickActionsIOSVersionString[];
+
+#import <quick_actions_ios/FLTQuickActionsPlugin.h>
diff --git a/packages/quick_actions/quick_actions_ios/ios/quick_actions_ios.podspec b/packages/quick_actions/quick_actions_ios/ios/quick_actions_ios.podspec
index e8485f9..68eaa6f 100644
--- a/packages/quick_actions/quick_actions_ios/ios/quick_actions_ios.podspec
+++ b/packages/quick_actions/quick_actions_ios/ios/quick_actions_ios.podspec
@@ -14,9 +14,11 @@
   s.author           = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
   s.source           = { :http => 'https://github.com/flutter/plugins/tree/main/packages/quick_actions' }
   s.documentation_url = 'https://pub.dev/packages/quick_actions'
-  s.source_files = 'Classes/**/*'
-  s.public_header_files = 'Classes/**/*.h'
+  s.source_files = 'Classes/**/*.{h,m}'
+  s.public_header_files = 'Classes/*.h'
+  s.private_header_files = 'Classes/PrivateHeaders/*.h'
   s.dependency 'Flutter'
   s.platform = :ios, '9.0'
   s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
+  s.module_map = 'Classes/QuickActionsPlugin.modulemap'
 end
diff --git a/packages/quick_actions/quick_actions_ios/pubspec.yaml b/packages/quick_actions/quick_actions_ios/pubspec.yaml
index 4dc91f4..08ea406 100644
--- a/packages/quick_actions/quick_actions_ios/pubspec.yaml
+++ b/packages/quick_actions/quick_actions_ios/pubspec.yaml
@@ -2,7 +2,7 @@
 description: An implementation for the iOS platform of the Flutter `quick_actions` plugin.
 repository: https://github.com/flutter/plugins/tree/main/packages/quick_actions/quick_actions_ios
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22
-version: 0.6.0+11
+version: 0.6.0+12
 
 environment:
   sdk: ">=2.15.0 <3.0.0"