<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''Views tests for the OSF.'''
from __future__ import absolute_import
import json
import unittest
import datetime as dt

from nose.tools import *  # PEP8 asserts
from webtest_plus import TestApp

import website.app
from website.models import Node, NodeLog
from website.project.model import ensure_schemas

from tests.base import DbTestCase
from tests.factories import (UserFactory, ApiKeyFactory, ProjectFactory,
                            WatchConfigFactory, NodeFactory, NodeLogFactory)


app = website.app.init_app(routes=True, set_backends=False,
                            settings_module="website.settings")


class TestProjectViews(DbTestCase):

    def setUp(self):
        ensure_schemas()
        self.app = TestApp(app)
        self.user1 = UserFactory.build()
        # Add an API key for quicker authentication
        api_key = ApiKeyFactory()
        self.user1.api_keys.append(api_key)
        self.user1.save()
        self.auth = ('test', api_key._primary_key)
        self.user2 = UserFactory()
        # A project has 2 contributors
        self.project = ProjectFactory(title="Ham",
                                        description='Honey-baked',
                                        creator=self.user1)
        self.project.add_contributor(self.user1)
        self.project.add_contributor(self.user2)
        self.project.api_keys.append(api_key)
        self.project.save()

    def test_edit_description(self):
        url = "/api/v1/project/{0}/edit/".format(self.project._id)
        self.app.post_json(url,
                            {"name": "description", "value": "Deep-fried"},
                            auth=self.auth)
        self.project.reload()
        assert_equal(self.project.description, "Deep-fried")

    def test_project_api_url(self):
        url = self.project.api_url
        res = self.app.get(url, auth=self.auth)
        data = res.json
        assert_equal(data['node']['category'], 'project')
        assert_equal(data['node']['title'], self.project.title)
        assert_equal(data['node']['is_public'], self.project.is_public)
        assert_equal(data['node']['is_registration'], False)
        assert_equal(data['node']['id'], self.project._primary_key)
        assert_equal(data['node']['watched_count'], 0)
        assert_true(data['user']['is_contributor'])
        assert_equal(data['node']['logs'][-1]['action'], 'project_created')

    def test_add_contributor_post(self):
        # Two users are added as a contributor via a POST request
        project = ProjectFactory(creator=self.user1, is_public=True)
        user = UserFactory()
        user2 = UserFactory()
        url = "/api/v1/project/{0}/addcontributors/".format(project._id)
        res = self.app.post(url, json.dumps({"user_ids": [user._id, user2._id]}),
                            content_type="application/json",
                            auth=self.auth).maybe_follow()
        project.reload()
        assert_in(user._id, project.contributors)
        # A log event was added
        assert_equal(project.logs[-1].action, "contributor_added")
        assert_equal(len(project.contributors), 2)
        assert_equal(len(project.contributor_list), 2)

    @unittest.skip('Adding non-registered contributors is on hold until '
                   'invitations and account merging are done.')
    def test_add_non_registered_contributor(self):
        url = "/api/v1/project/{0}/addcontributor/".format(self.project._id)
        # A non-registered user is added
        res = self.app.post(url, json.dumps({"email": "<EMAIL>", "fullname": "<NAME>"}),
                            content_type="application/json",
                            auth=self.auth).maybe_follow()
        self.project.reload()
        # The contributor list should have length 3 (2 registered, 1 unregistered)
        assert_equal(len(self.project.contributor_list), 3)
        # A log event was added
        assert_equal(self.project.logs[-1].action, "contributor_added")

    def test_project_remove_contributor(self):
        url = "/api/v1/project/{0}/removecontributors/".format(self.project._id)
        # User 1 removes user2
        res = self.app.post(url, json.dumps({"id": self.user2._id}),
                            content_type="application/json",
                            auth=self.auth).maybe_follow()
        self.project.reload()
        assert_not_in(self.user2._id, self.project.contributors)
        # A log event was added
        assert_equal(self.project.logs[-1].action, "contributor_removed")

    @unittest.skip('Removing non-registered contributors is on hold until '
                   'invitations and account merging are done.')
    def test_project_remove_non_registered_contributor(self):
        # A non-registered user is added to the project
        self.project.add_nonregistered_contributor(name="<NAME>",
                                                    email="<EMAIL>",
                                                    user=self.user1)
        self.project.save()
        url = "/api/v1/project/{0}/removecontributors/".format(self.project._id)
        # the contributor is removed via the API
        assert False, 'finish me'


    def test_edit_node_title(self):
        url = "/api/v1/project/{0}/edit/".format(self.project._id)
        # The title is changed though posting form data
        res = self.app.post_json(url, {"name": "title", "value": "Bacon"},
                            auth=self.auth).maybe_follow()
        self.project.reload()
        # The title was changed
        assert_equal(self.project.title, "Bacon")
        # A log event was saved
        assert_equal(self.project.logs[-1].action, "edit_title")

    def test_make_public(self):
        self.project.is_public = False
        self.project.save()
        url = "/api/v1/project/{0}/permissions/public/".format(self.project._id)
        res = self.app.post_json(url, {}, auth=self.auth)
        self.project.reload()
        assert_true(self.project.is_public)
        assert_equal(res.json['status'], 'success')

    def test_make_private(self):
        self.project.is_public = True
        self.project.save()
        url = "/api/v1/project/{0}/permissions/private/".format(self.project._id)
        res = self.app.post_json(url, {}, auth=self.auth)
        self.project.reload()
        assert_false(self.project.is_public)
        assert_equal(res.json['status'], 'success')

    def test_add_tag(self):
        url = "/api/v1/project/{0}/addtag/{tag}/".format(self.project._primary_key,
                                                        tag="footag")
        res = self.app.post_json(url, {}, auth=self.auth)
        self.project.reload()
        assert_in("footag", self.project.tags)

    def test_remove_tag(self):
        self.project.add_tag("footag", user=self.user1, api_key=None, save=True)
        assert_in("footag", self.project.tags)
        url = "/api/v1/project/{0}/removetag/{tag}/".format(self.project._primary_key,
                                                        tag="footag")
        res = self.app.post_json(url, {}, auth=self.auth)
        self.project.reload()
        assert_not_in("footag", self.project.tags)

    def test_register_template_page(self):
        url = "/api/v1/project/{0}/register/Brandt_Preregistration/".format(self.project._primary_key)
        res = self.app.post_json(url, {}, auth=self.auth)
        self.project.reload()
        # A registration was added to the project's registration list
        assert_equal(len(self.project.registration_list), 1)
        # A log event was saved
        assert_equal(self.project.logs[-1].action, "project_registered")
        # Most recent node is a registration
        reg = Node.load(self.project.registration_list[-1])
        assert_true(reg.is_registration)

    def test_get_logs(self):
        # Add some logs
        for _ in range(5):
            self.project.logs.append(NodeLogFactory(user=self.user1,
                                                action="file_added",
                                                params={"project": self.project._id}))
        self.project.save()
        url = "/api/v1/project/{0}/log/".format(self.project._primary_key)
        res = self.app.get(url, auth=self.auth)
        self.project.reload()
        data = res.json
        assert_equal(len(data['logs']), len(self.project.logs))
        most_recent = data['logs'][0]
        assert_equal(most_recent['action'], "file_added")

    def test_get_logs_with_count_param(self):
        # Add some logs<commit_msg>Fix failing test<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''Views tests for the OSF.'''
