#       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 re
import os
import allura
import unittest
import hashlib
import six
from mock import patch, Mock

from bson import ObjectId
from alluratest.tools import with_setup, assert_equal, assert_in, assert_not_in
from tg import tmpl_context as c, app_globals as g
import tg
from oembed import OEmbedError

from ming.orm import ThreadLocalORMSession
from alluratest.controller import (
    setup_basic_test,
    setup_global_objects,
    setup_unit_test,
    setup_functional_test,
    setup_trove_categories,
)

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

from forgewiki import model as WM
from forgeblog import model as BM


def squish_spaces(text):
    # \s is whitespace
    # \xa0 is &nbsp; in unicode form
    return re.sub(r'[\s\xa0]+', ' ', text)


def setUp():
    """Method called by nose once before running the package.  Some functions need it run again to reset data"""
    setup_basic_test()
    setup_unit_test()
    setup_with_tools()


def tearDown():
    setUp()


@td.with_wiki
def setup_with_tools():
    setup_global_objects()


@td.with_wiki
def test_app_globals():
    with h.push_context('test', 'wiki', neighborhood='Projects'):
        assert g.app_static(
            'css/wiki.css') == '/nf/_static_/wiki/css/wiki.css', g.app_static('css/wiki.css')


@with_setup(setUp)
def test_macro_projects():
    file_name = 'neo-icon-set-454545-256x350.png'
    file_path = os.path.join(
        allura.__path__[0], 'nf', 'allura', 'images', file_name)

    p_nbhd = M.Neighborhood.query.get(name='Projects')
    p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
    c.project = p_test
    icon_file = open(file_path, 'rb')
    M.ProjectFile.save_image(
        file_name, icon_file, content_type='image/png',
        square=True, thumbnail_size=(48, 48),
        thumbnail_meta=dict(project_id=c.project._id, category='icon'))
    icon_file.close()
    p_test2 = M.Project.query.get(
        shortname='test2', neighborhood_id=p_nbhd._id)
    c.project = p_test2
    icon_file = open(file_path, 'rb')
    M.ProjectFile.save_image(
        file_name, icon_file, content_type='image/png',
        square=True, thumbnail_size=(48, 48),
        thumbnail_meta=dict(project_id=c.project._id, category='icon'))
    icon_file.close()
    p_sub1 = M.Project.query.get(
        shortname='test/sub1', neighborhood_id=p_nbhd._id)
    c.project = p_sub1
    icon_file = open(file_path, 'rb')
    M.ProjectFile.save_image(
        file_name, icon_file, content_type='image/png',
        square=True, thumbnail_size=(48, 48),
        thumbnail_meta=dict(project_id=c.project._id, category='icon'))
    icon_file.close()
    p_test.labels = ['test', 'root']
    p_sub1.labels = ['test', 'sub1']
    # Make one project private
    p_test.private = False
    p_sub1.private = False
    p_test2.private = True

    ThreadLocalORMSession.flush_all()

    with h.push_config(c,
                       project=p_nbhd.neighborhood_project,
                       user=M.User.by_username('test-admin')):
        r = g.markdown_wiki.convert('[[projects]]')
        assert 'alt="Test Project Logo"' in r, r
        assert 'alt="A Subproject Logo"' in r, r
        r = g.markdown_wiki.convert('[[projects labels=root]]')
        assert 'alt="Test Project Logo"' in r, r
        assert 'alt="A Subproject Logo"' not in r, r
        r = g.markdown_wiki.convert('[[projects labels=sub1]]')
        assert 'alt="Test Project Logo"' not in r, r
        assert 'alt="A Subproject Logo"' in r, r
        r = g.markdown_wiki.convert('[[projects labels=test]]')
        assert 'alt="Test Project Logo"' in r, r
        assert 'alt="A Subproject Logo"' in r, r
        r = g.markdown_wiki.convert('[[projects labels=test,root]]')
        assert 'alt="Test Project Logo"' in r, r
        assert 'alt="A Subproject Logo"' not in r, r
        r = g.markdown_wiki.convert('[[projects labels=test,sub1]]')
        assert 'alt="Test Project Logo"' not in r, r
        assert 'alt="A Subproject Logo"' in r, r
        r = g.markdown_wiki.convert('[[projects labels=root|sub1]]')
        assert 'alt="Test Project Logo"' in r, r
        assert 'alt="A Subproject Logo"' in r, r
        r = g.markdown_wiki.convert('[[projects labels=test,root|root,sub1]]')
        assert 'alt="Test Project Logo"' in r, r
        assert 'alt="A Subproject Logo"' not in r, r
        r = g.markdown_wiki.convert('[[projects labels=test,root|test,sub1]]')
        assert 'alt="Test Project Logo"' in r, r
        assert 'alt="A Subproject Logo"' in r, r
        r = g.markdown_wiki.convert('[[projects show_total=True sort=random]]')
        assert '<p class="macro_projects_total">3 Projects' in r, r
        r = g.markdown_wiki.convert(
            '[[projects show_total=True private=True sort=random]]')
        assert '<p class="macro_projects_total">1 Projects' in r, r
        assert 'alt="Test 2 Logo"' in r, r
        assert 'alt="Test Project Logo"' not in r, r
        assert 'alt="A Subproject Logo"' not in r, r

        r = g.markdown_wiki.convert('[[projects show_proj_icon=True]]')
        assert 'alt="Test Project Logo"' in r
        r = g.markdown_wiki.convert('[[projects show_proj_icon=False]]')
        assert 'alt="Test Project Logo"' not in r


