diff --git a/code/haitiwater/apps/api/exports.py b/code/haitiwater/apps/api/exports.py index 2fbd385..d9c43a9 100644 --- a/code/haitiwater/apps/api/exports.py +++ b/code/haitiwater/apps/api/exports.py @@ -15,29 +15,24 @@ def graph(request): if not request.user.is_authenticated: return HttpResponse("Vous n'êtes pas connecté", status=403) - json_object = {} + json_object = {"jsonarray": []} export_format = request.GET.get('type', None) if export_format == "consumer_gender_pie": - json_object["jsonarray"] = [ - { - "label": "Femmes", - "data": 0 - }, - { - "label": "Hommes", - "data": 0 - }, - { - "label": "Autres", - "data": 0 - } - ] + json_object["jsonarray"].append({'label': "Femmes", 'data': 0}) + json_object["jsonarray"].append({'label': "Hommes", 'data': 0}) + json_object["jsonarray"].append({'label': "Autres", 'data': 0}) - for elem in Consumer.objects.all(): - if elem.gender == "F" or elem.gender == "Femme": + consumers = None + if is_user_fountain(request): + consumers = Consumer.objects.filter(water_outlet__id__in=request.user.profile.outlets) + elif is_user_zone(request): + consumers = Consumer.objects.filter(water_outlet__zone__name__in=request.user.profile.zone.subzones) + + for consumer in consumers: + if consumer.gender == "F" or consumer.gender == "Femme": json_object['jsonarray'][0]['data'] += 1 # One more women - elif elem.gender == "M" or elem.gender == "Homme": + elif consumer.gender == "M" or consumer.gender == "Homme": json_object['jsonarray'][1]['data'] += 1 # One more man else: json_object['jsonarray'][2]['data'] += 1 # One more other @@ -72,12 +67,7 @@ def graph(request): data.append(total if not no_data else None) - json_object["jsonarray"] = [ - { - "label": elements, - "data": data - } - ] + json_object["jsonarray"].append({"label": elements, "data": data}) return HttpResponse(json.dumps(json_object)) @@ -436,9 +426,7 @@ def details(request): table_name = request.GET.get("table", None) if table_name == "payment": - balance, validity = get_payment_details(request) - result = {"balance": balance, "validity": validity} - return HttpResponse(json.dumps(result)) + return get_payment_details(request) elif table_name == "water_element": return get_details_network(request) else: @@ -447,6 +435,9 @@ def details(request): def outlets(request): + if not request.user.is_authenticated: + return HttpResponse("Vous n'êtes pas connecté", status=403) + result = {"data": get_outlets(request)} return HttpResponse(json.dumps(result)) diff --git a/code/haitiwater/apps/api/get_table.py b/code/haitiwater/apps/api/get_table.py index 1ff538f..65def5b 100644 --- a/code/haitiwater/apps/api/get_table.py +++ b/code/haitiwater/apps/api/get_table.py @@ -196,13 +196,17 @@ def get_payment_details(request): consumer_id = request.GET.get("id", None) consumer = Consumer.objects.filter(id=consumer_id).first() if consumer is None: - return None + return HttpResponse("Impossible de charger cet élément", status=400) + if not has_access(consumer.water_outlet, request): + return HttpResponse("Vous n'avez pas les droits sur cet élément", status=403) balance = consumer.get_balance() invoice = Invoice.objects.filter(consumer_id=consumer_id).order_by('-expiration').first() validity = str(invoice.expiration) if invoice is not None else "Pas de prochaine facturation" - return balance, validity + result = {"balance": balance, "validity": validity} + + return HttpResponse(json.dumps(result)) def get_details_network(request): @@ -210,10 +214,11 @@ def get_details_network(request): outlet = Element.objects.filter(id=id_outlet).first() if outlet is None: return HttpResponse("Impossible de charger cet élément", status=400) + if not has_access(outlet, request): + return HttpResponse("Vous n'avez pas les droits sur cet élément", status=403) location = Location.objects.filter(elem=id_outlet).first() - if location is not None: - location = location.json_representation + geo_json = location.json_representation if location is not None else None infos = { "id": id_outlet, @@ -225,7 +230,7 @@ def get_details_network(request): "currentMonthCubic": outlet.get_current_output(), "averageMonthCubic": outlet.get_all_output()[1], "totalCubic": outlet.get_all_output()[0], - "geoJSON": location + "geoJSON": geo_json } return HttpResponse(json.dumps(infos)) diff --git a/code/haitiwater/apps/api/tests/tests_add.py b/code/haitiwater/apps/api/tests/tests_add.py index ba93cef..79d1e2a 100644 --- a/code/haitiwater/apps/api/tests/tests_add.py +++ b/code/haitiwater/apps/api/tests/tests_add.py @@ -60,7 +60,13 @@ class AddTests(TestCase): def tearDown(self): self.client.logout() - # Add Zone + def test_add_not_connected(self): + self.client.logout() + + response = self.client.post("/api/add/") + self.assertEqual(response.status_code, 403) + + # Zone def test_add_zone(self): response = self.client.post("/api/add/", { @@ -148,7 +154,7 @@ class AddTests(TestCase): self.assertIsNotNone(test_zone) self.assertEqual(test_zone.superzone, superzone) - # Add element + # Element def test_add_element(self): response = self.client.post("/api/add/", { @@ -176,7 +182,7 @@ class AddTests(TestCase): test_element = Element.objects.filter(location="test").first() self.assertIsNone(test_element) - # Add consumer + # Consumer def test_add_consumer(self): fountain = Element.objects.get(name="fountain") diff --git a/code/haitiwater/apps/api/tests/tests_delete.py b/code/haitiwater/apps/api/tests/tests_delete.py index 5452f97..3fdd174 100644 --- a/code/haitiwater/apps/api/tests/tests_delete.py +++ b/code/haitiwater/apps/api/tests/tests_delete.py @@ -91,6 +91,12 @@ class DeleteTests(TestCase): def tearDown(self): self.client.logout() + def test_add_not_connected(self): + self.client.logout() + + response = self.client.post("/api/remove/") + self.assertEqual(response.status_code, 403) + # Zone def test_delete_zone(self): @@ -123,11 +129,11 @@ class DeleteTests(TestCase): def test_delete_zone_not_exists(self): response = self.client.post("/api/remove/", { "table": "zone", - "id": 100 + "id": 1000 }) self.assertEqual(response.status_code, 400) - test_zone = Zone.objects.filter(id=100).first() + test_zone = Zone.objects.filter(id=1000).first() self.assertIsNone(test_zone) def test_delete_zone_used(self): @@ -157,11 +163,11 @@ class DeleteTests(TestCase): def test_delete_elem_not_exists(self): response = self.client.post("/api/remove/", { "table": "water_element", - "id": 100 + "id": 1000 }) self.assertEqual(response.status_code, 400) - test_elem = Element.objects.filter(id=100).first() + test_elem = Element.objects.filter(id=1000).first() self.assertIsNone(test_elem) def test_delete_elem_unauthorized(self): @@ -222,11 +228,11 @@ class DeleteTests(TestCase): def test_delete_consumer_not_exists(self): response = self.client.post("/api/remove/", { "table": "consumer", - "id": 100 + "id": 1000 }) self.assertEqual(response.status_code, 400) - test_consumer = Consumer.objects.filter(id=100).first() + test_consumer = Consumer.objects.filter(id=1000).first() self.assertIsNone(test_consumer) def test_delete_consumer_unauthorized(self): @@ -307,11 +313,11 @@ class DeleteTests(TestCase): def test_delete_ticket_not_exists(self): response = self.client.post("/api/remove/", { "table": "ticket", - "id": 100 + "id": 1000 }) self.assertEqual(response.status_code, 400) - test_ticket = Ticket.objects.filter(id=100).first() + test_ticket = Ticket.objects.filter(id=1000).first() self.assertIsNone(test_ticket) def test_delete_ticket_unauthorized(self): @@ -343,11 +349,11 @@ class DeleteTests(TestCase): def test_delete_payment_not_exists(self): response = self.client.post("/api/remove/", { "table": "payment", - "id": 100 + "id": 1000 }) self.assertEqual(response.status_code, 400) - test_payment = Payment.objects.filter(id=100).first() + test_payment = Payment.objects.filter(id=1000).first() self.assertIsNone(test_payment) def test_delete_payment_unauthorized(self): @@ -374,10 +380,10 @@ class DeleteTests(TestCase): self.assertIsNone(test_location) def test_delete_location_not_exists(self): - response = self.client.post("/api/gis/?id=100&action=remove") + response = self.client.post("/api/gis/?id=1000&action=remove") self.assertEqual(response.status_code, 400) - test_location = Location.objects.filter(elem__id=100).first() + test_location = Location.objects.filter(elem__id=1000).first() self.assertIsNone(test_location) def test_delete_location_unauthorized(self): diff --git a/code/haitiwater/apps/api/tests/tests_edit.py b/code/haitiwater/apps/api/tests/tests_edit.py index 076857b..f3e54ef 100644 --- a/code/haitiwater/apps/api/tests/tests_edit.py +++ b/code/haitiwater/apps/api/tests/tests_edit.py @@ -67,6 +67,12 @@ class EditTests(TestCase): def tearDown(self): self.client.logout() + def test_add_not_connected(self): + self.client.logout() + + response = self.client.post("/api/edit/") + self.assertEqual(response.status_code, 403) + # Zone def test_edit_zone(self): @@ -98,7 +104,7 @@ class EditTests(TestCase): def test_edit_zone_not_exists(self): response = self.client.post("/api/edit/", { "table": "zone", - "id": 100, + "id": 1000, "name": "test", "fountain-price": 100, "fountain-duration": 10, @@ -157,7 +163,7 @@ class EditTests(TestCase): def test_edit_element_not_exists(self): response = self.client.post("/api/edit/", { "table": "water_element", - "id": 100, + "id": 1000, "type": ElementType.FOUNTAIN.name, "localization": "test", "state": ElementStatus.OK.name @@ -233,7 +239,7 @@ class EditTests(TestCase): fountain = Element.objects.get(name="fountain") response = self.client.post("/api/edit/", { "table": "consumer", - "id": 100, + "id": 1000, "firstname": "test", "lastname": "test", "gender": "M", @@ -337,7 +343,7 @@ class EditTests(TestCase): fountain = Element.objects.get(name="fountain") response = self.client.post("/api/edit/", { "table": "ticket", - "id": 100, + "id": 1000, "id_outlet": fountain.id, "urgency": UrgencyType.LOW.name, "type": BreakType.MECHANICAL.name, @@ -477,7 +483,7 @@ class EditTests(TestCase): consumer = Consumer.objects.get(first_name="consumer", last_name="indiv") response = self.client.post("/api/edit/", { "table": "payment", - "id": 100, + "id": 1000, "id_consumer": consumer.id, "amount": 100 }) diff --git a/code/haitiwater/apps/api/tests/tests_table.py b/code/haitiwater/apps/api/tests/tests_table.py index ab9320f..24443fc 100644 --- a/code/haitiwater/apps/api/tests/tests_table.py +++ b/code/haitiwater/apps/api/tests/tests_table.py @@ -81,9 +81,22 @@ class TableTests(TestCase): payment = Payment(consumer=consumer_fountain, water_outlet=fountain, amount=100) payment.save() + self.client.post("/api/gis/?id={}&action=add".format(fountain.id), { + "geometry": { + "type": "Point", + "coordinates": [-72.331783, 19.394068] + } + }, content_type="application/json") + def tearDown(self): self.client.logout() + def test_get_table_not_connected(self): + self.client.logout() + + response = self.client.get("/api/table/") + self.assertEqual(response.status_code, 403) + # Zone def test_get_zone(self): @@ -471,3 +484,209 @@ class TableTests(TestCase): self.assertEqual(result["recordsTotal"], 20) self.assertEqual(result["recordsFiltered"], 20) self.assertEqual(len(result["data"]), 10) + + # Graph + + def test_get_graph_not_connected(self): + self.client.logout() + + response = self.client.get("/api/graph/") + self.assertEqual(response.status_code, 403) + + def test_get_graph_gender(self): + response = self.client.get("/api/graph/", {"type": "consumer_gender_pie"}) + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result["jsonarray"]), 3) + self.assertEqual(result["jsonarray"][1]["data"], 2) + + def test_get_graph_gender_sub(self): + self.client.login(username="user_zone", password="test") + + response = self.client.get("/api/graph/", {"type": "consumer_gender_pie"}) + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result["jsonarray"]), 3) + self.assertEqual(result["jsonarray"][1]["data"], 0) + + def test_get_graph_gender_fountain(self): + self.client.login(username="user_fountain", password="test") + + response = self.client.get("/api/graph/", {"type": "consumer_gender_pie"}) + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result["jsonarray"]), 3) + self.assertEqual(result["jsonarray"][1]["data"], 1) + + def test_get_graph_volume(self): + response = self.client.get("/api/graph/", {"type": "average_monthly_volume_per_zone"}) + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result["jsonarray"][0]["label"]), 2) + + def test_get_graph_volume_sub(self): + self.client.login(username="user_zone", password="test") + + response = self.client.get("/api/graph/", {"type": "average_monthly_volume_per_zone"}) + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result["jsonarray"][0]["label"]), 1) + + def test_get_graph_volume_fountain(self): + self.client.login(username="user_fountain", password="test") + + response = self.client.get("/api/graph/", {"type": "average_monthly_volume_per_zone"}) + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result["jsonarray"][0]["label"]), 1) + + # GIS + + def test_get_gis_not_connected(self): + self.client.logout() + + response = self.client.get("/api/gis/") + self.assertEqual(response.status_code, 403) + + def test_get_gis(self): + response = self.client.get("/api/gis/") + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result), 1) + + def test_get_gis_sub(self): + self.client.login(username="user_zone", password="test") + + response = self.client.get("/api/gis/") + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result), 0) + + def test_get_gis_fountain(self): + self.client.login(username="user_fountain", password="test") + + response = self.client.get("/api/gis/") + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result), 1) + + def test_get_gis_marker(self): + response = self.client.get("/api/gis/", {"marker": "fountain"}) + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result), 1) + + def test_get_gis_no_marker(self): + response = self.client.get("/api/gis/", {"marker": "kiosk"}) + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result), 0) + + # Details + + def test_get_details_not_connected(self): + self.client.logout() + + response = self.client.get("/api/details/") + self.assertEqual(response.status_code, 403) + + def test_get_details_payment(self): + consumer = Consumer.objects.get(last_name="fountain") + response = self.client.get("/api/details/", { + "table": "payment", + "id": consumer.id + }) + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(result["balance"], 100) + + def test_get_details_payment_not_exists(self): + response = self.client.get("/api/details/", { + "table": "payment", + "id": 1000 + }) + self.assertEqual(response.status_code, 400) + + def test_get_details_payment_unauthorized(self): + self.client.login(username="user_zone", password="test") + + consumer = Consumer.objects.get(last_name="fountain") + response = self.client.get("/api/details/", { + "table": "payment", + "id": consumer.id + }) + self.assertEqual(response.status_code, 403) + + def test_get_details_location(self): + fountain = Element.objects.get(name="fountain") + response = self.client.get("/api/details/", { + "table": "water_element", + "id": fountain.id + }) + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(result["localization"], "fountain") + self.assertIsNotNone(result["geoJSON"]) + + def test_get_details_location_not_exists(self): + response = self.client.get("/api/details/", { + "table": "water_element", + "id": 1000 + }) + self.assertEqual(response.status_code, 400) + + def test_get_details_location_unauthorized(self): + self.client.login(username="user_zone", password="test") + + fountain = Element.objects.get(name="fountain") + response = self.client.get("/api/details/", { + "table": "water_element", + "id": fountain.id + }) + self.assertEqual(response.status_code, 403) + + # Outlets + + def test_get_outlets_not_connected(self): + self.client.logout() + + response = self.client.get("/api/outlets/") + self.assertEqual(response.status_code, 403) + + def test_get_outlets(self): + response = self.client.get("/api/outlets/") + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result["data"]), 2) + + def test_get_outlets_sub(self): + self.client.login(username="user_zone", password="test") + + response = self.client.get("/api/outlets/") + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result["data"]), 0) + + def test_get_outlets_fountain(self): + self.client.login(username="user_fountain", password="test") + + response = self.client.get("/api/outlets/") + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result["data"]), 1)