Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit f07efc2

Browse files
authored
[quick_actions] backfill some unit tests for FLTQuickActionsPlugin class (#6206)
1 parent c3da2d1 commit f07efc2

File tree

6 files changed

+174
-7
lines changed

6 files changed

+174
-7
lines changed

packages/quick_actions/quick_actions_ios/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.6.0+13
2+
3+
* Adds some unit tests for `FLTQuickActionsPlugin` class.
4+
15
## 0.6.0+12
26

37
* Adds a custom module map with a Test submodule for unit tests on iOS platform.

packages/quick_actions/quick_actions_ios/example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
1919
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
2020
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
21+
E0C09C29289C729D00E6977E /* FLTQuickActionsPluginTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E0C09C28289C729D00E6977E /* FLTQuickActionsPluginTests.m */; };
2122
/* End PBXBuildFile section */
2223

2324
/* Begin PBXContainerItemProxy section */
@@ -76,6 +77,7 @@
7677
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
7778
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>"; };
7879
C35AD3650AB6BF850E016715 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
80+
E0C09C28289C729D00E6977E /* FLTQuickActionsPluginTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FLTQuickActionsPluginTests.m; sourceTree = "<group>"; };
7981
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>"; };
8082
/* End PBXFileReference section */
8183

@@ -111,6 +113,7 @@
111113
children = (
112114
33E20B3426EFCDFC00A4A191 /* RunnerTests.m */,
113115
33E20B3626EFCDFC00A4A191 /* Info.plist */,
116+
E0C09C28289C729D00E6977E /* FLTQuickActionsPluginTests.m */,
114117
);
115118
path = RunnerTests;
116119
sourceTree = "<group>";
@@ -413,6 +416,7 @@
413416
buildActionMask = 2147483647;
414417
files = (
415418
33E20B3526EFCDFC00A4A191 /* RunnerTests.m in Sources */,
419+
E0C09C29289C729D00E6977E /* FLTQuickActionsPluginTests.m in Sources */,
416420
);
417421
runOnlyForDeploymentPostprocessing = 0;
418422
};
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
@import Flutter;
6+
@import quick_actions_ios;
7+
@import quick_actions_ios.Test;
8+
@import XCTest;
9+
#import <OCMock/OCMock.h>
10+
11+
@interface FLTQuickActionsPluginTests : XCTestCase
12+
13+
@end
14+
15+
@implementation FLTQuickActionsPluginTests
16+
17+
// A dummy `UIApplicationShortcutItem`.
18+
- (UIApplicationShortcutItem *)searchTheThingShortcutItem {
19+
return [[UIApplicationShortcutItem alloc]
20+
initWithType:@"SearchTheThing"
21+
localizedTitle:@"Search the thing"
22+
localizedSubtitle:nil
23+
icon:[UIApplicationShortcutIcon
24+
iconWithTemplateImageName:@"search_the_thing.png"]
25+
userInfo:nil];
26+
}
27+
28+
// A dummy raw shortcut item.
29+
- (NSDictionary<NSString *, NSString *> *)searchTheThingRawItem {
30+
return @{
31+
@"type" : @"SearchTheThing",
32+
@"localizedTitle" : @"Search the thing",
33+
@"icon" : @"search_the_thing.png",
34+
};
35+
}
36+
37+
- (void)testHandleMethodCall_setShortcutItems {
38+
FlutterMethodCall *call =
39+
[FlutterMethodCall methodCallWithMethodName:@"setShortcutItems"
40+
arguments:@[ [self searchTheThingRawItem] ]];
41+
42+
FLTQuickActionsPlugin *plugin =
43+
[[FLTQuickActionsPlugin alloc] initWithChannel:OCMClassMock([FlutterMethodChannel class])];
44+
XCTestExpectation *resultExpectation =
45+
[self expectationWithDescription:@"result block must be called."];
46+
[plugin handleMethodCall:call
47+
result:^(id _Nullable result) {
48+
XCTAssertNil(result, @"result block must be called with nil.");
49+
XCTAssertEqualObjects(UIApplication.sharedApplication.shortcutItems,
50+
@[ [self searchTheThingShortcutItem] ],
51+
@"shortcut items should be set correctly.");
52+
[resultExpectation fulfill];
53+
}];
54+
[self waitForExpectationsWithTimeout:1 handler:nil];
55+
}
56+
57+
- (void)testHandleMethodCall_clearShortcutItems {
58+
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"clearShortcutItems"
59+
arguments:nil];
60+
61+
FLTQuickActionsPlugin *plugin =
62+
[[FLTQuickActionsPlugin alloc] initWithChannel:OCMClassMock([FlutterMethodChannel class])];
63+
XCTestExpectation *resultExpectation =
64+
[self expectationWithDescription:@"result block must be called."];
65+
[plugin handleMethodCall:call
66+
result:^(id _Nullable result) {
67+
XCTAssertNil(result, @"result block must be called with nil.");
68+
XCTAssertEqual(UIApplication.sharedApplication.shortcutItems.count, 0,
69+
@"shortcut items should be cleared");
70+
[resultExpectation fulfill];
71+
}];
72+
[self waitForExpectationsWithTimeout:1 handler:nil];
73+
}
74+
75+
- (void)testHandleMethodCall_getLaunchAction {
76+
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"getLaunchAction"
77+
arguments:nil];
78+
79+
FLTQuickActionsPlugin *plugin =
80+
[[FLTQuickActionsPlugin alloc] initWithChannel:OCMClassMock([FlutterMethodChannel class])];
81+
XCTestExpectation *resultExpectation =
82+
[self expectationWithDescription:@"result block must be called."];
83+
[plugin handleMethodCall:call
84+
result:^(id _Nullable result) {
85+
XCTAssertNil(result, @"result block must be called with nil.");
86+
[resultExpectation fulfill];
87+
}];
88+
[self waitForExpectationsWithTimeout:1 handler:nil];
89+
}
90+
91+
- (void)testHandleMethodCall_nonExistMethods {
92+
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"nonExist" arguments:nil];
93+
94+
FLTQuickActionsPlugin *plugin =
95+
[[FLTQuickActionsPlugin alloc] initWithChannel:OCMClassMock([FlutterMethodChannel class])];
96+
XCTestExpectation *resultExpectation =
97+
[self expectationWithDescription:@"result must be called."];
98+
[plugin
99+
handleMethodCall:call
100+
result:^(id _Nullable result) {
101+
XCTAssertEqual(result, FlutterMethodNotImplemented,
102+
@"result block must be called with FlutterMethodNotImplemented");
103+
[resultExpectation fulfill];
104+
}];
105+
106+
[self waitForExpectationsWithTimeout:1 handler:nil];
107+
}
108+
109+
- (void)testApplicationPerformActionForShortcutItem {
110+
id mockChannel = OCMClassMock([FlutterMethodChannel class]);
111+
FLTQuickActionsPlugin *plugin = [[FLTQuickActionsPlugin alloc] initWithChannel:mockChannel];
112+
113+
UIApplicationShortcutItem *item = [self searchTheThingShortcutItem];
114+
115+
BOOL actionResult = [plugin application:[UIApplication sharedApplication]
116+
performActionForShortcutItem:item
117+
completionHandler:^(BOOL succeeded){/* no-op */}];
118+
XCTAssert(actionResult, @"performActionForShortcutItem must return true.");
119+
OCMVerify([mockChannel invokeMethod:@"launch" arguments:item.type]);
120+
}
121+
122+
- (void)testApplicationDidFinishLaunchingWithOptions_launchWithShortcut {
123+
FLTQuickActionsPlugin *plugin =
124+
[[FLTQuickActionsPlugin alloc] initWithChannel:OCMClassMock([FlutterMethodChannel class])];
125+
126+
UIApplicationShortcutItem *item = [self searchTheThingShortcutItem];
127+
128+
BOOL launchResult = [plugin application:[UIApplication sharedApplication]
129+
didFinishLaunchingWithOptions:@{UIApplicationLaunchOptionsShortcutItemKey : item}];
130+
131+
XCTAssertFalse(launchResult,
132+
@"didFinishLaunchingWithOptions must return false if launched from shortcut.");
133+
}
134+
135+
- (void)testApplicationDidFinishLaunchingWithOptions_launchWithoutShortcut {
136+
FLTQuickActionsPlugin *plugin =
137+
[[FLTQuickActionsPlugin alloc] initWithChannel:OCMClassMock([FlutterMethodChannel class])];
138+
BOOL launchResult = [plugin application:[UIApplication sharedApplication]
139+
didFinishLaunchingWithOptions:@{}];
140+
XCTAssertTrue(launchResult,
141+
@"didFinishLaunchingWithOptions must return true if not launched from shortcut.");
142+
}
143+
144+
- (void)testApplicationDidBecomeActive {
145+
UIApplicationShortcutItem *item = [self searchTheThingShortcutItem];
146+
id mockChannel = OCMClassMock([FlutterMethodChannel class]);
147+
FLTQuickActionsPlugin *plugin = [[FLTQuickActionsPlugin alloc] initWithChannel:mockChannel];
148+
plugin.launchingShortcutType = item.type;
149+
[plugin applicationDidBecomeActive:[UIApplication sharedApplication]];
150+
151+
OCMVerify([mockChannel invokeMethod:@"launch" arguments:item.type]);
152+
XCTAssertNil(plugin.launchingShortcutType,
153+
@"Must reset launchingShortcutType to nil after being used.");
154+
}
155+
156+
@end

