Skip to content

Commit 2776a68

Browse files
committed
enh: implement and test get_datasets_user_owned for CachedAPIInterrogator
1 parent d6fe32a commit 2776a68

4 files changed

Lines changed: 119 additions & 8 deletions

File tree

dcoraid/dbmodel/db_api_cached.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ def __init__(self, api, cache_location):
3232
else:
3333
user_data = None
3434

35-
self._mc = MetaCache(self.cache_location)
35+
self._mc = MetaCache(directory=self.cache_location,
36+
user_id=self.api.user_id,
37+
)
3638
self._mc_timestamp_path = self.cache_location / "cache_timestamp"
3739
self._mc_timestamp_path.touch()
3840
self._mc_version_path = self.cache_location / "cache_version"
@@ -79,8 +81,9 @@ def get_datasets_user_following(self):
7981

8082
def get_datasets_user_owned(self):
8183
"""Return datasets the user created"""
82-
# TODO: Use datasets in self._mc
83-
return self.ai.get_datasets_user_owned()
84+
own_list = self._mc.datasets_user_owned
85+
ds_list = self._mc.datasets
86+
return [ds for (ds, byuser) in zip(ds_list, own_list) if byuser]
8487

8588
def get_datasets_user_shared(self):
8689
"""Return datasets shared with the user"""
@@ -134,6 +137,6 @@ def update(self, reset=False, abort_event=None):
134137
break
135138
self._mc.upsert_dataset(ds_dict)
136139
else:
137-
# Only update teh local timestamp if we actually did
140+
# Only update the local timestamp if we actually did
138141
# update the local database.
139142
self.local_timestamp = new_timestamp