def test_macro_neighborhood_feeds():
    p_nbhd = M.Neighborhood.query.get(name='Projects')
    p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
    with h.push_context('--init--', 'wiki', neighborhood='Projects'):
        r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]')
        assert 'Home modified by' in r, r
        r = re.sub(r'<small>.*? ago</small>', '', r)  # remove "less than 1 second ago" etc
        orig_len = len(r)
        # Make project private & verify we don't see its new feed items
        anon = M.User.anonymous()
        p_test.acl.insert(0, M.ACE.deny(
            M.ProjectRole.anonymous(p_test)._id, 'read'))
        ThreadLocalORMSession.flush_all()
        pg = WM.Page.query.get(title='Home', app_config_id=c.app.config._id)
        pg.text = 'Change'
        with h.push_config(c, user=M.User.by_username('test-admin')):
            pg.commit()
        r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]')
        r = re.sub(r'<small>.*? ago</small>', '', r)  # remove "less than 1 second ago" etc
        new_len = len(r)
        assert new_len == orig_len
        p = BM.BlogPost(title='test me',
                        neighborhood_id=p_test.neighborhood_id)
        p.text = 'test content'
        p.state = 'published'
        p.make_slug()
        with h.push_config(c, user=M.User.by_username('test-admin')):
            p.commit()
        ThreadLocalORMSession.flush_all()
        with h.push_config(c, user=anon):
            r = g.markdown_wiki.convert('[[neighborhood_blog_posts]]')
        assert 'test content' in r


@with_setup(setUp)
def test_macro_members():
    p_nbhd = M.Neighborhood.query.get(name='Projects')
    p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
    p_test.add_user(M.User.by_username('test-user'), ['Developer'])
    p_test.add_user(M.User.by_username('test-user-0'), ['Member'])
    ThreadLocalORMSession.flush_all()
    r = g.markdown_wiki.convert('[[members limit=2]]').replace('\t', '').replace('\n', '')
    assert_equal(r,
                 '<div class="markdown_content"><h6>Project Members:</h6>'
                 '<ul class="md-users-list">'
                 '<li><a href="/u/test-admin/">Test Admin</a> (admin)</li>'
                 '<li><a href="/u/test-user/">Test User</a></li>'
                 '<li class="md-users-list-more"><a href="/p/test/_members">All Members</a></li>'
                 '</ul>'
                 '</div>')


@with_setup(setUp)
def test_macro_members_escaping():
    user = M.User.by_username('test-admin')
    user.display_name = 'Test Admin <script>'
    r = g.markdown_wiki.convert('[[members]]')
    assert_equal(r.replace('\n', '').replace('\t', ''),
                 '<div class="markdown_content"><h6>Project Members:</h6>'
                 '<ul class="md-users-list">'
                 '<li><a href="/u/test-admin/">Test Admin &lt;script&gt;</a> (admin)</li>'
                 '</ul></div>')


@with_setup(setUp)
def test_macro_project_admins():
    user = M.User.by_username('test-admin')
    user.display_name = 'Test Ådmin <script>'
    with h.push_context('test', neighborhood='Projects'):
        r = g.markdown_wiki.convert('[[project_admins]]')
    assert_equal(r.replace('\n', ''),
                 '<div class="markdown_content"><h6>Project Admins:</h6>'
                 '<ul class="md-users-list">'
                 '    <li><a href="/u/test-admin/">Test \xc5dmin &lt;script&gt;</a></li>'
                 '</ul></div>')


@with_setup(setUp)
def test_macro_project_admins_one_br():
    p_nbhd = M.Neighborhood.query.get(name='Projects')
    p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
    p_test.add_user(M.User.by_username('test-user'), ['Admin'])
    ThreadLocalORMSession.flush_all()
    with h.push_config(c, project=p_test):
        r = g.markdown_wiki.convert('[[project_admins]]\n[[download_button]]')

    assert '</a><br/><br/><a href=' not in r, r
    assert '</a></li><li><a href=' in r, r


@td.with_wiki
def test_macro_include_no_extra_br():
    p_nbhd = M.Neighborhood.query.get(name='Projects')
    p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
    wiki = p_test.app_instance('wiki')
    with h.push_context(p_test._id, app_config_id=wiki.config._id):
        p = WM.Page.upsert(title='Include_1')
        p.text = 'included page 1'
        p.commit()
        p = WM.Page.upsert(title='Include_2')
        p.text = 'included page 2'
        p.commit()
        p = WM.Page.upsert(title='Include_3')
        p.text = 'included page 3'
        p.commit()
        ThreadLocalORMSession.flush_all()
        md = '[[include ref=Include_1]]\n[[include ref=Include_2]]\n[[include ref=Include_3]]'
        html = g.markdown_wiki.convert(md)

    expected_html = '''<div class="markdown_content"><p></p><div>
<div class="markdown_content"><p>included page 1</p></div>
</div>
<div>
<div class="markdown_content"><p>included page 2</p></div>
</div>
<div>
<div class="markdown_content"><p>included page 3</p></div>
</div>
<p></p></div>'''
    assert_equal(squish_spaces(html), squish_spaces(expected_html))


@with_setup(setUp, tearDown)
@td.with_wiki
@td.with_tool('test', 'Wiki', 'wiki2')
def test_macro_include_permissions():
    p_nbhd = M.Neighborhood.query.get(name='Projects')
    p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
    wiki = p_test.app_instance('wiki')
    wiki2 = p_test.app_instance('wiki2')
    with h.push_context(p_test._id, app_config_id=wiki.config._id):
        p = WM.Page.upsert(title='CanRead')
        p.text = 'Can see this!'
        p.commit()
        ThreadLocalORMSession.flush_all()

    with h.push_context(p_test._id, app_config_id=wiki2.config._id):
        role = M.ProjectRole.by_name('*anonymous')._id
        read_perm = M.ACE.allow(role, 'read')
        acl = c.app.config.acl
        if read_perm in acl:
            acl.remove(read_perm)
        p = WM.Page.upsert(title='CanNotRead')
        p.text = 'Can not see this!'
        p.commit()
        ThreadLocalORMSession.flush_all()

    with h.push_context(p_test._id, app_config_id=wiki.config._id):
        c.user = M.User.anonymous()
        md = '[[include ref=CanRead]]\n[[include ref=wiki2:CanNotRead]]'
        html = g.markdown_wiki.convert(md)
        assert_in('Can see this!', html)
        assert_not_in('Can not see this!', html)
        assert_in("[[include: you don't have a read permission for wiki2:CanNotRead]]", html)


