// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/overlays/ui_bundled/overlay_container_view_controller.h"
#import "ios/chrome/browser/overlays/model/public/overlay_request.h"
#import "ios/chrome/browser/overlays/model/public/test_modality/test_presented_overlay_request_config.h"
#import "ios/chrome/browser/overlays/model/public/test_modality/test_resizing_presented_overlay_request_config.h"
#import "ios/chrome/browser/shared/model/browser/test/test_browser.h"
#import "ios/chrome/browser/overlays/ui_bundled/overlay_presentation_context_impl.h"
#import "ios/chrome/browser/overlays/ui_bundled/test/fake_overlay_request_coordinator_delegate.h"
#import "ios/chrome/browser/overlays/ui_bundled/test_modality/test_presented_overlay_coordinator.h"
#import "ios/chrome/browser/overlays/ui_bundled/test_modality/test_resizing_presented_overlay_coordinator.h"
#import "ios/chrome/test/scoped_key_window.h"
#import "ios/web/public/test/web_task_environment.h"
#import "testing/platform_test.h"
#import "third_party/ocmock/OCMock/OCMock.h"
#import "third_party/ocmock/gtest_support.h"
// Test fixture for OverlayContainerViewController.
class OverlayContainerViewControllerTest : public PlatformTest {
public:
OverlayContainerViewControllerTest()
: root_view_controller_([[UIViewController alloc] init]),
delegate_(OCMStrictProtocolMock(
@protocol(OverlayContainerViewControllerDelegate))),
view_controller_([[OverlayContainerViewController alloc] init]) {
scoped_window_.Get().rootViewController = root_view_controller_;
view_controller_.delegate = delegate_;
}
~OverlayContainerViewControllerTest() override {
EXPECT_OCMOCK_VERIFY(delegate_);
}
protected:
ScopedKeyWindow scoped_window_;
UIViewController* root_view_controller_ = nil;
id<OverlayContainerViewControllerDelegate> delegate_ = nil;
OverlayContainerViewController* view_controller_ = nil;
};
// Verifies that the view controller notifies its delegate when its view's
// window is changed.
TEST_F(OverlayContainerViewControllerTest, MoveToWindow) {
OCMExpect([delegate_ containerViewController:view_controller_
didMoveToWindow:scoped_window_.Get()]);
[root_view_controller_.view addSubview:view_controller_.view];
OCMExpect([delegate_ containerViewController:view_controller_
didMoveToWindow:nil]);
[view_controller_.view removeFromSuperview];
}
// Verifies that the container view ignores touches that fall outside of any
// subviews.
TEST_F(OverlayContainerViewControllerTest, TouchHandling) {
// The container view will be laid out with `frame`. A subview will be added
// to the view and laid out `subview_inset` from the edges of the view.
CGRect frame = CGRectMake(0.0, 0.0, 100.0, 100.0);
CGFloat subview_inset = 25.0;
CGRect subview_frame = CGRectInset(frame, subview_inset, subview_inset);
// `center` is the center of the container view, which will land in the center
// of the added subview. `corner` is a point halfway between the container
// view's origin and the subview's origin.
CGPoint center = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame));
CGPoint corner = CGPointMake(subview_inset / 2.0, subview_inset / 2.0);
// Set up the view hierarchy using the calculated frames.
UIView* view = view_controller_.view;
view.frame = frame;
UIView* subview = [[UIView alloc] initWithFrame:subview_frame];
[view addSubview:subview];
// Verify that touches are ignored when they fall outside of any subview.
EXPECT_FALSE([view hitTest:corner withEvent:nil]);
EXPECT_FALSE([view pointInside:corner withEvent:nil]);
// Verify that touches are handled and forwarded to `subview` when falling
// inside `subview`'s bounds.
EXPECT_EQ([view hitTest:center withEvent:nil], subview);
EXPECT_TRUE([view pointInside:center withEvent:nil]);
// Remove the subview and verify that touches in the center are ignored.
[subview removeFromSuperview];
EXPECT_FALSE([view hitTest:center withEvent:nil]);
EXPECT_FALSE([view pointInside:center withEvent:nil]);
}