# -*- coding: utf-8 -*-

#       Licensed to the Apache Software Foundation (ASF) under one
#       or more contributor license agreements.  See the NOTICE file
#       distributed with this work for additional information
#       regarding copyright ownership.  The ASF licenses this file
#       to you under the Apache License, Version 2.0 (the
#       "License"); you may not use this file except in compliance
#       with the License.  You may obtain a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#       Unless required by applicable law or agreed to in writing,
#       software distributed under the License is distributed on an
#       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#       KIND, either express or implied.  See the License for the
#       specific language governing permissions and limitations
#       under the License.

import urllib
import os
import time
import json
import StringIO
import allura
import mock

import PIL
from mock import patch
from nose.tools import assert_true, assert_false, assert_equal, assert_in
from nose.tools import assert_raises, assert_not_in, assert_items_equal
from formencode.variabledecode import variable_encode
from pylons import tmpl_context as c
from pylons import app_globals as g

from alluratest.controller import TestController, setup_basic_test
from allura import model as M
from forgewiki import model as wm
from forgetracker import model as tm

from allura.lib.security import has_access
from allura.lib import helpers as h
from allura.lib.search import SearchError
from allura.tests import decorators as td
from allura.tasks import mail_tasks
from ming.orm.ormsession import ThreadLocalORMSession


class TrackerTestController(TestController):

    def setUp(self):
        super(TrackerTestController, self).setUp()
        self.setup_with_tools()

    @td.with_tracker
    def setup_with_tools(self):
        pass

    def new_ticket(self, mount_point='/bugs/', extra_environ=None, **kw):
        extra_environ = extra_environ or {}
        response = self.app.get(mount_point + 'new/',
                                extra_environ=extra_environ)
        form = response.forms[1]
        # If this is ProjectUserCombo's select populate it
        # with all the users in the project. This is a workaround for tests,
        # in real enviroment this is populated via ajax.
        p = M.Project.query.get(shortname='test')
        for f in form.fields:
            field = form[f] if f else None
            is_usercombo = (field and field.tag == 'select' and
                            field.attrs.get('class') == 'project-user-combobox')
            if is_usercombo:
                field.options = [('', False)] + [(u.username, False)
                                                 for u in p.users()]

        for k, v in kw.iteritems():
            form['ticket_form.%s' % k] = v
        resp = form.submit()
        assert resp.status_int != 200, resp
        return resp


class TestMilestones(TrackerTestController):

    def test_milestone_list(self):
        r = self.app.get('/bugs/milestones')
        assert '1.0' in r, r.showbrowser()

    def test_milestone_list_progress(self):
        self.new_ticket(summary='foo', _milestone='1.0')
        self.new_ticket(summary='bar', _milestone='1.0', status='closed')
        r = self.app.get('/bugs/milestones')
        assert '1 / 2' in r, r.showbrowser()

    def test_default_milestone_created_if_missing(self):
        p = M.Project.query.get(shortname='test')
        app = p.app_instance('bugs')
        app.globals.custom_fields = []
        ThreadLocalORMSession.flush_all()
        d = {
            'field_name': '_milestone',
            'milestones-0.old_name': '',
            'milestones-0.new_name': '1.0',
            'milestones-0.description': 'Version 1',
            'milestones-0.complete': 'Open',
            'milestones-0.due_date': ''
        }
        r = self.app.post('/bugs/update_milestones', d)
        r = self.app.get('/bugs/milestones')
        assert 'Version 1' in r
        # make sure _milestone doesn't get created again if it already exists
        r = self.app.post('/bugs/update_milestones', d)
        p = M.Project.query.get(shortname='test')
        app = p.app_instance('bugs')
        assert len(app.globals.custom_fields) == 1, len(
            app.globals.custom_fields)

    def test_closed_milestone(self):
        self.new_ticket(summary='bar', _milestone='1.0', status='closed')
        d = {
            'field_name': '_milestone',
            'milestones-0.old_name': '1.0',
            'milestones-0.new_name': '1.0',
            'milestones-0.description': '',
            'milestones-0.complete': 'Closed',
            'milestones-0.due_date': ''
        }
        self.app.post('/bugs/update_milestones', d)
        d = {
            'field_name': '_milestone',
            'milestones-9.old_name': '',
            'milestones-9.new_name': '3.0',
            'milestones-9.description': '',
            'milestones-9.complete': 'Closed',
            'milestones-9.due_date': ''
        }
        self.app.post('/bugs/update_milestones', d)
        d = {
            'field_name': '_milestone',
            'milestones-9.old_name': '',
            'milestones-9.new_name': '4.0',
            'milestones-9.description': '',
            'milestones-9.complete': 'Closed',
            'milestones-9.due_date': ''
        }
        self.app.post('/bugs/update_milestones', d)
        r = self.app.get('/bugs/1/')
        closed = r.html.find('optgroup', label='Closed')
        assert closed
        closed = str(closed)
        assert '<option selected value="1.0">1.0</option>' in r
        assert '<option selected value="1.0">1.0</option>' not in closed
        assert '<option value="2.0">2.0</option>' in r
        assert '<option value="2.0">2.0</option>' not in closed
        assert '<option value="3.0">3.0</option>' in closed
        assert '<option value="4.0">4.0</option>' in closed
        r = self.app.get('/bugs/new/')
        closed = r.html.find('optgroup', label='Closed')
        assert closed
        closed = str(closed)
        assert '<option selected value="1.0">1.0</option>' not in r
        assert '<option value="1.0">1.0</option>' in closed
        assert '<option value="2.0">2.0</option>' in r
        assert '<option value="2.0">2.0</option>' not in closed
        assert '<option value="3.0">3.0</option>' in closed
        assert '<option value="4.0">4.0</option>' in closed

    def test_duplicate_milestone(self):
        self.new_ticket(summary='bar', _milestone='1.0', status='closed')
        d = {
            'field_name': '_milestone',
            'milestones-0.old_name': '',
            'milestones-0.new_name': '1.0',
            'milestones-0.description': '',
            'milestones-0.complete': 'Closed',
            'milestones-0.due_date': ''
        }
        r = self.app.post('/bugs/update_milestones', d)
        assert 'error' in self.webflash(r)

        p = M.Project.query.get(shortname='test')
        app = p.app_instance('bugs')
        assert len(app.globals.milestone_fields[0]['milestones']) == 2

        d = {
            'field_name': '_milestone',
            'milestones-0.old_name': '2.0',
            'milestones-0.new_name': '1.0',
            'milestones-0.description': '',
            'milestones-0.complete': 'Closed',
            'milestones-0.due_date': ''
        }
        r = self.app.post('/bugs/update_milestones', d)
        assert 'error' in self.webflash(r)
        assert app.globals.milestone_fields[0][
            'milestones'][1]['name'] == '2.0'

    def test_default_milestone(self):
        self.new_ticket(summary='bar', _milestone='1.0', status='closed')
        d = {
            'field_name': '_milestone',
            'milestones-0.old_name': '2.0',
            'milestones-0.new_name': '2.0',
            'milestones-0.description': '',
            'milestones-0.complete': 'Open',
            'milestones-0.default': 'on',
            'milestones-0.due_date': ''
        }
        self.app.post('/bugs/update_milestones', d)
        r = self.app.get('/bugs/new/')
        assert '<option selected value="2.0">2.0</option>' in r


def post_install_create_ticket_permission(app):
    """Set to authenticated permission to create tickets but not update"""
    role = M.ProjectRole.by_name('*authenticated')._id
    create_permission = M.ACE.allow(role, 'create')
    update_permission = M.ACE.allow(role, 'update')
    acl = app.config.acl
    acl.append(create_permission)
    if update_permission in acl:
        acl.remove(update_permission)


def post_install_update_ticket_permission(app):
    """Set to anonymous permission to create and update tickets"""
    role = M.ProjectRole.by_name('*anonymous')._id
    app.config.acl.append(M.ACE.allow(role, 'create'))
    app.config.acl.append(M.ACE.allow(role, 'update'))


class TestSubprojectTrackerController(TrackerTestController):

    @td.with_tool('test/sub1', 'Tickets', 'tickets')
    def test_index_page_ticket_visibility(self):
        """Test that non-admin users can see tickets created by admins."""
        self.new_ticket(summary="my ticket", mount_point="/sub1/tickets/")
        response = self.app.get('/p/test/sub1/tickets/',
                                extra_environ=dict(username='*anonymous'))
        assert 'my ticket' in response

    @td.with_tool('test/sub1', 'Tickets', 'tickets')
    def test_search_page_ticket_visibility(self):
        """Test that non-admin users can see tickets created by admins."""
        self.new_ticket(summary="my ticket", mount_point="/sub1/tickets/")
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        response = self.app.get('/p/test/sub1/tickets/search/?q=my',
                                extra_environ=dict(username='*anonymous'))
        assert 'my ticket' in response, response.showbrowser()

    @td.with_tool('test/sub1', 'Tickets', 'tickets')
    def test_deleted_ticket_visibility(self):
        """Test that admins can see deleted tickets in a subproject tracker."""
        self.new_ticket(summary='test', mount_point="/sub1/tickets/")
        self.app.post('/sub1/tickets/1/delete')
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        r = self.app.get('/p/test/sub1/tickets/search/',
                         params=dict(q='test', deleted='True'))
        assert '<td><a href="/p/test/sub1/tickets/1/">test' in r
        assert '<tr class=" deleted">' in r