@patch('oembed.OEmbedEndpoint.fetch')
def test_macro_embed(oembed_fetch):
    oembed_fetch.return_value = {
        "html": '<iframe width="480" height="270" src="http://www.youtube.com/embed/kOLpSPEA72U?feature=oembed" '
                'frameborder="0" allowfullscreen></iframe>)',
        "title": "Nature's 3D Printer: MIND BLOWING Cocoon in Rainforest - Smarter Every Day 94",
    }
    r = g.markdown_wiki.convert('[[embed url=http://www.youtube.com/watch?v=kOLpSPEA72U]]')
    assert_in('<p><iframe height="270" '
              'src="https://www.youtube-nocookie.com/embed/kOLpSPEA72U?feature=oembed" width="480"></iframe></p>',
              r.replace('\n', ''))


def test_macro_embed_video_gone():
    # this does a real fetch
    r = g.markdown_wiki.convert('[[embed url=https://www.youtube.com/watch?v=OWsFqPZ3v-0]]')
    r = str(r)  # convert away from Markup, to get better assertion diff output
    # either of these could happen depending on the mood of youtube's oembed API:
    assert_in(r, [
        '<div class="markdown_content"><p>Video not available</p></div>',
        '<div class="markdown_content"><p>Could not embed: https://www.youtube.com/watch?v=OWsFqPZ3v-0</p></div>',
    ])


@patch('oembed.OEmbedEndpoint.fetch')
def test_macro_embed_video_error(oembed_fetch):
    oembed_fetch.side_effect = OEmbedError('Invalid mime-type in response...')
    r = g.markdown_wiki.convert('[[embed url=http://www.youtube.com/watch?v=6YbBmqUnoQM]]')
    assert_equal(r, '<div class="markdown_content"><p>Could not embed: '
                    'http://www.youtube.com/watch?v=6YbBmqUnoQM</p></div>')


def test_macro_embed_notsupported():
    r = g.markdown_wiki.convert('[[embed url=http://vimeo.com/46163090]]')
    assert_equal(
        r, '<div class="markdown_content"><p>[[embed url=http://vimeo.com/46163090]]</p></div>')


def test_markdown_toc():
    with h.push_context('test', neighborhood='Projects'):
        r = g.markdown_wiki.convert("""[TOC]

# Header 1

## Header 2""")
    assert '''<ul>
<li><a href="#header-1">Header 1</a><ul>
<li><a href="#header-2">Header 2</a></li>
</ul>
</li>
</ul>''' in r, r


@td.with_wiki
def test_wiki_artifact_links():
    text = g.markdown.convert('See [18:13:49]')
    assert 'See <span>[18:13:49]</span>' in text, text
    with h.push_context('test', 'wiki', neighborhood='Projects'):
        text = g.markdown.convert('Read [here](Home) about our project')
        assert '<a class="" href="/p/test/wiki/Home/">here</a>' in text, text
        text = g.markdown.convert('[Go home](test:wiki:Home)')
        assert '<a class="" href="/p/test/wiki/Home/">Go home</a>' in text, text
        text = g.markdown.convert('See [test:wiki:Home]')
        assert '<a class="alink" href="/p/test/wiki/Home/">[test:wiki:Home]</a>' in text, text


def test_markdown_links():
    with patch.dict(tg.config, {'nofollow_exempt_domains': 'foobar.net'}):
        text = g.markdown.convert('Read [here](http://foobar.net/) about our project')
        assert_in('class="" href="http://foobar.net/">here</a> about', text)

    text = g.markdown.convert('Read [here](http://foobar.net/) about our project')
    assert_in('class="" href="http://foobar.net/" rel="nofollow">here</a> about', text)

    text = g.markdown.convert('Read [here](/p/foobar/blah) about our project')
    assert_in('class="" href="/p/foobar/blah">here</a> about', text)

    text = g.markdown.convert('Read [here](/p/foobar/blah/) about our project')
    assert_in('class="" href="/p/foobar/blah/">here</a> about', text)

    text = g.markdown.convert('Read <http://foobar.net/> about our project')
    assert_in('href="http://foobar.net/" rel="nofollow">http://foobar.net/</a> about', text)


def test_markdown_and_html():
    with h.push_context('test', neighborhood='Projects'):
        r = g.markdown_wiki.convert('<div style="float:left">blah</div>')
    assert '<div style="float: left;">blah</div>' in r, r


def test_markdown_within_html():
    with h.push_context('test', neighborhood='Projects'):
        r = g.markdown_wiki.convert('<div style="float:left" markdown>**blah**</div>')
    assert_in('<div style="float: left;"><p><strong>blah</strong></p></div>',
              r.replace('\n', ''))


def test_markdown_with_html_comments():
    text = g.markdown.convert('test <!-- comment -->')
    assert '<div class="markdown_content"><p>test </p></div>' == text, text


def test_markdown_big_text():
    '''If text is too big g.markdown.convert should return plain text'''
    text = 'a' * 40001
    assert_equal(g.markdown.convert(text), '<pre>%s</pre>' % text)
    assert_equal(g.markdown_wiki.convert(text), '<pre>%s</pre>' % text)


@td.with_wiki
def test_markdown_basics():
    with h.push_context('test', 'wiki', neighborhood='Projects'):
        text = g.markdown.convert('# Foo!\n[Home]')
        assert_equal(text,
                     '<div class="markdown_content"><h1 id="foo">Foo!</h1>\n'
                     '<p><a class="alink" href="/p/test/wiki/Home/">[Home]</a></p></div>')
        text = g.markdown.convert('# Foo!\n[Rooted]')
        assert_equal(text,
                     '<div class="markdown_content"><h1 id="foo">Foo!</h1>\n'
                     '<p><span>[Rooted]</span></p></div>')

    assert_equal(
        g.markdown.convert('Multi\nLine'),
        '<div class="markdown_content"><p>Multi<br/>\n'
        'Line</p></div>')
    assert_equal(
        g.markdown.convert('Multi\n\nLine'),
        '<div class="markdown_content"><p>Multi</p>\n'
        '<p>Line</p></div>')

    # should not raise an exception:
    assert_equal(
        g.markdown.convert("<class 'foo'>"),
        '''<div class="markdown_content"><p>&lt;class 'foo'=""&gt;&lt;/class&gt;</p></div>''')

    assert_equal(
        g.markdown.convert('''# Header

Some text in a regular paragraph

    :::python
    for i in range(10):
        print i
'''),
        # no <br
        '<div class="markdown_content"><h1 id="header">Header</h1>\n'
        '<p>Some text in a regular paragraph</p>\n'
        '<div class="codehilite"><pre><span></span><code><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>\n'
        '    <span class="nb">print</span> <span class="n">i</span>\n'
        '</code></pre></div>\n'
        '</div>'
    )
    assert_equal(
        g.forge_markdown(email=True).convert('[Home]'),
        # uses localhost:
        '<div class="markdown_content"><p><a class="alink" href="http://localhost/p/test/wiki/Home/">[Home]</a></p></div>'
    )
    assert_equal(
        g.markdown.convert('''
~~~~
def foo(): pass
~~~~'''),
        '<div class="markdown_content"><div class="codehilite"><pre><span></span><code>def foo(): pass\n'
        '</code></pre></div>\n'
        '</div>'
    )


