// Copyright 2015 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.

#include "third_party/blink/renderer/modules/notifications/notification_data.h"

#include "base/stl_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/notifications/notification_constants.h"
#include "third_party/blink/renderer/core/testing/null_execution_context.h"
#include "third_party/blink/renderer/modules/notifications/notification.h"
#include "third_party/blink/renderer/modules/notifications/notification_options.h"
#include "third_party/blink/renderer/modules/notifications/timestamp_trigger.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"

#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace blink {
namespace {

const char kNotificationBaseUrl[] = "https://example.com/directory/";
const char kNotificationTitle[] = "My Notification";

const char kNotificationDir[] = "rtl";
const char kNotificationLang[] = "nl";
const char kNotificationBody[] = "Hello, world";
const char kNotificationTag[] = "my_tag";
const char kNotificationEmptyTag[] = "";
const char kNotificationImage[] = "https://example.com/image.jpg";
const char kNotificationIcon[] = "/icon.png";
const char kNotificationIconInvalid[] = "https://invalid:icon:url";
const char kNotificationBadge[] = "badge.png";
const unsigned kNotificationVibration[] = {42, 10, 20, 30, 40};
const uint64_t kNotificationTimestamp = 621046800ull;
const bool kNotificationRenotify = true;
const bool kNotificationSilent = false;
const bool kNotificationRequireInteraction = true;

const mojom::blink::NotificationActionType kBlinkNotificationActionType =
    mojom::blink::NotificationActionType::TEXT;
const char kNotificationActionType[] = "text";
const char kNotificationActionAction[] = "my_action";
const char kNotificationActionTitle[] = "My Action";
const char kNotificationActionIcon[] = "https://example.com/action_icon.png";
const char kNotificationActionPlaceholder[] = "Placeholder...";

const unsigned kNotificationVibrationUnnormalized[] = {10, 1000000, 50, 42};
const int kNotificationVibrationNormalized[] = {10, 10000, 50};

// Execution context that implements the CompleteURL method to complete
// URLs that are assumed to be relative against a given base URL.
class CompleteUrlExecutionContext final : public NullExecutionContext {
 public:
  explicit CompleteUrlExecutionContext(const String& base) : base_(base) {}

 protected:
  ~CompleteUrlExecutionContext() final = default;

  KURL CompleteURL(const String& url) const override {
    return KURL(base_, url);
  }

 private:
  KURL base_;
};

class NotificationDataTest : public testing::Test {
 public:
  void SetUp() override {
    execution_context_ =
        MakeGarbageCollected<CompleteUrlExecutionContext>(kNotificationBaseUrl);
  }

  ExecutionContext* GetExecutionContext() { return execution_context_.Get(); }

 private:
  Persistent<ExecutionContext> execution_context_;
};

TEST_F(NotificationDataTest, ReflectProperties) {
  Vector<unsigned> vibration_pattern;
  for (size_t i = 0; i < base::size(kNotificationVibration); ++i)
    vibration_pattern.push_back(kNotificationVibration[i]);

  UnsignedLongOrUnsignedLongSequence vibration_sequence;
  vibration_sequence.SetUnsignedLongSequence(vibration_pattern);

  HeapVector<Member<NotificationAction>> actions;
  for (size_t i = 0; i < Notification::maxActions(); ++i) {
    NotificationAction* action = NotificationAction::Create();
    action->setType(kNotificationActionType);
    action->setAction(kNotificationActionAction);
    action->setTitle(kNotificationActionTitle);
    action->setIcon(kNotificationActionIcon);
    action->setPlaceholder(kNotificationActionPlaceholder);

    actions.push_back(action);
  }

  DOMTimeStamp showTimestamp = base::Time::Now().ToDoubleT() * 1000.0;
  TimestampTrigger* showTrigger = TimestampTrigger::Create(showTimestamp);

  NotificationOptions* options = NotificationOptions::Create();
  options->setDir(kNotificationDir);
  options->setLang(kNotificationLang);
  options->setBody(kNotificationBody);
  options->setTag(kNotificationTag);
  options->setImage(kNotificationImage);
  options->setIcon(kNotificationIcon);
  options->setBadge(kNotificationBadge);
  options->setVibrate(vibration_sequence);
  options->setTimestamp(kNotificationTimestamp);
  options->setRenotify(kNotificationRenotify);
  options->setSilent(kNotificationSilent);
  options->setRequireInteraction(kNotificationRequireInteraction);
  options->setActions(actions);
  options->setShowTrigger(showTrigger);

  // TODO(peter): Test |options.data| and |notificationData.data|.

  DummyExceptionStateForTesting exception_state;
  mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
      GetExecutionContext(), kNotificationTitle, options, exception_state);
  ASSERT_FALSE(exception_state.HadException());

  EXPECT_EQ(kNotificationTitle, notification_data->title);

