Commit 1b8e0807 authored by VOISIN Thomas's avatar VOISIN Thomas
Browse files

URL refactor and deeper UTest on get_history_by_user

parent 9c5c05ab
import json
from django.contrib.auth.decorators import login_required
from django.core import serializers
from django.http import Http404
from django.db.models import CharField
from django.db.models import Value
from django.http import JsonResponse
from .models import HistoryLine
from .models import Note
@login_required
def get_history_by_user(request):
try:
notes = Note.objects.filter(mail=request.user.email)
if not notes:
raise Http404
result = []
for note in notes:
result.extend(
obj["fields"]
for obj in json.loads(
serializers.serialize("json", HistoryLine.objects.filter(note_id=note.foreign_id).annotate(
nick=Value(note.nickname, output_field=CharField())
)))
)
return JsonResponse(result, safe=False)
except Exception:
raise Http404 from None
import json
from datetime import datetime from datetime import datetime
from decimal import Decimal from decimal import Decimal
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.http import JsonResponse
from django.test import Client from django.test import Client
from django.test import TestCase from django.test import TestCase
from django.utils import timezone from django.utils import timezone
...@@ -16,25 +18,25 @@ class TestEnibarImport(TestCase): ...@@ -16,25 +18,25 @@ class TestEnibarImport(TestCase):
super().setUp() super().setUp()
def test_note_import_404(self): def test_note_import_404(self):
response = self.client.options("/enibar/note/", "{}") response = self.client.options("/enibar/api/note/", "{}")
self.assertEqual(response.status_code, 404) self.assertEqual(response.status_code, 404)
response = self.client.put("/enibar/note", "pouet") response = self.client.put("/enibar/api/note", "pouet")
self.assertEqual(response.status_code, 404) self.assertEqual(response.status_code, 404)
def test_note_put_403(self): def test_note_put_403(self):
response = self.client.put( response = self.client.put(
"/enibar/note", "/enibar/api/note",
'{"id": 1, "nickname": "coucou", "mail": "test@test.fr", "note": 52.2}', '{"id": 1, "nickname": "coucou", "mail": "test@test.fr", "note": 52.2}',
) )
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 403)
def test_note_delete_403(self): def test_note_delete_403(self):
response = self.client.delete("/enibar/note", '{"id": 2}') response = self.client.delete("/enibar/api/note", '{"id": 2}')
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 403)
def test_import_note_put(self): def test_import_note_put(self):
response = self.client.put( response = self.client.put(
"/enibar/note", "/enibar/api/note",
'{"token": "changeme", "id": 1, "nickname": "coucou", "mail": "test@test.fr", "note": 52.2}', '{"token": "changeme", "id": 1, "nickname": "coucou", "mail": "test@test.fr", "note": 52.2}',
) )
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
...@@ -44,7 +46,7 @@ class TestEnibarImport(TestCase): ...@@ -44,7 +46,7 @@ class TestEnibarImport(TestCase):
self.assertEqual(note.mail, "test@test.fr") self.assertEqual(note.mail, "test@test.fr")
self.assertEqual(note.note, Decimal("52.2")) self.assertEqual(note.note, Decimal("52.2"))
response = self.client.put( response = self.client.put(
"/enibar/note", "/enibar/api/note",
'{"token": "changeme", "id": 1, "nickname": "coucou", "mail": "test@test.fr", "note": 50.2}', '{"token": "changeme", "id": 1, "nickname": "coucou", "mail": "test@test.fr", "note": 50.2}',
) )
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
...@@ -58,7 +60,7 @@ class TestEnibarImport(TestCase): ...@@ -58,7 +60,7 @@ class TestEnibarImport(TestCase):
Note.objects.create( Note.objects.create(
foreign_id=2, nickname="toto", mail="coucou@test.fr", note=Decimal("10") foreign_id=2, nickname="toto", mail="coucou@test.fr", note=Decimal("10")
) )
response = self.client.delete("/enibar/note", '{"token": "changeme", "id": 2}') response = self.client.delete("/enibar/api/note", '{"token": "changeme", "id": 2}')
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
with self.assertRaises(Note.DoesNotExist): with self.assertRaises(Note.DoesNotExist):
Note.objects.get(foreign_id=2) Note.objects.get(foreign_id=2)
...@@ -71,7 +73,7 @@ class TestEnibarImport(TestCase): ...@@ -71,7 +73,7 @@ class TestEnibarImport(TestCase):
foreign_id=3, nickname="toto2", mail="cou@test.com", note=Decimal("11") foreign_id=3, nickname="toto2", mail="cou@test.com", note=Decimal("11")
) )
response = self.client.get("/enibar/note") response = self.client.get("/enibar/api/note")
self.assertEqual( self.assertEqual(
response.json(), response.json(),
[ [
...@@ -89,7 +91,7 @@ class TestEnibarImport(TestCase): ...@@ -89,7 +91,7 @@ class TestEnibarImport(TestCase):
}, },
], ],
) )
response = self.client.get("/enibar/note", {"foreign_id": 2}) response = self.client.get("/enibar/api/note", {"foreign_id": 2})
self.assertEqual( self.assertEqual(
response.json(), response.json(),
[ [
...@@ -101,7 +103,7 @@ class TestEnibarImport(TestCase): ...@@ -101,7 +103,7 @@ class TestEnibarImport(TestCase):
} }
], ],
) )
response = self.client.get("/enibar/note", {"pouet": 2}) response = self.client.get("/enibar/api/note", {"pouet": 2})
self.assertEqual(response.status_code, 404) self.assertEqual(response.status_code, 404)
...@@ -176,12 +178,17 @@ class TestHistoryByUser(TestCase): ...@@ -176,12 +178,17 @@ class TestHistoryByUser(TestCase):
def test_all(self) -> None: def test_all(self) -> None:
"""Tests the request getting all history lines of all notes""" """Tests the request getting all history lines of all notes"""
url = "/enibar/api/history" url = "/enibar/api/history-by-user"
response = self.client.get(url) response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIsInstance(response, JsonResponse)
self.assertNotContains(response, self.note_autre.nickname) self.assertNotContains(response, self.note_autre.nickname)
self.assertContains(response, "Produit", count=120) self.assertIsInstance(json.loads(response.content), list)
self.assertEqual(len(json.loads(response.content)), 120)
assert all(isinstance(value, dict) and all(field.name in value.keys() for field in HistoryLine._meta.get_fields())
for value in json.loads(response.content))
self.assertContains(response, self.note1.nickname) self.assertContains(response, self.note1.nickname)
self.assertContains(response, self.note2.nickname) self.assertContains(response, self.note2.nickname)
...@@ -363,6 +370,6 @@ class TestHistoryView(TestCase): ...@@ -363,6 +370,6 @@ class TestHistoryView(TestCase):
class TestGetPhotoPaths(TestCase): class TestGetPhotoPaths(TestCase):
def test_last_update_in_dst_change(self): def test_last_update_in_dst_change(self):
"""Regression test for #43""" """Regression test for #43"""
resp = self.client.get("/enibar/photos?last_updated=2020-10-25T02%3A00%3A01") resp = self.client.get("/enibar/api/photos?last_updated=2020-10-25T02%3A00%3A01")
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
from django.urls import path, include from django.urls import path, include
from . import views from . import views
from . import backend
app_name = "enibar" app_name = "enibar"
urlpatterns = [ urlpatterns = [
path("note", views.request_note, name="request_note"),
path("photos", views.get_photo_paths, name="photo_paths"),
path("history", views.request_history, name="request_history"),
path("show_history/", views.show_history, {"page": 1}, name="show_history"), path("show_history/", views.show_history, {"page": 1}, name="show_history"),
path("show_history/<int:page>", views.show_history, name="show_history"), path("show_history/<int:page>", views.show_history, name="show_history"),
path( path(
...@@ -16,6 +12,9 @@ urlpatterns = [ ...@@ -16,6 +12,9 @@ urlpatterns = [
name="show_history", name="show_history",
), ),
path('api/', include([ path('api/', include([
path("history", backend.get_history_by_user, name="get_history") path("note", views.request_note, name="request_note"),
path("photos", views.get_photo_paths, name="photo_paths"),
path("history", views.request_history, name="request_history"),
path("history-by-user", views.get_history_by_user, name="get_history_by_user")
])), ])),
] ]
...@@ -21,6 +21,7 @@ from django.http import JsonResponse ...@@ -21,6 +21,7 @@ from django.http import JsonResponse
from django.shortcuts import render from django.shortcuts import render
from django.utils import timezone from django.utils import timezone
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from .models import HistoryLine from .models import HistoryLine
from .models import Note from .models import Note
...@@ -132,7 +133,8 @@ def get_photo_paths(request: HttpRequest) -> JsonResponse: ...@@ -132,7 +133,8 @@ def get_photo_paths(request: HttpRequest) -> JsonResponse:
last_updated_in = request.GET.get("last_updated") last_updated_in = request.GET.get("last_updated")
if last_updated_in is not None: if last_updated_in is not None:
last_updated = datetime.datetime.strptime(last_updated_in, "%Y-%m-%dT%H:%M:%S") last_updated = datetime.datetime.strptime(last_updated_in, "%Y-%m-%dT%H:%M:%S")
last_updated = timezone.make_aware(last_updated, timezone=None, is_dst=True) # Make TZ aware avoiding DST by fetching more last_updated = timezone.make_aware(last_updated, timezone=None,
is_dst=True) # Make TZ aware avoiding DST by fetching more
users = User.objects.filter( users = User.objects.filter(
profile__last_updated__gt=last_updated profile__last_updated__gt=last_updated
).select_related("profile") ).select_related("profile")
...@@ -145,3 +147,20 @@ def get_photo_paths(request: HttpRequest) -> JsonResponse: ...@@ -145,3 +147,20 @@ def get_photo_paths(request: HttpRequest) -> JsonResponse:
} }
return JsonResponse(photos, safe=False) return JsonResponse(photos, safe=False)
@login_required
@require_http_methods(["GET"])
def get_history_by_user(request: HttpRequest) -> JsonResponse:
"""API GET method for getting all user's history lines"""
try:
notes = Note.objects.filter(mail=request.user.email) # type: ignore[union-attr] # login is required
if not notes:
raise Http404
result: List[dict] = []
for note in notes:
result.extend(HistoryLine.objects.filter(note_id=note.foreign_id)
.annotate(nick=Value(note.nickname, output_field=CharField())).values())
return JsonResponse(result, safe=False)
except Exception:
raise Http404 from None
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment