blob: 77705830f97fc30573bb66e73d842298e3d472bd [file] [log] [blame]
// Copyright 2019 The Chromium 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 "ios/web/public/web_state_delegate_bridge.h"
#include "ios/web/public/test/scoped_testing_web_client.h"
#import "ios/web/public/ui/context_menu_params.h"
#import "ios/web/test/web_test_with_web_controller.h"
#import "net/base/mac/url_conversions.h"
#import "testing/gtest_mac.h"
#include "testing/platform_test.h"
#import "third_party/ocmock/OCMock/OCMock.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
// A fake of CRWWebStateDelegate to test if the methods in the delegate
// bridge are called normally. Uses BOOLs below to record the calls.
@interface FakeCRWWebStateDelegate : NSObject <CRWWebStateDelegate>
@property(nonatomic) web::WebState* webState;
@property(nonatomic) NSURL* URL;
@property(nonatomic) BOOL contextMenuConfigurationNeeded;
@property(nonatomic) BOOL contextMenuWillPresent;
@property(nonatomic) BOOL contextMenuWillCommitWithAnimator;
@property(nonatomic) BOOL contextMenuDidEnd;
@end
@implementation FakeCRWWebStateDelegate
- (void)webState:(web::WebState*)webState
contextMenuConfigurationForParams:(const web::ContextMenuParams&)params
previewProvider:
(UIContextMenuContentPreviewProvider)previewProvider
completionHandler:
(void (^)(UIContextMenuConfiguration*))completionHandler
API_AVAILABLE(ios(13.0)) {
self.webState = webState;
self.URL = net::NSURLWithGURL(params.link_url);
self.contextMenuConfigurationNeeded = YES;
}
- (void)webState:(web::WebState*)webState
contextMenuWillPresentForLinkWithURL:(const GURL&)linkURL
API_AVAILABLE(ios(13.0)) {
self.webState = webState;
self.URL = net::NSURLWithGURL(linkURL);
self.contextMenuWillPresent = YES;
}
- (void)webState:(web::WebState*)webState
contextMenuForLinkWithURL:(const GURL&)linkURL
willCommitWithAnimator:
(id<UIContextMenuInteractionCommitAnimating>)animator
API_AVAILABLE(ios(13.0)) {
self.webState = webState;
self.URL = net::NSURLWithGURL(linkURL);
self.contextMenuWillCommitWithAnimator = YES;
}
- (void)webState:(web::WebState*)webState
contextMenuDidEndForLinkWithURL:(const GURL&)linkURL
API_AVAILABLE(ios(13.0)) {
self.webState = webState;
self.URL = net::NSURLWithGURL(linkURL);
self.contextMenuDidEnd = YES;
}
@end
namespace web {
// Tests if the iOS 13 context menu delegate methods are correctly called
// via the web state delegate bridge.
class WebStateContextMenuBridgeTest : public web::WebTestWithWebController {
public:
WebStateContextMenuBridgeTest() : web::WebTestWithWebController() {}
FakeCRWWebStateDelegate* MakeFakeCRWWebStateDelegate() {
FakeCRWWebStateDelegate* web_state_delegate =
[[FakeCRWWebStateDelegate alloc] init];
web_state_delegate_bridge_ =
std::make_unique<web::WebStateDelegateBridge>(web_state_delegate);
web_state()->SetDelegate(web_state_delegate_bridge_.get());
return web_state_delegate;
}
private:
std::unique_ptr<web::WebStateDelegateBridge> web_state_delegate_bridge_;
};
TEST_F(WebStateContextMenuBridgeTest, IOS13ContextMenuDelegateBridgeTest) {
if (@available(iOS 13, *)) {
WKWebView* web_view = [web_controller() ensureWebViewCreated];
id<WKUIDelegate> ui_delegate = web_view.UIDelegate;
NSURL* url = [NSURL URLWithString:@"https://google.com/"];
id element_info = OCMClassMock([WKContextMenuElementInfo class]);
[[[element_info stub] andReturn:url] linkURL];
FakeCRWWebStateDelegate* web_state_delegate = MakeFakeCRWWebStateDelegate();
[ui_delegate webView:web_view
contextMenuConfigurationForElement:element_info
completionHandler:^(id){
}];
EXPECT_EQ(web_state(), web_state_delegate.webState);
EXPECT_NSEQ(url, web_state_delegate.URL);
EXPECT_TRUE(web_state_delegate.contextMenuConfigurationNeeded);
EXPECT_FALSE(web_state_delegate.contextMenuDidEnd);
EXPECT_FALSE(web_state_delegate.contextMenuWillCommitWithAnimator);
EXPECT_FALSE(web_state_delegate.contextMenuWillPresent);
web_state_delegate = MakeFakeCRWWebStateDelegate();
[ui_delegate webView:web_view contextMenuDidEndForElement:element_info];
EXPECT_EQ(web_state(), web_state_delegate.webState);
EXPECT_NSEQ(url, web_state_delegate.URL);
EXPECT_FALSE(web_state_delegate.contextMenuConfigurationNeeded);
EXPECT_TRUE(web_state_delegate.contextMenuDidEnd);
EXPECT_FALSE(web_state_delegate.contextMenuWillCommitWithAnimator);
EXPECT_FALSE(web_state_delegate.contextMenuWillPresent);
web_state_delegate = MakeFakeCRWWebStateDelegate();
[ui_delegate webView:web_view
contextMenuForElement:element_info
willCommitWithAnimator:
[OCMockObject
mockForProtocol:@protocol(UIContextMenuInteractionDelegate)]];
EXPECT_EQ(web_state(), web_state_delegate.webState);
EXPECT_NSEQ(url, web_state_delegate.URL);
EXPECT_FALSE(web_state_delegate.contextMenuConfigurationNeeded);
EXPECT_FALSE(web_state_delegate.contextMenuDidEnd);
EXPECT_TRUE(web_state_delegate.contextMenuWillCommitWithAnimator);
EXPECT_FALSE(web_state_delegate.contextMenuWillPresent);
web_state_delegate = MakeFakeCRWWebStateDelegate();
[ui_delegate webView:web_view
contextMenuWillPresentForElement:element_info];
EXPECT_EQ(web_state(), web_state_delegate.webState);
EXPECT_NSEQ(url, web_state_delegate.URL);
EXPECT_FALSE(web_state_delegate.contextMenuConfigurationNeeded);
EXPECT_FALSE(web_state_delegate.contextMenuDidEnd);
EXPECT_FALSE(web_state_delegate.contextMenuWillCommitWithAnimator);
EXPECT_TRUE(web_state_delegate.contextMenuWillPresent);
}
}
} // namespace web