  EXPECT_EQ(mojom::blink::NotificationDirection::RIGHT_TO_LEFT,
            notification_data->direction);
  EXPECT_EQ(kNotificationLang, notification_data->lang);
  EXPECT_EQ(kNotificationBody, notification_data->body);
  EXPECT_EQ(kNotificationTag, notification_data->tag);
  EXPECT_EQ(base::Time::FromJsTime(showTimestamp),
            notification_data->show_trigger_timestamp);

  KURL base(kNotificationBaseUrl);

  // URLs should be resolved against the base URL of the execution context.
  EXPECT_EQ(KURL(base, kNotificationImage), notification_data->image);
  EXPECT_EQ(KURL(base, kNotificationIcon), notification_data->icon);
  EXPECT_EQ(KURL(base, kNotificationBadge), notification_data->badge);

  ASSERT_EQ(vibration_pattern.size(),
            notification_data->vibration_pattern->size());
  for (wtf_size_t i = 0; i < vibration_pattern.size(); ++i) {
    EXPECT_EQ(
        vibration_pattern[i],
        static_cast<unsigned>(notification_data->vibration_pattern.value()[i]));
  }

  EXPECT_EQ(kNotificationTimestamp, notification_data->timestamp);
  EXPECT_EQ(kNotificationRenotify, notification_data->renotify);
  EXPECT_EQ(kNotificationSilent, notification_data->silent);
  EXPECT_EQ(kNotificationRequireInteraction,
            notification_data->require_interaction);
  EXPECT_EQ(actions.size(), notification_data->actions->size());
  for (const auto& action : notification_data->actions.value()) {
    EXPECT_EQ(kBlinkNotificationActionType, action->type);
    EXPECT_EQ(kNotificationActionAction, action->action);
    EXPECT_EQ(kNotificationActionTitle, action->title);
    EXPECT_EQ(kNotificationActionPlaceholder, action->placeholder);
  }
}

TEST_F(NotificationDataTest, SilentNotificationWithVibration) {
  Vector<unsigned> vibration_pattern;
  for (size_t i = 0; i < base::size(kNotificationVibration); ++i)
    vibration_pattern.push_back(kNotificationVibration[i]);

  UnsignedLongOrUnsignedLongSequence vibration_sequence;
  vibration_sequence.SetUnsignedLongSequence(vibration_pattern);

  NotificationOptions* options = NotificationOptions::Create();
  options->setVibrate(vibration_sequence);
  options->setSilent(true);

  DummyExceptionStateForTesting exception_state;
  mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
      GetExecutionContext(), kNotificationTitle, options, exception_state);
  ASSERT_TRUE(exception_state.HadException());

  EXPECT_EQ("Silent notifications must not specify vibration patterns.",
            exception_state.Message());
}

TEST_F(NotificationDataTest, ActionTypeButtonWithPlaceholder) {
  HeapVector<Member<NotificationAction>> actions;
  NotificationAction* action = NotificationAction::Create();
  action->setType("button");
  action->setPlaceholder("I'm afraid I can't do that...");
  actions.push_back(action);

  NotificationOptions* options = NotificationOptions::Create();
  options->setActions(actions);

  DummyExceptionStateForTesting exception_state;
  mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
      GetExecutionContext(), kNotificationTitle, options, exception_state);
  ASSERT_TRUE(exception_state.HadException());

  EXPECT_EQ("Notifications of type \"button\" cannot specify a placeholder.",
            exception_state.Message());
}

TEST_F(NotificationDataTest, RenotifyWithEmptyTag) {
  NotificationOptions* options = NotificationOptions::Create();
  options->setTag(kNotificationEmptyTag);
  options->setRenotify(true);

  DummyExceptionStateForTesting exception_state;
  mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
      GetExecutionContext(), kNotificationTitle, options, exception_state);
  ASSERT_TRUE(exception_state.HadException());

  EXPECT_EQ(
      "Notifications which set the renotify flag must specify a non-empty tag.",
      exception_state.Message());
}

TEST_F(NotificationDataTest, InvalidIconUrls) {
  HeapVector<Member<NotificationAction>> actions;
  for (size_t i = 0; i < Notification::maxActions(); ++i) {
    NotificationAction* action = NotificationAction::Create();
    action->setAction(kNotificationActionAction);
    action->setTitle(kNotificationActionTitle);
    action->setIcon(kNotificationIconInvalid);
    actions.push_back(action);
  }

  NotificationOptions* options = NotificationOptions::Create();
  options->setImage(kNotificationIconInvalid);
  options->setIcon(kNotificationIconInvalid);
  options->setBadge(kNotificationIconInvalid);
  options->setActions(actions);

  DummyExceptionStateForTesting exception_state;
  mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
      GetExecutionContext(), kNotificationTitle, options, exception_state);
  ASSERT_FALSE(exception_state.HadException());

  EXPECT_TRUE(notification_data->image.IsEmpty());
  EXPECT_TRUE(notification_data->icon.IsEmpty());
  EXPECT_TRUE(notification_data->badge.IsEmpty());
  for (const auto& action : notification_data->actions.value())
    EXPECT_TRUE(action->icon.IsEmpty());
}

