diff --git a/PULL_REQUSET_TEMPLATE.MD b/.github/PULL_REQUEST_TEMPLATE/PULL_REQUSET_TEMPLATE.MD similarity index 100% rename from PULL_REQUSET_TEMPLATE.MD rename to .github/PULL_REQUEST_TEMPLATE/PULL_REQUSET_TEMPLATE.MD diff --git a/README.MD b/README.MD index 14157d4..41334ff 100644 --- a/README.MD +++ b/README.MD @@ -17,6 +17,10 @@ [Django System Check](http://127.0.0.1:8000/health/) +[Rabbit Console](http://127.0.0.1:15672/) + +[SonarQube Console](http://127.0.0.1:9000/) + [Forest Admin](https://app.forestadmin.com/) ## Setup Project @@ -27,7 +31,7 @@ pipenv install ``` -### Step.2 Constructor Environments with Docker-compose +### Step.2 Construct Environments with Docker-compose ```shell docker-compose up diff --git a/api/consumers/chatConsumer.py b/api/consumers/chatConsumer.py index 7c49322..8a57d20 100644 --- a/api/consumers/chatConsumer.py +++ b/api/consumers/chatConsumer.py @@ -9,16 +9,18 @@ def get_ai_reply(message): - return f'Hi {message}' - # openai.api_key = os.getenv("CHATGPT_APIKEY", None) - # response = openai.Completion.create( - # engine="davinci", - # prompt=message, - # max_tokens=5, - # n=1, - # stop=None, - # ) - # return response['choices'][0]['text'] + openai.api_key = os.getenv("CHATGPT_APIKEY", None) + if openai.api_key: + response = openai.Completion.create( + engine="davinci", + prompt=message, + max_tokens=5, + n=1, + stop=None, + ) + return response['choices'][0]['text'] + else: + return f'Hi {message}' class ChatConsumer(AsyncWebsocketConsumer): diff --git a/api/management/commands/callback/recordCallBack.py b/api/management/commands/callback/recordCallBack.py index 4a95c5c..2dd0abe 100644 --- a/api/management/commands/callback/recordCallBack.py +++ b/api/management/commands/callback/recordCallBack.py @@ -16,13 +16,11 @@ def temperature_humidity_callback(topic: str, body: str, ch=None, method=None, p logger.info("[Temperature] Received " + str(data["Temperature"])) logger.info("[Humidity] Received " + str(data["Humidity"])) logger.debug(f'Topic:{topic} ch:{ch} properties:{properties} method:{method}') - # ch.basic_ack(delivery_tag=method.delivery_tag) - # machine = models.Machine.objects.get(name=data["machineId"]) # Check for abnormal temperature temperature = float(data["Temperature"]) if temperature > 27 or temperature < 20: - raise Exception("溫度異常") + raise ValueError("溫度異常") try: machine = models.Machine.objects.get(name=topic.split("/")[1]) @@ -53,9 +51,7 @@ def weight_callback(topic: str, body: str, ch=None, method=None, properties=None weight = float(data["Weight"]) if weight < 0: - raise Exception("進食問題") - - # ch.basic_ack(delivery_tag=method.delivery_tag) + raise ValueError("進食問題") def water_callback(topic: str, body: str, ch=None, method=None, properties=None): @@ -65,5 +61,4 @@ def water_callback(topic: str, body: str, ch=None, method=None, properties=None) water = float(data["Water"]) if water < 0: - raise Exception("攝取水量問題") - # ch.basic_ack(delivery_tag=method.delivery_tag) + raise ValueError("攝取水量問題") diff --git a/api/tests/unit/models/test_machine_model.py b/api/tests/unit/models/test_machine_model.py new file mode 100644 index 0000000..57d09b5 --- /dev/null +++ b/api/tests/unit/models/test_machine_model.py @@ -0,0 +1,49 @@ +import datetime +import logging + +from django.contrib.auth.models import User +from django.test import TestCase +from api.models import Pet, PetType, Machine + +logger = logging.getLogger(__name__) + + +class MachineModelTest(TestCase): + def setUp(self): + cat_type = PetType.objects.create(typename="cat", description="貓咪") + dog_type = PetType.objects.create(typename="dog", description="狗") + + u1 = User.objects.create(username="u1", email="u1@gmail.com") + u2 = User.objects.create(username="u2", email="u2@gmail.com") + + cat1 = Pet.objects.create(name="cat1", keeper=u1, type=cat_type, birthday=datetime.date.today(), + content="cat1") + dog1 = Pet.objects.create(name="dog1", keeper=u2, type=dog_type, birthday=datetime.date.today(), + content="dog1") + + self.m1 = Machine.objects.create(name="m1", onlineStatus=True, pet=cat1) + self.m2 = Machine.objects.create(name="m2", onlineStatus=False, pet=dog1) + + def test_machine_properties(self): + self.assertEqual(self.m1.name, "m1") + self.assertEqual(self.m2.name, "m2") + + self.assertTrue(self.m1.onlineStatus) + self.assertFalse(self.m2.onlineStatus) + + self.assertEqual(self.m1.pet.name, "cat1") + self.assertEqual(self.m2.pet.name, "dog1") + logger.debug("Complete Machine Model Test") + + def test_machine_to_string(self): + self.assertEqual(str(self.m1), + f'機器名稱{self.m1.name} 狀態:{self.m1.onlineStatus} 綁定寵物:{self.m1.pet.name}') + self.assertEqual(str(self.m2), + f'機器名稱{self.m2.name} 狀態:{self.m2.onlineStatus} 綁定寵物:{self.m2.pet.name}') + logger.debug("Complete Machine Model To String Test") + + def tearDown(self): + Pet.objects.all().delete() + User.objects.all().delete() + PetType.objects.all().delete() + Machine.objects.all().delete() diff --git a/api/tests/unit/models/test_pet_model.py b/api/tests/unit/models/test_pet_model.py index 241c690..8bca703 100644 --- a/api/tests/unit/models/test_pet_model.py +++ b/api/tests/unit/models/test_pet_model.py @@ -28,27 +28,24 @@ def setUp(self): def testPetName(self): self.assertEqual(self.cat1.name, "cat1") self.assertEqual(self.dog1.name, "dog1") - logger.debug("Complete Pet Name Model Test") self.assertEqual(self.cat1.keeper, self.u1) self.assertEqual(self.dog1.keeper, self.u1) - logger.debug("Complete Pet Keeper Model Test") self.assertEqual(self.cat1.type, self.cat_type) self.assertEqual(self.dog1.type, self.dog_type) - logger.debug("Complete Pet Type Model Test") self.assertEqual(self.cat1.birthday, datetime.date.today()) self.assertEqual(self.dog1.birthday, datetime.date.today()) - logger.debug("Complete Pet Birthday Model Test") self.assertEqual(self.cat1.content, "cat1") self.assertEqual(self.dog1.content, "dog1") - logger.debug("Complete Pet Content Model Test") self.assertEqual(str(self.cat1), f'{self.cat1.name} 照顧人:{self.cat1.keeper.username}: 寵物種類{self.cat1.type.typename}') self.assertEqual(str(self.dog1), f'{self.dog1.name} 照顧人:{self.dog1.keeper.username}: 寵物種類{self.dog1.type.typename}') + logger.debug("Complete Pet Model Test") + def tearDown(self): Pet.objects.all().delete() User.objects.all().delete() diff --git a/api/tests/unit/views/test_pet_views.py b/api/tests/unit/views/test_pet_views.py index fb3ce95..1b37283 100644 --- a/api/tests/unit/views/test_pet_views.py +++ b/api/tests/unit/views/test_pet_views.py @@ -25,6 +25,12 @@ def setUp(self): self.mouse_type = PetType.objects.create(typename="mouse", description="鼠") self.other_type = PetType.objects.create(typename="other", description="其他") + image = Image.new('RGB', (100, 100)) + self.image_io = BytesIO() + image.save(self.image_io, 'JPEG') + self.image_io.seek(0) + + def tearDown(self) -> None: Pet.objects.all().delete() PetType.objects.all().delete() @@ -102,16 +108,20 @@ def test_count_pet(self): def test_upload_pet_image(self): pet = Pet.objects.create(name="cat1", keeper=self.u1, type=self.cat_type, birthday=datetime.date.today(), content="cat1") - image = Image.new('RGB', (100, 100)) - image_io = BytesIO() - image.save(image_io, 'JPEG') - image_io.seek(0) - url = reverse('pet-upload-image', args=[pet.id]) - request = self.factory.post(url, {'image': image_io}, format='multipart') + request = self.factory.post(url, {'image': self.image_io}, format='multipart') view = PetUploadImageAPIView.as_view() response = view(request, pk=pet.id) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertIsNotNone(response.data["image"]) + + def test_upload_pet_image_invalid(self): + url = reverse('pet-upload-image', args=[50]) + request = self.factory.post(url, {'image': self.image_io}, format='multipart') + + view = PetUploadImageAPIView.as_view() + response = view(request, pk=50) + + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)