From 3abd2ce803a44ff81392fc1c5b1391d37a6ed970 Mon Sep 17 00:00:00 2001 From: Dazbo Date: Sat, 14 Sep 2024 19:10:16 +0100 Subject: [PATCH 1/2] Added unit tests for extract_and_translate function --- app/backend_gcf/main.py | 6 +- app/backend_gcf/tests/test_main.py | 117 ++++++++++------------------- 2 files changed, 42 insertions(+), 81 deletions(-) diff --git a/app/backend_gcf/main.py b/app/backend_gcf/main.py index 9556c2e..57f92f7 100644 --- a/app/backend_gcf/main.py +++ b/app/backend_gcf/main.py @@ -85,7 +85,7 @@ def extract_and_translate(request): return "No text found in the image." -def detect_text(image: vision.Image) -> dict | None: +def detect_text(image: vision.Image) -> dict: """Extract the text from the Image object """ text_detection_response = vision_client.text_detection(image=image) annotations = text_detection_response.text_annotations @@ -94,7 +94,6 @@ def detect_text(image: vision.Image) -> dict | None: text = annotations[0].description else: text = "" - # print(f"Extracted text from image:\n{text}") # Returns language identifer in ISO 639-1 format. E.g. en. # See https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes @@ -112,8 +111,7 @@ def detect_text(image: vision.Image) -> dict | None: def translate_text(message: dict, to_lang: str) -> dict: """ Translates the text in the message from the specified source language - to the requested target language, then sends a message requesting another - service save the result. + to the requested target language. """ text = message["text"] diff --git a/app/backend_gcf/tests/test_main.py b/app/backend_gcf/tests/test_main.py index aececef..4ea0883 100644 --- a/app/backend_gcf/tests/test_main.py +++ b/app/backend_gcf/tests/test_main.py @@ -1,77 +1,40 @@ -import unittest -from unittest.mock import MagicMock -from ..main import extract_and_translate, detect_text, translate_text -from google.cloud import vision -from google.cloud import translate_v2 as translate - -class TestImageTextTranslator(unittest.TestCase): - - # def test_extract_and_translate_with_uploaded_file(self): - # with open("test_image.jpg", "rb") as f: - # test_image_data = f.read() - - # # Mock the request object using MagicMock - # request_mock = MagicMock() - # request_mock.method = 'POST' - # request_mock.files = {"uploaded": io.BytesIO(test_image_data)} - # request_mock.form = {"to_lang": "es"} - - # # Assuming detect_text and translate_text are working correctly - # # and mocking their responses for this test - # expected_detected_text = {"text": "Sample text", "src_lang": "en"} - # expected_translated_text = {"text": "Texto de ejemplo", "src_lang": "en", "to_lang": "es"} - - # # Mock the responses from the Vision and Translate APIs - # vision.ImageAnnotatorClient.text_detection = MagicMock(return_value=MagicMock(text_annotations=[MagicMock(description=expected_detected_text["text"])])) - # translate.Client.detect_language = MagicMock(return_value={"language": expected_detected_text["src_lang"]}) - # translate.Client.translate = MagicMock(return_value={"translatedText": expected_translated_text["text"]}) - - # response = extract_and_translate(request_mock) - - # self.assertEqual(response, expected_translated_text["text"]) - - def test_detect_text_with_text(self): - """ Mock the response from the Vision API """ - test_text = "Sample text" - vision.ImageAnnotatorClient.text_detection = MagicMock(return_value=MagicMock(text_annotations=[MagicMock(description=test_text)])) - translate.Client.detect_language = MagicMock(return_value={"language": "en"}) - - image_mock = MagicMock(spec=vision.Image) - detected_text = detect_text(image_mock) - - self.assertEqual(detected_text["text"], test_text) - - def test_detect_text_without_text(self): - """ Mock the response from the Vision API for no text detected """ - vision.ImageAnnotatorClient.text_detection = MagicMock(return_value=MagicMock(text_annotations=[])) - translate.Client.detect_language = MagicMock(return_value={"language": "und"}) - - image_mock = MagicMock(spec=vision.Image) - detected_text = detect_text(image_mock) - - self.assertEqual(detected_text["text"], "") - - def test_translate_text(self): - """ Mock the response from the Translate API """ - message = {"text": "Hola mundo", "src_lang": "es"} - to_lang = "en" - expected_translated_text = {"text": "Hello world", "src_lang": "es", "to_lang": "en"} - - # Mock the response from the Translate API - translate.Client.translate = MagicMock(return_value={"translatedText": expected_translated_text["text"]}) - - translated_text = translate_text(message, to_lang) - - self.assertEqual(translated_text, expected_translated_text) - - def test_translate_text_no_translation(self): - message = {"text": "Hello world", "src_lang": "en"} - to_lang = "en" - expected_translated_text = {"text": "Hello world", "src_lang": "en", "to_lang": "en"} - - translated_text = translate_text(message, to_lang) - - self.assertEqual(translated_text, expected_translated_text) - -if __name__ == "__main__": - unittest.main() +import pytest +from unittest.mock import patch, MagicMock # To mock external API calls +from flask import Flask, request # To simulate HTTP requests +from io import BytesIO + +# Import the function from main.py +from backend_gcf.main import extract_and_translate + +@pytest.fixture +def app(): + """ Fixture for Flask app context, for creating HTTP requests """ + app = Flask(__name__) + return app + +# Use patch to replace the Google clients with mock objects +@patch('backend_gcf.main.vision_client') +@patch('backend_gcf.main.translate_client') +def test_extract_and_translate_with_posted_image(mock_translate_client, mock_vision_client, app: Flask): + with app.test_request_context( + method='POST', + data={ + 'uploaded': (BytesIO(b'sample image data'), 'test_image.jpg'), + 'to_lang': 'en' + }, + content_type='multipart/form-data' + ): + # Mock Vision API response + mock_vision_client.text_detection.return_value = MagicMock( + text_annotations=[MagicMock(description="Put a glass of rice and three glasses of water in a saucepan")] + ) + + # Mock Translate API response + mock_translate_client.detect_language.return_value = {"language": "uk"} + mock_translate_client.translate.return_value = {"translatedText": "Put a glass of rice and three glasses of water in a saucepan"} + + # Call the function + response = extract_and_translate(request) + + # Check the result + assert response == "Put a glass of rice and three glasses of water in a saucepan" From 676ce3c813552aa3b36cece54d235ebabcccca55 Mon Sep 17 00:00:00 2001 From: Dazbo Date: Sat, 14 Sep 2024 19:21:59 +0100 Subject: [PATCH 2/2] Update comments in test --- app/backend_gcf/tests/test_main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/backend_gcf/tests/test_main.py b/app/backend_gcf/tests/test_main.py index 4ea0883..5b501ba 100644 --- a/app/backend_gcf/tests/test_main.py +++ b/app/backend_gcf/tests/test_main.py @@ -33,7 +33,7 @@ def test_extract_and_translate_with_posted_image(mock_translate_client, mock_vis mock_translate_client.detect_language.return_value = {"language": "uk"} mock_translate_client.translate.return_value = {"translatedText": "Put a glass of rice and three glasses of water in a saucepan"} - # Call the function + # Call the function - the request object is the one simulated in test_request_context response = extract_and_translate(request) # Check the result