Skip to content

Commit

Permalink
feat: always resolve content owner (#224)
Browse files Browse the repository at this point in the history
  • Loading branch information
tdstein authored Jun 13, 2024
1 parent 3a3019b commit 22e38c7
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 13 deletions.
2 changes: 1 addition & 1 deletion integration/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,4 @@ help:
# on local network.
test:
mkdir -p logs
CONNECT_VERSION=${CONNECT_VERSION} CONNECT_API_KEY="$(shell rsconnect bootstrap -i -s http://connect:3939 --raw)" $(PYTHON) -m pytest --junit-xml=./reports/$(CONNECT_VERSION).xml > ./logs/$(CONNECT_VERSION).log
CONNECT_VERSION=${CONNECT_VERSION} CONNECT_API_KEY="$(shell rsconnect bootstrap -i -s http://connect:3939 --raw)" $(PYTHON) -m pytest -s --junit-xml=./reports/$(CONNECT_VERSION).xml | tee ./logs/$(CONNECT_VERSION).log
3 changes: 0 additions & 3 deletions integration/tests/posit/connect/test_client.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import os
import pytest

from posit import connect


Expand Down
33 changes: 33 additions & 0 deletions integration/tests/posit/connect/test_content.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from posit import connect


class TestContent:
def setup_class(cls):
cls.client = connect.Client()
cls.item = cls.client.content.create(
name="Sample",
description="Simple sample content for testing",
access_type="acl",
)

def test_count(self):
assert self.client.content.count() == 1

def test_get(self):
assert self.client.content.get(self.item.guid) == self.item

def test_find(self):
assert self.client.content.find()

def test_find_one(self):
assert self.client.content.find_one()

def test_content_item_owner(self):
item = self.client.content.find_one(include=None)
owner = item.owner
assert owner.guid == self.client.me.guid

def test_content_item_owner_from_include(self):
item = self.client.content.find_one(include="owner")
owner = item.owner
assert owner.guid == self.client.me.guid
16 changes: 12 additions & 4 deletions src/posit/connect/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from .bundles import Bundles
from .permissions import Permissions
from .resources import Resources, Resource
from .users import Users


class ContentItemOwner(Resource):
Expand Down Expand Up @@ -146,6 +147,17 @@ def bundles(self) -> Bundles:
def permissions(self) -> Permissions:
return Permissions(self.config, self.session, self.guid)

@property
def owner(self) -> ContentItemOwner:
if "owner" not in self:
# It is possible to get a content item that does not contain owner.
# "owner" is an optional additional request param.
# If it's not included, we can retrieve the information by `owner_guid`
self["owner"] = Users(self.config, self.session).get(
self.owner_guid
)
return ContentItemOwner(self.config, self.session, **self["owner"])

# Properties

@property
Expand Down Expand Up @@ -308,10 +320,6 @@ def run_as_current_user(self) -> bool:
def owner_guid(self) -> str:
return self.get("owner_guid") # type: ignore

@property
def owner(self) -> ContentItemOwner:
return self.get("owner", {}) # type: ignore

@property
def content_url(self) -> str:
return self.get("content_url") # type: ignore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"default_py_environment_management": null,
"run_as": null,
"run_as_current_user": false,
"owner_guid": "87c12c08-11cd-4de1-8da3-12a7579c4998",
"owner_guid": "20a79ce3-6e87-4522-9faf-be24228800a4",
"content_url": "https://connect.example/content/f2f37341-e21d-3d80-c698-a935ad614066/",
"dashboard_url": "https://connect.example/connect/#/apps/f2f37341-e21d-3d80-c698-a935ad614066",
"app_role": "viewer",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
"confirmed": true,
"locked": false,
"guid": "20a79ce3-6e87-4522-9faf-be24228800a4"
}
}
57 changes: 54 additions & 3 deletions tests/posit/connect/test_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,34 @@

from posit.connect.client import Client
from posit.connect.config import Config
from posit.connect.content import ContentItem
from posit.connect.content import ContentItem, ContentItemOwner
from posit.connect.permissions import Permissions

from .api import load_mock # type: ignore


class TestContentOwnerAttributes:
@classmethod
def setup_class(cls):
guid = "20a79ce3-6e87-4522-9faf-be24228800a4"
config = Config(api_key="12345", url="https://connect.example/")
session = requests.Session()
fake_item = load_mock(f"v1/users/{guid}.json")
cls.item = ContentItemOwner(config, session, **fake_item)

def test_guid(self):
assert self.item.guid == "20a79ce3-6e87-4522-9faf-be24228800a4"

def test_username(self):
assert self.item.username == "carlos12"

def test_first_name(self):
assert self.item.first_name == "Carlos"

def test_last_name(self):
assert self.item.last_name == "User"


class TestContentItemAttributes:
@classmethod
def setup_class(cls):
Expand Down Expand Up @@ -138,7 +160,7 @@ def test_run_as_current_user(self):
assert self.item.run_as_current_user is False

def test_owner_guid(self):
assert self.item.owner_guid == "87c12c08-11cd-4de1-8da3-12a7579c4998"
assert self.item.owner_guid == "20a79ce3-6e87-4522-9faf-be24228800a4"

def test_content_url(self):
assert (
Expand All @@ -156,7 +178,7 @@ def test_app_role(self):
assert self.item.app_role == "viewer"

def test_owner(self):
assert self.item.owner == {}
assert "owner" not in self.item

def test_permissions(self):
assert isinstance(self.item.permissions, Permissions)
Expand All @@ -165,6 +187,35 @@ def test_tags(self):
assert self.item.tags == []


class TestContentItemGetContentOwner:
@responses.activate
def test_owner(self):
mock_content = load_mock(
"v1/content/f2f37341-e21d-3d80-c698-a935ad614066.json"
)
responses.get(
"https://connect.example/__api__/v1/content/f2f37341-e21d-3d80-c698-a935ad614066",
json=mock_content,
)

mock_user_get = responses.get(
f"https://connect.example/__api__/v1/users/20a79ce3-6e87-4522-9faf-be24228800a4",
json=load_mock(
f"v1/users/20a79ce3-6e87-4522-9faf-be24228800a4.json"
),
)

c = Client("12345", "https://connect.example")
item = c.content.get("f2f37341-e21d-3d80-c698-a935ad614066")
owner = item.owner
assert owner.guid == "20a79ce3-6e87-4522-9faf-be24228800a4"

# load a second time, assert tha owner is loaded from cached result
owner = item.owner
assert owner.guid == "20a79ce3-6e87-4522-9faf-be24228800a4"
assert mock_user_get.call_count == 1


class TestContentItemDelete:
@responses.activate
def test(self):
Expand Down

0 comments on commit 22e38c7

Please sign in to comment.