diff --git a/backend/laundry/data/laundry_data.csv b/backend/laundry/data/laundry_data.csv index 46ec4951..a398ac25 100644 --- a/backend/laundry/data/laundry_data.csv +++ b/backend/laundry/data/laundry_data.csv @@ -1,3 +1,4 @@ +room_id,room_name,room_description,room_location,count_washers,count_dryers 14089,English House,English House,14146,3,3 14082,"Gregory College House: Class of 1925""",Gregory College House: Class of 1925,14138,4,4 14085,Gregory College House: Van Pelt,Gregory College House: Van Pelt,14141,6,6 diff --git a/backend/laundry/management/commands/load_laundry_rooms.py b/backend/laundry/management/commands/load_laundry_rooms.py index 1bbbe668..4784d2c8 100644 --- a/backend/laundry/management/commands/load_laundry_rooms.py +++ b/backend/laundry/management/commands/load_laundry_rooms.py @@ -9,18 +9,16 @@ class Command(BaseCommand): def handle(self, *args, **kwargs): with open("laundry/data/laundry_data.csv") as data: - reader = csv.reader(data) - - for i, row in enumerate(reader): - room_id, name, location, location_id, total_washers, total_dryers = row - - LaundryRoom.objects.create( - room_id=room_id, - name=name, - location=location, - location_id=location_id, - total_washers=total_washers, - total_dryers=total_dryers, + reader = csv.DictReader(data) + + for row in reader: + LaundryRoom.objects.get_or_create( + room_id=int(row["room_id"]), + name=row["room_name"], + location=row["room_description"], + location_id=int(row["room_location"]), + total_washers=int(row["count_washers"]), + total_dryers=int(row["count_dryers"]), new=True, ) diff --git a/backend/laundry/management/commands/update_laundry_rooms.py b/backend/laundry/management/commands/update_laundry_rooms.py index 677cea4f..90916cfe 100644 --- a/backend/laundry/management/commands/update_laundry_rooms.py +++ b/backend/laundry/management/commands/update_laundry_rooms.py @@ -6,6 +6,13 @@ from requests.exceptions import HTTPError +def write_file(laundry_rooms): + with open("laundry/data/laundry_data.csv", "w") as f: + writer = csv.DictWriter(f, laundry_rooms[0].keys()) + writer.writeheader() + writer.writerows(laundry_rooms) + + class Command(BaseCommand): help = "Update laundry rooms csv from server" @@ -65,15 +72,4 @@ def handle(self, *args, **kwargs): room["count_washers"] = count_washers room["count_dryers"] = count_dryers - # write to csv - keys = [ - "room_id", - "room_name", - "room_description", - "room_location", - "count_washers", - "count_dryers", - ] - with open("laundry/data/laundry_data.csv", "w") as f: - writer = csv.DictWriter(f, keys) - writer.writerows(laundry_rooms) + write_file(laundry_rooms) diff --git a/backend/laundry/models.py b/backend/laundry/models.py index ab39e26c..d2a657cf 100644 --- a/backend/laundry/models.py +++ b/backend/laundry/models.py @@ -3,7 +3,7 @@ class LaundryRoom(models.Model): - room_id = models.IntegerField(default=0) + room_id = models.IntegerField(default=0, primary_key=True) name = models.CharField(max_length=255) location = models.CharField(max_length=255) location_id = models.IntegerField(default=0) diff --git a/backend/tests/laundry/mock_rooms_requests_14100.json b/backend/tests/laundry/mock_rooms_request_14100.json similarity index 100% rename from backend/tests/laundry/mock_rooms_requests_14100.json rename to backend/tests/laundry/mock_rooms_request_14100.json diff --git a/backend/tests/laundry/test_api_wrapper.py b/backend/tests/laundry/test_api_wrapper.py index faf26462..41f05808 100644 --- a/backend/tests/laundry/test_api_wrapper.py +++ b/backend/tests/laundry/test_api_wrapper.py @@ -5,13 +5,13 @@ from laundry.api_wrapper import all_status, room_status, save_data from laundry.models import LaundryRoom, LaundrySnapshot -from tests.laundry.test_commands import fakeLaundryGet +from tests.laundry.test_commands import mock_laundry_get ALL_URL = f"{settings.LAUNDRY_URL}/?location=" -@mock.patch("requests.get", fakeLaundryGet) +@mock.patch("requests.get", mock_laundry_get) class TestAllStatus(TestCase): def setUp(self): LaundryRoom.objects.get_or_create( @@ -54,7 +54,7 @@ def test_all_status(self): self.assertTrue(hall[machine]["offline"] >= 0) -@mock.patch("requests.get", fakeLaundryGet) +@mock.patch("requests.get", mock_laundry_get) class TestHallStatus(TestCase): def setUp(self): LaundryRoom.objects.get_or_create( @@ -86,7 +86,7 @@ def test_all_status(self): self.assertIn("status", machine) -@mock.patch("requests.get", fakeLaundryGet) +@mock.patch("requests.get", mock_laundry_get) class TestSaveData(TestCase): def setUp(self): LaundryRoom.objects.get_or_create( diff --git a/backend/tests/laundry/test_commands.py b/backend/tests/laundry/test_commands.py index b502c2ac..b82e0c0a 100644 --- a/backend/tests/laundry/test_commands.py +++ b/backend/tests/laundry/test_commands.py @@ -9,7 +9,7 @@ from laundry.models import LaundryRoom, LaundrySnapshot -def fakeLaundryGet(url, *args, **kwargs): +def mock_laundry_get(url, *args, **kwargs): # TODO: should we do this with regex? using split bc I think it's cleaner split = url.split("/") if "/".join(split[0:3]) == settings.LAUNDRY_URL: @@ -25,21 +25,35 @@ def fakeLaundryGet(url, *args, **kwargs): raise NotImplementedError -@mock.patch("requests.get", fakeLaundryGet) +@mock.patch("requests.get", mock_laundry_get) class TestGetSnapshot(TestCase): def setUp(self): # populates database with LaundryRooms LaundryRoom.objects.get_or_create( - hall_id=0, name="Bishop White", location="Quad", total_washers=9, total_dryers=9 - ) - LaundryRoom.objects.get_or_create( - hall_id=1, name="Chestnut Butcher", location="Quad", total_washers=11, total_dryers=11 + room_id=14089, + name="English House", + location="English House", + location_id=14146, + total_washers=3, + total_dryers=3, ) + LaundryRoom.objects.get_or_create( - hall_id=2, name="Class of 1928 Fisher", location="Quad", total_washers=8, total_dryers=8 + room_id=14099, + name="Harnwell 10th Floor", + location="Harnwell College House", + location_id=14150, + total_washers=3, + total_dryers=3, ) + LaundryRoom.objects.get_or_create( - hall_id=3, name="Craig", location="Quad", total_washers=3, total_dryers=3 + room_id=14100, + name="Harnwell 12th Floor", + location="Harnwell College House", + location_id=14150, + total_washers=3, + total_dryers=3, ) def test_db_populate(self): @@ -50,10 +64,10 @@ def test_db_populate(self): self.assertEqual("Captured snapshots!\n", out.getvalue()) # asserts that all rooms have been snapshotted - self.assertEqual(LaundrySnapshot.objects.all().count(), 4) + self.assertEqual(LaundrySnapshot.objects.all().count(), 3) -@mock.patch("requests.get", fakeLaundryGet) +@mock.patch("requests.get", mock_laundry_get) class TestLaundryRoomMigration(TestCase): def test_db_populate(self): out = StringIO() @@ -62,25 +76,56 @@ def test_db_populate(self): # tests the value of the output self.assertEqual("Uploaded Laundry Rooms!\n", out.getvalue()) - # asserts that the number of LaundryRooms created was 53 - self.assertEqual(LaundryRoom.objects.all().count(), 53) - + # compute expected number of rooms with open("laundry/data/laundry_data.csv") as data: reader = csv.reader(data) + # subtract 1 to account for header + num_rooms = sum(1 for _ in reader) - 1 - for i, row in enumerate(reader): - hall_id, hall_name, location, uuid, total_washers, total_dryers = row + # asserts that the number of LaundryRooms created was 53 + self.assertEqual(LaundryRoom.objects.all().count(), num_rooms) - room = LaundryRoom.objects.get(hall_id=hall_id) + with open("laundry/data/laundry_data.csv") as data: + reader = csv.DictReader(data) - # asserts that all fields of LaundryRoom are same - self.assertEqual(room.name, hall_name) - self.assertEqual(room.location, location) - self.assertEqual(str(room.uuid), uuid) - self.assertEqual(room.total_washers, int(total_washers)) - self.assertEqual(room.total_dryers, int(total_dryers)) + for row in reader: + room = LaundryRoom.objects.get(room_id=int(row["room_id"])) + # asserts that all fields of LaundryRoom are same + self.assertEqual(room.name, row["room_name"]) + self.assertEqual(room.location, row["room_description"]) + self.assertEqual(room.location_id, int(row["room_location"])) + self.assertEqual(room.total_washers, int(row["count_washers"])) + self.assertEqual(room.total_dryers, int(row["count_dryers"])) call_command("load_laundry_rooms") # asserts that LaundryRooms do not recreate itself - self.assertEqual(LaundryRoom.objects.all().count(), 53) + + +@mock.patch("requests.get", mock_laundry_get) +class TestUpdateLaundryRooms(TestCase): + @mock.patch("laundry.management.commands.update_laundry_rooms.write_file") + def test_update_laundry_rooms(self, mock_laundry_write): + call_command("update_laundry_rooms") + expected = [ + { + "room_id": 14089, + "room_name": "English House", + "room_description": "English House", + "room_location": 14146, + }, + { + "room_id": 14099, + "room_name": "Harnwell 10th Floor", + "room_description": "Harnwell College House", + "room_location": 14150, + }, + { + "room_id": 14100, + "room_name": "Harnwell 12th Floor", + "room_description": "Harnwell College House", + "room_location": 14150, + }, + ] + # assert that the mock was called with this + mock_laundry_write.assert_called_with(expected) diff --git a/backend/tests/laundry/test_views.py b/backend/tests/laundry/test_views.py index d0dae554..44e5f49a 100644 --- a/backend/tests/laundry/test_views.py +++ b/backend/tests/laundry/test_views.py @@ -8,13 +8,13 @@ from rest_framework.test import APIClient from laundry.models import LaundryRoom, LaundrySnapshot -from tests.laundry.test_commands import fakeLaundryGet +from tests.laundry.test_commands import mock_laundry_get User = get_user_model() -@mock.patch("requests.get", fakeLaundryGet) +@mock.patch("requests.get", mock_laundry_get) class HallIdViewTestCase(TestCase): def setUp(self): LaundryRoom.objects.get_or_create( @@ -42,7 +42,7 @@ def test_response(self): ) -@mock.patch("requests.get", fakeLaundryGet) +@mock.patch("requests.get", mock_laundry_get) class HallInfoViewTestCase(TestCase): def setUp(self): LaundryRoom.objects.get_or_create( @@ -74,7 +74,7 @@ def test_hall_error(self): self.assertEqual(404, response.status_code) -@mock.patch("requests.get", fakeLaundryGet) +@mock.patch("requests.get", mock_laundry_get) class MultipleHallInfoViewTestCase(TestCase): def setUp(self): LaundryRoom.objects.get_or_create( @@ -116,7 +116,7 @@ def test_hall_error(self): self.assertEqual(404, response.status_code) -@mock.patch("requests.get", fakeLaundryGet) +@mock.patch("requests.get", mock_laundry_get) class HallUsageViewTestCase(TestCase): def setUp(self): LaundryRoom.objects.get_or_create( @@ -148,7 +148,7 @@ def test_response(self): self.assertEqual(self.snapshot.available_dryers, res_json["dryer_data"][str(hour)]) -@mock.patch("requests.get", fakeLaundryGet) +@mock.patch("requests.get", mock_laundry_get) class PreferencesTestCase(TestCase): def setUp(self): LaundryRoom.objects.get_or_create( diff --git a/backend/utils/__init__.py b/backend/utils/__init__.py new file mode 100644 index 00000000..e69de29b