def test_revoke_didnt_award(self): badgeid = self.user_settings.badges[0]._id initnum = len(self.project.badgeassertion__awarded) assert_true(self.user_settings.can_award) url = api_url_for('award_badge', pid=self.project._id) ret = self.app.post_json(url, {'badgeid': badgeid}, auth=self.user.auth) self.project.reload() assert_equals(ret.status_int, 200) assert_equals(initnum + 1, len(self.project.badgeassertion__awarded)) assertion = self.project.badgeassertion__awarded[0] revoke = api_url_for('revoke_badge', pid=self.project._id) user2 = AuthUserFactory() user2.add_addon('badges', override=True) user2.save() user2.reload() ret = self.app.post_json(revoke, { 'id': assertion._id, 'reason': '' }, auth=user2.auth, expect_errors=True) self.project.reload() self.user_settings.reload() assertion.reload() assert_equals(ret.status_int, 400) assert_false(assertion.revoked) assert_true(self.project.badgeassertion__awarded[0]._id, assertion._id) assert_false(assertion._id in self.user_settings.revocation_list)
def test_confirm_non_contrib_viewers_dont_have_pid_in_comments_view_timestamp(self): non_contributor = AuthUserFactory() url = self.project.api_url_for("update_comments_timestamp") res = self.app.put_json(url, {"page": "node", "rootId": self.project._id}, auth=self.user.auth) non_contributor.reload() assert_not_in(self.project._id, non_contributor.comments_viewed_timestamp)
def test_user_settings_when_user_does_not_have_addon(self, _): user = AuthUserFactory() url = self.project.api_url_for("s3_post_user_settings") self.app.post_json(url, {"access_key": "ABCDEFG", "secret_key": "We are the champions"}, auth=user.auth) user.reload() user_settings = user.get_addon("s3") assert_equals(user_settings.access_key, "ABCDEFG") assert_equals(user_settings.secret_key, "We are the champions")
class TestCommentViews(OsfTestCase): def setUp(self): super(TestCommentViews, self).setUp() self.project = ProjectFactory(is_public=True) self.user = AuthUserFactory() self.project.add_contributor(self.user) self.project.save() self.user.save() def test_view_project_comments_updates_user_comments_view_timestamp(self): url = self.project.api_url_for('update_comments_timestamp') res = self.app.put_json(url, { 'page': 'node', 'rootId': self.project._id }, auth=self.user.auth) self.user.reload() user_timestamp = self.user.comments_viewed_timestamp[self.project._id]['node'] view_timestamp = dt.datetime.utcnow() assert_datetime_equal(user_timestamp, view_timestamp) def test_confirm_non_contrib_viewers_dont_have_pid_in_comments_view_timestamp(self): non_contributor = AuthUserFactory() url = self.project.api_url_for('update_comments_timestamp') res = self.app.put_json(url, { 'page': 'node', 'rootId': self.project._id }, auth=self.user.auth) non_contributor.reload() assert_not_in(self.project._id, non_contributor.comments_viewed_timestamp) def test_view_comments_updates_user_comments_view_timestamp_files(self): osfstorage = self.project.get_addon('osfstorage') root_node = osfstorage.get_root() test_file = root_node.append_file('test_file') test_file.create_version(self.user, { 'object': '06d80e', 'service': 'cloud', osfstorage_settings.WATERBUTLER_RESOURCE: 'osf', }, { 'size': 1337, 'contentType': 'img/png' }).save() url = self.project.api_url_for('update_comments_timestamp') res = self.app.put_json(url, { 'page': 'files', 'rootId': test_file._id }, auth=self.user.auth) self.user.reload() user_timestamp = self.user.comments_viewed_timestamp[self.project._id]['files'][test_file._id] view_timestamp = dt.datetime.utcnow() assert_datetime_equal(user_timestamp, view_timestamp)
class TestCommentViews(OsfTestCase): def setUp(self): super(TestCommentViews, self).setUp() self.project = ProjectFactory(is_public=True) self.user = AuthUserFactory() self.project.add_contributor(self.user) self.project.save() self.user.save() def test_view_project_comments_updates_user_comments_view_timestamp(self): url = self.project.api_url_for('update_comments_timestamp') res = self.app.put_json(url, { 'page': 'node', 'rootId': self.project._id }, auth=self.user.auth) self.user.reload() user_timestamp = self.user.comments_viewed_timestamp[self.project._id] view_timestamp = dt.datetime.utcnow() assert_datetime_equal(user_timestamp, view_timestamp) def test_confirm_non_contrib_viewers_dont_have_pid_in_comments_view_timestamp(self): non_contributor = AuthUserFactory() url = self.project.api_url_for('update_comments_timestamp') res = self.app.put_json(url, { 'page': 'node', 'rootId': self.project._id }, auth=self.user.auth) non_contributor.reload() assert_not_in(self.project._id, non_contributor.comments_viewed_timestamp) def test_view_comments_updates_user_comments_view_timestamp_files(self): osfstorage = self.project.get_addon('osfstorage') root_node = osfstorage.get_root() test_file = root_node.append_file('test_file') test_file.create_version(self.user, { 'object': '06d80e', 'service': 'cloud', osfstorage_settings.WATERBUTLER_RESOURCE: 'osf', }, { 'size': 1337, 'contentType': 'img/png' }).save() url = self.project.api_url_for('update_comments_timestamp') res = self.app.put_json(url, { 'page': 'files', 'rootId': test_file._id }, auth=self.user.auth) self.user.reload() user_timestamp = self.user.comments_viewed_timestamp[test_file._id] view_timestamp = dt.datetime.utcnow() assert_datetime_equal(user_timestamp, view_timestamp)
def test_confirm_non_contrib_viewers_dont_have_pid_in_comments_view_timestamp(self): non_contributor = AuthUserFactory() url = self.project.api_url_for('update_comments_timestamp') res = self.app.put_json(url, { 'page': 'node', 'rootId': self.project._id }, auth=self.user.auth) non_contributor.reload() assert_not_in(self.project._id, non_contributor.comments_viewed_timestamp)
def test_user_settings_when_user_does_not_have_addon(self, _): user = AuthUserFactory() url = self.project.api_url_for('s3_post_user_settings') self.app.post_json(url, { 'access_key': 'ABCDEFG', 'secret_key': 'We are the champions' }, auth=user.auth) user.reload() user_settings = user.get_addon('s3') assert_equals(user_settings.access_key, 'ABCDEFG') assert_equals(user_settings.secret_key, 'We are the champions')
def test_user_settings_when_user_does_not_have_addon(self, _): user = AuthUserFactory() url = self.project.api_url_for('s3_post_user_settings') self.app.post_json( url, { 'access_key': 'ABCDEFG', 'secret_key': 'We are the champions' }, auth=user.auth ) user.reload() user_settings = user.get_addon('s3') assert_equals(user_settings.access_key, 'ABCDEFG') assert_equals(user_settings.secret_key, 'We are the champions')
def test_merged_user(self): user = AuthUserFactory(fullname='Annie Lennox') merged_user = AuthUserFactory(fullname='Lisa Stansfield') user.save() merged_user.save() user.merge_user(merged_user) user.save() merged_user.save() user.reload() merged_user.reload() modify_user_dates_in_mongo(self.yesterday) data = UserSummary().get_events(self.yesterday.date())[0] assert_equal(data['status']['merged'], 1)
class TestRmapUserViews(OsfTestCase): def setUp(self): super(TestRmapUserViews, self).setUp() self.user = AuthUserFactory() self.url = api_url_for('user_rmap_post') self._old_rmap_url = settings.RMAP_BASE_URL self._old_rmap_pass = settings.RMAP_PASS settings.RMAP_BASE_URL = 'rmaptest.test/' settings.RMAP_PASS = '******' self._set_up_mock_response_for_user(self.user) def _set_up_mock_response_for_user(self, user): rmap_url = _rmap_url_for_user(user) httpretty.register_uri(httpretty.POST, rmap_url, body='abc123', status=200) def tearDown(self): super(TestRmapUserViews, self).tearDown() settings.RMAP_BASE_URL = self._old_rmap_url settings.RMAP_PASS = self._old_rmap_pass def test_rmap_get_valid_no_disco_id(self): res = self.app.get(self.url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.json['disco_id'], None) def test_rmap_get_valid_with_disco_id(self): disco_id = 'pan1cath3d1sc0' self.user.set_identifier_value('disco', disco_id) res = self.app.get(self.url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.json['disco_id'], disco_id) def test_rmap_post_valid(self): res = self.app.post_json(self.url, {}, auth=self.user.auth) assert_equal(res.status_code, 201) self.user.reload() rmap_id = self.user.get_identifier('disco') assert_true(bool(rmap_id)) assert_equal(rmap_id.value, 'abc123')
def test_find_unread_includes_edited_comments(self): project = ProjectFactory() user = AuthUserFactory() project.add_contributor(user) project.save() comment = CommentFactory(node=project, user=project.creator) url = project.api_url_for("update_comments_timestamp") payload = {"page": "node", "rootId": project._id} res = self.app.put_json(url, payload, auth=user.auth) user.reload() n_unread = Comment.find_n_unread(user=user, node=project, page="node") assert_equal(n_unread, 0) # Edit previously read comment comment.edit(auth=Auth(project.creator), content="edited", save=True) n_unread = Comment.find_n_unread(user=user, node=project, page="node") assert_equal(n_unread, 1)
def test_find_unread_includes_edited_comments(self): project = ProjectFactory() user = AuthUserFactory() project.add_contributor(user) project.save() comment = CommentFactory(node=project, user=project.creator) url = project.api_url_for('update_comments_timestamp') payload = {'page': 'node', 'rootId': project._id} res = self.app.put_json(url, payload, auth=user.auth) user.reload() n_unread = Comment.find_n_unread(user=user, node=project) assert_equal(n_unread, 0) # Edit previously read comment comment.edit(auth=Auth(project.creator), content='edited', save=True) n_unread = Comment.find_n_unread(user=user, node=project) assert_equal(n_unread, 1)
class TestCommentViews(OsfTestCase): def setUp(self): super(TestCommentViews, self).setUp() self.project = ProjectFactory(is_public=True) self.user = AuthUserFactory() self.project.add_contributor(self.user) self.project.save() self.user.save() def test_view_project_comments_updates_user_comments_view_timestamp(self): url = self.project.api_url_for("update_comments_timestamp") res = self.app.put_json(url, {"page": "node", "rootId": self.project._id}, auth=self.user.auth) self.user.reload() user_timestamp = self.user.comments_viewed_timestamp[self.project._id] view_timestamp = dt.datetime.utcnow() assert_datetime_equal(user_timestamp, view_timestamp) def test_confirm_non_contrib_viewers_dont_have_pid_in_comments_view_timestamp(self): non_contributor = AuthUserFactory() url = self.project.api_url_for("update_comments_timestamp") res = self.app.put_json(url, {"page": "node", "rootId": self.project._id}, auth=self.user.auth) non_contributor.reload() assert_not_in(self.project._id, non_contributor.comments_viewed_timestamp) def test_view_comments_updates_user_comments_view_timestamp_files(self): osfstorage = self.project.get_addon("osfstorage") root_node = osfstorage.get_root() test_file = root_node.append_file("test_file") test_file.create_version( self.user, {"object": "06d80e", "service": "cloud", osfstorage_settings.WATERBUTLER_RESOURCE: "osf"}, {"size": 1337, "contentType": "img/png"}, ).save() url = self.project.api_url_for("update_comments_timestamp") res = self.app.put_json(url, {"page": "files", "rootId": test_file._id}, auth=self.user.auth) self.user.reload() user_timestamp = self.user.comments_viewed_timestamp[test_file._id] view_timestamp = dt.datetime.utcnow() assert_datetime_equal(user_timestamp, view_timestamp)
class TestForgotAndResetPasswordViews(OsfTestCase): def setUp(self): super(TestForgotAndResetPasswordViews, self).setUp() self.user = AuthUserFactory() self.key = random_string(20) # manually set verifification key self.user.verification_key = self.key self.user.save() self.url = web_url_for('reset_password', verification_key=self.key) def test_reset_password_view_returns_200(self): res = self.app.get(self.url) assert_equal(res.status_code, 200) def test_can_reset_password_if_form_success(self): res = self.app.get(self.url) form = res.forms['resetPasswordForm'] form['password'] = '******' form['password2'] = 'newpassword' res = form.submit() # password was updated self.user.reload() assert_true(self.user.check_password('newpassword')) @unittest.skip('TODO: Get this working with CAS setup') def test_reset_password_logs_out_user(self): another_user = AuthUserFactory() # visits reset password link while another user is logged in res = self.app.get(self.url, auth=another_user.auth) assert_equal(res.status_code, 200) # We check if another_user is logged in by checking if # their full name appears on the page (it should be in the navbar). # Yes, this is brittle. assert_not_in(another_user.fullname, res) # make sure the form is on the page assert_true(res.forms['resetPasswordForm'])
class TestAddonFileViews(OsfTestCase): @classmethod def setUpClass(cls): super(TestAddonFileViews, cls).setUpClass() PROVIDER_MAP['github'] = [TestFolder, TestFile, TestFileNode] TestFileNode.provider = 'github' 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.append(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() @classmethod def tearDownClass(cls): super(TestAddonFileViews, cls).tearDownClass() PROVIDER_MAP['github'] = [models.GithubFolder, models.GithubFile, models.GithubFileNode] del PROVIDER_MAP['test_addons'] TrashedFileNode.remove() def get_test_file(self): version = models.FileVersion(identifier='1') version.save() versions = [version] ret = TestFile( name='Test', node=self.project, path='/test/Test', materialized_path='/test/Test', versions=versions ) ret.save() return ret def get_second_test_file(self): version = models.FileVersion(identifier='1') version.save() ret = TestFile( name='Test2', node=self.project, path='/test/Test2', materialized_path='/test/Test2', versions=[version] ) ret.save() 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': '', 'gravatar': '', '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('website.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('website.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('website.addons.github.model.GitHubNodeSettings.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(StoredFileNode.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(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_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, version=None)) def test_head_returns_url_with_version(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_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version=None, 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(StoredFileNode.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 = TestFolder( name='folder', node=self.project, path='/test/folder/', materialized_path='/test/folder/', versions=[] ) 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(StoredFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) assert_false(StoredFileNode.load(subfolder._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)
class TestExternalAccount(OsfTestCase): # Test the ExternalAccount object and associated views. # # Functionality not specific to the OAuth version used by the # ExternalProvider should go here. def setUp(self): super(TestExternalAccount, self).setUp() self.user = AuthUserFactory() self.provider = MockOAuth2Provider() def tearDown(self): ExternalAccount._clear_caches() ExternalAccount.remove() self.user.remove() super(TestExternalAccount, self).tearDown() def test_disconnect(self): # Disconnect an external account from a user external_account = ExternalAccountFactory( provider='mock2', provider_id='mock_provider_id', provider_name='Mock Provider', ) self.user.external_accounts.append(external_account) self.user.save() # If the external account isn't attached, this test has no meaning assert_equal(ExternalAccount.find().count(), 1) assert_in( external_account, self.user.external_accounts, ) response = self.app.delete( api_url_for('oauth_disconnect', external_account_id=external_account._id), auth=self.user.auth ) # Request succeeded assert_equal( response.status_code, http.OK, ) self.user.reload() # external_account.reload() # External account has been disassociated with the user assert_not_in( external_account, self.user.external_accounts, ) # External account is still in the database assert_equal(ExternalAccount.find().count(), 1) def test_disconnect_with_multiple_connected(self): # Disconnect an account connected to multiple users from one user external_account = ExternalAccountFactory( provider='mock2', provider_id='mock_provider_id', provider_name='Mock Provider', ) self.user.external_accounts.append(external_account) self.user.save() other_user = UserFactory() other_user.external_accounts.append(external_account) other_user.save() response = self.app.delete( api_url_for('oauth_disconnect', external_account_id=external_account._id), auth=self.user.auth ) # Request succeeded assert_equal( response.status_code, http.OK, ) self.user.reload() # External account has been disassociated with the user assert_not_in( external_account, self.user.external_accounts, ) # External account is still in the database assert_equal(ExternalAccount.find().count(), 1) other_user.reload() # External account is still associated with the other user assert_in( external_account, other_user.external_accounts, )
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 = AddonGitHubOauthSettings( github_user_id='denbarell', oauth_access_token='Truthy' ) self.oauth.save() self.user_addon.oauth_settings = self.oauth self.user_addon.save() self.node_addon.user_settings = self.user_addon self.node_addon.repo = 'Truth' self.node_addon.user = '******' self.node_addon.save() # self.node_addon.user_settings = 'Truthy' # setattr(self.node_addon, 'has_auth', True) def get_mako_return(self): ret = serialize_node(self.project, Auth(self.user), primary=True) ret.update({ 'error': '', 'provider': '', 'file_path': '', 'sharejs_uuid': '', 'urls': { 'files': '', 'render': '', 'sharejs': '', 'mfr': '', 'gravatar': '', }, 'size': '', 'extra': '', 'file_name': '', 'materialized_path': '', }) ret.update(rubeus.collect_addon_assets(self.project)) return ret def test_redirects_to_guid(self): path = 'bigdata' guid, _ = self.node_addon.find_or_create_file_guid('/' + path) resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github' ), auth=self.user.auth ) assert_equals(resp.status_code, 302) assert_equals(resp.headers['Location'], 'http://*****:*****@mock.patch('website.addons.base.request') def test_public_download_url_includes_view_only(self, mock_request): view_only = 'justworkplease' mock_request.args = { 'view_only': view_only } path = 'cloudfiles' guid, _ = self.node_addon.find_or_create_file_guid('/' + path) assert_in('view_only={}'.format(view_only), guid.public_download_url) @mock.patch('website.addons.base.views.addon_view_file') def test_action_view_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() path = 'cloudfiles' mock_view_file.return_value = self.get_mako_return() guid, _ = self.node_addon.find_or_create_file_guid('/' + path) self.app.get(guid.guid_url + '?action=view', auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[-1], {'action': 'view'}) assert_equals(args[1], self.project) assert_equals(args[0].user, self.user) assert_equals(args[2], self.node_addon) @mock.patch('website.addons.base.views.addon_view_file') def test_no_action_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() path = 'cloudfiles' mock_view_file.return_value = self.get_mako_return() guid, _ = self.node_addon.find_or_create_file_guid('/' + path) self.app.get(guid.guid_url, auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[-1], {}) assert_equals(args[1], self.project) assert_equals(args[0].user, self.user) assert_equals(args[2], self.node_addon) def test_download_create_guid(self): path = 'cloudfiles' self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth ) guid, created = self.node_addon.find_or_create_file_guid('/' + path) assert_true(guid) assert_false(created) assert_equals(guid.waterbutler_path, '/' + path) 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_head_returns_url(self): path = 'the little engine that couldnt' guid, _ = self.node_addon.find_or_create_file_guid('/' + path) download_url = furl.furl(guid.download_url) download_url.args['accept_url'] = 'false' resp = self.app.head(guid.guid_url, auth=self.user.auth) assert_urls_equal(resp.headers['Location'], download_url.url) 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)
class TestAddonFileViews(OsfTestCase): @classmethod def setUpClass(cls): super(TestAddonFileViews, cls).setUpClass() PROVIDER_MAP['github'] = [TestFolder, TestFile, TestFileNode] TestFileNode.provider = 'github' 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.append(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() @classmethod def tearDownClass(cls): super(TestAddonFileViews, cls).tearDownClass() PROVIDER_MAP['github'] = [ models.GithubFolder, models.GithubFile, models.GithubFileNode ] del PROVIDER_MAP['test_addons'] TrashedFileNode.remove() def get_test_file(self): version = models.FileVersion(identifier='1') version.save() versions = [version] ret = TestFile(name='Test', node=self.project, path='/test/Test', materialized_path='/test/Test', versions=versions) ret.save() return ret def get_second_test_file(self): version = models.FileVersion(identifier='1') version.save() ret = TestFile(name='Test2', node=self.project, path='/test/Test2', materialized_path='/test/Test2', versions=[version]) ret.save() 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': '', 'gravatar': '', '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('website.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('website.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( 'website.addons.github.model.GitHubNodeSettings.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(StoredFileNode.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(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_urls_equal( location.url, file_node.generate_waterbutler_url(direct=None, version=None)) def test_head_returns_url_with_version(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_urls_equal( location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version=None, 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(StoredFileNode.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 = TestFolder(name='folder', node=self.project, path='/test/folder/', materialized_path='/test/folder/', versions=[]) 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(StoredFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) assert_false(StoredFileNode.load(subfolder._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)
class TestUserInstititutionRelationship(ApiTestCase): def setUp(self): super(TestUserInstititutionRelationship, self).setUp() self.user = AuthUserFactory() self.user2 = AuthUserFactory() self.url = '/{}users/{}/relationships/institutions/'.format(API_BASE, self.user._id) self.institution1 = InstitutionFactory() self.institution2 = InstitutionFactory() self.user.affiliated_institutions.append(self.institution1) self.user.affiliated_institutions.append(self.institution2) self.user.save() def test_get_relationship_institutions(self): res = self.app.get( self.url, auth=self.user.auth ) assert_equal(res.status_code, 200) assert_in(self.user.absolute_api_v2_url + 'relationships/institutions/', res.json['links']['self']) assert_in(self.user.absolute_api_v2_url + 'institutions/', res.json['links']['html']) ids = [val['id'] for val in res.json['data']] assert_in(self.institution1._id, ids) assert_in(self.institution2._id, ids) def test_get_institutions_relationship_while_logged_out(self): res = self.app.get( self.url ) ids = [val['id'] for val in res.json['data']] assert_in(self.institution1._id, ids) assert_in(self.institution2._id, ids) def test_post_with_auth(self): res = self.app.post_json_api( self.url, {}, auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, 405) def test_put_with_auth(self): res = self.app.put_json_api( self.url, {}, auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, 405) def test_post_without_auth(self): res = self.app.post_json_api( self.url, {}, expect_errors=True ) assert_equal(res.status_code, 401) def test_put_without_auth(self): res = self.app.put_json_api( self.url, {}, expect_errors=True ) assert_equal(res.status_code, 401) def test_delete_no_auth(self): res = self.app.delete_json_api( self.url, {'data': [ {'type': 'institutions', 'id': self.institution1._id} ]}, expect_errors=True ) assert_equal(res.status_code, 401) def test_delete_wrong_auth(self): res = self.app.delete_json_api( self.url, {'data': [ {'type': 'institutions', 'id': self.institution1._id} ]}, auth=self.user2.auth, expect_errors=True ) assert_equal(res.status_code, 403) def test_delete_one(self): res = self.app.delete_json_api( self.url, {'data': [ {'type': 'institutions', 'id': self.institution1._id} ]}, auth=self.user.auth ) assert_equal(res.status_code, 204) self.user.reload() ids = [inst._id for inst in self.user.affiliated_institutions] assert_not_in(self.institution1._id, ids) assert_in(self.institution2._id, ids) def test_type_mistyped(self): res = self.app.delete_json_api( self.url, {'data': [ {'type': 'wow', 'id': self.institution1._id} ]}, auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, 409) def test_delete_multiple(self): res = self.app.delete_json_api( self.url, {'data': [ {'type': 'institutions', 'id': self.institution1._id}, {'type': 'institutions', 'id': self.institution2._id} ]}, auth=self.user.auth ) assert_equal(res.status_code, 204) self.user.reload() ids = [inst._id for inst in self.user.affiliated_institutions] assert_not_in(self.institution1._id, ids) assert_not_in(self.institution2._id, ids) def test_delete_one_not_existing(self): res = self.app.delete_json_api( self.url, {'data': [ {'type': 'institutions', 'id': 'not_an_id'} ]}, auth=self.user.auth ) assert_equal(res.status_code, 204) self.user.reload() ids = [inst._id for inst in self.user.affiliated_institutions] assert_in(self.institution1._id, ids) assert_in(self.institution2._id, ids) def test_attempt_payload_not_in_array(self): res = self.app.delete_json_api( self.url, {'data': {'type': 'institutions', 'id': self.institution1._id} }, auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, 400) def test_attempt_with_no_type_field(self): res = self.app.delete_json_api( self.url, {'data': [ {'id': self.institution1._id} ]}, auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, 400) def test_attempt_with_no_id_field(self): res = self.app.delete_json_api( self.url, {'data': [ {'type': 'institutions'} ]}, auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, 400)
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 = AddonGitHubOauthSettings( github_user_id='denbarell', oauth_access_token='Truthy' ) self.oauth.save() self.user_addon.oauth_settings = self.oauth self.user_addon.save() self.node_addon.user_settings = self.user_addon self.node_addon.save() # self.node_addon.user_settings = 'Truthy' # setattr(self.node_addon, 'has_auth', True) def get_mako_return(self): ret = serialize_node(self.project, Auth(self.user), primary=True) ret.update({ 'extra': '', 'provider': '', 'rendered': '', 'file_path': '', 'files_url': '', 'file_name': '', 'render_url': '', }) ret.update(rubeus.collect_addon_assets(self.project)) return ret def test_redirects_to_guid(self): path = 'bigdata' guid, _ = self.node_addon.find_or_create_file_guid('/' + path) resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github' ), auth=self.user.auth ) assert_equals(resp.status_code, 302) assert_equals(resp.headers['Location'], 'http://*****:*****@mock.patch('website.addons.base.request') def test_public_download_url_includes_view_only(self, mock_request): view_only = 'justworkplease' mock_request.args = { 'view_only': view_only } path = 'cloudfiles' guid, _ = self.node_addon.find_or_create_file_guid('/' + path) assert_in('view_only={}'.format(view_only), guid.public_download_url) @mock.patch('website.addons.base.views.addon_view_file') def test_action_view_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() path = 'cloudfiles' mock_view_file.return_value = self.get_mako_return() guid, _ = self.node_addon.find_or_create_file_guid('/' + path) self.app.get(guid.guid_url + '?action=view', auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[-1], {'action': 'view'}) assert_equals(args[1], self.project) assert_equals(args[0].user, self.user) assert_equals(args[2], self.node_addon) @mock.patch('website.addons.base.views.addon_view_file') def test_no_action_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() path = 'cloudfiles' mock_view_file.return_value = self.get_mako_return() guid, _ = self.node_addon.find_or_create_file_guid('/' + path) self.app.get(guid.guid_url, auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[-1], {}) assert_equals(args[1], self.project) assert_equals(args[0].user, self.user) assert_equals(args[2], self.node_addon) def test_download_create_guid(self): path = 'cloudfiles' self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth ) guid, created = self.node_addon.find_or_create_file_guid('/' + path) assert_true(guid) assert_false(created) assert_equals(guid.waterbutler_path, '/' + path) 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, 403) def test_head_returns_url(self): path = 'the little engine that couldnt' guid, _ = self.node_addon.find_or_create_file_guid('/' + path) download_url = furl.furl(guid.download_url) download_url.args['accept_url'] = 'false' resp = self.app.head(guid.guid_url, auth=self.user.auth) assert_urls_equal(resp.headers['Location'], download_url.url) 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.api_url_for( 'addon_render_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.api_url_for( 'addon_render_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 401) def test_unconfigured_addons_raise(self): path = 'cloudfiles' self.node_addon.repo = None self.node_addon.save() resp = self.app.get( self.project.api_url_for( 'addon_render_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 400)
class TestResetPassword(OsfTestCase): def setUp(self): super(TestResetPassword, self).setUp() self.user = AuthUserFactory() self.another_user = AuthUserFactory() self.osf_key_v2 = generate_verification_key( verification_type='password') self.user.verification_key_v2 = self.osf_key_v2 self.user.verification_key = None self.user.save() self.get_url = web_url_for('reset_password_get', uid=self.user._id, token=self.osf_key_v2['token']) self.get_url_invalid_key = web_url_for( 'reset_password_get', uid=self.user._id, token=generate_verification_key()) self.get_url_invalid_user = web_url_for('reset_password_get', uid=self.another_user._id, token=self.osf_key_v2['token']) # successfully load reset password page def test_reset_password_view_returns_200(self): res = self.app.get(self.get_url) assert_equal(res.status_code, 200) # raise http 400 error def test_reset_password_view_raises_400(self): res = self.app.get(self.get_url_invalid_key, expect_errors=True) assert_equal(res.status_code, 400) res = self.app.get(self.get_url_invalid_user, expect_errors=True) assert_equal(res.status_code, 400) self.user.verification_key_v2['expires'] = dt.datetime.utcnow() self.user.save() res = self.app.get(self.get_url, expect_errors=True) assert_equal(res.status_code, 400) # successfully reset password @mock.patch('framework.auth.cas.CasClient.service_validate') def test_can_reset_password_if_form_success(self, mock_service_validate): # load reset password page and submit email res = self.app.get(self.get_url) form = res.forms['resetPasswordForm'] form['password'] = '******' form['password2'] = 'newpassword' res = form.submit() # check request URL is /resetpassword with username and new verification_key_v2 token request_url_path = res.request.path assert_in('resetpassword', request_url_path) assert_in(self.user._id, request_url_path) assert_not_in(self.user.verification_key_v2['token'], request_url_path) # check verification_key_v2 for OSF is destroyed and verification_key for CAS is in place self.user.reload() assert_equal(self.user.verification_key_v2, {}) assert_not_equal(self.user.verification_key, None) # check redirection to CAS login with username and the new verification_key(CAS) assert_equal(res.status_code, 302) location = res.headers.get('Location') assert_true('login?service=' in location) assert_true('username={}'.format(self.user.username) in location) assert_true('verification_key={}'.format(self.user.verification_key) in location) # check if password was updated self.user.reload() assert_true(self.user.check_password('newpassword')) # check if verification_key is destroyed after service validation mock_service_validate.return_value = cas.CasResponse( authenticated=True, user=self.user._primary_key, attributes={'accessToken': fake.md5()}) ticket = fake.md5() service_url = 'http://accounts.osf.io/?ticket=' + ticket cas.make_response_from_ticket(ticket, service_url) assert_equal(self.user.verification_key, None) # log users out before they land on reset password page def test_reset_password_logs_out_user(self): # visit reset password link while another user is logged in res = self.app.get(self.get_url, auth=self.another_user.auth) # check redirection to CAS logout assert_equal(res.status_code, 302) location = res.headers.get('Location') assert_not_in('reauth', location) assert_in('logout?service=', location) assert_in('resetpassword', location)
class TestAddonFileViews(OsfTestCase): @classmethod def setUpClass(cls): super(TestAddonFileViews, cls).setUpClass() PROVIDER_MAP['github'] = [TestFolder, TestFile, TestFileNode] TestFileNode.provider = 'github' 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 = AddonGitHubOauthSettings(github_user_id='denbarell', oauth_access_token='Truthy') self.oauth.save() self.user_addon.oauth_settings = self.oauth self.user_addon.save() self.node_addon.user_settings = self.user_addon self.node_addon.repo = 'Truth' self.node_addon.user = '******' self.node_addon.save() @classmethod def tearDownClass(cls): super(TestAddonFileViews, cls).tearDownClass() PROVIDER_MAP['github'] = [ models.GithubFolder, models.GithubFile, models.GithubFileNode ] del PROVIDER_MAP['test_addons'] def get_test_file(self): ret = TestFile(name='Test', node=self.project, path='/test/Test', materialized_path='/test/Test') ret.save() 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': '', 'gravatar': '', 'external': '', }, 'size': '', 'extra': '', 'file_name': '', 'materialized_path': '', }) 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('website.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, self.user) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) @mock.patch('website.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, self.user) 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_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(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_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None)) 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)
class TestAddonFileViews(OsfTestCase): @classmethod def setUpClass(cls): super(TestAddonFileViews, cls).setUpClass() PROVIDER_MAP['github'] = [TestFolder, TestFile, TestFileNode] TestFileNode.provider = 'github' 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 = AddonGitHubOauthSettings( github_user_id='denbarell', oauth_access_token='Truthy' ) self.oauth.save() self.user_addon.oauth_settings = self.oauth self.user_addon.save() self.node_addon.user_settings = self.user_addon self.node_addon.repo = 'Truth' self.node_addon.user = '******' self.node_addon.save() @classmethod def tearDownClass(cls): super(TestAddonFileViews, cls).tearDownClass() PROVIDER_MAP['github'] = [models.GithubFolder, models.GithubFile, models.GithubFileNode] del PROVIDER_MAP['test_addons'] def get_test_file(self): version = models.FileVersion(identifier='1') version.save() ret = TestFile( name='Test', node=self.project, path='/test/Test', materialized_path='/test/Test', versions=[version] ) ret.save() 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': '', 'gravatar': '', 'external': '', }, 'size': '', 'extra': '', 'file_name': '', 'materialized_path': '', }) 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('website.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('website.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_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(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_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, version=None)) def test_head_returns_url_with_version(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_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version=1, 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)
class TestUserInstititutionRelationship(ApiTestCase): def setUp(self): super(TestUserInstititutionRelationship, self).setUp() self.user = AuthUserFactory() self.user2 = AuthUserFactory() self.url = '/{}users/{}/relationships/institutions/'.format( API_BASE, self.user._id) self.institution1 = InstitutionFactory() self.institution2 = InstitutionFactory() self.user.affiliated_institutions.append(self.institution1) self.user.affiliated_institutions.append(self.institution2) self.user.save() def test_get_relationship_institutions(self): res = self.app.get(self.url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_in( self.user.absolute_api_v2_url + 'relationships/institutions/', res.json['links']['self']) assert_in(self.user.absolute_api_v2_url + 'institutions/', res.json['links']['html']) ids = [val['id'] for val in res.json['data']] assert_in(self.institution1._id, ids) assert_in(self.institution2._id, ids) def test_get_institutions_relationship_while_logged_out(self): res = self.app.get(self.url) ids = [val['id'] for val in res.json['data']] assert_in(self.institution1._id, ids) assert_in(self.institution2._id, ids) def test_post_with_auth(self): res = self.app.post_json_api(self.url, {}, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 405) def test_put_with_auth(self): res = self.app.put_json_api(self.url, {}, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 405) def test_post_without_auth(self): res = self.app.post_json_api(self.url, {}, expect_errors=True) assert_equal(res.status_code, 401) def test_put_without_auth(self): res = self.app.put_json_api(self.url, {}, expect_errors=True) assert_equal(res.status_code, 401) def test_delete_no_auth(self): res = self.app.delete_json_api( self.url, {'data': [{ 'type': 'institutions', 'id': self.institution1._id }]}, expect_errors=True) assert_equal(res.status_code, 401) def test_delete_wrong_auth(self): res = self.app.delete_json_api( self.url, {'data': [{ 'type': 'institutions', 'id': self.institution1._id }]}, auth=self.user2.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_delete_one(self): res = self.app.delete_json_api( self.url, {'data': [{ 'type': 'institutions', 'id': self.institution1._id }]}, auth=self.user.auth) assert_equal(res.status_code, 204) self.user.reload() ids = [inst._id for inst in self.user.affiliated_institutions] assert_not_in(self.institution1._id, ids) assert_in(self.institution2._id, ids) def test_type_mistyped(self): res = self.app.delete_json_api( self.url, {'data': [{ 'type': 'wow', 'id': self.institution1._id }]}, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 409) def test_delete_multiple(self): res = self.app.delete_json_api(self.url, { 'data': [{ 'type': 'institutions', 'id': self.institution1._id }, { 'type': 'institutions', 'id': self.institution2._id }] }, auth=self.user.auth) assert_equal(res.status_code, 204) self.user.reload() ids = [inst._id for inst in self.user.affiliated_institutions] assert_not_in(self.institution1._id, ids) assert_not_in(self.institution2._id, ids) def test_delete_one_not_existing(self): res = self.app.delete_json_api( self.url, {'data': [{ 'type': 'institutions', 'id': 'not_an_id' }]}, auth=self.user.auth) assert_equal(res.status_code, 204) self.user.reload() ids = [inst._id for inst in self.user.affiliated_institutions] assert_in(self.institution1._id, ids) assert_in(self.institution2._id, ids) def test_attempt_payload_not_in_array(self): res = self.app.delete_json_api( self.url, {'data': { 'type': 'institutions', 'id': self.institution1._id }}, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) def test_attempt_with_no_type_field(self): res = self.app.delete_json_api( self.url, {'data': [{ 'id': self.institution1._id }]}, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) def test_attempt_with_no_id_field(self): res = self.app.delete_json_api(self.url, {'data': [{ 'type': 'institutions' }]}, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400)
class TestResetPassword(OsfTestCase): def setUp(self): super(TestResetPassword, self).setUp() self.user = AuthUserFactory() self.another_user = AuthUserFactory() self.osf_key_v2 = generate_verification_key(verification_type='password') self.user.verification_key_v2 = self.osf_key_v2 self.user.verification_key = None self.user.save() self.get_url = web_url_for( 'reset_password_get', uid=self.user._id, token=self.osf_key_v2['token'] ) self.get_url_invalid_key = web_url_for( 'reset_password_get', uid=self.user._id, token=generate_verification_key() ) self.get_url_invalid_user = web_url_for( 'reset_password_get', uid=self.another_user._id, token=self.osf_key_v2['token'] ) # successfully load reset password page def test_reset_password_view_returns_200(self): res = self.app.get(self.get_url) assert_equal(res.status_code, 200) # raise http 400 error def test_reset_password_view_raises_400(self): res = self.app.get(self.get_url_invalid_key, expect_errors=True) assert_equal(res.status_code, 400) res = self.app.get(self.get_url_invalid_user, expect_errors=True) assert_equal(res.status_code, 400) self.user.verification_key_v2['expires'] = dt.datetime.utcnow() self.user.save() res = self.app.get(self.get_url, expect_errors=True) assert_equal(res.status_code, 400) # successfully reset password @mock.patch('framework.auth.cas.CasClient.service_validate') def test_can_reset_password_if_form_success(self, mock_service_validate): # load reset password page and submit email res = self.app.get(self.get_url) form = res.forms['resetPasswordForm'] form['password'] = '******' form['password2'] = 'newpassword' res = form.submit() # check request URL is /resetpassword with username and new verification_key_v2 token request_url_path = res.request.path assert_in('resetpassword', request_url_path) assert_in(self.user._id, request_url_path) assert_not_in(self.user.verification_key_v2['token'], request_url_path) # check verification_key_v2 for OSF is destroyed and verification_key for CAS is in place self.user.reload() assert_equal(self.user.verification_key_v2, {}) assert_not_equal(self.user.verification_key, None) # check redirection to CAS login with username and the new verification_key(CAS) assert_equal(res.status_code, 302) location = res.headers.get('Location') assert_true('login?service=' in location) assert_true('username={}'.format(self.user.username) in location) assert_true('verification_key={}'.format(self.user.verification_key) in location) # check if password was updated self.user.reload() assert_true(self.user.check_password('newpassword')) # check if verification_key is destroyed after service validation mock_service_validate.return_value = cas.CasResponse( authenticated=True, user=self.user._primary_key, attributes={'accessToken': fake.md5()} ) ticket = fake.md5() service_url = 'http://accounts.osf.io/?ticket=' + ticket cas.make_response_from_ticket(ticket, service_url) assert_equal(self.user.verification_key, None) # log users out before they land on reset password page def test_reset_password_logs_out_user(self): # visit reset password link while another user is logged in res = self.app.get(self.get_url, auth=self.another_user.auth) # check redirection to CAS logout assert_equal(res.status_code, 302) location = res.headers.get('Location') assert_not_in('reauth', location) assert_in('logout?service=', location) assert_in('resetpassword', location)
class TestExternalAccount(OsfTestCase): # Test the ExternalAccount object and associated views. # # Functionality not specific to the OAuth version used by the # ExternalProvider should go here. def setUp(self): super(TestExternalAccount, self).setUp() self.user = AuthUserFactory() self.provider = MockOAuth2Provider() def tearDown(self): ExternalAccount._clear_caches() ExternalAccount.remove() self.user.remove() super(TestExternalAccount, self).tearDown() def test_disconnect(self): # Disconnect an external account from a user external_account = ExternalAccountFactory( provider='mock2', provider_id='mock_provider_id', provider_name='Mock Provider', ) self.user.external_accounts.append(external_account) self.user.save() # If the external account isn't attached, this test has no meaning assert_equal(ExternalAccount.find().count(), 1) assert_in( external_account, self.user.external_accounts, ) response = self.app.delete(api_url_for( 'oauth_disconnect', external_account_id=external_account._id), auth=self.user.auth) # Request succeeded assert_equal( response.status_code, http.OK, ) self.user.reload() # external_account.reload() # External account has been disassociated with the user assert_not_in( external_account, self.user.external_accounts, ) # External account is still in the database assert_equal(ExternalAccount.find().count(), 1) def test_disconnect_with_multiple_connected(self): # Disconnect an account connected to multiple users from one user external_account = ExternalAccountFactory( provider='mock2', provider_id='mock_provider_id', provider_name='Mock Provider', ) self.user.external_accounts.append(external_account) self.user.save() other_user = UserFactory() other_user.external_accounts.append(external_account) other_user.save() response = self.app.delete(api_url_for( 'oauth_disconnect', external_account_id=external_account._id), auth=self.user.auth) # Request succeeded assert_equal( response.status_code, http.OK, ) self.user.reload() # External account has been disassociated with the user assert_not_in( external_account, self.user.external_accounts, ) # External account is still in the database assert_equal(ExternalAccount.find().count(), 1) other_user.reload() # External account is still associated with the other user assert_in( external_account, other_user.external_accounts, )
class TestAddonFileViews(OsfTestCase): @classmethod def setUpClass(cls): super(TestAddonFileViews, cls).setUpClass() PROVIDER_MAP["github"] = [TestFolder, TestFile, TestFileNode] TestFileNode.provider = "github" 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.append(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() @classmethod def tearDownClass(cls): super(TestAddonFileViews, cls).tearDownClass() PROVIDER_MAP["github"] = [models.GithubFolder, models.GithubFile, models.GithubFileNode] del PROVIDER_MAP["test_addons"] TrashedFileNode.remove() def get_test_file(self): version = models.FileVersion(identifier="1") version.save() versions = [version] ret = TestFile( name="Test", node=self.project, path="/test/Test", materialized_path="/test/Test", versions=versions ) ret.save() return ret def get_second_test_file(self): version = models.FileVersion(identifier="1") version.save() ret = TestFile( name="Test2", node=self.project, path="/test/Test2", materialized_path="/test/Test2", versions=[version] ) ret.save() 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": "", "gravatar": "", "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("website.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("website.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( "website.addons.github.model.GitHubNodeSettings.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(StoredFileNode.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(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_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, version=None)) def test_head_returns_url_with_version(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_urls_equal( location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version=None, 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(StoredFileNode.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 = TestFolder( name="folder", node=self.project, path="/test/folder/", materialized_path="/test/folder/", versions=[] ) 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(StoredFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) assert_false(StoredFileNode.load(subfolder._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)