class TestFunctionalController(TrackerTestController):

    def test_bad_ticket_number(self):
        self.app.get('/bugs/input.project_user_select', status=404)

    def test_invalid_ticket(self):
        self.app.get('/bugs/2/', status=404)

    @patch('forgetracker.tracker_main.g.director.create_activity')
    def test_activity(self, create_activity):
        self.new_ticket(summary='my ticket', description='my description')
        assert create_activity.call_count == 1
        assert create_activity.call_args[0][1] == 'created'
        create_activity.reset_mock()
        self.app.post('/bugs/1/update_ticket', {
            'summary': 'my ticket',
            'description': 'new description',
        })
        assert create_activity.call_count == 1
        assert create_activity.call_args[0][1] == 'modified'

    def test_new_ticket(self):
        summary = 'test new ticket'
        ticket_view = self.new_ticket(summary=summary).follow()
        assert_true(summary in ticket_view)
        assert 'class="artifact_subscribe' in ticket_view

    def test_labels(self):
        ticket_view = self.new_ticket(summary='summary', labels="test label").follow()
        assert '''<a href="../search?q=labels:%22test+label%22">test label (1)</a>''' in ticket_view

    def test_new_with_milestone(self):
        ticket_view = self.new_ticket(
            summary='test new with milestone', **{'_milestone': '1.0'}).follow()
        assert 'Milestone' in ticket_view
        assert '1.0' in ticket_view

    def test_milestone_count(self):
        self.new_ticket(summary='test new with milestone',
                        **{'_milestone': '1.0'})
        self.new_ticket(
            summary='test new with milestone', **{'_milestone': '1.0',
                                                  'private': '1'})
        r = self.app.get('/bugs/milestone_counts')
        counts = {
            'milestone_counts': [
                {'name': '1.0', 'count': 2},
                {'name': '2.0', 'count': 0}
            ]}
        assert_equal(r.body, json.dumps(counts))
        # Private tickets shouldn't be included in counts if user doesn't
        # have read access to private tickets.
        r = self.app.get('/bugs/milestone_counts',
                         extra_environ=dict(username='*anonymous'))
        counts['milestone_counts'][0]['count'] = 1
        assert_equal(r.body, json.dumps(counts))

        self.app.post('/bugs/1/delete')
        r = self.app.get('/bugs/milestone_counts')
        assert_equal(r.body, json.dumps(counts))

    def test_milestone_progress(self):
        self.new_ticket(summary='Ticket 1', **{'_milestone': '1.0'})
        self.new_ticket(summary='Ticket 2', **{'_milestone': '1.0',
                                               'status': 'closed',
                                               'private': '1'}).follow()
        r = self.app.get('/bugs/milestone/1.0/')
        assert '1 / 2' in r
        # Private tickets shouldn't be included in counts if user doesn't
        # have read access to private tickets.
        r = self.app.get('/bugs/milestone/1.0/',
                         extra_environ=dict(username='*anonymous'))
        assert '0 / 1' in r

    def test_new_ticket_form(self):
        response = self.app.get('/bugs/new/')
        form = response.forms[1]
        form['ticket_form.summary'] = 'test new ticket form'
        form['ticket_form.description'] = 'test new ticket form description'
        response = form.submit().follow()
        assert 'test new ticket form' in response
        assert 'test new ticket form description' in response

    def test_mass_edit(self):
        ticket_view = self.new_ticket(summary='First Ticket').follow()
        ticket_view = self.new_ticket(summary='Second Ticket').follow()
        M.MonQTask.run_ready()
        first_ticket = tm.Ticket.query.find({
            'summary': 'First Ticket'}).first()
        second_ticket = tm.Ticket.query.find({
            'summary': 'Second Ticket'}).first()
        r = self.app.get('/p/test/bugs/edit/?q=ticket')
        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': [first_ticket._id],
                      '_milestone': '2.0',
                      })
        M.MonQTask.run_ready()
        r = self.app.get('/p/test/bugs/1/')
        assert '<li><strong>Milestone</strong>: 1.0 --&gt; 2.0</li>' in r
        r = self.app.get('/p/test/bugs/2/')
        assert '<li><strong>Milestone</strong>: 1.0 --&gt; 2.0</li>' not in r
        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': (
                          first_ticket._id,
                          second_ticket._id),
                      '_milestone': '1.0',
                      })
        M.MonQTask.run_ready()
        r = self.app.get('/p/test/bugs/1/')
        assert '<li><strong>Milestone</strong>: 2.0 --&gt; 1.0</li>' in r
        r = self.app.get('/p/test/bugs/2/')
        assert '<li><strong>Milestone</strong>: 2.0 --&gt; 1.0</li>' not in r

        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': (
                          first_ticket._id,
                          second_ticket._id),
                      'status': 'accepted',
                      })
        M.MonQTask.run_ready()
        r = self.app.get('/p/test/bugs/1/')
        assert '<li><strong>Status</strong>: open --&gt; accepted</li>' in r
        r = self.app.get('/p/test/bugs/2/')
        assert '<li><strong>Status</strong>: open --&gt; accepted</li>' in r

    def test_label_for_mass_edit(self):
        self.new_ticket(summary='Ticket1')
        self.new_ticket(summary='Ticket2', labels='tag1')
        self.new_ticket(summary='Ticket3', labels='tag1,tag2')
        M.MonQTask.run_ready()
        ticket1 = tm.Ticket.query.get(summary='Ticket1')
        ticket2 = tm.Ticket.query.get(summary='Ticket2')
        ticket3 = tm.Ticket.query.get(summary='Ticket3')
        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': (
                          ticket1._id,
                          ticket2._id,
                          ticket3._id),
                      'labels': 'tag2, tag3',
                      })
        M.MonQTask.run_ready()

        ticket1 = tm.Ticket.query.get(summary='Ticket1')
        ticket2 = tm.Ticket.query.get(summary='Ticket2')
        ticket3 = tm.Ticket.query.get(summary='Ticket3')
        assert_equal(ticket1.labels, ['tag2', 'tag3'])
        assert_equal(ticket2.labels, ['tag1', 'tag2', 'tag3'])
        assert_equal(ticket3.labels, ['tag1', 'tag2', 'tag3'])
        r = self.app.get('/p/test/bugs/3/')
        assert '<li><strong>Labels</strong>: tag1, tag2 --&gt; tag1, tag2, tag3</li>' in r

    def test_mass_edit_custom_fields(self):
        params = dict(
            custom_fields=[
                dict(name='_major', label='Major', type='boolean'), ],
            open_status_names='aa bb',
            closed_status_names='cc',
        )
        self.app.post(
            '/admin/bugs/set_custom_fields',
            params=variable_encode(params))
        kw = {'custom_fields._major': True}
        self.new_ticket(summary='First Custom', **kw)
        self.new_ticket(summary='Second Custom')
        M.MonQTask.run_ready()

        ticket1 = tm.Ticket.query.find({
            'summary': 'First Custom'}).first()
        ticket2 = tm.Ticket.query.find({
            'summary': 'Second Custom'}).first()
        ticket2.custom_fields._major = None
        ticket2.commit()
        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': (
                          ticket1._id,
                          ticket2._id,),
                      'status': 'accepted',
                      '_major': 'False'
                      })
        M.MonQTask.run_ready()
        r = self.app.get('/p/test/bugs/1/')
        assert '<li><strong>Major</strong>: True --&gt; False</li>' in r
        r = self.app.get('/p/test/bugs/2/')
        assert '<li><strong>Major</strong>: --&gt; False</li>' in r
        ticket1 = tm.Ticket.query.find({
            'summary': 'First Custom'}).first()
        ticket2 = tm.Ticket.query.find({
            'summary': 'Second Custom'}).first()
        assert_equal(ticket1.custom_fields._major, False)
        assert_equal(ticket2.custom_fields._major, False)

        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': (
                          ticket1._id,
                          ticket2._id,),
                      'status': 'accepted',
                      '_major': 'True'
                      })
        M.MonQTask.run_ready()
        r = self.app.get('/p/test/bugs/1/')
        assert '<li><strong>Major</strong>: False --&gt; True</li>' in r
        r = self.app.get('/p/test/bugs/2/')
        assert '<li><strong>Major</strong>: False --&gt; True</li>' in r
        ticket1 = tm.Ticket.query.find({
            'summary': 'First Custom'}).first()
        ticket2 = tm.Ticket.query.find({
            'summary': 'Second Custom'}).first()
        assert_equal(ticket1.custom_fields._major, True)
        assert_equal(ticket2.custom_fields._major, True)

        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': (
                          ticket2._id,),
                      '_major': 'False'
                      })
        M.MonQTask.run_ready()
        ticket2 = tm.Ticket.query.find({
            'summary': 'Second Custom'}).first()
        assert_equal(ticket2.custom_fields._major, False)
        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': (
                          ticket1._id,
                          ticket2._id,),
                      'status': 'accepted',
                      '_major': ''
                      })
        M.MonQTask.run_ready()
        ticket1 = tm.Ticket.query.find({
            'summary': 'First Custom'}).first()
        ticket2 = tm.Ticket.query.find({
            'summary': 'Second Custom'}).first()
        assert_equal(ticket1.custom_fields._major, True)
        assert_equal(ticket2.custom_fields._major, False)

    def test_mass_edit_private_field(self):
        kw = {'private': True}
        self.new_ticket(summary='First', **kw)
        self.new_ticket(summary='Second')
        M.MonQTask.run_ready()
        ticket1 = tm.Ticket.query.find({
            'summary': 'First'}).first()
        ticket2 = tm.Ticket.query.find({
            'summary': 'Second'}).first()
        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': (
                          ticket1._id,
                          ticket2._id,),
                      'private': False
                      })
        M.MonQTask.run_ready()
        r = self.app.get('/p/test/bugs/1/')
        assert '<li><strong>Private</strong>: Yes --&gt; No</li>' in r
        r = self.app.get('/p/test/bugs/2/')
        assert '<li><strong>Private</strong>: No --&gt; Yes</li>' not in r
        ticket1 = tm.Ticket.query.find({
            'summary': 'First'}).first()
        ticket2 = tm.Ticket.query.find({
            'summary': 'Second'}).first()
        assert_equal(ticket1.private, False)
        assert_equal(ticket2.private, False)

        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': (
                          ticket1._id,
                          ticket2._id,),
                      'private': True
                      })
        M.MonQTask.run_ready()
        r = self.app.get('/p/test/bugs/1/')
        assert '<li><strong>Private</strong>: No --&gt; Yes</li>' in r
        r = self.app.get('/p/test/bugs/2/')
        assert '<li><strong>Private</strong>: No --&gt; Yes</li>' in r
        ticket1 = tm.Ticket.query.find({
            'summary': 'First'}).first()
        ticket2 = tm.Ticket.query.find({
            'summary': 'Second'}).first()
        assert_equal(ticket1.private, True)
        assert_equal(ticket2.private, True)

        ticket2.private = False
        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': (
                          ticket1._id,
                          ticket2._id,),
                      'private': ''
                      })
        M.MonQTask.run_ready()
        ticket1 = tm.Ticket.query.find({
            'summary': 'First'}).first()
        ticket2 = tm.Ticket.query.find({
            'summary': 'Second'}).first()
        assert_equal(ticket1.private, True)
        assert_equal(ticket2.private, False)

    def test_private_ticket(self):
        ticket_view = self.new_ticket(summary='Public Ticket').follow()
        assert_true('<label class="simple">Private:</label> No' in ticket_view)
        ticket_view = self.new_ticket(summary='Private Ticket',
                                      private=True).follow()
        assert_true(
            '<label class="simple">Private:</label> Yes' in ticket_view)
        M.MonQTask.run_ready()
        # Creator sees private ticket on list page...
        index_response = self.app.get('/p/test/bugs/')
        assert '2 results' in index_response
        assert 'Public Ticket' in index_response
        assert 'Private Ticket' in index_response
        # ...and in search results.
        search_response = self.app.get('/p/test/bugs/search/?q=ticket')
        assert '2 results' in search_response
        assert 'Private Ticket' in search_response
        # Unauthorized user doesn't see private ticket on list page...
        env = dict(username='*anonymous')
        r = self.app.get('/p/test/bugs/', extra_environ=env)
        assert '1 results' in r
        assert 'Private Ticket' not in r
        # ...or in search results...
        r = self.app.get('/p/test/bugs/search/?q=ticket', extra_environ=env)
        assert '1 results' in r
        assert 'Private Ticket' not in r
        # ... or in search feed...
        r = self.app.get('/p/test/bugs/search_feed?q=ticket',
                         extra_environ=env)
        assert 'Private Ticket' not in r
        # ...and can't get to the private ticket directly.
        r = self.app.get(ticket_view.request.url, extra_environ=env)
        assert 'Private Ticket' not in r
        # ... and it doesn't appear in the feed
        r = self.app.get('/p/test/bugs/feed.atom', extra_environ=env)
        assert 'Private Ticket' not in r
        # ... or in the API ...
        r = self.app.get('/rest/p/test/bugs/2/', extra_environ=env, status=401)
        r = self.app.get('/rest/p/test/bugs/', extra_environ=env)
        assert 'Private Ticket' not in r

        # update private ticket
        self.app.post('/bugs/1/update_ticket_from_widget', {
            'ticket_form.summary': 'Public Ticket',
            'ticket_form.description': '',
            'ticket_form.status': 'open',
            'ticket_form._milestone': '1.0',
            'ticket_form.assigned_to': '',
            'ticket_form.labels': '',
            'ticket_form.comment': 'gotta be secret about this now',
            'ticket_form.private': 'on',
        })
        response = self.app.get('/bugs/1/')
        assert_true(
            '<li><strong>private</strong>: No --&gt; Yes</li>' in response)

    @td.with_tool('test', 'Tickets', 'doc-bugs')
    def test_two_trackers(self):
        summary = 'test two trackers'
        ticket_view = self.new_ticket(
            '/doc-bugs/', summary=summary, _milestone='1.0').follow()
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        assert_true(summary in ticket_view)
        index_view = self.app.get('/doc-bugs/')
        assert_true(summary in index_view)
        assert_true(sidebar_contains(index_view, '<span>1.0</span>'))
        index_view = self.app.get('/bugs/')
        assert_true(sidebar_contains(index_view, '<span>1.0</span>'))
        assert_false(summary in index_view)

    def test_render_ticket(self):
        summary = 'test render ticket'
        ticket_view = self.new_ticket(summary=summary).follow()
        ticket_view.mustcontain(summary, 'Discussion')

    def test_render_index(self):
        admin = M.User.query.get(username='test-admin')
        anon = M.User.query.get(username="*anonymous")
        for app in M.AppConfig.query.find({'options.mount_point': 'bugs'}):
            assert has_access(app, 'create', admin)
            assert not has_access(app, 'create', anon)

        index_view = self.app.get('/bugs/')
        assert 'No open tickets found.' in index_view
        assert 'Create Ticket' in index_view
        # No 'Create Ticket' button for user without 'create' perm
        r = self.app.get('/bugs/', extra_environ=dict(username='*anonymous'))
        assert 'Create Ticket' not in r

    def test_render_markdown_syntax(self):
        r = self.app.get('/bugs/markdown_syntax')
        assert_true('Markdown Syntax' in r)

    def test_ticket_diffs(self):
        self.new_ticket(summary='difftest', description='1\n2\n3\n')
        self.app.post('/bugs/1/update_ticket', {
            'summary': 'difftest',
            'description': '1\n3\n4\n',
        })
        r = self.app.get('/bugs/1/')
        assert '<span class="gd">-2</span>' in r, r.showbrowser()
        assert '<span class="gi">+4</span>' in r, r.showbrowser()

    def test_meta_comment(self):
        self.new_ticket(summary="foo")
        self.app.post('/bugs/1/update_ticket', {
            'summary': 'bar',
            'comment': 'user comment',
        })
        t = tm.Ticket.query.get(ticket_num=1)
        assert_true(t.discussion_thread.first_post.is_meta)
        assert_false(t.discussion_thread.last_post.is_meta)

    def test_ticket_label_unlabel(self):
        summary = 'test labeling and unlabeling a ticket'
        self.new_ticket(summary=summary)
        self.app.post('/bugs/1/update_ticket', {
            'summary': 'aaa',
            'description': 'bbb',
            'status': 'ccc',
            '_milestone': '',
            'assigned_to': '',
            'labels': u'yellow,greén'.encode('utf-8'),
            'comment': ''
        })
        response = self.app.get('/bugs/1/')
        assert_true('yellow' in response)
        assert_true(u'greén' in response)
        assert_true(
            '<li><strong>labels</strong>:  --&gt; yellow, greén</li>' in response)
        self.app.post('/bugs/1/update_ticket', {
            'summary': 'zzz',
            'description': 'bbb',
            'status': 'ccc',
            '_milestone': '',
            'assigned_to': '',
            'labels': 'yellow',
            'comment': ''
        })
        response = self.app.get('/bugs/1/')
        assert_true('yellow' in response)
        assert_true(
            '<li><strong>labels</strong>: yellow, greén --&gt; yellow</li>' in response)
        self.app.post('/bugs/1/update_ticket', {
            'summary': 'zzz',
            'description': 'bbb',
            'status': 'ccc',
            '_milestone': '',
            'assigned_to': '',
            'labels': '',
            'comment': ''
        })
        response = self.app.get('/bugs/1/')
        assert_true(
            '<li><strong>labels</strong>: yellow --&gt; </li>' in response)

    def test_new_attachment(self):
        file_name = 'test_root.py'
        file_data = file(__file__).read()
        upload = ('attachment', file_name, file_data)
        self.new_ticket(summary='test new attachment')
        ticket_editor = self.app.post('/bugs/1/update_ticket', {
            'summary': 'zzz'
        }, upload_files=[upload]).follow()
        assert_true(file_name in ticket_editor)
        assert '<span>py</span>' not in ticket_editor

    def test_delete_attachment(self):
        file_name = 'test_root.py'
        file_data = file(__file__).read()
        upload = ('attachment', file_name, file_data)
        self.new_ticket(summary='test new attachment')
        ticket_editor = self.app.post('/bugs/1/update_ticket', {
            'summary': 'zzz'
        }, upload_files=[upload]).follow()
        assert file_name in ticket_editor, ticket_editor.showbrowser()
        req = self.app.get('/bugs/1/')
        file_link = req.html.findAll('form')[1].findAll('a')[6]
        assert_equal(file_link.string, file_name)
        self.app.post(str(file_link['href']), {
            'delete': 'True'
        })
        deleted_form = self.app.get('/bugs/1/')
        assert file_name not in deleted_form

    def test_delete_attachment_from_comments(self):
        ticket_view = self.new_ticket(summary='test ticket').follow()
        for f in ticket_view.html.findAll('form'):
            if f.get('action', '').endswith('/post'):
                break
        params = dict()
        inputs = f.findAll('input')
        for field in inputs:
            if field.has_key('name'):
                params[field['name']] = field.has_key(
                    'value') and field['value'] or ''
        params[f.find('textarea')['name']] = 'test comment'
        self.app.post(f['action'].encode('utf-8'), params=params,
                      headers={'Referer': '/bugs/1/'.encode("utf-8")})
        r = self.app.get('/bugs/1/', dict(page=1))
        post_link = str(
            r.html.find('div', {'class': 'edit_post_form reply'}).find('form')['action'])
        self.app.post(post_link + 'attach',
                      upload_files=[('file_info', 'test.txt', 'HiThere!')])
        r = self.app.get('/bugs/1/', dict(page=1))
        assert '<input class="submit delete_attachment file" type="submit" value="X"/>' in r
        form = r.forms[5].submit()
        r = self.app.get('/bugs/1/', dict(page=1))
        assert '<input class="submit delete_attachment" type="submit" value="X"/>' not in r

    def test_new_text_attachment_content(self):
        file_name = 'test_root.py'
        file_data = file(__file__).read()
        upload = ('attachment', file_name, file_data)
        self.new_ticket(summary='test new attachment')
        ticket_editor = self.app.post('/bugs/1/update_ticket', {
            'summary': 'zzz'
        }, upload_files=[upload]).follow()
        download = self.app.get(
            str(ticket_editor.html.findAll('form')[1].findAll('a')[7]['href']))
        assert_equal(download.body, file_data)

    def test_two_attachments(self):
        file_name1 = 'test_root1.py'
        file_name2 = 'test_root2.py'
        file_data = file(__file__).read()
        self.new_ticket(summary='test new attachment')
        ticket_editor = self.app.post('/bugs/1/update_ticket', {
            'summary': 'zzz'
        }, upload_files=[('attachment', file_name1, file_data), ('attachment', file_name2, file_data)]).follow()

        assert 'test_root1.py' in ticket_editor
        assert 'test_root2.py' in ticket_editor

    def test_new_image_attachment_content(self):
        h.set_context('test', 'bugs', neighborhood='Projects')
        file_name = 'neo-icon-set-454545-256x350.png'
        file_path = os.path.join(
            allura.__path__[0], 'nf', 'allura', 'images', file_name)
        file_data = file(file_path).read()
        upload = ('attachment', file_name, file_data)
        self.new_ticket(summary='test new attachment')
        ticket_editor = self.app.post('/bugs/1/update_ticket', {
            'summary': 'zzz'
        }, upload_files=[upload]).follow()
        ticket = tm.Ticket.query.find({'ticket_num': 1}).first()
        filename = ticket.attachments[0].filename

        uploaded = PIL.Image.open(file_path)
        r = self.app.get('/bugs/1/attachment/' + filename)
        downloaded = PIL.Image.open(StringIO.StringIO(r.body))
        assert uploaded.size == downloaded.size
        r = self.app.get('/bugs/1/attachment/' + filename + '/thumb')

        thumbnail = PIL.Image.open(StringIO.StringIO(r.body))
        assert thumbnail.size == (100, 100)

    def test_sidebar_static_page(self):
        admin = M.User.query.get(username='test-admin')
        for app in M.AppConfig.query.find({'options.mount_point': 'bugs'}):
            assert has_access(app, 'create', admin)

        response = self.app.get('/bugs/search/')
        assert 'Create Ticket' in response
        assert 'Related Pages' not in response

    def test_related_artifacts(self):
        summary = 'test sidebar logic for a ticket page'
        self.new_ticket(summary=summary)
        response = self.app.get('/p/test/bugs/1/')
        assert 'Related Pages' not in response
        self.app.post('/wiki/aaa/update', params={
            'title': 'aaa',
            'text': '',
            'labels': '',
            'viewable_by-0.id': 'all'})
        self.new_ticket(summary='bbb')
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()

        h.set_context('test', 'wiki', neighborhood='Projects')
        a = wm.Page.query.find(dict(title='aaa')).first()
        a.text = '\n[bugs:#1]\n[bugs:#2]\n'
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        b = tm.Ticket.query.find(dict(ticket_num=2)).first()
        b.description = '\n[#1]\n'
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()

        response = self.app.get('/p/test/bugs/1/')
        assert 'Related' in response
        assert 'Wiki: aaa' in response
        assert 'Tickets: #2' in response

        b = tm.Ticket.query.find(dict(ticket_num=2)).first()
        b.deleted = True
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        response = self.app.get('/p/test/bugs/1/')
        assert 'Tickets: #2' not in response
        response = self.app.get('/wiki/aaa/')
        assert 'alink notfound' in response

    def test_related_artifacts_closed_tickets(self):
        self.new_ticket(summary='Ticket 1')
        self.new_ticket(summary='Ticket 2', status='closed')
        self.new_ticket(summary='Ticket 3', description='[#1]\n\n[#2]')
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        r = self.app.get('/p/test/bugs/3/')
        assert_in('Tickets: #1', r)
        assert_not_in('Tickets: <s>#1</s>', r)
        assert_in('Tickets: <s>#2</s>', r)

        assert_in('<a class="alink" href="/p/test/bugs/1">[#1]</a>', r.body)
        assert_in('<a class="alink strikethrough" href="/p/test/bugs/2">[#2]</a>', r.body)

    def test_ticket_view_editable(self):
        summary = 'test ticket view page can be edited'
        self.new_ticket(summary=summary)
        response = self.app.get('/p/test/bugs/1/')
        assert response.html.find('input', {'name': 'ticket_form.summary'})
        assert response.html.find(
            'select', {'name': 'ticket_form.assigned_to'})
        assert response.html.find(
            'textarea', {'name': 'ticket_form.description'})
        assert response.html.find('select', {'name': 'ticket_form.status'})
        assert response.html.find('select', {'name': 'ticket_form._milestone'})
        assert response.html.find('input', {'name': 'ticket_form.labels'})
        assert response.html.find('textarea', {'name': 'ticket_form.comment'})

    def test_assigned_to_nobody(self):
        summary = 'test default assignment'
        self.new_ticket(summary=summary)
        response = self.app.get('/p/test/bugs/1/')
        assert 'nobody' in str(
            response.html.find('div', {'class': 'grid-5 ticket-assigned-to'}))

    def test_assign_ticket(self):
        summary = 'test assign ticket'
        self.new_ticket(summary=summary)
        response = self.app.get('/p/test/bugs/1/')
        assert 'nobody' in str(
            response.html.find('div', {'class': 'grid-5 ticket-assigned-to'}))
        response = self.app.post('/bugs/1/update_ticket', {
            'summary': 'zzz',
            'description': 'bbb',
            'status': 'ccc',
            '_milestone': '',
            'assigned_to': 'test-admin',
            'labels': '',
            'comment': ''
        }).follow()
        assert 'test-admin' in str(response.html.find('div',
                                   {'class': 'grid-5 ticket-assigned-to'}))
        assert '<li><strong>summary</strong>: test assign ticket --&gt; zzz' in response
        assert '<li><strong>status</strong>: open --&gt; ccc' in response

    def test_custom_fields(self):
        params = dict(
            custom_fields=[
                dict(name='_priority', label='Priority', type='select',
                     options='normal urgent critical'),
                dict(name='_category', label='Category', type='string',
                     options=''),
                dict(name='_code_review', label='Code Review', type='user')],
            open_status_names='aa bb',
            closed_status_names='cc',
        )
        self.app.post(
            '/admin/bugs/set_custom_fields',
            params=variable_encode(params))
        kw = {'custom_fields._priority': 'normal',
              'custom_fields._category': 'helloworld',
              'custom_fields._code_review': 'test-admin'}
        ticket_view = self.new_ticket(
            summary='test custom fields', **kw).follow()
        assert 'Priority:' in ticket_view
        assert 'normal' in ticket_view
        assert 'Test Admin' in ticket_view

    def test_select_custom_field(self):
        params = dict(
            custom_fields=[
                dict(name='_testselect', label='Test', type='select',
                     options='"test select"'),
            ],
            open_status_names='aa bb',
            closed_status_names='cc',
        )
        self.app.post(
            '/admin/bugs/set_custom_fields',
            params=variable_encode(params))
        r = self.app.get('/bugs/new/')
        assert '<option value="test select">test select</option>' in r
        kw = {'custom_fields._testselect': 'test select'}
        ticket_view = self.new_ticket(
            summary='test select custom fields', **kw).follow()
        assert '<option selected value="test select">test select</option>' in ticket_view

    def test_select_custom_field_unicode(self):
        params = dict(
            custom_fields=[
                dict(name='_testselect', label='Test', type='select',
                     options='oné "one and á half" two'),
            ],
            open_status_names='aa bb',
            closed_status_names='cc',
        )
        self.app.post(
            '/admin/bugs/set_custom_fields',
            params=variable_encode(params))
        r = self.app.get('/bugs/new/')
        assert u'<option value="oné">oné</option>'.encode('utf-8') in r
        assert u'<option value="one and á half">one and á half</option>'.encode('utf-8') in r
        assert u'<option value="two">two</option>' in r

    def test_select_custom_field_invalid_quotes(self):
        params = dict(
            custom_fields=[
                dict(name='_testselect', label='Test', type='select',
                     options='closéd "quote missing'),
            ],
            open_status_names='aa bb',
            closed_status_names='cc',
        )
        self.app.post(
            '/admin/bugs/set_custom_fields',
            params=variable_encode(params))
        r = self.app.get('/bugs/new/')
        assert u'<option value="closéd">closéd</option>'.encode('utf-8') in r
        assert u'<option value="quote">quote</option>' in r
        assert u'<option value="missing">missing</option>' in r

    def test_custom_field_update_comments(self):
        params = dict(
            custom_fields=[
                dict(label='Number', type='number', options='')],
            open_status_names='aa bb',
            closed_status_names='cc',
        )
        r = self.app.post('/admin/bugs/set_custom_fields',
                          params=variable_encode(params))
        kw = {'custom_fields._number': ''}
        ticket_view = self.new_ticket(
            summary='test custom fields', **kw).follow()
        assert '<strong>Number</strong>:  --&gt;' not in ticket_view
        ticket_view = self.app.post('/bugs/1/update_ticket', params={
            'summary': 'zzz',
            'description': 'bbb',
            'status': 'ccc',
            '_milestone': 'aaa',
            'assigned_to': '',
            'labels': '',
            'custom_fields._number': '',
            'comment': ''
        }).follow()
        assert '<strong>Number</strong>:  --&gt;' not in ticket_view
        ticket_view = self.app.post('/bugs/1/update_ticket', params={
            'summary': 'zzz',
            'description': 'bbb',
            'status': 'ccc',
            '_milestone': 'aaa',
            'assigned_to': '',
            'labels': '',
            'custom_fields._number': '4',
            'comment': ''
        }).follow()
        assert '<strong>Number</strong>:  --&gt;' in ticket_view

    def test_milestone_names(self):
        params = {
            'open_status_names': 'aa bb',
            'closed_status_names': 'cc',
            'custom_fields': [dict(
                label='Milestone',
                show_in_search='on',
                type='milestone',
                milestones=[
                    dict(name='aaaé'),
                    dict(name='bbb'),
                    dict(name='ccc')])]}
        self.app.post('/admin/bugs/set_custom_fields',
                      variable_encode(params),
                      status=302)
        self.new_ticket(summary='test milestone names')
        self.app.post('/bugs/1/update_ticket', {
            'summary': 'zzz',
            'description': 'bbb',
            'status': 'ccc',
            '_milestone': 'aaaé',
            'assigned_to': '',
            'labels': '',
            'comment': ''
        })
        ticket_view = self.app.get('/p/test/bugs/1/')
        assert 'Milestone' in ticket_view
        assert 'aaaé' in ticket_view

    def test_milestone_rename(self):
        self.new_ticket(summary='test milestone rename')
        self.app.post('/bugs/1/update_ticket', {
            'summary': 'test milestone rename',
            'description': '',
            'status': '',
            '_milestone': '1.0',
            'assigned_to': '',
            'labels': '',
            'comment': ''
        })
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        ticket_view = self.app.get('/p/test/bugs/1/')
        assert 'Milestone' in ticket_view
        assert '1.0' in ticket_view
        assert 'zzzé' not in ticket_view
        r = self.app.post('/bugs/update_milestones', {
            'field_name': '_milestone',
            'milestones-0.old_name': '1.0',
            'milestones-0.new_name': 'zzzé',
            'milestones-0.description': '',
            'milestones-0.complete': 'Open',
            'milestones-0.due_date': ''
        })
        ticket_view = self.app.get('/p/test/bugs/1/')
        assert '1.0' not in ticket_view
        assert 'zzzé' in ticket_view

    def test_milestone_close(self):
        self.new_ticket(summary='test milestone close')
        r = self.app.get('/bugs/milestones')
        assert 'view closed' not in r
        r = self.app.post('/bugs/update_milestones', {
            'field_name': '_milestone',
            'milestones-0.old_name': '1.0',
            'milestones-0.new_name': '1.0',
            'milestones-0.description': '',
            'milestones-0.complete': 'Closed',
            'milestones-0.due_date': ''
        })
        r = self.app.get('/bugs/milestones')
        assert 'view closed' in r

    def test_edit_all_button(self):
        admin = M.User.query.get(username='test-admin')
        for app in M.AppConfig.query.find({'options.mount_point': 'bugs'}):
            assert has_access(app, 'update', admin)

        response = self.app.get('/p/test/bugs/search/')
        assert 'Edit All' not in response

    def test_custom_fields_preserve_user_input_on_form_errors(self):
        params = dict(
            custom_fields=[
                dict(name='_priority', label='Priority', type='select',
                     options='normal urgent critical'),
                dict(name='_category', label='Category', type='string',
                     options='')],
            open_status_names='aa bb',
            closed_status_names='cc',
        )
        self.app.post(
            '/admin/bugs/set_custom_fields', params=variable_encode(params))
        # Test new ticket form
        r = self.app.get('/bugs/new/')
        form = r.forms[1]
        form['ticket_form.custom_fields._priority'] = 'urgent'
        form['ticket_form.custom_fields._category'] = 'bugs'
        error_form = form.submit()
        assert_equal(
            error_form.forms[1]['ticket_form.custom_fields._priority'].value, 'urgent')
        assert_equal(
            error_form.forms[1]['ticket_form.custom_fields._category'].value, 'bugs')
        # Test edit ticket form
        self.new_ticket(summary='Test ticket')
        response = self.app.get('/bugs/1/')
        form = response.forms[1]
        assert_equal(
            form['ticket_form.custom_fields._priority'].value, 'normal')
        assert_equal(form['ticket_form.custom_fields._category'].value, '')
        form['ticket_form.summary'] = ''
        form['ticket_form.custom_fields._priority'] = 'urgent'
        form['ticket_form.custom_fields._category'] = 'bugs'
        error_form = form.submit()
        assert_equal(
            error_form.forms[1]['ticket_form.custom_fields._priority'].value, 'urgent')
        assert_equal(
            error_form.forms[1]['ticket_form.custom_fields._category'].value, 'bugs')

    def test_new_ticket_validation(self):
        summary = 'ticket summary'
        response = self.app.get('/bugs/new/')
        assert not response.html.find('div', {'class': 'error'})
        form = response.forms[1]
        form['ticket_form.labels'] = 'foo'
        # try submitting with no summary set and check for error message
        error_form = form.submit()
        assert error_form.forms[1]['ticket_form.labels'].value == 'foo'
        error_message = error_form.html.find('div', {'class': 'error'})
        assert error_message
        assert (error_message.string == 'You must provide a Title' or
                error_message.string == 'Missing value')
        assert error_message.findPreviousSibling(
            'input').get('name') == 'ticket_form.summary'
        # set a summary, submit, and check for success
        error_form.forms[1]['ticket_form.summary'] = summary
        success = error_form.forms[1].submit().follow().html
        assert success.findAll('form')[1].get(
            'action') == '/p/test/bugs/1/update_ticket_from_widget'
        assert success.find('input', {'name': 'ticket_form.summary'})[
            'value'] == summary

    def test_edit_ticket_validation(self):
        old_summary = 'edit ticket test'
        new_summary = "new summary"
        self.new_ticket(summary=old_summary)
        response = self.app.get('/bugs/1/')
        # check that existing form is valid
        assert response.html.find(
            'input', {'name': 'ticket_form.summary'})['value'] == old_summary
        assert not response.html.find('div', {'class': 'error'})
        form = response.forms[1]
        # try submitting with no summary set and check for error message
        form['ticket_form.summary'] = ""
        error_form = form.submit()
        error_message = error_form.html.find('div', {'class': 'error'})
        assert error_message
        assert error_message.string == 'You must provide a Title'
        assert error_message.findPreviousSibling(
            'input').get('name') == 'ticket_form.summary'
        # set a summary, submit, and check for success
        error_form.forms[1]['ticket_form.summary'] = new_summary
        r = error_form.forms[1].submit()
        assert r.status_int == 302, r.showbrowser()
        success = r.follow().html
        assert success.findAll('form')[1].get(
            'action') == '/p/test/bugs/1/update_ticket_from_widget'
        assert success.find('input', {'name': 'ticket_form.summary'})[
            'value'] == new_summary

    def test_home(self):
        self.new_ticket(summary='test first ticket')
        self.new_ticket(summary='test second ticket')
        self.new_ticket(summary='test third ticket')
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        response = self.app.get('/p/test/bugs/')
        assert 'test third ticket' in response

    def test_search(self):
        self.new_ticket(summary='test first ticket')
        self.new_ticket(summary='test second ticket')
        self.new_ticket(summary='test third ticket')
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        response = self.app.get('/p/test/bugs/search/?q=test')
        assert '3 results' in response, response.showbrowser()
        assert 'test third ticket' in response, response.showbrowser()

    def test_search_with_strange_chars(self):
        r = self.app.get('/p/test/bugs/search/?' +
                         urllib.urlencode({'q': 'tést'}))
        assert 'Search bugs: tést' in r

    def test_saved_search_with_strange_chars(self):
        '''Sidebar must be visible even with a strange characters in saved search terms'''
        r = self.app.post('/admin/bugs/bins/save_bin', {
            'summary': 'Strange chars in terms here',
            'terms': 'labels:tést',
            'old_summary': '',
            'sort': ''}).follow()
        r = self.app.get('/bugs/')
        assert sidebar_contains(r, 'Strange chars in terms here')

    def test_search_feed(self):
        self.new_ticket(summary='test first ticket')
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        for ext in ['', '.rss', '.atom']:
            assert '<title>test first ticket</title>' in \
                self.app.get('/p/test/bugs/search_feed%s?q=test' % ext)

    def test_search_current_user(self):
        self.new_ticket(summary='test first ticket')
        self.new_ticket(summary='test second ticket')
        p = M.Project.query.get(shortname='test')
        tracker = p.app_instance('bugs')
        t = tm.Ticket.query.get(summary='test first ticket')
        t.reported_by_id = M.User.by_username('test-user-0')._id
        t = tm.Ticket.query.get(summary='test second ticket')
        t.reported_by_id = M.User.by_username('test-user-1')._id
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        response = self.app.get('/p/test/bugs/search/?q=reported_by_s:$USER',
                                extra_environ={'username': 'test-user-0'})
        assert '1 result' in response, response.showbrowser()
        assert 'test first ticket' in response, response.showbrowser()
        response = self.app.get('/p/test/bugs/search/?q=reported_by_s:$USER',
                                extra_environ={'username': 'test-user-1'})
        assert '1 result' in response, response.showbrowser()
        assert 'test second ticket' in response, response.showbrowser()

    def test_feed(self):
        self.new_ticket(
            summary='test first ticket',
            description='test description')
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        response = self.app.get('/p/test/bugs/feed')
        assert 'test first ticket' in response

    def test_touch(self):
        self.new_ticket(summary='test touch')
        h.set_context('test', 'bugs', neighborhood='Projects')
        ticket = tm.Ticket.query.get(ticket_num=1)
        old_date = ticket.mod_date
        ticket.summary = 'changing the summary'
        time.sleep(1)
        ThreadLocalORMSession.flush_all()
        ThreadLocalORMSession.close_all()
        ticket = tm.Ticket.query.get(ticket_num=1)
        new_date = ticket.mod_date
        assert new_date > old_date

    @patch('forgetracker.tracker_main.search_artifact')
    def test_save_invalid_search(self, search_artifact):
        err = 'Error running search query: [Reason: undefined field label]'
        search_artifact.side_effect = SearchError(err)
        r = self.app.post('/admin/bugs/bins/save_bin', {
            'summary': 'This is not too long.',
            'terms': 'label:foo',
            'old_summary': '',
            'sort': ''})
        assert err in r
        r = self.app.get('/admin/bugs/bins/')
        edit_form = r.form
        edit_form['bins-2.summary'] = 'Original'
        edit_form['bins-2.terms'] = 'label:foo'
        r = edit_form.submit()
        assert err in r

    def test_saved_search_labels_truncated(self):
        r = self.app.post('/admin/bugs/bins/save_bin', {
            'summary': 'This is not too long.',
            'terms': 'aaa',
            'old_summary': '',
            'sort': ''}).follow()
        r = self.app.get('/bugs/')
        assert sidebar_contains(r, 'This is not too long.')
        r = self.app.post('/admin/bugs/bins/save_bin', {
            'summary': 'This will be truncated because it is too long to show in the sidebar without being ridiculous.',
            'terms': 'aaa',
            'old_summary': '',
            'sort': ''}).follow()
        r = self.app.get('/bugs/')
        assert sidebar_contains(
            r, 'This will be truncated because it is too long to show in the sidebar ...')

    def test_edit_saved_search(self):
        r = self.app.get('/admin/bugs/bins/')
        edit_form = r.form
        edit_form['bins-2.summary'] = 'Original'
        edit_form['bins-2.terms'] = 'aaa'
        edit_form.submit()
        r = self.app.get('/bugs/')
        assert sidebar_contains(r, 'Original')
        assert not sidebar_contains(r, 'New')
        r = self.app.get('/admin/bugs/bins/')
        edit_form = r.form
        edit_form['bins-2.summary'] = 'New'
        edit_form.submit()
        r = self.app.get('/bugs/')
        assert sidebar_contains(r, 'New')
        assert not sidebar_contains(r, 'Original')

    def test_comment_split(self):
        summary = 'new ticket'
        ticket_view = self.new_ticket(summary=summary).follow()
        for f in ticket_view.html.findAll('form'):
            if f.get('action', '').endswith('/post'):
                break
        post_content = 'ticket discussion post content'
        params = dict()
        inputs = f.findAll('input')
        for field in inputs:
            if field.has_key('name'):
                params[field['name']] = field.has_key(
                    'value') and field['value'] or ''
        params[f.find('textarea')['name']] = post_content
        r = self.app.post(f['action'].encode('utf-8'), params=params,
                          headers={'Referer': '/bugs/1/'.encode("utf-8")})
        r = self.app.get('/bugs/1/', dict(page=1))
        assert_true(post_content in r)
        assert_true(
            len(r.html.findAll(attrs={'class': 'discussion-post'})) == 1)

        new_summary = 'old ticket'
        for f in ticket_view.html.findAll('form'):
            if f.get('action', '').endswith('update_ticket_from_widget'):
                break
        params = dict()
        inputs = f.findAll('input')
        for field in inputs:
            if field.has_key('name'):
                params[field['name']] = field.has_key(
                    'value') and field['value'] or ''
        params['ticket_form.summary'] = new_summary
        r = self.app.post(f['action'].encode('utf-8'), params=params,
                          headers={'Referer': '/bugs/1/'.encode("utf-8")})
        r = self.app.get('/bugs/1/', dict(page=1))
        assert_true(summary + ' --&gt; ' + new_summary in r)
        assert_true(
            len(r.html.findAll(attrs={'class': 'discussion-post'})) == 2)

    def test_discussion_paging(self):
        summary = 'test discussion paging'
        ticket_view = self.new_ticket(summary=summary).follow()
        for f in ticket_view.html.findAll('form'):
            if f.get('action', '').endswith('/post'):
                break
        post_content = 'ticket discussion post content'
        params = dict()
        inputs = f.findAll('input')
        for field in inputs:
            if field.has_key('name'):
                params[field['name']] = field.has_key(
                    'value') and field['value'] or ''
        params[f.find('textarea')['name']] = post_content
        r = self.app.post(f['action'].encode('utf-8'), params=params,
                          headers={'Referer': '/bugs/1/'.encode("utf-8")})
        r = self.app.get('/bugs/1/', dict(page=-1))
        assert_true(summary in r)
        r = self.app.get('/bugs/1/', dict(page=1))
        assert_true(post_content in r)
        # no pager if just one page
        assert_false('Page 1 of 1' in r)
        # add some more posts and check for pager
        for i in range(2):
            r = self.app.post(f['action'].encode('utf-8'), params=params,
                              headers={'Referer': '/bugs/1/'.encode("utf-8")})
        r = self.app.get('/bugs/1/', dict(page=1, limit=2))
        assert_true('Page 2 of 2' in r)

    def test_discussion_feed(self):
        summary = 'test discussion paging'
        ticket_view = self.new_ticket(summary=summary).follow()
        for f in ticket_view.html.findAll('form'):
            if f.get('action', '').endswith('/post'):
                break
        post_content = 'ticket discussion post content'
        params = dict()
        inputs = f.findAll('input')
        for field in inputs:
            if field.has_key('name'):
                params[field['name']] = field.has_key(
                    'value') and field['value'] or ''
        params[f.find('textarea')['name']] = post_content
        self.app.post(f['action'].encode('utf-8'), params=params,
                      headers={'Referer': '/bugs/1/'.encode("utf-8")})
        r = self.app.get('/bugs/feed.rss')
        post = M.Post.query.find().first()
        assert '/p/test/bugs/1/?limit=50#' + post.slug in r
        r = self.app.get('/bugs/1/')
        post_link = str(
            r.html.find('div', {'class': 'edit_post_form reply'}).find('form')['action'])
        post_form = r.html.find('form', {'action': post_link + 'reply'})
        params = dict()
        inputs = post_form.findAll('input')
        for field in inputs:
            if field.has_key('name'):
                params[field['name']] = field.has_key(
                    'value') and field['value'] or ''
        params[post_form.find('textarea')['name']] = 'Tis a reply'
        r = self.app.post(post_link + 'reply',
                          params=params,
                          headers={'Referer': post_link.encode("utf-8")})
        r = self.app.get('/bugs/feed.rss')
        assert 'Tis a reply' in r
        assert 'ticket discussion post content' in r
        r = self.app.get('/bugs/1/feed.rss')
        assert 'Tis a reply' in r
        assert 'ticket discussion post content' in r

    def test_bulk_edit_index(self):
        self.new_ticket(summary='test first ticket', status='open')
        self.new_ticket(summary='test second ticket', status='accepted')
        self.new_ticket(summary='test third ticket', status='closed')
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        response = self.app.get('/p/test/bugs/?sort=summary+asc')
        ticket_rows = response.html.find(
            'table', {'class': 'ticket-list'}).find('tbody')
        assert_in('test first ticket', str(ticket_rows))
        assert_in('test second ticket', str(ticket_rows))
        edit_link = response.html.find('a',{'title':'Bulk Edit'})
        expected_link = "/p/test/bugs/edit/?q=%21status%3Awont-fix+%26%26+%21status%3Aclosed&sort=snippet_s+asc&limit=25&filter=&page=0"
        assert_equal(expected_link, edit_link['href'])
        response = self.app.get(edit_link['href'])
        ticket_rows = response.html.find('tbody', {'class': 'ticket-list'})
        assert_in('test first ticket', str(ticket_rows))
        assert_in('test second ticket', str(ticket_rows))

    def test_bulk_edit_milestone(self):
        self.new_ticket(summary='test first ticket',
                        status='open', _milestone='1.0')
        self.new_ticket(summary='test second ticket',
                        status='accepted', _milestone='1.0')
        self.new_ticket(summary='test third ticket',
                        status='closed', _milestone='1.0')
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        response = self.app.get(
            '/p/test/bugs/milestone/1.0/?sort=ticket_num+asc')
        ticket_rows = response.html.find(
            'table', {'class': 'ticket-list'}).find('tbody')
        assert_in('test first ticket', str(ticket_rows))
        assert_in('test second ticket', str(ticket_rows))
        assert_in('test third ticket', str(ticket_rows))
        edit_link = response.html.find('a',{'title':'Bulk Edit'})
        expected_link = "/p/test/bugs/edit/?q=_milestone%3A1.0&sort=ticket_num_i+asc&limit=25&filter=&page=0"
        assert_equal(expected_link, edit_link['href'])
        response = self.app.get(edit_link['href'])
        ticket_rows = response.html.find('tbody', {'class': 'ticket-list'})
        assert_in('test first ticket', str(ticket_rows))
        assert_in('test second ticket', str(ticket_rows))
        assert_in('test third ticket', str(ticket_rows))

    def test_bulk_edit_search(self):
        self.new_ticket(summary='test first ticket', status='open')
        self.new_ticket(summary='test second ticket', status='open')
        self.new_ticket(summary='test third ticket',
                        status='closed', _milestone='1.0')
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        response = self.app.get('/p/test/bugs/search/?q=status%3Aopen')
        ticket_rows = response.html.find(
            'table', {'class': 'ticket-list'}).find('tbody')
        assert_in('test first ticket', str(ticket_rows))
        assert_in('test second ticket', str(ticket_rows))
        assert_false('test third ticket' in str(ticket_rows))
        edit_link = response.html.find('a',{'title':'Bulk Edit'})
        expected_link = "/p/test/bugs/edit/?q=status%3Aopen&limit=25&filter=%7B%7D&page=0"
        assert_equal(expected_link, edit_link['href'])
        response = self.app.get(edit_link['href'])
        ticket_rows = response.html.find('tbody', {'class': 'ticket-list'})
        assert_in('test first ticket', str(ticket_rows))
        assert_in('test second ticket', str(ticket_rows))
        assert_false('test third ticket' in str(ticket_rows))

    def test_ticket_notification_contains_milestones(self):
        params = dict(
            custom_fields=[
                dict(
                    name='_releases',
                    label='Releases',
                    type='milestone',
                    milestones=[{'name': '0.9.3'}, {'name': '1.0-beta'}],
                    show_in_search='on',
                ),
                dict(
                    name='_milestone',
                    label='Milestone',
                    type='milestone',
                    milestones=[{'name': '1.0'}, {'name': '2.0'}],
                    show_in_search='on',
                ),
            ],
            open_status_names='aa bb',
            closed_status_names='cc',
        )
        self.app.post(
            '/admin/bugs/set_custom_fields',
            params=variable_encode(params))
        self.new_ticket(summary='test new milestone', _milestone='2.0',
                        **{'custom_fields._releases': '1.0-beta'})
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        email = M.MonQTask.query.find(
            dict(task_name='allura.tasks.mail_tasks.sendmail')).first()
        assert_in('**Releases:** 1.0-beta', email.kwargs.text)
        assert_in('**Milestone:** 2.0', email.kwargs.text)

    def test_bulk_edit_notifications(self):
        self.new_ticket(summary='test first ticket',
                        status='open', _milestone='2.0')
        self.new_ticket(summary='test second ticket',
                        status='accepted', _milestone='1.0')
        self.new_ticket(summary='test third ticket', status='unread')
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        first_ticket = tm.Ticket.query.get(summary='test first ticket')
        second_ticket = tm.Ticket.query.get(summary='test second ticket')
        third_ticket = tm.Ticket.query.get(summary='test third ticket')
        first_user = M.User.by_username('test-user-0')
        second_user = M.User.by_username('test-user-1')
        admin = M.User.by_username('test-admin')
        first_ticket.subscribe(user=first_user)
        second_ticket.subscribe(user=second_user)
        M.MonQTask.query.remove()
        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': (
                          first_ticket._id,
                          second_ticket._id,
                          third_ticket._id),
                      'status': 'accepted',
                      '_milestone': '2.0',
                      'assigned_to': 'test-admin'})
        M.MonQTask.run_ready()

        emails = M.MonQTask.query.find(
            dict(task_name='allura.tasks.mail_tasks.sendmail')).all()
        assert_equal(len(emails), 3)
        for email in emails:
            assert_equal(email.kwargs.subject,
                         '[test:bugs] Mass edit changes by Test Admin')
        first_user_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': str(first_user._id)
        }).all()
        assert_equal(len(first_user_email), 1)
        first_user_email = first_user_email[0]
        second_user_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': str(second_user._id)
        }).all()
        assert_equal(len(second_user_email), 1)
        second_user_email = second_user_email[0]
        admin_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': str(admin._id)
        }).all()
        assert_equal(len(admin_email), 1)
        admin_email = admin_email[0]

        # Expected data
        email_header = '''Mass edit changing:

- **Owner**: Test Admin
- **Status**: accepted
- **Milestone**: 2.0

'''
        first_ticket_changes = '''ticket: bugs:#1 test first ticket

- **Owner**: Anonymous --> Test Admin
- **Status**: open --> accepted
'''
        second_ticket_changes = '''ticket: bugs:#2 test second ticket

- **Owner**: Anonymous --> Test Admin
- **Milestone**: 1.0 --> 2.0
'''
        third_ticket_changes = '''ticket: bugs:#3 test third ticket

- **Owner**: Anonymous --> Test Admin
- **Status**: unread --> accepted
- **Milestone**: 1.0 --> 2.0
'''
        email = u'\n'.join([email_header, first_ticket_changes, ''])
        assert_equal(email, first_user_email.kwargs.text)
        email = u'\n'.join([email_header, second_ticket_changes, ''])
        assert_equal(email, second_user_email.kwargs.text)
        assert_in(email_header, admin_email.kwargs.text)
        assert_in(first_ticket_changes, admin_email.kwargs.text)
        assert_in(second_ticket_changes, admin_email.kwargs.text)
        assert_in(third_ticket_changes, admin_email.kwargs.text)

    def test_bulk_edit_notifications_monitoring_email(self):
        self.app.post('/admin/bugs/set_options', params={
            'TicketMonitoringEmail': 'monitoring@email.com',
            'TicketMonitoringType': 'AllTicketChanges',
        })
        self.new_ticket(summary='test first ticket',
                        status='open', _milestone='2.0', private=True)
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        ticket = tm.Ticket.query.get(summary='test first ticket')
        M.MonQTask.query.remove()
        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': [ticket._id],
                      'status': 'accepted'})
        M.MonQTask.run_ready()
        emails = M.MonQTask.query.find(
            dict(task_name='allura.tasks.mail_tasks.sendmail')).all()
        # one for admin and one for monitoring email
        assert_equal(len(emails), 2)
        for email in emails:
            assert_equal(email.kwargs.subject,
                         '[test:bugs] Mass edit changes by Test Admin')
        admin = M.User.by_username('test-admin')
        admin_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': str(admin._id)
        }).all()
        monitoring_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': 'monitoring@email.com'
        }).all()
        assert_equal(len(admin_email), 1)
        assert_equal(len(monitoring_email), 1)
        admin_email_text = admin_email[0].kwargs.text
        monitoring_email_text = monitoring_email[0].kwargs.text
        assert_equal(admin_email_text, monitoring_email_text)

    def test_bulk_edit_notifications_monitoring_email_public_only(self):
        """Test that private tickets are not included in bulk edit
        notifications if the "public only" option is selected.
        """
        self.app.post('/admin/bugs/set_options', params={
            'TicketMonitoringEmail': 'monitoring@email.com',
            'TicketMonitoringType': 'AllPublicTicketChanges',
        })
        self.new_ticket(summary='test first ticket',
                        status='open', _milestone='2.0')
        self.new_ticket(summary='test second ticket',
                        status='open', private=True)
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        tickets = tm.Ticket.query.find(dict(status='open')).all()
        M.MonQTask.query.remove()
        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': [t._id for t in tickets],
                      'status': 'accepted'})
        M.MonQTask.run_ready()
        emails = M.MonQTask.query.find(
            dict(task_name='allura.tasks.mail_tasks.sendmail')).all()
        # one for admin and one for monitoring email
        assert_equal(len(emails), 2)
        for email in emails:
            assert_equal(email.kwargs.subject,
                         '[test:bugs] Mass edit changes by Test Admin')
        admin = M.User.by_username('test-admin')
        admin_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': str(admin._id)
        }).all()
        monitoring_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': 'monitoring@email.com'
        }).all()
        assert_equal(len(admin_email), 1)
        assert_equal(len(monitoring_email), 1)
        admin_email_text = admin_email[0].kwargs.text
        monitoring_email_text = monitoring_email[0].kwargs.text
        assert_in('second ticket', admin_email_text)
        assert_not_in('second ticket', monitoring_email_text)

    def test_bulk_edit_monitoring_email_all_private_edits(self):
        """Test that no monitoring email is sent if the "public only"
        option is selected, and only private tickets were updated.
        """
        self.app.post('/admin/bugs/set_options', params={
            'TicketMonitoringEmail': 'monitoring@email.com',
            'TicketMonitoringType': 'AllPublicTicketChanges',
        })
        self.new_ticket(summary='test first ticket',
                        status='open', private=True)
        self.new_ticket(summary='test second ticket',
                        status='open', private=True)
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        tickets = tm.Ticket.query.find(dict(status='open')).all()
        M.MonQTask.query.remove()
        self.app.post('/p/test/bugs/update_tickets', {
                      '__search': '',
                      '__ticket_ids': [t._id for t in tickets],
                      'status': 'accepted'})
        M.MonQTask.run_ready()
        emails = M.MonQTask.query.find(
            dict(task_name='allura.tasks.mail_tasks.sendmail')).all()
        assert_equal(len(emails), 1)  # only admin email sent
        for email in emails:
            assert_equal(email.kwargs.subject,
                         '[test:bugs] Mass edit changes by Test Admin')
        admin = M.User.by_username('test-admin')
        admin_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': str(admin._id)
        }).all()
        monitoring_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': 'monitoring@email.com'
        }).all()
        assert_equal(len(admin_email), 1)
        assert_equal(len(monitoring_email), 0)

    def test_filtered_by_subscription(self):
        self.new_ticket(summary='test first ticket', status='open')
        self.new_ticket(summary='test second ticket', status='open')
        self.new_ticket(summary='test third ticket', status='open')
        tickets = []
        users = []
        tickets.append(tm.Ticket.query.get(summary='test first ticket'))
        tickets.append(tm.Ticket.query.get(summary='test second ticket'))
        tickets.append(tm.Ticket.query.get(summary='test third ticket'))
        users.append(M.User.by_username('test-user-0'))
        users.append(M.User.by_username('test-user-1'))
        users.append(M.User.by_username('test-user-2'))
        admin = M.User.by_username('test-admin')
        tickets[0].subscribe(user=users[0])
        tickets[0].subscribe(user=users[1])
        tickets[1].subscribe(user=users[1])
        tickets[2].subscribe(user=users[2])
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()

        # Pretend we're changing first and second ticket.
        # Then we should notify test-user-0, test-user-1 and admin.
        # test-user-2 shoudn't be notified
        # (he has subscription to third ticket, but it didn't change).
        # test-user-0 should see changes only for first ticket.
        # test-user-1 - for both (separate subscription for both tickets).
        # admin - for both (tool subscription).
        changes = {
            tickets[0]._id: tickets[0],
            tickets[1]._id: tickets[1],
        }
        filtered_changes = c.app.globals.filtered_by_subscription(changes)
        filtered_users = [uid for uid, data in filtered_changes.iteritems()]
        assert_equal(sorted(filtered_users),
                     sorted([u._id for u in users[:-1] + [admin]]))
        ticket_ids = [t._id for t in tickets]
        assert_equal(filtered_changes[users[0]._id], set(ticket_ids[0:1]))
        assert_equal(filtered_changes[users[1]._id], set(ticket_ids[:-1]))
        assert_equal(filtered_changes[admin._id], set(ticket_ids[:-1]))

    def test_vote(self):
        r = self.new_ticket(summary='test vote').follow()
        assert_false(r.html.find('div', {'id': 'vote'}))

        # enable voting
        self.app.post('/admin/bugs/set_options',
                      params={'EnableVoting': 'true'})

        # test vote form not visible to anon user
        r = self.app.get('/bugs/1/', extra_environ=dict(username='*anonymous'))
        assert_false(r.html.find('div', {'id': 'vote'}))

        r = self.app.get('/bugs/1/')
        votes_up = r.html.find('span', {'class': 'votes-up'})
        votes_down = r.html.find('span', {'class': 'votes-down'})
        assert_in('0', str(votes_up))
        assert_in('0', str(votes_down))

        # invalid vote
        r = self.app.post('/bugs/1/vote', dict(vote='invalid'))
        expected_resp = json.dumps(
            dict(status='error', votes_up=0, votes_down=0, votes_percent=0))
        assert r.response.content == expected_resp

        # vote up
        r = self.app.post('/bugs/1/vote', dict(vote='u'))
        expected_resp = json.dumps(
            dict(status='ok', votes_up=1, votes_down=0, votes_percent=100))
        assert r.response.content == expected_resp

        # vote down by another user
        r = self.app.post('/bugs/1/vote', dict(vote='d'),
                          extra_environ=dict(username='test-user-0'))

        expected_resp = json.dumps(
            dict(status='ok', votes_up=1, votes_down=1, votes_percent=50))
        assert r.response.content == expected_resp

        # make sure that on the page we see the same result
        r = self.app.get('/bugs/1/')
        votes_up = r.html.find('span', {'class': 'votes-up'})
        votes_down = r.html.find('span', {'class': 'votes-down'})
        assert_in('1', str(votes_up))
        assert_in('1', str(votes_down))

        r = self.app.get('/bugs/')
        assert "Votes" in r
        self.app.post(
            '/admin/bugs/set_options',
            params={'EnableVoting': 'false'})
        r = self.app.get('/bugs/')
        assert "Votes" not in r

    @td.with_tool('test', 'Tickets', 'tracker',
                  post_install_hook=post_install_create_ticket_permission)
    def test_create_permission(self):
        """Test that user with `create` permission can create ticket,
        but can't edit it without `update` permission.
        """
        response = self.app.get('/p/test/tracker/',
                                extra_environ=dict(username='test-user-0'))
        assert 'Create Ticket' in response

        response = self.new_ticket(summary='test create, not update',
                                   mount_point='/tracker/',
                                   extra_environ=dict(username='test-user-0'))
        ticket_url = response.headers['Location']
        response = self.app.get(ticket_url,
                                extra_environ=dict(username='test-user-0'))
        assert not response.html.find('div', {'class': 'error'})
        assert not response.html.find('a', {'class': 'edit_ticket'})

    @td.with_tool('test', 'Tickets', 'tracker',
                  post_install_hook=post_install_update_ticket_permission)
    def test_update_permission(self):
        r = self.app.get('/p/test/tracker/',
                         extra_environ=dict(username='*anonymous'))
        assert 'Create Ticket' in r

        r = self.new_ticket(summary='test', mount_point='/tracker/',
                            extra_environ=dict(username='*anonymous'))
        ticket_url = r.headers['Location']
        r = self.app.get(ticket_url, extra_environ=dict(username='*anonymous'))
        a = r.html.find('a', {'class': 'edit_ticket'})
        assert a.text == 'Edit'

    def test_ticket_creator_cant_edit_private_ticket_without_update_perm(self):
        p = M.Project.query.get(shortname='test')
        tracker = p.app_instance('bugs')
        # authenticated user has 'create' permission, but not 'update'
        role = M.ProjectRole.by_name('*authenticated')._id
        create_permission = M.ACE.allow(role, 'create')
        update_permission = M.ACE.allow(role, 'update')
        acl = tracker.config.acl
        acl.append(create_permission)
        if update_permission in acl:
            acl.remove(update_permission)
        # test-user creates private ticket
        env = {'username': 'test-user'}
        post_data = {
            'ticket_form.summary': 'Private ticket title',
            'ticket_form.private': True
        }
        self.app.post('/bugs/save_ticket', post_data, extra_environ=env)
        # ... and can see it
        r = self.app.get('/bugs/1/', extra_environ=env)
        assert 'Private ticket title' in r
        assert '<label class="simple">Private:</label> Yes' in r, 'Ticket is not private'
        # ... and can't see 'Edit' link
        assert r.html.find('a', {'class': 'edit_ticket'}
                           ) is None, "Found 'Edit' link"
        # ... and can't actually edit it
        self.app.post('/bugs/1/update_ticket', {'summary': 'should fail'},
                      extra_environ=env, status=403)

    def test_imported_tickets_redirect(self):
        self.new_ticket(summary='Imported ticket')
        ticket = tm.Ticket.query.get(ticket_num=1)
        ticket.import_id = {'source_id': '42000'}
        ThreadLocalORMSession.flush_all()

        # expect permanent redirect to /p/test/bugs/1/
        r = self.app.get('/p/test/bugs/42000/', status=301).follow()
        assert r.request.path == '/p/test/bugs/1/', r.request.path

        # not found and has not import_id
        self.app.get('/p/test/bugs/42042/', status=404)

    def test_ticket_delete(self):
        self.new_ticket(summary='Test ticket')
        self.app.post('/bugs/1/delete')
        r = self.app.get('/bugs/')
        assert 'No open tickets found.' in r
        assert tm.Ticket.query.get(ticket_num=1).summary != 'Test ticket'
        self.app.post('/bugs/1/undelete')
        r = self.app.get('/bugs/')
        assert 'No open tickets found.' not in r
        assert tm.Ticket.query.get(ticket_num=1).summary == 'Test ticket'

    def test_ticket_delete_without_permission(self):
        self.new_ticket(summary='Test ticket')
        self.app.post('/bugs/1/delete',
                      extra_environ=dict(username='*anonymous'))
        r = self.app.get('/bugs/')
        assert '<a href="/p/test/bugs/1/">Test ticket</a>' in r
        self.app.post('/bugs/1/delete')
        self.app.post('/bugs/1/undelete',
                      extra_environ=dict(username='*anonymous'))
        r = self.app.get('/bugs/')
        assert 'No open tickets found.' in r

    def test_deleted_ticket_visible(self):
        self.new_ticket(summary='test')
        self.app.post('/bugs/1/delete')
        r = self.app.get('/p/test/bugs/1/')
        assert '#1 test' in r
        self.app.get('/p/test/bugs/1/',
                     extra_environ=dict(username='*anonymous'), status=404)
        r = self.app.get('/p/test/bugs/',
                         params=dict(q='test', deleted='True'))
        assert '<td><a href="/p/test/bugs/1/">test' in r
        assert '<tr class=" deleted">' in r
        r = self.app.get(
            '/p/test/bugs/', params=dict(q='test', deleted='True'),
            extra_environ=dict(username='*anonymous'))
        assert 'No open tickets found.' in r

    def test_show_hide_deleted_tickets(self):
        self.new_ticket(summary='Test ticket')
        r = self.app.get('/p/test/bugs/')
        assert 'Show deleted tickets' not in r
        self.app.post('/bugs/1/delete')
        r = self.app.get('/p/test/bugs/')
        assert 'Show deleted tickets' in r
        assert 'No open tickets found' in r
        r = self.app.get('/bugs/?deleted=True')
        assert '<a href="/p/test/bugs/1/">Test ticket' in r
        assert 'Hide deleted tickets' in r

    @td.with_tool('test', 'Tickets', 'bugs2')
    @td.with_tool('test2', 'Tickets', 'bugs')
    @td.with_tool('test2', 'Tickets', 'bugs2')
    def test_move_ticket(self):
        self.new_ticket(summary='test')
        r = self.app.get('/p/test/bugs/1/move')
        trackers = r.html.find('select', {'name': 'tracker'}).findAll('option')
        trackers = set([t.text for t in trackers])
        expected = set(
            ['test/bugs', 'test/bugs2', 'test2/bugs', 'test2/bugs2'])
        assert trackers == expected, trackers

        p = M.Project.query.get(shortname='test2')
        tracker = p.app_instance('bugs2')
        r = self.app.post('/p/test/bugs/1/move/',
                          params={'tracker': str(tracker.config._id)}).follow()
        assert_equal(r.request.path, '/p/test2/bugs2/1/')
        summary = r.html.findAll(
            'h2', {'class': 'dark title'})[0].contents[0].strip()
        assert_equal(summary, '#1 test')
        ac_id = tracker.config._id
        ticket = tm.Ticket.query.find({
            'app_config_id': ac_id,
            'ticket_num': 1}).first()
        assert ticket is not None, "Can't find moved ticket"
        assert_equal(ticket.discussion_thread.app_config_id, ac_id)
        assert_equal(ticket.discussion_thread.discussion.app_config_id, ac_id)
        post = ticket.discussion_thread.last_post
        assert_equal(post.text, 'Ticket moved from /p/test/bugs/1/')

    @td.with_tool('test2', 'Tickets', 'bugs2')
    def test_move_ticket_feed(self):
        self.new_ticket(summary='test')
        p = M.Project.query.get(shortname='test2')
        ac_id = p.app_instance('bugs2').config._id
        r = self.app.post('/p/test/bugs/1/move/',
                          params={'tracker': str(ac_id)}).follow()

        ticket = tm.Ticket.query.find({
            'app_config_id': ac_id,
            'ticket_num': 1}).first()
        post = ticket.discussion_thread.last_post
        ticket_link = '/p/test2/bugs2/1/?limit=50#' + post.slug
        msg = 'Ticket moved from /p/test/bugs/1/'
        assert_equal(post.text, msg)
        # auto comment content and link to it should be in a ticket's feed
        r = self.app.get('/p/test2/bugs2/1/feed')
        assert msg in r, r
        assert ticket_link in r, r
        # auto comment content and link to it should be in a tracker's feed
        r = self.app.get('/p/test2/bugs2/1/feed')
        assert msg in r, r
        assert ticket_link in r, r

        # post comment and make sure that it appears on the feeds
        r = self.app.get('/p/test2/bugs2/1/')
        for f in r.html.findAll('form'):
            if f.get('action', '').endswith('/post'):
                break
        post_content = 'ticket discussion post content'
        params = dict()
        inputs = f.findAll('input')
        for field in inputs:
            if field.has_key('name'):
                params[field['name']] = field.has_key(
                    'value') and field['value'] or ''
        params[f.find('textarea')['name']] = post_content
        r = self.app.post(f['action'].encode('utf-8'), params=params,
                          headers={'Referer': '/p/test2/bugs2/1/'.encode("utf-8")})
        r = self.app.get('/p/test2/bugs2/1/', dict(page=1))
        assert_true(post_content in r)
        comments_cnt = len(r.html.findAll(attrs={'class': 'discussion-post'}))
        assert_equal(comments_cnt, 2)  # moved auto comment + new comment
        post = ticket.discussion_thread.last_post
        # content and link to the ticket should be in a tracker's feed
        ticket_link = '/p/test2/bugs2/1/?limit=50#' + post.slug
        r = self.app.get('/p/test2/bugs2/feed')
        assert post_content in r, r
        assert ticket_link in r, r
        # content and link to the ticket should be in a ticket's feed
        r = self.app.get('/p/test2/bugs2/1/feed')
        assert post_content in r, r
        assert ticket_link in r, r

    def test_move_ticket_bad_data(self):
        self.new_ticket(summary='test')
        r = self.app.post('/p/test/bugs/1/move').follow()  # empty POST
        assert 'Select valid tracker' in r, r
        r = self.app.post('/p/test/bugs/1/move',
                          params={'tracker': 'invalid tracker id'}).follow()
        assert 'Select valid tracker' in r, r
        p = M.Project.query.get(shortname='test')
        tracker = p.app_instance('bugs')
        r = self.app.post('/p/test/bugs/1/move',
                          params={'tracker': str(tracker.config._id)}).follow()
        assert 'Ticket already in a selected tracker' in r, r

    def test_move_ticket_access(self):
        self.new_ticket(summary='test')
        self.app.get('/p/test/bugs/1/move',
                     extra_environ={'username': 'test-user'},
                     status=403)
        self.app.post('/p/test/bugs/1/move',
                      extra_environ={'username': 'test-user'},
                      status=403)

    @td.with_tool('test', 'Tickets', 'dummy')
    def test_move_ticket_redirect(self):
        self.new_ticket(summary='test 1')
        self.app.get('/p/test/bugs/1/', status=200)  # shouldn't fail

        # move ticket 1 to 'dummy' tracker
        p = M.Project.query.get(shortname='test')
        dummy_tracker = p.app_instance('dummy')
        r = self.app.post('/p/test/bugs/1/move',
                          params={'tracker': str(dummy_tracker.config._id)}).follow()
        assert_equal(r.request.path, '/p/test/dummy/1/')

        # test that old url redirects to moved ticket
        self.app.get('/p/test/bugs/1/', status=301).follow()
        assert_equal(r.request.path, '/p/test/dummy/1/')

    @td.with_tool('test', 'Tickets', 'dummy')
    def test_move_ticket_and_delete_tool(self):
        """See [#5708] for details."""
        # create two tickets and ensure they are viewable
        self.new_ticket(summary='test 1')
        self.new_ticket(summary='test 2')
        self.app.get('/p/test/bugs/1/', status=200)  # shouldn't fail
        self.app.get('/p/test/bugs/2/', status=200)  # shouldn't fail

        # move ticket 1 to 'dummy' tracker
        p = M.Project.query.get(shortname='test')
        dummy_tracker = p.app_instance('dummy')
        r = self.app.post('/p/test/bugs/1/move',
                          params={'tracker': str(dummy_tracker.config._id)}).follow()
        assert_equal(r.request.path, '/p/test/dummy/1/')

        # delete 'dummy' tracker
        p.uninstall_app('dummy')

        # remaining tickets in 'bugs' tracker should still be viewable
        self.app.get('/p/test/bugs/2/', status=200)  # shouldn't fail
        # ticket counts as moved
        r = self.app.get('/p/test/bugs/1/', status=301)
        r.follow(status=404)  # and not found 'cause already deleted

    @td.with_tool('test', 'Tickets', 'dummy')
    def test_move_ticket_email_notifications(self):
        """See [#5691] for details"""
        # create two tickets and ensure they are viewable
        self.new_ticket(summary='test 1')
        self.new_ticket(summary='test 2')
        self.app.get('/p/test/bugs/1/', status=200)  # shouldn't fail
        self.app.get('/p/test/bugs/2/', status=200)  # shouldn't fail

        # move ticket 1 to 'dummy' tracker
        p = M.Project.query.get(shortname='test')
        dummy_tracker = p.app_instance('dummy')
        r = self.app.post('/p/test/bugs/1/move',
                          params={'tracker': str(dummy_tracker.config._id)}).follow()
        assert_equal(r.request.path, '/p/test/dummy/1/')

        # comment ticket 2
        M.Notification.query.remove()
        r = self.app.get('/p/test/bugs/2/')
        field_name = None  # comment text textarea name
        for name, field in r.forms[2].fields.iteritems():
            if field[0].tag == 'textarea':
                field_name = name
        assert field_name, "Can't find comment field"
        r.forms[2].fields[field_name][0].value = 'Hi there'
        r.forms[2].submit()

        # notification for ticket 2 should reference [test:bugs], not
        # [test:dummy]
        n = M.Notification.query.find().all()[0]
        assert_in('[test:bugs]', n.subject)
        assert_in('[test:bugs]', n.reply_to_address)

    @td.with_tool('test2', 'Tickets', 'bugs2')
    def test_move_attachment(self):
        file_name = 'neo-icon-set-454545-256x350.png'
        file_path = os.path.join(
            allura.__path__[0], 'nf', 'allura', 'images', file_name)
        file_data = file(file_path).read()
        upload = ('attachment', file_name, file_data)
        self.new_ticket(summary='test move attachment')

        # attach an image to the ticket
        self.app.post('/bugs/1/update_ticket',
                      {'summary': 'test'},
                      upload_files=[upload])
        # attach a txt file to the comment
        r = self.app.get('/p/test/bugs/1/')
        post_link = str(
            r.html.find('div', {'class': 'edit_post_form reply'}).find('form')['action'])
        r = self.app.post(post_link + 'attach',
                          upload_files=[('file_info', 'test.txt', 'test')])
        # move ticket
        p = M.Project.query.get(shortname='test2')
        bugs2 = p.app_instance('bugs2')
        r = self.app.post('/p/test/bugs/1/move/',
                          params={'tracker': str(bugs2.config._id)}).follow()

        attachs = r.html.findAll('div', attrs={'class': 'attachment_thumb'})
        ta = str(attachs[1])  # ticket's attachments
        ca = str(attachs[2])  # comment's attachments
        assert_in(
            '<a href="/p/test2/bugs2/1/attachment/neo-icon-set-454545-256x350.png"', ta)
        assert_in(
            '<img src="/p/test2/bugs2/1/attachment/neo-icon-set-454545-256x350.png/thumb"', ta)
        p = M.Post.query.find().sort('timestamp', 1).first()
        assert_in(
            '<a href="/p/test2/bugs2/_discuss/thread/%s/%s/attachment/test.txt"' %
            (p.thread_id, p.slug), ca)
        for attach in M.BaseAttachment.query.find():
            assert_equal(attach.app_config_id, bugs2.config._id)
            if attach.attachment_type == 'DiscussionAttachment':
                assert_equal(attach.discussion_id, bugs2.config.discussion_id)

    @td.with_tool('test', 'Tickets', 'dummy')
    def test_move_ticket_comments(self):
        """Comments should move along with the ticket"""
        self.new_ticket(summary='test ticket')
        r = self.app.get('/p/test/bugs/1/')
        field_name = None  # comment text textarea name
        for name, field in r.forms[2].fields.iteritems():
            if field[0].tag == 'textarea':
                field_name = name
        assert field_name, "Can't find comment field"
        r.forms[2].fields[field_name][0].value = 'I am comment'
        r.forms[2].submit()
        r = self.app.get('/p/test/bugs/1/')
        assert_in('I am comment', r)

        p = M.Project.query.get(shortname='test')
        dummy_tracker = p.app_instance('dummy')
        r = self.app.post('/p/test/bugs/1/move',
                          params={'tracker': str(dummy_tracker.config._id)}).follow()
        assert_equal(r.request.path, '/p/test/dummy/1/')
        assert_in('I am comment', r)

    def test_tags(self):
        p = M.Project.query.get(shortname='test')
        tracker = p.app_instance('bugs')
        self.new_ticket(summary='a', labels='tag1,tag2')
        self.new_ticket(summary='b', labels='tag2')
        self.new_ticket(summary='c', labels='42cc,test')
        # Testing only empty 'term', because mim doesn't support aggregation
        # calls
        r = self.app.get('/p/test/bugs/tags')
        assert_equal(json.loads(r.body), [])
        r = self.app.get('/p/test/bugs/tags?term=')
        assert_equal(json.loads(r.body), [])

    def test_rest_tickets(self):
        ticket_view = self.new_ticket(summary='test').follow()
        for f in ticket_view.html.findAll('form'):
            if f.get('action', '').endswith('/post'):
                break
        params = dict()
        inputs = f.findAll('input')
        for field in inputs:
            if field.has_key('name'):
                params[field['name']] = field.has_key(
                    'value') and field['value'] or ''
        params[f.find('textarea')['name']] = 'test comment'
        self.app.post(f['action'].encode('utf-8'), params=params,
                      headers={'Referer': '/bugs/1/'.encode("utf-8")})
        r = self.app.get('/bugs/1/', dict(page=1))
        post_link = str(
            r.html.find('div', {'class': 'edit_post_form reply'}).find('form')['action'])
        self.app.post(post_link + 'attach',
                      upload_files=[('file_info', 'test.txt', 'test attach')])
        r = self.app.get('/p/test/bugs/1/')
        discussion_url = r.html.findAll('form')[-1]['action'][:-4]
        r = self.app.get('/rest/p/test/bugs/1/')
        r = json.loads(r.body)
        assert_equal(r['ticket']['discussion_thread_url'],
                     'http://localhost/rest%s' % discussion_url)
        slug = r['ticket']['discussion_thread']['posts'][0]['slug']
        assert_equal(
            r['ticket']['discussion_thread'][
                'posts'][0]['attachments'][0]['url'],
            'http://localhost%s%s/attachment/test.txt' % (discussion_url, slug))
        assert_equal(r['ticket']['discussion_thread']['posts']
                     [0]['attachments'][0]['bytes'], 11)

        file_name = 'test_root.py'
        file_data = file(__file__).read()
        upload = ('attachment', file_name, file_data)
        r = self.app.post('/bugs/1/update_ticket', {
            'summary': 'test rest attach'
        }, upload_files=[upload]).follow()
        r = self.app.get('/rest/p/test/bugs/1/')
        r = json.loads(r.body)
        assert_equal(r['ticket']['attachments'][0]['url'],
                     'http://localhost/p/test/bugs/1/attachment/test_root.py')

    def test_html_escaping(self):
        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
            self.new_ticket(summary='test <h2> ticket',
                            status='open', _milestone='2.0')
            ThreadLocalORMSession.flush_all()
            M.MonQTask.run_ready()
            ThreadLocalORMSession.flush_all()
            email = M.MonQTask.query.find(
                dict(task_name='allura.tasks.mail_tasks.sendmail')).first()
            assert_equal(email.kwargs.subject,
                         '[test:bugs] #1 test <h2> ticket')
            text = email.kwargs.text
            assert '** [bugs:#1] test &lt;h2&gt; ticket**' in text
            mail_tasks.sendmail(
                fromaddr=str(c.user._id),
                destinations=[str(c.user._id)],
                text=text,
                reply_to=g.noreply,
                subject=email.kwargs.subject,
                message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')
            assert 'Subject: [test:bugs] #1 test <h2> ticket' in body
            assert '<p><strong> <a class="alink" href="http://localhost/p/test/bugs/1">[bugs:#1]</a> test &lt;h2&gt; ticket</strong></p>' in body

    @patch('forgetracker.search.query_filter_choices')
    def test_multiselect(self, query_filter_choices):
        self.new_ticket(summary='test')
        self.new_ticket(summary='test2')
        query_filter_choices.return_value = {'status': [('open', 2)], }
        r = self.app.get('/bugs/')
        assert '<option value="open">open (2)</option>' in r
        assert query_filter_choices.call_count == 1
        assert query_filter_choices.call_args[0][0] == '!status_s:wont-fix && !status_s:closed'

class TestMilestoneAdmin(TrackerTestController):

    def _post(self, params, **kw):
        params['open_status_names'] = 'aa bb'
        params['closed_status_names'] = 'cc'
        self.app.post('/admin/bugs/set_custom_fields',
                      params=variable_encode(params), **kw)
        return self.app.get('/admin/bugs/fields')

    def _post_milestones(self, milestones):
        params = {'custom_fields': [
            dict(label=mf['label'],
                 show_in_search='on',
                 type='milestone',
                 milestones=[
                     dict((k, v) for k, v in d.iteritems()) for d in mf['milestones']])
            for mf in milestones]}
        return self._post(params)

    def test_create_milestone_field(self):
        r = self._post_milestones([
            dict(label='releases', milestones=[dict(name='1.0/beta')])
        ])
        assert 'releases' in r
        assert '1.0-beta' in r

    def test_delete_milestone_field(self):
        r = self._post_milestones([
            dict(label='releases', milestones=[dict(name='1.0/beta')])
        ])
        self.new_ticket(summary='test new milestone',
                        **{'custom_fields._releases': '1.0-beta'})
        assert tm.Ticket.query.find({
            'custom_fields._releases': '1.0-beta'}).count() == 1
        r = self._post_milestones([])
        assert 'Releases' not in r
        assert '1.0-beta' not in r
        assert tm.Ticket.query.find({
            'custom_fields._releases': '1.0-beta'}).count() == 0

    def test_rename_milestone_field(self):
        r = self._post_milestones([
            dict(label='releases', milestones=[dict(name='1.0/beta')])
        ])
        self.new_ticket(summary='test new milestone',
                        **{'custom_fields._releases': '1.0-beta'})
        r = self._post_milestones([
            dict(label='versions', milestones=[dict(name='1.0/beta')])
        ])
        assert 'Releases' not in r
        assert 'versions' in r
        assert '1.0-beta' in r
        # TODO: This doesn't work - need to make milestone custom fields
        #       renameable.
        # assert tm.Ticket.query.find({
        #    'custom_fields._versions': '1.0-beta'}).count() == 1

    def test_create_milestone(self):
        r = self._post_milestones([
            dict(label='releases', milestones=[dict(name='1.0/beta')])
        ])
        r = self._post_milestones([
            dict(label='releases', milestones=[dict(name='1.0/beta'),
                                               dict(name='2.0')])
        ])
        assert '1.0-beta' in r
        assert '2.0' in r

    def test_delete_milestone(self):
        r = self._post_milestones([
            dict(label='releases', milestones=[dict(name='1.0/beta')])
        ])
        self.new_ticket(summary='test new milestone',
                        **{'custom_fields._releases': '1.0-beta'})
        assert tm.Ticket.query.find({
            'custom_fields._releases': '1.0-beta'}).count() == 1
        r = self._post_milestones([
            dict(label='releases', milestones=[])
        ])
        assert 'releases' in r
        assert '1.0-beta' not in r
        assert tm.Ticket.query.find({
            'custom_fields._releases': '1.0-beta'}).count() == 0

    def test_rename_milestone(self):
        r = self._post_milestones([
            dict(label='releases', milestones=[dict(name='1.0')])
        ])
        self.new_ticket(summary='test new milestone',
                        **{'custom_fields._releases': '1.0'})
        r = self._post_milestones([
            dict(label='releases', milestones=[
                dict(name='1.1', old_name='1.0')])
        ])
        assert 'releases'in r
        assert '1.0' not in r
        assert '1.1' in r
        assert tm.Ticket.query.find({
            'custom_fields._releases': '1.0'}).count() == 0
        assert tm.Ticket.query.find({
            'custom_fields._releases': '1.1'}).count() == 1


def post_install_hook(app):
    role_anon = M.ProjectRole.by_name('*anonymous')._id
    app.config.acl.append(M.ACE.allow(role_anon, 'post'))
    app.config.acl.append(M.ACE.allow(role_anon, 'create'))
    app.config.acl.append(M.ACE.allow(role_anon, 'update'))


class TestEmailMonitoring(TrackerTestController):

    def __init__(self):
        super(TestEmailMonitoring, self).__init__()
        self.test_email = 'mailinglist@example.com'

    def _set_options(self, monitoring_type='AllTicketChanges'):
        r = self.app.post('/admin/bugs/set_options', params={
            'TicketMonitoringEmail': self.test_email,
            'TicketMonitoringType': monitoring_type,
        })
        return r

    def test_set_options(self):
        r = self._set_options()
        r = self.app.get('/admin/bugs/options')
        email = r.html.findAll(attrs=dict(name='TicketMonitoringEmail'))
        mtype = r.html.findAll('option', attrs=dict(value='AllTicketChanges'))
        assert email[0]['value'] == self.test_email
        assert mtype[0]['selected'] == 'selected'

    @td.with_tool('test', 'Tickets', 'doc-bugs', post_install_hook=post_install_hook)
    @patch('forgetracker.model.ticket.Notification.send_direct')
    @patch('allura.model.discuss.Thread.is_spam')
    def test_notifications_moderators(self, is_spam, send_direct):
        is_spam.return_value = True
        self.new_ticket(summary='test moderation', mount_point='/doc-bugs/')
        self.app.post('/doc-bugs/1/update_ticket', {
            'summary': 'test moderation',
            'comment': 'test unmoderated post'
        }, extra_environ=dict(username='*anonymous'))
        send_direct.assert_called_with(
            str(M.User.query.get(username='test-admin')._id))

    @patch('forgetracker.model.ticket.Notification.send_simple')
    def test_notifications_new(self, send_simple):
        self._set_options('NewTicketsOnly')
        self.new_ticket(summary='test', private=True)
        send_simple.assert_called_once_with(self.test_email)

    @patch('forgetracker.model.ticket.Notification.send_simple')
    def test_notifications_new_public_only(self, send_simple):
        """Test that notification not sent for new private ticket
        if "public only" option selected.
        """
        self._set_options('NewPublicTicketsOnly')
        self.new_ticket(summary='test', private=True)
        assert not send_simple.called

    @patch('forgetracker.tracker_main.M.Notification.send_simple')
    def test_notifications_all(self, send_simple):
        self._set_options()
        self.new_ticket(summary='test')
        send_simple.assert_called_once_with(self.test_email)
        send_simple.reset_mock()
        response = self.app.post('/bugs/1/update_ticket', {
            'summary': 'test',
            'description': 'update',
            'private': '1'})
        assert send_simple.call_count == 1, send_simple.call_count
        send_simple.assert_called_with(self.test_email)
        send_simple.reset_mock()
        response = response.follow()
        for f in response.html.findAll('form'):
            # Dirty way to find comment form
            if (('thread' in f['action']) and ('post' in f['action'])):
                params = {i['name']: i.get('value', '')
                          for i in f.findAll('input')
                          if i.has_key('name')}
                params[f.find('textarea')['name']] = 'foobar'
                self.app.post(str(f['action']), params)
                break  # Do it only once if many forms met
        assert send_simple.call_count == 1, send_simple.call_count
        send_simple.assert_called_with(self.test_email)

    @patch('forgetracker.tracker_main.M.Notification.send_simple')
    def test_notifications_all_public_only(self, send_simple):
        """Test that notifications are not sent for private tickets
        if "public only" option selected.
        """
        self._set_options('AllPublicTicketChanges')
        self.new_ticket(summary='test')
        send_simple.assert_called_once_with(self.test_email)
        send_simple.reset_mock()
        self.app.post('/bugs/1/update_ticket', {
            'summary': 'test',
            'description': 'update 1'})
        send_simple.assert_called_once_with(self.test_email)
        send_simple.reset_mock()
        self.app.post('/bugs/1/update_ticket', {
            'summary': 'test',
            'description': 'update 2',
            'private': '1'})
        assert not send_simple.called

    @patch('forgetracker.tracker_main.M.Notification.send_simple')
    def test_notifications_off(self, send_simple):
        """Test that tracker notification email is not sent if notifications
        are disabled at the project level.
        """
        p = M.Project.query.get(shortname='test')
        p.notifications_disabled = True
        self._set_options()
        with patch.object(M.Project.query, 'get') as get:
            get.side_effect = lambda * \
                a, **k: None if 'bugs' in k.get('shortname', '') else p
            self.new_ticket(summary='test')
        assert send_simple.call_count == 0, send_simple.call_count

    def test_footer(self):
        self._set_options(monitoring_type='AllTicketChanges')
        M.MonQTask.query.remove()
        self.new_ticket(summary='test')
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        email_tasks = M.MonQTask.query.find(
            dict(task_name='allura.tasks.mail_tasks.sendsimplemail')).all()
        assert 'Sent from localhost because mailinglist@example.com is subscribed to http://localhost/p/test/bugs/' in email_tasks[
            0].kwargs['text']
        assert 'a project admin can change settings at http://localhost/p/test/admin/bugs/options' in email_tasks[
            0].kwargs['text']


class TestCustomUserField(TrackerTestController):

    def setUp(self):
        super(TestCustomUserField, self).setUp()
        params = dict(
            custom_fields=[
                dict(name='_code_review', label='Code Review', type='user',
                     show_in_search='on')],
            open_status_names='aa bb',
            closed_status_names='cc',
        )
        self.app.post(
            '/admin/bugs/set_custom_fields',
            params=variable_encode(params))

    def test_blank_user(self):
        kw = {'custom_fields._code_review': ''}
        ticket_view = self.new_ticket(
            summary='test custom fields', **kw).follow()
        # summary header shows 'nobody'
        assert ticket_view.html.findAll('label', 'simple',
                                        text='Code Review:')[1].parent.parent.text == 'Code Review:nobody'
        # form input is blank
        select = ticket_view.html.find('select',
                                       dict(name='ticket_form.custom_fields._code_review'))
        selected = None
        for option in select.findChildren():
            if option.get('selected'):
                selected = option
        assert selected is None

    def test_non_project_member(self):
        """ Test that you can't put a non-project-member user in a custom
        user field.
        """
        kw = {'custom_fields._code_review': 'test-user-0'}
        assert_raises(ValueError, self.new_ticket,
                      summary='test custom fields', **kw)

    def test_project_member(self):
        kw = {'custom_fields._code_review': 'test-admin'}
        ticket_view = self.new_ticket(
            summary='test custom fields', **kw).follow()
        # summary header shows 'nobody'
        assert ticket_view.html.findAll('label', 'simple',
                                        text='Code Review:')[1].parent.parent.text == 'Code Review:Test Admin'
        # form input is blank
        select = ticket_view.html.find('select',
                                       dict(name='ticket_form.custom_fields._code_review'))
        selected = None
        for option in select.findChildren():
            if option.get('selected'):
                selected = option
        assert_equal(selected['value'], 'test-admin')

    def test_change_user_field(self):
        kw = {'custom_fields._code_review': ''}
        r = self.new_ticket(summary='test custom fields', **kw).follow()
        f = r.forms[1]
        # Populate ProjectUserCombo's select with option we want.
        # This is a workaround for tests,
        # in real enviroment this is populated via ajax.
        f['ticket_form.custom_fields._code_review'].options = [
            ('test-admin', False)]
        f['ticket_form.custom_fields._code_review'] = 'test-admin'
        r = f.submit().follow()
        assert '<li><strong>Code Review</strong>: Test Admin' in r

    def test_search_results(self):
        kw = {'custom_fields._code_review': 'test-admin'}
        self.new_ticket(summary='test custom fields', **kw)
        r = self.app.get('/bugs/')
        assert r.html.find('table', 'ticket-list').findAll('th')[7].text[:11] == 'Code Review'
        assert r.html.find('table', 'ticket-list').tbody.tr.findAll('td')[7].text == 'Test Admin'


class TestHelpTextOptions(TrackerTestController):

    def _set_options(self, new_txt='', search_txt=''):
        r = self.app.post('/admin/bugs/set_options', params={
            'TicketHelpNew': new_txt,
            'TicketHelpSearch': search_txt,
        })
        return r

    def test_help_text(self):
        self._set_options(
            new_txt='**foo**',
            search_txt='*bar*')
        r = self.app.get('/bugs/')
        assert '<em>bar</em>' in r
        r = self.app.get('/bugs/search', params=dict(q='test'))
        assert '<em>bar</em>' in r
        r = self.app.get('/bugs/milestone/1.0/')
        assert '<em>bar</em>' in r
        r = self.app.get('/bugs/new/')
        assert '<strong>foo</strong>' in r

        self._set_options()
        r = self.app.get('/bugs/')
        assert len(
            r.html.findAll(attrs=dict(id='search-ticket-help-msg'))) == 0
        r = self.app.get('/bugs/search', params=dict(q='test'))
        assert len(
            r.html.findAll(attrs=dict(id='search-ticket-help-msg'))) == 0
        r = self.app.get('/bugs/milestone/1.0/')
        assert len(
            r.html.findAll(attrs=dict(id='search-ticket-help-msg'))) == 0
        r = self.app.get('/bugs/new/')
        assert len(r.html.findAll(attrs=dict(id='new-ticket-help-msg'))) == 0


class test_show_default_fields(TrackerTestController):

    def test_show_default_fields(self):
        r = self.app.get('/admin/bugs/fields')
        assert '<td>Ticket Number</td> <td><input type="checkbox" name="ticket_num" checked ></td>' in r
        assert '<td>Summary</td> <td><input type="checkbox" name="summary" checked ></td>' in r
        assert '<td>Milestone</td> <td><input type="checkbox" name="_milestone" checked ></td>' in r
        assert '<td>Status</td> <td><input type="checkbox" name="status" checked ></td>' in r
        assert '<td>Owner</td> <td><input type="checkbox" name="assigned_to" checked ></td>' in r
        assert '<td>Creator</td> <td><input type="checkbox" name="reported_by" ></td>' in r
        assert '<td>Created</td> <td><input type="checkbox" name="created_date" checked ></td>' in r
        assert '<td>Updated</td> <td><input type="checkbox" name="mod_date" checked ></td>' in r
        assert '<td>Labels</td> <td><input type="checkbox" name="labels" ></td>' in r
        self.new_ticket(summary='test')
        M.MonQTask.run_ready()
        r = self.app.get('/bugs/search', params=dict(q='test'))
        assert '<td><a href="/p/test/bugs/1/">1</a></td>' in r
        p = M.Project.query.get(shortname='test')
        app = p.app_instance('bugs')
        app.globals.show_in_search['ticket_num'] = False
        r = self.app.get('/bugs/search', params=dict(q='test'))
        assert '<td><a href="/p/test/bugs/1/">1</a></td>' not in r
        self.app.post('/admin/bugs/allow_default_field',
                      params={'status': 'on'})
        r = self.app.get('/admin/bugs/fields')
        assert '<td>Ticket Number</td> <td><input type="checkbox" name="ticket_num" ></td>' in r
        assert '<td>Summary</td> <td><input type="checkbox" name="summary" ></td>' in r
        assert '<td>Milestone</td> <td><input type="checkbox" name="_milestone" ></td>' in r
        assert '<td>Status</td> <td><input type="checkbox" name="status" checked ></td>' in r
        assert '<td>Owner</td> <td><input type="checkbox" name="assigned_to" ></td>' in r
        assert '<td>Creator</td> <td><input type="checkbox" name="reported_by" ></td>' in r
        assert '<td>Created</td> <td><input type="checkbox" name="created_date" ></td>' in r
        assert '<td>Updated</td> <td><input type="checkbox" name="mod_date" ></td>' in r
        assert '<td>Labels</td> <td><input type="checkbox" name="labels" ></td>' in r


class TestBulkMove(TrackerTestController):

    def setUp(self):
        super(TestBulkMove, self).setUp()
        self.new_ticket(summary='A New Hope')
        self.new_ticket(summary='The Empire Strikes Back')
        self.new_ticket(summary='Return Of The Jedi')
        M.MonQTask.run_ready()

    def test_access_restriction(self):
        self.app.get('/bugs/move/', status=200)
        self.app.get('/bugs/move/',
                     extra_environ={'username': 'test-user-0'},
                     status=403)
        self.app.get('/bugs/move/',
                     extra_environ={'username': '*anonymous'},
                     status=302)
        self.app.post('/bugs/move_tickets',
                      extra_environ={'username': 'test-user-0'},
                      status=403)

    def test_ticket_list(self):
        r = self.app.get('/bugs/move/?q=The')
        tickets_table = r.html.find('tbody', attrs={'class': 'ticket-list'})
        tickets = tickets_table.findAll('tr')
        assert_equal(len(tickets), 2)
        assert_in('The Empire Strikes Back', tickets_table.text)
        assert_in('Return Of The Jedi', tickets_table.text)

    @td.with_tool('test', 'Tickets', 'bugs2')
    @td.with_tool('test2', 'Tickets', 'bugs')
    @td.with_tool('test2', 'Tickets', 'bugs2')
    def test_controls_present(self):
        r = self.app.get('/bugs/move/')
        trackers = r.html.find('select', {'name': 'tracker'}).findAll('option')
        trackers = set([t.text for t in trackers])
        expected = set(
            ['test/bugs', 'test/bugs2', 'test2/bugs', 'test2/bugs2'])
        assert_equal(trackers, expected)
        move_btn = r.html.find(
            'input', attrs={'type': 'submit', 'value': 'Move'})
        assert move_btn is not None

    @td.with_tool('test2', 'Tickets', 'bugs')
    def test_move(self):
        tickets = [
            tm.Ticket.query.find(
                {'summary': 'The Empire Strikes Back'}).first(),
            tm.Ticket.query.find({'summary': 'Return Of The Jedi'}).first()]
        p = M.Project.query.get(shortname='test2')
        original_p = M.Project.query.get(shortname='test')
        tracker = p.app_instance('bugs')
        original_tracker = original_p.app_instance('bugs')
        r = self.app.post('/p/test/bugs/move_tickets', {
            'tracker': str(tracker.config._id),
            '__ticket_ids': [t._id for t in tickets],
            '__search': '',
        })
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        ac_id = tracker.config._id
        original_ac_id = original_tracker.config._id
        moved_tickets = tm.Ticket.query.find({'app_config_id': ac_id}).all()
        original_tickets = tm.Ticket.query.find(
            {'app_config_id': original_ac_id}).all()
        assert_equal(len(moved_tickets), 2)
        assert_equal(len(original_tickets), 1)
        for ticket in moved_tickets:
            assert_equal(ticket.discussion_thread.app_config_id, ac_id)
            assert_equal(
                ticket.discussion_thread.discussion.app_config_id, ac_id)
            post = ticket.discussion_thread.last_post
            assert_in('Ticket moved from /p/test/bugs/', post.text)
        for t in original_tickets:
            assert_equal(t.discussion_thread.app_config_id, original_ac_id)
            assert_equal(t.discussion_thread.discussion.app_config_id,
                         original_ac_id)
            assert t.discussion_thread.last_post is None

    @td.with_tool('test2', 'Tickets', 'bugs2')
    def test_notifications(self):
        tickets = [
            tm.Ticket.query.find({'summary': 'A New Hope'}).first(),
            tm.Ticket.query.find(
                {'summary': 'The Empire Strikes Back'}).first(),
            tm.Ticket.query.find({'summary': 'Return Of The Jedi'}).first()]
        p = M.Project.query.get(shortname='test2')
        tracker = p.app_instance('bugs2')
        first_user = M.User.by_username('test-user-0')
        second_user = M.User.by_username('test-user-1')
        admin = M.User.by_username('test-admin')
        tickets[0].subscribe(user=first_user)
        tickets[1].subscribe(user=second_user)
        M.MonQTask.query.remove()
        r = self.app.post('/p/test/bugs/move_tickets', {
            'tracker': str(tracker.config._id),
            '__ticket_ids': [t._id for t in tickets],
            '__search': '',
        })
        M.MonQTask.run_ready()
        emails = M.MonQTask.query.find(
            dict(task_name='allura.tasks.mail_tasks.sendmail')).all()
        assert_equal(len(emails), 3)
        for email in emails:
            assert_equal(email.kwargs.subject,
                         '[test:bugs] Mass ticket moving by Test Admin')
        first_user_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': str(first_user._id)
        }).all()
        assert_equal(len(first_user_email), 1)
        first_user_email = first_user_email[0]
        second_user_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': str(second_user._id)
        }).all()
        assert_equal(len(second_user_email), 1)
        second_user_email = second_user_email[0]
        admin_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': str(admin._id)
        }).all()
        assert_equal(len(admin_email), 1)
        admin_email = admin_email[0]

        email_header = 'Tickets were moved from [test:bugs] to [test2:bugs2]\n'
        first_ticket_changes = 'A New Hope'
        second_ticket_changes = 'The Empire Strikes Back'
        third_ticket_changes = 'Return Of The Jedi'
        assert_in(email_header, first_user_email.kwargs.text)
        assert_in(first_ticket_changes, first_user_email.kwargs.text)
        assert_in(email_header, second_user_email.kwargs.text)
        assert_in(second_ticket_changes, second_user_email.kwargs.text)
        assert_in(email_header, admin_email.kwargs.text)
        assert_in(first_ticket_changes, admin_email.kwargs.text)
        assert_in(second_ticket_changes, admin_email.kwargs.text)
        assert_in(third_ticket_changes, admin_email.kwargs.text)
        # After tickets moved, user should see a flash
        mbox = M.Mailbox.query.get(user_id=admin._id, is_flash=True)
        notification_id = mbox.queue[-1]
        notification = M.Notification.query.get(_id=notification_id)
        assert_equal(notification.text,
                     'Tickets moved from test/bugs to test2/bugs2')

    @td.with_tool('test2', 'Tickets', 'bugs2')
    def test_monitoring_email(self):
        self.app.post('/admin/bugs/set_options', params={
            'TicketMonitoringEmail': 'monitoring@email.com',
            'TicketMonitoringType': 'AllTicketChanges',
        })
        tickets = [
            tm.Ticket.query.find({'summary': 'A New Hope'}).first(),
            tm.Ticket.query.find(
                {'summary': 'The Empire Strikes Back'}).first(),
            tm.Ticket.query.find({'summary': 'Return Of The Jedi'}).first()]
        p = M.Project.query.get(shortname='test2')
        tracker = p.app_instance('bugs2')
        M.MonQTask.query.remove()
        r = self.app.post('/p/test/bugs/move_tickets', {
            'tracker': str(tracker.config._id),
            '__ticket_ids': [t._id for t in tickets],
            '__search': '',
        })
        M.MonQTask.run_ready()
        emails = M.MonQTask.query.find(
            dict(task_name='allura.tasks.mail_tasks.sendmail')).all()
        assert_equal(len(emails), 2)
        for email in emails:
            assert_equal(email.kwargs.subject,
                         '[test:bugs] Mass ticket moving by Test Admin')
        admin_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': str(M.User.by_username('test-admin')._id)
        }).all()
        monitoring_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': 'monitoring@email.com'
        }).all()
        assert_equal(len(admin_email), 1)
        assert_equal(len(monitoring_email), 1)
        admin_email_text = admin_email[0].kwargs.text
        assert_in('test:bugs:#1 --> test2:bugs2:#1 A New Hope',
                  admin_email_text)
        assert_in('test:bugs:#2 --> test2:bugs2:#2 The Empire Strikes Back',
                  admin_email_text)
        assert_in('test:bugs:#3 --> test2:bugs2:#3 Return Of The Jedi',
                  admin_email_text)
        monitoring_email_text = monitoring_email[0].kwargs.text
        assert_in('test:bugs:#1 --> test2:bugs2:#1 A New Hope',
                  monitoring_email_text)
        assert_in('test:bugs:#2 --> test2:bugs2:#2 The Empire Strikes Back',
                  monitoring_email_text)
        assert_in('test:bugs:#3 --> test2:bugs2:#3 Return Of The Jedi',
                  monitoring_email_text)

    @td.with_tool('test2', 'Tickets', 'bugs2')
    def test_monitoring_email_public_only(self):
        """Test that private tickets are not included in bulk move
        notifications if the "public only" option is selected.
        """
        self.app.post('/admin/bugs/set_options', params={
            'TicketMonitoringEmail': 'monitoring@email.com',
            'TicketMonitoringType': 'AllPublicTicketChanges',
        })
        self.new_ticket(summary='test first ticket', status='open')
        self.new_ticket(summary='test second ticket',
                        status='open', private=True)
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        tickets = [
            tm.Ticket.query.find({'summary': 'test first ticket'}).first(),
            tm.Ticket.query.find({'summary': 'test second ticket'}).first()]
        M.MonQTask.query.remove()
        p = M.Project.query.get(shortname='test2')
        tracker = p.app_instance('bugs2')
        self.app.post('/p/test/bugs/move_tickets', {
            'tracker': str(tracker.config._id),
            '__ticket_ids': [t._id for t in tickets],
            '__search': '',
        })
        M.MonQTask.run_ready()
        emails = M.MonQTask.query.find(
            dict(task_name='allura.tasks.mail_tasks.sendmail')).all()
        # one for admin and one for monitoring email
        assert_equal(len(emails), 2)
        for email in emails:
            assert_equal(email.kwargs.subject,
                         '[test:bugs] Mass ticket moving by Test Admin')
        admin = M.User.by_username('test-admin')
        admin_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': str(admin._id)
        }).all()
        monitoring_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': 'monitoring@email.com'
        }).all()
        assert_equal(len(admin_email), 1)
        assert_equal(len(monitoring_email), 1)
        admin_email_text = admin_email[0].kwargs.text
        monitoring_email_text = monitoring_email[0].kwargs.text
        assert_in('second ticket', admin_email_text)
        assert_not_in('second ticket', monitoring_email_text)

    @td.with_tool('test2', 'Tickets', 'bugs2')
    def test_monitoring_email_all_private_moved(self):
        """Test that no monitoring email is sent if the "public only"
        option is selected, and only private tickets were moved.
        """
        self.app.post('/admin/bugs/set_options', params={
            'TicketMonitoringEmail': 'monitoring@email.com',
            'TicketMonitoringType': 'AllPublicTicketChanges',
        })
        self.new_ticket(summary='test first ticket',
                        status='open', private=True)
        self.new_ticket(summary='test second ticket',
                        status='open', private=True)
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        tickets = [
            tm.Ticket.query.find({'summary': 'test first ticket'}).first(),
            tm.Ticket.query.find({'summary': 'test second ticket'}).first()]
        M.MonQTask.query.remove()
        p = M.Project.query.get(shortname='test2')
        tracker = p.app_instance('bugs2')
        self.app.post('/p/test/bugs/move_tickets', {
            'tracker': str(tracker.config._id),
            '__ticket_ids': [t._id for t in tickets],
            '__search': '',
        })
        M.MonQTask.run_ready()
        emails = M.MonQTask.query.find(
            dict(task_name='allura.tasks.mail_tasks.sendmail')).all()
        assert_equal(len(emails), 1)  # only admin email sent
        for email in emails:
            assert_equal(email.kwargs.subject,
                         '[test:bugs] Mass ticket moving by Test Admin')
        admin = M.User.by_username('test-admin')
        admin_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': str(admin._id)
        }).all()
        monitoring_email = M.MonQTask.query.find({
            'task_name': 'allura.tasks.mail_tasks.sendmail',
            'kwargs.destinations': 'monitoring@email.com'
        }).all()
        assert_equal(len(admin_email), 1)
        assert_equal(len(monitoring_email), 0)


