|
| 1 | +from unittest.mock import patch |
| 2 | +from uuid import uuid4 |
| 3 | + |
| 4 | +from django.urls import reverse |
| 5 | + |
| 6 | +from temba.flows.models import Flow |
| 7 | +from temba.tests.base import TembaTest |
| 8 | + |
| 9 | + |
| 10 | +class TestInternalFlowsAPIView(TembaTest): |
| 11 | + def setUp(self): |
| 12 | + super().setUp() |
| 13 | + # ensure project has a proj_uuid for lookups |
| 14 | + self.org.proj_uuid = uuid4() |
| 15 | + self.org.save(update_fields=["proj_uuid"]) |
| 16 | + |
| 17 | + @patch("temba.api.v2.flows.views.InternalFlowsAPIView.authentication_classes", []) |
| 18 | + @patch("temba.api.v2.flows.views.InternalFlowsAPIView.permission_classes", []) |
| 19 | + def test_list_flows_success(self): |
| 20 | + # create some flows |
| 21 | + flow1 = Flow.create(self.org, self.user, name="Flow One") |
| 22 | + Flow.create(self.org, self.user, name="Flow Two") |
| 23 | + Flow.create(self.org, self.user, name="Flow Three") |
| 24 | + |
| 25 | + url = f"{reverse('api.v2.internal_flows')}?project_uuid={self.org.proj_uuid}&limit=2" |
| 26 | + resp = self.client.get(url) |
| 27 | + self.assertEqual(resp.status_code, 200) |
| 28 | + data = resp.json() |
| 29 | + |
| 30 | + # paginated response shape |
| 31 | + self.assertIn("results", data) |
| 32 | + self.assertIn("next", data) |
| 33 | + self.assertIn("previous", data) |
| 34 | + |
| 35 | + # only uuid and name returned |
| 36 | + self.assertEqual(len(data["results"][0].keys()), 2) |
| 37 | + self.assertIn("uuid", data["results"][0]) |
| 38 | + self.assertIn("name", data["results"][0]) |
| 39 | + |
| 40 | + # ordering should be newest first (flow3, flow2, ...) |
| 41 | + self.assertEqual({r["name"] for r in data["results"]}, {"Flow Three", "Flow Two"}) |
| 42 | + self.assertIsNotNone(data["next"]) # has more pages |
| 43 | + |
| 44 | + # follow next page |
| 45 | + next_url = data["next"] |
| 46 | + resp = self.client.get(next_url) |
| 47 | + self.assertEqual(resp.status_code, 200) |
| 48 | + data2 = resp.json() |
| 49 | + self.assertEqual(len(data2["results"]), 1) |
| 50 | + self.assertEqual(data2["results"][0]["name"], flow1.name) |
| 51 | + |
| 52 | + @patch("temba.api.v2.flows.views.InternalFlowsAPIView.authentication_classes", []) |
| 53 | + @patch("temba.api.v2.flows.views.InternalFlowsAPIView.permission_classes", []) |
| 54 | + def test_missing_project_uuid(self): |
| 55 | + resp = self.client.get(reverse("api.v2.internal_flows")) |
| 56 | + self.assertEqual(resp.status_code, 400) |
| 57 | + self.assertEqual(resp.json(), {"error": "project_uuid is required"}) |
| 58 | + |
| 59 | + @patch("temba.api.v2.flows.views.InternalFlowsAPIView.authentication_classes", []) |
| 60 | + @patch("temba.api.v2.flows.views.InternalFlowsAPIView.permission_classes", []) |
| 61 | + def test_invalid_project_uuid(self): |
| 62 | + url = f"{reverse('api.v2.internal_flows')}?project_uuid={uuid4()}&limit=1" |
| 63 | + resp = self.client.get(url) |
| 64 | + self.assertEqual(resp.status_code, 404) |
| 65 | + self.assertEqual(resp.json(), {"error": "Project not found"}) |
| 66 | + |
| 67 | + @patch("temba.api.v2.flows.views.InternalFlowsAPIView.authentication_classes", []) |
| 68 | + @patch("temba.api.v2.flows.views.InternalFlowsAPIView.permission_classes", []) |
| 69 | + def test_pagination_limit(self): |
| 70 | + # create more flows than the limit |
| 71 | + for i in range(12): |
| 72 | + Flow.create(self.org, self.user, name=f"Flow {i}") |
| 73 | + |
| 74 | + url = f"{reverse('api.v2.internal_flows')}?project_uuid={self.org.proj_uuid}&limit=5" |
| 75 | + resp = self.client.get(url) |
| 76 | + self.assertEqual(resp.status_code, 200) |
| 77 | + data = resp.json() |
| 78 | + self.assertEqual(len(data["results"]), 5) |
| 79 | + self.assertIsNotNone(data.get("next")) |
0 commit comments