def test_markdown_list_without_break():
    # this is not a valid way to make a list in original Markdown or python-markdown
    #   https://github.com/Python-Markdown/markdown/issues/874
    # it is valid in the CommonMark spec https://spec.commonmark.org/0.30/#lists
    # TODO: try https://github.com/adamb70/mdx-breakless-lists
    #       or https://gitlab.com/ayblaq/prependnewline
    assert_equal(
        g.markdown.convert('''\
Regular text
* first item
* second item'''),
        '<div class="markdown_content"><p>Regular text\n'  # no <br>
        '* first item\n'  # no <br>
        '* second item</p></div>'
    )

    assert_equal(
        g.markdown.convert('''\
Regular text
- first item
- second item'''),
        '<div class="markdown_content"><p>Regular text<br/>\n'
        '- first item<br/>\n'
        '- second item</p></div>'
    )

    assert_equal(
        g.markdown.convert('''\
Regular text
+ first item
+ second item'''),
        '<div class="markdown_content"><p>Regular text<br/>\n'
        '+ first item<br/>\n'
        '+ second item</p></div>'
    )

    assert_equal(
        g.markdown.convert('''\
Regular text
1. first item
2. second item'''),
        '<div class="markdown_content"><p>Regular text<br/>\n'
        '1. first item<br/>\n'
        '2. second item</p></div>'
    )


def test_markdown_autolink():
    tgt = 'http://everything2.com/?node=nate+oostendorp'
    s = g.markdown.convert('This is %s' % tgt)
    assert_equal(
        s, f'<div class="markdown_content"><p>This is <a href="{tgt}" rel="nofollow">{tgt}</a></p></div>')
    assert '<a href=' in g.markdown.convert('This is http://domain.net')
    # beginning of doc
    assert_in('<a href=', g.markdown.convert('http://domain.net abc'))
    # beginning of a line
    assert_in('<br/>\n<a href="http://',
              g.markdown.convert('foobar\nhttp://domain.net abc'))
    # no conversion of these urls:
    assert_in('a blahttp://sdf.com z',
              g.markdown.convert('a blahttp://sdf.com z'))
    assert_in('literal <code>http://domain.net</code> literal',
              g.markdown.convert('literal `http://domain.net` literal'))
    assert_in('<pre><span></span><code>preformatted http://domain.net\n</code></pre>',
              g.markdown.convert('    :::text\n'
                                 '    preformatted http://domain.net'))


def test_markdown_autolink_with_escape():
    # \_ is unnecessary but valid markdown escaping and should be considered as a regular underscore
    # (it occurs during html2text conversion during project migrations)
    r = g.markdown.convert(r'a http://www.phpmyadmin.net/home\_page/security/\#target b')
    assert 'href="http://www.phpmyadmin.net/home_page/security/#target"' in r, r


def test_markdown_invalid_script():
    r = g.markdown.convert('<script>alert(document.cookies)</script>')
    assert_equal('<div class="markdown_content">&lt;script&gt;alert(document.cookies)&lt;/script&gt;\n</div>', r)


def test_markdown_invalid_onerror():
    r = g.markdown.convert('<img src=x onerror=alert(document.cookie)>')
    assert_not_in('onerror', r)


def test_markdown_invalid_tagslash():
    r = g.markdown.convert('<div/onload><img src=x onerror=alert(document.cookie)>')
    assert_not_in('onerror', r)


def test_markdown_invalid_script_in_link():
    r = g.markdown.convert('[xss](http://"><a onmouseover=prompt(document.domain)>xss</a>)')
    assert_equal('<div class="markdown_content"><p><a class="" '
                 '''href='http://"&gt;&lt;a%20onmouseover=prompt(document.domain)&gt;xss&lt;/a&gt;' '''
                 'rel="nofollow">xss</a></p></div>', r)


def test_markdown_invalid_script_in_link2():
    r = g.markdown.convert('[xss](http://"><img src=x onerror=alert(document.cookie)>)')
    assert_equal('<div class="markdown_content"><p><a class="" '
                 '''href='http://"&gt;&lt;img%20src=x%20onerror=alert(document.cookie)&gt;' '''
                 'rel="nofollow">xss</a></p></div>', r)


