|
30 | 30 | from ...tokens.tests.factories import TokenFactory |
31 | 31 | from ...utils.utils import datetime_to_str |
32 | 32 | from ..helpers import DelegateSignatureHelperV2, DeleteMultisigTxSignatureHelper |
33 | | -from ..models import MultisigConfirmation, MultisigTransaction, SafeContractDelegate |
| 33 | +from ..models import ( |
| 34 | + MultisigConfirmation, |
| 35 | + MultisigTransaction, |
| 36 | + SafeContractDelegate, |
| 37 | + SafeLastStatus, |
| 38 | +) |
34 | 39 | from ..serializers import TransferType |
35 | 40 | from ..views_v2 import SafeMultisigTransactionListView |
36 | 41 | from .factories import ( |
|
43 | 48 | MultisigTransactionFactory, |
44 | 49 | SafeContractDelegateFactory, |
45 | 50 | SafeContractFactory, |
| 51 | + SafeLastStatusFactory, |
| 52 | + SafeStatusFactory, |
46 | 53 | ) |
47 | 54 |
|
48 | 55 |
|
@@ -2610,3 +2617,190 @@ def test_all_transactions_duplicated_module_view(self): |
2610 | 2617 | {module_transaction_1.module, module_transaction_2.module}, |
2611 | 2618 | {module_tx["module"] for module_tx in response.data["results"]}, |
2612 | 2619 | ) |
| 2620 | + |
| 2621 | + def test_owners_view_v2(self): |
| 2622 | + """Test OwnersViewV2 with pagination and all SafeLastStatus fields""" |
| 2623 | + invalid_address = "0x2A" |
| 2624 | + response = self.client.get( |
| 2625 | + reverse("v2:history:owners", args=(invalid_address,)) |
| 2626 | + ) |
| 2627 | + self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) |
| 2628 | + self.assertEqual(response.data["code"], 1) |
| 2629 | + self.assertEqual(response.data["message"], "Checksum address validation failed") |
| 2630 | + |
| 2631 | + owner_address = Account.create().address |
| 2632 | + response = self.client.get( |
| 2633 | + reverse("v2:history:owners", args=(owner_address,)), format="json" |
| 2634 | + ) |
| 2635 | + self.assertEqual(response.status_code, status.HTTP_200_OK) |
| 2636 | + self.assertEqual(response.data["count"], 0) |
| 2637 | + self.assertEqual(response.data["results"], []) |
| 2638 | + |
| 2639 | + # Create SafeLastStatus with the owner |
| 2640 | + safe_last_status = SafeLastStatusFactory(owners=[owner_address]) |
| 2641 | + response = self.client.get( |
| 2642 | + reverse("v2:history:owners", args=(owner_address,)), format="json" |
| 2643 | + ) |
| 2644 | + self.assertEqual(response.status_code, status.HTTP_200_OK) |
| 2645 | + self.assertEqual(response.data["count"], 1) |
| 2646 | + self.assertEqual(len(response.data["results"]), 1) |
| 2647 | + |
| 2648 | + # Verify all SafeLastStatus fields are present |
| 2649 | + result = response.data["results"][0] |
| 2650 | + self.assertEqual(result["address"], safe_last_status.address) |
| 2651 | + self.assertCountEqual(result["owners"], safe_last_status.owners) |
| 2652 | + self.assertEqual(result["threshold"], safe_last_status.threshold) |
| 2653 | + self.assertEqual(result["nonce"], safe_last_status.nonce) |
| 2654 | + self.assertEqual(result["master_copy"], safe_last_status.master_copy) |
| 2655 | + self.assertEqual(result["fallback_handler"], safe_last_status.fallback_handler) |
| 2656 | + self.assertEqual(result["guard"], safe_last_status.guard) |
| 2657 | + self.assertCountEqual( |
| 2658 | + result["enabled_modules"], safe_last_status.enabled_modules |
| 2659 | + ) |
| 2660 | + |
| 2661 | + # Test with multiple safes |
| 2662 | + safe_status_2 = SafeLastStatusFactory(owners=[owner_address]) |
| 2663 | + SafeStatusFactory() # Test that other SafeStatus don't appear |
| 2664 | + response = self.client.get( |
| 2665 | + reverse("v2:history:owners", args=(owner_address,)), format="json" |
| 2666 | + ) |
| 2667 | + self.assertEqual(response.status_code, status.HTTP_200_OK) |
| 2668 | + self.assertEqual(response.data["count"], 2) |
| 2669 | + self.assertEqual(len(response.data["results"]), 2) |
| 2670 | + addresses = [result["address"] for result in response.data["results"]] |
| 2671 | + self.assertCountEqual( |
| 2672 | + addresses, [safe_last_status.address, safe_status_2.address] |
| 2673 | + ) |
| 2674 | + |
| 2675 | + # Test pagination |
| 2676 | + _safe_status_3 = SafeLastStatusFactory(owners=[owner_address]) |
| 2677 | + response = self.client.get( |
| 2678 | + reverse("v2:history:owners", args=(owner_address,)) + "?limit=2&offset=0", |
| 2679 | + format="json", |
| 2680 | + ) |
| 2681 | + self.assertEqual(response.status_code, status.HTTP_200_OK) |
| 2682 | + self.assertEqual(response.data["count"], 3) |
| 2683 | + self.assertEqual(len(response.data["results"]), 2) |
| 2684 | + self.assertIsNotNone(response.data["next"]) |
| 2685 | + self.assertIsNone(response.data["previous"]) |
| 2686 | + |
| 2687 | + # Test next page |
| 2688 | + response = self.client.get( |
| 2689 | + reverse("v2:history:owners", args=(owner_address,)) + "?limit=2&offset=2", |
| 2690 | + format="json", |
| 2691 | + ) |
| 2692 | + self.assertEqual(response.status_code, status.HTTP_200_OK) |
| 2693 | + self.assertEqual(response.data["count"], 3) |
| 2694 | + self.assertEqual(len(response.data["results"]), 1) |
| 2695 | + self.assertIsNone(response.data["next"]) |
| 2696 | + self.assertIsNotNone(response.data["previous"]) |
| 2697 | + |
| 2698 | + # Test that safes without the owner don't appear |
| 2699 | + other_owner = Account.create().address |
| 2700 | + SafeLastStatusFactory(owners=[other_owner]) |
| 2701 | + response = self.client.get( |
| 2702 | + reverse("v2:history:owners", args=(owner_address,)), format="json" |
| 2703 | + ) |
| 2704 | + self.assertEqual(response.status_code, status.HTTP_200_OK) |
| 2705 | + self.assertEqual(response.data["count"], 3) |
| 2706 | + addresses = [result["address"] for result in response.data["results"]] |
| 2707 | + self.assertNotIn( |
| 2708 | + SafeLastStatus.objects.filter(owners__contains=[other_owner]) |
| 2709 | + .first() |
| 2710 | + .address, |
| 2711 | + addresses, |
| 2712 | + ) |
| 2713 | + |
| 2714 | + def test_modules_view_v2(self): |
| 2715 | + """Test ModulesViewV2 with pagination and all SafeLastStatus fields""" |
| 2716 | + invalid_address = "0x2A" |
| 2717 | + response = self.client.get( |
| 2718 | + reverse("v2:history:modules", args=(invalid_address,)) |
| 2719 | + ) |
| 2720 | + self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) |
| 2721 | + self.assertEqual(response.data["code"], 1) |
| 2722 | + self.assertEqual(response.data["message"], "Checksum address validation failed") |
| 2723 | + |
| 2724 | + module_address = Account.create().address |
| 2725 | + response = self.client.get( |
| 2726 | + reverse("v2:history:modules", args=(module_address,)), format="json" |
| 2727 | + ) |
| 2728 | + self.assertEqual(response.status_code, status.HTTP_200_OK) |
| 2729 | + self.assertEqual(response.data["count"], 0) |
| 2730 | + self.assertEqual(response.data["results"], []) |
| 2731 | + |
| 2732 | + # Create SafeLastStatus with the module |
| 2733 | + safe_last_status = SafeLastStatusFactory(enabled_modules=[module_address]) |
| 2734 | + response = self.client.get( |
| 2735 | + reverse("v2:history:modules", args=(module_address,)), format="json" |
| 2736 | + ) |
| 2737 | + self.assertEqual(response.status_code, status.HTTP_200_OK) |
| 2738 | + self.assertEqual(response.data["count"], 1) |
| 2739 | + self.assertEqual(len(response.data["results"]), 1) |
| 2740 | + |
| 2741 | + # Verify all SafeLastStatus fields are present |
| 2742 | + result = response.data["results"][0] |
| 2743 | + self.assertEqual(result["address"], safe_last_status.address) |
| 2744 | + self.assertCountEqual(result["owners"], safe_last_status.owners) |
| 2745 | + self.assertEqual(result["threshold"], safe_last_status.threshold) |
| 2746 | + self.assertEqual(result["nonce"], safe_last_status.nonce) |
| 2747 | + self.assertEqual(result["master_copy"], safe_last_status.master_copy) |
| 2748 | + self.assertEqual(result["fallback_handler"], safe_last_status.fallback_handler) |
| 2749 | + self.assertEqual(result["guard"], safe_last_status.guard) |
| 2750 | + self.assertCountEqual( |
| 2751 | + result["enabled_modules"], safe_last_status.enabled_modules |
| 2752 | + ) |
| 2753 | + self.assertIn(module_address, result["enabled_modules"]) |
| 2754 | + |
| 2755 | + # Test with multiple safes |
| 2756 | + safe_status_2 = SafeLastStatusFactory(enabled_modules=[module_address]) |
| 2757 | + SafeStatusFactory() # Test that other SafeStatus don't appear |
| 2758 | + response = self.client.get( |
| 2759 | + reverse("v2:history:modules", args=(module_address,)), format="json" |
| 2760 | + ) |
| 2761 | + self.assertEqual(response.status_code, status.HTTP_200_OK) |
| 2762 | + self.assertEqual(response.data["count"], 2) |
| 2763 | + self.assertEqual(len(response.data["results"]), 2) |
| 2764 | + addresses = [result["address"] for result in response.data["results"]] |
| 2765 | + self.assertCountEqual( |
| 2766 | + addresses, [safe_last_status.address, safe_status_2.address] |
| 2767 | + ) |
| 2768 | + |
| 2769 | + # Test pagination |
| 2770 | + _safe_status_3 = SafeLastStatusFactory(enabled_modules=[module_address]) |
| 2771 | + response = self.client.get( |
| 2772 | + reverse("v2:history:modules", args=(module_address,)) + "?limit=2&offset=0", |
| 2773 | + format="json", |
| 2774 | + ) |
| 2775 | + self.assertEqual(response.status_code, status.HTTP_200_OK) |
| 2776 | + self.assertEqual(response.data["count"], 3) |
| 2777 | + self.assertEqual(len(response.data["results"]), 2) |
| 2778 | + self.assertIsNotNone(response.data["next"]) |
| 2779 | + self.assertIsNone(response.data["previous"]) |
| 2780 | + |
| 2781 | + # Test next page |
| 2782 | + response = self.client.get( |
| 2783 | + reverse("v2:history:modules", args=(module_address,)) + "?limit=2&offset=2", |
| 2784 | + format="json", |
| 2785 | + ) |
| 2786 | + self.assertEqual(response.status_code, status.HTTP_200_OK) |
| 2787 | + self.assertEqual(response.data["count"], 3) |
| 2788 | + self.assertEqual(len(response.data["results"]), 1) |
| 2789 | + self.assertIsNone(response.data["next"]) |
| 2790 | + self.assertIsNotNone(response.data["previous"]) |
| 2791 | + |
| 2792 | + # Test that safes without the module don't appear |
| 2793 | + other_module = Account.create().address |
| 2794 | + SafeLastStatusFactory(enabled_modules=[other_module]) |
| 2795 | + response = self.client.get( |
| 2796 | + reverse("v2:history:modules", args=(module_address,)), format="json" |
| 2797 | + ) |
| 2798 | + self.assertEqual(response.status_code, status.HTTP_200_OK) |
| 2799 | + self.assertEqual(response.data["count"], 3) |
| 2800 | + addresses = [result["address"] for result in response.data["results"]] |
| 2801 | + self.assertNotIn( |
| 2802 | + SafeLastStatus.objects.filter(enabled_modules__contains=[other_module]) |
| 2803 | + .first() |
| 2804 | + .address, |
| 2805 | + addresses, |
| 2806 | + ) |
0 commit comments