dcoraid/dbmodel/meta_cache.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class MetaCache:
2020
"""
2121
def __init__(self,
2222
directory: str | pathlib.Path,
23+
user_id: str = None,
2324
circle_ids: list[str] = None,
2425
) -> None:
2526
"""
@@ -28,24 +29,33 @@ def __init__(self,
2829
2930
Parameters
3031
----------
31-
directory : str | pathlib.Path
32+
directory: str | pathlib.Path
3233
Path to the folder that will hold the ``circle_<org_id>.db`` files.
3334
The folder is created automatically if it does not exist.
34-
circle_ids : list[str]
35+
user_id: str
36+
The ID of the user operating the database.
37+
circle_ids: list[str]
3538
List of circle IDs that should be taken into consideration.
3639
If set to None (default), all databases in the `directory`
3740
are loaded.
3841
"""
3942
self.base_dir = pathlib.Path(directory).expanduser().resolve()
4043
self.base_dir.mkdir(parents=True, exist_ok=True)
44+
self.user_id = user_id
4145

42-
# The registry is a dictionary with circle IDs and a list of
43-
# dataset IDs as values.
46+
# The organization registry is a dictionary with circle IDs and
47+
# a list of dataset IDs as values.
4448
self._registry_org = {}
4549

50+
# List of booleans indicating whether dataset was created by the user
51+
self.datasets_user_owned = []
52+
4653
# Dictionary of databases for persistent storage
4754
self._databases = {}
4855

56+
# List of dataset dictionaries
57+
self.datasets = []
58+
4959
# Search blob array
5060
self._srt_blobs = None
5161

@@ -249,6 +259,12 @@ def _upsert_dataset_insert(self, ds_dict):
249259
db_name=self.base_dir / f"circle_{org_id}.db")
250260
self._databases[org_id][ds_id] = ds_dict
251261

262+
# user's dataset list
263+
self.datasets_user_owned.insert(
264+
new_idx,
265+
ds_dict["creator_user_id"] == self.user_id
266+
)
267+
252268
def _upsert_dataset_update(self, ds_dict):
253269
"""Update an existing dataset
254270

tests/test_dbmodel_api.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ def test_get_collections():
3838
assert "figshare-collection" in collections
3939

4040

41+
def test_get_datasets_user_owned(tmp_path):
42+
ds_dict = common.make_dataset_for_download()
43+
api = common.get_api()
44+
db = db_api.APIInterrogator(api=api)
45+
ds_list = db.get_datasets_user_owned()
46+
assert ds_dict in ds_list
47+
48+
4149
def test_get_users_anonymous():
4250
api = CKANAPI(server=common.SERVER) # anonymous access
4351
db = db_api.APIInterrogator(api=api)

tests/test_dbmodel_api_cache.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import pathlib
2+
3+
import pytest
4+
5+
from dcoraid.api import CKANAPI, errors
6+
from dcoraid.dbmodel import CachedAPIInterrogator
7+
8+
from . import common
9+
10+
dpath = pathlib.Path(__file__).parent / "data" / "calibration_beads_47.rtdc"
11+
12+
HAS_FIGSHARE_ACCESS = common.get_test_defaults()["user"] == "dcoraid"
13+
14+
15+
@pytest.mark.skipif(not HAS_FIGSHARE_ACCESS,
16+
reason="No access to figshare-import circle")
17+
def test_get_circles(tmp_path):
18+
api = common.get_api()
19+
db = CachedAPIInterrogator(cache_location=tmp_path, api=api)
20+
circles = db.get_circles()
21+
defaults = common.get_test_defaults()
22+
assert defaults["circle"] in circles
23+
# requires that the "dcoraid" user is in the figshare-import circle
24+
assert "figshare-import" in circles
25+
26+
27+
@pytest.mark.skipif(not HAS_FIGSHARE_ACCESS,
28+
reason="No access to figshare-import circle")
29+
def test_get_collections(tmp_path):
30+
api = common.get_api()
31+
db = CachedAPIInterrogator(cache_location=tmp_path, api=api)
32+
collections = db.get_collections()
33+
defaults = common.get_test_defaults()
34+
assert defaults["collection"] in collections
35+
# requires that the "dcoraid" user is in figshare-collection collection
36+
assert "figshare-collection" in collections
37+
38+
39+
def test_get_datasets_user_owned(tmp_path):
40+
ds_dict = common.make_dataset_for_download()
41+
api = common.get_api()
42+
db = CachedAPIInterrogator(cache_location=tmp_path, api=api)
43+
db.update()
44+
ds_list = db.get_datasets_user_owned()
45+
assert ds_dict in ds_list
46+
47+
48+
def test_get_users_anonymous(tmp_path):
49+
api = CKANAPI(server=common.SERVER) # anonymous access
50+
db = CachedAPIInterrogator(cache_location=tmp_path, api=api)
51+
with pytest.raises(errors.APIAuthorizationError, match="Access denied"):
52+
db.get_users()
53+
54+
55+
def test_public_api_interrogator(tmp_path):
56+
api = common.get_api()
57+
db = CachedAPIInterrogator(cache_location=tmp_path, api=api)
58+
defaults = common.get_test_defaults()
59+
assert defaults["circle"] in db.get_circles()
60+
assert defaults["collection"] in db.get_collections()
61+
assert defaults["user"] in db.get_users()
62+
63+
64+
def test_user_data(tmp_path):
65+
"""Test the user information"""
66+
api = common.get_api()
67+
db = CachedAPIInterrogator(cache_location=tmp_path, api=api)
68+
data = db.user_data
69+
defaults = common.get_test_defaults()
70+
assert data["fullname"] == defaults["user_name"], "fullname not correct"
71+
72+
73+
@pytest.mark.skipif(not HAS_FIGSHARE_ACCESS,
74+
reason="No access to figshare-import circle")
75+
def test_get_datasets_user_shared_figshare(tmp_path):
76+
# The figshare circle must have the testing user as a member
77+
api = common.get_api()
78+
db = CachedAPIInterrogator(cache_location=tmp_path, api=api)
79+
datasets = db.get_datasets_user_shared()
80+
for dd in datasets:
81+
if dd["id"] == "89bf2177-ffeb-9893-83cc-b619fc2f6663":
82+
break
83+
else:
84+
assert False, "Search did not return figshare-7771184-v2!"

0 commit comments

Comments
 (0)