from __future__ import absolute_import
import json
import unittest
import datetime as dt

from nose.tools import *  # PEP8 asserts
from webtest_plus import TestApp

import website.app
from website.models import Node, NodeLog
from website.project.model import ensure_schemas

from tests.base import DbTestCase
from tests.factories import (UserFactory, ApiKeyFactory, ProjectFactory,
                            WatchConfigFactory, NodeFactory, NodeLogFactory)


app = website.app.init_app(routes=True, set_backends=False,
                            settings_module="website.settings")


class TestProjectViews(DbTestCase):

    def setUp(self):
        ensure_schemas()
        self.app = TestApp(app)
        self.user1 = UserFactory.build()
        # Add an API key for quicker authentication
        api_key = ApiKeyFactory()
        self.user1.api_keys.append(api_key)
        self.user1.save()
        self.auth = ('test', api_key._primary_key)
        self.user2 = UserFactory()
        # A project has 2 contributors
        self.project = ProjectFactory(title="Ham",
                                        description='Honey-baked',
                                        creator=self.user1)
        self.project.add_contributor(self.user1)
        self.project.add_contributor(self.user2)
        self.project.api_keys.append(api_key)
        self.project.save()

    def test_edit_description(self):
        url = "/api/v1/project/{0}/edit/".format(self.project._id)
        self.app.post_json(url,
                            {"name": "description", "value": "Deep-fried"},
                            auth=self.auth)
        self.project.reload()
        assert_equal(self.project.description, "Deep-fried")

    def test_project_api_url(self):
        url = self.project.api_url
        res = self.app.get(url, auth=self.auth)
        data = res.json
        assert_equal(data['node']['category'], 'project')
        assert_equal(data['node']['title'], self.project.title)
        assert_equal(data['node']['is_public'], self.project.is_public)
        assert_equal(data['node']['is_registration'], False)
        assert_equal(data['node']['id'], self.project._primary_key)
        assert_equal(data['node']['watched_count'], 0)
        assert_true(data['user']['is_contributor'])
        assert_equal(data['node']['logs'][-1]['action'], 'project_created')

    def test_add_contributor_post(self):
        # Two users are added as a contributor via a POST request
        project = ProjectFactory(creator=self.user1, is_public=True)
        user = UserFactory()
        user2 = UserFactory()
        url = "/api/v1/project/{0}/addcontributors/".format(project._id)
        res = self.app.post(url, json.dumps({"user_ids": [user._id, user2._id]}),
                            content_type="application/json",
                            auth=self.auth).maybe_follow()
        project.reload()
        assert_in(user._id, project.contributors)
        # A log event was added
        assert_equal(project.logs[-1].action, "contributor_added")
        assert_equal(len(project.contributors), 2)
        assert_equal(len(project.contributor_list), 2)

    @unittest.skip('Adding non-registered contributors is on hold until '
                   'invitations and account merging are done.')
    def test_add_non_registered_contributor(self):
        url = "/api/v1/project/{0}/addcontributor/".format(self.project._id)
        # A non-registered user is added
        res = self.app.post(url, json.dumps({"email": "<EMAIL>", "fullname": "<NAME>"}),
                            content_type="application/json",
                            auth=self.auth).maybe_follow()
        self.project.reload()
        # The contributor list should have length 3 (2 registered, 1 unregistered)
        assert_equal(len(self.project.contributor_list), 3)
        # A log event was added
        assert_equal(self.project.logs[-1].action, "contributor_added")

    def test_project_remove_contributor(self):
        url = "/api/v1/project/{0}/removecontributors/".format(self.project._id)
        # User 1 removes user2
        res = self.app.post(url, json.dumps({"id": self.user2._id}),
                            content_type="application/json",
                            auth=self.auth).maybe_follow()
        self.project.reload()
        assert_not_in(self.user2._id, self.project.contributors)
        # A log event was added
        assert_equal(self.project.logs[-1].action, "contributor_removed")

    @unittest.skip('Removing non-registered contributors is on hold until '
                   'invitations and account merging are done.')
    def test_project_remove_non_registered_contributor(self):
        # A non-registered user is added to the project
        self.project.add_nonregistered_contributor(name="<NAME>",
                                                    email="<EMAIL>",
                                                    user=self.user1)
        self.project.save()
        url = "/api/v1/project/{0}/removecontributors/".format(self.project._id)
        # the contributor is removed via the API
        assert False, 'finish me'


    def test_edit_node_title(self):
        url = "/api/v1/project/{0}/edit/".format(self.project._id)
        # The title is changed though posting form data
        res = self.app.post_json(url, {"name": "title", "value": "Bacon"},
                            auth=self.auth).maybe_follow()
        self.project.reload()
        # The title was changed
        assert_equal(self.project.title, "Bacon")
        # A log event was saved
        assert_equal(self.project.logs[-1].action, "edit_title")

    def test_make_public(self):
        self.project.is_public = False
        self.project.save()
        url = "/api/v1/project/{0}/permissions/public/".format(self.project._id)
        res = self.app.post_json(url, {}, auth=self.auth)
        self.project.reload()
        assert_true(self.project.is_public)
        assert_equal(res.json['status'], 'success')

    def test_make_private(self):
        self.project.is_public = True
        self.project.save()
        url = "/api/v1/project/{0}/permissions/private/".format(self.project._id)
        res = self.app.post_json(url, {}, auth=self.auth)
        self.project.reload()
        assert_false(self.project.is_public)
        assert_equal(res.json['status'], 'success')

    def test_add_tag(self):
        url = "/api/v1/project/{0}/addtag/{tag}/".format(self.project._primary_key,
                                                        tag="footag")
        res = self.app.post_json(url, {}, auth=self.auth)
        self.project.reload()
        assert_in("footag", self.project.tags)

    def test_remove_tag(self):
        self.project.add_tag("footag", user=self.user1, api_key=None, save=True)
        assert_in("footag", self.project.tags)
        url = "/api/v1/project/{0}/removetag/{tag}/".format(self.project._primary_key,
                                                        tag="footag")
        res = self.app.post_json(url, {}, auth=self.auth)
        self.project.reload()
        assert_not_in("footag", self.project.tags)

    def test_register_template_page(self):
        url = "/api/v1/project/{0}/register/Replication_Recipe_(Brandt_et_al.,_2013):_Post-Completion/".format(self.project._primary_key)
        res = self.app.post_json(url, {}, auth=self.auth)
        self.project.reload()
        # A registration was added to the project's registration list
        assert_equal(len(self.project.registration_list), 1)
        # A log event was saved
        assert_equal(self.project.logs[-1].action, "project_registered")
        # Most recent node is a registration
        reg = Node.load(self.project.registration_list[-1])
        assert_true(reg.is_registration)

    def test_get_logs(self):
        # Add some logs
        for _ in range(5):
            self.project.logs.append(NodeLogFactory(user=self.user1,
                                                action="file_added",
                                                params={"project": self.project._id}))
        self.project.save()
        url = "/api/v1/project/{0}/log/".format(self.project._primary_key)
        res = self.app.get(url, auth=self.auth)
        self.project.reload()
        data = res.json
        assert_equal(len(data['logs']), len(self.project.logs))
        most_recent = data['logs'][0]
        assert_equal(most_recent['action'], "file_added")

    def test_get_logs_with_count_param(self):
        # Add some logs
{'fraction_non_alphanumeric': 0.12527447128163643, 'fraction_numerical': 0.007280711891829423, 'mean_word_length': 2.3060171919770776, 'pattern_counts': {'":': 18, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2443230', 'n_tokens_mistral': 5044, 'n_tokens_neox': 4889, 'n_words': 895}