def partial_update(self, request, *args, **kwargs): instance_id = kwargs["pk"] try: before_update = self.get_queryset().get(pk=instance_id) except Person.DoesNotExist: before_update = None kwargs["partial"] = True response = self.update(request, *args, **kwargs) updated_instance = self.get_object() changes = changes_between(model_type="Person", previous=before_update, current=updated_instance) log_activity( organization_id=self.organization.id, team_id=self.team.id, user=request.user, item_id=instance_id, scope="Person", activity="updated", detail=Detail(changes=changes), ) return response
def perform_create(self, serializer): serializer.save() log_activity( organization_id=self.organization.id, team_id=self.team_id, user=serializer.context["request"].user, item_id=serializer.instance.id, scope="FeatureFlag", activity="created", detail=Detail(name=serializer.instance.key), )
def test_does_not_save_an_updated_activity_that_has_no_changes(self): log_activity( organization_id=self.organization.id, team_id=self.team.id, user=self.user, item_id=None, scope="dinglehopper", activity="updated", detail=Detail(), ) with pytest.raises(ActivityLog.DoesNotExist): ActivityLog.objects.latest("id")
def test_can_save_a_log_that_has_no_model_changes(self): log_activity( organization_id=self.organization.id, team_id=self.team.id, user=self.user, item_id=None, scope="dinglehopper", activity="added_to_clink_expander", detail=Detail(), ) log: ActivityLog = ActivityLog.objects.latest("id") self.assertEqual(log.activity, "added_to_clink_expander")
def merge(self, request: request.Request, pk=None, **kwargs) -> response.Response: people = Person.objects.filter(team_id=self.team_id, pk__in=request.data.get("ids")) person = Person.objects.get(pk=pk, team_id=self.team_id) person.merge_people([p for p in people]) data = PersonSerializer(person).data for p in people: for distinct_id in p.distinct_ids: data["distinct_ids"].append(distinct_id) log_activity( organization_id=self.organization.id, team_id=self.team_id, user=request.user, # type: ignore item_id=p.id, scope="Person", activity="was_merged_into_person", detail=Detail( merge=Merge(type="Person", source=PersonSerializer(p).data, target=PersonSerializer(person).data,) ), ) log_activity( organization_id=self.organization.id, team_id=self.team_id, user=request.user, # type: ignore item_id=person.id, scope="Person", activity="people_merged_into", detail=Detail( merge=Merge( type="Person", source=[PersonSerializer(p).data for p in people], target=PersonSerializer(person).data, ), ), ) return response.Response(data, status=201)
def destroy(self, request, *args, **kwargs): instance: FeatureFlag = self.get_object() instance_id = instance.id instance.delete() log_activity( organization_id=self.organization.id, team_id=self.team_id, user=request.user, item_id=instance_id, scope="FeatureFlag", activity="deleted", detail=Detail(name=instance.key), ) return response.Response(status=status.HTTP_204_NO_CONTENT)
def split(self, request: request.Request, pk=None, **kwargs) -> response.Response: person: Person = Person.objects.get(pk=pk, team_id=self.team_id) distinct_ids = person.distinct_ids split_person.delay(person.id, request.data.get("main_distinct_id", None)) log_activity( organization_id=self.organization.id, team_id=self.team.id, user=request.user, # type: ignore item_id=person.id, scope="Person", activity="split_person", detail=Detail(changes=[Change(type="Person", action="split", after={"distinct_ids": distinct_ids})]), ) return response.Response({"success": True}, status=201)
def test_can_save_a_model_changed_activity_log(self): change = Change(type="FeatureFlag", field="active", action="created", before=False, after=True) log_activity( organization_id=self.organization.id, team_id=self.team.id, user=self.user, item_id=6, scope="FeatureFlag", activity="updated", detail=(Detail(changes=[change])), ) log: ActivityLog = ActivityLog.objects.latest("id") self.assertEqual(log.team_id, self.team.id) self.assertEqual(log.organization_id, self.organization.id) self.assertEqual(log.user, self.user) self.assertEqual(log.item_id, "6") self.assertEqual(log.scope, "FeatureFlag") self.assertEqual(log.activity, "updated") self.assertEqual(log.detail["changes"], [change.__dict__])
def perform_update(self, serializer): instance_id = serializer.instance.id try: before_update = FeatureFlag.objects.get(pk=instance_id) except FeatureFlag.DoesNotExist: before_update = None serializer.save() changes = changes_between("FeatureFlag", previous=before_update, current=serializer.instance) log_activity( organization_id=self.organization.id, team_id=self.team_id, user=serializer.context["request"].user, item_id=instance_id, scope="FeatureFlag", activity="updated", detail=Detail(changes=changes, name=serializer.instance.key), )
def destroy(self, request: request.Request, pk=None, **kwargs): # type: ignore try: person = Person.objects.get(team=self.team, pk=pk) person_id = person.id delete_person( person.uuid, person.properties, person.is_identified, delete_events=True, team_id=self.team.pk ) person.delete() log_activity( organization_id=self.organization.id, team_id=self.team_id, user=request.user, # type: ignore item_id=person_id, scope="Person", activity="deleted", detail=Detail(name=str(person_id)), ) return response.Response(status=204) except Person.DoesNotExist: raise NotFound(detail="Person not found.")
def test_does_not_throw_if_cannot_log_activity(self): with self.assertLogs(level="WARN") as log: try: log_activity( organization_id=UUIDT(), team_id=1, # will cause logging to raise exception because user is unsaved # avoids needing to mock anything to force the exception user=User(first_name="testy", email="*****@*****.**"), item_id="12345", scope="testing throwing exceptions on create", activity="does not explode", detail=Detail(), ) except Exception as e: raise pytest.fail(f"Should not have raised exception: {e}") logged_warning = log.records[0].__dict__ self.assertEqual(logged_warning["levelname"], "WARNING") self.assertEqual(logged_warning["msg"]["event"], "failed to write activity log") self.assertEqual(logged_warning["msg"]["scope"], "testing throwing exceptions on create") self.assertEqual(logged_warning["msg"]["team"], 1) self.assertEqual(logged_warning["msg"]["activity"], "does not explode") self.assertIsInstance(logged_warning["msg"]["exception"], ValueError)