def test_markdown_extremely_slow():
    r = g.markdown.convert('''bonjour, voila ce que j'obtient en voulant ajouter un utilisateur a un groupe de sécurite, que ce soit sur un groupe pre-existant, ou sur un groupe crée.
message d'erreur:

ERROR: Could not complete the Add UserLogin To SecurityGroup [file:/C:/neogia/ofbizNeogia/applications/securityext/script/org/ofbiz/securityext/securitygroup/SecurityGroupServices.xml#addUserLoginToSecurityGroup] process [problem creating the newEntity value: Exception while inserting the following entity: [GenericEntity:UserLoginSecurityGroup][createdStamp,2006-01-23 17:42:39.312(java.sql.Timestamp)][createdTxStamp,2006-01-23 17:42:38.875(java.sql.Timestamp)][fromDate,2006-01-23 17:42:39.312(java.sql.Timestamp)][groupId,FULLADMIN(java.lang.String)][lastUpdatedStamp,2006-01-23 17:42:39.312(java.sql.Timestamp)][lastUpdatedTxStamp,2006-01-23 17:42:38.875(java.sql.Timestamp)][thruDate,null()][userLoginId,10012(java.lang.String)] (while inserting: [GenericEntity:UserLoginSecurityGroup][createdStamp,2006-01-23 17:42:39.312(java.sql.Timestamp)][createdTxStamp,2006-01-23 17:42:38.875(java.sql.Timestamp)][fromDate,2006-01-23 17:42:39.312(java.sql.Timestamp)][groupId,FULLADMIN(java.lang.String)][lastUpdatedStamp,2006-01-23 17:42:39.312(java.sql.Timestamp)][lastUpdatedTxStamp,2006-01-23 17:42:38.875(java.sql.Timestamp)][thruDate,null()][userLoginId,10012(java.lang.String)] (SQL Exception while executing the following:INSERT INTO public.USER_LOGIN_SECURITY_GROUP (USER_LOGIN_ID, GROUP_ID, FROM_DATE, THRU_DATE, LAST_UPDATED_STAMP, LAST_UPDATED_TX_STAMP, CREATED_STAMP, CREATED_TX_STAMP) VALUES (?, ?, ?, ?, ?, ?, ?, ?) (ERROR: insert or update on table &quot;user_login_security_group&quot; violates foreign key constraint &quot;user_secgrp_user&quot;)))].

à priori les données du formulaire ne sont pas traitées : VALUES (?, ?, ?, ?, ?, ?, ?, ?) ce qui entraine l'echec du traitement SQL.


Si une idée vous vient à l'esprit, merci de me tenir au courant.

cordialement, julien.''')
    assert True   # finished!


@td.with_tool('test', 'Wiki', 'wiki-len')
def test_markdown_link_length_limits():
    with h.push_context('test', 'wiki-len', neighborhood='Projects'):
        # these are always ok, no matter the NOBRACKET length
        WM.Page.upsert(title='12345678901').commit()
        text = g.markdown.convert('See [12345678901]')
        assert 'href="/p/test/wiki-len/12345678901/">[12345678901]</a>' in text, text
        WM.Page.upsert(title='this is 26 characters long').commit()
        text = g.markdown.convert('See [this is 26 characters long]')
        assert 'href="/p/test/wiki-len/this%20is%2026%20characters%20long/">[this is 26 characters long]</a>' in text, text

        # NOBRACKET regex length impacts standard markdown links
        text = g.markdown.convert('See [short](http://a.de)')
        assert 'href="http://a.de" rel="nofollow">short</a>' in text, text
        text = g.markdown.convert('See [this is 26 characters long](http://a.de)')
        assert 'href="http://a.de" rel="nofollow">this is 26 characters long</a>' in text, text  # {0,12} fails {0,13} ok

        # NOBRACKET regex length impacts our custom artifact links
        text = g.markdown.convert('See [short](Home)')
        assert 'href="/p/test/wiki-len/Home/">short</a>' in text, text
        text = g.markdown.convert('See [123456789](Home)')
        assert 'href="/p/test/wiki-len/Home/">123456789</a>' in text, text
        text = g.markdown.convert('See [12345678901](Home)')
        assert 'href="/p/test/wiki-len/Home/">12345678901</a>' in text, text  # {0,5} fails, {0,6} ok
        text = g.markdown.convert('See [this is 16 chars](Home)')
        assert 'href="/p/test/wiki-len/Home/">this is 16 chars</a>' in text, text  # {0,7} fails {0,8} ok
        text = g.markdown.convert('See [this is 26 characters long](Home)')
        assert 'href="/p/test/wiki-len/Home/">this is 26 characters long</a>' in text, text  # {0,12} fails {0,13} ok

        # limit, currently
        charSuperLong = '1234567890'*21
        text = g.markdown.convert(f'See [{charSuperLong}](Home)')
        assert f'<span>[{charSuperLong}]</span>(Home)' in text, text  # current limitation, not a link
        # assert f'href="/p/test/wiki-len/Home/">{charSuperLong}</a>' in text, text  # ideal output


@td.with_wiki
def test_macro_include():
    r = g.markdown.convert('[[include ref=Home id=foo]]')
    assert '<div id="foo">' in r, r
    assert 'href="../foo"' in g.markdown.convert('[My foo](foo)')
    assert 'href="..' not in g.markdown.convert('[My foo](./foo)')


def test_macro_nbhd_feeds():
    with h.push_context('--init--', 'wiki', neighborhood='Projects'):
        r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]')
        assert 'Home modified by ' in r, r
        assert '&lt;div class="markdown_content"&gt;' not in r


def test_sort_alpha():
    p_nbhd = M.Neighborhood.query.get(name='Projects')

    with h.push_context(p_nbhd.neighborhood_project._id):
        r = g.markdown_wiki.convert('[[projects sort=alpha]]')
        project_list = get_project_names(r)
        assert project_list == sorted(project_list)


def test_sort_registered():
    p_nbhd = M.Neighborhood.query.get(name='Projects')

    with h.push_context(p_nbhd.neighborhood_project._id):
        r = g.markdown_wiki.convert('[[projects sort=last_registered]]')
        project_names = get_project_names(r)
        ids = get_projects_property_in_the_same_order(project_names, '_id')
        assert ids == sorted(ids, reverse=True)


def test_sort_updated():
    p_nbhd = M.Neighborhood.query.get(name='Projects')

    with h.push_context(p_nbhd.neighborhood_project._id):
        r = g.markdown_wiki.convert('[[projects sort=last_updated]]')
        project_names = get_project_names(r)
        updated_at = get_projects_property_in_the_same_order(
            project_names, 'last_updated')
        assert updated_at == sorted(updated_at, reverse=True)


@with_setup(setup_functional_test)
def test_filtering():
    # set up for test
    from random import choice
    setup_trove_categories()
    random_trove = choice(M.TroveCategory.query.find().all())
    test_project = M.Project.query.get(shortname='test')
    test_project_troves = getattr(test_project, 'trove_' + random_trove.type)
    test_project_troves.append(random_trove._id)
    ThreadLocalORMSession.flush_all()

    p_nbhd = M.Neighborhood.query.get(name='Projects')
    with h.push_config(c,
                       project=p_nbhd.neighborhood_project,
                       user=M.User.by_username('test-admin')):
        r = g.markdown_wiki.convert(
            '[[projects category="%s"]]' % random_trove.fullpath)
        project_names = get_project_names(r)
        assert_equal([test_project.name], project_names)


