Skip to content

Commit

Permalink
Added the attributes extension
Browse files Browse the repository at this point in the history
  • Loading branch information
crazyscientist committed Oct 24, 2023
1 parent db52e6e commit b9bc537
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 1 deletion.
3 changes: 3 additions & 0 deletions doc/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ Core
Extensions
----------

.. automodule:: osctiny.extensions.attributes
:members:

.. automodule:: osctiny.extensions.buildresults
:members:

Expand Down
73 changes: 73 additions & 0 deletions osctiny/extensions/attributes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"""
Attributes extension
--------------------
.. versionadded:: 0.8.0
"""
import typing
from urllib.parse import urljoin

from lxml.objectify import ObjectifiedElement

from ..utils.base import ExtensionBase


class Attribute(ExtensionBase):
"""
Access attribute namespaces and definitions
"""
base_path = "/attribute/"

def list_namespaces(self) -> typing.List[str]:
"""
Get a list of all namespaces
:return: List of namespace names
"""
response = self.osc.request(
url=urljoin(self.osc.url, self.base_path),
method="GET"
)
content = self.osc.get_objectified_xml(response)
return [entry.get("name") for entry in content.findall("entry")]

def get_namespace_meta(self, namespace: str) -> ObjectifiedElement:
"""
Get the meta of the namespace
:param namespace: namespace name
:return: Objectified XML element
"""
response = self.osc.request(
url=urljoin(self.osc.url, f"{self.base_path}{namespace}/_meta"),
method="GET"
)
return self.osc.get_objectified_xml(response)

def list_attributes(self, namespace: str) -> typing.List[str]:
"""
List the attributes available in namespace
:param namespace: Namespace name
:return: List of attribute names
"""
response = self.osc.request(
url=urljoin(self.osc.url, self.base_path + namespace),
method="GET"
)
content = self.osc.get_objectified_xml(response)
return [entry.get("name") for entry in content.findall("entry")]

def get_attribute_meta(self, namespace: str, name: str) -> ObjectifiedElement:
"""
Get meta data for attribute
:param namespace: Namespace name
:param name: Attribute name
:return: Objectified XML element
"""
response = self.osc.request(
url=urljoin(self.osc.url, f"{self.base_path}{namespace}/{name}/_meta"),
method="GET"
)
return self.osc.get_objectified_xml(response)
7 changes: 6 additions & 1 deletion osctiny/osc.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from requests.cookies import RequestsCookieJar, cookiejar_from_dict
from requests.exceptions import ConnectionError as _ConnectionError

from .extensions.attributes import Attribute
from .extensions.buildresults import Build
from .extensions.comments import Comment
from .extensions.distributions import Distribution
Expand Down Expand Up @@ -85,6 +86,8 @@ class Osc:
- :py:attr:`distributions`
* - :py:class:`osctiny.extensions.origin.Origin`
- :py:attr:`origins`
* - :py:class:`osctiny.extensions.attributes.Attribute`
- :py:attr:`attributes`
:param url: API URL of a BuildService instance
:param username: Username
Expand Down Expand Up @@ -117,7 +120,8 @@ class Osc:
meaning of the ``password`` parameter
.. versionchanged:: 0.8.0
Removed the ``cache`` parameter
* Removed the ``cache`` parameter
* Added the ``attributes`` extensions
.. _SSL Cert Verification:
http://docs.python-requests.org/en/master/user/advanced/
Expand Down Expand Up @@ -149,6 +153,7 @@ def __init__(self, url: typing.Optional[str] = None, username: typing.Optional[s
raise OscError from error

# API endpoints
self.attributes = Attribute(osc_obj=self)
self.build = Build(osc_obj=self)
self.comments = Comment(osc_obj=self)
self.distributions = Distribution(osc_obj=self)
Expand Down
52 changes: 52 additions & 0 deletions osctiny/tests/test_attributes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import responses

from .base import OscTest


class TestAttribute(OscTest):
def setUp(self):
super().setUp()

self.mock_request(
method=responses.GET,
url=self.osc.url + '/attribute/',
body="<directory><entry name='Foo'/><entry name='Bar'/></directory>"
)

self.mock_request(
method=responses.GET,
url=self.osc.url + '/attribute/Foo/_meta',
body="<namespace name='Foo'><modifiable_by user='A'/></namespace>"
)

self.mock_request(
method=responses.GET,
url=self.osc.url + '/attribute/Foo',
body="<directory><entry name='Hello'/><entry name='World'/></directory>"
)

self.mock_request(
method=responses.GET,
url=self.osc.url + '/attribute/Foo/Hello/_meta',
body="<definition name='Hello' namespace='Foo'><description>Lorem ipsum</description>"
"<count>1</count><modifiable_by role='B'/></definition>"
)

@responses.activate
def test_list_namespace(self):
self.assertEqual(["Foo", "Bar"], self.osc.attributes.list_namespaces())

@responses.activate
def test_get_namespace_meta(self):
meta = self.osc.attributes.get_namespace_meta("Foo")
self.assertEqual(meta.get("name"), "Foo")

@responses.activate
def test_list_attributes(self):
self.assertEqual(["Hello", "World"], self.osc.attributes.list_attributes("Foo"))

@responses.activate
def test_get_attribute_meta(self):
meta = self.osc.attributes.get_attribute_meta("Foo", "Hello")
self.assertEqual(meta.get("name"), "Hello")
self.assertEqual(meta.get("namespace"), "Foo")

0 comments on commit b9bc537

Please sign in to comment.