From 2d3dafbacc35b68820def33e5c408dd28aeb19de Mon Sep 17 00:00:00 2001 From: Daniel Bauer Date: Fri, 1 Nov 2024 13:02:56 +0100 Subject: [PATCH] use signposting package --- django_signposting/middleware.py | 17 ++++++------- django_signposting/utils.py | 20 ++++++--------- pyproject.toml | 1 + tests/test_middleware.py | 37 +++++++++++++-------------- tests/test_utils.py | 43 +++++++++++++------------------- 5 files changed, 50 insertions(+), 68 deletions(-) diff --git a/django_signposting/middleware.py b/django_signposting/middleware.py index 27fed75..41b6f48 100644 --- a/django_signposting/middleware.py +++ b/django_signposting/middleware.py @@ -1,5 +1,6 @@ from typing import Callable from django.http import HttpRequest, HttpResponse +from signposting import Signpost class SignpostingMiddleware: @@ -21,20 +22,18 @@ class SignpostingMiddleware: return response - def _add_signposts(self, response: HttpResponse, typed_links: dict[str, list[str|tuple[str, str]]]): + def _add_signposts(self, response: HttpResponse, signposts: list[Signpost]): """ Adds signposting headers to the respones. params: response - the response object - typed_links - a map of relation types to a list of corresponding links. Each link can be a link or a tuple of link and media type. + signposts - a list of Signposts """ + link_snippets = [] - for relation_type in typed_links.keys(): - links = typed_links.get(relation_type, []) - for link in links: - if isinstance(link, tuple) and len(link) > 1: - link_snippets.append(f'<{link[0]}> ; rel="{relation_type}" ; type="{link[1]}"') - else: - link_snippets.append(f'<{link}> ; rel="{relation_type}"') + for signpost in signposts: + link_snippets.append(f'<{signpost.target}> ; rel="{signpost.rel}"') + if signpost.type: + link_snippets[-1] += f' ; type="{signpost.type}"' response["Link"] = " , ".join(link_snippets) diff --git a/django_signposting/utils.py b/django_signposting/utils.py index 31b2110..955728d 100644 --- a/django_signposting/utils.py +++ b/django_signposting/utils.py @@ -1,23 +1,17 @@ from django.http import HttpResponse +from signposting import Signpost -def add_signposts(response: HttpResponse, **kwargs): +def add_signposts(response: HttpResponse, *args: Signpost): """ Adds signposting headers to the responses. params: response - the response object - kwargs - a map of relation types to a list of corresponding links. Each link can be a link or a tuple of link and media type. + args - a list of signposts to add to this resposnse. """ if not hasattr(response, '_signposts'): - response._signposts = {} + response._signposts = [] - for key in kwargs.keys(): - - values = kwargs[key] - if isinstance(values, str) or isinstance(values, tuple): - values = [values] - - if key not in response._signposts: - response._signposts[key] = values - else: - response._signposts[key] += values \ No newline at end of file + for signpost in args: + if not signpost in response._signposts: + response._signposts.append(signpost) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 0cf492e..2a98f4a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ readme = "README.md" requires-python = ">=3.10" dependencies = [ "Django>=3.0", + "signposting>=0.9.9", ] [project.urls] diff --git a/tests/test_middleware.py b/tests/test_middleware.py index bf07c1e..b2a1fa2 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -1,6 +1,7 @@ +from re import A from django.http import HttpResponse from django_signposting.middleware import SignpostingMiddleware - +from signposting import LinkRel, Signpost def test_middleware_no_signposting(): response = HttpResponse() @@ -14,7 +15,9 @@ def test_middleware_no_signposting(): def test_middleware_signposting(): response = HttpResponse() response.status_code = 200 - response._signposts = {"author": ["http://example.com"]} + response._signposts = [ + Signpost(LinkRel.author, "http://example.com") + ] middleware = SignpostingMiddleware(lambda request: response) response = middleware(None) @@ -24,15 +27,11 @@ def test_middleware_signposting(): def test_middleware_multiple_signposts(): response = HttpResponse() response.status_code = 200 - response._signposts = { - "author": [ - "http://example.com", - "http://example2.com" - ], - "cite-as": [ - "http://example3.com" - ] - } + response._signposts = [ + Signpost(LinkRel.author, "http://example.com"), + Signpost(LinkRel.author, "http://example2.com"), + Signpost(LinkRel.cite_as, "http://example3.com"), + ] middleware = SignpostingMiddleware(lambda request: response) response = middleware(None) @@ -45,23 +44,21 @@ def test_middleware_multiple_signposts(): def test_middleware_signpost_with_content_type(): response = HttpResponse() response.status_code = 200 - response._signposts = { - "item": [ - ("http://example.com", "test/json"), - ] - } + response._signposts = [ + Signpost(LinkRel.item, "http://example.com", "text/json") + ] middleware = SignpostingMiddleware(lambda request: response) response = middleware(None) - assert response.headers["Link"] == ' ; rel="item" ; type="test/json"' + assert response.headers["Link"] == ' ; rel="item" ; type="text/json"' def test_middleware_ignore_error_responses(): response = HttpResponse() response.status_code = 400 - response._signposts = { - "author": ["https://example.com"] - } + response._signposts = [ + Signpost(LinkRel.author, "http://example.com") + ] middleware = SignpostingMiddleware(lambda request: response) response = middleware(None) diff --git a/tests/test_utils.py b/tests/test_utils.py index f11e8a6..da254fd 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,47 +1,38 @@ from django.http import HttpResponse from django_signposting.utils import add_signposts +from signposting import Signpost, LinkRel def test_add_signpost(): response = HttpResponse() - add_signposts(response, item="http://example.com") + add_signposts(response, Signpost(LinkRel.item,"http://example.com")) - assert response._signposts["item"] == ["http://example.com"] + assert len(response._signposts) == 1 def test_add_multiple_signposts(): response = HttpResponse() add_signposts(response, - item="http://example.com", - author=["https://example2.com", "https://example3.com"] + Signpost(LinkRel.item, "http://example.com"), + Signpost(LinkRel.author, "https://example2.com"), + Signpost(LinkRel.author, "https://example3.com"), ) - assert response._signposts == { - "item": ["http://example.com"], - "author": [ - "https://example2.com", - "https://example3.com", - ] - } + + assert len(response._signposts) == 3 -def test_add_signposts_with_content_type(): +def test_add_signpost_call_multiple_times(): response = HttpResponse() - add_signposts(response, - item=("http://example.com", "text/json"), - author=["https://example2.com", "https://example3.com"] - ) + add_signposts(response, Signpost(LinkRel.item, "http://example.com")) + add_signposts(response, Signpost(LinkRel.item, "http://example2.com")) - assert response._signposts == { - "item": [("http://example.com", "text/json")], - "author": [ - "https://example2.com", - "https://example3.com", - ] - } + assert len(response._signposts) == 2 -def test_add_signposts_from_dict(): +def test_add_signpost_duplicate(): response = HttpResponse() - add_signposts(response, **{"cite-as": ["https://example.com"]}) - assert response._signposts["cite-as"] == ["https://example.com"] + add_signposts(response, Signpost(LinkRel.item, "http://example.com")) + add_signposts(response, Signpost(LinkRel.item, "http://example.com")) + + assert len(response._signposts) == 1 \ No newline at end of file