Exemplo n.º 1
0
def test_create_event():
    """
    Verifies events can be created manually and are linked with proper
    context
    """
    m = ddf.G('tests.EventModel')
    with pytest.raises(ValueError, match='not a registered event'):
        pghistory.create_event(m, label='invalid_event')

    event = pghistory.create_event(m, label='manual_event')
    assert event.pgh_label == 'manual_event'
    assert event.dt_field == m.dt_field
    assert event.int_field == m.int_field
    assert event.pgh_context is None

    event = pghistory.create_event(m, label='no_pgh_obj_manual_event')
    assert event.pgh_label == 'no_pgh_obj_manual_event'
    assert event.dt_field == m.dt_field
    assert event.int_field == m.int_field
    assert event.pgh_context is None

    # Context should be added properly
    with pghistory.context(hello='world') as ctx:
        event = pghistory.create_event(m, label='manual_event')
        assert event.pgh_label == 'manual_event'
        assert event.dt_field == m.dt_field
        assert event.int_field == m.int_field
        assert event.pgh_context.id == ctx.id
        assert event.pgh_context.metadata == {'hello': 'world'}
Exemplo n.º 2
0
    def middleware(request):
        if request.method in ('POST', 'PUT', 'PATCH'):
            with pghistory.context(
                    user=request.user.id if hasattr(request, 'user') else None,
                    url=request.path,
            ):
                if isinstance(request, DjangoWSGIRequest):  # pragma: no branch
                    request.__class__ = WSGIRequest

                return get_response(request)
        else:
            return get_response(request)
Exemplo n.º 3
0
def test_custom_snapshot_model_tracking(mocker):
    """
    Tests the snapshot trigger when a custom snapshot model is declared
    """
    # There is no context foreign key, so no context should be saved
    with pghistory.context():
        tracking = ddf.G(test_models.SnapshotModel, int_field=0)
        assert tracking.custom_related_name.exists()

        tracking.int_field = 1
        tracking.save()

    # Do an empty update to make sure extra snapshot aren't tracked
    tracking.save()

    assert list(tracking.custom_related_name.order_by('pgh_id').values()) == [
        {
            'pgh_id': mocker.ANY,
            'id': tracking.id,
            'pgh_label': 'custom_snapshot',
            'int_field': 0,
            'fk_field_id': tracking.fk_field_id,
            'fk_field2_id': None,
            'pgh_obj_id': tracking.id,
            'pgh_created_at': mocker.ANY,
        },
        {
            'pgh_id': mocker.ANY,
            'id': tracking.id,
            'pgh_label': 'custom_snapshot',
            'int_field': 1,
            'fk_field_id': tracking.fk_field_id,
            'fk_field2_id': None,
            'pgh_obj_id': tracking.id,
            'pgh_created_at': mocker.ANY,
        },
    ]
    assert list(
        tracking.custom_related_name.order_by('pgh_id').values()
    ) == list(
        test_models.CustomSnapshotModel.objects.order_by('pgh_id').values()
    )

    # Deleting the model will not delete the tracking model since it
    # has a custom foreign key
    tracking.delete()
    assert test_models.CustomSnapshotModel.objects.count() == 2
Exemplo n.º 4
0
def test_model_snapshot_tracking(mocker):
    """
    Tests the snapshot trigger for any model snapshot
    """
    # Even though the context is only set for this section of code,
    # it actually persists through the whole transaction (if there is
    # one). Since tests are ran in a transaction by default, all
    # subsequent events will be grouped under the same context
    with pghistory.context() as ctx:
        tracking = ddf.G(
            test_models.SnapshotModel,
            dt_field=dt.datetime(2020, 1, 1, tzinfo=dt.timezone.utc),
            int_field=0,
            fk_field=ddf.F(),
        )
        assert tracking.snapshot.exists()

    tracking.dt_field = dt.datetime(2019, 1, 1, tzinfo=dt.timezone.utc)
    tracking.save()

    # Do an empty update to make sure extra snapshot aren't tracked
    tracking.save()

    # Update the int field
    tracking.int_field = 1
    tracking.save()

    assert list(tracking.snapshot.order_by('pgh_id').values()) == [
        {
            'pgh_id': mocker.ANY,
            'id': tracking.id,
            'fk_field_id': tracking.fk_field_id,
            'dt_field': dt.datetime(2020, 1, 1, tzinfo=dt.timezone.utc),
            'pgh_label': 'snapshot',
            'int_field': 0,
            'pgh_obj_id': tracking.id,
            'pgh_created_at': mocker.ANY,
            'pgh_context_id': ctx.id,
        },
        {
            'pgh_id': mocker.ANY,
            'id': tracking.id,
            'dt_field': dt.datetime(2019, 1, 1, tzinfo=dt.timezone.utc),
            'fk_field_id': tracking.fk_field_id,
            'pgh_label': 'snapshot',
            'int_field': 0,
            'pgh_obj_id': tracking.id,
            'pgh_created_at': mocker.ANY,
            'pgh_context_id': ctx.id,
        },
        {
            'pgh_id': mocker.ANY,
            'id': tracking.id,
            'dt_field': dt.datetime(2019, 1, 1, tzinfo=dt.timezone.utc),
            'fk_field_id': tracking.fk_field_id,
            'pgh_label': 'snapshot',
            'int_field': 1,
            'pgh_obj_id': tracking.id,
            'pgh_created_at': mocker.ANY,
            'pgh_context_id': ctx.id,
        },
    ]

    # Deleting the model will not delete history by default
    tracking.delete()
    assert (
        apps.get_model('tests', 'SnapshotModelSnapshot').objects.count() == 3
    )
Exemplo n.º 5
0
    def __setattr__(self, attr, value):
        if attr == 'user':
            pghistory.context(user=value.id if value else None)

        return super().__setattr__(attr, value)