Skip to content

Commit

Permalink
Merge pull request CenterForOpenScience#10726 from opaduchak/feature/…
Browse files Browse the repository at this point in the history
…ENG-5729

[ENG-5729] x.0.3.1 (OSF) New tests for Files Endpoints
  • Loading branch information
adlius authored Sep 4, 2024
2 parents e522fe8 + 931d46b commit 88b8892
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 9 deletions.
108 changes: 108 additions & 0 deletions api_tests/nodes/views/test_node_files_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from furl import furl
import responses
from django.utils import timezone
from waffle.testutils import override_flag

from framework.auth.core import Auth

Expand All @@ -13,6 +14,8 @@
from api.base.settings.defaults import API_BASE
from api.base.utils import waterbutler_api_url_for
from api_tests import utils as api_utils
from osf.models import AbstractNode
from osf_tests.external.gravy_valet.gv_fakes import FakeGravyValet
from tests.base import ApiTestCase
from osf.models.files import FileVersionUserMetadata
from osf_tests.factories import (
Expand All @@ -24,6 +27,7 @@
from osf.utils.permissions import READ
from dateutil.parser import parse as parse_date
from website import settings
from osf.features import ENABLE_GV


def prepare_mock_wb_response(
Expand Down Expand Up @@ -435,6 +439,110 @@ def test_files_list_contains_relationships_object(self):
assert res.status_code == 200
assert 'relationships' in res.json['data'][0]

class TestGVNodeFileList(ApiTestCase):
def setUp(self):
super().setUp()
self.flag_override = override_flag(ENABLE_GV, True)
self.flag_override.__enter__()
self.user = AuthUserFactory()
self.project = ProjectFactory(creator=self.user)
self.private_url = f"/{API_BASE}nodes/{self.project._id}/files/"
self.resource_reference_id = '2fe95af1-e06e-4f5a-9fef-6fe85a88f62a'
self.configured_storage_addon_id = 'self.configured_storage_addon_id'

self.user_two = AuthUserFactory()

self.public_project = ProjectFactory(creator=self.user, is_public=True)
self.public_url = f"/{API_BASE}nodes/{self.public_project._id}/files/"
self.fake_gv = FakeGravyValet()
self.fake_gv.configure_resource(self.project)
self.fake_gv.configure_resource(self.public_project)

def tearDown(self):
super().tearDown()
self.flag_override.__exit__(None, None, None)

def configure_account(self):
self.fake_gv.configure_fake_provider('box')
return self.fake_gv.configure_fake_account(self.user, 'box')

def configure_addon(self, project: AbstractNode):
account = self.configure_account()
return self.fake_gv.configure_fake_addon(project, account)

@responses.activate
def test_returns_public_files_logged_out_with_gv_response(self):
self.configure_addon(self.public_project)
with self.fake_gv.run_fake():
res = self.app.get(self.public_url, expect_errors=True)
assert res.status_code == 200
assert res.json['data'][0]['attributes']['provider'] == 'osfstorage'
assert res.json['data'][1]['attributes']['provider'] == 'box'
assert res.content_type == 'application/vnd.api+json'

@responses.activate
def test_returns_public_files_logged_in_no_gv_response(self):
with self.fake_gv.run_fake():
res = self.app.get(self.public_url, auth=self.user.auth)
assert res.status_code == 200
assert res.content_type == 'application/vnd.api+json'
assert len(res.json['data']) == 1
assert res.json['data'][0]['attributes']['provider'] == 'osfstorage'

@responses.activate
def test_returns_public_files_logged_in_with_gv_response(self):
self.configure_addon(self.public_project)
with self.fake_gv.run_fake():
res = self.app.get(self.public_url, auth=self.user.auth)
assert res.status_code == 200
assert res.content_type == 'application/vnd.api+json'
assert len(res.json['data']) == 2, 'invalid addon count'
assert res.json['data'][0]['attributes']['provider'] == 'osfstorage'
assert (res.json['data'][1]['attributes']['provider'] == 'box'), 'addon returned from gv is not of expected provider'

@responses.activate
def test_returns_storage_addons_link(self):
self.configure_addon(self.project)
with self.fake_gv.run_fake():
res = self.app.get(self.private_url, auth=self.user.auth)
assert 'storage_addons' in res.json['data'][1]['links']

def test_returns_private_files_logged_out(self):
res = self.app.get(self.private_url, expect_errors=True)
assert res.status_code == 401
assert 'detail' in res.json['errors'][0]

@responses.activate
def test_returns_private_files_logged_in_contributor(self):
self.configure_addon(self.project)
with self.fake_gv.run_fake():
res = self.app.get(self.private_url, auth=self.user.auth)
assert res.status_code == 200
assert res.content_type == 'application/vnd.api+json'
assert len(res.json['data']) == 2
assert res.json['data'][0]['attributes']['provider'] == 'osfstorage'
assert res.json['data'][1]['attributes']['provider'] == 'box'

@responses.activate
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 res.status_code == 403
assert 'detail' in res.json['errors'][0]

@responses.activate
def test_returns_private_files_logged_in_osf_group_member(self):
self.configure_addon(self.project)
group_mem = AuthUserFactory()
group = OSFGroupFactory(creator=group_mem)
self.project.add_osf_group(group, READ)
with self.fake_gv.run_fake():
res = self.app.get(
self.private_url, auth=group_mem.auth, expect_errors=True
)
assert res.status_code == 200


class TestNodeFilesListFiltering(ApiTestCase):

Expand Down
2 changes: 1 addition & 1 deletion osf/external/gravy_valet/request_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def get_gv_result(
params=params,
).json()

if not response_json['data']:
if not response_json.get('data'):
return None
data = response_json['data']
if isinstance(data, list):
Expand Down
11 changes: 11 additions & 0 deletions osf/external/gravy_valet/translations.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import enum

import dataclasses
from dataclasses import asdict

from addons.box.apps import BoxAddonAppConfig
from . import request_helpers as gv_requests
Expand Down Expand Up @@ -46,6 +47,10 @@ class EphemeralAddonConfig:
short_name: str
full_name: str

@property
def has_hgrid_files(self):
return True

@classmethod
def from_legacy_config(cls, legacy_config):
return cls(
Expand All @@ -55,6 +60,9 @@ def from_legacy_config(cls, legacy_config):
short_name=legacy_config.short_name,
)

def to_json(self):
return asdict(self)


@dataclasses.dataclass
class EphemeralNodeSettings:
Expand Down Expand Up @@ -84,6 +92,9 @@ def configured(self):
attribute_name='credentials_available'
)

def before_page_load(self, *args, **kwargs):
pass

@property
def folder_id(self):
return self.gv_data.get_attribute('root_folder')
Expand Down
5 changes: 4 additions & 1 deletion osf_tests/external/gravy_valet/gv_fakes.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def _serialize_relationships(self):
}


