# Copyright 2016 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 or at
# https://developers.google.com/open-source/licenses/bsd

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

import unittest

import webapp2

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)
    self.assertItemsEqual(
        ['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)
    self.assertItemsEqual(
        ['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)
    self.assertItemsEqual(
        ['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)
    self.assertItemsEqual(
        ['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'])