def test_projects_macro():
    two_column_style = 'width: 330px;'

    p_nbhd = M.Neighborhood.query.get(name='Projects')
    with h.push_config(c,
                       project=p_nbhd.neighborhood_project,
                       user=M.User.anonymous()):
        # test columns
        r = g.markdown_wiki.convert('[[projects display_mode=list columns=2]]')
        assert two_column_style in r
        r = g.markdown_wiki.convert('[[projects display_mode=list columns=3]]')
        assert two_column_style not in r


@td.with_user_project('test-admin')
@td.with_user_project('test-user-1')
def test_myprojects_macro():
    h.set_context('u/%s' % (c.user.username), 'wiki', neighborhood='Users')
    r = g.markdown_wiki.convert('[[my_projects]]')
    for p in c.user.my_projects():
        if p.deleted or p.is_nbhd_project:
            continue
        proj_title = f'<h2><a href="{p.url()}">{p.name}</a></h2>'
        assert_in(proj_title, r)

    h.set_context('u/test-user-1', 'wiki', neighborhood='Users')
    user = M.User.query.get(username='test-user-1')
    r = g.markdown_wiki.convert('[[my_projects]]')
    for p in user.my_projects():
        if p.deleted or p.is_nbhd_project:
            continue
        proj_title = f'<h2><a href="{p.url()}">{p.name}</a></h2>'
        assert_in(proj_title, r)


@td.with_wiki
def test_hideawards_macro():
    p_nbhd = M.Neighborhood.query.get(name='Projects')

    app_config_id = ObjectId()
    award = M.Award(app_config_id=app_config_id)
    award.short = 'Award short'
    award.full = 'Award full'
    award.created_by_neighborhood_id = p_nbhd._id

    project = M.Project.query.get(
        neighborhood_id=p_nbhd._id, shortname='test')

    M.AwardGrant(
        award=award,
        award_url='http://award.org',
        comment='Winner!',
        granted_by_neighborhood=p_nbhd,
        granted_to_project=project)

    ThreadLocalORMSession.flush_all()

    with h.push_context(p_nbhd.neighborhood_project._id):
        r = g.markdown_wiki.convert('[[projects]]')
        assert_in('<div class="feature"> <a href="http://award.org" rel="nofollow" title="Winner!">'
                  'Award short</a> </div>',
                  squish_spaces(r))

        r = g.markdown_wiki.convert('[[projects show_awards_banner=False]]')
        assert_not_in('Award short', r)


@td.with_tool('test', 'Blog', 'blog')
def test_project_blog_posts_macro():
    from forgeblog import model as BM
    with h.push_context('test', 'blog', neighborhood='Projects'):
        BM.BlogPost.new(
            title='Test title',
            text='test post',
            state='published',
        )
        BM.BlogPost.new(
            title='Test title2',
            text='test post2',
            state='published',
        )

        r = g.markdown_wiki.convert('[[project_blog_posts]]')
        assert_in('Test title</a></h3>', r)
        assert_in('Test title2</a></h3>', r)
        assert_in('<div class="markdown_content"><p>test post</p></div>', r)
        assert_in('<div class="markdown_content"><p>test post2</p></div>', r)
        assert_in('by <em>Test Admin</em>', r)


def test_project_screenshots_macro():
    with h.push_context('test', neighborhood='Projects'):
        M.ProjectFile(project_id=c.project._id, category='screenshot', caption='caption', filename='test_file.jpg')
        ThreadLocalORMSession.flush_all()

        r = g.markdown_wiki.convert('[[project_screenshots]]')

        assert_in('href="/p/test/screenshot/test_file.jpg"', r)
        assert_in('src="/p/test/screenshot/test_file.jpg/thumb"', r)


def get_project_names(r):
    """
    Extracts a list of project names from a wiki page HTML.
    """
    # projects short names are in h2 elements without any attributes
    # there is one more h2 element, but it has `class` attribute
    # re_proj_names = re.compile(r'<h2><a[^>]>(.+)</a></h2>')
    re_proj_names = re.compile(r'<h2><a[^>]+>(.+)</a></h2>')
    return [e for e in re_proj_names.findall(r)]


def get_projects_property_in_the_same_order(names, prop):
    """
    Returns a list of projects properties `prop` in the same order as
    project `names`.
    It is required because results of the query are not in the same order as names.
    """
    projects = M.Project.query.find(dict(name={'$in': names})).all()
    projects_dict = {p['name']: p[prop] for p in projects}
    return [projects_dict[name] for name in names]