TEST_F(NotificationDataTest, VibrationNormalization) {
  Vector<unsigned> unnormalized_pattern;
  for (size_t i = 0; i < base::size(kNotificationVibrationUnnormalized); ++i)
    unnormalized_pattern.push_back(kNotificationVibrationUnnormalized[i]);

  UnsignedLongOrUnsignedLongSequence vibration_sequence;
  vibration_sequence.SetUnsignedLongSequence(unnormalized_pattern);

  NotificationOptions* options = NotificationOptions::Create();
  options->setVibrate(vibration_sequence);

  DummyExceptionStateForTesting exception_state;
  mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
      GetExecutionContext(), kNotificationTitle, options, exception_state);
  EXPECT_FALSE(exception_state.HadException());

  Vector<int> normalized_pattern;
  for (size_t i = 0; i < base::size(kNotificationVibrationNormalized); ++i)
    normalized_pattern.push_back(kNotificationVibrationNormalized[i]);

  ASSERT_EQ(normalized_pattern.size(),
            notification_data->vibration_pattern->size());
  for (wtf_size_t i = 0; i < normalized_pattern.size(); ++i) {
    EXPECT_EQ(normalized_pattern[i],
              notification_data->vibration_pattern.value()[i]);
  }
}

TEST_F(NotificationDataTest, DefaultTimestampValue) {
  NotificationOptions* options = NotificationOptions::Create();

  DummyExceptionStateForTesting exception_state;
  mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
      GetExecutionContext(), kNotificationTitle, options, exception_state);
  EXPECT_FALSE(exception_state.HadException());

  // The timestamp should be set to the current time since the epoch if it
  // wasn't supplied by the developer. "32" has no significance, but an equal
  // comparison of the value could lead to flaky failures.
  EXPECT_NEAR(notification_data->timestamp,
              base::Time::Now().ToDoubleT() * 1000.0, 32);
}

TEST_F(NotificationDataTest, DirectionValues) {
  WTF::HashMap<String, mojom::blink::NotificationDirection> mappings;
  mappings.insert("ltr", mojom::blink::NotificationDirection::LEFT_TO_RIGHT);
  mappings.insert("rtl", mojom::blink::NotificationDirection::RIGHT_TO_LEFT);
  mappings.insert("auto", mojom::blink::NotificationDirection::AUTO);

  // Invalid values should default to "auto".
  mappings.insert("peter", mojom::blink::NotificationDirection::AUTO);

  for (const String& direction : mappings.Keys()) {
    NotificationOptions* options = NotificationOptions::Create();
    options->setDir(direction);

    DummyExceptionStateForTesting exception_state;
    mojom::blink::NotificationDataPtr notification_data =
        CreateNotificationData(GetExecutionContext(), kNotificationTitle,
                               options, exception_state);
    ASSERT_FALSE(exception_state.HadException());

    EXPECT_EQ(mappings.at(direction), notification_data->direction);
  }
}

TEST_F(NotificationDataTest, MaximumActionCount) {
  HeapVector<Member<NotificationAction>> actions;
  for (size_t i = 0; i < Notification::maxActions() + 2; ++i) {
    NotificationAction* action = NotificationAction::Create();
    action->setAction(String::Number(i));
    action->setTitle(kNotificationActionTitle);

    actions.push_back(action);
  }

  NotificationOptions* options = NotificationOptions::Create();
  options->setActions(actions);

  DummyExceptionStateForTesting exception_state;
  mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
      GetExecutionContext(), kNotificationTitle, options, exception_state);
  ASSERT_FALSE(exception_state.HadException());

  // The stored actions will be capped to |maxActions| entries.
  ASSERT_EQ(Notification::maxActions(), notification_data->actions->size());

  for (wtf_size_t i = 0; i < Notification::maxActions(); ++i) {
    String expected_action = String::Number(i);
    EXPECT_EQ(expected_action, notification_data->actions.value()[i]->action);
  }
}

TEST_F(NotificationDataTest, RejectsTriggerTimestampOverAYear) {
  base::Time show_timestamp = base::Time::Now() +
                              kMaxNotificationShowTriggerDelay +
                              base::TimeDelta::FromDays(1);
  TimestampTrigger* show_trigger =
      TimestampTrigger::Create(show_timestamp.ToJsTime());

  NotificationOptions* options = NotificationOptions::Create();
  options->setShowTrigger(show_trigger);

  DummyExceptionStateForTesting exception_state;
  mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
      GetExecutionContext(), kNotificationTitle, options, exception_state);
  ASSERT_TRUE(exception_state.HadException());

  EXPECT_EQ("Notification trigger timestamp too far ahead in the future.",
            exception_state.Message());
}

}  // namespace
}  // namespace blink
