<commit_before># -*- coding: utf-8 -*-
import time
from datetime import datetime
from nose.tools import *  # noqa (PEP8 asserts)

import mock
from dateutil import relativedelta

from framework.auth import Auth
from framework.exceptions import PermissionsError
from tests.base import OsfTestCase
from tests.factories import UserFactory, ProjectFactory
from website.addons.base import exceptions

from website.addons.googledrive import model
from website.addons.googledrive.client import GoogleAuthClient
from website.addons.googledrive.tests.factories import GoogleDriveAccountFactory

class TestGoogleDriveProvider(OsfTestCase):
    def setUp(self):
        super(TestGoogleDriveProvider, self).setUp()
        self.provider = model.GoogleDriveProvider()

    @mock.patch.object(GoogleAuthClient, 'userinfo')
    def test_handle_callback(self, mock_client):
        fake_response = {'access_token': 'abc123'}
        fake_info = {'sub': '12345', 'name': 'fakename', 'profile': 'fakeUrl'}
        mock_client.return_value = fake_info
        res = self.provider.handle_callback(fake_response)
        assert_equal(res['provider_id'], '12345')
        assert_equal(res['display_name'], 'fakename')
        assert_equal(res['profile_url'], 'fakeUrl')

class TestGoogleDriveUserSettings(OsfTestCase):
    def setUp(self):
        super(TestGoogleDriveUserSettings, self).setUp()
        self.node = ProjectFactory()
        self.user = self.node.creator

        self.external_account = GoogleDriveAccountFactory()

        self.user.external_accounts.append(self.external_account)
        self.user.save()

        self.user_settings = self.user.get_or_add_addon('googledrive')

    def tearDown(self):
        super(TestGoogleDriveUserSettings, self).tearDown()
        self.user_settings.remove()
        self.external_account.remove()
        self.node.remove()
        self.user.remove()

    def test_grant_oauth_access_no_metadata(self):
        self.user_settings.grant_oauth_access(
            node=self.node,
            external_account=self.external_account,
        )
        self.user_settings.save()

        assert_equal(
            self.user_settings.oauth_grants,
            {self.node._id: {self.external_account._id: {}}},
        )

    def test_grant_oauth_access_metadata(self):
        self.user_settings.grant_oauth_access(
            node=self.node,
            external_account=self.external_account,
            metadata={'folder': 'fake_folder_id'}
        )
        self.user_settings.save()

        assert_equal(
            self.user_settings.oauth_grants,
            {
                self.node._id: {
                    self.external_account._id: {'folder': 'fake_folder_id'}
                },
            }
        )

    def test_verify_oauth_access_no_metadata(self):
        self.user_settings.grant_oauth_access(
            node=self.node,
            external_account=self.external_account,
        )
        self.user_settings.save()

        account_has_access = self.user_settings.verify_oauth_access(
            node=self.node,
            external_account=self.external_account
        )

        factory_account_has_access = self.user_settings.verify_oauth_access(
            node=self.node,
            external_account=GoogleDriveAccountFactory()
        )

        assert_true(account_has_access)
        assert_false(factory_account_has_access)

    def test_verify_oauth_access_metadata(self):
        self.user_settings.grant_oauth_access(
            node=self.node,
            external_account=self.external_account,
            metadata={'folder': 'fake_folder_id'}
        )
        self.user_settings.save()

        correct_meta_access = self.user_settings.verify_oauth_access(
            node=self.node,
            external_account=self.external_account,
            metadata={'folder': 'fake_folder_id'}
        )

        incorrect_meta_no_access = self.user_settings.verify_oauth_access(
            node=self.node,
            external_account=self.external_account,
            metadata={'folder': 'another_folder_id'}
        )

        assert_true(correct_meta_access)
        assert_false(incorrect_meta_no_access)


