"""Tests for infrastructure/ai/graphs/workspace_qa.py - workspace Q&A graph.""" from __future__ import annotations from typing import TYPE_CHECKING, Final import pytest from noteflow.infrastructure.ai.graphs.workspace_qa import ( NO_INFORMATION_ANSWER, WORKSPACE_QA_GRAPH_NAME, WORKSPACE_QA_GRAPH_VERSION, WorkspaceQAConfig, WorkspaceQADependencies, ) if TYPE_CHECKING: from tests.infrastructure.ai.conftest import MockEmbedder, MockLLM EXPECTED_GRAPH_NAME: Final[str] = "workspace_qa" EXPECTED_GRAPH_VERSION: Final[int] = 2 EXPECTED_NO_INFO_ANSWER: Final[str] = "I couldn't find relevant information across your meetings." class TestWorkspaceQAGraphConstants: """Tests for workspace_qa module constants.""" def test_workspace_qa_graph_name_value(self) -> None: """WORKSPACE_QA_GRAPH_NAME has expected value.""" assert WORKSPACE_QA_GRAPH_NAME == EXPECTED_GRAPH_NAME, "graph name should match" def test_workspace_qa_graph_version_value(self) -> None: """WORKSPACE_QA_GRAPH_VERSION has expected value.""" assert WORKSPACE_QA_GRAPH_VERSION == EXPECTED_GRAPH_VERSION, "graph version should match" def test_workspace_qa_no_information_answer_value(self) -> None: """NO_INFORMATION_ANSWER has expected value.""" assert NO_INFORMATION_ANSWER == EXPECTED_NO_INFO_ANSWER, "no info answer should match" class TestWorkspaceQAConfig: """Tests for WorkspaceQAConfig dataclass.""" def test_workspace_qa_config_default_enable_web_search_is_false(self) -> None: """Default enable_web_search is False.""" config = WorkspaceQAConfig() assert config.enable_web_search is False, "enable_web_search default should be False" def test_workspace_qa_config_default_require_web_approval_is_true(self) -> None: """Default require_web_approval is True.""" config = WorkspaceQAConfig() assert config.require_web_approval is True, "require_web_approval default should be True" def test_workspace_qa_config_default_require_annotation_approval_is_false(self) -> None: """Default require_annotation_approval is False.""" config = WorkspaceQAConfig() assert config.require_annotation_approval is False, "require_annotation_approval default should be False" def test_workspace_qa_config_accepts_custom_enable_web_search(self) -> None: """Config accepts custom enable_web_search value.""" config = WorkspaceQAConfig(enable_web_search=True) assert config.enable_web_search is True, "should accept custom value" def test_workspace_qa_config_accepts_custom_require_web_approval(self) -> None: """Config accepts custom require_web_approval value.""" config = WorkspaceQAConfig(require_web_approval=False) assert config.require_web_approval is False, "should accept custom value" def test_workspace_qa_config_accepts_custom_require_annotation_approval(self) -> None: """Config accepts custom require_annotation_approval value.""" config = WorkspaceQAConfig(require_annotation_approval=True) assert config.require_annotation_approval is True, "should accept custom value" def test_workspace_qa_config_is_frozen(self) -> None: """Config is a frozen dataclass.""" config = WorkspaceQAConfig() with pytest.raises(AttributeError, match="cannot assign"): config.enable_web_search = True class TestWorkspaceQADependencies: """Tests for WorkspaceQADependencies dataclass.""" def test_workspace_qa_deps_stores_embedder(self, mock_embedder: MockEmbedder, mock_llm: MockLLM) -> None: """Dependencies stores embedder.""" deps = WorkspaceQADependencies( embedder=mock_embedder, segment_repo=None, llm=mock_llm, ) assert deps.embedder is mock_embedder, "should store embedder" def test_workspace_qa_deps_stores_llm(self, mock_embedder: MockEmbedder, mock_llm: MockLLM) -> None: """Dependencies stores llm.""" deps = WorkspaceQADependencies( embedder=mock_embedder, segment_repo=None, llm=mock_llm, ) assert deps.llm is mock_llm, "should store llm" def test_workspace_qa_deps_default_web_search_provider_is_none( self, mock_embedder: MockEmbedder, mock_llm: MockLLM ) -> None: """Dependencies default web_search_provider is None.""" deps = WorkspaceQADependencies( embedder=mock_embedder, segment_repo=None, llm=mock_llm, ) assert deps.web_search_provider is None, "default web_search_provider should be None" def test_workspace_qa_deps_is_frozen(self, mock_embedder: MockEmbedder, mock_llm: MockLLM) -> None: """Dependencies is a frozen dataclass.""" deps = WorkspaceQADependencies( embedder=mock_embedder, segment_repo=None, llm=mock_llm, ) with pytest.raises(AttributeError, match="cannot assign"): deps.embedder = None