mirror of
https://github.com/suitenumerique/docs.git
synced 2026-09-12 20:57:56 +02:00
📈(backend) capture an event when a document is created and deleted
When a document is created and deleted, we capture an event and we send it to posthog.
This commit is contained in:
@@ -23,6 +23,7 @@ from core.services.converter_services import (
|
||||
ConversionError,
|
||||
Converter,
|
||||
)
|
||||
from core.utils.analytics import PosthogEventName, posthog_capture
|
||||
from core.utils.treebeard import create_tree_node_with_retry
|
||||
|
||||
|
||||
@@ -490,6 +491,8 @@ class ServerCreateDocumentSerializer(serializers.Serializer):
|
||||
)
|
||||
)
|
||||
|
||||
posthog_capture(PosthogEventName.DOC_CREATED, user, {}, document=document)
|
||||
|
||||
if user:
|
||||
# Associate the document with the pre-existing user
|
||||
models.DocumentAccess.objects.create(
|
||||
|
||||
@@ -67,6 +67,7 @@ from core.services.search_indexers import (
|
||||
get_visited_document_ids_of,
|
||||
)
|
||||
from core.tasks.mail import send_ask_for_access_mail
|
||||
from core.utils.analytics import PosthogEventName, posthog_capture
|
||||
from core.utils.paths import filter_descendants
|
||||
from core.utils.treebeard import create_tree_node_with_retry
|
||||
from core.utils.users import users_sharing_documents_with
|
||||
@@ -778,10 +779,18 @@ class DocumentViewSet(
|
||||
role=models.RoleChoices.OWNER,
|
||||
)
|
||||
|
||||
posthog_capture(
|
||||
PosthogEventName.DOC_CREATED, self.request.user, {}, document=obj
|
||||
)
|
||||
|
||||
def perform_destroy(self, instance):
|
||||
"""Override to implement a soft delete instead of dumping the record in database."""
|
||||
instance.soft_delete()
|
||||
|
||||
posthog_capture(
|
||||
PosthogEventName.DOC_DELETED, self.request.user, {}, document=instance
|
||||
)
|
||||
|
||||
def _can_user_edit_document(self, document_id, set_cache=False):
|
||||
"""Check if the user can edit the document."""
|
||||
try:
|
||||
@@ -1112,6 +1121,13 @@ class DocumentViewSet(
|
||||
# Set the created instance to the serializer
|
||||
serializer.instance = child_document
|
||||
|
||||
posthog_capture(
|
||||
PosthogEventName.DOC_CREATED,
|
||||
self.request.user,
|
||||
{"document_parent": str(document.id)},
|
||||
document=child_document,
|
||||
)
|
||||
|
||||
headers = self.get_success_headers(serializer.data)
|
||||
return drf.response.Response(
|
||||
serializer.data, status=status.HTTP_201_CREATED, headers=headers
|
||||
|
||||
@@ -4,6 +4,7 @@ Tests for Documents API endpoint in impress's core app: children create
|
||||
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from io import BytesIO
|
||||
from unittest import mock
|
||||
from unittest.mock import patch
|
||||
from uuid import uuid4
|
||||
|
||||
@@ -13,6 +14,7 @@ from rest_framework.test import APIClient
|
||||
from core import factories
|
||||
from core.models import Document, LinkReachChoices, LinkRoleChoices
|
||||
from core.services import mime_types
|
||||
from core.utils.analytics import PosthogEventName
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
@@ -105,12 +107,13 @@ def test_api_documents_children_create_authenticated_success(reach, role, depth)
|
||||
parent=document, link_reach="restricted"
|
||||
)
|
||||
|
||||
response = client.post(
|
||||
f"/api/v1.0/documents/{document.id!s}/children/",
|
||||
{
|
||||
"title": "my child",
|
||||
},
|
||||
)
|
||||
with mock.patch("core.api.viewsets.posthog_capture") as mock_capture:
|
||||
response = client.post(
|
||||
f"/api/v1.0/documents/{document.id!s}/children/",
|
||||
{
|
||||
"title": "my child",
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code == 201
|
||||
|
||||
@@ -120,6 +123,13 @@ def test_api_documents_children_create_authenticated_success(reach, role, depth)
|
||||
# Access objects on the child are not necessary
|
||||
assert child.accesses.exists() is False
|
||||
|
||||
mock_capture.assert_called_once_with(
|
||||
PosthogEventName.DOC_CREATED,
|
||||
user,
|
||||
{"document_parent": str(document.id)},
|
||||
document=child,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("depth", [1, 2, 3])
|
||||
def test_api_documents_children_create_related_forbidden(depth):
|
||||
|
||||
@@ -3,6 +3,7 @@ Tests for Documents API endpoint in impress's core app: create
|
||||
"""
|
||||
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
@@ -10,6 +11,7 @@ from rest_framework.test import APIClient
|
||||
|
||||
from core import factories
|
||||
from core.models import Document
|
||||
from core.utils.analytics import PosthogEventName
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
@@ -37,13 +39,14 @@ def test_api_documents_create_authenticated_success():
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
response = client.post(
|
||||
"/api/v1.0/documents/",
|
||||
{
|
||||
"title": "my document",
|
||||
},
|
||||
format="json",
|
||||
)
|
||||
with mock.patch("core.api.viewsets.posthog_capture") as mock_capture:
|
||||
response = client.post(
|
||||
"/api/v1.0/documents/",
|
||||
{
|
||||
"title": "my document",
|
||||
},
|
||||
format="json",
|
||||
)
|
||||
|
||||
assert response.status_code == 201
|
||||
document = Document.objects.get()
|
||||
@@ -51,6 +54,13 @@ def test_api_documents_create_authenticated_success():
|
||||
assert document.link_reach == "restricted"
|
||||
assert document.accesses.filter(role="owner", user=user).exists()
|
||||
|
||||
mock_capture.assert_called_once_with(
|
||||
PosthogEventName.DOC_CREATED,
|
||||
user,
|
||||
{},
|
||||
document=document,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.django_db(transaction=True)
|
||||
def test_api_documents_create_document_race_condition():
|
||||
|
||||
@@ -5,6 +5,7 @@ Tests for Documents API endpoint in impress's core app: create
|
||||
# pylint: disable=W0621
|
||||
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from unittest import mock
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.core import mail
|
||||
@@ -18,6 +19,7 @@ from core.api.serializers import ServerCreateDocumentSerializer
|
||||
from core.models import Document, Invitation, User
|
||||
from core.services import mime_types
|
||||
from core.services.converter_services import ConversionError, YdocConverter
|
||||
from core.utils.analytics import PosthogEventName
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
@@ -183,12 +185,13 @@ def test_api_documents_create_for_owner_existing(mock_convert_md):
|
||||
"email": "irrelevant@example.com", # Should be ignored since the user already exists
|
||||
}
|
||||
|
||||
response = APIClient().post(
|
||||
"/api/v1.0/documents/create-for-owner/",
|
||||
data,
|
||||
format="json",
|
||||
HTTP_AUTHORIZATION="Bearer DummyToken",
|
||||
)
|
||||
with mock.patch("core.api.serializers.posthog_capture") as mock_capture:
|
||||
response = APIClient().post(
|
||||
"/api/v1.0/documents/create-for-owner/",
|
||||
data,
|
||||
format="json",
|
||||
HTTP_AUTHORIZATION="Bearer DummyToken",
|
||||
)
|
||||
|
||||
assert response.status_code == 201
|
||||
|
||||
@@ -204,6 +207,13 @@ def test_api_documents_create_for_owner_existing(mock_convert_md):
|
||||
assert document.creator == user
|
||||
assert document.accesses.filter(user=user, role="owner").exists()
|
||||
|
||||
mock_capture.assert_called_once_with(
|
||||
PosthogEventName.DOC_CREATED,
|
||||
user,
|
||||
{},
|
||||
document=document,
|
||||
)
|
||||
|
||||
assert Invitation.objects.exists() is False
|
||||
|
||||
assert len(mail.outbox) == 1
|
||||
@@ -230,12 +240,13 @@ def test_api_documents_create_for_owner_new_user(mock_convert_md):
|
||||
"email": "john.doe@example.com", # Should be used to create a new user
|
||||
}
|
||||
|
||||
response = APIClient().post(
|
||||
"/api/v1.0/documents/create-for-owner/",
|
||||
data,
|
||||
format="json",
|
||||
HTTP_AUTHORIZATION="Bearer DummyToken",
|
||||
)
|
||||
with mock.patch("core.api.serializers.posthog_capture") as mock_capture:
|
||||
response = APIClient().post(
|
||||
"/api/v1.0/documents/create-for-owner/",
|
||||
data,
|
||||
format="json",
|
||||
HTTP_AUTHORIZATION="Bearer DummyToken",
|
||||
)
|
||||
|
||||
assert response.status_code == 201
|
||||
|
||||
@@ -251,6 +262,13 @@ def test_api_documents_create_for_owner_new_user(mock_convert_md):
|
||||
assert document.creator is None
|
||||
assert document.accesses.exists() is False
|
||||
|
||||
mock_capture.assert_called_once_with(
|
||||
PosthogEventName.DOC_CREATED,
|
||||
None,
|
||||
{},
|
||||
document=document,
|
||||
)
|
||||
|
||||
invitation = Invitation.objects.get()
|
||||
assert invitation.email == "john.doe@example.com"
|
||||
assert invitation.role == "owner"
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
Tests for Documents API endpoint in impress's core app: delete
|
||||
"""
|
||||
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from core import factories, models
|
||||
from core.tests.conftest import TEAM, USER, VIA
|
||||
from core.utils.analytics import PosthogEventName
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
@@ -127,9 +130,10 @@ def test_api_documents_delete_authenticated_owner(via, mock_user_teams):
|
||||
document=document, team="lasuite", role="owner"
|
||||
)
|
||||
|
||||
response = client.delete(
|
||||
f"/api/v1.0/documents/{document.id}/",
|
||||
)
|
||||
with mock.patch("core.api.viewsets.posthog_capture") as mock_capture:
|
||||
response = client.delete(
|
||||
f"/api/v1.0/documents/{document.id}/",
|
||||
)
|
||||
|
||||
assert response.status_code == 204
|
||||
|
||||
@@ -137,3 +141,10 @@ def test_api_documents_delete_authenticated_owner(via, mock_user_teams):
|
||||
assert models.Document.objects.count() == 1
|
||||
assert models.Document.objects.filter(deleted_at__isnull=True).exists() is False
|
||||
assert models.Document.objects.filter(deleted_at__isnull=False).count() == 1
|
||||
|
||||
mock_capture.assert_called_once_with(
|
||||
PosthogEventName.DOC_DELETED,
|
||||
user,
|
||||
{},
|
||||
document=document,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user