class TestGoogleDriveNodeSettings(OsfTestCase):

    def setUp(self):
        super(TestGoogleDriveNodeSettings, self).setUp()
        self.node = ProjectFactory()
        self.node_settings = model.GoogleDriveNodeSettings(owner=self.node)
        self.node_settings.save()
        self.user = self.node.creator
        self.user_settings = self.user.get_or_add_addon('googledrive')

    def tearDown(self):
        super(TestGoogleDriveNodeSettings, self).tearDown()
        self.user_settings.remove()
        self.node_settings.remove()
        self.node.remove()
        self.user.remove()

    @mock.patch('website.addons.googledrive.model.GoogleDriveProvider')
    def test_api_not_cached(self, mock_gdp):
        # The first call to .api returns a new object
        api = self.node_settings.api
        mock_gdp.assert_called_once()
        assert_equal(api, mock_gdp())

    @mock.patch('website.addons.googledrive.model.GoogleDriveProvider')
    def test_api_cached(self, mock_gdp):
        # Repeated calls to .api returns the same object
        self.node_settings._api = 'testapi'
        api = self.node_settings.api
        assert_false(mock_gdp.called)
        assert_equal(api, 'testapi')

    def test_set_auth(self):
        external_account = GoogleDriveAccountFactory()
        self.user.external_accounts.append(external_account)
        self.user.save()

        # this should be reset after the call
        self.node_settings.folder_id = 'anything'

        self.node_settings.set_auth(
            external_account=external_account,
            user=self.user
        )

        # this instance is updated
        assert_equal(
            self.node_settings.external_account,
            external_account
        )
        assert_equal(
            self.node_settings.user_settings,
            self.user_settings
        )
        assert_is_none(
            self.node_settings.folder_id
        )

        set_auth_gives_access = self.user_settings.verify_oauth_access(
            node=self.node,
            external_account=external_account,
        )

        assert_true(set_auth_gives_access)

    def test_set_auth_wrong_user(self):
        external_account = GoogleDriveAccountFactory()
        self.user.external_accounts.append(external_account)
        self.user.save()

        with assert_raises(PermissionsError):
            self.node_settings.set_auth(
                external_account=external_account,
                user=UserFactory()
            )

    def test_clear_auth(self):
        self.node_settings.external_account = GoogleDriveAccountFactory()
        self.node_settings.folder_id = 'something'
        self.node_settings.user_settings = self.user_settings
        self.node_settings.save()

        self.node_settings.clear_auth()

        assert_is_none(self.node_settings.external_account)
        assert_is_none(self.node_settings.folder_id)
        assert_is_none(self.node_settings.user_settings)
        assert_is_none(self.node_settings.folder_path)
        assert_is_none(self.node_settings.folder_name)

    def test_set_target_folder(self):

        folder = {
            'id': 'fake-folder-id',
            'name': 'fake-folder-name',<commit_msg>Update test<commit_after># -*- coding: utf-8 -*-
import time
from datetime import datetime
from nose.tools import *  # noqa (PEP8 asserts)

import mock
from dateutil import relativedelta

from framework.auth import Auth
from framework.exceptions import PermissionsError
from tests.base import OsfTestCase
from tests.factories import UserFactory, ProjectFactory
from website.addons.base import exceptions

from website.addons.googledrive import model
from website.addons.googledrive.client import GoogleAuthClient
from website.addons.googledrive.tests.factories import GoogleDriveAccountFactory

class TestGoogleDriveProvider(OsfTestCase):
    def setUp(self):
        super(TestGoogleDriveProvider, self).setUp()
        self.provider = model.GoogleDriveProvider()

    @mock.patch.object(GoogleAuthClient, 'userinfo')
    def test_handle_callback(self, mock_client):
        fake_response = {'access_token': 'abc123'}
        fake_info = {'sub': '12345', 'name': 'fakename', 'profile': 'fakeUrl'}
        mock_client.return_value = fake_info
        res = self.provider.handle_callback(fake_response)
        assert_equal(res['provider_id'], '12345')
        assert_equal(res['display_name'], 'fakename')
        assert_equal(res['profile_url'], 'fakeUrl')

class TestGoogleDriveUserSettings(OsfTestCase):
    def setUp(self):
        super(TestGoogleDriveUserSettings, self).setUp()
        self.node = ProjectFactory()
        self.user = self.node.creator

        self.external_account = GoogleDriveAccountFactory()

        self.user.external_accounts.append(self.external_account)
        self.user.save()

        self.user_settings = self.user.get_or_add_addon('googledrive')

    def tearDown(self):
        super(TestGoogleDriveUserSettings, self).tearDown()
        self.user_settings.remove()
        self.external_account.remove()
        self.node.remove()
        self.user.remove()

    def test_grant_oauth_access_no_metadata(self):
        self.user_settings.grant_oauth_access(
            node=self.node,
            external_account=self.external_account,
        )
        self.user_settings.save()

        assert_equal(
            self.user_settings.oauth_grants,
            {self.node._id: {self.external_account._id: {}}},
        )

    def test_grant_oauth_access_metadata(self):
        self.user_settings.grant_oauth_access(
            node=self.node,
            external_account=self.external_account,
            metadata={'folder': 'fake_folder_id'}
        )
        self.user_settings.save()

        assert_equal(
            self.user_settings.oauth_grants,
            {
                self.node._id: {
                    self.external_account._id: {'folder': 'fake_folder_id'}
                },
            }
        )

    def test_verify_oauth_access_no_metadata(self):
        self.user_settings.grant_oauth_access(
            node=self.node,
            external_account=self.external_account,
        )
        self.user_settings.save()

        account_has_access = self.user_settings.verify_oauth_access(
            node=self.node,
            external_account=self.external_account
        )

        factory_account_has_access = self.user_settings.verify_oauth_access(
            node=self.node,
            external_account=GoogleDriveAccountFactory()
        )

        assert_true(account_has_access)
        assert_false(factory_account_has_access)

    def test_verify_oauth_access_metadata(self):
        self.user_settings.grant_oauth_access(
            node=self.node,
            external_account=self.external_account,
            metadata={'folder': 'fake_folder_id'}
        )
        self.user_settings.save()

        correct_meta_access = self.user_settings.verify_oauth_access(
            node=self.node,
            external_account=self.external_account,
            metadata={'folder': 'fake_folder_id'}
        )

        incorrect_meta_no_access = self.user_settings.verify_oauth_access(
            node=self.node,
            external_account=self.external_account,
            metadata={'folder': 'another_folder_id'}
        )

        assert_true(correct_meta_access)
        assert_false(incorrect_meta_no_access)


class TestGoogleDriveNodeSettings(OsfTestCase):

    def setUp(self):
        super(TestGoogleDriveNodeSettings, self).setUp()
        self.node = ProjectFactory()
        self.node_settings = model.GoogleDriveNodeSettings(owner=self.node)
        self.node_settings.save()
        self.user = self.node.creator
        self.user_settings = self.user.get_or_add_addon('googledrive')

    def tearDown(self):
        super(TestGoogleDriveNodeSettings, self).tearDown()
        self.user_settings.remove()
        self.node_settings.remove()
        self.node.remove()
        self.user.remove()

    @mock.patch('website.addons.googledrive.model.GoogleDriveProvider')
    def test_api_not_cached(self, mock_gdp):
        # The first call to .api returns a new object
        api = self.node_settings.api
        mock_gdp.assert_called_once()
        assert_equal(api, mock_gdp())

    @mock.patch('website.addons.googledrive.model.GoogleDriveProvider')
    def test_api_cached(self, mock_gdp):
        # Repeated calls to .api returns the same object
        self.node_settings._api = 'testapi'
        api = self.node_settings.api
        assert_false(mock_gdp.called)
        assert_equal(api, 'testapi')

    def test_set_auth(self):
        external_account = GoogleDriveAccountFactory()
        self.user.external_accounts.append(external_account)
        self.user.save()
        self.node_settings.external_account = external_account
        self.node_settings.user_settings = self.user_settings
        self.node_settings.save()

        # this should not be reset after the call
        folder = {'id': 'anything', 'path': 'anything'}
        self.node_settings.set_target_folder(folder, Auth(self.user_settings.owner))

        self.node_settings.set_auth(
            external_account=external_account,
            user=self.user
        )

        # this instance is updated
        assert_equal(
            self.node_settings.external_account,
            external_account
        )
        assert_equal(
            self.node_settings.user_settings,
            self.user_settings
        )
        assert_equal(
            self.node_settings.folder_id,
            folder['id']
        )

        assert_true(self.node_settings.complete)

    def test_set_auth_wrong_user(self):
        external_account = GoogleDriveAccountFactory()
        self.user.external_accounts.append(external_account)
        self.user.save()

        with assert_raises(PermissionsError):
            self.node_settings.set_auth(
                external_account=external_account,
                user=UserFactory()
            )

    def test_clear_auth(self):
        self.node_settings.external_account = GoogleDriveAccountFactory()
        self.node_settings.folder_id = 'something'
        self.node_settings.user_settings = self.user_settings
        self.node_settings.save()

        self.node_settings.clear_auth()

        assert_is_none(self.node_settings.external_account)
        assert_is_none(self.node_settings.folder_id)
        assert_is_none(self.node_settings.user_settings)
        assert_is_none(self.node_settings.folder_path)
        assert_is_none(self.node_settings.folder_name)

    def test_set_target_folder(self):

        folder = {
            'id': 'fake-folder-id',
            'name': 'fake-folder-name',
{'fraction_non_alphanumeric': 0.08949832775919732, 'fraction_numerical': 0.002006688963210702, 'mean_word_length': 2.6779827798277984, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4931974', 'n_tokens_mistral': 4403, 'n_tokens_neox': 4240, 'n_words': 610}