# Copyright 2016 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unit tests for the moved project notification page servlet."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import six
import unittest

from framework import exceptions
from services import service_manager
from sitewide import moved
from testing import fake
from testing import testing_helpers


class MovedTest(unittest.TestCase):

  def setUp(self):
    self.services = service_manager.Services(
        project=fake.ProjectService())
    self.servlet = moved.ProjectMoved(services=self.services)
    self.old_project = 'old-project'

  def testGatherPageData_NoProjectSpecified(self):
    # Project was not included in URL, so raise exception, will cause 400.
    _, mr = testing_helpers.GetRequestObjects(
        path='/hosting/moved')

    with self.assertRaises(exceptions.InputException):
      self.servlet.GatherPageData(mr)

  def testGatherPageData_NoSuchProject(self):
    # Project doesn't exist, so 404 NOT FOUND.
    _, mr = testing_helpers.GetRequestObjects(
        path='/hosting/moved?project=nonexistent')

    with self.assertRaises(Exception) as cm:
      self.servlet.GatherPageData(mr)
    self.assertEqual(404, cm.exception.code)

  def testGatherPageData_NotMoved(self):
    # Project exists but has not been moved, so 400 BAD_REQUEST.
    self.services.project.TestAddProject(self.old_project)
    _, mr = testing_helpers.GetRequestObjects(
        path='/hosting/moved?project=%s' % self.old_project)

    with self.assertRaises(Exception) as cm:
      self.servlet.GatherPageData(mr)
    self.assertEqual(400, cm.exception.code)

  def testGatherPageData_URL(self):
    # Display the moved_to url if it is valid.
    project = self.services.project.TestAddProject(self.old_project)
    project.moved_to = 'https://other-tracker.bugs'
    _, mr = testing_helpers.GetRequestObjects(
        path='/hosting/moved?project=%s' % self.old_project)

    page_data = self.servlet.GatherPageData(mr)
    six.assertCountEqual(
        self, ['project_name', 'moved_to_url'], list(page_data.keys()))
    self.assertEqual(self.old_project, page_data['project_name'])
    self.assertEqual('https://other-tracker.bugs', page_data['moved_to_url'])

  def testGatherPageData_ProjectName(self):
    # Construct the moved-to url from just the project name.
    project = self.services.project.TestAddProject(self.old_project)
    project.moved_to = 'new-project'
    _, mr = testing_helpers.GetRequestObjects(
        path='/hosting/moved?project=%s' % self.old_project)

    page_data = self.servlet.GatherPageData(mr)
    six.assertCountEqual(
        self, ['project_name', 'moved_to_url'], list(page_data.keys()))
    self.assertEqual(self.old_project, page_data['project_name'])
    self.assertEqual('http://127.0.0.1/p/new-project/',
                     page_data['moved_to_url'])

  def testGatherPageData_HttpProjectName(self):
    # A project named "http-foo" gets treated as a project, not a url.
    project = self.services.project.TestAddProject(self.old_project)
    project.moved_to = 'http-project'
    _, mr = testing_helpers.GetRequestObjects(
        path='/hosting/moved?project=%s' % self.old_project)

    page_data = self.servlet.GatherPageData(mr)
    six.assertCountEqual(
        self, ['project_name', 'moved_to_url'], list(page_data.keys()))
    self.assertEqual(self.old_project, page_data['project_name'])
    self.assertEqual('http://127.0.0.1/p/http-project/',
                     page_data['moved_to_url'])

  def testGatherPageData_BadScheme(self):
    # We only display URLs that start with 'http(s)://'.
    project = self.services.project.TestAddProject(self.old_project)
    project.moved_to = 'javascript:alert(1)'
    _, mr = testing_helpers.GetRequestObjects(
        path='/hosting/moved?project=%s' % self.old_project)

    page_data = self.servlet.GatherPageData(mr)
    six.assertCountEqual(
        self, ['project_name', 'moved_to_url'], list(page_data.keys()))
    self.assertEqual(self.old_project, page_data['project_name'])
    self.assertEqual('#invalid-destination-url', page_data['moved_to_url'])