class TestCachedMarkdown(unittest.TestCase):

    def setUp(self):
        self.md = ForgeMarkdown()
        self.post = M.Post()
        self.post.text = '**bold**'
        self.expected_html = '<p><strong>bold</strong></p>'

    def test_bad_source_field_name(self):
        self.assertRaises(AttributeError, self.md.cached_convert,
                          self.post, 'no_such_field')

    def test_missing_cache_field(self):
        delattr(self.post, 'text_cache')
        html = self.md.cached_convert(self.post, 'text')
        self.assertEqual(html, self.expected_html)

    @patch.dict('allura.lib.app_globals.config', markdown_cache_threshold='-0.01')
    def test_non_ascii(self):
        self.post.text = 'å∫ç'
        expected = '<p>å∫ç</p>'
        # test with empty cache
        self.assertEqual(expected, self.md.cached_convert(self.post, 'text'))
        # test with primed cache
        self.assertEqual(expected, self.md.cached_convert(self.post, 'text'))

    @patch.dict('allura.lib.app_globals.config', markdown_cache_threshold='-0.01')
    def test_empty_cache(self):
        html = self.md.cached_convert(self.post, 'text')
        self.assertEqual(html, self.expected_html)
        self.assertEqual(html, self.post.text_cache.html)
        self.assertEqual(hashlib.md5(self.post.text.encode('utf-8')).hexdigest(),
                         self.post.text_cache.md5)
        self.assertTrue(self.post.text_cache.render_time > 0)

    @patch.dict('allura.lib.app_globals.config', markdown_cache_threshold='-0.01')
    def test_stale_cache(self):
        old = self.md.cached_convert(self.post, 'text')
        self.post.text = 'new, different source text'
        html = self.md.cached_convert(self.post, 'text')
        self.assertNotEqual(old, html)
        self.assertEqual(html, self.post.text_cache.html)
        self.assertEqual(hashlib.md5(self.post.text.encode('utf-8')).hexdigest(),
                         self.post.text_cache.md5)
        self.assertTrue(self.post.text_cache.render_time > 0)

    @patch.dict('allura.lib.app_globals.config', markdown_cache_threshold='-0.01')
    def test_valid_cache(self):
        from markupsafe import Markup
        self.md.cached_convert(self.post, 'text')
        with patch.object(self.md, 'convert') as convert_func:
            html = self.md.cached_convert(self.post, 'text')
            self.assertEqual(html, self.expected_html)
            self.assertIsInstance(html, Markup)
            self.assertFalse(convert_func.called)
            self.post.text = "text [[include]] pass"
            html = self.md.cached_convert(self.post, 'text')
            self.assertTrue(convert_func.called)

    @patch.dict('allura.lib.app_globals.config', markdown_cache_threshold='-0.01')
    def test_cacheable_macro(self):
        # cachable
        self.post.text = "text [[img src=...]] pass"
        del self.post.text_cache
        self.md.cached_convert(self.post, 'text')
        assert self.post.text_cache.html

        # cachable, its not even a macro!
        self.post.text = "text [[ blah"
        del self.post.text_cache
        self.md.cached_convert(self.post, 'text')
        assert self.post.text_cache.html

        # not cacheable
        self.post.text = "text [[include file=...]] pass"
        del self.post.text_cache
        self.md.cached_convert(self.post, 'text')
        assert not self.post.text_cache.html

        # not cacheable
        self.post.text = "text [[   \n   include file=... ]] pass"
        del self.post.text_cache
        self.md.cached_convert(self.post, 'text')
        assert not self.post.text_cache.html

    @patch.dict('allura.lib.app_globals.config', {})
    def test_no_threshold_defined(self):
        html = self.md.cached_convert(self.post, 'text')
        self.assertEqual(html, self.expected_html)
        self.assertIsNone(self.post.text_cache.md5)
        self.assertIsNone(self.post.text_cache.html)
        self.assertIsNone(self.post.text_cache.render_time)

    @patch.dict('allura.lib.app_globals.config', markdown_cache_threshold='foo')
    def test_invalid_threshold(self):
        html = self.md.cached_convert(self.post, 'text')
        self.assertEqual(html, self.expected_html)
        self.assertIsNone(self.post.text_cache.md5)
        self.assertIsNone(self.post.text_cache.html)
        self.assertIsNone(self.post.text_cache.render_time)

    @patch.dict('allura.lib.app_globals.config', markdown_cache_threshold='99999')
    def test_render_time_below_threshold(self):
        html = self.md.cached_convert(self.post, 'text')
        self.assertEqual(html, self.expected_html)
        self.assertIsNone(self.post.text_cache.md5)
        self.assertIsNone(self.post.text_cache.html)
        self.assertIsNone(self.post.text_cache.render_time)

    @patch.dict('allura.lib.app_globals.config', {})
    def test_all_expected_keys_exist_in_cache(self):
        self.md.cached_convert(self.post, 'text')
        required_keys = ['fix7528', 'html', 'md5', 'render_time']
        keys = sorted(self.post.text_cache.keys())
        self.assertEqual(required_keys, keys)


class TestEmojis(unittest.TestCase):

    def test_markdown_emoji_atomic(self):
        output = g.markdown.convert(':smile:')
        assert_in('<p>\U0001F604</p>', output)
        output = g.markdown.convert(':+1:')
        assert_in('<p>\U0001F44D</p>', output)
        output = g.markdown.convert(':Bosnia_&_Herzegovina:')
        assert_in('<p>\U0001F1E7\U0001F1E6</p>', output)
        output = g.markdown.convert(':Åland_Islands:')  # emoji code with non-ascii character
        assert_in('<p>\U0001F1E6\U0001F1FD</p>', output)

    def test_markdown_emoji_with_text(self):
        output = g.markdown.convert('Thumbs up emoji :+1: wow!')
        assert_in('<p>Thumbs up emoji \U0001F44D wow!</p>', output)
        output = g.markdown.convert('More emojis :+1::camel::three_o’clock: wow!')
        assert_in('<p>More emojis \U0001F44D\U0001F42B\U0001F552 wow!</p>', output)
        output = g.markdown.convert(':man_bouncing_ball_medium-light_skin_tone:emoji:+1:')
        assert_in('<p>\U000026F9\U0001F3FC\U0000200D\U00002642\U0000FE0Femoji\U0001F44D</p>', output)

    def test_markdown_emoji_in_code(self):
        output = g.markdown.convert('This will not become an emoji `:+1:`')
        assert_in('<p>This will not become an emoji <code>:+1:</code></p>', output)
        output = g.markdown.convert('```html\n<p>:camel:</p>\n```')
        assert_in(':camel:', output)
        output = g.markdown.convert('~~~\n:camel:\n~~~')
        assert_in('<pre><span></span><code>:camel:\n</code></pre>', output)

    def test_markdown_commit_with_emojis(self):
        output = g.markdown_commit.convert('Thumbs up emoji :+1: wow!')
        assert_in('Thumbs up emoji \U0001F44D wow!', output)
        output = g.markdown.convert('More emojis :+1::camel::three_o’clock: wow!')
        assert_in('More emojis \U0001F44D\U0001F42B\U0001F552 wow!', output)