def sidebar_contains(response, text):
    sidebar_menu = response.html.find('div', attrs={'id': 'sidebar'})
    return text in str(sidebar_menu)


class TestStats(TrackerTestController):

    def test_stats(self):
        r = self.app.get('/bugs/stats/', status=200)
        assert_in('# tickets: 0', r.body)


class TestNotificationEmailGrouping(TrackerTestController):

    def test_new_ticket_message_id(self):
        self.new_ticket(summary='Test Ticket')
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        email = M.MonQTask.query.find(
            dict(task_name='allura.tasks.mail_tasks.sendmail')).first()
        ticket = tm.Ticket.query.get(ticket_num=1)
        assert_equal(email.kwargs.message_id, ticket.message_id())
        assert_equal(email.kwargs.in_reply_to, None)
        assert_equal(email.kwargs.references, [])

    def test_comments(self):
        def find(d, pred):
            for n, v in d.items():
                if pred(v):
                    return (n, v)

        ticket_view = self.new_ticket(summary='Test Ticket').follow()
        ThreadLocalORMSession.flush_all()
        M.MonQTask.query.remove()
        ThreadLocalORMSession.flush_all()
        _, form = find(ticket_view.forms, lambda f: f.action.endswith('/post'))
        field, _ = find(form.fields, lambda f: f[0].tag == 'textarea')
        form.set(field, 'top-level comment')
        r = form.submit()
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        # Check that comment notification refers ticket's message id
        email = M.MonQTask.query.find(
            dict(task_name='allura.tasks.mail_tasks.sendmail')).first()
        ticket = tm.Ticket.query.get(ticket_num=1)
        top_level_comment = ticket.discussion_thread.posts[0]
        top_level_comment_msg_id = ticket.url() + top_level_comment._id
        assert_equal(email.kwargs.message_id, top_level_comment_msg_id)
        assert_equal(email.kwargs.in_reply_to, ticket.message_id())
        assert_equal(email.kwargs.references, [ticket.message_id()])

        ThreadLocalORMSession.flush_all()
        M.MonQTask.query.remove()
        ThreadLocalORMSession.flush_all()
        r = self.app.get('/bugs/1/')
        _, form = find(r.forms, lambda f: f.action.endswith('/reply'))
        field, _ = find(form.fields, lambda f: f[0].tag == 'textarea')
        reply_text = 'Reply to top-level-comment'
        form.set(field, reply_text)
        r = form.submit()
        ThreadLocalORMSession.flush_all()
        M.MonQTask.run_ready()
        ThreadLocalORMSession.flush_all()
        # Check that reply notification refers top-level comment's message id
        email = M.MonQTask.query.find(
            dict(task_name='allura.tasks.mail_tasks.sendmail')).first()
        ticket = tm.Ticket.query.get(ticket_num=1)
        reply = [
            post for post in ticket.discussion_thread.posts if post.text == reply_text][0]
        assert_equal(email.kwargs.message_id, ticket.url() + reply._id)
        assert_equal(email.kwargs.in_reply_to, top_level_comment_msg_id)
        assert_equal(email.kwargs.references,
                     [ticket.message_id(), top_level_comment_msg_id])


def test_status_passthru():
    setup_basic_test()
    c.project = M.Project.query.get(shortname='test')
    c.user = M.User.by_username('test-admin')
    c.project.install_app('tickets', mount_point='tsp',
                          open_status_names='foo bar', closed_status_names='qux baz')
    ThreadLocalORMSession.flush_all()
    app = c.project.app_instance('tsp')
    assert_items_equal(app.globals.set_of_open_status_names, ['foo', 'bar'])
    assert_items_equal(app.globals.set_of_closed_status_names, ['qux', 'baz'])
    assert_not_in('open_status_names', app.config.options)
    assert_not_in('closed_status_names', app.config.options)
