✨(documents) allow retrieving versions (list and detail)
Versions are retrieved directly from object storage and served on API endpoints. We make sure a user who is given access to a document will only see versions that were created after s.he gained access.
This commit is contained in:
committed by
Anthony LC
parent
8e262da8f5
commit
130e7a8c99
@@ -24,6 +24,9 @@ def test_api_documents_retrieve_anonymous_public():
|
||||
"partial_update": False,
|
||||
"retrieve": True,
|
||||
"update": False,
|
||||
"versions_destroy": False,
|
||||
"versions_list": False,
|
||||
"versions_retrieve": False,
|
||||
},
|
||||
"accesses": [],
|
||||
"title": document.title,
|
||||
@@ -66,6 +69,9 @@ def test_api_documents_retrieve_authenticated_unrelated_public():
|
||||
"partial_update": False,
|
||||
"retrieve": True,
|
||||
"update": False,
|
||||
"versions_destroy": False,
|
||||
"versions_list": False,
|
||||
"versions_retrieve": False,
|
||||
},
|
||||
"accesses": [],
|
||||
"title": document.title,
|
||||
|
||||
526
src/backend/core/tests/test_api_document_versions.py
Normal file
526
src/backend/core/tests/test_api_document_versions.py
Normal file
@@ -0,0 +1,526 @@
|
||||
"""
|
||||
Test document versions API endpoints for users in impress's core app.
|
||||
"""
|
||||
import random
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from core import factories, models
|
||||
from core.tests.conftest import TEAM, USER, VIA
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_api_document_versions_list_anonymous_public():
|
||||
"""
|
||||
Anonymous users should not be allowed to list document versions for a public document.
|
||||
"""
|
||||
document = factories.DocumentFactory(is_public=True)
|
||||
factories.UserDocumentAccessFactory.create_batch(2, document=document)
|
||||
|
||||
response = APIClient().get(f"/api/v1.0/documents/{document.id!s}/versions/")
|
||||
|
||||
assert response.status_code == 401
|
||||
assert response.json() == {
|
||||
"detail": "Authentication credentials were not provided."
|
||||
}
|
||||
|
||||
|
||||
def test_api_document_versions_list_anonymous_private():
|
||||
"""
|
||||
Anonymous users should not be allowed to find document versions for a private document.
|
||||
"""
|
||||
document = factories.DocumentFactory(is_public=False)
|
||||
factories.UserDocumentAccessFactory.create_batch(2, document=document)
|
||||
|
||||
response = APIClient().get(f"/api/v1.0/documents/{document.id!s}/versions/")
|
||||
|
||||
assert response.status_code == 404
|
||||
assert response.json() == {"detail": "Not found."}
|
||||
|
||||
|
||||
def test_api_document_versions_list_authenticated_unrelated_public():
|
||||
"""
|
||||
Authenticated users should not be allowed to list document versions for a public document
|
||||
to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory(is_public=True)
|
||||
factories.UserDocumentAccessFactory.create_batch(3, document=document)
|
||||
|
||||
# The versions of another document to which the user is related should not be listed either
|
||||
factories.UserDocumentAccessFactory(user=user)
|
||||
|
||||
response = client.get(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/",
|
||||
)
|
||||
assert response.status_code == 403
|
||||
assert response.json() == {
|
||||
"detail": "You do not have permission to perform this action."
|
||||
}
|
||||
|
||||
|
||||
def test_api_document_versions_list_authenticated_unrelated_private():
|
||||
"""
|
||||
Authenticated users should not be allowed to find document versions for a private document
|
||||
to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory(is_public=False)
|
||||
factories.UserDocumentAccessFactory.create_batch(3, document=document)
|
||||
|
||||
# The versions of another document to which the user is related should not be listed either
|
||||
factories.UserDocumentAccessFactory(user=user)
|
||||
|
||||
response = client.get(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/",
|
||||
)
|
||||
assert response.status_code == 404
|
||||
assert response.json() == {"detail": "Not found."}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("via", VIA)
|
||||
def test_api_document_versions_list_authenticated_related(via, mock_user_get_teams):
|
||||
"""
|
||||
Authenticated users should be able to list document versions for a document
|
||||
to which they are directly related, whatever their role in the document.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory()
|
||||
if via == USER:
|
||||
models.DocumentAccess.objects.create(
|
||||
document=document,
|
||||
user=user,
|
||||
role=random.choice(models.RoleChoices.choices)[0],
|
||||
)
|
||||
elif via == TEAM:
|
||||
mock_user_get_teams.return_value = ["lasuite", "unknown"]
|
||||
models.DocumentAccess.objects.create(
|
||||
document=document,
|
||||
team="lasuite",
|
||||
role=random.choice(models.RoleChoices.choices)[0],
|
||||
)
|
||||
|
||||
# Other versions of documents to which the user has access should not be listed
|
||||
factories.UserDocumentAccessFactory(user=user)
|
||||
|
||||
# A version created before the user got access should be hidden
|
||||
response = client.get(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/",
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
content = response.json()
|
||||
assert len(content["versions"]) == 0
|
||||
|
||||
# Add a new version to the document
|
||||
document.content = {"foo": "bar"}
|
||||
document.save()
|
||||
|
||||
response = client.get(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/",
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
content = response.json()
|
||||
assert len(content["versions"]) == 1
|
||||
assert content["next_version_id_marker"] == ""
|
||||
assert content["is_truncated"] is False
|
||||
|
||||
|
||||
def test_api_document_versions_retrieve_anonymous_public():
|
||||
"""
|
||||
Anonymous users should not be allowed to retrieve specific versions for a public document.
|
||||
"""
|
||||
document = factories.DocumentFactory(is_public=True)
|
||||
version_id = document.get_versions_slice()["versions"][0]["version_id"]
|
||||
|
||||
url = f"/api/v1.0/documents/{document.id!s}/versions/{version_id:s}/"
|
||||
response = APIClient().get(url)
|
||||
|
||||
assert response.status_code == 401
|
||||
assert response.json() == {
|
||||
"detail": "Authentication credentials were not provided."
|
||||
}
|
||||
|
||||
|
||||
def test_api_document_versions_retrieve_anonymous_private():
|
||||
"""
|
||||
Anonymous users should not be allowed to find specific versions for a private document.
|
||||
"""
|
||||
document = factories.DocumentFactory(is_public=False)
|
||||
version_id = document.get_versions_slice()["versions"][0]["version_id"]
|
||||
|
||||
url = f"/api/v1.0/documents/{document.id!s}/versions/{version_id:s}/"
|
||||
response = APIClient().get(url)
|
||||
|
||||
assert response.status_code == 404
|
||||
assert response.json() == {"detail": "Not found."}
|
||||
|
||||
|
||||
def test_api_document_versions_retrieve_authenticated_unrelated_public():
|
||||
"""
|
||||
Authenticated users should not be allowed to retrieve specific versions for a public
|
||||
document to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory(is_public=True)
|
||||
version_id = document.get_versions_slice()["versions"][0]["version_id"]
|
||||
|
||||
response = client.get(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/{version_id:s}/",
|
||||
)
|
||||
assert response.status_code == 403
|
||||
assert response.json() == {
|
||||
"detail": "You do not have permission to perform this action."
|
||||
}
|
||||
|
||||
|
||||
def test_api_document_versions_retrieve_authenticated_unrelated_private():
|
||||
"""
|
||||
Authenticated users should not be allowed to find specific versions for a private document
|
||||
to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory(is_public=False)
|
||||
version_id = document.get_versions_slice()["versions"][0]["version_id"]
|
||||
|
||||
response = client.get(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/{version_id:s}/",
|
||||
)
|
||||
assert response.status_code == 404
|
||||
assert response.json() == {"detail": "Not found."}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("via", VIA)
|
||||
def test_api_document_versions_retrieve_authenticated_related(via, mock_user_get_teams):
|
||||
"""
|
||||
A user who is related to a document should be allowed to retrieve the
|
||||
associated document user accesses.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory()
|
||||
version_id = document.get_versions_slice()["versions"][0]["version_id"]
|
||||
|
||||
if via == USER:
|
||||
factories.UserDocumentAccessFactory(document=document, user=user)
|
||||
elif via == TEAM:
|
||||
mock_user_get_teams.return_value = ["lasuite", "unknown"]
|
||||
factories.TeamDocumentAccessFactory(document=document, team="lasuite")
|
||||
|
||||
# Versions created before the document was shared should not be available to the user
|
||||
response = client.get(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/{version_id:s}/",
|
||||
)
|
||||
|
||||
assert response.status_code == 404
|
||||
|
||||
# Create a new version should make it available to the user
|
||||
time.sleep(1) # minio stores datetimes with the precision of a second
|
||||
document.content = {"foo": "bar"}
|
||||
document.save()
|
||||
|
||||
version_id = document.get_versions_slice()["versions"][0]["version_id"]
|
||||
|
||||
response = client.get(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/{version_id:s}/",
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json()["content"] == {"foo": "bar"}
|
||||
|
||||
|
||||
def test_api_document_versions_create_anonymous():
|
||||
"""Anonymous users should not be allowed to create document versions."""
|
||||
document = factories.DocumentFactory()
|
||||
|
||||
response = APIClient().post(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/",
|
||||
{"foo": "bar"},
|
||||
format="json",
|
||||
)
|
||||
|
||||
assert response.status_code == 401
|
||||
assert response.json() == {
|
||||
"detail": "Authentication credentials were not provided."
|
||||
}
|
||||
|
||||
|
||||
def test_api_document_versions_create_authenticated_unrelated():
|
||||
"""
|
||||
Authenticated users should not be allowed to create document versions for a document to
|
||||
which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory()
|
||||
|
||||
response = client.post(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/",
|
||||
{"foo": "bar"},
|
||||
format="json",
|
||||
)
|
||||
|
||||
assert response.status_code == 405
|
||||
|
||||
|
||||
@pytest.mark.parametrize("via", VIA)
|
||||
def test_api_document_versions_create_authenticated_related(via, mock_user_get_teams):
|
||||
"""
|
||||
Authenticated users related to a document should not be allowed to create document versions
|
||||
whatever their role.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory()
|
||||
if via == USER:
|
||||
factories.UserDocumentAccessFactory(document=document, user=user)
|
||||
elif via == TEAM:
|
||||
mock_user_get_teams.return_value = ["lasuite", "unknown"]
|
||||
factories.TeamDocumentAccessFactory(document=document, team="lasuite")
|
||||
|
||||
response = client.post(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/",
|
||||
{"foo": "bar"},
|
||||
format="json",
|
||||
)
|
||||
|
||||
assert response.status_code == 405
|
||||
|
||||
|
||||
def test_api_document_versions_update_anonymous():
|
||||
"""Anonymous users should not be allowed to update a document version."""
|
||||
access = factories.UserDocumentAccessFactory()
|
||||
version_id = access.document.get_versions_slice()["versions"][0]["version_id"]
|
||||
|
||||
response = APIClient().put(
|
||||
f"/api/v1.0/documents/{access.document_id!s}/versions/{version_id:s}/",
|
||||
{"foo": "bar"},
|
||||
format="json",
|
||||
)
|
||||
assert response.status_code == 401
|
||||
|
||||
|
||||
def test_api_document_versions_update_authenticated_unrelated():
|
||||
"""
|
||||
Authenticated users should not be allowed to update a document version for a document to which
|
||||
they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
access = factories.UserDocumentAccessFactory()
|
||||
version_id = access.document.get_versions_slice()["versions"][0]["version_id"]
|
||||
|
||||
response = client.put(
|
||||
f"/api/v1.0/documents/{access.document_id!s}/versions/{version_id:s}/",
|
||||
{"foo": "bar"},
|
||||
format="json",
|
||||
)
|
||||
assert response.status_code == 405
|
||||
|
||||
|
||||
@pytest.mark.parametrize("via", VIA)
|
||||
def test_api_document_versions_update_authenticated_related(via, mock_user_get_teams):
|
||||
"""
|
||||
Authenticated users with access to a document should not be able to update its versions
|
||||
whatever their role.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory()
|
||||
version_id = document.get_versions_slice()["versions"][0]["version_id"]
|
||||
|
||||
if via == USER:
|
||||
factories.UserDocumentAccessFactory(document=document, user=user)
|
||||
elif via == TEAM:
|
||||
mock_user_get_teams.return_value = ["lasuite", "unknown"]
|
||||
factories.TeamDocumentAccessFactory(document=document, team="lasuite")
|
||||
|
||||
response = client.put(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/{version_id!s}/",
|
||||
{"foo": "bar"},
|
||||
format="json",
|
||||
)
|
||||
assert response.status_code == 405
|
||||
|
||||
|
||||
# Delete
|
||||
|
||||
|
||||
def test_api_document_versions_delete_anonymous():
|
||||
"""Anonymous users should not be allowed to destroy a document version."""
|
||||
access = factories.UserDocumentAccessFactory()
|
||||
|
||||
response = APIClient().delete(
|
||||
f"/api/v1.0/documents/{access.document_id!s}/versions/{access.id!s}/",
|
||||
)
|
||||
|
||||
assert response.status_code == 401
|
||||
|
||||
|
||||
def test_api_document_versions_delete_authenticated_public():
|
||||
"""
|
||||
Authenticated users should not be allowed to delete a document version for a
|
||||
public document to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory(is_public=True)
|
||||
version_id = document.get_versions_slice()["versions"][0]["version_id"]
|
||||
|
||||
response = client.delete(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/{version_id:s}/",
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
def test_api_document_versions_delete_authenticated_private():
|
||||
"""
|
||||
Authenticated users should not be allowed to find a document version to delete it
|
||||
for a private document to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory(is_public=False)
|
||||
version_id = document.get_versions_slice()["versions"][0]["version_id"]
|
||||
|
||||
response = client.delete(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/{version_id:s}/",
|
||||
)
|
||||
|
||||
assert response.status_code == 404
|
||||
assert response.json() == {"detail": "Not found."}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("via", VIA)
|
||||
def test_api_document_versions_delete_member(via, mock_user_get_teams):
|
||||
"""
|
||||
Authenticated users should not be allowed to delete a document version for a
|
||||
document in which they are a simple member.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory()
|
||||
if via == USER:
|
||||
factories.UserDocumentAccessFactory(document=document, user=user, role="member")
|
||||
elif via == TEAM:
|
||||
mock_user_get_teams.return_value = ["lasuite", "unknown"]
|
||||
factories.TeamDocumentAccessFactory(
|
||||
document=document, team="lasuite", role="member"
|
||||
)
|
||||
|
||||
# Create a new version should make it available to the user
|
||||
time.sleep(1) # minio stores datetimes with the precision of a second
|
||||
document.content = {"foo": "bar"}
|
||||
document.save()
|
||||
|
||||
versions = document.get_versions_slice()["versions"]
|
||||
assert len(versions) == 2
|
||||
|
||||
version_id = versions[1]["version_id"]
|
||||
response = client.delete(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/{version_id:s}/",
|
||||
)
|
||||
assert response.status_code == 403
|
||||
|
||||
version_id = versions[0]["version_id"]
|
||||
response = client.delete(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/{version_id:s}/",
|
||||
)
|
||||
assert response.status_code == 403
|
||||
|
||||
versions = document.get_versions_slice()["versions"]
|
||||
assert len(versions) == 2
|
||||
|
||||
|
||||
@pytest.mark.parametrize("via", VIA)
|
||||
def test_api_document_versions_delete_administrator_or_owner(via, mock_user_get_teams):
|
||||
"""
|
||||
Users who are administrator or owner of a document should be allowed to delete a version.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory()
|
||||
role = random.choice(["administrator", "owner"])
|
||||
if via == USER:
|
||||
factories.UserDocumentAccessFactory(document=document, user=user, role=role)
|
||||
elif via == TEAM:
|
||||
mock_user_get_teams.return_value = ["lasuite", "unknown"]
|
||||
factories.TeamDocumentAccessFactory(
|
||||
document=document, team="lasuite", role=role
|
||||
)
|
||||
|
||||
# Create a new version should make it available to the user
|
||||
time.sleep(1) # minio stores datetimes with the precision of a second
|
||||
document.content = {"foo": "bar"}
|
||||
document.save()
|
||||
|
||||
versions = document.get_versions_slice()["versions"]
|
||||
assert len(versions) == 2
|
||||
|
||||
version_id = versions[1]["version_id"]
|
||||
response = client.delete(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/{version_id:s}/",
|
||||
)
|
||||
# 404 because the version was created before the user was given access to the document
|
||||
assert response.status_code == 404
|
||||
|
||||
version_id = versions[0]["version_id"]
|
||||
response = client.delete(
|
||||
f"/api/v1.0/documents/{document.id!s}/versions/{version_id:s}/",
|
||||
)
|
||||
assert response.status_code == 204
|
||||
|
||||
versions = document.get_versions_slice()["versions"]
|
||||
assert len(versions) == 1
|
||||
@@ -6,7 +6,6 @@ from django.core.exceptions import ValidationError
|
||||
from django.core.files.storage import default_storage
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
|
||||
from core import factories, models
|
||||
|
||||
@@ -61,6 +60,9 @@ def test_models_documents_get_abilities_anonymous_public():
|
||||
"update": False,
|
||||
"manage_accesses": False,
|
||||
"partial_update": False,
|
||||
"versions_destroy": False,
|
||||
"versions_list": False,
|
||||
"versions_retrieve": False,
|
||||
}
|
||||
|
||||
|
||||
@@ -74,10 +76,13 @@ def test_models_documents_get_abilities_anonymous_not_public():
|
||||
"update": False,
|
||||
"manage_accesses": False,
|
||||
"partial_update": False,
|
||||
"versions_destroy": False,
|
||||
"versions_list": False,
|
||||
"versions_retrieve": False,
|
||||
}
|
||||
|
||||
|
||||
def test_models_documents_get_abilities_authenticated_public():
|
||||
def test_models_documents_get_abilities_authenticated_unrelated_public():
|
||||
"""Check abilities returned for an authenticated user if the user is public."""
|
||||
document = factories.DocumentFactory(is_public=True)
|
||||
abilities = document.get_abilities(factories.UserFactory())
|
||||
@@ -87,10 +92,13 @@ def test_models_documents_get_abilities_authenticated_public():
|
||||
"update": False,
|
||||
"manage_accesses": False,
|
||||
"partial_update": False,
|
||||
"versions_destroy": False,
|
||||
"versions_list": False,
|
||||
"versions_retrieve": False,
|
||||
}
|
||||
|
||||
|
||||
def test_models_documents_get_abilities_authenticated_not_public():
|
||||
def test_models_documents_get_abilities_authenticated_unrelated_not_public():
|
||||
"""Check abilities returned for an authenticated user if the document is private."""
|
||||
document = factories.DocumentFactory(is_public=False)
|
||||
abilities = document.get_abilities(factories.UserFactory())
|
||||
@@ -100,6 +108,9 @@ def test_models_documents_get_abilities_authenticated_not_public():
|
||||
"update": False,
|
||||
"manage_accesses": False,
|
||||
"partial_update": False,
|
||||
"versions_destroy": False,
|
||||
"versions_list": False,
|
||||
"versions_retrieve": False,
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +125,9 @@ def test_models_documents_get_abilities_owner():
|
||||
"update": True,
|
||||
"manage_accesses": True,
|
||||
"partial_update": True,
|
||||
"versions_destroy": True,
|
||||
"versions_list": True,
|
||||
"versions_retrieve": True,
|
||||
}
|
||||
|
||||
|
||||
@@ -127,6 +141,9 @@ def test_models_documents_get_abilities_administrator():
|
||||
"update": True,
|
||||
"manage_accesses": True,
|
||||
"partial_update": True,
|
||||
"versions_destroy": True,
|
||||
"versions_list": True,
|
||||
"versions_retrieve": True,
|
||||
}
|
||||
|
||||
|
||||
@@ -143,6 +160,9 @@ def test_models_documents_get_abilities_member_user(django_assert_num_queries):
|
||||
"update": False,
|
||||
"manage_accesses": False,
|
||||
"partial_update": False,
|
||||
"versions_destroy": False,
|
||||
"versions_list": True,
|
||||
"versions_retrieve": True,
|
||||
}
|
||||
|
||||
|
||||
@@ -160,23 +180,51 @@ def test_models_documents_get_abilities_preset_role(django_assert_num_queries):
|
||||
"update": False,
|
||||
"manage_accesses": False,
|
||||
"partial_update": False,
|
||||
"versions_destroy": False,
|
||||
"versions_list": True,
|
||||
"versions_retrieve": True,
|
||||
}
|
||||
|
||||
|
||||
def test_models_documents_file_upload_to_minio():
|
||||
"""Validate read/write from/to minio"""
|
||||
document = factories.DocumentFactory()
|
||||
document.content = {"foé": "çar"}
|
||||
document.save()
|
||||
def test_models_documents_get_versions_slice(settings):
|
||||
"""
|
||||
The "get_versions_slice" method should allow navigating all versions of
|
||||
the document with pagination.
|
||||
"""
|
||||
settings.S3_VERSIONS_PAGE_SIZE = 4
|
||||
|
||||
# Check that the file exists in MinIO:
|
||||
file_key = str(document.pk)
|
||||
# - through the storage backend
|
||||
assert default_storage.exists(file_key) is True
|
||||
# - directly from minio
|
||||
signed_url = default_storage.url(file_key)
|
||||
response = requests.get(signed_url, timeout=1)
|
||||
assert response.json() == {"foé": "çar"}
|
||||
# Create a document with 7 versions
|
||||
document = factories.DocumentFactory()
|
||||
for i in range(6):
|
||||
document.content = {"foo": f"bar{i:d}"}
|
||||
document.save()
|
||||
|
||||
# Add a version not related to the first document
|
||||
factories.DocumentFactory()
|
||||
|
||||
# - Get default max versions
|
||||
response = document.get_versions_slice()
|
||||
assert response["is_truncated"] is True
|
||||
assert len(response["versions"]) == 4
|
||||
assert response["next_version_id_marker"] != ""
|
||||
|
||||
expected_keys = ["etag", "is_latest", "last_modified", "version_id"]
|
||||
for i in range(4):
|
||||
assert list(response["versions"][i].keys()) == expected_keys
|
||||
|
||||
# - Get page 2
|
||||
response = document.get_versions_slice(
|
||||
from_version_id=response["next_version_id_marker"]
|
||||
)
|
||||
assert response["is_truncated"] is False
|
||||
assert len(response["versions"]) == 3
|
||||
assert response["next_version_id_marker"] == ""
|
||||
|
||||
# - Get custom max versions
|
||||
response = document.get_versions_slice(page_size=2)
|
||||
assert response["is_truncated"] is True
|
||||
assert len(response["versions"]) == 2
|
||||
assert response["next_version_id_marker"] != ""
|
||||
|
||||
|
||||
def test_models_documents_version_duplicate():
|
||||
|
||||
Reference in New Issue
Block a user