From 5c48ed2f26e49d17254e7164dc257d534cbb97fc Mon Sep 17 00:00:00 2001 From: berat-552 Date: Sat, 5 Jul 2025 12:37:10 +0100 Subject: [PATCH 1/2] add docker-compose.dev.yml --- Makefile | 23 +++++++++++++++++++++++ docker-compose.dev.yml | 12 ++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 docker-compose.dev.yml diff --git a/Makefile b/Makefile index 8cce65e..49d0c0c 100644 --- a/Makefile +++ b/Makefile @@ -49,3 +49,26 @@ docker-stop: docker-remove: -@docker rm -f $(CONTAINER_NAME) && echo "Removed Docker container." || echo "No container to remove." + +# ==== Docker Compose Workflow ==== +.PHONY: compose-dev + +compose-dev: + docker compose -f docker-compose.dev.yml up + +.PHONY: compose-down + +compose-down: + docker compose -f docker-compose.dev.yml down + + +dev-full: + @echo Starting backend using Docker Compose... + cmd /C "start /B docker compose -f docker-compose.dev.yml up" + @timeout /T 3 > NUL + @echo Launching GUI (main.py)... + python main.py + +dev-full-down: + @echo "Stopping backend (Docker Compose)..." + docker compose -f docker-compose.dev.yml down \ No newline at end of file diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..6f9276b --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,12 @@ +services: + api: + build: + context: . + dockerfile: Dockerfile + command: uvicorn backend.api:app --host 0.0.0.0 --port 8000 --reload + volumes: + - ./backend:/app/backend + env_file: + - .env + ports: + - 8000:8000 From f524fa1c92f40c24925bb3593088168010fcf563 Mon Sep 17 00:00:00 2001 From: berat-552 Date: Sat, 5 Jul 2025 12:58:15 +0100 Subject: [PATCH 2/2] add unit test and modify generate content test --- backend/content_generator.py | 8 +++++++- tests/helpers/fakes.py | 15 +++++++++++++++ ...enerate_study_content_returns_qna_format.py | 16 +++++----------- tests/test_output_contains_only_qna_lines.py | 18 ++++++++++++++++++ 4 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 tests/helpers/fakes.py create mode 100644 tests/test_output_contains_only_qna_lines.py diff --git a/backend/content_generator.py b/backend/content_generator.py index e50c95d..2f9c120 100644 --- a/backend/content_generator.py +++ b/backend/content_generator.py @@ -34,7 +34,13 @@ def generate_study_content(text: str, prompt: str = "", co_client=None) -> str: max_tokens=600, temperature=0.4 ) - return response.generations[0].text.strip() + raw_output = response.generations[0].text.strip() + + # Clean trailing non-QA lines + lines = raw_output.splitlines() + qa_lines = [line for line in lines if line.strip().startswith("Q:") or line.strip().startswith("A:")] + return "\n".join(qa_lines) + except Exception as e: return f"[Error generating study content: {str(e)}]" diff --git a/tests/helpers/fakes.py b/tests/helpers/fakes.py new file mode 100644 index 0000000..36f5aa0 --- /dev/null +++ b/tests/helpers/fakes.py @@ -0,0 +1,15 @@ +class FakeCohereResponse: + def __init__(self, text): + class Generations: + pass + gen = Generations() + gen.text = text + self.generations = [gen] + + +class FakeCohereClient: + def __init__(self, mock_text): + self.mock_text = mock_text + + def generate(self, *args, **kwargs): + return FakeCohereResponse(self.mock_text) diff --git a/tests/test_generate_study_content_returns_qna_format.py b/tests/test_generate_study_content_returns_qna_format.py index 7f6e21e..669039e 100644 --- a/tests/test_generate_study_content_returns_qna_format.py +++ b/tests/test_generate_study_content_returns_qna_format.py @@ -1,19 +1,13 @@ from backend import content_generator +from tests.helpers.fakes import FakeCohereClient def test_generate_study_content_returns_qna_format(): - class FakeResponse: - class Generations: - text = "Q: What is Python?\nA: A programming language." - - generations = [Generations()] - - class FakeCohereClient: - def generate(self, *args, **kwargs): - return FakeResponse() + mock_output = "Q: What is Python?\nA: A programming language." + fake_client = FakeCohereClient(mock_output) output = content_generator.generate_study_content( - "What is Python?", co_client=FakeCohereClient() - ) + "What is Python?", co_client=fake_client) + assert "Q:" in output assert "A:" in output diff --git a/tests/test_output_contains_only_qna_lines.py b/tests/test_output_contains_only_qna_lines.py new file mode 100644 index 0000000..8265eb7 --- /dev/null +++ b/tests/test_output_contains_only_qna_lines.py @@ -0,0 +1,18 @@ +from backend import content_generator +from tests.helpers.fakes import FakeCohereClient + + +def test_generate_study_content_strips_non_qa_lines(): + mock_output = """ + Q: What is Python? + A: A programming language. + Let me know if you need more help.""" + + fake_client = FakeCohereClient(mock_output) + output = content_generator.generate_study_content( + "text", co_client=fake_client) + + for line in output.strip().splitlines(): + clean_line = line.strip() + assert (clean_line.startswith("Q:") + or clean_line.startswith("A:")), f"Invalid line: {line}"