class TestUserMentions(unittest.TestCase):

    def test_markdown_user_mention_default(self):
        output = g.markdown.convert('Hello.. @nouser1, how are you?')
        assert 'Hello.. @nouser1, how are you?' in output
        u1 = M.User.register(dict(username='admin1'), make_project=True)
        ThreadLocalORMSession.flush_all()
        output = g.markdown.convert('Hello.. @admin1, how are you?')
        assert 'class="user-mention"' in output
        assert ('href="%s"' % u1.url()) in output
        u2 = M.User.register(dict(username='admin-2'), make_project=True)
        ThreadLocalORMSession.flush_all()
        output = g.markdown.convert('Do you know @ab? @admin-2 has solved it!')
        assert 'Do you know @ab?' in output
        assert 'class="user-mention"' in output
        assert ('href="%s"' % u2.url()) in output
        output = g.markdown.convert('test@admin1.com Hey!')
        assert 'test@admin1.com Hey!' in output

    def test_markdown_user_mention_in_code(self):
        u1 = M.User.register(dict(username='admin-user-4'), make_project=True)
        ThreadLocalORMSession.flush_all()
        output = g.markdown.convert('Hello.. `@admin-user-4, how` are you?')
        assert 'class="user-mention"' not in output
        assert '<code>' in output
        assert ('href="%s"' % u1.url()) not in output
        output = g.markdown.convert('Hello.. This is code \n~~~python\nprint("@admin-user-4")\n~~~')
        assert 'class="user-mention"' not in output
        assert '<div class="codehilite">' in output
        assert ('href="%s"' % u1.url()) not in output

    @patch('allura.lib.widgets.forms.NeighborhoodProjectShortNameValidator')
    def test_markdown_user_mention_underscores(self, NeighborhoodProjectShortNameValidator):
        username = 'r_808__'
        NeighborhoodProjectShortNameValidator.to_python.return_value = username
        u1 = M.User.register(dict(username=username), make_project=True)
        ThreadLocalORMSession.flush_all()
        output = g.markdown.convert(f'Hello.. @{username}, how are you?')
        assert 'class="user-mention"' in output


class TestHandlePaging(unittest.TestCase):

    def setUp(self):
        prefs = {}
        c.user = Mock()

        def get_pref(name):
            return prefs.get(name)

        def set_pref(name, value):
            prefs[name] = value
        c.user.get_pref = get_pref
        c.user.set_pref = set_pref

    def test_with_limit(self):
        self.assertEqual(g.handle_paging(10, 0), (10, 0, 0))
        self.assertEqual(g.handle_paging(10, 2), (10, 2, 20))
        # handle paging must not mess up user preferences
        self.assertEqual(c.user.get_pref('results_per_page'), None)
        # maximum enforced
        self.assertEqual(g.handle_paging(99999999, 0), (500, 0, 0))

    def test_without_limit(self):
        # default limit = 25
        self.assertEqual(g.handle_paging(None, 0), (25, 0, 0))
        self.assertEqual(g.handle_paging(None, 2), (25, 2, 50))
        # handle paging must not mess up user preferences
        self.assertEqual(c.user.get_pref('results_per_page'), None)

        # user has page size preference
        c.user.set_pref('results_per_page', 100)
        self.assertEqual(g.handle_paging(None, 0), (100, 0, 0))
        self.assertEqual(g.handle_paging(None, 2), (100, 2, 200))
        # handle paging must not mess up user preferences
        self.assertEqual(c.user.get_pref('results_per_page'), 100)

    def test_without_limit_with_default(self):
        # default limit is not used when explicitly provided
        self.assertEqual(g.handle_paging(None, 0, 30), (30, 0, 0))
        self.assertEqual(g.handle_paging(None, 2, 30), (30, 2, 60))
        # handle paging must not mess up user preferences
        self.assertEqual(c.user.get_pref('results_per_page'), None)

        # user has page size preference, which is not affected by default
        c.user.set_pref('results_per_page', 25)
        self.assertEqual(g.handle_paging(None, 0, 30), (25, 0, 0))
        self.assertEqual(g.handle_paging(None, 2, 30), (25, 2, 50))
        # handle paging must not mess up user preferences
        self.assertEqual(c.user.get_pref('results_per_page'), 25)

    def test_with_invalid_limit(self):
        self.assertEqual(g.handle_paging('foo', 0, 30), (30, 0, 0))

        c.user.set_pref('results_per_page', 'bar')
        self.assertEqual(g.handle_paging(None, 0, 30), (30, 0, 0))

    def test_with_invalid_page(self):
        self.assertEqual(g.handle_paging(10, 'asdf', 30), (10, 0, 0))


class TestIconRender:

    def setUp(self):
        self.i = g.icons['edit']

    def test_default(self):
        html = '<a class="icon" href="#" title="Edit"><i class="fa fa-edit"></i></a>'
        assert_equal(html, self.i.render())

    def test_show_title(self):
        html = '<a class="icon" href="#" title="Edit"><i class="fa fa-edit"></i>&nbsp;Edit</a>'
        assert_equal(html, self.i.render(show_title=True))

        html = '<a class="icon" href="#" title="&lt;script&gt;"><i class="fa fa-edit"></i>&nbsp;&lt;script&gt;</a>'
        assert_equal(html, self.i.render(show_title=True, title="<script>"))

    def test_extra_css(self):
        html = '<a class="icon reply btn" href="#" title="Edit"><i class="fa fa-edit"></i></a>'
        assert_equal(html, self.i.render(extra_css='reply btn'))

    def test_no_closing_tag(self):
        html = '<a class="icon" href="#" title="Edit"><i class="fa fa-edit"></i>'
        assert_equal(html, self.i.render(closing_tag=False))

    def test_tag(self):
        html = '<div class="icon" title="Edit"><i class="fa fa-edit"></i></div>'
        assert_equal(html, self.i.render(tag='div'))

    def test_kwargs(self):
        html = '<a class="icon" data-id="123" href="#" title="Edit"><i class="fa fa-edit"></i></a>'
        assert_equal(html, self.i.render(**{'data-id': '123'}))

    def test_escaping(self):
        html = '<a class="icon &#34;" data-url="&gt;" href="#" title="Edit"><i class="fa fa-edit"></i></a>'
        assert_equal(html, self.i.render(extra_css='"', **{'data-url': '>'}))
