loko/streetup/documents/tests.py

749 lines
No EOL
31 KiB
Python

from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase
from django.urls import reverse
from common.models import Role, UserConfig
from interventions.models import Intervention
from projects.models import Project
from .models import DocumentAttachment, DocumentFolder, DocumentFolderShare, DocumentShare, ManagedDocument
from .views import ensure_document_deletable
from .permissions import (
filter_documents_for_user,
filter_folders_for_user,
get_user_visible_folder_ids,
user_has_document_permission,
)
User = get_user_model()
class DocumentPermissionTests(TestCase):
def setUp(self):
self.owner = User.objects.create_user(username="owner", password="owner")
self.shared_user = User.objects.create_user(username="shared", password="shared")
self.folder_user = User.objects.create_user(username="folder", password="folder")
self.other_user = User.objects.create_user(username="other", password="other")
self.superuser = User.objects.create_superuser(username="admin", password="admin")
self.document = ManagedDocument.objects.create(title="Doc", created_by=self.owner)
self.folder = DocumentFolder.objects.create(
name="Folder", slug="folder", created_by=self.owner
)
self.parent_folder = DocumentFolder.objects.create(
name="Parent", slug="parent-folder", created_by=self.owner
)
self.folder.parent_folders.add(self.parent_folder)
self.document.folders.add(self.folder)
DocumentShare.objects.create(
document=self.document,
user=self.shared_user,
permission=ManagedDocument.PERMISSION_COMMENT,
)
DocumentFolderShare.objects.create(
folder=self.folder,
user=self.folder_user,
permission=ManagedDocument.PERMISSION_VIEW,
)
def test_owner_has_full_access(self):
self.assertTrue(user_has_document_permission(self.owner, self.document))
self.assertTrue(
user_has_document_permission(
self.owner,
self.document,
required_permission=ManagedDocument.PERMISSION_APPROVE,
)
)
def test_share_permission_respected(self):
self.assertTrue(user_has_document_permission(self.shared_user, self.document))
self.assertFalse(
user_has_document_permission(
self.shared_user,
self.document,
required_permission=ManagedDocument.PERMISSION_EDIT,
)
)
def test_folder_share_grants_access(self):
self.assertTrue(user_has_document_permission(self.folder_user, self.document))
def test_superuser_has_access(self):
self.assertTrue(user_has_document_permission(self.superuser, self.document))
def test_anonymous_user_has_no_access(self):
self.assertFalse(user_has_document_permission(AnonymousUser(), self.document))
def test_filter_documents_for_user(self):
queryset = ManagedDocument.objects.order_by("pk")
shared_ids = set(filter_documents_for_user(queryset, self.shared_user).values_list("pk", flat=True))
folder_ids = set(filter_documents_for_user(queryset, self.folder_user).values_list("pk", flat=True))
other_ids = set(filter_documents_for_user(queryset, self.other_user).values_list("pk", flat=True))
self.assertEqual(shared_ids, {self.document.pk})
self.assertEqual(folder_ids, {self.document.pk})
self.assertEqual(other_ids, set())
def test_filter_documents_for_superuser_returns_all(self):
queryset = ManagedDocument.objects.order_by("pk")
filtered = filter_documents_for_user(queryset, self.superuser)
self.assertEqual(set(filtered.values_list("pk", flat=True)), set(queryset.values_list("pk", flat=True)))
def test_filter_folders_for_user(self):
queryset = DocumentFolder.objects.order_by("pk")
owner_ids = set(filter_folders_for_user(queryset, self.owner).values_list("pk", flat=True))
shared_ids = set(filter_folders_for_user(queryset, self.folder_user).values_list("pk", flat=True))
other_ids = set(filter_folders_for_user(queryset, self.other_user).values_list("pk", flat=True))
self.assertIn(self.folder.pk, owner_ids)
self.assertIn(self.folder.pk, shared_ids)
self.assertEqual(other_ids, set())
def test_visible_folder_ids_include_ancestors(self):
visible = get_user_visible_folder_ids(self.folder_user)
self.assertIn(self.folder.pk, visible)
self.assertIn(self.parent_folder.pk, visible)
class DocumentListViewTests(TestCase):
def setUp(self):
self.user = User.objects.create_user(username="viewer", password="viewer")
UserConfig.objects.create(user=self.user, is_intern=True)
self.client.force_login(self.user)
self.parent = DocumentFolder.objects.create(
name="Parent", slug="parent", created_by=self.user
)
self.child = DocumentFolder.objects.create(
name="Child", slug="child", created_by=self.user
)
self.grandchild = DocumentFolder.objects.create(
name="Grandchild", slug="grandchild", created_by=self.user
)
self.child.parent_folders.add(self.parent)
self.grandchild.parent_folders.add(self.child)
self.parent_doc = ManagedDocument.objects.create(
title="Parent document",
created_by=self.user,
)
self.parent_doc.folders.add(self.parent)
self.child_doc = ManagedDocument.objects.create(
title="Child note",
created_by=self.user,
)
self.child_doc.folders.add(self.child)
self.grandchild_doc = ManagedDocument.objects.create(
title="Grand strategy",
created_by=self.user,
)
self.grandchild_doc.folders.add(self.grandchild)
self.outside_folder = DocumentFolder.objects.create(name="External", slug="external")
self.outside_doc = ManagedDocument.objects.create(
title="Grand outside",
created_by=self.user,
)
self.outside_doc.folders.add(self.outside_folder)
def test_folder_filter_only_includes_direct_documents(self):
response = self.client.get(reverse("documents:list"), {"folder": self.parent.slug})
self.assertEqual(response.status_code, 200)
documents = list(response.context["documents"])
document_ids = {document.pk for document in documents}
self.assertSetEqual(
document_ids,
{self.parent_doc.pk},
)
self.assertNotIn(self.outside_doc.pk, document_ids)
def test_search_returns_descendant_folders(self):
response = self.client.get(
reverse("documents:list"),
{"folder": self.parent.slug, "search": "Grand"},
)
self.assertEqual(response.status_code, 200)
visible_folders = response.context["visible_folders"]
self.assertIn(self.grandchild, visible_folders)
self.assertNotIn(self.outside_folder, visible_folders)
self.assertNotIn(self.child, visible_folders)
listing_items = response.context["listing_items"]
self.assertTrue(
any(
item["type"] == "folder" and item["object"].pk == self.grandchild.pk
for item in listing_items
)
)
def test_search_limits_documents_to_folder_descendants(self):
response = self.client.get(
reverse("documents:list"),
{"folder": self.parent.slug, "search": "Grand"},
)
self.assertEqual(response.status_code, 200)
documents = list(response.context["documents"])
document_ids = {document.pk for document in documents}
self.assertSetEqual(document_ids, {self.grandchild_doc.pk})
self.assertNotIn(self.outside_doc.pk, document_ids)
class DocumentFolderManagementTests(TestCase):
def setUp(self):
self.owner = User.objects.create_user(username="folder-owner", password="owner")
UserConfig.objects.create(user=self.owner, is_intern=True)
self.other = User.objects.create_user(username="folder-other", password="other")
UserConfig.objects.create(user=self.other, is_intern=True)
self.admin = User.objects.create_user(username="folder-admin", password="admin")
admin_role, _ = Role.objects.get_or_create(name="admin")
admin_config = UserConfig.objects.create(user=self.admin, is_intern=True)
admin_config.roles.add(admin_role)
self.folder = DocumentFolder.objects.create(
name="Root",
slug="root",
created_by=self.owner,
)
def test_owner_can_update_folder(self):
self.client.force_login(self.owner)
response = self.client.post(
reverse("documents:folder_edit", args=[self.folder.pk]),
{
"name": "Updated",
"description": "",
"application_label": "",
"parent_folders": [],
},
)
self.assertRedirects(response, f"{reverse('documents:list')}?folder={self.folder.slug}")
self.folder.refresh_from_db()
self.assertEqual(self.folder.name, "Updated")
self.assertEqual(self.folder.created_by, self.owner)
def test_non_owner_cannot_update_folder(self):
self.client.force_login(self.other)
response = self.client.post(
reverse("documents:folder_edit", args=[self.folder.pk]),
{
"name": "Blocked",
"description": "",
"application_label": "",
"parent_folders": [],
},
)
self.assertEqual(response.status_code, 403)
def test_predefined_folder_cannot_be_modified(self):
self.folder.is_predefined = True
self.folder.save()
self.client.force_login(self.owner)
def test_admin_can_change_owner(self):
new_owner = User.objects.create_user(username="new-owner", password="new")
self.client.force_login(self.admin)
response = self.client.post(
reverse("documents:folder_edit", args=[self.folder.pk]),
{
"name": "Admin updated",
"description": "",
"application_label": "",
"parent_folders": [],
"created_by": new_owner.pk,
},
)
self.assertRedirects(response, f"{reverse('documents:list')}?folder={self.folder.slug}")
self.folder.refresh_from_db()
self.assertEqual(self.folder.created_by, new_owner)
def test_owner_can_access_share_page(self):
self.client.force_login(self.owner)
response = self.client.get(
reverse("documents:folder_share", args=[self.folder.pk])
)
self.assertEqual(response.status_code, 200)
def test_owner_can_create_share(self):
target = User.objects.create_user(username="share-target", password="pass")
self.client.force_login(self.owner)
response = self.client.post(
reverse("documents:folder_share_add", args=[self.folder.pk]),
{"user": target.pk, "permission": ManagedDocument.PERMISSION_VIEW},
)
self.assertRedirects(
response, reverse("documents:folder_share", args=[self.folder.pk])
)
self.assertTrue(
DocumentFolderShare.objects.filter(folder=self.folder, user=target).exists()
)
def test_owner_can_create_access_link(self):
self.client.force_login(self.owner)
response = self.client.post(
reverse("documents:folder_access_link", args=[self.folder.pk]),
{"permission": ManagedDocument.PERMISSION_VIEW},
)
self.assertRedirects(
response, reverse("documents:folder_share", args=[self.folder.pk])
)
self.assertEqual(self.folder.access_links.count(), 1)
def test_owner_can_delete_folder(self):
self.client.force_login(self.owner)
response = self.client.post(
reverse("documents:folder_delete", args=[self.folder.pk]),
{},
)
self.assertRedirects(response, reverse("documents:list"))
self.assertFalse(DocumentFolder.objects.filter(pk=self.folder.pk).exists())
def test_non_owner_cannot_delete_folder(self):
self.client.force_login(self.other)
response = self.client.post(
reverse("documents:folder_delete", args=[self.folder.pk]),
{},
)
self.assertEqual(response.status_code, 403)
def test_admin_can_delete_folder(self):
self.client.force_login(self.admin)
response = self.client.post(
reverse("documents:folder_delete", args=[self.folder.pk]),
{},
)
self.assertRedirects(response, reverse("documents:list"))
self.assertFalse(DocumentFolder.objects.filter(pk=self.folder.pk).exists())
def test_predefined_folder_cannot_be_deleted(self):
self.folder.is_predefined = True
self.folder.save()
self.client.force_login(self.owner)
response = self.client.post(
reverse("documents:folder_delete", args=[self.folder.pk]),
{},
)
self.assertEqual(response.status_code, 403)
def test_cannot_set_folder_as_child_of_descendant(self):
child = DocumentFolder.objects.create(name="Child", slug="child", created_by=self.owner)
child.parent_folders.add(self.folder)
self.client.force_login(self.owner)
response = self.client.post(
reverse("documents:folder_edit", args=[self.folder.pk]),
{
"name": self.folder.name,
"description": "",
"application_label": "",
"parent_folders": [child.pk],
},
)
self.assertEqual(response.status_code, 200)
self.assertIn("parent_folders", response.context["form"].errors)
def test_folder_creation_assigns_owner(self):
self.client.force_login(self.other)
response = self.client.post(
reverse("documents:folder_create"),
{
"name": "New Folder",
"description": "",
"application_label": "",
"parent_folders": [],
},
)
created_folder = DocumentFolder.objects.get(name="New Folder")
expected_redirect = f"{reverse('documents:list')}?folder={created_folder.slug}"
self.assertRedirects(response, expected_redirect)
self.assertEqual(created_folder.created_by, self.other)
class DocumentDeletionPermissionTests(TestCase):
def setUp(self):
self.owner = User.objects.create_user(username="doc-owner", password="owner")
UserConfig.objects.create(user=self.owner, is_intern=True)
self.manager = User.objects.create_user(username="doc-manager", password="manager")
manager_role, _ = Role.objects.get_or_create(name="manager")
self.manager_config = UserConfig.objects.create(user=self.manager, is_intern=True)
self.manager_config.roles.add(manager_role)
self.project = Project.objects.create(name="Project linked doc", created_by=self.owner)
self.intervention = Intervention.objects.create(title="Intervention linked doc")
self.folder = DocumentFolder.objects.create(
name="Root",
slug="root",
created_by=self.owner,
)
def test_internal_manager_can_delete_thematic_asset_document_owned_by_others(self):
from common.models import Thematic, UserThematics
from assets.models import TrafficLightIntersection
from documents.models import DocumentFolderAttachment
from django.core.exceptions import PermissionDenied
thematic, _ = Thematic.objects.get_or_create(
code="trafficlights",
defaults={"name_fr": "Signalisation Lumineuse Tricolore", "name_nl": "Verkeerslichten"}
)
UserThematics.objects.create(user_config=self.manager_config, thematic=thematic, can_edit_assets=True)
intersection = TrafficLightIntersection.objects.create(code="TL-TEST-1", name_fr="Carrefour Test 1")
root_folder = DocumentFolder.objects.create(name="Root Intersection Folder", created_by=self.owner)
sub_folder = DocumentFolder.objects.create(name="Subfolder Schemas", created_by=self.owner)
sub_folder.parent_folders.add(root_folder)
DocumentFolderAttachment.objects.create(
folder=root_folder,
content_type=ContentType.objects.get_for_model(TrafficLightIntersection),
object_id=intersection.pk,
)
other_doc = ManagedDocument.objects.create(title="Other User Doc in Subfolder", created_by=self.owner)
other_doc.folders.add(sub_folder)
# The manager with edit rights on trafficlights should be allowed to delete the document in the subfolder
ensure_document_deletable(other_doc, self.manager)
def test_internal_manager_without_edit_rights_cannot_delete_thematic_asset_document_owned_by_others(self):
from common.models import Thematic, UserThematics
from assets.models import TrafficLightIntersection
from documents.models import DocumentFolderAttachment
from django.core.exceptions import PermissionDenied
thematic, _ = Thematic.objects.get_or_create(
code="trafficlights",
defaults={"name_fr": "Signalisation Lumineuse Tricolore", "name_nl": "Verkeerslichten"}
)
# Manager has can_edit_assets=False
UserThematics.objects.create(user_config=self.manager_config, thematic=thematic, can_edit_assets=False)
intersection = TrafficLightIntersection.objects.create(code="TL-TEST-2", name_fr="Carrefour Test 2")
root_folder = DocumentFolder.objects.create(name="Root Intersection Folder 2", created_by=self.owner)
DocumentFolderAttachment.objects.create(
folder=root_folder,
content_type=ContentType.objects.get_for_model(TrafficLightIntersection),
object_id=intersection.pk,
)
other_doc = ManagedDocument.objects.create(title="Other User Doc 2", created_by=self.owner)
other_doc.folders.add(root_folder)
# Deletion should raise PermissionDenied because manager lacks edit rights on the thematic
with self.assertRaises(PermissionDenied):
ensure_document_deletable(other_doc, self.manager)
def test_document_list_view_renders_delete_button_when_user_has_permission(self):
from common.models import Thematic, UserThematics
from assets.models import TrafficLightIntersection
from documents.models import DocumentFolderAttachment
thematic, _ = Thematic.objects.get_or_create(
code="trafficlights",
defaults={"name_fr": "Signalisation Lumineuse Tricolore", "name_nl": "Verkeerslichten"}
)
UserThematics.objects.create(user_config=self.manager_config, thematic=thematic, can_edit_assets=True)
intersection = TrafficLightIntersection.objects.create(code="TL-LIST-1", name_fr="Carrefour List 1")
root_folder = DocumentFolder.objects.create(name="Root Intersection Folder List", created_by=self.owner)
DocumentFolderAttachment.objects.create(
folder=root_folder,
content_type=ContentType.objects.get_for_model(TrafficLightIntersection),
object_id=intersection.pk,
)
other_doc = ManagedDocument.objects.create(title="Other User Doc List Test", created_by=self.owner)
other_doc.folders.add(root_folder)
self.client.force_login(self.manager)
response = self.client.get(reverse("documents:list"))
self.assertEqual(response.status_code, 200)
delete_url = reverse("documents:delete", args=[other_doc.pk])
self.assertContains(response, delete_url)
def test_document_list_view_hides_delete_button_when_user_lacks_permission(self):
from common.models import Thematic, UserThematics
from assets.models import TrafficLightIntersection
from documents.models import DocumentFolderAttachment
thematic, _ = Thematic.objects.get_or_create(
code="trafficlights",
defaults={"name_fr": "Signalisation Lumineuse Tricolore", "name_nl": "Verkeerslichten"}
)
UserThematics.objects.create(user_config=self.manager_config, thematic=thematic, can_edit_assets=False)
intersection = TrafficLightIntersection.objects.create(code="TL-LIST-2", name_fr="Carrefour List 2")
root_folder = DocumentFolder.objects.create(name="Root Intersection Folder List 2", created_by=self.owner)
DocumentFolderAttachment.objects.create(
folder=root_folder,
content_type=ContentType.objects.get_for_model(TrafficLightIntersection),
object_id=intersection.pk,
)
other_doc = ManagedDocument.objects.create(title="Other User Doc List Test 2", created_by=self.owner)
other_doc.folders.add(root_folder)
self.client.force_login(self.manager)
response = self.client.get(reverse("documents:list"))
self.assertEqual(response.status_code, 200)
delete_url = reverse("documents:delete", args=[other_doc.pk])
self.assertNotContains(response, delete_url)
class SearchObjectsViewTests(TestCase):
def setUp(self):
self.user = User.objects.create_user(username="testuser", password="testpassword")
UserConfig.objects.create(user=self.user, is_intern=True)
self.document = ManagedDocument.objects.create(title="Test Document", created_by=self.user)
self.project = Project.objects.create(name="Awesome project name", created_by=self.user)
self.content_type = ContentType.objects.get_for_model(Project)
def test_search_objects_anonymous(self):
url = reverse("documents:search_objects", args=[self.document.pk])
response = self.client.get(url, {"content_type": self.content_type.pk, "q": "Awesome"})
self.assertEqual(response.status_code, 302)
def test_search_objects_authenticated(self):
self.client.force_login(self.user)
url = reverse("documents:search_objects", args=[self.document.pk])
response = self.client.get(url, {"content_type": self.content_type.pk, "q": "Awesome"})
self.assertEqual(response.status_code, 200)
data = response.json()
self.assertEqual(len(data["results"]), 1)
self.assertEqual(data["results"][0]["id"], self.project.pk)
self.assertIn("Awesome project name", data["results"][0]["text"])
class DocumentGeoreferenceTests(TestCase):
def setUp(self):
self.user = User.objects.create_user(username="geo_user", password="password")
UserConfig.objects.create(user=self.user, is_intern=True)
self.document = ManagedDocument.objects.create(title="Geo Doc", created_by=self.user)
def test_georeference_view_denied_for_anonymous(self):
url = reverse("documents:georeference", args=[self.document.pk])
response = self.client.get(url)
self.assertEqual(response.status_code, 302) # Redirect to login
def test_georeference_view_allowed_for_owner(self):
self.client.force_login(self.user)
url = reverse("documents:georeference", args=[self.document.pk])
response = self.client.get(url, {"mode": "overlay"})
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Superposition")
def test_georeference_save_success(self):
self.client.force_login(self.user)
url = reverse("documents:georeference_save", args=[self.document.pk])
coords = [[4.1, 50.1], [4.2, 50.1], [4.2, 50.2], [4.1, 50.2]]
response = self.client.post(
url,
{"coordinates": coords, "page": 1},
content_type="application/json"
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json()["status"], "success")
# Verify model updated
self.document.refresh_from_db()
self.assertEqual(self.document.georeference_coords, coords)
self.assertEqual(self.document.georeference_page, 1)
def test_georeference_save_invalid_format(self):
self.client.force_login(self.user)
url = reverse("documents:georeference_save", args=[self.document.pk])
# 3 points instead of 4
coords = [[4.1, 50.1], [4.2, 50.1], [4.2, 50.2]]
response = self.client.post(
url,
{"coordinates": coords},
content_type="application/json"
)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json()["status"], "error")
def test_map_view_not_georeferenced(self):
self.client.force_login(self.user)
url = reverse("documents:map_view", args=[self.document.pk])
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
def test_map_view_georeferenced(self):
self.client.force_login(self.user)
self.document.georeference_coords = [[4.1, 50.1], [4.2, 50.1], [4.2, 50.2], [4.1, 50.2]]
self.document.save()
url = reverse("documents:map_view", args=[self.document.pk])
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
from unittest.mock import patch
from django.core.files.uploadedfile import SimpleUploadedFile
from documents.models import DocumentVersion
import os
class DocumentCadPreviewTests(TestCase):
def setUp(self):
self.user = User.objects.create_user(username="cad_user", password="password")
UserConfig.objects.create(user=self.user, is_intern=True)
self.document = ManagedDocument.objects.create(title="Cad Doc", created_by=self.user)
# Create a version with a mock DXF file
self.version = DocumentVersion.objects.create(
document=self.document,
file=SimpleUploadedFile("plan.dxf", b"DUMMY DXF CONTENT"),
uploaded_by=self.user,
version_number=1
)
@patch("documents.utils.render_cad_file_to_image")
def test_dxf_preview_rendering_and_serving(self, mock_render):
# We simulate the render_cad_file_to_image writing a mock file
def fake_render(input_path, output_path):
with open(output_path, "wb") as f:
f.write(b"MOCK PNG CONTENT")
mock_render.side_effect = fake_render
self.client.force_login(self.user)
url = reverse("documents:page_image", args=[self.document.pk, 1])
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response["Content-Type"], "image/png")
self.assertEqual(b"".join(response.streaming_content), b"MOCK PNG CONTENT")
# Verify preview file was created on disk
preview_path = self.version.file.path + ".preview.png"
self.assertTrue(os.path.exists(preview_path))
# Clean up preview file after test
if os.path.exists(preview_path):
os.remove(preview_path)
@patch("documents.utils.render_cad_file_to_image")
def test_dwg_preview_rendering_and_serving(self, mock_render):
# Create a document and version with .dwg file
doc_dwg = ManagedDocument.objects.create(title="Dwg Doc", created_by=self.user)
version_dwg = DocumentVersion.objects.create(
document=doc_dwg,
file=SimpleUploadedFile("plan.dwg", b"DUMMY DWG CONTENT"),
uploaded_by=self.user,
version_number=1
)
def fake_render(input_path, output_path):
with open(output_path, "wb") as f:
f.write(b"MOCK DWG PNG CONTENT")
mock_render.side_effect = fake_render
self.client.force_login(self.user)
url = reverse("documents:page_image", args=[doc_dwg.pk, 1])
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response["Content-Type"], "image/png")
self.assertEqual(b"".join(response.streaming_content), b"MOCK DWG PNG CONTENT")
# Clean up preview file after test
preview_path = version_dwg.file.path + ".preview.png"
if os.path.exists(preview_path):
os.remove(preview_path)
from assets.models import NatureLocation
from documents.models import DocumentFolderAttachment
class DocumentGeoreferenceAutoZoomTests(TestCase):
def setUp(self):
self.user = User.objects.create_user(username="geo_user", password="password")
UserConfig.objects.create(user=self.user, is_intern=True)
self.document = ManagedDocument.objects.create(
title="Auto Zoom Doc",
created_by=self.user
)
self.location = NatureLocation.objects.create(
code="LOC1",
name_fr="Location 1",
lon=4.3517,
lat=50.8503
)
def test_direct_attachment_coords(self):
# Create direct attachment to the geolocated asset
DocumentAttachment.objects.create(
document=self.document,
content_type=ContentType.objects.get_for_model(self.location),
object_id=self.location.pk
)
# Test helper function
from .views import _get_associated_asset_coords
coords = _get_associated_asset_coords(self.document)
self.assertEqual(coords, [4.3517, 50.8503])
# Test that view injects associated_coords into template context
self.client.force_login(self.user)
url = reverse("documents:georeference", args=[self.document.pk])
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context["associated_coords"], [4.3517, 50.8503])
def test_folder_attachment_coords(self):
# Create folder and associate with document
folder = DocumentFolder.objects.create(name="Geo Folder", slug="geo-folder")
self.document.folders.add(folder)
# Create folder attachment to the geolocated asset
DocumentFolderAttachment.objects.create(
folder=folder,
content_type=ContentType.objects.get_for_model(self.location),
object_id=self.location.pk
)
from .views import _get_associated_asset_coords
coords = _get_associated_asset_coords(self.document)
self.assertEqual(coords, [4.3517, 50.8503])
def test_parent_folder_attachment_coords(self):
# Create parent folder, child folder, and associate with document
parent_folder = DocumentFolder.objects.create(name="Parent Geo Folder", slug="parent-geo-folder")
child_folder = DocumentFolder.objects.create(name="Child Folder", slug="child-folder")
child_folder.parent_folders.add(parent_folder)
self.document.folders.add(child_folder)
# Create folder attachment to the parent folder
DocumentFolderAttachment.objects.create(
folder=parent_folder,
content_type=ContentType.objects.get_for_model(self.location),
object_id=self.location.pk
)
from .views import _get_associated_asset_coords
coords = _get_associated_asset_coords(self.document)
self.assertEqual(coords, [4.3517, 50.8503])