class FakeGravyValet():
class FakeGravyValet:

ROUTES = {
r'v1/user-references(/(?P<pk>\d+)|(\?filter\[user_uri\]=(?P<user_uri>[^&]+)))': '_get_user',
Expand Down Expand Up @@ -250,6 +250,9 @@ def _get_or_create_user_entry(self, user: OSFUser):
self._known_users[user_pk] = user_uri
return user_uri, user_pk

def configure_resource(self, resource: AbstractNode):
return self._get_or_create_resource_entry(resource)

def _get_or_create_resource_entry(self, resource: AbstractNode):
resource_uri = resource.get_semantic_iri()
resource_pk = self._known_resources.get(resource_uri)
Expand Down
10 changes: 6 additions & 4 deletions website/project/views/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from framework.utils import iso8601format
from framework.flask import redirect # VOL-aware redirect
from framework.auth.decorators import must_be_logged_in, collect_auth
from osf.external.gravy_valet.translations import EphemeralAddonConfig
from website.ember_osf_web.decorators import ember_flag_is_active
from api.waffle.utils import flag_is_active, storage_i18n_flag_active, storage_usage_flag_active
from framework.exceptions import HTTPError
Expand Down Expand Up @@ -668,11 +669,12 @@ def _render_addons(addons):

for addon in addons:
configs[addon.config.short_name] = addon.config.to_json()
js.extend(addon.config.include_js.get('widget', []))
css.extend(addon.config.include_css.get('widget', []))
if not isinstance(addon.config, EphemeralAddonConfig):
js.extend(addon.config.include_js.get('widget', []))
css.extend(addon.config.include_css.get('widget', []))

js.extend(addon.config.include_js.get('files', []))
css.extend(addon.config.include_css.get('files', []))
js.extend(addon.config.include_js.get('files', []))
css.extend(addon.config.include_css.get('files', []))

return widgets, configs, js, css

Expand Down
2 changes: 1 addition & 1 deletion website/settings/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ def parent_dir(path):
DEFAULT_HMAC_ALGORITHM = hashlib.sha256
WATERBUTLER_URL = 'http://localhost:7777'
WATERBUTLER_INTERNAL_URL = WATERBUTLER_URL
GRAVYVALET_URL = 'https://localhost:8004'
GRAVYVALET_URL = 'http://192.168.168.167:8004'

####################
# Identifiers #
Expand Down
2 changes: 1 addition & 1 deletion website/templates/project/project.mako
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@
% if addons:
<!-- Show widgets in left column if present -->
% for addon in addons_enabled:
% if addons[addon]['has_widget']:
% if addons[addon].get('has_widget'):
%if addon != 'wiki': ## We already show the wiki widget at the top
${ render_addon_widget.render_addon_widget(addon, addons_widget_data[addon]) }
%endif
Expand Down
2 changes: 1 addition & 1 deletion website/templates/project/project_header.mako
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<!-- Add-on tabs -->
% for addon in addons_enabled:

% if addons[addon]['has_page']:
% if addons[addon].get('has_page', False):
<li>
<a href="${node['url']}${addons[addon]['short_name']}" class="subnav-header">

Expand Down

0 comments on commit 88b8892

Please sign in to comment.