// Copyright 2018 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/web/web_state/ui/crw_web_view_proxy_impl.h"

#import <UIKit/UIKit.h>

#import "ios/web/web_state/ui/crw_web_controller.h"
#import "testing/gtest/include/gtest/gtest.h"
#import "testing/platform_test.h"
#import "third_party/ocmock/OCMock/OCMock.h"
#import "third_party/ocmock/gtest_support.h"

// The typedef doesn't work with OCMock. Create a real class to be able to mock
// it.
@interface CRWFakeContentView : CRWContentView
@end

@implementation CRWFakeContentView
@synthesize contentOffset = _contentOffset;
@synthesize contentInset = _contentInset;
@synthesize obscuredInsets = _obscuredInsets;
@synthesize scrollView = _scrollView;
@synthesize shouldUseViewContentInset = _shouldUseViewContentInset;

- (BOOL)isViewAlive {
  return YES;
}

- (void)setObscuredInsets:(UIEdgeInsets)obscuredInsets
          initialVelocity:(CGFloat)initialVelocity {
  _obscuredInsets = obscuredInsets;
}

- (void)setMinimumViewportInset:(UIEdgeInsets)minInset
           maximumViewportInset:(UIEdgeInsets)maxInset {
}

@end

namespace {

using CRWWebViewProxyImplTest = PlatformTest;

// Tests that CRWWebViewProxyImpl returns the correct property values from
// the underlying CRWContentView.
TEST_F(CRWWebViewProxyImplTest, ContentViewPresent) {
  CRWWebViewProxyImpl* proxy = [[CRWWebViewProxyImpl alloc] init];
  CRWFakeContentView* fakeContentView = [[CRWFakeContentView alloc] init];
  proxy.contentView = fakeContentView;

  // Content inset.
  const UIEdgeInsets contentInset = UIEdgeInsetsMake(10, 10, 10, 10);
  fakeContentView.contentInset = contentInset;
  EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets(contentInset, proxy.contentInset));

  // Set content inset.
  fakeContentView.contentInset = UIEdgeInsetsZero;
  proxy.contentInset = contentInset;
  EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets(contentInset,
                                            fakeContentView.contentInset));

  // Should use inset.
  fakeContentView.shouldUseViewContentInset = YES;
  EXPECT_TRUE(proxy.shouldUseViewContentInset);

  // Set should use inset.
  fakeContentView.shouldUseViewContentInset = NO;
  proxy.shouldUseViewContentInset = YES;
  EXPECT_TRUE(fakeContentView.shouldUseViewContentInset);
}

// Tests allowsBackForwardNavigationGestures property is delegated to
// CWVWebController.
TEST_F(CRWWebViewProxyImplTest, AllowsBackForwardNavigationGestures) {
  CRWWebController* mockWebController =
      OCMStrictClassMock([CRWWebController class]);
  CRWWebViewProxyImpl* proxy =
      [[CRWWebViewProxyImpl alloc] initWithWebController:mockWebController];

  OCMStub([mockWebController allowsBackForwardNavigationGestures])
      .andReturn(YES);
  EXPECT_TRUE(proxy.allowsBackForwardNavigationGestures);

  OCMExpect([mockWebController setAllowsBackForwardNavigationGestures:YES]);
  proxy.allowsBackForwardNavigationGestures = YES;
  EXPECT_OCMOCK_VERIFY((id)mockWebController);
}

// Tests allowsLinkPreview property is delegated to CWVWebController.
TEST_F(CRWWebViewProxyImplTest, AllowsLinkPreview) {
  CRWWebController* mockWebController =
      OCMStrictClassMock([CRWWebController class]);
  CRWWebViewProxyImpl* proxy =
      [[CRWWebViewProxyImpl alloc] initWithWebController:mockWebController];

  OCMStub([mockWebController allowsLinkPreview]).andReturn(YES);
  EXPECT_TRUE(proxy.allowsLinkPreview);

  OCMExpect([mockWebController setAllowsLinkPreview:YES]);
  proxy.allowsLinkPreview = YES;
  EXPECT_OCMOCK_VERIFY((id)mockWebController);
}

// Tests that setting obscuredInsets has no effect when ignoreObscuredInsets is
// YES.
TEST_F(CRWWebViewProxyImplTest, IgnoreObscuredInsets) {
  CRWWebViewProxyImpl* proxy = [[CRWWebViewProxyImpl alloc] init];
  CRWFakeContentView* fakeContentView = [[CRWFakeContentView alloc] init];
  proxy.contentView = fakeContentView;

  proxy.ignoreObscuredInsets = YES;
  EXPECT_TRUE(proxy.ignoreObscuredInsets);

  const UIEdgeInsets obscuredInsets = UIEdgeInsetsMake(10, 10, 10, 10);
  proxy.obscuredInsets = obscuredInsets;
  EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero,
                                            fakeContentView.obscuredInsets));

  proxy.ignoreObscuredInsets = NO;
  EXPECT_FALSE(proxy.ignoreObscuredInsets);

  proxy.obscuredInsets = obscuredInsets;
  EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets(obscuredInsets,
                                            fakeContentView.obscuredInsets));
}

}  // namespace