packages/quick_actions/quick_actions_ios/ios/Classes/FLTQuickActionsPlugin.m

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
@interface FLTQuickActionsPlugin ()
1111
@property(nonatomic, retain) FlutterMethodChannel *channel;
12-
@property(nonatomic, retain) NSString *shortcutType;
1312
@end
1413

1514
@implementation FLTQuickActionsPlugin
@@ -65,7 +64,7 @@ - (BOOL)application:(UIApplication *)application
6564
// Keep hold of the shortcut type and handle it in the
6665
// `applicationDidBecomeActure:` method once the Dart MethodChannel
6766
// is initialized.
68-
self.shortcutType = shortcutItem.type;
67+
self.launchingShortcutType = shortcutItem.type;
6968

7069
// Return NO to indicate we handled the quick action to ensure
7170
// the `application:performActionFor:` method is not called (as
@@ -77,9 +76,9 @@ - (BOOL)application:(UIApplication *)application
7776
}
7877

7978
- (void)applicationDidBecomeActive:(UIApplication *)application {
80-
if (self.shortcutType) {
81-
[self handleShortcut:self.shortcutType];
82-
self.shortcutType = nil;
79+
if (self.launchingShortcutType) {
80+
[self handleShortcut:self.launchingShortcutType];
81+
self.launchingShortcutType = nil;
8382
}
8483
}
8584

packages/quick_actions/quick_actions_ios/ios/Classes/PrivateHeaders/FLTQuickActionsPlugin_Test.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
NS_ASSUME_NONNULL_BEGIN
88

99
/// APIs exposed for unit tests.
10-
@interface FLTQuickActionsPlugin (Test)
10+
@interface FLTQuickActionsPlugin ()
11+
12+
/// The type of the shortcut item selected when launching the app.
13+
/// API exposed for unit tests.
14+
@property(nonatomic, strong, nullable) NSString *launchingShortcutType;
1115

1216
/// Initializes a FLTQuickActionsPlugin with the given method channel.
1317
/// API exposed for unit tests.

packages/quick_actions/quick_actions_ios/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: quick_actions_ios
22
description: An implementation for the iOS platform of the Flutter `quick_actions` plugin.
33
repository: https://github.com/flutter/plugins/tree/main/packages/quick_actions/quick_actions_ios
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22
5-
version: 0.6.0+12
5+
version: 0.6.0+13
66

77
environment:
88
sdk: ">=2.15.0 <3.0.0"

0 commit comments

Comments
 (0)