Skip to content

Commit

Permalink
refactor Tags and add test_tags
Browse files Browse the repository at this point in the history
  • Loading branch information
flashdagger committed Oct 20, 2023
1 parent eda56a7 commit 8252cfc
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 29 deletions.
1 change: 1 addition & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ future release
* for all ResourcesT like :class:`tickets.Tickets` ``.url`` is now a property
* exchange ``tickets.Ticket.merge_with()`` with :meth:`tickets.Ticket.merge_into`
mimicking the logic provided by the Web UI
* :meth:`tags.Tags.delete()` and :meth:`tags.Tags.delete()` now only accept the tag name

* **fixes**

Expand Down
39 changes: 24 additions & 15 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ def pytest_addoption(parser):
default=False,
help="run the tests against a zammad server instance and record the responses",
)
parser.addoption(
"--record-missing",
action="store_true",
default=False,
help="run tests without logfile against a zammad server instance and record the responses",
)
parser.addoption(
"--client-url", default="https://localhost/api/v1", help="the zammad server url"
)
Expand All @@ -42,20 +48,6 @@ def initialize(self):
return patch.object(Resource, "_initialize", new=initialize)


@pytest.fixture(scope="session")
def client(request) -> Client:
client_url = request.config.getoption("--client-url")
http_token = request.config.getoption("--http-token")

if os.path.exists(http_token):
with open(http_token, encoding="utf-8") as fd:
http_token = fd.read()

client = Client(client_url, http_token=http_token)
client.session.verify = "mylocalhost.crt"
return client


class FileWriter:
def __init__(self, path: Path) -> None:
self.fd = open(path, "ab")
Expand Down Expand Up @@ -103,13 +95,30 @@ def close(self) -> None:
self.fd.close()


@pytest.fixture(scope="function")
def client(request) -> Client:
client_url = request.config.getoption("--client-url")
http_token = request.config.getoption("--http-token")

if os.path.exists(http_token):
with open(http_token, encoding="utf-8") as fd:
http_token = fd.read()

client = Client(client_url, http_token=http_token)
client.session.verify = "mylocalhost.crt"
return client


@pytest.fixture(scope="function")
def rclient(request: pytest.FixtureRequest, client) -> Generator[Client, None, None]:
session_request = Session.request
recording = request.config.getoption("--record")
missing_only = request.config.getoption("--record-missing")
recording = missing_only or request.config.getoption("--record")

rpath = request.path
record_file = rpath.with_name(rpath.stem) / f"{request.function.__name__}.log"
if recording and missing_only and record_file.is_file():
recording = False

def serialize(method: str, url: str, params: Dict[str, Any]) -> str:
param_items = params.items() if isinstance(params, dict) else params or ()
Expand Down
53 changes: 53 additions & 0 deletions tests/test_tags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from contextlib import suppress

import pytest

from zammadoo.utils import TypedTag


def test_representation_of_tags(request, client):
client_url = request.config.getoption("--client-url")
assert repr(client.tags) == f"<Tags '{client_url}/tag_list'>"


def test_tag_iteration(rclient):
for tag in rclient.tags:
assert tag.keys() == TypedTag.__required_keys__
break


def test_mutable_tag_operations(rclient):
tag_name = "__pytest__"
new_tag_name = "__pytest_new__"
tags = rclient.tags

# make sure tag does not exist
with suppress(KeyError):
tags.delete(tag_name)
with suppress(KeyError):
tags.delete(new_tag_name)

assert tag_name not in tags

with pytest.raises(KeyError, match=tag_name):
tags.delete(tag_name)

tags.create(tag_name)
assert tag_name in tags
tag_info = tags[tag_name]
assert tag_info["name"] == tag_name
assert tag_info["count"] == 0

assert tag_name in tags.search(tag_name)

tags.cache.clear()
tags.rename(tag_name, new_tag_name)
assert new_tag_name in tags
assert tag_name not in tags

tags.cache.clear()
assert tag_info["id"] == tags[new_tag_name]["id"]

tags.delete(new_tag_name)
Binary file added tests/test_tags/test_mutable_tag_operations.log
Binary file not shown.
Binary file added tests/test_tags/test_tag_iteration.log
Binary file not shown.
33 changes: 19 additions & 14 deletions zammadoo/tags.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from typing import TYPE_CHECKING, Dict, Iterator, List, Union
from typing import TYPE_CHECKING, Dict, Iterator, List

from .utils import TypedTag, info_cast

Expand Down Expand Up @@ -59,35 +59,40 @@ def create(self, name: str) -> None:
"""
creates a new tag (admin only), if name already exists, it is ignored
"""
cache = self.cache
if name not in cache:
cache.clear()
self.client.post(self.endpoint, json={"name": name})

def delete(self, name_or_tid: Union[str, int]) -> None:
def delete(self, name: str) -> None:
"""
deletes an existing tag (admin only)
:param name_or_tid: the name or tag id
:raises: :class:`KeyError` or :class:`zammadoo.client.APIException` if not found
:param name: tag name
:raises: :class:`KeyError` if not found
"""
cache = self.cache
if not cache:
self.reload()
if isinstance(name_or_tid, str):
name_or_tid = cache[name_or_tid]["id"]
self.client.delete(self.endpoint, name_or_tid)
self.client.delete(self.endpoint, cache.pop(name)["id"])

def rename(self, name: str, new_name: str) -> None:
"""
rename an existing tag (admin only)
def rename(self, name_or_tid: Union[str, int], new_name: str) -> None:
"""rename an existing tag (admin only)
if the new name already exists, the current name will be deleted
:param name_or_tid: the name or tag id
:param name: the current name
:param new_name: new name
:raises: :class:`KeyError` or :class:`client.APIException` if not found
:raises: :class:`KeyError` if not found
"""
cache = self.cache
if not cache:
self.reload()
if isinstance(name_or_tid, str):
name_or_tid = cache[name_or_tid]["id"]
self.client.put(self.endpoint, name_or_tid, json={"name": new_name})

tag = cache[new_name] = cache.pop(name)
tag["name"] = new_name
self.client.put(self.endpoint, tag["id"], json={"name": new_name})

def add_to_ticket(self, tid: int, *names: str) -> None:
"""
Expand Down

0 comments on commit 8252cfc

Please sign in to comment.