def test_import_auth_invalid_account(self): ea = self.ExternalAccountFactory() node = ProjectFactory(creator=self.user) node.add_addon(self.ADDON_SHORT_NAME, auth=self.auth) node.save() url = node.api_url_for('{0}_import_auth'.format(self.ADDON_SHORT_NAME)) res = self.app.put_json(url, {'external_account_id': ea._id}, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, http.FORBIDDEN)
def test_import_auth_invalid_account(self): ea = self.ExternalAccountFactory() node = ProjectFactory(creator=self.user) node.add_addon(self.ADDON_SHORT_NAME, auth=self.auth) node.save() url = node.api_url_for('{0}_import_auth'.format(self.ADDON_SHORT_NAME)) res = self.app.put_json(url, { 'external_account_id': ea._id }, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, http.FORBIDDEN)
def test_node_count_deleted_addon(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['deleted'], 0) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.delete() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['deleted'], 1)
class TestRegistrationsWithGithub(OsfTestCase): def setUp(self): super(TestRegistrationsWithGithub, self).setUp() self.project = ProjectFactory() self.consolidated_auth = Auth(user=self.project.creator) self.project.add_addon('github', auth=self.consolidated_auth) self.project.creator.add_addon('github') self.node_settings = self.project.get_addon('github') self.user_settings = self.project.creator.get_addon('github') self.node_settings.user_settings = self.user_settings self.node_settings.user = '******' self.node_settings.repo = 'Sheer-Heart-Attack' self.node_settings.save()
def test_import_auth_cant_write_node(self): ea = self.ExternalAccountFactory() user = AuthUserFactory() user.add_addon(self.ADDON_SHORT_NAME, auth=Auth(user)) user.external_accounts.add(ea) user.save() node = ProjectFactory(creator=self.user) node.add_contributor(user, permissions=[permissions.READ], auth=self.auth, save=True) node.add_addon(self.ADDON_SHORT_NAME, auth=self.auth) node.save() url = node.api_url_for('{0}_import_auth'.format(self.ADDON_SHORT_NAME)) res = self.app.put_json(url, { 'external_account_id': ea._id }, auth=user.auth, expect_errors=True) assert_equal(res.status_code, http.FORBIDDEN)
def test_import_auth_cant_write_node(self): ea = self.ExternalAccountFactory() user = AuthUserFactory() user.add_addon(self.ADDON_SHORT_NAME, auth=Auth(user)) user.external_accounts.add(ea) user.save() node = ProjectFactory(creator=self.user) node.add_contributor(user, permissions=[permissions.READ], auth=self.auth, save=True) node.add_addon(self.ADDON_SHORT_NAME, auth=self.auth) node.save() url = node.api_url_for('{0}_import_auth'.format(self.ADDON_SHORT_NAME)) res = self.app.put_json(url, { 'external_account_id': ea._id }, auth=user.auth, expect_errors=True) assert_equal(res.status_code, http.FORBIDDEN)
class TestCRUD(OsfTestCase): def setUp(self): super(TestCRUD, self).setUp() self.gitlab = create_mock_gitlab(user='******', private=False) self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.project.add_addon('gitlab', auth=self.consolidated_auth) self.project.creator.add_addon('gitlab') self.node_settings = self.project.get_addon('gitlab') self.node_settings.user_settings = self.project.creator.get_addon('gitlab') # Set the node addon settings to correspond to the values of the mock repo self.node_settings.user = self.gitlab.repo.return_value.owner.login self.node_settings.repo = self.gitlab.repo.return_value.name self.node_settings.save()
class TestCRUD(OsfTestCase): def setUp(self): super(TestCRUD, self).setUp() self.gitlab = create_mock_gitlab(user='******', private=False) self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.project.add_addon('gitlab', auth=self.consolidated_auth) self.project.creator.add_addon('gitlab') self.node_settings = self.project.get_addon('gitlab') self.node_settings.user_settings = self.project.creator.get_addon( 'gitlab') # Set the node addon settings to correspond to the values of the mock repo self.node_settings.user = self.gitlab.repo.return_value.owner.login self.node_settings.repo = self.gitlab.repo.return_value.name self.node_settings.save()
class TestRegistrationsWithGithub(OsfTestCase): def setUp(self): super(TestRegistrationsWithGithub, self).setUp() self.project = ProjectFactory() self.consolidated_auth = Auth(user=self.project.creator) self.project.add_addon('github', auth=self.consolidated_auth) self.project.creator.add_addon('github') self.node_settings = self.project.get_addon('github') self.user_settings = self.project.creator.get_addon('github') self.node_settings.user_settings = self.user_settings self.node_settings.user = '******' self.node_settings.repo = 'Sheer-Heart-Attack' self.node_settings.save()
class TestGithubViews(OsfTestCase): def setUp(self): super(TestGithubViews, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.non_authenticator = UserFactory() self.project.add_contributor( contributor=self.non_authenticator, auth=self.consolidated_auth, ) self.project.creator.add_addon('github') self.project.creator.external_accounts.add(GitHubAccountFactory()) self.project.creator.save() self.project.save() self.project.add_addon('github', auth=self.consolidated_auth) self.github = create_mock_github(user='******', private=False) self.node_settings = self.project.get_addon('github') self.node_settings.user_settings = self.project.creator.get_addon('github') # Set the node addon settings to correspond to the values of the mock repo self.node_settings.user = self.github.repo.return_value.owner.login self.node_settings.repo = self.github.repo.return_value.name self.node_settings.save() def _get_sha_for_branch(self, branch=None, mock_branches=None): github_mock = self.github if mock_branches is None: mock_branches = github_mock.branches if branch is None: # Get default branch name branch = self.github.repo.return_value.default_branch for each in mock_branches.return_value: if each.name == branch: branch_sha = each.commit.sha return branch_sha # Tests for _get_refs @mock.patch('addons.github.api.GitHubClient.branches') @mock.patch('addons.github.api.GitHubClient.repo') def test_get_refs_defaults(self, mock_repo, mock_branches): github_mock = self.github mock_repo.return_value = github_mock.repo.return_value mock_branches.return_value = github_mock.branches.return_value branch, sha, branches = utils.get_refs(self.node_settings)
def test_node_count_deleted_addon(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['deleted'], 0) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.delete() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['deleted'], 1)
def test_many_nodes_with_one_addon(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['total'], 1) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.user = self.user.fullname node_addon.repo = '8 (circle)' node_addon.user_settings = self.user_addon node_addon.external_account = self.external_account node_addon.save() node.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['total'], 2)
class AddonNodeLoggerTestSuiteMixinBase(object): __metaclass__ = abc.ABCMeta @abc.abstractproperty def addon_short_name(self): pass @abc.abstractproperty def NodeLogger(self): pass def setUp(self): super(AddonNodeLoggerTestSuiteMixinBase, self).setUp() self.auth = Auth(AuthUserFactory()) self.node = ProjectFactory(creator=self.auth.user) self.path = None self.node.add_addon(self.addon_short_name, auth=self.auth) self.logger = self.NodeLogger(node=self.node, auth=self.auth)
def test_many_nodes_with_one_addon(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['total'], 1) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.user = self.user.fullname node_addon.repo = '8 (circle)' node_addon.user_settings = self.user_addon node_addon.external_account = self.external_account node_addon.save() node.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['total'], 2)
class TestMustHaveAddonDecorator(AuthAppTestCase): def setUp(self): super(TestMustHaveAddonDecorator, self).setUp() self.project = ProjectFactory() @mock.patch('website.project.decorators._kwargs_to_nodes') def test_must_have_addon_node_true(self, mock_kwargs_to_nodes): mock_kwargs_to_nodes.return_value = (None, self.project) self.project.add_addon('github', auth=None) decorated = must_have_addon('github', 'node')(needs_addon_view) res = decorated() assert_equal(res, 'openaddon') @mock.patch('website.project.decorators._kwargs_to_nodes') def test_must_have_addon_node_false(self, mock_kwargs_to_nodes): mock_kwargs_to_nodes.return_value = (None, self.project) self.project.delete_addon('github', auth=None) decorated = must_have_addon('github', 'node')(needs_addon_view) with assert_raises(HTTPError): decorated() @mock.patch('framework.auth.decorators.Auth.from_kwargs') def test_must_have_addon_user_true(self, mock_current_user): mock_current_user.return_value = Auth(self.project.creator) self.project.creator.add_addon('github') decorated = must_have_addon('github', 'user')(needs_addon_view) res = decorated() assert_equal(res, 'openaddon') @mock.patch('framework.auth.decorators.Auth.from_kwargs') def test_must_have_addon_user_false(self, mock_current_user): mock_current_user.return_value = Auth(self.project.creator) self.project.creator.delete_addon('github') decorated = must_have_addon('github', 'user')(needs_addon_view) with assert_raises(HTTPError): decorated()
class TestMustHaveAddonDecorator(AuthAppTestCase): def setUp(self): super(TestMustHaveAddonDecorator, self).setUp() self.project = ProjectFactory() @mock.patch('website.project.decorators._kwargs_to_nodes') def test_must_have_addon_node_true(self, mock_kwargs_to_nodes): mock_kwargs_to_nodes.return_value = (None, self.project) self.project.add_addon('github', auth=None) decorated = must_have_addon('github', 'node')(needs_addon_view) res = decorated() assert_equal(res, 'openaddon') @mock.patch('website.project.decorators._kwargs_to_nodes') def test_must_have_addon_node_false(self, mock_kwargs_to_nodes): mock_kwargs_to_nodes.return_value = (None, self.project) self.project.delete_addon('github', auth=None) decorated = must_have_addon('github', 'node')(needs_addon_view) with assert_raises(HTTPError): decorated() @mock.patch('framework.auth.decorators.Auth.from_kwargs') def test_must_have_addon_user_true(self, mock_current_user): mock_current_user.return_value = Auth(self.project.creator) self.project.creator.add_addon('github') decorated = must_have_addon('github', 'user')(needs_addon_view) res = decorated() assert_equal(res, 'openaddon') @mock.patch('framework.auth.decorators.Auth.from_kwargs') def test_must_have_addon_user_false(self, mock_current_user): mock_current_user.return_value = Auth(self.project.creator) self.project.creator.delete_addon('github') decorated = must_have_addon('github', 'user')(needs_addon_view) with assert_raises(HTTPError): decorated()
class TestMustBeAddonAuthorizerDecorator(AuthAppTestCase): def setUp(self): super(TestMustBeAddonAuthorizerDecorator, self).setUp() self.project = ProjectFactory() self.decorated = must_be_addon_authorizer('github')(needs_addon_view) @mock.patch('website.project.decorators._kwargs_to_nodes') @mock.patch('framework.auth.decorators.Auth.from_kwargs') def test_must_be_authorizer_true(self, mock_get_current_user, mock_kwargs_to_nodes): # Mock mock_get_current_user.return_value = Auth(self.project.creator) mock_kwargs_to_nodes.return_value = (None, self.project) # Setup self.project.add_addon('github', auth=None) node_settings = self.project.get_addon('github') self.project.creator.add_addon('github') user_settings = self.project.creator.get_addon('github') node_settings.user_settings = user_settings node_settings.save() # Test res = self.decorated() assert_equal(res, 'openaddon') def test_must_be_authorizer_false(self): # Setup self.project.add_addon('github', auth=None) node_settings = self.project.get_addon('github') user2 = UserFactory() user2.add_addon('github') user_settings = user2.get_addon('github') node_settings.user_settings = user_settings node_settings.save() # Test with assert_raises(HTTPError): self.decorated() def test_must_be_authorizer_no_user_settings(self): self.project.add_addon('github', auth=None) with assert_raises(HTTPError): self.decorated() def test_must_be_authorizer_no_node_settings(self): with assert_raises(HTTPError): self.decorated()
class TestMustBeAddonAuthorizerDecorator(AuthAppTestCase): def setUp(self): super(TestMustBeAddonAuthorizerDecorator, self).setUp() self.project = ProjectFactory() self.decorated = must_be_addon_authorizer('github')(needs_addon_view) @mock.patch('website.project.decorators._kwargs_to_nodes') @mock.patch('framework.auth.decorators.Auth.from_kwargs') def test_must_be_authorizer_true(self, mock_get_current_user, mock_kwargs_to_nodes): # Mock mock_get_current_user.return_value = Auth(self.project.creator) mock_kwargs_to_nodes.return_value = (None, self.project) # Setup self.project.add_addon('github', auth=None) node_settings = self.project.get_addon('github') self.project.creator.add_addon('github') user_settings = self.project.creator.get_addon('github') node_settings.user_settings = user_settings node_settings.save() # Test res = self.decorated() assert_equal(res, 'openaddon') def test_must_be_authorizer_false(self): # Setup self.project.add_addon('github', auth=None) node_settings = self.project.get_addon('github') user2 = UserFactory() user2.add_addon('github') user_settings = user2.get_addon('github') node_settings.user_settings = user_settings node_settings.save() # Test with assert_raises(HTTPError): self.decorated() def test_must_be_authorizer_no_user_settings(self): self.project.add_addon('github', auth=None) with assert_raises(HTTPError): self.decorated() def test_must_be_authorizer_no_node_settings(self): with assert_raises(HTTPError): self.decorated()
class TestGithubViews(OsfTestCase): def setUp(self): super(TestGithubViews, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.non_authenticator = UserFactory() self.project.add_contributor( contributor=self.non_authenticator, auth=self.consolidated_auth, ) self.project.creator.add_addon('github') self.project.creator.external_accounts.add(GitHubAccountFactory()) self.project.creator.save() self.project.save() self.project.add_addon('github', auth=self.consolidated_auth) self.github = create_mock_github(user='******', private=False) self.node_settings = self.project.get_addon('github') self.node_settings.user_settings = self.project.creator.get_addon( 'github') # Set the node addon settings to correspond to the values of the mock repo self.node_settings.user = self.github.repo.return_value.owner.login self.node_settings.repo = self.github.repo.return_value.name self.node_settings.save() def _get_sha_for_branch(self, branch=None, mock_branches=None): github_mock = self.github if mock_branches is None: mock_branches = github_mock.branches if branch is None: # Get default branch name branch = self.github.repo.return_value.default_branch for each in mock_branches.return_value: if each.name == branch: branch_sha = each.commit.sha return branch_sha # Tests for _get_refs @mock.patch('addons.github.api.GitHubClient.branches') @mock.patch('addons.github.api.GitHubClient.repo') def test_get_refs_defaults(self, mock_repo, mock_branches): github_mock = self.github mock_repo.return_value = github_mock.repo.return_value mock_branches.return_value = github_mock.branches.return_value branch, sha, branches = utils.get_refs(self.node_settings) assert_equal(branch, github_mock.repo.return_value.default_branch) assert_equal(sha, self._get_sha_for_branch( branch=None)) # Get refs for default branch assert_equal(branches, github_mock.branches.return_value) @mock.patch('addons.github.api.GitHubClient.branches') @mock.patch('addons.github.api.GitHubClient.repo') def test_get_refs_branch(self, mock_repo, mock_branches): github_mock = self.github mock_repo.return_value = github_mock.repo.return_value mock_branches.return_value = github_mock.branches.return_value branch, sha, branches = utils.get_refs(self.node_settings, 'master') assert_equal(branch, 'master') branch_sha = self._get_sha_for_branch('master') assert_equal(sha, branch_sha) assert_equal(branches, github_mock.branches.return_value) def test_before_fork(self): url = self.project.api_url + 'fork/before/' res = self.app.get(url, auth=self.user.auth).maybe_follow() assert_equal(len(res.json['prompts']), 1) def test_get_refs_sha_no_branch(self): with assert_raises(HTTPError): utils.get_refs(self.node_settings, sha='12345') def test_get_refs_registered_missing_branch(self): github_mock = self.github self.node_settings.registration_data = { 'branches': [branch.to_json() for branch in github_mock.branches.return_value] } with mock.patch('osf.models.node.AbstractNode.is_registration', new_callable=mock.PropertyMock) as mock_is_reg: mock_is_reg.return_value = True with assert_raises(HTTPError): utils.get_refs(self.node_settings, branch='nothere') # Tests for _check_permissions # make a user with no authorization; make sure check_permissions returns false def test_permissions_no_auth(self): github_mock = self.github # project is set to private right now connection = github_mock non_authenticated_user = UserFactory() non_authenticated_auth = Auth(user=non_authenticated_user) branch = 'master' assert_false( check_permissions(self.node_settings, non_authenticated_auth, connection, branch)) # make a repository that doesn't allow push access for this user; # make sure check_permissions returns false @mock.patch('addons.github.models.UserSettings.has_auth') @mock.patch('addons.github.api.GitHubClient.repo') def test_permissions_no_access(self, mock_repo, mock_has_auth): github_mock = self.github mock_has_auth.return_value = True connection = github_mock branch = 'master' mock_repository = mock.NonCallableMock() mock_repository.user = '******' mock_repository.repo = 'mock-repo' mock_repository.to_json.return_value = { 'user': '******', 'repo': 'mock-repo', 'permissions': { 'push': False, # this is key }, } mock_repo.return_value = mock_repository assert_false( check_permissions(self.node_settings, self.consolidated_auth, connection, branch, repo=mock_repository)) # make a branch with a different commit than the commit being passed into check_permissions @mock.patch('addons.github.models.UserSettings.has_auth') def test_permissions_not_head(self, mock_has_auth): github_mock = self.github mock_has_auth.return_value = True connection = github_mock mock_branch = mock.NonCallableMock() mock_branch.commit.sha = '67890' sha = '12345' assert_false( check_permissions(self.node_settings, self.consolidated_auth, connection, mock_branch, sha=sha)) # make sure permissions are not granted for editing a registration @mock.patch('addons.github.models.UserSettings.has_auth') def test_permissions(self, mock_has_auth): github_mock = self.github mock_has_auth.return_value = True connection = github_mock with mock.patch('osf.models.node.AbstractNode.is_registration', new_callable=mock.PropertyMock) as mock_is_reg: mock_is_reg.return_value = True assert_false( check_permissions(self.node_settings, self.consolidated_auth, connection, 'master')) def check_hook_urls(self, urls, node, path, sha): url = node.web_url_for('addon_view_or_download_file', path=path, provider='github') expected_urls = { 'view': '{0}?ref={1}'.format(url, sha), 'download': '{0}?action=download&ref={1}'.format(url, sha) } assert_equal(urls['view'], expected_urls['view']) assert_equal(urls['download'], expected_urls['download']) @mock.patch('addons.github.views.verify_hook_signature') def test_hook_callback_add_file_not_thro_osf(self, mock_verify): url = '/api/v1/project/{0}/github/hook/'.format(self.project._id) timestamp = str(timezone.now()) self.app.post_json( url, { "test": True, "commits": [{ "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "foo", "timestamp": timestamp, "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": { "name": "Illidan", "email": "*****@*****.**" }, "committer": { "name": "Testor", "email": "*****@*****.**", "username": "******" }, "added": ["PRJWN3TV"], "removed": [], "modified": [], }] }, content_type="application/json", ).maybe_follow() self.project.reload() assert_equal(self.project.logs.latest().action, "github_file_added") urls = self.project.logs.latest().params['urls'] self.check_hook_urls( urls, self.project, path='PRJWN3TV', sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', ) @mock.patch('addons.github.views.verify_hook_signature') def test_hook_callback_modify_file_not_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) timestamp = str(timezone.now()) self.app.post_json(url, { "test": True, "commits": [{ "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": " foo", "timestamp": timestamp, "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": { "name": "Illidan", "email": "*****@*****.**" }, "committer": { "name": "Testor", "email": "*****@*****.**", "username": "******" }, "added": [], "removed": [], "modified": ["PRJWN3TV"] }] }, content_type="application/json").maybe_follow() self.project.reload() assert_equal(self.project.logs.latest().action, "github_file_updated") urls = self.project.logs.latest().params['urls'] self.check_hook_urls( urls, self.project, path='PRJWN3TV', sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', ) @mock.patch('addons.github.views.verify_hook_signature') def test_hook_callback_remove_file_not_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) timestamp = str(timezone.now()) self.app.post_json(url, { "test": True, "commits": [{ "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "foo", "timestamp": timestamp, "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": { "name": "Illidan", "email": "*****@*****.**" }, "committer": { "name": "Testor", "email": "*****@*****.**", "username": "******" }, "added": [], "removed": ["PRJWN3TV"], "modified": [] }] }, content_type="application/json").maybe_follow() self.project.reload() assert_equal(self.project.logs.latest().action, "github_file_removed") urls = self.project.logs.latest().params['urls'] assert_equal(urls, {}) @mock.patch('addons.github.views.verify_hook_signature') def test_hook_callback_add_file_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) self.app.post_json(url, { "test": True, "commits": [{ "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "Added via the Open Science Framework", "timestamp": "2014-01-08T14:15:51-08:00", "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": { "name": "Illidan", "email": "*****@*****.**" }, "committer": { "name": "Testor", "email": "*****@*****.**", "username": "******" }, "added": ["PRJWN3TV"], "removed": [], "modified": [] }] }, content_type="application/json").maybe_follow() self.project.reload() assert_not_equal(self.project.logs.latest().action, "github_file_added") @mock.patch('addons.github.views.verify_hook_signature') def test_hook_callback_modify_file_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) self.app.post_json(url, { "test": True, "commits": [{ "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "Updated via the Open Science Framework", "timestamp": "2014-01-08T14:15:51-08:00", "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": { "name": "Illidan", "email": "*****@*****.**" }, "committer": { "name": "Testor", "email": "*****@*****.**", "username": "******" }, "added": [], "removed": [], "modified": ["PRJWN3TV"] }] }, content_type="application/json").maybe_follow() self.project.reload() assert_not_equal(self.project.logs.latest().action, "github_file_updated") @mock.patch('addons.github.views.verify_hook_signature') def test_hook_callback_remove_file_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) self.app.post_json(url, { "test": True, "commits": [{ "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "Deleted via the Open Science Framework", "timestamp": "2014-01-08T14:15:51-08:00", "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": { "name": "Illidan", "email": "*****@*****.**" }, "committer": { "name": "Testor", "email": "*****@*****.**", "username": "******" }, "added": [], "removed": ["PRJWN3TV"], "modified": [] }] }, content_type="application/json").maybe_follow() self.project.reload() assert_not_equal(self.project.logs.latest().action, "github_file_removed")
class TestNodeFilesList(ApiTestCase): def setUp(self): super(TestNodeFilesList, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.private_url = '/{}nodes/{}/files/'.format( API_BASE, self.project._id) self.user_two = AuthUserFactory() self.public_project = ProjectFactory(creator=self.user, is_public=True) self.public_url = '/{}nodes/{}/files/'.format(API_BASE, self.public_project._id) def add_github(self): user_auth = Auth(self.user) self.project.add_addon('github', auth=user_auth) addon = self.project.get_addon('github') addon.repo = 'something' addon.user = '******' oauth_settings = GitHubAccountFactory() oauth_settings.save() self.user.add_addon('github') self.user.external_accounts.add(oauth_settings) self.user.save() addon.user_settings = self.user.get_addon('github') addon.external_account = oauth_settings addon.save() self.project.save() addon.user_settings.oauth_grants[self.project._id] = { oauth_settings._id: []} addon.user_settings.save() def view_only_link(self): private_link = PrivateLinkFactory(creator=self.user) private_link.nodes.add(self.project) private_link.save() return private_link def _prepare_mock_wb_response(self, node=None, **kwargs): prepare_mock_wb_response(node=node or self.project, **kwargs) def test_returns_public_files_logged_out(self): res = self.app.get(self.public_url, expect_errors=True) assert_equal(res.status_code, 200) assert_equal( res.json['data'][0]['attributes']['provider'], 'osfstorage' ) assert_equal(res.content_type, 'application/vnd.api+json') def test_returns_public_files_logged_in(self): res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.content_type, 'application/vnd.api+json') assert_equal( res.json['data'][0]['attributes']['provider'], 'osfstorage' ) def test_returns_storage_addons_link(self): res = self.app.get(self.private_url, auth=self.user.auth) assert_in('storage_addons', res.json['data'][0]['links']) def test_returns_file_data(self): fobj = self.project.get_addon( 'osfstorage').get_root().append_file('NewFile') fobj.save() res = self.app.get( '{}osfstorage/{}'.format(self.private_url, fobj._id), auth=self.user.auth) assert_equal(res.status_code, 200) assert_true(isinstance(res.json['data'], dict)) assert_equal(res.content_type, 'application/vnd.api+json') assert_equal(res.json['data']['attributes']['kind'], 'file') assert_equal(res.json['data']['attributes']['name'], 'NewFile') def test_returns_osfstorage_folder_version_two(self): fobj = self.project.get_addon( 'osfstorage').get_root().append_folder('NewFolder') fobj.save() res = self.app.get( '{}osfstorage/'.format(self.private_url), auth=self.user.auth) assert_equal(res.status_code, 200) def test_returns_osf_storage_folder_version_two_point_two(self): fobj = self.project.get_addon( 'osfstorage').get_root().append_folder('NewFolder') fobj.save() res = self.app.get( '{}osfstorage/?version=2.2'.format(self.private_url), auth=self.user.auth) assert_equal(res.status_code, 200) def test_list_returns_folder_data(self): fobj = self.project.get_addon( 'osfstorage').get_root().append_folder('NewFolder') fobj.save() res = self.app.get( '{}osfstorage/'.format(self.private_url, fobj._id), auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 1) assert_equal(res.content_type, 'application/vnd.api+json') assert_equal(res.json['data'][0]['attributes']['name'], 'NewFolder') def test_returns_folder_data(self): fobj = self.project.get_addon( 'osfstorage').get_root().append_folder('NewFolder') fobj.save() res = self.app.get( '{}osfstorage/{}/'.format(self.private_url, fobj._id), auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 0) assert_equal(res.content_type, 'application/vnd.api+json') def test_returns_private_files_logged_out(self): res = self.app.get(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) assert_in('detail', res.json['errors'][0]) def test_returns_private_files_logged_in_contributor(self): res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.content_type, 'application/vnd.api+json') assert_equal(len(res.json['data']), 1) assert_equal( res.json['data'][0]['attributes']['provider'], 'osfstorage' ) def test_returns_private_files_logged_in_non_contributor(self): res = self.app.get( self.private_url, auth=self.user_two.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_in('detail', res.json['errors'][0]) def test_returns_addon_folders(self): user_auth = Auth(self.user) res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(len(res.json['data']), 1) assert_equal( res.json['data'][0]['attributes']['provider'], 'osfstorage' ) self.project.add_addon('github', auth=user_auth) addon = self.project.get_addon('github') addon.repo = 'something' addon.user = '******' oauth_settings = GitHubAccountFactory() oauth_settings.save() self.user.add_addon('github') self.user.external_accounts.add(oauth_settings) self.user.save() addon.user_settings = self.user.get_addon('github') addon.external_account = oauth_settings addon.save() self.project.save() addon.user_settings.oauth_grants[self.project._id] = { oauth_settings._id: []} addon.user_settings.save() res = self.app.get(self.private_url, auth=self.user.auth) data = res.json['data'] providers = [item['attributes']['provider'] for item in data] assert_equal(len(data), 2) assert_in('github', providers) assert_in('osfstorage', providers) @responses.activate def test_vol_node_files_list(self): self._prepare_mock_wb_response( provider='github', files=[{'name': 'NewFile'}]) self.add_github() vol = self.view_only_link() url = '/{}nodes/{}/files/github/?view_only={}'.format( API_BASE, self.project._id, vol.key) res = self.app.get(url, auth=self.user_two.auth) wb_request = responses.calls[-1].request url = furl.furl(wb_request.url) assert_equal(url.query, 'meta=True&view_only={}'.format(unicode(vol.key, 'utf-8'))) assert_equal(res.json['data'][0]['attributes']['name'], 'NewFile') assert_equal(res.json['data'][0]['attributes']['provider'], 'github') assert_in(vol.key, res.json['data'][0]['links']['info']) assert_in(vol.key, res.json['data'][0]['links']['move']) assert_in(vol.key, res.json['data'][0]['links']['upload']) assert_in(vol.key, res.json['data'][0]['links']['download']) assert_in(vol.key, res.json['data'][0]['links']['delete']) @responses.activate def test_returns_node_files_list(self): self._prepare_mock_wb_response( provider='github', files=[{'name': 'NewFile'}]) self.add_github() url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) # test create res = self.app.get(url, auth=self.user.auth) assert_equal(res.json['data'][0]['attributes']['name'], 'NewFile') assert_equal(res.json['data'][0]['attributes']['provider'], 'github') # test get res = self.app.get(url, auth=self.user.auth) assert_equal(res.json['data'][0]['attributes']['name'], 'NewFile') assert_equal(res.json['data'][0]['attributes']['provider'], 'github') @responses.activate def test_returns_folder_metadata_not_children(self): folder = GithubFolder( name='Folder', target=self.project, path='/Folder/' ) folder.save() self._prepare_mock_wb_response(provider='github', files=[{'name': 'Folder'}], path='/Folder/') self.add_github() url = '/{}nodes/{}/files/github/Folder/'.format(API_BASE, self.project._id) res = self.app.get(url, params={'info': ''}, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.json['data'][0]['attributes']['kind'], 'folder') assert_equal(res.json['data'][0]['attributes']['name'], 'Folder') assert_equal(res.json['data'][0]['attributes']['provider'], 'github') @responses.activate def test_returns_node_file(self): self._prepare_mock_wb_response( provider='github', files=[{'name': 'NewFile'}], folder=False, path='/file') self.add_github() url = '/{}nodes/{}/files/github/file'.format( API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth, headers={ 'COOKIE': 'foo=bar;' # Webtests doesnt support cookies? }) # test create assert_equal(res.status_code, 200) assert_equal(res.json['data']['attributes']['name'], 'NewFile') assert_equal(res.json['data']['attributes']['provider'], 'github') # test get assert_equal(res.status_code, 200) assert_equal(res.json['data']['attributes']['name'], 'NewFile') assert_equal(res.json['data']['attributes']['provider'], 'github') @responses.activate def test_notfound_node_file_returns_folder(self): self._prepare_mock_wb_response( provider='github', files=[{'name': 'NewFile'}], path='/file') url = '/{}nodes/{}/files/github/file'.format( API_BASE, self.project._id) res = self.app.get( url, auth=self.user.auth, expect_errors=True, headers={'COOKIE': 'foo=bar;'} # Webtests doesnt support cookies? ) assert_equal(res.status_code, 404) @responses.activate def test_notfound_node_folder_returns_file(self): self._prepare_mock_wb_response( provider='github', files=[{'name': 'NewFile'}], folder=False, path='/') url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get( url, auth=self.user.auth, expect_errors=True, headers={'COOKIE': 'foo=bar;'} # Webtests doesnt support cookies? ) assert_equal(res.status_code, 404) @responses.activate def test_waterbutler_server_error_returns_503(self): self._prepare_mock_wb_response(status_code=500) self.add_github() url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get( url, auth=self.user.auth, expect_errors=True, headers={'COOKIE': 'foo=bar;'} # Webtests doesnt support cookies? ) assert_equal(res.status_code, 503) @responses.activate def test_waterbutler_invalid_data_returns_503(self): wb_url = waterbutler_api_url_for(self.project._id, _internal=True, provider='github', path='/', meta=True) self.add_github() responses.add( responses.Response( responses.GET, wb_url, body=json.dumps({}), status=400 ) ) url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 503) @responses.activate def test_handles_unauthenticated_waterbutler_request(self): self._prepare_mock_wb_response(status_code=401) self.add_github() url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_in('detail', res.json['errors'][0]) @responses.activate def test_handles_notfound_waterbutler_request(self): invalid_provider = 'gilkjadsflhub' self._prepare_mock_wb_response( status_code=404, provider=invalid_provider) url = '/{}nodes/{}/files/{}/'.format(API_BASE, self.project._id, invalid_provider) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) assert_in('detail', res.json['errors'][0]) def test_handles_request_to_provider_not_configured_on_project(self): provider = 'box' url = '/{}nodes/{}/files/{}/'.format( API_BASE, self.project._id, provider) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_false(self.project.get_addon(provider)) assert_equal(res.status_code, 404) assert_equal( res.json['errors'][0]['detail'], 'The {} provider is not configured for this project.'.format(provider)) @responses.activate def test_handles_bad_waterbutler_request(self): wb_url = waterbutler_api_url_for(self.project._id, _internal=True, provider='github', path='/', meta=True) responses.add( responses.Response( responses.GET, wb_url, json={'bad' : 'json'}, status=418 ) ) self.add_github() url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 503) assert_in('detail', res.json['errors'][0]) def test_files_list_contains_relationships_object(self): res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert 'relationships' in res.json['data'][0]
class TestNodeFilesListPagination(ApiTestCase): def setUp(self): super(TestNodeFilesListPagination, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) httpretty.enable() def tearDown(self): super(TestNodeFilesListPagination, self).tearDown() httpretty.disable() httpretty.reset() def add_github(self): user_auth = Auth(self.user) self.project.add_addon('github', auth=user_auth) addon = self.project.get_addon('github') addon.repo = 'something' addon.user = '******' oauth_settings = GitHubAccountFactory() oauth_settings.save() self.user.add_addon('github') self.user.external_accounts.add(oauth_settings) self.user.save() addon.user_settings = self.user.get_addon('github') addon.external_account = oauth_settings addon.save() self.project.save() addon.user_settings.oauth_grants[self.project._id] = { oauth_settings._id: [] } addon.user_settings.save() def check_file_order(self, resp): previous_file_name = 0 for file in resp.json['data']: int_file_name = int(file['attributes']['name']) assert int_file_name > previous_file_name, 'Files were not in order' previous_file_name = int_file_name def test_node_files_are_sorted_correctly(self): prepare_mock_wb_response(node=self.project, provider='github', files=[ { 'name': '01', 'path': '/01/', 'materialized': '/01/', 'kind': 'folder' }, { 'name': '02', 'path': '/02', 'materialized': '/02', 'kind': 'file' }, { 'name': '03', 'path': '/03/', 'materialized': '/03/', 'kind': 'folder' }, { 'name': '04', 'path': '/04', 'materialized': '/04', 'kind': 'file' }, { 'name': '05', 'path': '/05/', 'materialized': '/05/', 'kind': 'folder' }, { 'name': '06', 'path': '/06', 'materialized': '/06', 'kind': 'file' }, { 'name': '07', 'path': '/07/', 'materialized': '/07/', 'kind': 'folder' }, { 'name': '08', 'path': '/08', 'materialized': '/08', 'kind': 'file' }, { 'name': '09', 'path': '/09/', 'materialized': '/09/', 'kind': 'folder' }, { 'name': '10', 'path': '/10', 'materialized': '/10', 'kind': 'file' }, { 'name': '11', 'path': '/11/', 'materialized': '/11/', 'kind': 'folder' }, { 'name': '12', 'path': '/12', 'materialized': '/12', 'kind': 'file' }, { 'name': '13', 'path': '/13/', 'materialized': '/13/', 'kind': 'folder' }, { 'name': '14', 'path': '/14', 'materialized': '/14', 'kind': 'file' }, { 'name': '15', 'path': '/15/', 'materialized': '/15/', 'kind': 'folder' }, { 'name': '16', 'path': '/16', 'materialized': '/16', 'kind': 'file' }, { 'name': '17', 'path': '/17/', 'materialized': '/17/', 'kind': 'folder' }, { 'name': '18', 'path': '/18', 'materialized': '/18', 'kind': 'file' }, { 'name': '19', 'path': '/19/', 'materialized': '/19/', 'kind': 'folder' }, { 'name': '20', 'path': '/20', 'materialized': '/20', 'kind': 'file' }, { 'name': '21', 'path': '/21/', 'materialized': '/21/', 'kind': 'folder' }, { 'name': '22', 'path': '/22', 'materialized': '/22', 'kind': 'file' }, { 'name': '23', 'path': '/23/', 'materialized': '/23/', 'kind': 'folder' }, { 'name': '24', 'path': '/24', 'materialized': '/24', 'kind': 'file' }, ]) self.add_github() url = '/{}nodes/{}/files/github/?page[size]=100'.format( API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth) self.check_file_order(res)
class TestAddonFileViews(OsfTestCase): def setUp(self): super(TestAddonFileViews, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.user.add_addon('github') self.project.add_addon('github', auth=Auth(self.user)) self.user_addon = self.user.get_addon('github') self.node_addon = self.project.get_addon('github') self.oauth = GitHubAccountFactory() self.oauth.save() self.user.external_accounts.add(self.oauth) self.user.save() self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth self.node_addon.repo = 'Truth' self.node_addon.user = '******' self.node_addon.save() self.user_addon.oauth_grants[self.project._id] = {self.oauth._id: []} self.user_addon.save() def set_sentry(status): def wrapper(func): @functools.wraps(func) def wrapped(*args, **kwargs): enabled, sentry.enabled = sentry.enabled, status func(*args, **kwargs) sentry.enabled = enabled return wrapped return wrapper with_sentry = set_sentry(True) def get_test_file(self): version = file_models.FileVersion(identifier='1') version.save() ret = GithubFile( name='Test', node=self.project, path='/test/Test', materialized_path='/test/Test', ) ret.save() ret.versions.add(version) return ret def get_second_test_file(self): version = file_models.FileVersion(identifier='1') version.save() ret = GithubFile( name='Test2', node=self.project, path='/test/Test2', materialized_path='/test/Test2', ) ret.save() ret.versions.add(version) return ret def get_mako_return(self): ret = serialize_node(self.project, Auth(self.user), primary=True) ret.update({ 'error': '', 'provider': '', 'file_path': '', 'sharejs_uuid': '', 'private': '', 'urls': { 'files': '', 'render': '', 'sharejs': '', 'mfr': '', 'profile_image': '', 'external': '', 'archived_from': '', }, 'size': '', 'extra': '', 'file_name': '', 'materialized_path': '', 'file_id': '', }) ret.update(rubeus.collect_addon_assets(self.project)) return ret def test_redirects_to_guid(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github' ), auth=self.user.auth ) assert_equals(resp.status_code, 302) assert_equals(resp.location, 'http://*****:*****@mock.patch('addons.base.views.addon_view_file') def test_action_view_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/?action=view'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) @mock.patch('addons.base.views.addon_view_file') def test_no_action_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) def test_download_create_guid(self): file_node = self.get_test_file() assert_is(file_node.get_guid(), None) self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github', ), auth=self.user.auth ) assert_true(file_node.get_guid()) def test_view_file_does_not_delete_file_when_requesting_invalid_version(self): with mock.patch('addons.github.models.NodeSettings.is_private', new_callable=mock.PropertyMock) as mock_is_private: mock_is_private.return_value = False file_node = self.get_test_file() assert_is(file_node.get_guid(), None) url = self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github', ) # First view generated GUID self.app.get(url, auth=self.user.auth) self.app.get(url + '?version=invalid', auth=self.user.auth, expect_errors=True) assert_is_not_none(BaseFileNode.load(file_node._id)) assert_is_none(TrashedFileNode.load(file_node._id)) def test_unauthorized_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 401) def test_nonstorage_addons_raise(self): resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path='sillywiki', provider='wiki', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 400) def test_head_returns_url_and_redriect(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) assert_equals(resp.status_code, 302) assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, version='')) def test_head_returns_url_with_version_and_redirect(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/?revision=1&foo=bar'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) # Note: version is added but us but all other url params are added as well assert_equals(resp.status_code, 302) assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version='', foo='bar')) def test_nonexistent_addons_raise(self): path = 'cloudfiles' self.project.delete_addon('github', Auth(self.user)) self.project.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 400) def test_unauth_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 401) def test_delete_action_creates_trashed_file_node(self): file_node = self.get_test_file() payload = { 'provider': file_node.provider, 'metadata': { 'path': '/test/Test', 'materialized': '/test/Test' } } views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload) assert_false(GithubFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) def test_delete_action_for_folder_deletes_subfolders_and_creates_trashed_file_nodes(self): file_node = self.get_test_file() subfolder = GithubFolder( name='folder', node=self.project, path='/test/folder/', materialized_path='/test/folder/', ) subfolder.save() payload = { 'provider': file_node.provider, 'metadata': { 'path': '/test/', 'materialized': '/test/' } } views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload) assert_false(GithubFileNode.load(subfolder._id)) assert_true(TrashedFileNode.load(file_node._id)) @mock.patch('website.archiver.tasks.archive') def test_archived_from_url(self, mock_archive): file_node = self.get_test_file() second_file_node = self.get_second_test_file() file_node.copied_from = second_file_node registered_node = self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) archived_from_url = views.get_archived_from_url(registered_node, file_node) view_url = self.project.web_url_for('addon_view_or_download_file', provider=file_node.provider, path=file_node.copied_from._id) assert_true(archived_from_url) assert_urls_equal(archived_from_url, view_url) @mock.patch('website.archiver.tasks.archive') def test_archived_from_url_without_copied_from(self, mock_archive): file_node = self.get_test_file() registered_node = self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) archived_from_url = views.get_archived_from_url(registered_node, file_node) assert_false(archived_from_url) @mock.patch('website.archiver.tasks.archive') def test_copied_from_id_trashed(self, mock_archive): file_node = self.get_test_file() second_file_node = self.get_second_test_file() file_node.copied_from = second_file_node self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) trashed_node = second_file_node.delete() assert_false(trashed_node.copied_from) @mock.patch('website.archiver.tasks.archive') def test_missing_modified_date_in_file_data(self, mock_archive): file_node = self.get_test_file() file_data = { 'name': 'Test File Update', 'materialized': file_node.materialized_path, 'modified': None } file_node.update(revision=None, data=file_data) assert_equal(len(file_node.history), 1) assert_equal(file_node.history[0], file_data) @mock.patch('website.archiver.tasks.archive') def test_missing_modified_date_in_file_history(self, mock_archive): file_node = self.get_test_file() file_node.history.append({'modified': None}) file_data = { 'name': 'Test File Update', 'materialized': file_node.materialized_path, 'modified': None } file_node.update(revision=None, data=file_data) assert_equal(len(file_node.history), 2) assert_equal(file_node.history[1], file_data) @with_sentry @mock.patch('framework.sentry.sentry.captureMessage') def test_update_logs_to_sentry_when_called_with_disordered_metadata(self, mock_capture): file_node = self.get_test_file() file_node.history.append({'modified': parse_date( '2017-08-22T13:54:32.100900', ignoretz=True, default=timezone.now() # Just incase nothing can be parsed )}) data = { 'name': 'a name', 'materialized': 'materialized', 'modified': '2016-08-22T13:54:32.100900' } file_node.update(revision=None, user=None, data=data) mock_capture.assert_called_with(unicode('update() receives metatdata older than the newest entry in file history.'), extra={'session': {}})
class TestAddonLogs(OsfTestCase): def setUp(self): super(TestAddonLogs, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = GitHubAccountFactory(display_name='john') self.oauth_settings.save() self.user.external_accounts.add(self.oauth_settings) self.user.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() self.user_addon.oauth_grants[self.node._id] = {self.oauth_settings._id: []} self.user_addon.save() def configure_osf_addon(self): self.project = ProjectFactory(creator=self.user) self.node_addon = self.project.get_addon('osfstorage') self.node_addon.save() def build_payload(self, metadata, **kwargs): options = dict( auth={'id': self.user._id}, action='create', provider=self.node_addon.config.short_name, metadata=metadata, time=time.time() + 1000, ) options.update(kwargs) options = { key: value for key, value in options.iteritems() if value is not None } message, signature = signing.default_signer.sign_payload(options) return { 'payload': message, 'signature': signature, } @mock.patch('website.notifications.events.files.FileAdded.perform') def test_add_log(self, mock_perform): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = self.node.logs.count() self.app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal(self.node.logs.count(), nlogs + 1) # # Mocking form_message and perform so that the payload need not be exact. # assert_true(mock_form_message.called, "form_message not called") assert_true(mock_perform.called, 'perform not called') def test_add_log_missing_args(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth=None) nlogs = self.node.logs.count() res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(self.node.logs.count(), nlogs) def test_add_log_no_user(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth={'id': None}) nlogs = self.node.logs.count() res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(self.node.logs.count(), nlogs) def test_add_log_no_addon(self): path = 'pizza' node = ProjectFactory(creator=self.user) url = node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = node.logs.count() res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(node.logs.count(), nlogs) def test_add_log_bad_action(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, action='dance') nlogs = self.node.logs.count() res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(self.node.logs.count(), nlogs) def test_action_file_rename(self): url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload( action='rename', metadata={ 'path': 'foo', }, source={ 'materialized': 'foo', 'provider': 'github', 'node': {'_id': self.node._id}, 'name': 'new.txt', 'kind': 'file', }, destination={ 'path': 'foo', 'materialized': 'foo', 'provider': 'github', 'node': {'_id': self.node._id}, 'name': 'old.txt', 'kind': 'file', }, ) self.app.put_json( url, payload, headers={'Content-Type': 'application/json'} ) self.node.reload() assert_equal( self.node.logs.latest().action, 'github_addon_file_renamed', ) def test_action_downloads(self): url = self.node.api_url_for('create_waterbutler_log') download_actions=('download_file', 'download_zip') for action in download_actions: payload = self.build_payload(metadata={'path': 'foo'}, action=action) nlogs = self.node.logs.count() res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=False, ) assert_equal(res.status_code, 200) self.node.reload() assert_equal(self.node.logs.count(), nlogs) def test_add_file_osfstorage_log(self): self.configure_osf_addon() path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'materialized': path, 'kind': 'file', 'path': path}) nlogs = self.node.logs.count() self.app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal(self.node.logs.count(), nlogs + 1) assert('urls' in self.node.logs.filter(action='osf_storage_file_added')[0].params) def test_add_folder_osfstorage_log(self): self.configure_osf_addon() path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'materialized': path, 'kind': 'folder', 'path': path}) nlogs = self.node.logs.count() self.app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal(self.node.logs.count(), nlogs + 1) assert('urls' not in self.node.logs.filter(action='osf_storage_file_added')[0].params)
class TestAddonCount(OsfTestCase): def setUp(self): super(TestAddonCount, self).setUp() self.user = AuthUserFactory() self.node = ProjectFactory(creator=self.user) self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.external_account = GitHubAccountFactory(display_name='hmoco1') self.user_settings = self.user.get_or_add_addon('github') self.user_settings.save() self.user.external_accounts.add(self.external_account) self.user.save() self.node.add_addon('github', Auth(self.user)) self.node_addon = self.node.get_addon('github') self.node_addon.user = self.user.fullname self.node_addon.repo = '29 #Strafford APTS' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.external_account self.node_addon.save() self.user_settings.grant_oauth_access( node=self.node, external_account=self.external_account, ) def test_run_for_all_addon(self): results = AddonSnapshot().get_events() names = [res['provider']['name'] for res in results] for addon in ADDONS_AVAILABLE: assert_in(addon.short_name, names) def test_one_user_one_node_one_addon(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['users']['enabled'], 1) assert_equal(github_res['nodes']['total'], 1) def test_one_user_one_node_one_addon_one_node_linked(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['users']['enabled'], 1) assert_equal(github_res['nodes']['total'], 1) def test_one_user_with_multiple_githubs(self): oauth_settings2 = GitHubAccountFactory(display_name='hmoco2') oauth_settings2.save() self.user.external_accounts.add(oauth_settings2) self.user.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['users']['enabled'], 1) def test_one_user_with_multiple_addons(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] googledrive_res = [res for res in results if res['provider']['name'] == 'googledrive'][0] assert_equal(github_res['users']['enabled'], 1) assert_equal(googledrive_res['users']['enabled'], 0) self.user.add_addon('googledrive') oauth_settings = GoogleDriveAccountFactory() oauth_settings.save() self.user.external_accounts.add(oauth_settings) self.user.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] googledrive_res = [res for res in results if res['provider']['name'] == 'googledrive'][0] assert_equal(github_res['users']['enabled'], 1) assert_equal(googledrive_res['users']['enabled'], 1) def test_many_users_each_with_a_different_github(self): user = AuthUserFactory() user.add_addon('github') oauth_settings2 = GitHubAccountFactory(display_name='hmoco2') oauth_settings2.save() user.external_accounts.add(oauth_settings2) user.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['users']['enabled'], 2) assert_equal(github_res['users']['authorized'], 1) assert_equal(github_res['users']['linked'], 1) def test_many_users_each_with_the_same_github_enabled(self): user = AuthUserFactory() user.add_addon('github') user.external_accounts.add(self.external_account) user.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['users']['enabled'], 2) def test_github_enabled_not_linked_or_authorized(self): user = AuthUserFactory() user.add_addon('github') user.external_accounts.add(self.external_account) user.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['users']['enabled'], 2) assert_equal(github_res['users']['authorized'], 1) assert_equal(github_res['users']['linked'], 1) def test_one_node_with_multiple_addons(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] googledrive_res = [res for res in results if res['provider']['name'] == 'googledrive'][0] assert_equal(github_res['nodes']['total'], 1) assert_equal(googledrive_res['nodes']['total'], 0) self.user.add_addon('googledrive') user_addon = self.user.get_addon('googledrive') oauth_settings = GoogleDriveAccountFactory() oauth_settings.save() self.user.external_accounts.add(oauth_settings) self.user.save() self.node.add_addon('googledrive', Auth(self.user)) node_addon = self.node.get_addon('googledrive') node_addon.user = self.user.fullname node_addon.user_settings = user_addon node_addon.external_account = oauth_settings node_addon.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] googledrive_res = [res for res in results if res['provider']['name'] == 'googledrive'][0] assert_equal(github_res['nodes']['total'], 1) assert_equal(googledrive_res['nodes']['total'], 1) def test_many_nodes_with_one_addon(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['total'], 1) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.user = self.user.fullname node_addon.repo = '8 (circle)' node_addon.user_settings = self.user_addon node_addon.external_account = self.external_account node_addon.save() node.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['total'], 2) def test_node_count_deleted_addon(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['deleted'], 0) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.delete() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['deleted'], 1) def test_node_count_disconected_addon(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['disconnected'], 0) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.external_account = None node_addon.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['disconnected'], 1) def test_all_users_have_wiki_osfstorage_enabled(self): all_user_count = OSFUser.objects.all().count() results = AddonSnapshot().get_events() osfstorage_res = [res for res in results if res['provider']['name'] == 'osfstorage'][0] wiki_res = [res for res in results if res['provider']['name'] == 'osfstorage'][0] assert_equal(osfstorage_res['users']['enabled'], all_user_count) assert_equal(wiki_res['users']['enabled'], all_user_count) def test_wiki_deleted_shows_as_deleted(self): node = ProjectFactory(creator=self.user) node.delete_addon('wiki', auth=Auth(self.user)) results = AddonSnapshot().get_events() wiki_res = [res for res in results if res['provider']['name'] == 'wiki'][0] assert_equal(wiki_res['nodes']['deleted'], 1) def test_node_settings_has_no_owner_not_connected(self): self.node_addon.owner = None self.node_addon.save() results = AddonSnapshot().get_events() storage_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(storage_res['nodes']['connected'], 0)
class TestCreateBucket(S3AddonTestCase, OsfTestCase): def setUp(self): super(TestCreateBucket, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.auth = self.user.auth self.project = ProjectFactory(creator=self.user) self.project.add_addon('s3', auth=self.consolidated_auth) self.project.creator.add_addon('s3') self.user_settings = self.user.get_addon('s3') self.user_settings.access_key = 'We-Will-Rock-You' self.user_settings.secret_key = 'Idontknowanyqueensongs' self.user_settings.save() self.node_settings = self.project.get_addon('s3') self.node_settings.bucket = 'Sheer-Heart-Attack' self.node_settings.user_settings = self.project.creator.get_addon('s3') self.node_settings.save() def test_bad_names(self): assert_false(validate_bucket_name('')) assert_false(validate_bucket_name('no')) assert_false(validate_bucket_name('a' * 64)) assert_false(validate_bucket_name(' leadingspace')) assert_false(validate_bucket_name('trailingspace ')) assert_false(validate_bucket_name('bogus naMe')) assert_false(validate_bucket_name('.cantstartwithp')) assert_false(validate_bucket_name('or.endwith.')) assert_false(validate_bucket_name('..nodoubles')) assert_false(validate_bucket_name('no_unders_in')) assert_false(validate_bucket_name('-leadinghyphen')) assert_false(validate_bucket_name('trailinghyphen-')) assert_false(validate_bucket_name('Mixedcase')) assert_false(validate_bucket_name('empty..label')) assert_false(validate_bucket_name('label-.trailinghyphen')) assert_false(validate_bucket_name('label.-leadinghyphen')) assert_false(validate_bucket_name('8.8.8.8')) assert_false(validate_bucket_name('600.9000.0.28')) assert_false(validate_bucket_name('no_underscore')) assert_false(validate_bucket_name('_nounderscoreinfront')) assert_false(validate_bucket_name('no-underscore-in-back_')) assert_false( validate_bucket_name('no-underscore-in_the_middle_either')) def test_names(self): assert_true(validate_bucket_name('imagoodname')) assert_true(validate_bucket_name('still.passing')) assert_true(validate_bucket_name('can-have-dashes')) assert_true(validate_bucket_name('kinda.name.spaced')) assert_true(validate_bucket_name('a-o.valid')) assert_true(validate_bucket_name('11.12.m')) assert_true(validate_bucket_name('a--------a')) assert_true(validate_bucket_name('a' * 63)) def test_bad_locations(self): assert_false(validate_bucket_location('Venus')) assert_false(validate_bucket_location('AlphaCentari')) assert_false(validate_bucket_location('CostaRica')) def test_locations(self): assert_true(validate_bucket_location('')) assert_true(validate_bucket_location('eu-central-1')) assert_true(validate_bucket_location('ca-central-1')) assert_true(validate_bucket_location('us-west-1')) assert_true(validate_bucket_location('us-west-2')) assert_true(validate_bucket_location('ap-northeast-1')) assert_true(validate_bucket_location('ap-northeast-2')) assert_true(validate_bucket_location('ap-southeast-1')) assert_true(validate_bucket_location('ap-southeast-2')) assert_true(validate_bucket_location('sa-east-1')) assert_true(validate_bucket_location('eu-west-1')) assert_true(validate_bucket_location('eu-west-2')) @mock.patch('addons.s3.views.utils.create_bucket') @mock.patch('addons.s3.views.utils.get_bucket_names') def test_create_bucket_pass(self, mock_names, mock_make): mock_make.return_value = True mock_names.return_value = ['butintheend', 'it', 'doesntevenmatter'] url = self.project.api_url_for('create_bucket') ret = self.app.post_json(url, { 'bucket_name': 'doesntevenmatter', 'bucket_location': '', }, auth=self.user.auth) assert_equal(ret.status_int, http.OK) assert_equal(ret.json, {}) @mock.patch('addons.s3.views.utils.create_bucket') def test_create_bucket_fail(self, mock_make): error = S3ResponseError(418, 'because Im a test') error.message = 'This should work' mock_make.side_effect = error url = '/api/v1/project/{0}/s3/newbucket/'.format(self.project._id) ret = self.app.post_json(url, {'bucket_name': 'doesntevenmatter'}, auth=self.user.auth, expect_errors=True) assert_equals( ret.body, '{"message": "This should work", "title": "Problem connecting to S3"}' ) @mock.patch('addons.s3.views.utils.create_bucket') def test_bad_location_fails(self, mock_make): url = '/api/v1/project/{0}/s3/newbucket/'.format(self.project._id) ret = self.app.post_json( url, { 'bucket_name': 'doesntevenmatter', 'bucket_location': 'not a real bucket location', }, auth=self.user.auth, expect_errors=True) assert_equals( ret.body, '{"message": "That bucket location is not valid.", "title": "Invalid bucket location"}' )
class TestBitbucketSettings(OsfTestCase): def setUp(self): super(TestBitbucketSettings, self).setUp() self.bitbucket = create_mock_bitbucket(user='******', private=False) self.project = ProjectFactory() self.project.save() self.auth = self.project.creator.auth self.consolidated_auth = Auth(user=self.project.creator) self.project.add_addon('bitbucket', auth=self.consolidated_auth) self.project.creator.add_addon('bitbucket') self.node_settings = self.project.get_addon('bitbucket') self.user_settings = self.project.creator.get_addon('bitbucket') self.node_settings.user_settings = self.user_settings self.node_settings.user = '******' self.node_settings.repo = 'Sheer-Heart-Attack' self.node_settings.save() @mock.patch('addons.bitbucket.api.BitbucketClient.repo') @mock.patch('addons.bitbucket.models.NodeSettings.external_account') def test_link_repo(self, mock_account, mock_repo): bitbucket_mock = self.bitbucket mock_account.return_value = mock.Mock() mock_repo.return_value = bitbucket_mock.repo.return_value url = self.project.api_url + 'bitbucket/settings/' self.app.post_json( url, { 'bitbucket_user': '******', 'bitbucket_repo': 'night at the opera', }, auth=self.auth ).maybe_follow() self.project.reload() self.node_settings.reload() assert_equal(self.node_settings.user, 'queen') assert_equal(self.node_settings.repo, 'night at the opera') assert_equal(self.project.logs.latest().action, 'bitbucket_repo_linked') @mock.patch('addons.bitbucket.api.BitbucketClient.repo') @mock.patch('addons.bitbucket.models.NodeSettings.external_account') def test_link_repo_no_change(self, mock_account, mock_repo): bitbucket_mock = self.bitbucket mock_account.return_value = mock.Mock() mock_repo.return_value = bitbucket_mock.repo.return_value log_count = self.project.logs.count() url = self.project.api_url + 'bitbucket/settings/' self.app.post_json( url, { 'bitbucket_user': '******', 'bitbucket_repo': 'Sheer-Heart-Attack', }, auth=self.auth ).maybe_follow() self.project.reload() self.node_settings.reload() assert_equal(self.project.logs.count(), log_count) @mock.patch('addons.bitbucket.api.BitbucketClient.repo') @mock.patch('addons.bitbucket.models.NodeSettings.external_account') def test_link_repo_non_existent(self, mock_account, mock_repo): mock_account.return_value = mock.Mock() mock_repo.return_value = None url = self.project.api_url + 'bitbucket/settings/' res = self.app.post_json( url, { 'bitbucket_user': '******', 'bitbucket_repo': 'night at the opera', }, auth=self.auth, expect_errors=True ).maybe_follow() assert_equal(res.status_code, 400) @mock.patch('addons.bitbucket.api.BitbucketClient.branches') def test_link_repo_registration(self, mock_branches): bitbucket_mock = self.bitbucket mock_branches.return_value = bitbucket_mock.branches.return_value registration = self.project.register_node( schema=get_default_metaschema(), auth=self.consolidated_auth, data='' ) url = registration.api_url + 'bitbucket/settings/' res = self.app.post_json( url, { 'bitbucket_user': '******', 'bitbucket_repo': 'night at the opera', }, auth=self.auth, expect_errors=True ).maybe_follow() assert_equal(res.status_code, 400) def test_deauthorize(self): url = self.project.api_url + 'bitbucket/user_auth/' self.app.delete(url, auth=self.auth).maybe_follow() self.project.reload() self.node_settings.reload() assert_equal(self.node_settings.user, None) assert_equal(self.node_settings.repo, None) assert_equal(self.node_settings.user_settings, None) assert_equal(self.project.logs.latest().action, 'bitbucket_node_deauthorized')
class TestGithubViews(OsfTestCase): def setUp(self): super(TestGithubViews, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.non_authenticator = UserFactory() self.project.add_contributor( contributor=self.non_authenticator, auth=self.consolidated_auth, ) self.project.creator.add_addon('github') self.project.creator.external_accounts.add(GitHubAccountFactory()) self.project.creator.save() self.project.save() self.project.add_addon('github', auth=self.consolidated_auth) self.github = create_mock_github(user='******', private=False) self.node_settings = self.project.get_addon('github') self.node_settings.user_settings = self.project.creator.get_addon('github') # Set the node addon settings to correspond to the values of the mock repo self.node_settings.user = self.github.repo.return_value.owner.login self.node_settings.repo = self.github.repo.return_value.name self.node_settings.save() def _get_sha_for_branch(self, branch=None, mock_branches=None): github_mock = self.github if mock_branches is None: mock_branches = github_mock.branches if branch is None: # Get default branch name branch = self.github.repo.return_value.default_branch for each in mock_branches.return_value: if each.name == branch: branch_sha = each.commit.sha return branch_sha # Tests for _get_refs @mock.patch('addons.github.api.GitHubClient.branches') @mock.patch('addons.github.api.GitHubClient.repo') def test_get_refs_defaults(self, mock_repo, mock_branches): github_mock = self.github mock_repo.return_value = github_mock.repo.return_value mock_branches.return_value = github_mock.branches.return_value branch, sha, branches = utils.get_refs(self.node_settings) assert_equal( branch, github_mock.repo.return_value.default_branch ) assert_equal(sha, self._get_sha_for_branch(branch=None)) # Get refs for default branch assert_equal( branches, github_mock.branches.return_value ) @mock.patch('addons.github.api.GitHubClient.branches') @mock.patch('addons.github.api.GitHubClient.repo') def test_get_refs_branch(self, mock_repo, mock_branches): github_mock = self.github mock_repo.return_value = github_mock.repo.return_value mock_branches.return_value = github_mock.branches.return_value branch, sha, branches = utils.get_refs(self.node_settings, 'master') assert_equal(branch, 'master') branch_sha = self._get_sha_for_branch('master') assert_equal(sha, branch_sha) assert_equal( branches, github_mock.branches.return_value ) def test_before_fork(self): url = self.project.api_url + 'fork/before/' res = self.app.get(url, auth=self.user.auth).maybe_follow() assert_equal(len(res.json['prompts']), 1) def test_get_refs_sha_no_branch(self): with assert_raises(HTTPError): utils.get_refs(self.node_settings, sha='12345') def test_get_refs_registered_missing_branch(self): github_mock = self.github self.node_settings.registration_data = { 'branches': [ branch.to_json() for branch in github_mock.branches.return_value ] } with mock.patch('osf.models.node.AbstractNode.is_registration', new_callable=mock.PropertyMock) as mock_is_reg: mock_is_reg.return_value = True with assert_raises(HTTPError): utils.get_refs(self.node_settings, branch='nothere') # Tests for _check_permissions # make a user with no authorization; make sure check_permissions returns false def test_permissions_no_auth(self): github_mock = self.github # project is set to private right now connection = github_mock non_authenticated_user = UserFactory() non_authenticated_auth = Auth(user=non_authenticated_user) branch = 'master' assert_false(check_permissions(self.node_settings, non_authenticated_auth, connection, branch)) # make a repository that doesn't allow push access for this user; # make sure check_permissions returns false @mock.patch('addons.github.models.UserSettings.has_auth') @mock.patch('addons.github.api.GitHubClient.repo') def test_permissions_no_access(self, mock_repo, mock_has_auth): github_mock = self.github mock_has_auth.return_value = True connection = github_mock branch = 'master' mock_repository = mock.NonCallableMock() mock_repository.user = '******' mock_repository.repo = 'mock-repo' mock_repository.to_json.return_value = { 'user': '******', 'repo': 'mock-repo', 'permissions': { 'push': False, # this is key }, } mock_repo.return_value = mock_repository assert_false(check_permissions(self.node_settings, self.consolidated_auth, connection, branch, repo=mock_repository)) # make a branch with a different commit than the commit being passed into check_permissions @mock.patch('addons.github.models.UserSettings.has_auth') def test_permissions_not_head(self, mock_has_auth): github_mock = self.github mock_has_auth.return_value = True connection = github_mock mock_branch = mock.NonCallableMock() mock_branch.commit.sha = '67890' sha = '12345' assert_false(check_permissions(self.node_settings, self.consolidated_auth, connection, mock_branch, sha=sha)) # make sure permissions are not granted for editing a registration @mock.patch('addons.github.models.UserSettings.has_auth') def test_permissions(self, mock_has_auth): github_mock = self.github mock_has_auth.return_value = True connection = github_mock with mock.patch('osf.models.node.AbstractNode.is_registration', new_callable=mock.PropertyMock) as mock_is_reg: mock_is_reg.return_value = True assert_false(check_permissions(self.node_settings, self.consolidated_auth, connection, 'master')) def check_hook_urls(self, urls, node, path, sha): url = node.web_url_for('addon_view_or_download_file', path=path, provider='github') expected_urls = { 'view': '{0}?ref={1}'.format(url, sha), 'download': '{0}?action=download&ref={1}'.format(url, sha) } assert_equal(urls['view'], expected_urls['view']) assert_equal(urls['download'], expected_urls['download']) @mock.patch('addons.github.views.verify_hook_signature') def test_hook_callback_add_file_not_thro_osf(self, mock_verify): url = '/api/v1/project/{0}/github/hook/'.format(self.project._id) timestamp = str(timezone.now()) self.app.post_json( url, { "test": True, "commits": [{ "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "foo", "timestamp": timestamp, "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": {"name": "Illidan", "email": "*****@*****.**"}, "committer": {"name": "Testor", "email": "*****@*****.**", "username": "******"}, "added": ["PRJWN3TV"], "removed": [], "modified": [], }] }, content_type="application/json", ).maybe_follow() self.project.reload() assert_equal(self.project.logs.latest().action, "github_file_added") urls = self.project.logs.latest().params['urls'] self.check_hook_urls( urls, self.project, path='PRJWN3TV', sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', ) @mock.patch('addons.github.views.verify_hook_signature') def test_hook_callback_modify_file_not_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) timestamp = str(timezone.now()) self.app.post_json( url, {"test": True, "commits": [{"id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": " foo", "timestamp": timestamp, "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": {"name": "Illidan", "email": "*****@*****.**"}, "committer": {"name": "Testor", "email": "*****@*****.**", "username": "******"}, "added": [], "removed":[], "modified":["PRJWN3TV"]}]}, content_type="application/json").maybe_follow() self.project.reload() assert_equal(self.project.logs.latest().action, "github_file_updated") urls = self.project.logs.latest().params['urls'] self.check_hook_urls( urls, self.project, path='PRJWN3TV', sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', ) @mock.patch('addons.github.views.verify_hook_signature') def test_hook_callback_remove_file_not_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) timestamp = str(timezone.now()) self.app.post_json( url, {"test": True, "commits": [{"id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "foo", "timestamp": timestamp, "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": {"name": "Illidan", "email": "*****@*****.**"}, "committer": {"name": "Testor", "email": "*****@*****.**", "username": "******"}, "added": [], "removed": ["PRJWN3TV"], "modified":[]}]}, content_type="application/json").maybe_follow() self.project.reload() assert_equal(self.project.logs.latest().action, "github_file_removed") urls = self.project.logs.latest().params['urls'] assert_equal(urls, {}) @mock.patch('addons.github.views.verify_hook_signature') def test_hook_callback_add_file_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) self.app.post_json( url, {"test": True, "commits": [{"id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "Added via the Open Science Framework", "timestamp": "2014-01-08T14:15:51-08:00", "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": {"name": "Illidan", "email": "*****@*****.**"}, "committer": {"name": "Testor", "email": "*****@*****.**", "username": "******"}, "added": ["PRJWN3TV"], "removed":[], "modified":[]}]}, content_type="application/json").maybe_follow() self.project.reload() assert_not_equal(self.project.logs.latest().action, "github_file_added") @mock.patch('addons.github.views.verify_hook_signature') def test_hook_callback_modify_file_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) self.app.post_json( url, {"test": True, "commits": [{"id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "Updated via the Open Science Framework", "timestamp": "2014-01-08T14:15:51-08:00", "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": {"name": "Illidan", "email": "*****@*****.**"}, "committer": {"name": "Testor", "email": "*****@*****.**", "username": "******"}, "added": [], "removed":[], "modified":["PRJWN3TV"]}]}, content_type="application/json").maybe_follow() self.project.reload() assert_not_equal(self.project.logs.latest().action, "github_file_updated") @mock.patch('addons.github.views.verify_hook_signature') def test_hook_callback_remove_file_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) self.app.post_json( url, {"test": True, "commits": [{"id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "Deleted via the Open Science Framework", "timestamp": "2014-01-08T14:15:51-08:00", "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": {"name": "Illidan", "email": "*****@*****.**"}, "committer": {"name": "Testor", "email": "*****@*****.**", "username": "******"}, "added": [], "removed":["PRJWN3TV"], "modified":[]}]}, content_type="application/json").maybe_follow() self.project.reload() assert_not_equal(self.project.logs.latest().action, "github_file_removed")
class TestNodeLogList(ApiTestCase): def setUp(self): super(TestNodeLogList, self).setUp() self.user = AuthUserFactory() self.contrib = AuthUserFactory() self.creator = AuthUserFactory() self.user_auth = Auth(self.user) self.NodeLogFactory = ProjectFactory() self.pointer = ProjectFactory() self.private_project = ProjectFactory(is_public=False, creator=self.user) self.private_url = '/{}nodes/{}/logs/?version=2.2'.format( API_BASE, self.private_project._id) self.public_project = ProjectFactory(is_public=True, creator=self.user) self.public_url = '/{}nodes/{}/logs/?version=2.2'.format( API_BASE, self.public_project._id) def test_add_tag(self): user_auth = Auth(self.user) self.public_project.add_tag("Jeff Spies", auth=user_auth) assert_equal("tag_added", self.public_project.logs.latest().action) res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), self.public_project.logs.count()) assert_equal(res.json['data'][API_LATEST]['attributes']['action'], 'tag_added') assert_equal("Jeff Spies", self.public_project.logs.latest().params['tag']) def test_remove_tag(self): user_auth = Auth(self.user) self.public_project.add_tag("Jeff Spies", auth=user_auth) assert_equal("tag_added", self.public_project.logs.latest().action) self.public_project.remove_tag("Jeff Spies", auth=self.user_auth) assert_equal("tag_removed", self.public_project.logs.latest().action) res = self.app.get(self.public_url, auth=self.user) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), self.public_project.logs.count()) assert_equal(res.json['data'][API_LATEST]['attributes']['action'], 'tag_removed') assert_equal("Jeff Spies", self.public_project.logs.latest().params['tag']) def test_project_created(self): res = self.app.get(self.public_url) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), self.public_project.logs.count()) assert_equal(self.public_project.logs.first().action, 'project_created') assert_equal(self.public_project.logs.first().action, res.json['data'][API_LATEST]['attributes']['action']) def test_log_create_on_public_project(self): res = self.app.get(self.public_url) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), self.public_project.logs.count()) assert_datetime_equal( parse_date(res.json['data'][API_FIRST]['attributes']['date']), self.public_project.logs.first().date) assert_equal(res.json['data'][API_FIRST]['attributes']['action'], self.public_project.logs.first().action) def test_log_create_on_private_project(self): res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), self.public_project.logs.count()) assert_datetime_equal( parse_date(res.json['data'][API_FIRST]['attributes']['date']), self.private_project.logs.first().date) assert_equal(res.json['data'][API_FIRST]['attributes']['action'], self.private_project.logs.first().action) def test_add_addon(self): self.public_project.add_addon('github', auth=self.user_auth) assert_equal('addon_added', self.public_project.logs.latest().action) res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), self.public_project.logs.count()) assert_equal(res.json['data'][API_LATEST]['attributes']['action'], 'addon_added') def test_project_add_remove_contributor(self): self.public_project.add_contributor(self.contrib, auth=self.user_auth) assert_equal('contributor_added', self.public_project.logs.latest().action) # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in osf-models with disconnected_from_listeners(contributor_removed): self.public_project.remove_contributor(self.contrib, auth=self.user_auth) assert_equal('contributor_removed', self.public_project.logs.latest().action) res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), self.public_project.logs.count()) assert_equal(res.json['data'][API_LATEST]['attributes']['action'], 'contributor_removed') assert_equal(res.json['data'][1]['attributes']['action'], 'contributor_added') def test_remove_addon(self): self.public_project.add_addon('github', auth=self.user_auth) assert_equal('addon_added', self.public_project.logs.latest().action) old_log_length = len(list(self.public_project.logs.all())) self.public_project.delete_addon('github', auth=self.user_auth) assert_equal('addon_removed', self.public_project.logs.latest().action) assert_equal((self.public_project.logs.count() - 1), old_log_length) res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), self.public_project.logs.count()) assert_equal(res.json['data'][API_LATEST]['attributes']['action'], 'addon_removed') def test_add_pointer(self): self.public_project.add_pointer(self.pointer, auth=Auth(self.user), save=True) assert_equal('pointer_created', self.public_project.logs.latest().action) res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), self.public_project.logs.count()) assert_equal(res.json['data'][API_LATEST]['attributes']['action'], 'pointer_created')
class TestCallbacks(OsfTestCase): def setUp(self): super(TestCallbacks, self).setUp() self.project = ProjectFactory() self.consolidated_auth = Auth(self.project.creator) self.non_authenticator = UserFactory() self.project.add_contributor( contributor=self.non_authenticator, auth=self.consolidated_auth, ) self.project.add_addon('bitbucket', auth=self.consolidated_auth) self.project.creator.add_addon('bitbucket') self.external_account = BitbucketAccountFactory() self.project.creator.external_accounts.add(self.external_account) self.node_settings = self.project.get_addon('bitbucket') self.user_settings = self.project.creator.get_addon('bitbucket') self.node_settings.user_settings = self.user_settings self.node_settings.user = '******' self.node_settings.repo = 'Sheer-Heart-Attack' self.node_settings.external_account = self.external_account self.node_settings.save() self.node_settings.set_auth self.user_settings.oauth_grants[self.project._id] = { self.external_account._id: [] } self.user_settings.save() @mock.patch('addons.bitbucket.api.BitbucketClient.repo') def test_before_make_public(self, mock_repo): mock_repo.side_effect = NotFoundError result = self.node_settings.before_make_public(self.project) assert_is(result, None) @mock.patch('addons.bitbucket.api.BitbucketClient.repo') def test_before_page_load_osf_public_bb_public(self, mock_repo): self.project.is_public = True self.project.save() mock_repo.return_value = {'is_private': False} message = self.node_settings.before_page_load(self.project, self.project.creator) mock_repo.assert_called_with( user=self.node_settings.user, repo=self.node_settings.repo, ) assert_false(message) @mock.patch('addons.bitbucket.api.BitbucketClient.repo') def test_before_page_load_osf_public_bb_private(self, mock_repo): self.project.is_public = True self.project.save() mock_repo.return_value = {'is_private': True} message = self.node_settings.before_page_load(self.project, self.project.creator) mock_repo.assert_called_with( user=self.node_settings.user, repo=self.node_settings.repo, ) assert_true(message) assert_in( 'Users can view the contents of this private Bitbucket repository through this public project.', message[0]) @mock.patch('addons.bitbucket.api.BitbucketClient.repo') def test_before_page_load_repo_deleted(self, mock_repo): self.project.is_public = True self.project.save() mock_repo.return_value = None message = self.node_settings.before_page_load(self.project, self.project.creator) mock_repo.assert_called_with( user=self.node_settings.user, repo=self.node_settings.repo, ) assert_true(message) assert_in('has been deleted.', message[0]) @mock.patch('addons.bitbucket.api.BitbucketClient.repo') def test_before_page_load_osf_private_bb_public(self, mock_repo): mock_repo.return_value = {'is_private': False} message = self.node_settings.before_page_load(self.project, self.project.creator) mock_repo.assert_called_with( user=self.node_settings.user, repo=self.node_settings.repo, ) assert_true(message) assert_in( 'The files in this Bitbucket repo can be viewed on Bitbucket', message[0]) @mock.patch('addons.bitbucket.api.BitbucketClient.repo') def test_before_page_load_osf_private_bb_private(self, mock_repo): mock_repo.return_value = {'is_private': True} message = self.node_settings.before_page_load(self.project, self.project.creator) mock_repo.assert_called_with( user=self.node_settings.user, repo=self.node_settings.repo, ) assert_false(message) def test_before_page_load_not_contributor(self): message = self.node_settings.before_page_load(self.project, UserFactory()) assert_false(message) def test_before_page_load_not_logged_in(self): message = self.node_settings.before_page_load(self.project, None) assert_false(message) def test_before_remove_contributor_authenticator(self): message = self.node_settings.before_remove_contributor( self.project, self.project.creator) assert_true(message) def test_before_remove_contributor_not_authenticator(self): message = self.node_settings.before_remove_contributor( self.project, self.non_authenticator) assert_false(message) def test_after_remove_contributor_authenticator_self(self): message = self.node_settings.after_remove_contributor( self.project, self.project.creator, self.consolidated_auth) assert_equal(self.node_settings.user_settings, None) assert_true(message) assert_not_in('You can re-authenticate', message) def test_after_remove_contributor_authenticator_not_self(self): auth = Auth(user=self.non_authenticator) message = self.node_settings.after_remove_contributor( self.project, self.project.creator, auth) assert_equal(self.node_settings.user_settings, None) assert_true(message) assert_in('You can re-authenticate', message) def test_after_remove_contributor_not_authenticator(self): self.node_settings.after_remove_contributor(self.project, self.non_authenticator, self.consolidated_auth) assert_not_equal( self.node_settings.user_settings, None, ) def test_after_fork_authenticator(self): fork = ProjectFactory() clone = self.node_settings.after_fork( self.project, fork, self.project.creator, ) assert_equal( self.node_settings.user_settings, clone.user_settings, ) def test_after_fork_not_authenticator(self): fork = ProjectFactory() clone = self.node_settings.after_fork( self.project, fork, self.non_authenticator, ) assert_equal( clone.user_settings, None, ) def test_after_delete(self): self.project.remove_node(Auth(user=self.project.creator)) # Ensure that changes to node settings have been saved self.node_settings.reload() assert_true(self.node_settings.user_settings is None) @mock.patch('website.archiver.tasks.archive') def test_does_not_get_copied_to_registrations(self, mock_archive): registration = self.project.register_node( schema=get_default_metaschema(), auth=Auth(user=self.project.creator), data='hodor', ) assert_false(registration.has_addon('bitbucket'))
class TestGitLabSettings(OsfTestCase): def setUp(self): super(TestGitLabSettings, self).setUp() self.gitlab = create_mock_gitlab(user='******', private=False) self.project = ProjectFactory() self.auth = self.project.creator.auth self.consolidated_auth = Auth(user=self.project.creator) self.project.add_addon('gitlab', auth=self.consolidated_auth) self.project.creator.add_addon('gitlab') self.node_settings = self.project.get_addon('gitlab') self.user_settings = self.project.creator.get_addon('gitlab') self.node_settings.user_settings = self.user_settings self.node_settings.user = '******' self.node_settings.repo = 'Sheer-Heart-Attack' self.node_settings.repo_id = 'sheer-heart-attack' self.node_settings.save() @mock.patch('addons.gitlab.models.NodeSettings.add_hook') @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_link_repo(self, mock_repo, mock_add_hook): gitlab_mock = self.gitlab mock_repo.return_value = gitlab_mock.repo.return_value url = self.project.api_url + 'gitlab/settings/' self.app.post_json( url, { 'gitlab_user': '******', 'gitlab_repo': 'night at the opera', 'gitlab_repo_id': 'abc', }, auth=self.auth ).maybe_follow() self.project.reload() self.node_settings.reload() assert_equal(self.node_settings.user, 'queen') assert_equal(self.node_settings.repo, 'night at the opera') assert_equal(self.project.logs.latest().action, 'gitlab_repo_linked') mock_add_hook.assert_called_once_with(save=False) @mock.patch('addons.gitlab.models.NodeSettings.add_hook') @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_link_repo_no_change(self, mock_repo, mock_add_hook): gitlab_mock = self.gitlab mock_repo.return_value = gitlab_mock.repo.return_value log_count = self.project.logs.count() url = self.project.api_url + 'gitlab/settings/' self.app.post_json( url, { 'gitlab_user': self.node_settings.user, 'gitlab_repo': self.node_settings.repo, 'gitlab_repo_id': self.node_settings.repo_id, }, auth=self.auth ).maybe_follow() self.project.reload() self.node_settings.reload() assert_equal(self.project.logs.count(), log_count) assert_false(mock_add_hook.called) @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_link_repo_non_existent(self, mock_repo): mock_repo.return_value = None url = self.project.api_url + 'gitlab/settings/' res = self.app.post_json( url, { 'gitlab_user': '******', 'gitlab_repo': 'night at the opera', }, auth=self.auth, expect_errors=True ).maybe_follow() assert_equal(res.status_code, 400) @mock.patch('addons.gitlab.api.GitLabClient.branches') def test_link_repo_registration(self, mock_branches): mock_branches.return_value = [ Branch.from_json(dumps({ 'name': 'master', 'commit': { 'sha': '6dcb09b5b57875f334f61aebed695e2e4193db5e', 'url': 'https://api.gitlab.com/repos/octocat/Hello-World/commits/c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc', } })), Branch.from_json(dumps({ 'name': 'develop', 'commit': { 'sha': '6dcb09b5b57875asdasedawedawedwedaewdwdass', 'url': 'https://api.gitlab.com/repos/octocat/Hello-World/commits/cdcb09b5b57875asdasedawedawedwedaewdwdass', } })) ] registration = self.project.register_node( schema=get_default_metaschema(), auth=self.consolidated_auth, data='' ) url = registration.api_url + 'gitlab/settings/' res = self.app.post_json( url, { 'gitlab_user': '******', 'gitlab_repo': 'night at the opera', }, auth=self.auth, expect_errors=True ).maybe_follow() assert_equal(res.status_code, 400) @mock.patch('addons.gitlab.models.NodeSettings.delete_hook') def test_deauthorize(self, mock_delete_hook): url = self.project.api_url + 'gitlab/user_auth/' self.app.delete(url, auth=self.auth).maybe_follow() self.project.reload() self.node_settings.reload() assert_equal(self.node_settings.user, None) assert_equal(self.node_settings.repo, None) assert_equal(self.node_settings.user_settings, None) assert_equal(self.project.logs.latest().action, 'gitlab_node_deauthorized')
class TestGitLabSettings(OsfTestCase): def setUp(self): super(TestGitLabSettings, self).setUp() self.gitlab = create_mock_gitlab(user='******', private=False) self.project = ProjectFactory() self.auth = self.project.creator.auth self.consolidated_auth = Auth(user=self.project.creator) self.project.add_addon('gitlab', auth=self.consolidated_auth) self.project.creator.add_addon('gitlab') self.node_settings = self.project.get_addon('gitlab') self.user_settings = self.project.creator.get_addon('gitlab') self.node_settings.user_settings = self.user_settings self.node_settings.user = '******' self.node_settings.repo = 'Sheer-Heart-Attack' self.node_settings.repo_id = 'sheer-heart-attack' self.node_settings.save() @mock.patch('addons.gitlab.models.NodeSettings.add_hook') @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_link_repo(self, mock_repo, mock_add_hook): gitlab_mock = self.gitlab mock_repo.return_value = gitlab_mock.repo.return_value url = self.project.api_url + 'gitlab/settings/' self.app.post_json(url, { 'gitlab_user': '******', 'gitlab_repo': 'night at the opera', 'gitlab_repo_id': 'abc', }, auth=self.auth).maybe_follow() self.project.reload() self.node_settings.reload() assert_equal(self.node_settings.user, 'queen') assert_equal(self.node_settings.repo, 'night at the opera') assert_equal(self.project.logs.latest().action, 'gitlab_repo_linked') mock_add_hook.assert_called_once_with(save=False) @mock.patch('addons.gitlab.models.NodeSettings.add_hook') @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_link_repo_no_change(self, mock_repo, mock_add_hook): gitlab_mock = self.gitlab mock_repo.return_value = gitlab_mock.repo.return_value log_count = self.project.logs.count() url = self.project.api_url + 'gitlab/settings/' self.app.post_json(url, { 'gitlab_user': self.node_settings.user, 'gitlab_repo': self.node_settings.repo, 'gitlab_repo_id': self.node_settings.repo_id, }, auth=self.auth).maybe_follow() self.project.reload() self.node_settings.reload() assert_equal(self.project.logs.count(), log_count) assert_false(mock_add_hook.called) @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_link_repo_non_existent(self, mock_repo): mock_repo.return_value = None url = self.project.api_url + 'gitlab/settings/' res = self.app.post_json(url, { 'gitlab_user': '******', 'gitlab_repo': 'night at the opera', }, auth=self.auth, expect_errors=True).maybe_follow() assert_equal(res.status_code, 400) @mock.patch('addons.gitlab.api.GitLabClient.branches') def test_link_repo_registration(self, mock_branches): mock_branches.return_value = [ Branch.from_json( dumps({ 'name': 'master', 'commit': { 'sha': '6dcb09b5b57875f334f61aebed695e2e4193db5e', 'url': 'https://api.gitlab.com/repos/octocat/Hello-World/commits/c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc', } })), Branch.from_json( dumps({ 'name': 'develop', 'commit': { 'sha': '6dcb09b5b57875asdasedawedawedwedaewdwdass', 'url': 'https://api.gitlab.com/repos/octocat/Hello-World/commits/cdcb09b5b57875asdasedawedawedwedaewdwdass', } })) ] registration = self.project.register_node( schema=get_default_metaschema(), auth=self.consolidated_auth, data='') url = registration.api_url + 'gitlab/settings/' res = self.app.post_json(url, { 'gitlab_user': '******', 'gitlab_repo': 'night at the opera', }, auth=self.auth, expect_errors=True).maybe_follow() assert_equal(res.status_code, 400) @mock.patch('addons.gitlab.models.NodeSettings.delete_hook') def test_deauthorize(self, mock_delete_hook): url = self.project.api_url + 'gitlab/user_auth/' self.app.delete(url, auth=self.auth).maybe_follow() self.project.reload() self.node_settings.reload() assert_equal(self.node_settings.user, None) assert_equal(self.node_settings.repo, None) assert_equal(self.node_settings.user_settings, None) assert_equal(self.project.logs.latest().action, 'gitlab_node_deauthorized')
class TestCreateContainer(SwiftAddonTestCase, OsfTestCase): def setUp(self): super(TestCreateContainer, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.auth = self.user.auth self.project = ProjectFactory(creator=self.user) self.project.add_addon('swift', auth=self.consolidated_auth) self.project.creator.add_addon('swift') self.user_settings = self.user.get_addon('swift') self.user_settings.access_key = 'We-Will-Rock-You' self.user_settings.secret_key = 'Idontknowanyqueensongs' self.user_settings.save() self.node_settings = self.project.get_addon('swift') self.node_settings.container = 'Sheer-Heart-Attack' self.node_settings.user_settings = self.project.creator.get_addon( 'swift') self.node_settings.save() def test_bad_names(self): assert_false(validate_container_name('')) assert_false(validate_container_name('a' * 257)) assert_false(validate_container_name('a/b')) assert_false(validate_container_name('a/')) assert_false(validate_container_name('/a')) def test_names(self): assert_true(validate_container_name('a')) assert_true(validate_container_name('1')) assert_true(validate_container_name('can have whitespaces')) assert_true(validate_container_name('imagoodname')) assert_true(validate_container_name('still.passing')) assert_true(validate_container_name('can-have-dashes')) assert_true(validate_container_name('kinda.name.spaced')) assert_true(validate_container_name('a-o.valid')) assert_true(validate_container_name('11.12.m')) assert_true(validate_container_name('a--------a')) assert_true(validate_container_name('a' * 256)) @mock.patch('addons.swift.views.utils.create_container') @mock.patch('addons.swift.views.utils.get_container_names') def test_create_container_pass(self, mock_names, mock_make): mock_make.return_value = True mock_names.return_value = ['butintheend', 'it', 'doesntevenmatter'] url = self.project.api_url_for('swift_create_container') ret = self.app.post_json(url, {'container_name': 'doesntevenmatter'}, auth=self.user.auth) assert_equal(ret.status_int, http.OK) assert_equal(ret.json, {}) @mock.patch('addons.swift.views.utils.create_container') def test_create_container_fail(self, mock_make): error = swift_exceptions.ClientException( 'This should work', http_status=418, http_reason='because Im a test') mock_make.side_effect = error url = "/api/v1/project/{0}/swift/newcontainer/".format( self.project._id) ret = self.app.post_json(url, {'container_name': 'doesntevenmatter'}, auth=self.user.auth, expect_errors=True) assert_equals( ret.body, '{"message": "This should work", "title": "Problem creating container \'doesntevenmatter\'"}' )
class TestNodeFilesListFiltering(ApiTestCase): def setUp(self): super(TestNodeFilesListFiltering, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) httpretty.enable() # Prep HTTP mocks prepare_mock_wb_response( node=self.project, provider='github', files=[ {'name': 'abc', 'path': '/abc/', 'materialized': '/abc/', 'kind': 'folder'}, {'name': 'xyz', 'path': '/xyz', 'materialized': '/xyz', 'kind': 'file'}, ] ) def tearDown(self): super(TestNodeFilesListFiltering, self).tearDown() httpretty.disable() httpretty.reset() def add_github(self): user_auth = Auth(self.user) self.project.add_addon('github', auth=user_auth) addon = self.project.get_addon('github') addon.repo = 'something' addon.user = '******' oauth_settings = GitHubAccountFactory() oauth_settings.save() self.user.add_addon('github') self.user.external_accounts.add(oauth_settings) self.user.save() addon.user_settings = self.user.get_addon('github') addon.external_account = oauth_settings addon.save() self.project.save() addon.user_settings.oauth_grants[self.project._id] = {oauth_settings._id: []} addon.user_settings.save() def test_node_files_are_filterable_by_name(self): url = '/{}nodes/{}/files/github/?filter[name]=xyz'.format(API_BASE, self.project._id) self.add_github() res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 1) # filters out 'abc' assert_equal(res.json['data'][0]['attributes']['name'], 'xyz') def test_node_files_filter_by_name_case_insensitive(self): url = '/{}nodes/{}/files/github/?filter[name]=XYZ'.format(API_BASE, self.project._id) self.add_github() res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 1) # filters out 'abc', but finds 'xyz' assert_equal(res.json['data'][0]['attributes']['name'], 'xyz') def test_node_files_are_filterable_by_path(self): url = '/{}nodes/{}/files/github/?filter[path]=abc'.format(API_BASE, self.project._id) self.add_github() res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 1) # filters out 'xyz' assert_equal(res.json['data'][0]['attributes']['name'], 'abc') def test_node_files_are_filterable_by_kind(self): url = '/{}nodes/{}/files/github/?filter[kind]=folder'.format(API_BASE, self.project._id) self.add_github() res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 1) # filters out 'xyz' assert_equal(res.json['data'][0]['attributes']['name'], 'abc') def test_node_files_external_provider_can_filter_by_last_touched(self): yesterday_stamp = timezone.now() - datetime.timedelta(days=1) self.add_github() url = '/{}nodes/{}/files/github/?filter[last_touched][gt]={}'.format(API_BASE, self.project._id, yesterday_stamp.isoformat()) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 2) def test_node_files_osfstorage_cannot_filter_by_last_touched(self): yesterday_stamp = timezone.now() - datetime.timedelta(days=1) self.file = api_utils.create_test_file(self.project, self.user) url = '/{}nodes/{}/files/osfstorage/?filter[last_touched][gt]={}'.format(API_BASE, self.project._id, yesterday_stamp.isoformat()) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_equal(len(res.json['errors']), 1)
class TestBitbucketViews(OsfTestCase): def setUp(self): super(TestBitbucketViews, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.non_authenticator = UserFactory() self.project.add_contributor( contributor=self.non_authenticator, auth=self.consolidated_auth, ) self.project.save() self.external_account = BitbucketAccountFactory() self.project.add_addon('bitbucket', auth=self.consolidated_auth) self.project.creator.add_addon('bitbucket') self.project.creator.external_accounts.add(self.external_account) self.project.creator.save() self.bitbucket = create_mock_bitbucket(user='******', private=False) self.user_settings = self.project.creator.get_addon('bitbucket') self.user_settings.oauth_grants[self.project._id] = {self.external_account._id: []} self.user_settings.save() self.node_settings = self.project.get_addon('bitbucket') self.node_settings.user_settings = self.user_settings self.node_settings.external_account = self.external_account self.node_settings.user = self.bitbucket.repo.return_value['owner']['username'] self.node_settings.repo = self.bitbucket.repo.return_value['name'] self.node_settings.save() def _get_sha_for_branch(self, branch=None, mock_branches=None): bitbucket_mock = self.bitbucket if mock_branches is None: mock_branches = bitbucket_mock.branches if branch is None: # Get default branch name branch = self.bitbucket.repo_default_branch.return_value for each in mock_branches.return_value: if each['name'] == branch: branch_sha = each['target']['hash'] return branch_sha # Tests for _get_refs @mock.patch('addons.bitbucket.api.BitbucketClient.branches') @mock.patch('addons.bitbucket.api.BitbucketClient.repo') @mock.patch('addons.bitbucket.api.BitbucketClient.repo_default_branch') @mock.patch('addons.bitbucket.models.NodeSettings.external_account') def test_get_refs_defaults(self, mock_account, mock_default_branch, mock_repo, mock_branches): bitbucket_mock = self.bitbucket mock_account.return_value = mock.Mock() mock_default_branch.return_value = bitbucket_mock.repo_default_branch.return_value mock_repo.return_value = bitbucket_mock.repo.return_value mock_branches.return_value = bitbucket_mock.branches.return_value branch, sha, branches = utils.get_refs(self.node_settings) assert_equal( branch, bitbucket_mock.repo_default_branch.return_value ) assert_equal(sha, self._get_sha_for_branch(branch=None)) # Get refs for default branch expected_branches = [ {'name': x['name'], 'sha': x['target']['hash']} for x in bitbucket_mock.branches.return_value ] assert_equal(branches, expected_branches) @mock.patch('addons.bitbucket.api.BitbucketClient.branches') @mock.patch('addons.bitbucket.api.BitbucketClient.repo') @mock.patch('addons.bitbucket.api.BitbucketClient.repo_default_branch') @mock.patch('addons.bitbucket.models.NodeSettings.external_account') def test_get_refs_branch(self, mock_account, mock_default_branch, mock_repo, mock_branches): bitbucket_mock = self.bitbucket mock_account.return_value = mock.Mock() mock_default_branch.return_value = bitbucket_mock.repo_default_branch.return_value mock_repo.return_value = bitbucket_mock.repo.return_value mock_branches.return_value = bitbucket_mock.branches.return_value branch, sha, branches = utils.get_refs(self.node_settings, 'master') assert_equal(branch, 'master') branch_sha = self._get_sha_for_branch('master') assert_equal(sha, branch_sha) expected_branches = [ {'name': x['name'], 'sha': x['target']['hash']} for x in bitbucket_mock.branches.return_value ] assert_equal(branches, expected_branches) def test_before_fork(self): url = self.project.api_url + 'fork/before/' res = self.app.get(url, auth=self.user.auth).maybe_follow() assert_equal(len(res.json['prompts']), 1) def test_before_register(self): url = self.project.api_url + 'beforeregister/' res = self.app.get(url, auth=self.user.auth).maybe_follow() assert_true('Bitbucket' in res.json['prompts'][1]) @mock.patch('addons.bitbucket.models.NodeSettings.external_account') def test_get_refs_sha_no_branch(self, mock_account): with assert_raises(HTTPError): utils.get_refs(self.node_settings, sha='12345') def check_hook_urls(self, urls, node, path, sha): url = node.web_url_for('addon_view_or_download_file', path=path, provider='bitbucket') expected_urls = { 'view': '{0}?ref={1}'.format(url, sha), 'download': '{0}?action=download&ref={1}'.format(url, sha) } assert_equal(urls['view'], expected_urls['view']) assert_equal(urls['download'], expected_urls['download'])
class TestGitLabViews(OsfTestCase): def setUp(self): super(TestGitLabViews, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.non_authenticator = UserFactory() self.project.add_contributor( contributor=self.non_authenticator, auth=self.consolidated_auth, ) self.project.save() self.project.add_addon('gitlab', auth=self.consolidated_auth) self.project.creator.add_addon('gitlab') self.project.creator.external_accounts.add(GitLabAccountFactory()) self.project.creator.save() self.gitlab = create_mock_gitlab(user='******', private=False) self.node_settings = self.project.get_addon('gitlab') self.node_settings.user_settings = self.project.creator.get_addon( 'gitlab') # Set the node addon settings to correspond to the values of the mock repo self.node_settings.user = '******' self.node_settings.repo = 'mock-repo' self.node_settings.repo_id = 1748448 self.node_settings.save() def _get_sha_for_branch(self, branch=None, mock_branches=None): gitlab_mock = self.gitlab if mock_branches is None: mock_branches = gitlab_mock.branches if branch is None: # Get default branch name branch = self.gitlab.repo.default_branch for each in mock_branches: if each.name == branch: branch_sha = each.commit['id'] return branch_sha # Tests for _get_refs @mock.patch('addons.gitlab.api.GitLabClient.branches') @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_get_refs_defaults(self, mock_repo, mock_branches): gitlab_mock = self.gitlab mock_repo.return_value = gitlab_mock.repo mock_branches.return_value = gitlab_mock.branches.return_value branch, sha, branches = utils.get_refs(self.node_settings) assert_equal(branch, gitlab_mock.repo.default_branch) assert_equal(sha, branches[0].commit['id']) # Get refs for default branch assert_equal(branches, gitlab_mock.branches.return_value) @mock.patch('addons.gitlab.api.GitLabClient.branches') @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_get_refs_branch(self, mock_repo, mock_branches): gitlab_mock = self.gitlab mock_repo.return_value = gitlab_mock.repo.return_value mock_branches.return_value = gitlab_mock.branches.return_value branch, sha, branches = utils.get_refs(self.node_settings, 'master') assert_equal(branch, 'master') assert_equal(sha, branches[0].commit['id']) assert_equal(branches, gitlab_mock.branches.return_value) def test_before_fork(self): url = self.project.api_url + 'fork/before/' res = self.app.get(url, auth=self.user.auth).maybe_follow() assert_equal(len(res.json['prompts']), 1) @mock.patch('addons.gitlab.models.UserSettings.has_auth') def test_before_register(self, mock_has_auth): mock_has_auth.return_value = True url = self.project.api_url + 'beforeregister/' res = self.app.get(url, auth=self.user.auth).maybe_follow() assert_true('GitLab' in res.json['prompts'][1]) def test_get_refs_sha_no_branch(self): with assert_raises(HTTPError): utils.get_refs(self.node_settings, sha='12345') # Tests for _check_permissions # make a user with no authorization; make sure check_permissions returns false def test_permissions_no_auth(self): gitlab_mock = self.gitlab # project is set to private right now connection = gitlab_mock non_authenticated_user = UserFactory() non_authenticated_auth = Auth(user=non_authenticated_user) branch = 'master' assert_false( check_permissions(self.node_settings, non_authenticated_auth, connection, branch)) # make a repository that doesn't allow push access for this user; # make sure check_permissions returns false @mock.patch('addons.gitlab.models.UserSettings.has_auth') @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_permissions_no_access(self, mock_repo, mock_has_auth): gitlab_mock = self.gitlab mock_has_auth.return_value = True connection = gitlab_mock branch = 'master' mock_repository = mock.Mock( **{ 'user': '******', 'repo': 'mock-repo', 'permissions': { 'project_access': { 'access_level': 20, 'notification_level': 3 } }, }) mock_repo.attributes.return_value = mock_repository assert_false( check_permissions(self.node_settings, self.consolidated_auth, connection, branch, repo=mock_repository)) # make a branch with a different commit than the commit being passed into check_permissions @mock.patch('addons.gitlab.models.UserSettings.has_auth') @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_permissions_not_head(self, mock_repo, mock_has_auth): gitlab_mock = self.gitlab mock_has_auth.return_value = True connection = gitlab_mock mock_branch = mock.Mock(**{'commit': {'id': '67890'}}) connection.branches.return_value = mock_branch sha = '12345' assert_false( check_permissions(self.node_settings, self.consolidated_auth, connection, mock_branch, sha=sha)) # make sure permissions are not granted for editing a registration @mock.patch('addons.gitlab.models.UserSettings.has_auth') def test_permissions(self, mock_has_auth): gitlab_mock = self.gitlab mock_has_auth.return_value = True connection = gitlab_mock with mock.patch('osf.models.node.AbstractNode.is_registration', new_callable=mock.PropertyMock) as mock_is_reg: mock_is_reg.return_value = True assert_false( check_permissions(self.node_settings, self.consolidated_auth, connection, 'master')) def check_hook_urls(self, urls, node, path, sha): url = node.web_url_for('addon_view_or_download_file', path=path, provider='gitlab') expected_urls = { 'view': '{0}?branch={1}'.format(url, sha), 'download': '{0}?action=download&branch={1}'.format(url, sha) } assert_equal(urls['view'], expected_urls['view']) assert_equal(urls['download'], expected_urls['download']) @mock.patch('addons.gitlab.views.verify_hook_signature') @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_hook_callback_add_file_not_thro_osf(self, mock_repo, mock_verify): gitlab_mock = self.gitlab gitlab_mock.repo = mock_repo url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id) timestamp = str(datetime.datetime.utcnow()) self.app.post_json( url, { 'test': True, 'commits': [{ 'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'distinct': True, 'message': 'foo', 'timestamp': timestamp, 'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'author': { 'name': 'Illidan', 'email': '*****@*****.**' }, 'committer': { 'name': 'Testor', 'email': '*****@*****.**', 'username': '******' }, 'added': ['PRJWN3TV'], 'removed': [], 'modified': [], }] }, content_type='application/json', ).maybe_follow() self.project.reload() assert_equal(self.project.logs.latest().action, 'gitlab_file_added') urls = self.project.logs.latest().params['urls'] self.check_hook_urls( urls, self.project, path='PRJWN3TV', sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', ) @mock.patch('addons.gitlab.views.verify_hook_signature') def test_hook_callback_modify_file_not_thro_osf(self, mock_verify): url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id) timestamp = str(datetime.datetime.utcnow()) self.app.post_json(url, { 'test': True, 'commits': [{ 'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'distinct': True, 'message': ' foo', 'timestamp': timestamp, 'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'author': { 'name': 'Illidan', 'email': '*****@*****.**' }, 'committer': { 'name': 'Testor', 'email': '*****@*****.**', 'username': '******' }, 'added': [], 'removed': [], 'modified': ['PRJWN3TV'] }] }, content_type='application/json').maybe_follow() self.project.reload() assert_equal(self.project.logs.latest().action, 'gitlab_file_updated') urls = self.project.logs.latest().params['urls'] self.check_hook_urls( urls, self.project, path='PRJWN3TV', sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', ) @mock.patch('addons.gitlab.views.verify_hook_signature') def test_hook_callback_remove_file_not_thro_osf(self, mock_verify): url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id) timestamp = str(datetime.datetime.utcnow()) self.app.post_json(url, { 'test': True, 'commits': [{ 'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'distinct': True, 'message': 'foo', 'timestamp': timestamp, 'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'author': { 'name': 'Illidan', 'email': '*****@*****.**' }, 'committer': { 'name': 'Testor', 'email': '*****@*****.**', 'username': '******' }, 'added': [], 'removed': ['PRJWN3TV'], 'modified': [] }] }, content_type='application/json').maybe_follow() self.project.reload() assert_equal(self.project.logs.latest().action, 'gitlab_file_removed') urls = self.project.logs.latest().params['urls'] assert_equal(urls, {}) @mock.patch('addons.gitlab.views.verify_hook_signature') def test_hook_callback_add_file_thro_osf(self, mock_verify): url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id) self.app.post_json(url, { 'test': True, 'commits': [{ 'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'distinct': True, 'message': 'Added via the Open Science Framework', 'timestamp': '2014-01-08T14:15:51-08:00', 'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'author': { 'name': 'Illidan', 'email': '*****@*****.**' }, 'committer': { 'name': 'Testor', 'email': '*****@*****.**', 'username': '******' }, 'added': ['PRJWN3TV'], 'removed': [], 'modified': [] }] }, content_type='application/json').maybe_follow() self.project.reload() assert_not_equal(self.project.logs.latest().action, 'gitlab_file_added') @mock.patch('addons.gitlab.views.verify_hook_signature') def test_hook_callback_modify_file_thro_osf(self, mock_verify): url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id) self.app.post_json(url, { 'test': True, 'commits': [{ 'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'distinct': True, 'message': 'Updated via the Open Science Framework', 'timestamp': '2014-01-08T14:15:51-08:00', 'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'author': { 'name': 'Illidan', 'email': '*****@*****.**' }, 'committer': { 'name': 'Testor', 'email': '*****@*****.**', 'username': '******' }, 'added': [], 'removed': [], 'modified': ['PRJWN3TV'] }] }, content_type='application/json').maybe_follow() self.project.reload() assert_not_equal(self.project.logs.latest().action, 'gitlab_file_updated') @mock.patch('addons.gitlab.views.verify_hook_signature') def test_hook_callback_remove_file_thro_osf(self, mock_verify): url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id) self.app.post_json(url, { 'test': True, 'commits': [{ 'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'distinct': True, 'message': 'Deleted via the Open Science Framework', 'timestamp': '2014-01-08T14:15:51-08:00', 'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'author': { 'name': 'Illidan', 'email': '*****@*****.**' }, 'committer': { 'name': 'Testor', 'email': '*****@*****.**', 'username': '******' }, 'added': [], 'removed': ['PRJWN3TV'], 'modified': [] }] }, content_type='application/json').maybe_follow() self.project.reload() assert_not_equal(self.project.logs.latest().action, 'gitlab_file_removed')
class TestNodeFilesListPagination(ApiTestCase): def setUp(self): super(TestNodeFilesListPagination, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) httpretty.enable() def tearDown(self): super(TestNodeFilesListPagination, self).tearDown() httpretty.disable() httpretty.reset() def add_github(self): user_auth = Auth(self.user) self.project.add_addon('github', auth=user_auth) addon = self.project.get_addon('github') addon.repo = 'something' addon.user = '******' oauth_settings = GitHubAccountFactory() oauth_settings.save() self.user.add_addon('github') self.user.external_accounts.add(oauth_settings) self.user.save() addon.user_settings = self.user.get_addon('github') addon.external_account = oauth_settings addon.save() self.project.save() addon.user_settings.oauth_grants[self.project._id] = {oauth_settings._id: []} addon.user_settings.save() def check_file_order(self, resp): previous_file_name = 0 for file in resp.json['data']: int_file_name = int(file['attributes']['name']) assert int_file_name > previous_file_name, 'Files were not in order' previous_file_name = int_file_name def test_node_files_are_sorted_correctly(self): prepare_mock_wb_response( node=self.project, provider='github', files=[ {'name': '01', 'path': '/01/', 'materialized': '/01/', 'kind': 'folder'}, {'name': '02', 'path': '/02', 'materialized': '/02', 'kind': 'file'}, {'name': '03', 'path': '/03/', 'materialized': '/03/', 'kind': 'folder'}, {'name': '04', 'path': '/04', 'materialized': '/04', 'kind': 'file'}, {'name': '05', 'path': '/05/', 'materialized': '/05/', 'kind': 'folder'}, {'name': '06', 'path': '/06', 'materialized': '/06', 'kind': 'file'}, {'name': '07', 'path': '/07/', 'materialized': '/07/', 'kind': 'folder'}, {'name': '08', 'path': '/08', 'materialized': '/08', 'kind': 'file'}, {'name': '09', 'path': '/09/', 'materialized': '/09/', 'kind': 'folder'}, {'name': '10', 'path': '/10', 'materialized': '/10', 'kind': 'file'}, {'name': '11', 'path': '/11/', 'materialized': '/11/', 'kind': 'folder'}, {'name': '12', 'path': '/12', 'materialized': '/12', 'kind': 'file'}, {'name': '13', 'path': '/13/', 'materialized': '/13/', 'kind': 'folder'}, {'name': '14', 'path': '/14', 'materialized': '/14', 'kind': 'file'}, {'name': '15', 'path': '/15/', 'materialized': '/15/', 'kind': 'folder'}, {'name': '16', 'path': '/16', 'materialized': '/16', 'kind': 'file'}, {'name': '17', 'path': '/17/', 'materialized': '/17/', 'kind': 'folder'}, {'name': '18', 'path': '/18', 'materialized': '/18', 'kind': 'file'}, {'name': '19', 'path': '/19/', 'materialized': '/19/', 'kind': 'folder'}, {'name': '20', 'path': '/20', 'materialized': '/20', 'kind': 'file'}, {'name': '21', 'path': '/21/', 'materialized': '/21/', 'kind': 'folder'}, {'name': '22', 'path': '/22', 'materialized': '/22', 'kind': 'file'}, {'name': '23', 'path': '/23/', 'materialized': '/23/', 'kind': 'folder'}, {'name': '24', 'path': '/24', 'materialized': '/24', 'kind': 'file'}, ] ) self.add_github() url = '/{}nodes/{}/files/github/?page[size]=100'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth) self.check_file_order(res)
class TestCreateContainer(AzureBlobStorageAddonTestCase, OsfTestCase): def setUp(self): super(TestCreateContainer, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.auth = self.user.auth self.project = ProjectFactory(creator=self.user) self.project.add_addon('azureblobstorage', auth=self.consolidated_auth) self.project.creator.add_addon('azureblobstorage') self.user_settings = self.user.get_addon('azureblobstorage') self.user_settings.access_key = 'We-Will-Rock-You' self.user_settings.secret_key = 'Idontknowanyqueensongs' self.user_settings.save() self.node_settings = self.project.get_addon('azureblobstorage') self.node_settings.container = 'Sheer-Heart-Attack' self.node_settings.user_settings = self.project.creator.get_addon( 'azureblobstorage') self.node_settings.save() def test_bad_names(self): assert_false(validate_container_name('')) assert_false(validate_container_name('no')) assert_false(validate_container_name('a' * 64)) assert_false(validate_container_name(' leadingspace')) assert_false(validate_container_name('trailingspace ')) assert_false(validate_container_name('bogus naMe')) assert_false(validate_container_name('.cantstartwithp')) assert_false(validate_container_name('or.endwith.')) assert_false(validate_container_name('..nodoubles')) assert_false(validate_container_name('no_unders_in')) assert_false(validate_container_name('-leadinghyphen')) assert_false(validate_container_name('trailinghyphen-')) assert_false(validate_container_name('Mixedcase')) assert_false(validate_container_name('empty..label')) assert_false(validate_container_name('label-.trailinghyphen')) assert_false(validate_container_name('label.-leadinghyphen')) assert_false(validate_container_name('8.8.8.8')) assert_false(validate_container_name('600.9000.0.28')) assert_false(validate_container_name('no_underscore')) assert_false(validate_container_name('_nounderscoreinfront')) assert_false(validate_container_name('no-underscore-in-back_')) assert_false( validate_container_name('no-underscore-in_the_middle_either')) def test_names(self): assert_true(validate_container_name('imagoodname')) assert_true(validate_container_name('can-have-dashes')) assert_true(validate_container_name('a--------a')) assert_true(validate_container_name('a' * 63)) @mock.patch('addons.azureblobstorage.views.utils.create_container') @mock.patch('addons.azureblobstorage.views.utils.get_container_names') def test_create_container_pass(self, mock_names, mock_make): mock_make.return_value = True mock_names.return_value = ['butintheend', 'it', 'doesntevenmatter'] url = self.project.api_url_for('azureblobstorage_create_container') ret = self.app.post_json(url, {'container_name': 'doesntevenmatter'}, auth=self.user.auth) assert_equal(ret.status_int, http.OK) assert_equal(ret.json, {}) @mock.patch('addons.azureblobstorage.views.utils.create_container') def test_create_container_fail(self, mock_make): error = AzureHttpError('because Im a test', 418) error.message = 'This should work' mock_make.side_effect = error url = "/api/v1/project/{0}/azureblobstorage/newcontainer/".format( self.project._id) ret = self.app.post_json(url, {'container_name': 'doesntevenmatter'}, auth=self.user.auth, expect_errors=True) assert_equals( ret.body, '{"message": "This should work", "title": "Problem connecting to Azure Blob Storage"}' )
class TestNodeFilesList(ApiTestCase): def setUp(self): super(TestNodeFilesList, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.private_url = '/{}nodes/{}/files/'.format(API_BASE, self.project._id) self.user_two = AuthUserFactory() self.public_project = ProjectFactory(creator=self.user, is_public=True) self.public_url = '/{}nodes/{}/files/'.format(API_BASE, self.public_project._id) httpretty.enable() def tearDown(self): super(TestNodeFilesList, self).tearDown() httpretty.disable() httpretty.reset() def add_github(self): user_auth = Auth(self.user) self.project.add_addon('github', auth=user_auth) addon = self.project.get_addon('github') addon.repo = 'something' addon.user = '******' oauth_settings = GitHubAccountFactory() oauth_settings.save() self.user.add_addon('github') self.user.external_accounts.add(oauth_settings) self.user.save() addon.user_settings = self.user.get_addon('github') addon.external_account = oauth_settings addon.save() self.project.save() addon.user_settings.oauth_grants[self.project._id] = {oauth_settings._id: []} addon.user_settings.save() def _prepare_mock_wb_response(self, node=None, **kwargs): prepare_mock_wb_response(node=node or self.project, **kwargs) def test_returns_public_files_logged_out(self): res = self.app.get(self.public_url, expect_errors=True) assert_equal(res.status_code, 200) assert_equal(res.json['data'][0]['attributes']['provider'], 'osfstorage') assert_equal(res.content_type, 'application/vnd.api+json') def test_returns_public_files_logged_in(self): res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.content_type, 'application/vnd.api+json') assert_equal(res.json['data'][0]['attributes']['provider'], 'osfstorage') def test_returns_storage_addons_link(self): res = self.app.get(self.private_url, auth=self.user.auth) assert_in('storage_addons', res.json['data'][0]['links']) def test_returns_file_data(self): fobj = self.project.get_addon('osfstorage').get_root().append_file('NewFile') fobj.save() res = self.app.get('{}osfstorage/{}'.format(self.private_url, fobj._id), auth=self.user.auth) assert_equal(res.status_code, 200) assert_true(isinstance(res.json['data'], dict)) assert_equal(res.content_type, 'application/vnd.api+json') assert_equal(res.json['data']['attributes']['kind'], 'file') assert_equal(res.json['data']['attributes']['name'], 'NewFile') def test_returns_osfstorage_folder_version_two(self): fobj = self.project.get_addon('osfstorage').get_root().append_folder('NewFolder') fobj.save() res = self.app.get('{}osfstorage/'.format(self.private_url), auth=self.user.auth) assert_equal(res.status_code, 200) def test_returns_osf_storage_folder_version_two_point_two(self): fobj = self.project.get_addon('osfstorage').get_root().append_folder('NewFolder') fobj.save() res = self.app.get('{}osfstorage/?version=2.2'.format(self.private_url), auth=self.user.auth) assert_equal(res.status_code, 200) def test_list_returns_folder_data(self): fobj = self.project.get_addon('osfstorage').get_root().append_folder('NewFolder') fobj.save() res = self.app.get('{}osfstorage/'.format(self.private_url, fobj._id), auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 1) assert_equal(res.content_type, 'application/vnd.api+json') assert_equal(res.json['data'][0]['attributes']['name'], 'NewFolder') def test_returns_folder_data(self): fobj = self.project.get_addon('osfstorage').get_root().append_folder('NewFolder') fobj.save() res = self.app.get('{}osfstorage/{}/'.format(self.private_url, fobj._id), auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 0) assert_equal(res.content_type, 'application/vnd.api+json') def test_returns_private_files_logged_out(self): res = self.app.get(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) assert_in('detail', res.json['errors'][0]) def test_returns_private_files_logged_in_contributor(self): res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.content_type, 'application/vnd.api+json') assert_equal(len(res.json['data']), 1) assert_equal(res.json['data'][0]['attributes']['provider'], 'osfstorage') def test_returns_private_files_logged_in_non_contributor(self): res = self.app.get(self.private_url, auth=self.user_two.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_in('detail', res.json['errors'][0]) def test_returns_addon_folders(self): user_auth = Auth(self.user) res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(len(res.json['data']), 1) assert_equal(res.json['data'][0]['attributes']['provider'], 'osfstorage') self.project.add_addon('github', auth=user_auth) addon = self.project.get_addon('github') addon.repo = 'something' addon.user = '******' oauth_settings = GitHubAccountFactory() oauth_settings.save() self.user.add_addon('github') self.user.external_accounts.add(oauth_settings) self.user.save() addon.user_settings = self.user.get_addon('github') addon.external_account = oauth_settings addon.save() self.project.save() addon.user_settings.oauth_grants[self.project._id] = {oauth_settings._id: []} addon.user_settings.save() res = self.app.get(self.private_url, auth=self.user.auth) data = res.json['data'] providers = [item['attributes']['provider'] for item in data] assert_equal(len(data), 2) assert_in('github', providers) assert_in('osfstorage', providers) def test_returns_node_files_list(self): self._prepare_mock_wb_response(provider='github', files=[{'name': 'NewFile'}]) self.add_github() url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth) assert_equal(res.json['data'][0]['attributes']['name'], 'NewFile') assert_equal(res.json['data'][0]['attributes']['provider'], 'github') def test_returns_node_file(self): self._prepare_mock_wb_response(provider='github', files=[{'name': 'NewFile'}], folder=False, path='/file') self.add_github() url = '/{}nodes/{}/files/github/file'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth, headers={ 'COOKIE': 'foo=bar;' # Webtests doesnt support cookies? }) assert_equal(res.status_code, 200) assert_equal(res.json['data']['attributes']['name'], 'NewFile') assert_equal(res.json['data']['attributes']['provider'], 'github') def test_notfound_node_file_returns_folder(self): self._prepare_mock_wb_response(provider='github', files=[{'name': 'NewFile'}], path='/file') url = '/{}nodes/{}/files/github/file'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth, expect_errors=True, headers={ 'COOKIE': 'foo=bar;' # Webtests doesnt support cookies? }) assert_equal(res.status_code, 404) def test_notfound_node_folder_returns_file(self): self._prepare_mock_wb_response(provider='github', files=[{'name': 'NewFile'}], folder=False, path='/') url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth, expect_errors=True, headers={ 'COOKIE': 'foo=bar;' # Webtests doesnt support cookies? }) assert_equal(res.status_code, 404) def test_waterbutler_server_error_returns_503(self): self._prepare_mock_wb_response(status_code=500) self.add_github() url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth, expect_errors=True, headers={ 'COOKIE': 'foo=bar;' # Webtests doesnt support cookies? }) assert_equal(res.status_code, 503) def test_waterbutler_invalid_data_returns_503(self): wb_url = waterbutler_api_url_for(self.project._id, provider='github', path='/', meta=True) self.add_github() httpretty.register_uri( httpretty.GET, wb_url, body=json.dumps({}), status=400 ) url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 503) def test_handles_unauthenticated_waterbutler_request(self): self._prepare_mock_wb_response(status_code=401) self.add_github() url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_in('detail', res.json['errors'][0]) def test_handles_notfound_waterbutler_request(self): invalid_provider = 'gilkjadsflhub' self._prepare_mock_wb_response(status_code=404, provider=invalid_provider) url = '/{}nodes/{}/files/{}/'.format(API_BASE, self.project._id, invalid_provider) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) assert_in('detail', res.json['errors'][0]) def test_handles_request_to_provider_not_configured_on_project(self): provider = 'box' url = '/{}nodes/{}/files/{}/'.format(API_BASE, self.project._id, provider) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_false(self.project.get_addon(provider)) assert_equal(res.status_code, 404) assert_equal(res.json['errors'][0]['detail'], 'The {} provider is not configured for this project.'.format(provider)) def test_handles_bad_waterbutler_request(self): wb_url = waterbutler_api_url_for(self.project._id, provider='github', path='/', meta=True) httpretty.register_uri( httpretty.GET, wb_url, body=json.dumps({}), status=418 ) self.add_github() url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 503) assert_in('detail', res.json['errors'][0]) def test_files_list_contains_relationships_object(self): res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert 'relationships' in res.json['data'][0]
class TestViewUtils(OsfTestCase): def setUp(self): super(TestViewUtils, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() self.JWE_KEY = jwe.kdf(settings.WATERBUTLER_JWE_SECRET.encode('utf-8'), settings.WATERBUTLER_JWE_SALT.encode('utf-8')) def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = GitHubAccountFactory(display_name='john') self.oauth_settings.save() self.user.external_accounts.add(self.oauth_settings) self.user.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() self.user_addon.oauth_grants[self.node._id] = {self.oauth_settings._id: []} self.user_addon.save() def test_serialize_addons(self): addon_dicts = serialize_addons(self.node, self.auth_obj) enabled_addons = [addon for addon in addon_dicts if addon['enabled']] assert len(enabled_addons) == 2 assert enabled_addons[0]['short_name'] == 'github' assert enabled_addons[1]['short_name'] == 'osfstorage' default_addons = [addon for addon in addon_dicts if addon['default']] assert len(default_addons) == 1 assert default_addons[0]['short_name'] == 'osfstorage' def test_include_template_json(self): """ Some addons (github, gitlab) need more specialized template infomation so we want to ensure we get those extra variables that when the addon is enabled. """ addon_dicts = serialize_addons(self.node, self.auth_obj) enabled_addons = [addon for addon in addon_dicts if addon['enabled']] assert len(enabled_addons) == 2 assert enabled_addons[1]['short_name'] == 'osfstorage' assert enabled_addons[0]['short_name'] == 'github' assert 'node_has_auth' in enabled_addons[0] assert 'valid_credentials' in enabled_addons[0] def test_collect_node_config_js(self): addon_dicts = serialize_addons(self.node, self.auth_obj) asset_paths = collect_node_config_js(addon_dicts) # Default addons should be in addon dicts, but they have no js assets because you can't # connect/disconnect from them, think osfstorage, there's no node-cfg for that. default_addons = [addon['short_name'] for addon in addon_dicts if addon['default']] assert not any('/{}/'.format(addon) in asset_paths for addon in default_addons)
class TestAddonAuth(OsfTestCase): def setUp(self): super(TestAddonAuth, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() self.JWE_KEY = jwe.kdf(settings.WATERBUTLER_JWE_SECRET.encode('utf-8'), settings.WATERBUTLER_JWE_SALT.encode('utf-8')) def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = GitHubAccountFactory(display_name='john') self.oauth_settings.save() self.user.external_accounts.add(self.oauth_settings) self.user.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() self.user_addon.oauth_grants[self.node._id] = {self.oauth_settings._id: []} self.user_addon.save() def build_url(self, **kwargs): options = {'payload': jwe.encrypt(jwt.encode({'data': dict(dict( action='download', nid=self.node._id, provider=self.node_addon.config.short_name), **kwargs), 'exp': timezone.now() + datetime.timedelta(seconds=settings.WATERBUTLER_JWT_EXPIRATION), }, settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM), self.JWE_KEY)} return api_url_for('get_auth', **options) def test_auth_download(self): url = self.build_url() res = self.app.get(url, auth=self.user.auth) data = jwt.decode(jwe.decrypt(res.json['payload'].encode('utf-8'), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data'] assert_equal(data['auth'], views.make_auth(self.user)) assert_equal(data['credentials'], self.node_addon.serialize_waterbutler_credentials()) assert_equal(data['settings'], self.node_addon.serialize_waterbutler_settings()) expected_url = furl.furl(self.node.api_url_for('create_waterbutler_log', _absolute=True, _internal=True)) observed_url = furl.furl(data['callback_url']) observed_url.port = expected_url.port assert_equal(expected_url, observed_url) def test_auth_missing_args(self): url = self.build_url(cookie=None) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_bad_cookie(self): url = self.build_url(cookie=self.cookie) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 200) data = jwt.decode(jwe.decrypt(res.json['payload'].encode('utf-8'), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data'] assert_equal(data['auth'], views.make_auth(self.user)) assert_equal(data['credentials'], self.node_addon.serialize_waterbutler_credentials()) assert_equal(data['settings'], self.node_addon.serialize_waterbutler_settings()) expected_url = furl.furl(self.node.api_url_for('create_waterbutler_log', _absolute=True, _internal=True)) observed_url = furl.furl(data['callback_url']) observed_url.port = expected_url.port assert_equal(expected_url, observed_url) def test_auth_cookie(self): url = self.build_url(cookie=self.cookie[::-1]) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_missing_addon(self): url = self.build_url(provider='queenhub') res = self.app.get(url, expect_errors=True, auth=self.user.auth) assert_equal(res.status_code, 400) @mock.patch('addons.base.views.cas.get_client') def test_auth_bad_bearer_token(self, mock_cas_client): mock_cas_client.return_value = mock.Mock(profile=mock.Mock(return_value=cas.CasResponse(authenticated=False))) url = self.build_url() res = self.app.get(url, headers={'Authorization': 'Bearer invalid_access_token'}, expect_errors=True) assert_equal(res.status_code, 403)
class TestAddonAuth(OsfTestCase): def setUp(self): super(TestAddonAuth, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() self.JWE_KEY = jwe.kdf(settings.WATERBUTLER_JWE_SECRET.encode('utf-8'), settings.WATERBUTLER_JWE_SALT.encode('utf-8')) def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = GitHubAccountFactory(display_name='john') self.oauth_settings.save() self.user.external_accounts.add(self.oauth_settings) self.user.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() self.user_addon.oauth_grants[self.node._id] = {self.oauth_settings._id: []} self.user_addon.save() def build_url(self, **kwargs): options = {'payload': jwe.encrypt(jwt.encode({'data': dict(dict( action='download', nid=self.node._id, provider=self.node_addon.config.short_name), **kwargs), 'exp': timezone.now() + datetime.timedelta(seconds=settings.WATERBUTLER_JWT_EXPIRATION), }, settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM), self.JWE_KEY)} return api_url_for('get_auth', **options) def test_auth_download(self): url = self.build_url() res = self.app.get(url, auth=self.user.auth) data = jwt.decode(jwe.decrypt(res.json['payload'].encode('utf-8'), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data'] assert_equal(data['auth'], views.make_auth(self.user)) assert_equal(data['credentials'], self.node_addon.serialize_waterbutler_credentials()) assert_equal(data['settings'], self.node_addon.serialize_waterbutler_settings()) expected_url = furl.furl(self.node.api_url_for('create_waterbutler_log', _absolute=True, _internal=True)) observed_url = furl.furl(data['callback_url']) observed_url.port = expected_url.port assert_equal(expected_url, observed_url) def test_auth_missing_args(self): url = self.build_url(cookie=None) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_bad_cookie(self): url = self.build_url(cookie=self.cookie) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 200) data = jwt.decode(jwe.decrypt(res.json['payload'].encode('utf-8'), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data'] assert_equal(data['auth'], views.make_auth(self.user)) assert_equal(data['credentials'], self.node_addon.serialize_waterbutler_credentials()) assert_equal(data['settings'], self.node_addon.serialize_waterbutler_settings()) expected_url = furl.furl(self.node.api_url_for('create_waterbutler_log', _absolute=True, _internal=True)) observed_url = furl.furl(data['callback_url']) observed_url.port = expected_url.port assert_equal(expected_url, observed_url) def test_auth_cookie(self): url = self.build_url(cookie=self.cookie[::-1]) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_missing_addon(self): url = self.build_url(provider='queenhub') res = self.app.get(url, expect_errors=True, auth=self.user.auth) assert_equal(res.status_code, 400) @mock.patch('addons.base.views.cas.get_client') def test_auth_bad_bearer_token(self, mock_cas_client): mock_cas_client.return_value = mock.Mock(profile=mock.Mock(return_value=cas.CasResponse(authenticated=False))) url = self.build_url() res = self.app.get(url, headers={'Authorization': 'Bearer invalid_access_token'}, expect_errors=True) assert_equal(res.status_code, 403)
class TestViewUtils(OsfTestCase): def setUp(self): super(TestViewUtils, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() self.JWE_KEY = jwe.kdf(settings.WATERBUTLER_JWE_SECRET.encode('utf-8'), settings.WATERBUTLER_JWE_SALT.encode('utf-8')) def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = GitHubAccountFactory(display_name='john') self.oauth_settings.save() self.user.external_accounts.add(self.oauth_settings) self.user.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() self.user_addon.oauth_grants[self.node._id] = {self.oauth_settings._id: []} self.user_addon.save() def test_serialize_addons(self): addon_dicts = serialize_addons(self.node, self.auth_obj) enabled_addons = [addon for addon in addon_dicts if addon['enabled']] assert len(enabled_addons) == 2 assert enabled_addons[0]['short_name'] == 'github' assert enabled_addons[1]['short_name'] == 'osfstorage' default_addons = [addon for addon in addon_dicts if addon['default']] assert len(default_addons) == 1 assert default_addons[0]['short_name'] == 'osfstorage' def test_include_template_json(self): """ Some addons (github, gitlab) need more specialized template infomation so we want to ensure we get those extra variables that when the addon is enabled. """ addon_dicts = serialize_addons(self.node, self.auth_obj) enabled_addons = [addon for addon in addon_dicts if addon['enabled']] assert len(enabled_addons) == 2 assert enabled_addons[1]['short_name'] == 'osfstorage' assert enabled_addons[0]['short_name'] == 'github' assert 'node_has_auth' in enabled_addons[0] assert 'valid_credentials' in enabled_addons[0] def test_collect_node_config_js(self): addon_dicts = serialize_addons(self.node, self.auth_obj) asset_paths = collect_node_config_js(addon_dicts) # Default addons should be in addon dicts, but they have no js assets because you can't # connect/disconnect from them, think osfstorage, there's no node-cfg for that. default_addons = [addon['short_name'] for addon in addon_dicts if addon['default']] assert not any('/{}/'.format(addon) in asset_paths for addon in default_addons)
class TestNodeFilesListFiltering(ApiTestCase): def setUp(self): super(TestNodeFilesListFiltering, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) httpretty.enable() # Prep HTTP mocks prepare_mock_wb_response(node=self.project, provider='github', files=[ { 'name': 'abc', 'path': '/abc/', 'materialized': '/abc/', 'kind': 'folder' }, { 'name': 'xyz', 'path': '/xyz', 'materialized': '/xyz', 'kind': 'file' }, ]) def tearDown(self): super(TestNodeFilesListFiltering, self).tearDown() httpretty.disable() httpretty.reset() def add_github(self): user_auth = Auth(self.user) self.project.add_addon('github', auth=user_auth) addon = self.project.get_addon('github') addon.repo = 'something' addon.user = '******' oauth_settings = GitHubAccountFactory() oauth_settings.save() self.user.add_addon('github') self.user.external_accounts.add(oauth_settings) self.user.save() addon.user_settings = self.user.get_addon('github') addon.external_account = oauth_settings addon.save() self.project.save() addon.user_settings.oauth_grants[self.project._id] = { oauth_settings._id: [] } addon.user_settings.save() def test_node_files_are_filterable_by_name(self): url = '/{}nodes/{}/files/github/?filter[name]=xyz'.format( API_BASE, self.project._id) self.add_github() # test create res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 1) # filters out 'abc' assert_equal(res.json['data'][0]['attributes']['name'], 'xyz') # test get res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 1) # filters out 'abc' assert_equal(res.json['data'][0]['attributes']['name'], 'xyz') def test_node_files_filter_by_name_case_insensitive(self): url = '/{}nodes/{}/files/github/?filter[name]=XYZ'.format( API_BASE, self.project._id) self.add_github() # test create res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) # filters out 'abc', but finds 'xyz' assert_equal(len(res.json['data']), 1) assert_equal(res.json['data'][0]['attributes']['name'], 'xyz') # test get res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) # filters out 'abc', but finds 'xyz' assert_equal(len(res.json['data']), 1) assert_equal(res.json['data'][0]['attributes']['name'], 'xyz') def test_node_files_are_filterable_by_path(self): url = '/{}nodes/{}/files/github/?filter[path]=abc'.format( API_BASE, self.project._id) self.add_github() # test create res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 1) # filters out 'xyz' assert_equal(res.json['data'][0]['attributes']['name'], 'abc') # test get res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 1) # filters out 'xyz' assert_equal(res.json['data'][0]['attributes']['name'], 'abc') def test_node_files_are_filterable_by_kind(self): url = '/{}nodes/{}/files/github/?filter[kind]=folder'.format( API_BASE, self.project._id) self.add_github() # test create res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 1) # filters out 'xyz' assert_equal(res.json['data'][0]['attributes']['name'], 'abc') # test get res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 1) # filters out 'xyz' assert_equal(res.json['data'][0]['attributes']['name'], 'abc') def test_node_files_external_provider_can_filter_by_last_touched(self): yesterday_stamp = timezone.now() - datetime.timedelta(days=1) self.add_github() url = '/{}nodes/{}/files/github/?filter[last_touched][gt]={}'.format( API_BASE, self.project._id, yesterday_stamp.isoformat()) # test create res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 2) # test get res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 2) def test_node_files_osfstorage_cannot_filter_by_last_touched(self): yesterday_stamp = timezone.now() - datetime.timedelta(days=1) self.file = api_utils.create_test_file(self.project, self.user) url = '/{}nodes/{}/files/osfstorage/?filter[last_touched][gt]={}'.format( API_BASE, self.project._id, yesterday_stamp.isoformat()) # test create res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_equal(len(res.json['errors']), 1) # test get res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_equal(len(res.json['errors']), 1)
class TestCallbacks(OsfTestCase): def setUp(self): super(TestCallbacks, self).setUp() self.project = ProjectFactory() self.consolidated_auth = Auth(self.project.creator) self.project.creator.save() self.non_authenticator = UserFactory() self.non_authenticator.save() self.project.save() self.project.add_contributor( contributor=self.non_authenticator, auth=self.consolidated_auth, ) self.project.add_addon('github', auth=self.consolidated_auth) self.project.creator.add_addon('github') self.external_account = factories.GitHubAccountFactory() self.project.creator.external_accounts.add(self.external_account) self.project.creator.save() self.node_settings = self.project.get_addon('github') self.user_settings = self.project.creator.get_addon('github') self.node_settings.user_settings = self.user_settings self.node_settings.user = '******' self.node_settings.repo = 'Sheer-Heart-Attack' self.node_settings.external_account = self.external_account self.node_settings.save() self.node_settings.set_auth self.user_settings.oauth_grants[self.project._id] = { self.external_account._id: [] } self.user_settings.save() @mock.patch('addons.github.api.GitHubClient.repo') def test_before_make_public(self, mock_repo): mock_repo.side_effect = NotFoundError result = self.node_settings.before_make_public(self.project) assert_is(result, None) @mock.patch('addons.github.api.GitHubClient.repo') def test_before_page_load_osf_public_gh_public(self, mock_repo): self.project.is_public = True self.project.save() mock_repo.return_value = Repository.from_json(dumps({'private': False})) message = self.node_settings.before_page_load(self.project, self.project.creator) mock_repo.assert_called_with( self.node_settings.user, self.node_settings.repo, ) assert_false(message) @mock.patch('addons.github.api.GitHubClient.repo') def test_before_page_load_osf_public_gh_private(self, mock_repo): self.project.is_public = True self.project.save() mock_repo.return_value = Repository.from_json(dumps({'private': True})) message = self.node_settings.before_page_load(self.project, self.project.creator) mock_repo.assert_called_with( self.node_settings.user, self.node_settings.repo, ) assert_true(message) @mock.patch('addons.github.api.GitHubClient.repo') def test_before_page_load_osf_private_gh_public(self, mock_repo): mock_repo.return_value = Repository.from_json(dumps({'private': False})) message = self.node_settings.before_page_load(self.project, self.project.creator) mock_repo.assert_called_with( self.node_settings.user, self.node_settings.repo, ) assert_true(message) @mock.patch('addons.github.api.GitHubClient.repo') def test_before_page_load_osf_private_gh_private(self, mock_repo): mock_repo.return_value = Repository.from_json(dumps({'private': True})) message = self.node_settings.before_page_load(self.project, self.project.creator) mock_repo.assert_called_with( self.node_settings.user, self.node_settings.repo, ) assert_false(message) def test_before_page_load_not_contributor(self): message = self.node_settings.before_page_load(self.project, UserFactory()) assert_false(message) def test_before_page_load_not_logged_in(self): message = self.node_settings.before_page_load(self.project, None) assert_false(message) def test_before_remove_contributor_authenticator(self): message = self.node_settings.before_remove_contributor( self.project, self.project.creator) assert_true(message) def test_before_remove_contributor_not_authenticator(self): message = self.node_settings.before_remove_contributor( self.project, self.non_authenticator) assert_false(message) def test_after_remove_contributor_authenticator_self(self): message = self.node_settings.after_remove_contributor( self.project, self.project.creator, self.consolidated_auth) assert_equal(self.node_settings.user_settings, None) assert_true(message) assert_not_in('You can re-authenticate', message) def test_after_remove_contributor_authenticator_not_self(self): auth = Auth(user=self.non_authenticator) message = self.node_settings.after_remove_contributor( self.project, self.project.creator, auth) assert_equal(self.node_settings.user_settings, None) assert_true(message) assert_in('You can re-authenticate', message) def test_after_remove_contributor_not_authenticator(self): self.node_settings.after_remove_contributor(self.project, self.non_authenticator, self.consolidated_auth) assert_not_equal( self.node_settings.user_settings, None, ) def test_after_fork_authenticator(self): fork = ProjectFactory() clone = self.node_settings.after_fork( self.project, fork, self.project.creator, ) assert_equal( self.node_settings.user_settings, clone.user_settings, ) def test_after_fork_not_authenticator(self): fork = ProjectFactory() clone = self.node_settings.after_fork( self.project, fork, self.non_authenticator, ) assert_equal( clone.user_settings, None, ) def test_after_delete(self): self.project.remove_node(Auth(user=self.project.creator)) # Ensure that changes to node settings have been saved self.node_settings.reload() assert_true(self.node_settings.user_settings is None) @mock.patch('website.archiver.tasks.archive') def test_does_not_get_copied_to_registrations(self, mock_archive): registration = self.project.register_node( schema=get_default_metaschema(), auth=Auth(user=self.project.creator), draft_registration=DraftRegistrationFactory( branched_from=self.project), ) assert_false(registration.has_addon('github'))
class TestNodeFilesList(ApiTestCase): def setUp(self): super(TestNodeFilesList, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.private_url = '/{}nodes/{}/files/'.format(API_BASE, self.project._id) self.user_two = AuthUserFactory() self.public_project = ProjectFactory(creator=self.user, is_public=True) self.public_url = '/{}nodes/{}/files/'.format(API_BASE, self.public_project._id) httpretty.enable() def tearDown(self): super(TestNodeFilesList, self).tearDown() httpretty.disable() httpretty.reset() def add_github(self): user_auth = Auth(self.user) self.project.add_addon('github', auth=user_auth) addon = self.project.get_addon('github') addon.repo = 'something' addon.user = '******' oauth_settings = GitHubAccountFactory() oauth_settings.save() self.user.add_addon('github') self.user.external_accounts.add(oauth_settings) self.user.save() addon.user_settings = self.user.get_addon('github') addon.external_account = oauth_settings addon.save() self.project.save() addon.user_settings.oauth_grants[self.project._id] = { oauth_settings._id: [] } addon.user_settings.save() def view_only_link(self): private_link = PrivateLinkFactory(creator=self.user) private_link.nodes.add(self.project) private_link.save() return private_link def _prepare_mock_wb_response(self, node=None, **kwargs): prepare_mock_wb_response(node=node or self.project, **kwargs) def test_returns_public_files_logged_out(self): res = self.app.get(self.public_url, expect_errors=True) assert_equal(res.status_code, 200) assert_equal(res.json['data'][0]['attributes']['provider'], 'osfstorage') assert_equal(res.content_type, 'application/vnd.api+json') def test_returns_public_files_logged_in(self): res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.content_type, 'application/vnd.api+json') assert_equal(res.json['data'][0]['attributes']['provider'], 'osfstorage') def test_returns_storage_addons_link(self): res = self.app.get(self.private_url, auth=self.user.auth) assert_in('storage_addons', res.json['data'][0]['links']) def test_returns_file_data(self): fobj = self.project.get_addon('osfstorage').get_root().append_file( 'NewFile') fobj.save() res = self.app.get('{}osfstorage/{}'.format(self.private_url, fobj._id), auth=self.user.auth) assert_equal(res.status_code, 200) assert_true(isinstance(res.json['data'], dict)) assert_equal(res.content_type, 'application/vnd.api+json') assert_equal(res.json['data']['attributes']['kind'], 'file') assert_equal(res.json['data']['attributes']['name'], 'NewFile') def test_returns_osfstorage_folder_version_two(self): fobj = self.project.get_addon('osfstorage').get_root().append_folder( 'NewFolder') fobj.save() res = self.app.get('{}osfstorage/'.format(self.private_url), auth=self.user.auth) assert_equal(res.status_code, 200) def test_returns_osf_storage_folder_version_two_point_two(self): fobj = self.project.get_addon('osfstorage').get_root().append_folder( 'NewFolder') fobj.save() res = self.app.get('{}osfstorage/?version=2.2'.format( self.private_url), auth=self.user.auth) assert_equal(res.status_code, 200) def test_list_returns_folder_data(self): fobj = self.project.get_addon('osfstorage').get_root().append_folder( 'NewFolder') fobj.save() res = self.app.get('{}osfstorage/'.format(self.private_url, fobj._id), auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 1) assert_equal(res.content_type, 'application/vnd.api+json') assert_equal(res.json['data'][0]['attributes']['name'], 'NewFolder') def test_returns_folder_data(self): fobj = self.project.get_addon('osfstorage').get_root().append_folder( 'NewFolder') fobj.save() res = self.app.get('{}osfstorage/{}/'.format(self.private_url, fobj._id), auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']), 0) assert_equal(res.content_type, 'application/vnd.api+json') def test_returns_private_files_logged_out(self): res = self.app.get(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) assert_in('detail', res.json['errors'][0]) def test_returns_private_files_logged_in_contributor(self): res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.content_type, 'application/vnd.api+json') assert_equal(len(res.json['data']), 1) assert_equal(res.json['data'][0]['attributes']['provider'], 'osfstorage') def test_returns_private_files_logged_in_non_contributor(self): res = self.app.get(self.private_url, auth=self.user_two.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_in('detail', res.json['errors'][0]) def test_returns_addon_folders(self): user_auth = Auth(self.user) res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(len(res.json['data']), 1) assert_equal(res.json['data'][0]['attributes']['provider'], 'osfstorage') self.project.add_addon('github', auth=user_auth) addon = self.project.get_addon('github') addon.repo = 'something' addon.user = '******' oauth_settings = GitHubAccountFactory() oauth_settings.save() self.user.add_addon('github') self.user.external_accounts.add(oauth_settings) self.user.save() addon.user_settings = self.user.get_addon('github') addon.external_account = oauth_settings addon.save() self.project.save() addon.user_settings.oauth_grants[self.project._id] = { oauth_settings._id: [] } addon.user_settings.save() res = self.app.get(self.private_url, auth=self.user.auth) data = res.json['data'] providers = [item['attributes']['provider'] for item in data] assert_equal(len(data), 2) assert_in('github', providers) assert_in('osfstorage', providers) def test_vol_node_files_list(self): self._prepare_mock_wb_response(provider='github', files=[{ 'name': 'NewFile' }]) self.add_github() vol = self.view_only_link() url = '/{}nodes/{}/files/github/?view_only={}'.format( API_BASE, self.project._id, vol.key) res = self.app.get(url, auth=self.user_two.auth) wb_request = httpretty.last_request() assert_equal(wb_request.querystring, { u'view_only': [unicode(vol.key, 'utf-8')], u'meta': [u'True'] }) assert_equal(res.json['data'][0]['attributes']['name'], 'NewFile') assert_equal(res.json['data'][0]['attributes']['provider'], 'github') assert_in(vol.key, res.json['data'][0]['links']['info']) assert_in(vol.key, res.json['data'][0]['links']['move']) assert_in(vol.key, res.json['data'][0]['links']['upload']) assert_in(vol.key, res.json['data'][0]['links']['download']) assert_in(vol.key, res.json['data'][0]['links']['delete']) def test_returns_node_files_list(self): self._prepare_mock_wb_response(provider='github', files=[{ 'name': 'NewFile' }]) self.add_github() url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) # test create res = self.app.get(url, auth=self.user.auth) assert_equal(res.json['data'][0]['attributes']['name'], 'NewFile') assert_equal(res.json['data'][0]['attributes']['provider'], 'github') # test get res = self.app.get(url, auth=self.user.auth) assert_equal(res.json['data'][0]['attributes']['name'], 'NewFile') assert_equal(res.json['data'][0]['attributes']['provider'], 'github') def test_returns_node_file(self): self._prepare_mock_wb_response(provider='github', files=[{ 'name': 'NewFile' }], folder=False, path='/file') self.add_github() url = '/{}nodes/{}/files/github/file'.format(API_BASE, self.project._id) res = self.app.get( url, auth=self.user.auth, headers={ 'COOKIE': 'foo=bar;' # Webtests doesnt support cookies? }) # test create assert_equal(res.status_code, 200) assert_equal(res.json['data']['attributes']['name'], 'NewFile') assert_equal(res.json['data']['attributes']['provider'], 'github') # test get assert_equal(res.status_code, 200) assert_equal(res.json['data']['attributes']['name'], 'NewFile') assert_equal(res.json['data']['attributes']['provider'], 'github') def test_notfound_node_file_returns_folder(self): self._prepare_mock_wb_response(provider='github', files=[{ 'name': 'NewFile' }], path='/file') url = '/{}nodes/{}/files/github/file'.format(API_BASE, self.project._id) res = self.app.get( url, auth=self.user.auth, expect_errors=True, headers={'COOKIE': 'foo=bar;'} # Webtests doesnt support cookies? ) assert_equal(res.status_code, 404) def test_notfound_node_folder_returns_file(self): self._prepare_mock_wb_response(provider='github', files=[{ 'name': 'NewFile' }], folder=False, path='/') url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get( url, auth=self.user.auth, expect_errors=True, headers={'COOKIE': 'foo=bar;'} # Webtests doesnt support cookies? ) assert_equal(res.status_code, 404) def test_waterbutler_server_error_returns_503(self): self._prepare_mock_wb_response(status_code=500) self.add_github() url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get( url, auth=self.user.auth, expect_errors=True, headers={'COOKIE': 'foo=bar;'} # Webtests doesnt support cookies? ) assert_equal(res.status_code, 503) def test_waterbutler_invalid_data_returns_503(self): wb_url = waterbutler_api_url_for(self.project._id, provider='github', path='/', meta=True) self.add_github() httpretty.register_uri(httpretty.GET, wb_url, body=json.dumps({}), status=400) url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 503) def test_handles_unauthenticated_waterbutler_request(self): self._prepare_mock_wb_response(status_code=401) self.add_github() url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_in('detail', res.json['errors'][0]) def test_handles_notfound_waterbutler_request(self): invalid_provider = 'gilkjadsflhub' self._prepare_mock_wb_response(status_code=404, provider=invalid_provider) url = '/{}nodes/{}/files/{}/'.format(API_BASE, self.project._id, invalid_provider) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) assert_in('detail', res.json['errors'][0]) def test_handles_request_to_provider_not_configured_on_project(self): provider = 'box' url = '/{}nodes/{}/files/{}/'.format(API_BASE, self.project._id, provider) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_false(self.project.get_addon(provider)) assert_equal(res.status_code, 404) assert_equal( res.json['errors'][0]['detail'], 'The {} provider is not configured for this project.'.format( provider)) def test_handles_bad_waterbutler_request(self): wb_url = waterbutler_api_url_for(self.project._id, provider='github', path='/', meta=True) httpretty.register_uri(httpretty.GET, wb_url, body=json.dumps({}), status=418) self.add_github() url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 503) assert_in('detail', res.json['errors'][0]) def test_files_list_contains_relationships_object(self): res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert 'relationships' in res.json['data'][0]
class TestGitLabViews(OsfTestCase): def setUp(self): super(TestGitLabViews, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.non_authenticator = UserFactory() self.project.add_contributor( contributor=self.non_authenticator, auth=self.consolidated_auth, ) self.project.save() self.project.add_addon('gitlab', auth=self.consolidated_auth) self.project.creator.add_addon('gitlab') self.project.creator.external_accounts.add(GitLabAccountFactory()) self.project.creator.save() self.gitlab = create_mock_gitlab(user='******', private=False) self.node_settings = self.project.get_addon('gitlab') self.node_settings.user_settings = self.project.creator.get_addon('gitlab') # Set the node addon settings to correspond to the values of the mock repo self.node_settings.user = '******' self.node_settings.repo = 'mock-repo' self.node_settings.repo_id = 1748448 self.node_settings.save() def _get_sha_for_branch(self, branch=None, mock_branches=None): gitlab_mock = self.gitlab if mock_branches is None: mock_branches = gitlab_mock.branches if branch is None: # Get default branch name branch = self.gitlab.repo.default_branch for each in mock_branches: if each.name == branch: branch_sha = each.commit['id'] return branch_sha # Tests for _get_refs @mock.patch('addons.gitlab.api.GitLabClient.branches') @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_get_refs_defaults(self, mock_repo, mock_branches): gitlab_mock = self.gitlab mock_repo.return_value = gitlab_mock.repo mock_branches.return_value = gitlab_mock.branches.return_value branch, sha, branches = utils.get_refs(self.node_settings) assert_equal( branch, gitlab_mock.repo.default_branch ) assert_equal(sha, branches[0].commit['id']) # Get refs for default branch assert_equal( branches, gitlab_mock.branches.return_value ) @mock.patch('addons.gitlab.api.GitLabClient.branches') @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_get_refs_branch(self, mock_repo, mock_branches): gitlab_mock = self.gitlab mock_repo.return_value = gitlab_mock.repo.return_value mock_branches.return_value = gitlab_mock.branches.return_value branch, sha, branches = utils.get_refs(self.node_settings, 'master') assert_equal(branch, 'master') assert_equal(sha, branches[0].commit['id']) assert_equal( branches, gitlab_mock.branches.return_value ) def test_before_fork(self): url = self.project.api_url + 'fork/before/' res = self.app.get(url, auth=self.user.auth).maybe_follow() assert_equal(len(res.json['prompts']), 1) @mock.patch('addons.gitlab.models.UserSettings.has_auth') def test_before_register(self, mock_has_auth): mock_has_auth.return_value = True url = self.project.api_url + 'beforeregister/' res = self.app.get(url, auth=self.user.auth).maybe_follow() assert_true('GitLab' in res.json['prompts'][1]) def test_get_refs_sha_no_branch(self): with assert_raises(HTTPError): utils.get_refs(self.node_settings, sha='12345') # Tests for _check_permissions # make a user with no authorization; make sure check_permissions returns false def test_permissions_no_auth(self): gitlab_mock = self.gitlab # project is set to private right now connection = gitlab_mock non_authenticated_user = UserFactory() non_authenticated_auth = Auth(user=non_authenticated_user) branch = 'master' assert_false(check_permissions(self.node_settings, non_authenticated_auth, connection, branch)) # make a repository that doesn't allow push access for this user; # make sure check_permissions returns false @mock.patch('addons.gitlab.models.UserSettings.has_auth') @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_permissions_no_access(self, mock_repo, mock_has_auth): gitlab_mock = self.gitlab mock_has_auth.return_value = True connection = gitlab_mock branch = 'master' mock_repository = mock.Mock(**{ 'user': '******', 'repo': 'mock-repo', 'permissions': { 'project_access': {'access_level': 20, 'notification_level': 3} }, }) mock_repo.attributes.return_value = mock_repository assert_false(check_permissions(self.node_settings, self.consolidated_auth, connection, branch, repo=mock_repository)) # make a branch with a different commit than the commit being passed into check_permissions @mock.patch('addons.gitlab.models.UserSettings.has_auth') @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_permissions_not_head(self, mock_repo, mock_has_auth): gitlab_mock = self.gitlab mock_has_auth.return_value = True connection = gitlab_mock mock_branch = mock.Mock(**{ 'commit': {'id': '67890'} }) connection.branches.return_value = mock_branch sha = '12345' assert_false(check_permissions(self.node_settings, self.consolidated_auth, connection, mock_branch, sha=sha)) # make sure permissions are not granted for editing a registration @mock.patch('addons.gitlab.models.UserSettings.has_auth') def test_permissions(self, mock_has_auth): gitlab_mock = self.gitlab mock_has_auth.return_value = True connection = gitlab_mock with mock.patch('osf.models.node.AbstractNode.is_registration', new_callable=mock.PropertyMock) as mock_is_reg: mock_is_reg.return_value = True assert_false(check_permissions(self.node_settings, self.consolidated_auth, connection, 'master')) def check_hook_urls(self, urls, node, path, sha): url = node.web_url_for('addon_view_or_download_file', path=path, provider='gitlab') expected_urls = { 'view': '{0}?branch={1}'.format(url, sha), 'download': '{0}?action=download&branch={1}'.format(url, sha) } assert_equal(urls['view'], expected_urls['view']) assert_equal(urls['download'], expected_urls['download']) @mock.patch('addons.gitlab.views.verify_hook_signature') @mock.patch('addons.gitlab.api.GitLabClient.repo') def test_hook_callback_add_file_not_thro_osf(self, mock_repo, mock_verify): gitlab_mock = self.gitlab gitlab_mock.repo = mock_repo url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id) timestamp = str(datetime.datetime.utcnow()) self.app.post_json( url, { 'test': True, 'commits': [{ 'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'distinct': True, 'message': 'foo', 'timestamp': timestamp, 'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'author': {'name': 'Illidan', 'email': '*****@*****.**'}, 'committer': {'name': 'Testor', 'email': '*****@*****.**', 'username': '******'}, 'added': ['PRJWN3TV'], 'removed': [], 'modified': [], }] }, content_type='application/json', ).maybe_follow() self.project.reload() assert_equal(self.project.logs.latest().action, 'gitlab_file_added') urls = self.project.logs.latest().params['urls'] self.check_hook_urls( urls, self.project, path='PRJWN3TV', sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', ) @mock.patch('addons.gitlab.views.verify_hook_signature') def test_hook_callback_modify_file_not_thro_osf(self, mock_verify): url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id) timestamp = str(datetime.datetime.utcnow()) self.app.post_json( url, {'test': True, 'commits': [{'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'distinct': True, 'message': ' foo', 'timestamp': timestamp, 'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'author': {'name': 'Illidan', 'email': '*****@*****.**'}, 'committer': {'name': 'Testor', 'email': '*****@*****.**', 'username': '******'}, 'added': [], 'removed':[], 'modified':['PRJWN3TV']}]}, content_type='application/json').maybe_follow() self.project.reload() assert_equal(self.project.logs.latest().action, 'gitlab_file_updated') urls = self.project.logs.latest().params['urls'] self.check_hook_urls( urls, self.project, path='PRJWN3TV', sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', ) @mock.patch('addons.gitlab.views.verify_hook_signature') def test_hook_callback_remove_file_not_thro_osf(self, mock_verify): url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id) timestamp = str(datetime.datetime.utcnow()) self.app.post_json( url, {'test': True, 'commits': [{'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'distinct': True, 'message': 'foo', 'timestamp': timestamp, 'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'author': {'name': 'Illidan', 'email': '*****@*****.**'}, 'committer': {'name': 'Testor', 'email': '*****@*****.**', 'username': '******'}, 'added': [], 'removed': ['PRJWN3TV'], 'modified':[]}]}, content_type='application/json').maybe_follow() self.project.reload() assert_equal(self.project.logs.latest().action, 'gitlab_file_removed') urls = self.project.logs.latest().params['urls'] assert_equal(urls, {}) @mock.patch('addons.gitlab.views.verify_hook_signature') def test_hook_callback_add_file_thro_osf(self, mock_verify): url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id) self.app.post_json( url, {'test': True, 'commits': [{'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'distinct': True, 'message': 'Added via the Open Science Framework', 'timestamp': '2014-01-08T14:15:51-08:00', 'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'author': {'name': 'Illidan', 'email': '*****@*****.**'}, 'committer': {'name': 'Testor', 'email': '*****@*****.**', 'username': '******'}, 'added': ['PRJWN3TV'], 'removed':[], 'modified':[]}]}, content_type='application/json').maybe_follow() self.project.reload() assert_not_equal(self.project.logs.latest().action, 'gitlab_file_added') @mock.patch('addons.gitlab.views.verify_hook_signature') def test_hook_callback_modify_file_thro_osf(self, mock_verify): url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id) self.app.post_json( url, {'test': True, 'commits': [{'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'distinct': True, 'message': 'Updated via the Open Science Framework', 'timestamp': '2014-01-08T14:15:51-08:00', 'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'author': {'name': 'Illidan', 'email': '*****@*****.**'}, 'committer': {'name': 'Testor', 'email': '*****@*****.**', 'username': '******'}, 'added': [], 'removed':[], 'modified':['PRJWN3TV']}]}, content_type='application/json').maybe_follow() self.project.reload() assert_not_equal(self.project.logs.latest().action, 'gitlab_file_updated') @mock.patch('addons.gitlab.views.verify_hook_signature') def test_hook_callback_remove_file_thro_osf(self, mock_verify): url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id) self.app.post_json( url, {'test': True, 'commits': [{'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'distinct': True, 'message': 'Deleted via the Open Science Framework', 'timestamp': '2014-01-08T14:15:51-08:00', 'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', 'author': {'name': 'Illidan', 'email': '*****@*****.**'}, 'committer': {'name': 'Testor', 'email': '*****@*****.**', 'username': '******'}, 'added': [], 'removed':['PRJWN3TV'], 'modified':[]}]}, content_type='application/json').maybe_follow() self.project.reload() assert_not_equal(self.project.logs.latest().action, 'gitlab_file_removed')
class TestCreateBucket(S3AddonTestCase, OsfTestCase): def setUp(self): super(TestCreateBucket, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.auth = self.user.auth self.project = ProjectFactory(creator=self.user) self.project.add_addon('s3', auth=self.consolidated_auth) self.project.creator.add_addon('s3') self.user_settings = self.user.get_addon('s3') self.user_settings.access_key = 'We-Will-Rock-You' self.user_settings.secret_key = 'Idontknowanyqueensongs' self.user_settings.save() self.node_settings = self.project.get_addon('s3') self.node_settings.bucket = 'Sheer-Heart-Attack' self.node_settings.user_settings = self.project.creator.get_addon('s3') self.node_settings.save() def test_bad_names(self): assert_false(validate_bucket_name('')) assert_false(validate_bucket_name('no')) assert_false(validate_bucket_name('a' * 64)) assert_false(validate_bucket_name(' leadingspace')) assert_false(validate_bucket_name('trailingspace ')) assert_false(validate_bucket_name('bogus naMe')) assert_false(validate_bucket_name('.cantstartwithp')) assert_false(validate_bucket_name('or.endwith.')) assert_false(validate_bucket_name('..nodoubles')) assert_false(validate_bucket_name('no_unders_in')) assert_false(validate_bucket_name('-leadinghyphen')) assert_false(validate_bucket_name('trailinghyphen-')) assert_false(validate_bucket_name('Mixedcase')) assert_false(validate_bucket_name('empty..label')) assert_false(validate_bucket_name('label-.trailinghyphen')) assert_false(validate_bucket_name('label.-leadinghyphen')) assert_false(validate_bucket_name('8.8.8.8')) assert_false(validate_bucket_name('600.9000.0.28')) assert_false(validate_bucket_name('no_underscore')) assert_false(validate_bucket_name('_nounderscoreinfront')) assert_false(validate_bucket_name('no-underscore-in-back_')) assert_false(validate_bucket_name('no-underscore-in_the_middle_either')) def test_names(self): assert_true(validate_bucket_name('imagoodname')) assert_true(validate_bucket_name('still.passing')) assert_true(validate_bucket_name('can-have-dashes')) assert_true(validate_bucket_name('kinda.name.spaced')) assert_true(validate_bucket_name('a-o.valid')) assert_true(validate_bucket_name('11.12.m')) assert_true(validate_bucket_name('a--------a')) assert_true(validate_bucket_name('a' * 63)) def test_bad_locations(self): assert_false(validate_bucket_location('Venus')) assert_false(validate_bucket_location('AlphaCentari')) assert_false(validate_bucket_location('CostaRica')) def test_locations(self): assert_true(validate_bucket_location('')) assert_true(validate_bucket_location('eu-central-1')) assert_true(validate_bucket_location('ca-central-1')) assert_true(validate_bucket_location('us-west-1')) assert_true(validate_bucket_location('us-west-2')) assert_true(validate_bucket_location('ap-northeast-1')) assert_true(validate_bucket_location('ap-northeast-2')) assert_true(validate_bucket_location('ap-southeast-1')) assert_true(validate_bucket_location('ap-southeast-2')) assert_true(validate_bucket_location('sa-east-1')) assert_true(validate_bucket_location('eu-west-1')) assert_true(validate_bucket_location('eu-west-2')) @mock.patch('addons.s3.views.utils.create_bucket') @mock.patch('addons.s3.views.utils.get_bucket_names') def test_create_bucket_pass(self, mock_names, mock_make): mock_make.return_value = True mock_names.return_value = [ 'butintheend', 'it', 'doesntevenmatter' ] url = self.project.api_url_for('create_bucket') ret = self.app.post_json( url, { 'bucket_name': 'doesntevenmatter', 'bucket_location': '', }, auth=self.user.auth ) assert_equal(ret.status_int, http.OK) assert_equal(ret.json, {}) @mock.patch('addons.s3.views.utils.create_bucket') def test_create_bucket_fail(self, mock_make): error = S3ResponseError(418, 'because Im a test') error.message = 'This should work' mock_make.side_effect = error url = '/api/v1/project/{0}/s3/newbucket/'.format(self.project._id) ret = self.app.post_json(url, {'bucket_name': 'doesntevenmatter'}, auth=self.user.auth, expect_errors=True) assert_equals(ret.body, '{"message": "This should work", "title": "Problem connecting to S3"}') @mock.patch('addons.s3.views.utils.create_bucket') def test_bad_location_fails(self, mock_make): url = '/api/v1/project/{0}/s3/newbucket/'.format(self.project._id) ret = self.app.post_json( url, { 'bucket_name': 'doesntevenmatter', 'bucket_location': 'not a real bucket location', }, auth=self.user.auth, expect_errors=True) assert_equals(ret.body, '{"message": "That bucket location is not valid.", "title": "Invalid bucket location"}')
class TestCallbacks(OsfTestCase): def setUp(self): super(TestCallbacks, self).setUp() self.project = ProjectFactory() self.consolidated_auth = Auth(self.project.creator) self.project.creator.save() self.non_authenticator = UserFactory() self.non_authenticator.save() self.project.save() self.project.add_contributor( contributor=self.non_authenticator, auth=self.consolidated_auth, ) self.project.add_addon('github', auth=self.consolidated_auth) self.project.creator.add_addon('github') self.external_account = factories.GitHubAccountFactory() self.project.creator.external_accounts.add(self.external_account) self.project.creator.save() self.node_settings = self.project.get_addon('github') self.user_settings = self.project.creator.get_addon('github') self.node_settings.user_settings = self.user_settings self.node_settings.user = '******' self.node_settings.repo = 'Sheer-Heart-Attack' self.node_settings.external_account = self.external_account self.node_settings.save() self.node_settings.set_auth self.user_settings.oauth_grants[self.project._id] = {self.external_account._id: []} self.user_settings.save() @mock.patch('addons.github.api.GitHubClient.repo') def test_before_make_public(self, mock_repo): mock_repo.side_effect = NotFoundError result = self.node_settings.before_make_public(self.project) assert_is(result, None) @mock.patch('addons.github.api.GitHubClient.repo') def test_before_page_load_osf_public_gh_public(self, mock_repo): self.project.is_public = True self.project.save() mock_repo.return_value = Repository.from_json({'private': False}) message = self.node_settings.before_page_load(self.project, self.project.creator) mock_repo.assert_called_with( self.node_settings.user, self.node_settings.repo, ) assert_false(message) @mock.patch('addons.github.api.GitHubClient.repo') def test_before_page_load_osf_public_gh_private(self, mock_repo): self.project.is_public = True self.project.save() mock_repo.return_value = Repository.from_json({'private': True}) message = self.node_settings.before_page_load(self.project, self.project.creator) mock_repo.assert_called_with( self.node_settings.user, self.node_settings.repo, ) assert_true(message) @mock.patch('addons.github.api.GitHubClient.repo') def test_before_page_load_osf_private_gh_public(self, mock_repo): mock_repo.return_value = Repository.from_json({'private': False}) message = self.node_settings.before_page_load(self.project, self.project.creator) mock_repo.assert_called_with( self.node_settings.user, self.node_settings.repo, ) assert_true(message) @mock.patch('addons.github.api.GitHubClient.repo') def test_before_page_load_osf_private_gh_private(self, mock_repo): mock_repo.return_value = Repository.from_json({'private': True}) message = self.node_settings.before_page_load(self.project, self.project.creator) mock_repo.assert_called_with( self.node_settings.user, self.node_settings.repo, ) assert_false(message) def test_before_page_load_not_contributor(self): message = self.node_settings.before_page_load(self.project, UserFactory()) assert_false(message) def test_before_page_load_not_logged_in(self): message = self.node_settings.before_page_load(self.project, None) assert_false(message) def test_before_remove_contributor_authenticator(self): message = self.node_settings.before_remove_contributor( self.project, self.project.creator ) assert_true(message) def test_before_remove_contributor_not_authenticator(self): message = self.node_settings.before_remove_contributor( self.project, self.non_authenticator ) assert_false(message) def test_after_remove_contributor_authenticator_self(self): message = self.node_settings.after_remove_contributor( self.project, self.project.creator, self.consolidated_auth ) assert_equal( self.node_settings.user_settings, None ) assert_true(message) assert_not_in('You can re-authenticate', message) def test_after_remove_contributor_authenticator_not_self(self): auth = Auth(user=self.non_authenticator) message = self.node_settings.after_remove_contributor( self.project, self.project.creator, auth ) assert_equal( self.node_settings.user_settings, None ) assert_true(message) assert_in('You can re-authenticate', message) def test_after_remove_contributor_not_authenticator(self): self.node_settings.after_remove_contributor( self.project, self.non_authenticator, self.consolidated_auth ) assert_not_equal( self.node_settings.user_settings, None, ) def test_after_fork_authenticator(self): fork = ProjectFactory() clone = self.node_settings.after_fork( self.project, fork, self.project.creator, ) assert_equal( self.node_settings.user_settings, clone.user_settings, ) def test_after_fork_not_authenticator(self): fork = ProjectFactory() clone = self.node_settings.after_fork( self.project, fork, self.non_authenticator, ) assert_equal( clone.user_settings, None, ) def test_after_delete(self): self.project.remove_node(Auth(user=self.project.creator)) # Ensure that changes to node settings have been saved self.node_settings.reload() assert_true(self.node_settings.user_settings is None) @mock.patch('website.archiver.tasks.archive') def test_does_not_get_copied_to_registrations(self, mock_archive): registration = self.project.register_node( schema=get_default_metaschema(), auth=Auth(user=self.project.creator), data='hodor', ) assert_false(registration.has_addon('github'))
class TestAddonLogs(OsfTestCase): def setUp(self): super(TestAddonLogs, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = GitHubAccountFactory(display_name='john') self.oauth_settings.save() self.user.external_accounts.add(self.oauth_settings) self.user.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() self.user_addon.oauth_grants[self.node._id] = {self.oauth_settings._id: []} self.user_addon.save() def configure_osf_addon(self): self.project = ProjectFactory(creator=self.user) self.node_addon = self.project.get_addon('osfstorage') self.node_addon.save() def build_payload(self, metadata, **kwargs): options = dict( auth={'id': self.user._id}, action='create', provider=self.node_addon.config.short_name, metadata=metadata, time=time.time() + 1000, ) options.update(kwargs) options = { key: value for key, value in options.iteritems() if value is not None } message, signature = signing.default_signer.sign_payload(options) return { 'payload': message, 'signature': signature, } @mock.patch('website.notifications.events.files.FileAdded.perform') @mock.patch('requests.get',{'code': 404, 'referrer': None,'message_short': 'Page not found'}) def test_add_log_timestamptoken(self, mock_perform): from osf.models import RdmFileTimestamptokenVerifyResult, NodeLog from api_tests.utils import create_test_file from website.views import userkey_generation result_list1_count = RdmFileTimestamptokenVerifyResult.objects.filter(project_id=self.node._id).count() nodelog_count1 = NodeLog.objects.all().count() path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') userkey_generation(self.user._id) file_node = create_test_file(node=self.node, user=self.user, filename=path) file_node._path = '/' + path file_node.save() metadata = { 'path': path, 'provider': 'osfstorage', 'name': path, 'materialized': '/' + path, 'extra': { 'version': 1 } } payload = self.build_payload(metadata=metadata) logging.info('---test_add_log_timestamptoken.payload: {}'.format(payload)) nlogs = self.node.logs.count() self.app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal(self.node.logs.count(), nlogs + 1) nodelog_count2 = NodeLog.objects.all().count() assert_equal(nodelog_count1 + 1, nodelog_count2) result_list2 = RdmFileTimestamptokenVerifyResult.objects.filter(project_id=self.node._id) assert_true(mock_perform.called, 'perform not called') ## tearDown import os from api.base import settings as api_settings from osf.models import RdmUserKey rdmuserkey_pvt_key = RdmUserKey.objects.get(guid=self.user.id, key_kind=api_settings.PRIVATE_KEY_VALUE) pvt_key_path = os.path.join(api_settings.KEY_SAVE_PATH, rdmuserkey_pvt_key.key_name) os.remove(pvt_key_path) rdmuserkey_pvt_key.delete() rdmuserkey_pub_key = RdmUserKey.objects.get(guid=self.user.id, key_kind=api_settings.PUBLIC_KEY_VALUE) pub_key_path = os.path.join(api_settings.KEY_SAVE_PATH, rdmuserkey_pub_key.key_name) os.remove(pub_key_path) rdmuserkey_pub_key.delete() @mock.patch('website.notifications.events.files.FileAdded.perform') def test_add_log(self, mock_perform): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = self.node.logs.count() self.app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal(self.node.logs.count(), nlogs + 1) # # Mocking form_message and perform so that the payload need not be exact. # assert_true(mock_form_message.called, "form_message not called") assert_true(mock_perform.called, 'perform not called') def test_add_log_missing_args(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth=None) nlogs = self.node.logs.count() res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(self.node.logs.count(), nlogs) def test_add_log_no_user(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth={'id': None}) nlogs = self.node.logs.count() res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(self.node.logs.count(), nlogs) def test_add_log_no_addon(self): path = 'pizza' node = ProjectFactory(creator=self.user) url = node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = node.logs.count() res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(node.logs.count(), nlogs) def test_add_log_bad_action(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, action='dance') nlogs = self.node.logs.count() res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(self.node.logs.count(), nlogs) def test_action_file_rename(self): url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload( action='rename', metadata={ 'path': 'foo', }, source={ 'materialized': 'foo', 'provider': 'github', 'node': {'_id': self.node._id}, 'name': 'new.txt', 'kind': 'file', }, destination={ 'path': 'foo', 'materialized': 'foo', 'provider': 'github', 'node': {'_id': self.node._id}, 'name': 'old.txt', 'kind': 'file', }, ) self.app.put_json( url, payload, headers={'Content-Type': 'application/json'} ) self.node.reload() assert_equal( self.node.logs.latest().action, 'github_addon_file_renamed', ) def test_action_downloads(self): url = self.node.api_url_for('create_waterbutler_log') download_actions=('download_file', 'download_zip') for action in download_actions: payload = self.build_payload(metadata={'path': 'foo'}, action=action) nlogs = self.node.logs.count() res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=False, ) assert_equal(res.status_code, 200) self.node.reload() assert_equal(self.node.logs.count(), nlogs) def test_add_file_osfstorage_log(self): self.configure_osf_addon() path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'materialized': path, 'kind': 'file', 'path': path}) nlogs = self.node.logs.count() self.app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal(self.node.logs.count(), nlogs + 1) assert('urls' in self.node.logs.filter(action='osf_storage_file_added')[0].params) def test_add_folder_osfstorage_log(self): self.configure_osf_addon() path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'materialized': path, 'kind': 'folder', 'path': path}) nlogs = self.node.logs.count() self.app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal(self.node.logs.count(), nlogs + 1) assert('urls' not in self.node.logs.filter(action='osf_storage_file_added')[0].params)
class TestAddonLogs(OsfTestCase): def setUp(self): super(TestAddonLogs, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = GitHubAccountFactory(display_name='john') self.oauth_settings.save() self.user.external_accounts.add(self.oauth_settings) self.user.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() self.user_addon.oauth_grants[self.node._id] = {self.oauth_settings._id: []} self.user_addon.save() def build_payload(self, metadata, **kwargs): options = dict( auth={'id': self.user._id}, action='create', provider=self.node_addon.config.short_name, metadata=metadata, time=time.time() + 1000, ) options.update(kwargs) options = { key: value for key, value in options.iteritems() if value is not None } message, signature = signing.default_signer.sign_payload(options) return { 'payload': message, 'signature': signature, } @mock.patch('website.notifications.events.files.FileAdded.perform') def test_add_log(self, mock_perform): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = self.node.logs.count() self.app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal(self.node.logs.count(), nlogs + 1) # # Mocking form_message and perform so that the payload need not be exact. # assert_true(mock_form_message.called, "form_message not called") assert_true(mock_perform.called, 'perform not called') def test_add_log_missing_args(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth=None) nlogs = self.node.logs.count() res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(self.node.logs.count(), nlogs) def test_add_log_no_user(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth={'id': None}) nlogs = self.node.logs.count() res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(self.node.logs.count(), nlogs) def test_add_log_no_addon(self): path = 'pizza' node = ProjectFactory(creator=self.user) url = node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = node.logs.count() res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(node.logs.count(), nlogs) def test_add_log_bad_action(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, action='dance') nlogs = self.node.logs.count() res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(self.node.logs.count(), nlogs) def test_action_file_rename(self): url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload( action='rename', metadata={ 'path': 'foo', }, source={ 'materialized': 'foo', 'provider': 'github', 'node': {'_id': self.node._id}, 'name': 'new.txt', 'kind': 'file', }, destination={ 'path': 'foo', 'materialized': 'foo', 'provider': 'github', 'node': {'_id': self.node._id}, 'name': 'old.txt', 'kind': 'file', }, ) self.app.put_json( url, payload, headers={'Content-Type': 'application/json'} ) self.node.reload() assert_equal( self.node.logs.latest().action, 'github_addon_file_renamed', )
class TestAddonFileViews(OsfTestCase): def setUp(self): super(TestAddonFileViews, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.user.add_addon('github') self.project.add_addon('github', auth=Auth(self.user)) self.user_addon = self.user.get_addon('github') self.node_addon = self.project.get_addon('github') self.oauth = GitHubAccountFactory() self.oauth.save() self.user.external_accounts.add(self.oauth) self.user.save() self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth self.node_addon.repo = 'Truth' self.node_addon.user = '******' self.node_addon.save() self.user_addon.oauth_grants[self.project._id] = {self.oauth._id: []} self.user_addon.save() def set_sentry(status): def wrapper(func): @functools.wraps(func) def wrapped(*args, **kwargs): enabled, sentry.enabled = sentry.enabled, status func(*args, **kwargs) sentry.enabled = enabled return wrapped return wrapper with_sentry = set_sentry(True) def get_test_file(self): version = file_models.FileVersion(identifier='1') version.save() ret = GithubFile( name='Test', node=self.project, path='/test/Test', materialized_path='/test/Test', ) ret.save() ret.versions.add(version) return ret def get_second_test_file(self): version = file_models.FileVersion(identifier='1') version.save() ret = GithubFile( name='Test2', node=self.project, path='/test/Test2', materialized_path='/test/Test2', ) ret.save() ret.versions.add(version) return ret def get_mako_return(self): ret = serialize_node(self.project, Auth(self.user), primary=True) ret.update({ 'error': '', 'provider': '', 'file_path': '', 'sharejs_uuid': '', 'private': '', 'urls': { 'files': '', 'render': '', 'sharejs': '', 'mfr': '', 'profile_image': '', 'external': '', 'archived_from': '', }, 'size': '', 'extra': '', 'file_name': '', 'materialized_path': '', 'file_id': '', }) ret.update(rubeus.collect_addon_assets(self.project)) return ret def test_redirects_to_guid(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github' ), auth=self.user.auth ) assert_equals(resp.status_code, 302) assert_equals(resp.location, 'http://*****:*****@mock.patch('addons.base.views.addon_view_file') def test_action_view_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/?action=view'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) @mock.patch('addons.base.views.addon_view_file') def test_no_action_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) def test_download_create_guid(self): file_node = self.get_test_file() assert_is(file_node.get_guid(), None) self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github', ), auth=self.user.auth ) assert_true(file_node.get_guid()) def test_view_file_does_not_delete_file_when_requesting_invalid_version(self): with mock.patch('addons.github.models.NodeSettings.is_private', new_callable=mock.PropertyMock) as mock_is_private: mock_is_private.return_value = False file_node = self.get_test_file() assert_is(file_node.get_guid(), None) url = self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github', ) # First view generated GUID self.app.get(url, auth=self.user.auth) self.app.get(url + '?version=invalid', auth=self.user.auth, expect_errors=True) assert_is_not_none(BaseFileNode.load(file_node._id)) assert_is_none(TrashedFileNode.load(file_node._id)) def test_unauthorized_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 401) def test_nonstorage_addons_raise(self): resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path='sillywiki', provider='wiki', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 400) def test_head_returns_url_and_redriect(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) assert_equals(resp.status_code, 302) assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, version='')) def test_head_returns_url_with_version_and_redirect(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/?revision=1&foo=bar'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) # Note: version is added but us but all other url params are added as well assert_equals(resp.status_code, 302) assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version='', foo='bar')) def test_nonexistent_addons_raise(self): path = 'cloudfiles' self.project.delete_addon('github', Auth(self.user)) self.project.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 400) def test_unauth_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 401) def test_delete_action_creates_trashed_file_node(self): file_node = self.get_test_file() payload = { 'provider': file_node.provider, 'metadata': { 'path': '/test/Test', 'materialized': '/test/Test' } } views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload) assert_false(GithubFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) def test_delete_action_for_folder_deletes_subfolders_and_creates_trashed_file_nodes(self): file_node = self.get_test_file() subfolder = GithubFolder( name='folder', node=self.project, path='/test/folder/', materialized_path='/test/folder/', ) subfolder.save() payload = { 'provider': file_node.provider, 'metadata': { 'path': '/test/', 'materialized': '/test/' } } views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload) assert_false(GithubFileNode.load(subfolder._id)) assert_true(TrashedFileNode.load(file_node._id)) @mock.patch('website.archiver.tasks.archive') def test_archived_from_url(self, mock_archive): file_node = self.get_test_file() second_file_node = self.get_second_test_file() file_node.copied_from = second_file_node registered_node = self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) archived_from_url = views.get_archived_from_url(registered_node, file_node) view_url = self.project.web_url_for('addon_view_or_download_file', provider=file_node.provider, path=file_node.copied_from._id) assert_true(archived_from_url) assert_urls_equal(archived_from_url, view_url) @mock.patch('website.archiver.tasks.archive') def test_archived_from_url_without_copied_from(self, mock_archive): file_node = self.get_test_file() registered_node = self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) archived_from_url = views.get_archived_from_url(registered_node, file_node) assert_false(archived_from_url) @mock.patch('website.archiver.tasks.archive') def test_copied_from_id_trashed(self, mock_archive): file_node = self.get_test_file() second_file_node = self.get_second_test_file() file_node.copied_from = second_file_node self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) trashed_node = second_file_node.delete() assert_false(trashed_node.copied_from) @mock.patch('website.archiver.tasks.archive') def test_missing_modified_date_in_file_data(self, mock_archive): file_node = self.get_test_file() file_data = { 'name': 'Test File Update', 'materialized': file_node.materialized_path, 'modified': None } file_node.update(revision=None, data=file_data) assert_equal(len(file_node.history), 1) assert_equal(file_node.history[0], file_data) @mock.patch('website.archiver.tasks.archive') def test_missing_modified_date_in_file_history(self, mock_archive): file_node = self.get_test_file() file_node.history.append({'modified': None}) file_data = { 'name': 'Test File Update', 'materialized': file_node.materialized_path, 'modified': None } file_node.update(revision=None, data=file_data) assert_equal(len(file_node.history), 2) assert_equal(file_node.history[1], file_data) @with_sentry @mock.patch('framework.sentry.sentry.captureMessage') def test_update_logs_to_sentry_when_called_with_disordered_metadata(self, mock_capture): file_node = self.get_test_file() file_node.history.append({'modified': parse_date( '2017-08-22T13:54:32.100900', ignoretz=True, default=timezone.now() # Just incase nothing can be parsed )}) data = { 'name': 'a name', 'materialized': 'materialized', 'modified': '2016-08-22T13:54:32.100900' } file_node.update(revision=None, user=None, data=data) mock_capture.assert_called_with(unicode('update() receives metatdata older than the newest entry in file history.'), extra={'session': {}})
class TestAddonCount(OsfTestCase): def setUp(self): super(TestAddonCount, self).setUp() self.user = AuthUserFactory() self.node = ProjectFactory(creator=self.user) self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.external_account = GitHubAccountFactory(display_name='hmoco1') self.user_settings = self.user.get_or_add_addon('github') self.user_settings.save() self.user.external_accounts.add(self.external_account) self.user.save() self.node.add_addon('github', Auth(self.user)) self.node_addon = self.node.get_addon('github') self.node_addon.user = self.user.fullname self.node_addon.repo = '29 #Strafford APTS' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.external_account self.node_addon.save() self.user_settings.grant_oauth_access( node=self.node, external_account=self.external_account, ) def test_run_for_all_addon(self): results = AddonSnapshot().get_events() names = [res['provider']['name'] for res in results] for addon in ADDONS_AVAILABLE: assert_in(addon.short_name, names) def test_one_user_one_node_one_addon(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['users']['enabled'], 1) assert_equal(github_res['nodes']['total'], 1) def test_one_user_one_node_one_addon_one_node_linked(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['users']['enabled'], 1) assert_equal(github_res['nodes']['total'], 1) def test_one_user_with_multiple_githubs(self): oauth_settings2 = GitHubAccountFactory(display_name='hmoco2') oauth_settings2.save() self.user.external_accounts.add(oauth_settings2) self.user.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['users']['enabled'], 1) def test_one_user_with_multiple_addons(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] googledrive_res = [ res for res in results if res['provider']['name'] == 'googledrive' ][0] assert_equal(github_res['users']['enabled'], 1) assert_equal(googledrive_res['users']['enabled'], 0) self.user.add_addon('googledrive') oauth_settings = GoogleDriveAccountFactory() oauth_settings.save() self.user.external_accounts.add(oauth_settings) self.user.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] googledrive_res = [ res for res in results if res['provider']['name'] == 'googledrive' ][0] assert_equal(github_res['users']['enabled'], 1) assert_equal(googledrive_res['users']['enabled'], 1) def test_many_users_each_with_a_different_github(self): user = AuthUserFactory() user.add_addon('github') oauth_settings2 = GitHubAccountFactory(display_name='hmoco2') oauth_settings2.save() user.external_accounts.add(oauth_settings2) user.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['users']['enabled'], 2) assert_equal(github_res['users']['authorized'], 1) assert_equal(github_res['users']['linked'], 1) def test_many_users_each_with_the_same_github_enabled(self): user = AuthUserFactory() user.add_addon('github') user.external_accounts.add(self.external_account) user.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['users']['enabled'], 2) def test_github_enabled_not_linked_or_authorized(self): user = AuthUserFactory() user.add_addon('github') user.external_accounts.add(self.external_account) user.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['users']['enabled'], 2) assert_equal(github_res['users']['authorized'], 1) assert_equal(github_res['users']['linked'], 1) def test_one_node_with_multiple_addons(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] googledrive_res = [ res for res in results if res['provider']['name'] == 'googledrive' ][0] assert_equal(github_res['nodes']['total'], 1) assert_equal(googledrive_res['nodes']['total'], 0) self.user.add_addon('googledrive') user_addon = self.user.get_addon('googledrive') oauth_settings = GoogleDriveAccountFactory() oauth_settings.save() self.user.external_accounts.add(oauth_settings) self.user.save() self.node.add_addon('googledrive', Auth(self.user)) node_addon = self.node.get_addon('googledrive') node_addon.user = self.user.fullname node_addon.user_settings = user_addon node_addon.external_account = oauth_settings node_addon.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] googledrive_res = [ res for res in results if res['provider']['name'] == 'googledrive' ][0] assert_equal(github_res['nodes']['total'], 1) assert_equal(googledrive_res['nodes']['total'], 1) def test_many_nodes_with_one_addon(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['total'], 1) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.user = self.user.fullname node_addon.repo = '8 (circle)' node_addon.user_settings = self.user_addon node_addon.external_account = self.external_account node_addon.save() node.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['total'], 2) def test_node_count_deleted_addon(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['deleted'], 0) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.delete() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['deleted'], 1) def test_node_count_disconected_addon(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['disconnected'], 0) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.external_account = None node_addon.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['disconnected'], 1) def test_all_users_have_wiki_osfstorage_enabled(self): all_user_count = OSFUser.objects.all().count() results = AddonSnapshot().get_events() osfstorage_res = [ res for res in results if res['provider']['name'] == 'osfstorage' ][0] wiki_res = [ res for res in results if res['provider']['name'] == 'osfstorage' ][0] assert_equal(osfstorage_res['users']['enabled'], all_user_count) assert_equal(wiki_res['users']['enabled'], all_user_count) def test_wiki_deleted_shows_as_deleted(self): node = ProjectFactory(creator=self.user) node.delete_addon('wiki', auth=Auth(self.user)) results = AddonSnapshot().get_events() wiki_res = [ res for res in results if res['provider']['name'] == 'wiki' ][0] assert_equal(wiki_res['nodes']['deleted'], 1) def test_node_settings_has_no_owner_not_connected(self): self.node_addon.owner = None self.node_addon.save() results = AddonSnapshot().get_events() storage_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(storage_res['nodes']['connected'], 0)