#       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 json
import os
from cStringIO import StringIO
import urllib2

import PIL
from tg import config
from nose.tools import assert_equal
from ming.orm.ormsession import ThreadLocalORMSession
from paste.httpexceptions import HTTPFound

import allura
from allura import model as M
from allura.tests import TestController
from allura.tests import decorators as td
from allura.lib import helpers as h

class TestNeighborhood(TestController):

    def setUp(self):
        # change the override_root config value to change which root controller the test uses
        self._make_app = allura.config.middleware.make_app
        def make_app(global_conf, full_stack=True, **app_conf):
            app_conf['override_root'] = 'basetest_neighborhood_root'
            return self._make_app(global_conf, full_stack, **app_conf)
        allura.config.middleware.make_app = make_app
        super(TestNeighborhood, self).setUp()

    def tearDown(self):
        super(TestNeighborhood, self).tearDown()
        allura.config.middleware.make_app = self._make_app

    def test_home_project(self):
        r = self.app.get('/adobe/wiki/')
        assert r.location.endswith('/adobe/wiki/Home/')
        r = r.follow()
        assert 'This is the "Adobe" neighborhood' in str(r), str(r)
        r = self.app.get('/adobe/admin/', extra_environ=dict(username='test-user'),
                         status=403)

    def test_redirect(self):
        r = self.app.post('/adobe/_admin/update',
                          params=dict(redirect='wiki/Home/'),
                          extra_environ=dict(username='root'))
        r = self.app.get('/adobe/')
        assert r.location.endswith('/adobe/wiki/Home/')

    def test_admin(self):
        r = self.app.get('/adobe/_admin/', extra_environ=dict(username='root'))
        r = self.app.get('/adobe/_admin/overview', extra_environ=dict(username='root'))
        r = self.app.get('/adobe/_admin/accolades', extra_environ=dict(username='root'))
        neighborhood = M.Neighborhood.query.get(name='Adobe')
        neighborhood.features['google_analytics'] = True
        r = self.app.post('/adobe/_admin/update',
                          params=dict(name='Mozq1', css='', homepage='# MozQ1!', tracking_id='U-123456'),
                          extra_environ=dict(username='root'))
        r = self.app.post('/adobe/_admin/update',
                          params=dict(name='Mozq1', css='', homepage='# MozQ1!\n[Root]'),
                          extra_environ=dict(username='root'))
        # make sure project_template is validated as proper json
        r = self.app.post('/adobe/_admin/update',
                          params=dict(project_template='{'),
                          extra_environ=dict(username='root'))
        assert 'Invalid JSON' in r

    def test_admin_overview_audit_log(self):

        def check_log(message):
            return M.AuditLog.query.find({'message': message}).count() == 1

        nbhd = M.Neighborhood.query.get(name='Projects')
        nbhd.features['css'] = 'custom'
        nbhd.features['google_analytics'] = True
        params = {
            'name': 'Pjs',
            'redirect': 'http://fake.org/',
            'show_title': 'false',
            'allow_browse': 'false',
            'css': '.class { border: 1px; }',
            'tracking_id': 'U-123456',
            'homepage': '[Homepage]',
            'project_list_url': 'http://fake.org/project_list',
            'project_template': '{"name": "template"}',
            'anchored_tools': 'wiki:Wiki'

        }
        self.app.post('/p/_admin/update', params=params,
                      extra_environ=dict(username='root'))
        # must get as many log records as many values are updated
        assert M.AuditLog.query.find().count() == len(params)

        assert check_log('change neighborhood name to Pjs')
        assert check_log('change neighborhood redirect to http://fake.org/')
        assert check_log('change neighborhood show title to False')
        assert check_log('change neighborhood allow browse to False')
        assert check_log('change neighborhood css to .class { border: 1px; }')
        assert check_log('change neighborhood homepage to [Homepage]')
        assert check_log('change neighborhood project list url to '
                         'http://fake.org/project_list')

        assert check_log('change neighborhood project template to '
                         '{"name": "template"}')
        assert check_log('update neighborhood tracking_id')

    @td.with_wiki
    def test_anchored_tools(self):
        neighborhood = M.Neighborhood.query.get(name='Projects')

        r = self.app.post('/p/_admin/update',
                          params=dict(name='Projects',
                                      anchored_tools='wiki:Wiki, tickets:Ticket'),
                          extra_environ=dict(username='root'))
        assert 'error' not in self.webflash(r)
        r = self.app.post('/p/_admin/update',
                          params=dict(name='Projects',
                                      anchored_tools='w!iki:Wiki, tickets:Ticket'),
                          extra_environ=dict(username='root'))
        assert 'error' in self.webflash(r)
        assert_equal(neighborhood.anchored_tools, 'wiki:Wiki, tickets:Ticket')

        r = self.app.post('/p/_admin/update',
                          params=dict(name='Projects',
                                      anchored_tools='wiki:Wiki,'),
                          extra_environ=dict(username='root'))
        assert 'error' in self.webflash(r)
        assert_equal(neighborhood.anchored_tools, 'wiki:Wiki, tickets:Ticket')

        r = self.app.post('/p/_admin/update',
                          params=dict(name='Projects',
                                      anchored_tools='badname,'),
                          extra_environ=dict(username='root'))
        assert 'error' in self.webflash(r)
        assert_equal(neighborhood.anchored_tools, 'wiki:Wiki, tickets:Ticket')

        r = self.app.get('/p/test/admin/overview')
        top_nav = r.html.find(id='top_nav')
        assert top_nav.find(href='/p/test/wiki/'), top_nav
        assert top_nav.find(href='/p/test/tickets/'), top_nav

        r = self.app.get('/p/test/admin/tools')
        assert '<div class="fleft isnt_sorted">' in r
        delete_tool = r.html.find('a', {'class':'mount_delete'})
        assert_equal(len(delete_tool), 1)

    def test_show_title(self):
        r = self.app.get('/adobe/_admin/overview', extra_environ=dict(username='root'))
        neighborhood = M.Neighborhood.query.get(name='Adobe')
        # if not set show_title must be True
        assert neighborhood.show_title
        # title should be present
        assert 'class="project_title"' in str(r)
        r = self.app.post('/adobe/_admin/update',
                          params=dict(name='Mozq1', css='',
                                      homepage='# MozQ1!',
                                      tracking_id='U-123456',
                                      show_title='false'),
                          extra_environ=dict(username='root'))
        # no title now
        r = self.app.get('/adobe/', extra_environ=dict(username='root'))
        assert 'class="project_title"' not in str(r)
        r = self.app.get('/adobe/wiki/Home/',
                         extra_environ=dict(username='root'))
        assert 'class="project_title"' not in str(r)

        # title must be present on project page
        r = self.app.get('/adobe/adobe-1/admin/',
                         extra_environ=dict(username='root'))
        assert 'class="project_title"' in str(r)


    def test_admin_stats_del_count(self):
        neighborhood = M.Neighborhood.query.get(name='Adobe')
        proj = M.Project.query.get(neighborhood_id=neighborhood._id)
        proj.deleted = True
        ThreadLocalORMSession.flush_all()
        r = self.app.get('/adobe/_admin/stats/', extra_environ=dict(username='root'))
        assert 'Deleted: 1' in r
        assert 'Private: 0' in r

    def test_admin_stats_priv_count(self):
        neighborhood = M.Neighborhood.query.get(name='Adobe')
        proj = M.Project.query.get(neighborhood_id=neighborhood._id)
        proj.deleted = False
        proj.private = True
        ThreadLocalORMSession.flush_all()
        r = self.app.get('/adobe/_admin/stats/', extra_environ=dict(username='root'))
        assert 'Deleted: 0' in r
        assert 'Private: 1' in r

    def test_admin_stats_adminlist(self):
        neighborhood = M.Neighborhood.query.get(name='Adobe')
        proj = M.Project.query.get(neighborhood_id=neighborhood._id)
        proj.private = False
        ThreadLocalORMSession.flush_all()
        r = self.app.get('/adobe/_admin/stats/adminlist', extra_environ=dict(username='root'))
        pq = M.Project.query.find(dict(neighborhood_id=neighborhood._id, deleted=False))
        pq.sort('name')
        projects = pq.skip(0).limit(int(25)).all()
        for proj in projects:
            admin_role = M.ProjectRole.query.get(project_id=proj.root_project._id, name='Admin')
            if admin_role is None:
                continue
            user_role_list = M.ProjectRole.query.find(dict(project_id=proj.root_project._id, name=None)).all()
            for ur in user_role_list:
                if ur.user is not None and admin_role._id in ur.roles:
                    assert proj.name in r
                    assert ur.user.username in r

    def test_icon(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 = ('icon', file_name, file_data)

        r = self.app.get('/adobe/_admin/', extra_environ=dict(username='root'))
        r = self.app.post('/adobe/_admin/update',
                          params=dict(name='Mozq1', css='', homepage='# MozQ1'),
                          extra_environ=dict(username='root'), upload_files=[upload])
        r = self.app.get('/adobe/icon')
        image = PIL.Image.open(StringIO(r.body))
        assert image.size == (48, 48)

        r = self.app.get('/adobe/icon?foo=bar')

    def test_google_analytics(self):
        # analytics allowed
        neighborhood = M.Neighborhood.query.get(name='Adobe')
        neighborhood.features['google_analytics'] = True
        r = self.app.get('/adobe/_admin/overview', extra_environ=dict(username='root'))
        assert 'Analytics Tracking ID' in r
        r = self.app.get('/adobe/adobe-1/admin/overview', extra_environ=dict(username='root'))
        assert 'Analytics Tracking ID' in r
        r = self.app.post('/adobe/_admin/update',
                          params=dict(name='Adobe', css='', homepage='# MozQ1', tracking_id='U-123456'),
                          extra_environ=dict(username='root'))
        r = self.app.post('/adobe/adobe-1/admin/update',
                          params=dict(tracking_id='U-654321'),
                          extra_environ=dict(username='root'))
        r = self.app.get('/adobe/adobe-1/admin/overview', extra_environ=dict(username='root'))
        assert "_add_tracking('nbhd', 'U-123456');" in r
        assert "_add_tracking('proj', 'U-654321');" in r
        # analytics not allowed
        neighborhood = M.Neighborhood.query.get(name='Adobe')
        neighborhood.features['google_analytics'] = False
        r = self.app.get('/adobe/_admin/overview', extra_environ=dict(username='root'))
        assert 'Analytics Tracking ID' not in r
        r = self.app.get('/adobe/adobe-1/admin/overview', extra_environ=dict(username='root'))
        assert 'Analytics Tracking ID' not in r
        r = self.app.get('/adobe/adobe-1/admin/overview', extra_environ=dict(username='root'))
        assert "_add_tracking('nbhd', 'U-123456');" not in r
        assert "_add_tracking('proj', 'U-654321');" not in r

    def test_custom_css(self):
        test_css = '.test{color:red;}'
        custom_css = 'Custom CSS'

        neighborhood = M.Neighborhood.query.get(name='Adobe')
        neighborhood.css = test_css
        neighborhood.features['css'] = 'none'
        r = self.app.get('/adobe/')
        assert test_css not in r
        r = self.app.get('/adobe/_admin/overview', extra_environ=dict(username='root'))
        assert custom_css not in r

        neighborhood = M.Neighborhood.query.get(name='Adobe')
        neighborhood.features['css'] = 'picker'
        r = self.app.get('/adobe/')
        while isinstance(r.response, HTTPFound):
            r = r.follow()
        assert test_css in r
        r = self.app.get('/adobe/_admin/overview', extra_environ=dict(username='root'))
        assert custom_css in r

        neighborhood = M.Neighborhood.query.get(name='Adobe')
        neighborhood.features['css'] = 'custom'
        r = self.app.get('/adobe/')
        while isinstance(r.response, HTTPFound):
            r = r.follow()
        assert test_css in r
        r = self.app.get('/adobe/_admin/overview', extra_environ=dict(username='root'))
        assert custom_css in r

    def test_picker_css(self):
        neighborhood = M.Neighborhood.query.get(name='Adobe')
        neighborhood.features['css'] = 'picker'

        r = self.app.get('/adobe/_admin/overview', extra_environ=dict(username='root'))
        assert 'Project title, font' in r
        assert 'Project title, color' in r
        assert 'Bar on top' in r
        assert 'Title bar, background' in r
        assert 'Title bar, foreground' in r

        r = self.app.post('/adobe/_admin/update',
                          params={'name': 'Adobe',
                                  'css': '',
                                  'homepage': '',
                                  'css-projecttitlefont': 'arial,sans-serif',
                                  'css-projecttitlecolor': 'green',
                                  'css-barontop': '#555555',
                                  'css-titlebarbackground': '#333',
                                  'css-titlebarcolor': '#444',
                                  'css-addopt-icon-theme': 'dark'},
                          extra_environ=dict(username='root'), upload_files=[])
        neighborhood = M.Neighborhood.query.get(name='Adobe')
        assert '/*projecttitlefont*/.project_title{font-family:arial,sans-serif;}' in neighborhood.css
        assert '/*projecttitlecolor*/.project_title{color:green;}' in neighborhood.css
        assert '/*barontop*/.pad h2.colored {background-color:#555555; background-image: none;}' in neighborhood.css
        assert '/*titlebarbackground*/.pad h2.title{background-color:#333; background-image: none;}' in neighborhood.css
        assert "/*titlebarcolor*/.pad h2.title, .pad h2.title small a {color:#444;} "\
               ".pad h2.dark small b.ico {background-image: "\
               "url('/nf/_ew_/theme/allura/images/neo-icon-set-ffffff-256x350.png');}" in neighborhood.css

    def test_max_projects(self):
        # Set max value to unlimit
        neighborhood = M.Neighborhood.query.get(name='Projects')
        neighborhood.features['max_projects'] = None
        r = self.app.post('/p/register',
                          params=dict(project_unixname='maxproject1', project_name='Max project1', project_description='', neighborhood='Projects'),
                          antispam=True,
                          extra_environ=dict(username='root'), status=302)
        assert '/p/maxproject1/admin' in r.location

        # Set max value to 0
        neighborhood = M.Neighborhood.query.get(name='Projects')
        neighborhood.features['max_projects'] = 0
        r = self.app.post('/p/register',
                          params=dict(project_unixname='maxproject2', project_name='Max project2', project_description='', neighborhood='Projects'),
                          antispam=True,
                          extra_environ=dict(username='root'))
        while isinstance(r.response, HTTPFound):
            r = r.follow()
        assert 'You have exceeded the maximum number of projects' in r

    def test_project_rate_limit(self):
        # Set rate limit to unlimit
        with h.push_config(config, **{'project.rate_limits': '{}'}):
            r = self.app.post('/p/register',
                              params=dict(project_unixname='rateproject1', project_name='Rate project1', project_description='', neighborhood='Projects'),
                              antispam=True,
                              extra_environ=dict(username='test-user-1'), status=302)
            assert '/p/rateproject1/admin' in r.location

        # Set rate limit to 1 in first hour of user account
        with h.push_config(config, **{'project.rate_limits': '{"3600": 1}'}):
            r = self.app.post('/p/register',
                              params=dict(project_unixname='rateproject2', project_name='Rate project2', project_description='', neighborhood='Projects'),
                              antispam=True,
                              extra_environ=dict(username='test-user-1'))
            while isinstance(r.response, HTTPFound):
                r = r.follow()
            assert 'Project creation rate limit exceeded.  Please try again later.' in r

    def test_project_rate_limit_admin(self):
        # Set rate limit to unlimit
        with h.push_config(config, **{'project.rate_limits': '{}'}):
            r = self.app.post('/p/register',
                              params=dict(project_unixname='rateproject1', project_name='Rate project1', project_description='', neighborhood='Projects'),
                              antispam=True,
                              extra_environ=dict(username='root'), status=302)
            assert '/p/rateproject1/admin' in r.location

        # Set rate limit to 1 in first hour of user account
        with h.push_config(config, **{'project.rate_limits': '{"3600": 1}'}):
            r = self.app.post('/p/register',
                              params=dict(project_unixname='rateproject2', project_name='Rate project2', project_description='', neighborhood='Projects'),
                              antispam=True,
                              extra_environ=dict(username='root'))
            assert '/p/rateproject2/admin' in r.location

    def test_invite(self):
        p_nbhd_id = str(M.Neighborhood.query.get(name='Projects')._id)
        r = self.app.get('/adobe/_moderate/', extra_environ=dict(username='root'))
        r = self.app.post('/adobe/_moderate/invite',
                          params=dict(pid='adobe-1', invite='on', neighborhood_id=p_nbhd_id),
                          extra_environ=dict(username='root'))
        r = self.app.get(r.location, extra_environ=dict(username='root'))
        assert 'error' in r
        r = self.app.post('/adobe/_moderate/invite',
                          params=dict(pid='no_such_user', invite='on', neighborhood_id=p_nbhd_id),
                          extra_environ=dict(username='root'))
        r = self.app.get(r.location, extra_environ=dict(username='root'))
        assert 'error' in r
        r = self.app.post('/adobe/_moderate/invite',
                          params=dict(pid='test', invite='on', neighborhood_id=p_nbhd_id),
                          extra_environ=dict(username='root'))
        r = self.app.get(r.location, extra_environ=dict(username='root'))
        assert 'invited' in r, r
        assert 'warning' not in r
        r = self.app.post('/adobe/_moderate/invite',
                          params=dict(pid='test', invite='on', neighborhood_id=p_nbhd_id),
                          extra_environ=dict(username='root'))
        r = self.app.get(r.location, extra_environ=dict(username='root'))
        assert 'warning' in r
        r = self.app.post('/adobe/_moderate/invite',
                          params=dict(pid='test', uninvite='on', neighborhood_id=p_nbhd_id),
                          extra_environ=dict(username='root'))
        r = self.app.get(r.location, extra_environ=dict(username='root'))
        assert 'uninvited' in r
        assert 'warning' not in r
        r = self.app.post('/adobe/_moderate/invite',
                          params=dict(pid='test', uninvite='on', neighborhood_id=p_nbhd_id),
                          extra_environ=dict(username='root'))
        r = self.app.get(r.location, extra_environ=dict(username='root'))
        assert 'warning' in r
        r = self.app.post('/adobe/_moderate/invite',
                          params=dict(pid='test', invite='on', neighborhood_id=p_nbhd_id),
                          extra_environ=dict(username='root'))
        r = self.app.get(r.location, extra_environ=dict(username='root'))
        assert 'invited' in r
        assert 'warning' not in r

    def test_evict(self):
        r = self.app.get('/adobe/_moderate/', extra_environ=dict(username='root'))
        r = self.app.post('/adobe/_moderate/evict',
                          params=dict(pid='test'),
                          extra_environ=dict(username='root'))
        r = self.app.get(r.location, extra_environ=dict(username='root'))
        assert 'error' in r
        r = self.app.post('/adobe/_moderate/evict',
                          params=dict(pid='adobe-1'),
                          extra_environ=dict(username='root'))
        r = self.app.get(r.location, extra_environ=dict(username='root'))
        assert 'adobe-1 evicted to Projects' in r

    def test_home(self):
        r = self.app.get('/adobe/')

    def test_register(self):
        r = self.app.get('/adobe/register', status=405)
        r = self.app.post('/adobe/register',
                          params=dict(project_unixname='', project_name='Nothing', project_description='', neighborhood='Adobe'),
                          antispam=True,
                          extra_environ=dict(username='root'))
        assert r.html.find('div', {'class':'error'}).string == 'Please use only letters, numbers, and dashes 3-15 characters long.'
        r = self.app.post('/adobe/register',
                          params=dict(project_unixname='mymoz', project_name='My Moz', project_description='', neighborhood='Adobe'),
                          antispam=True,
                          extra_environ=dict(username='*anonymous'),
                          status=302)
        r = self.app.post('/adobe/register',
                          params=dict(project_unixname='foo.mymoz', project_name='My Moz', project_description='', neighborhood='Adobe'),
                          antispam=True,
                          extra_environ=dict(username='root'))
        assert r.html.find('div', {'class':'error'}).string == 'Please use only letters, numbers, and dashes 3-15 characters long.'
        r = self.app.post('/p/register',
                          params=dict(project_unixname='test', project_name='Tester', project_description='', neighborhood='Projects'),
                          antispam=True,
                          extra_environ=dict(username='root'))
        assert r.html.find('div', {'class':'error'}).string == 'This project name is taken.'
        r = self.app.post('/adobe/register',
                          params=dict(project_unixname='mymoz', project_name='My Moz', project_description='', neighborhood='Adobe'),
                          antispam=True,
                          extra_environ=dict(username='root'),
                          status=302)

    def test_register_private_fails_for_anon(self):
        r = self.app.post(
            '/p/register',
            params=dict(
                project_unixname='mymoz',
                project_name='My Moz',
                project_description='',
                neighborhood='Projects',
                private_project='on'),
            antispam=True,
            extra_environ=dict(username='*anonymous'),
            status=302)
        assert config.get('auth.login_url', '/auth/') in r.location, r.location

    def test_register_private_fails_for_non_admin(self):
        self.app.post(
            '/p/register',
            params=dict(
                project_unixname='mymoz',
                project_name='My Moz',
                project_description='',
                neighborhood='Projects',
                private_project='on'),
            antispam=True,
            extra_environ=dict(username='test-user'),
            status=403)

    def test_register_private_fails_for_non_private_neighborhood(self):
        # Turn off private
        neighborhood = M.Neighborhood.query.get(name='Projects')
        neighborhood.features['private_projects'] = False
        r = self.app.get('/p/add_project', extra_environ=dict(username='root'))
        assert 'private_project' not in r

        r = self.app.post(
            '/p/register',
            params=dict(
                project_unixname='myprivate1',
                project_name='My Priv1',
                project_description='',
                neighborhood='Projects',
                private_project='on'),
            antispam=True,
            extra_environ=dict(username='root'))
        flash_msg_cookie = urllib2.unquote(r.headers['Set-Cookie'])
        assert 'Internal Error.' in flash_msg_cookie

        proj = M.Project.query.get(shortname='myprivate1', neighborhood_id=neighborhood._id)
        assert proj is None

        # Turn on private
        neighborhood = M.Neighborhood.query.get(name='Projects')
        neighborhood.features['private_projects'] = True
        r = self.app.get('/p/add_project', extra_environ=dict(username='root'))
        assert 'private_project' in r

        self.app.post(
            '/p/register',
            params=dict(
                project_unixname='myprivate2',
                project_name='My Priv2',
                project_description='',
                neighborhood='Projects',
                private_project='on'),
            antispam=True,
            extra_environ=dict(username='root'))

        proj = M.Project.query.get(shortname='myprivate2', neighborhood_id=neighborhood._id)
        assert proj.private

    def test_register_private_ok(self):
        r = self.app.post(
            '/p/register',
            params=dict(
                project_unixname='mymoz',
                project_name='My Moz',
                project_description='',
                neighborhood='Projects',
                private_project='on',
                tools='wiki'),
            antispam=True,
            extra_environ=dict(username='root'),
            status=302)
        assert config.get('auth.login_url', '/auth/') not in r.location, r.location
        r = self.app.get(
            '/p/mymoz/wiki/',
            extra_environ=dict(username='root')).follow(extra_environ=dict(username='root'), status=200)
        r = self.app.get(
            '/p/mymoz/wiki/',
            extra_environ=dict(username='*anonymous'),
            status=302)
        assert config.get('auth.login_url', '/auth/') in r.location, r.location
        self.app.get(
            '/p/mymoz/wiki/',
            extra_environ=dict(username='test-user'),
            status=403)

    def test_project_template(self):
        icon_url = 'file://' + os.path.join(allura.__path__[0], 'nf', 'allura', 'images', 'neo-icon-set-454545-256x350.png')
        test_groups = [{
            "name": "Viewer", # group will be created, all params are valid
            "permissions": ["read"],
            "usernames": ["user01"]
        }, {
            "name": "", # group won't be created - invalid name
            "permissions": ["read"],
            "usernames": ["user01"]
        }, {
            "name": "TestGroup1", # group won't be created - invalid perm name
            "permissions": ["foobar"],
            "usernames": ["user01"]
        }, {
            "name": "TestGroup2", # will be created; 'inspect' perm ignored
            "permissions": ["read", "inspect"],
            "usernames": ["user01", "user02"]
        }, {
            "name": "TestGroup3", # will be created with no users in group
            "permissions": ["admin"]
        }]
        r = self.app.post('/adobe/_admin/update', params=dict(name='Mozq1',
            css='', homepage='# MozQ1!\n[Root]', project_template="""{
                "private":true,
                "icon":{
                    "url":"%s",
                    "filename":"icon.png"
                },
                "tools":{
                    "wiki":{
                        "label":"Wiki",
                        "mount_point":"wiki",
                        "options":{
                            "show_right_bar":false,
                            "show_left_bar":false,
                            "show_discussion":false,
                            "some_url": "http://foo.com/$shortname/"
                        },
                        "home_text":"My home text!"
                    },
                    "discussion":{"label":"Discussion","mount_point":"discussion"},
                    "blog":{"label":"News","mount_point":"news","options":{
                    "show_discussion":false
                    }},
                    "admin":{"label":"Admin","mount_point":"admin"}
                },
                "tool_order":["wiki","discussion","news","admin"],
                "labels":["mmi"],
                "trove_cats":{
                    "topic":[247],
                    "developmentstatus":[11]
                },
                "groups": %s
                }""" % (icon_url, json.dumps(test_groups))),
            extra_environ=dict(username='root'))
        r = self.app.post(
            '/adobe/register',
            params=dict(
                project_unixname='testtemp',
                project_name='Test Template',
                project_description='',
                neighborhood='Mozq1',
                private_project='off'),
            antispam=True,
            extra_environ=dict(username='root'),
            status=302).follow()
        p = M.Project.query.get(shortname='testtemp')
        # make sure the correct tools got installed in the right order
        top_nav = r.html.find('div', {'id':'top_nav'})
        assert top_nav.contents[1].contents[1].contents[1]['href'] == '/adobe/testtemp/wiki/'
        assert 'Wiki' in top_nav.contents[1].contents[1].contents[1].contents[0]
        assert top_nav.contents[1].contents[3].contents[1]['href'] == '/adobe/testtemp/discussion/'
        assert 'Discussion' in top_nav.contents[1].contents[3].contents[1].contents[0]
        assert top_nav.contents[1].contents[5].contents[1]['href'] == '/adobe/testtemp/news/'
        assert 'News' in top_nav.contents[1].contents[5].contents[1].contents[0]
        assert top_nav.contents[1].contents[7].contents[1]['href'] == '/adobe/testtemp/admin/'
        assert 'Admin' in top_nav.contents[1].contents[7].contents[1].contents[0]
        # make sure project is private
        r = self.app.get(
            '/adobe/testtemp/wiki/',
            extra_environ=dict(username='root')).follow(extra_environ=dict(username='root'), status=200)
        r = self.app.get(
            '/adobe/testtemp/wiki/',
            extra_environ=dict(username='*anonymous'),
            status=302)
        # check the labels and trove cats
        r = self.app.get('/adobe/testtemp/admin/trove')
        assert 'mmi' in r
        assert 'Topic :: Communications :: Telephony' in r
        assert 'Development Status :: 5 - Production/Stable' in r
        # check the wiki text
        r = self.app.get('/adobe/testtemp/wiki/').follow()
        assert "My home text!" in r
        # check tool options
        opts = p.app_config('wiki').options
        assert_equal(False, opts.show_discussion)
        assert_equal(False, opts.show_left_bar)
        assert_equal(False, opts.show_right_bar)
        assert_equal("http://foo.com/testtemp/", opts.some_url)
        # check that custom groups/perms/users were setup correctly
        roles = p.named_roles
        for group in test_groups:
            name = group.get('name')
            permissions = group.get('permissions', [])
            usernames = group.get('usernames', [])
            if name in ('Viewer', 'TestGroup2', 'TestGroup3'):
                role = M.ProjectRole.by_name(name, project=p)
                # confirm role created in project
                assert role in roles
                for perm in permissions:
                    # confirm valid permissions added to role, and invalid
                    # permissions ignored
                    if perm in p.permissions:
                        assert M.ACE.allow(role._id, perm) in p.acl
                    else:
                        assert M.ACE.allow(role._id, perm) not in p.acl
                # confirm valid users received role
                for username in usernames:
                    user = M.User.by_username(username)
                    if user and user._id:
                        assert role in user.project_role(project=p).roles
            # confirm roles with invalid json data are not created
            if name in ('', 'TestGroup1'):
                assert name not in roles

    def test_projects_anchored_tools(self):
        r = self.app.post('/adobe/_admin/update', params=dict(name='Adobe',
            css='',
            homepage='# Adobe!\n[Root]',
            project_template="""{
                "private":true,
                "tools":{
                    "wiki":{
                        "label":"Wiki",
                        "mount_point":"wiki",
                        "options":{
                            "show_right_bar":false,
                            "show_left_bar":false,
                            "show_discussion":false,
                            "some_url": "http://foo.com/$shortname/"
                        },
                        "home_text":"My home text!"
                    },
                    "admin":{"label":"Admin","mount_point":"admin"}
                },
                "tool_order":["wiki","admin"],

                }""" ),
            extra_environ=dict(username='root'))
        neighborhood = M.Neighborhood.query.get(name='Adobe')
        neighborhood.anchored_tools ='wiki:Wiki'
        r = self.app.post(
            '/adobe/register',
            params=dict(
                project_unixname='testtemp',
                project_name='Test Template',
                project_description='',
                neighborhood='Adobe',
                private_project='off'),
            antispam=True,
            extra_environ=dict(username='root'))
        r = self.app.get('/adobe/testtemp/admin/tools')
        assert '<a href="/adobe/testtemp/wiki/" class="ui-icon-tool-wiki">' in r
        assert '<a href="/adobe/testtemp/admin/" class="ui-icon-tool-admin">' in r

    def test_name_suggest(self):
        r = self.app.get('/p/suggest_name?project_name=My+Moz')
        assert_equal(r.json, dict(suggested_name='mymoz'))
        r = self.app.get('/p/suggest_name?project_name=Te%st!')
        assert_equal(r.json, dict(suggested_name='test'))

    def test_name_check(self):
        for name in ('My+Moz', 'Te%st!', 'ab', 'a' * 16):
            r = self.app.get('/p/check_names?neighborhood=Projects&project_unixname=%s' % name)
            assert_equal(r.json, {'project_unixname': 'Please use only letters, numbers, and dashes 3-15 characters long.'})
        r = self.app.get('/p/check_names?neighborhood=Projects&project_unixname=mymoz')
        assert_equal(r.json, {})
        r = self.app.get('/p/check_names?neighborhood=Projects&project_unixname=test')
        assert_equal(r.json, {'project_unixname': 'This project name is taken.'})

    @td.with_tool('test/sub1', 'Wiki', 'wiki')
    def test_neighborhood_project(self):
        self.app.get('/adobe/adobe-1/admin/', status=200)
        self.app.get('/p/test/sub1/wiki/')
        self.app.get('/p/test/sub1/', status=302)
        self.app.get('/p/test/no-such-app/', status=404)

    def test_neighborhood_namespace(self):
        # p/test exists, so try creating adobe/test
        self.app.get('/adobe/test/wiki/', status=404)
        r = self.app.post('/adobe/register',
                          params=dict(project_unixname='test', project_name='Test again', project_description='', neighborhood='Adobe', tools='wiki'),
                          antispam=True,
                          extra_environ=dict(username='root'))
        assert r.status_int == 302, r.html.find('div', {'class':'error'}).string
        r = self.app.get('/adobe/test/wiki/').follow(status=200)

    def test_neighborhood_awards(self):
        file_name = 'adobe_icon.png'
        file_path = os.path.join(allura.__path__[0], 'public', 'nf', 'images', file_name)
        file_data = file(file_path).read()
        upload = ('icon', file_name, file_data)

        r = self.app.get('/adobe/_admin/awards', extra_environ=dict(username='root'))
        r = self.app.post('/adobe/_admin/awards/create',
                          params=dict(short='FOO', full='A basic foo award'),
                          extra_environ=dict(username='root'), upload_files=[upload])
        r = self.app.post('/adobe/_admin/awards/create',
                          params=dict(short='BAR', full='A basic bar award with no icon'),
                          extra_environ=dict(username='root'))
        foo_id = str(M.Award.query.find(dict(short='FOO')).first()._id)
        bar_id = str(M.Award.query.find(dict(short='BAR')).first()._id)
        r = self.app.post('/adobe/_admin/awards/%s/update' % bar_id,
                          params=dict(short='BAR2', full='Updated description.'),
                          extra_environ=dict(username='root')).follow().follow()
        assert 'BAR2' in r
        assert 'Updated description.' in r
        r = self.app.get('/adobe/_admin/awards/%s' % foo_id, extra_environ=dict(username='root'))
        r = self.app.get('/adobe/_admin/awards/%s/icon' % foo_id, extra_environ=dict(username='root'))
        image = PIL.Image.open(StringIO(r.body))
        assert image.size == (48, 48)
        self.app.post('/adobe/_admin/awards/grant',
                          params=dict(grant='FOO', recipient='adobe-1'),
                          extra_environ=dict(username='root'))
        self.app.get('/adobe/_admin/awards/%s/adobe-1' % foo_id, extra_environ=dict(username='root'))
        self.app.post('/adobe/_admin/awards/%s/adobe-1/revoke' % foo_id,
                          extra_environ=dict(username='root'))
        self.app.post('/adobe/_admin/awards/%s/delete' % foo_id,
                          extra_environ=dict(username='root'))

    def test_add_a_project_link(self):
        from pylons import tmpl_context as c
        # Install Home tool for all neighborhoods
        for nb in M.Neighborhood.query.find().all():
            p = nb.neighborhood_project
            with h.push_config(c, user=M.User.query.get()):
                p.install_app('home', 'home', 'Home', ordinal=0)
        r = self.app.get('/p/')
        assert 'Add a Project' in r
        r = self.app.get('/u/', extra_environ=dict(username='test-user'))
        assert 'Add a Project' not in r
        r = self.app.get('/adobe/', extra_environ=dict(username='test-user'))
        assert 'Add a Project' not in r
        r = self.app.get('/u/', extra_environ=dict(username='root'))
        assert 'Add a Project' in r
        r = self.app.get('/adobe/', extra_environ=dict(username='root'))
        assert 'Add a Project' in r

    def test_help(self):
        r = self.app.get('/p/_admin/help/', extra_environ=dict(username='root'))
        assert 'macro' in r

    @td.with_user_project('test-user')
    def test_profile_topnav_menu(self):
        r = self.app.get('/u/test-user/', extra_environ=dict(username='test-user')).follow()
        assert '<a href="/u/test-user/profile/" class="ui-icon-tool-profile">' in r, r

    def test_user_project_creates_on_demand(self):
        M.User.register(dict(username='donald-duck'), make_project=False)
        ThreadLocalORMSession.flush_all()
        self.app.get('/u/donald-duck/')

    def test_disabled_user_has_no_user_project(self):
        user = M.User.register(dict(username='donald-duck'))
        self.app.get('/u/donald-duck/')  # assert it's there
        M.User.query.update(dict(username='donald-duck'), {'$set': {'disabled': True}})
        self.app.get('/u/donald-duck/', status=404)


    def test_more_projects_link(self):
        r = self.app.get('/adobe/adobe-1/admin/')
        link = r.html.find('div', {'class':'neighborhood_title_link'}).find('a')
        assert 'View More Projects' in str(link)
        assert link['href'] == '/adobe/'
