|
10 | 10 |
|
11 | 11 | from dj_cqrs.constants import SignalType, FIELDS_TRACKER_FIELD_NAME
|
12 | 12 | from dj_cqrs.metas import MasterMeta
|
| 13 | + |
13 | 14 | from tests.dj_master import models
|
14 | 15 | from tests.dj_master.serializers import AuthorSerializer
|
15 | 16 | from tests.utils import (
|
@@ -268,7 +269,7 @@ def test_create():
|
268 | 269 | assert m.cqrs_updated is not None
|
269 | 270 |
|
270 | 271 |
|
271 |
| -@pytest.mark.django_db |
| 272 | +@pytest.mark.django_db(transaction=True) |
272 | 273 | def test_update():
|
273 | 274 | m = models.AutoFieldsModel.objects.create()
|
274 | 275 | cqrs_updated = m.cqrs_updated
|
@@ -668,3 +669,126 @@ def test_m2m_not_supported():
|
668 | 669 |
|
669 | 670 | assert 'm2m_field' not in cqrs_data
|
670 | 671 | assert 'char_field' in cqrs_data
|
| 672 | + |
| 673 | + |
| 674 | +@pytest.mark.django_db(transaction=True) |
| 675 | +def test_transaction_instance_saved_once_simple_case(mocker): |
| 676 | + publisher_mock = mocker.patch('dj_cqrs.controller.producer.produce') |
| 677 | + |
| 678 | + i0 = models.TrackedFieldsChildModel.objects.create(char_field='old') |
| 679 | + with transaction.atomic(): |
| 680 | + i1 = models.TrackedFieldsParentModel.objects.create(char_field='1') |
| 681 | + i1.char_field = '2' |
| 682 | + i1.save() |
| 683 | + |
| 684 | + i2 = models.TrackedFieldsParentModel(char_field='a') |
| 685 | + i2.save() |
| 686 | + |
| 687 | + i3 = models.TrackedFieldsChildModel.objects.create(char_field='.') |
| 688 | + |
| 689 | + i0.char_field = 'new' |
| 690 | + i0.save() |
| 691 | + |
| 692 | + assert publisher_mock.call_count == 5 |
| 693 | + |
| 694 | + for i in [i0, i1, i2, i3]: |
| 695 | + i.refresh_from_db() |
| 696 | + assert i0.cqrs_revision == 1 |
| 697 | + assert i1.cqrs_revision == 0 |
| 698 | + assert i2.cqrs_revision == 0 |
| 699 | + assert i3.cqrs_revision == 0 |
| 700 | + |
| 701 | + mapper = ( |
| 702 | + (i0.pk, 0, 'old', None), |
| 703 | + (i1.pk, 0, '2', '1'), |
| 704 | + (i2.pk, 0, 'a', None), |
| 705 | + (i3.pk, 0, '.', None), |
| 706 | + (i0.pk, 1, 'new', 'old'), |
| 707 | + ) |
| 708 | + for index, call in enumerate(publisher_mock.call_args_list): |
| 709 | + payload = call[0][0] |
| 710 | + expected_data = mapper[index] |
| 711 | + |
| 712 | + assert payload.pk == expected_data[0] |
| 713 | + assert payload.instance_data['cqrs_revision'] == expected_data[1] |
| 714 | + assert payload.instance_data['char_field'] == expected_data[2] |
| 715 | + assert payload.previous_data['char_field'] == expected_data[3] |
| 716 | + |
| 717 | + |
| 718 | +@pytest.mark.django_db(transaction=True) |
| 719 | +def test_cqrs_saves_count_lifecycle(): |
| 720 | + instance = models.TrackedFieldsParentModel(char_field='1') |
| 721 | + instance.reset_cqrs_saves_count() |
| 722 | + assert instance.cqrs_saves_count == 0 |
| 723 | + assert instance.is_initial_cqrs_save |
| 724 | + |
| 725 | + instance.save() |
| 726 | + assert instance.cqrs_saves_count == 0 |
| 727 | + assert instance.is_initial_cqrs_save |
| 728 | + |
| 729 | + instance.save() |
| 730 | + assert instance.cqrs_saves_count == 0 |
| 731 | + assert instance.is_initial_cqrs_save |
| 732 | + |
| 733 | + instance.refresh_from_db() |
| 734 | + assert instance.cqrs_saves_count == 0 |
| 735 | + assert instance.is_initial_cqrs_save |
| 736 | + |
| 737 | + with transaction.atomic(): |
| 738 | + instance.save() |
| 739 | + assert instance.cqrs_saves_count == 1 |
| 740 | + assert instance.is_initial_cqrs_save |
| 741 | + |
| 742 | + instance.save() |
| 743 | + assert instance.cqrs_saves_count == 2 |
| 744 | + assert not instance.is_initial_cqrs_save |
| 745 | + |
| 746 | + instance.refresh_from_db() |
| 747 | + assert instance.cqrs_saves_count == 2 |
| 748 | + assert not instance.is_initial_cqrs_save |
| 749 | + |
| 750 | + same_db_object_other_instance = models.TrackedFieldsParentModel.objects.first() |
| 751 | + assert same_db_object_other_instance.pk == instance.pk |
| 752 | + assert same_db_object_other_instance.cqrs_saves_count == 0 |
| 753 | + assert same_db_object_other_instance.is_initial_cqrs_save |
| 754 | + |
| 755 | + same_db_object_other_instance.save() |
| 756 | + assert same_db_object_other_instance.cqrs_saves_count == 1 |
| 757 | + assert same_db_object_other_instance.is_initial_cqrs_save |
| 758 | + |
| 759 | + same_db_object_other_instance.reset_cqrs_saves_count() |
| 760 | + assert same_db_object_other_instance.cqrs_saves_count == 0 |
| 761 | + assert same_db_object_other_instance.is_initial_cqrs_save |
| 762 | + |
| 763 | + same_db_object_other_instance.save() |
| 764 | + assert same_db_object_other_instance.cqrs_saves_count == 1 |
| 765 | + assert same_db_object_other_instance.is_initial_cqrs_save |
| 766 | + |
| 767 | + assert instance.cqrs_saves_count == 0 |
| 768 | + assert same_db_object_other_instance.cqrs_saves_count == 0 |
| 769 | + |
| 770 | + |
| 771 | +@pytest.mark.django_db(transaction=True) |
| 772 | +def test_sequential_transactions(mocker): |
| 773 | + publisher_mock = mocker.patch('dj_cqrs.controller.producer.produce') |
| 774 | + |
| 775 | + with transaction.atomic(): |
| 776 | + instance = models.TrackedFieldsParentModel.objects.create(char_field='1') |
| 777 | + |
| 778 | + with transaction.atomic(): |
| 779 | + instance.char_field = '3' |
| 780 | + instance.save() |
| 781 | + |
| 782 | + transaction.set_rollback(True) |
| 783 | + instance.reset_cqrs_saves_count() |
| 784 | + |
| 785 | + with transaction.atomic(): |
| 786 | + instance.char_field = '2' |
| 787 | + instance.save() |
| 788 | + |
| 789 | + instance.refresh_from_db() |
| 790 | + |
| 791 | + assert publisher_mock.call_count == 2 |
| 792 | + assert instance.cqrs_revision == 1 |
| 793 | + assert publisher_mock.call_args_list[0][0][0].instance_data['char_field'] == '1' |
| 794 | + assert publisher_mock.call_args_list[1][0][0].instance_data['char_field'] == '2' |
0 commit comments