julee 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- julee/__init__.py +3 -0
- julee/api/__init__.py +20 -0
- julee/api/app.py +180 -0
- julee/api/dependencies.py +257 -0
- julee/api/requests.py +175 -0
- julee/api/responses.py +43 -0
- julee/api/routers/__init__.py +43 -0
- julee/api/routers/assembly_specifications.py +212 -0
- julee/api/routers/documents.py +182 -0
- julee/api/routers/knowledge_service_configs.py +79 -0
- julee/api/routers/knowledge_service_queries.py +293 -0
- julee/api/routers/system.py +137 -0
- julee/api/routers/workflows.py +234 -0
- julee/api/services/__init__.py +20 -0
- julee/api/services/system_initialization.py +214 -0
- julee/api/tests/__init__.py +14 -0
- julee/api/tests/routers/__init__.py +17 -0
- julee/api/tests/routers/test_assembly_specifications.py +749 -0
- julee/api/tests/routers/test_documents.py +301 -0
- julee/api/tests/routers/test_knowledge_service_configs.py +234 -0
- julee/api/tests/routers/test_knowledge_service_queries.py +738 -0
- julee/api/tests/routers/test_system.py +179 -0
- julee/api/tests/routers/test_workflows.py +393 -0
- julee/api/tests/test_app.py +285 -0
- julee/api/tests/test_dependencies.py +245 -0
- julee/api/tests/test_requests.py +250 -0
- julee/domain/__init__.py +22 -0
- julee/domain/models/__init__.py +49 -0
- julee/domain/models/assembly/__init__.py +17 -0
- julee/domain/models/assembly/assembly.py +103 -0
- julee/domain/models/assembly/tests/__init__.py +0 -0
- julee/domain/models/assembly/tests/factories.py +37 -0
- julee/domain/models/assembly/tests/test_assembly.py +430 -0
- julee/domain/models/assembly_specification/__init__.py +24 -0
- julee/domain/models/assembly_specification/assembly_specification.py +172 -0
- julee/domain/models/assembly_specification/knowledge_service_query.py +123 -0
- julee/domain/models/assembly_specification/tests/__init__.py +0 -0
- julee/domain/models/assembly_specification/tests/factories.py +78 -0
- julee/domain/models/assembly_specification/tests/test_assembly_specification.py +490 -0
- julee/domain/models/assembly_specification/tests/test_knowledge_service_query.py +310 -0
- julee/domain/models/custom_fields/__init__.py +0 -0
- julee/domain/models/custom_fields/content_stream.py +68 -0
- julee/domain/models/custom_fields/tests/__init__.py +0 -0
- julee/domain/models/custom_fields/tests/test_custom_fields.py +53 -0
- julee/domain/models/document/__init__.py +17 -0
- julee/domain/models/document/document.py +150 -0
- julee/domain/models/document/tests/__init__.py +0 -0
- julee/domain/models/document/tests/factories.py +76 -0
- julee/domain/models/document/tests/test_document.py +297 -0
- julee/domain/models/knowledge_service_config/__init__.py +17 -0
- julee/domain/models/knowledge_service_config/knowledge_service_config.py +86 -0
- julee/domain/models/policy/__init__.py +15 -0
- julee/domain/models/policy/document_policy_validation.py +220 -0
- julee/domain/models/policy/policy.py +203 -0
- julee/domain/models/policy/tests/__init__.py +0 -0
- julee/domain/models/policy/tests/factories.py +47 -0
- julee/domain/models/policy/tests/test_document_policy_validation.py +420 -0
- julee/domain/models/policy/tests/test_policy.py +546 -0
- julee/domain/repositories/__init__.py +27 -0
- julee/domain/repositories/assembly.py +45 -0
- julee/domain/repositories/assembly_specification.py +52 -0
- julee/domain/repositories/base.py +146 -0
- julee/domain/repositories/document.py +49 -0
- julee/domain/repositories/document_policy_validation.py +52 -0
- julee/domain/repositories/knowledge_service_config.py +54 -0
- julee/domain/repositories/knowledge_service_query.py +44 -0
- julee/domain/repositories/policy.py +49 -0
- julee/domain/use_cases/__init__.py +17 -0
- julee/domain/use_cases/decorators.py +107 -0
- julee/domain/use_cases/extract_assemble_data.py +649 -0
- julee/domain/use_cases/initialize_system_data.py +842 -0
- julee/domain/use_cases/tests/__init__.py +7 -0
- julee/domain/use_cases/tests/test_extract_assemble_data.py +548 -0
- julee/domain/use_cases/tests/test_initialize_system_data.py +455 -0
- julee/domain/use_cases/tests/test_validate_document.py +1228 -0
- julee/domain/use_cases/validate_document.py +736 -0
- julee/fixtures/assembly_specifications.yaml +70 -0
- julee/fixtures/documents.yaml +178 -0
- julee/fixtures/knowledge_service_configs.yaml +37 -0
- julee/fixtures/knowledge_service_queries.yaml +27 -0
- julee/repositories/__init__.py +17 -0
- julee/repositories/memory/__init__.py +31 -0
- julee/repositories/memory/assembly.py +84 -0
- julee/repositories/memory/assembly_specification.py +125 -0
- julee/repositories/memory/base.py +227 -0
- julee/repositories/memory/document.py +149 -0
- julee/repositories/memory/document_policy_validation.py +104 -0
- julee/repositories/memory/knowledge_service_config.py +123 -0
- julee/repositories/memory/knowledge_service_query.py +120 -0
- julee/repositories/memory/policy.py +87 -0
- julee/repositories/memory/tests/__init__.py +0 -0
- julee/repositories/memory/tests/test_document.py +212 -0
- julee/repositories/memory/tests/test_document_policy_validation.py +161 -0
- julee/repositories/memory/tests/test_policy.py +443 -0
- julee/repositories/minio/__init__.py +31 -0
- julee/repositories/minio/assembly.py +103 -0
- julee/repositories/minio/assembly_specification.py +170 -0
- julee/repositories/minio/client.py +570 -0
- julee/repositories/minio/document.py +530 -0
- julee/repositories/minio/document_policy_validation.py +120 -0
- julee/repositories/minio/knowledge_service_config.py +187 -0
- julee/repositories/minio/knowledge_service_query.py +211 -0
- julee/repositories/minio/policy.py +106 -0
- julee/repositories/minio/tests/__init__.py +0 -0
- julee/repositories/minio/tests/fake_client.py +213 -0
- julee/repositories/minio/tests/test_assembly.py +374 -0
- julee/repositories/minio/tests/test_assembly_specification.py +391 -0
- julee/repositories/minio/tests/test_client_protocol.py +57 -0
- julee/repositories/minio/tests/test_document.py +591 -0
- julee/repositories/minio/tests/test_document_policy_validation.py +192 -0
- julee/repositories/minio/tests/test_knowledge_service_config.py +374 -0
- julee/repositories/minio/tests/test_knowledge_service_query.py +438 -0
- julee/repositories/minio/tests/test_policy.py +559 -0
- julee/repositories/temporal/__init__.py +38 -0
- julee/repositories/temporal/activities.py +114 -0
- julee/repositories/temporal/activity_names.py +34 -0
- julee/repositories/temporal/proxies.py +159 -0
- julee/services/__init__.py +18 -0
- julee/services/knowledge_service/__init__.py +48 -0
- julee/services/knowledge_service/anthropic/__init__.py +12 -0
- julee/services/knowledge_service/anthropic/knowledge_service.py +331 -0
- julee/services/knowledge_service/anthropic/tests/test_knowledge_service.py +318 -0
- julee/services/knowledge_service/factory.py +138 -0
- julee/services/knowledge_service/knowledge_service.py +160 -0
- julee/services/knowledge_service/memory/__init__.py +13 -0
- julee/services/knowledge_service/memory/knowledge_service.py +278 -0
- julee/services/knowledge_service/memory/test_knowledge_service.py +345 -0
- julee/services/knowledge_service/test_factory.py +112 -0
- julee/services/temporal/__init__.py +38 -0
- julee/services/temporal/activities.py +86 -0
- julee/services/temporal/activity_names.py +22 -0
- julee/services/temporal/proxies.py +41 -0
- julee/util/__init__.py +0 -0
- julee/util/domain.py +119 -0
- julee/util/repos/__init__.py +0 -0
- julee/util/repos/minio/__init__.py +0 -0
- julee/util/repos/minio/file_storage.py +213 -0
- julee/util/repos/temporal/__init__.py +11 -0
- julee/util/repos/temporal/client_proxies/file_storage.py +68 -0
- julee/util/repos/temporal/data_converter.py +123 -0
- julee/util/repos/temporal/minio_file_storage.py +12 -0
- julee/util/repos/temporal/proxies/__init__.py +0 -0
- julee/util/repos/temporal/proxies/file_storage.py +58 -0
- julee/util/repositories.py +55 -0
- julee/util/temporal/__init__.py +22 -0
- julee/util/temporal/activities.py +123 -0
- julee/util/temporal/decorators.py +473 -0
- julee/util/tests/__init__.py +1 -0
- julee/util/tests/test_decorators.py +770 -0
- julee/util/validation/__init__.py +29 -0
- julee/util/validation/repository.py +100 -0
- julee/util/validation/type_guards.py +369 -0
- julee/worker.py +211 -0
- julee/workflows/__init__.py +26 -0
- julee/workflows/extract_assemble.py +215 -0
- julee/workflows/validate_document.py +228 -0
- julee-0.1.0.dist-info/METADATA +195 -0
- julee-0.1.0.dist-info/RECORD +161 -0
- julee-0.1.0.dist-info/WHEEL +5 -0
- julee-0.1.0.dist-info/licenses/LICENSE +674 -0
- julee-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for InitializeSystemDataUseCase.
|
|
3
|
+
|
|
4
|
+
This module tests the use case for initializing required system data,
|
|
5
|
+
ensuring it properly loads configurations from the YAML fixture file
|
|
6
|
+
and creates knowledge service configurations correctly.
|
|
7
|
+
|
|
8
|
+
These tests use the actual YAML fixture file to validate the real
|
|
9
|
+
integration rather than mocking the file system operations.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from datetime import datetime, timezone
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
import pytest
|
|
16
|
+
import yaml
|
|
17
|
+
|
|
18
|
+
from julee.domain.models.knowledge_service_config import (
|
|
19
|
+
KnowledgeServiceConfig,
|
|
20
|
+
ServiceApi,
|
|
21
|
+
)
|
|
22
|
+
from julee.domain.use_cases.initialize_system_data import (
|
|
23
|
+
InitializeSystemDataUseCase,
|
|
24
|
+
)
|
|
25
|
+
from julee.repositories.memory.assembly_specification import (
|
|
26
|
+
MemoryAssemblySpecificationRepository,
|
|
27
|
+
)
|
|
28
|
+
from julee.repositories.memory.document import (
|
|
29
|
+
MemoryDocumentRepository,
|
|
30
|
+
)
|
|
31
|
+
from julee.repositories.memory.knowledge_service_config import (
|
|
32
|
+
MemoryKnowledgeServiceConfigRepository,
|
|
33
|
+
)
|
|
34
|
+
from julee.repositories.memory.knowledge_service_query import (
|
|
35
|
+
MemoryKnowledgeServiceQueryRepository,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@pytest.fixture
|
|
40
|
+
def memory_config_repository() -> MemoryKnowledgeServiceConfigRepository:
|
|
41
|
+
"""Create memory knowledge service config repository."""
|
|
42
|
+
return MemoryKnowledgeServiceConfigRepository()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@pytest.fixture
|
|
46
|
+
def memory_document_repository() -> MemoryDocumentRepository:
|
|
47
|
+
"""Create memory document repository."""
|
|
48
|
+
return MemoryDocumentRepository()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@pytest.fixture
|
|
52
|
+
def memory_query_repository() -> MemoryKnowledgeServiceQueryRepository:
|
|
53
|
+
"""Create memory knowledge service query repository."""
|
|
54
|
+
return MemoryKnowledgeServiceQueryRepository()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@pytest.fixture
|
|
58
|
+
def memory_assembly_spec_repository() -> MemoryAssemblySpecificationRepository:
|
|
59
|
+
"""Create memory assembly specification repository."""
|
|
60
|
+
return MemoryAssemblySpecificationRepository()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@pytest.fixture
|
|
64
|
+
def use_case(
|
|
65
|
+
memory_config_repository: MemoryKnowledgeServiceConfigRepository,
|
|
66
|
+
memory_document_repository: MemoryDocumentRepository,
|
|
67
|
+
memory_query_repository: MemoryKnowledgeServiceQueryRepository,
|
|
68
|
+
memory_assembly_spec_repository: MemoryAssemblySpecificationRepository,
|
|
69
|
+
) -> InitializeSystemDataUseCase:
|
|
70
|
+
"""Create use case with memory repositories."""
|
|
71
|
+
return InitializeSystemDataUseCase(
|
|
72
|
+
memory_config_repository,
|
|
73
|
+
memory_document_repository,
|
|
74
|
+
memory_query_repository,
|
|
75
|
+
memory_assembly_spec_repository,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@pytest.fixture
|
|
80
|
+
def fixture_configs() -> list[dict]:
|
|
81
|
+
"""Load actual configurations from YAML fixture file."""
|
|
82
|
+
# Get the fixture file path
|
|
83
|
+
current_file = Path(__file__)
|
|
84
|
+
julee_dir = current_file.parent.parent.parent.parent
|
|
85
|
+
fixture_path = julee_dir / "fixtures" / "knowledge_service_configs.yaml"
|
|
86
|
+
|
|
87
|
+
assert fixture_path.exists(), f"Fixture file not found: {fixture_path}"
|
|
88
|
+
|
|
89
|
+
with open(fixture_path, "r", encoding="utf-8") as f:
|
|
90
|
+
fixture_data = yaml.safe_load(f)
|
|
91
|
+
|
|
92
|
+
assert "knowledge_services" in fixture_data
|
|
93
|
+
assert isinstance(fixture_data["knowledge_services"], list)
|
|
94
|
+
assert len(fixture_data["knowledge_services"]) > 0
|
|
95
|
+
|
|
96
|
+
return fixture_data["knowledge_services"]
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@pytest.fixture
|
|
100
|
+
def sample_anthropic_config() -> KnowledgeServiceConfig:
|
|
101
|
+
"""Create sample Anthropic configuration."""
|
|
102
|
+
return KnowledgeServiceConfig(
|
|
103
|
+
knowledge_service_id="anthropic-claude",
|
|
104
|
+
name="Anthropic Claude",
|
|
105
|
+
description="Claude 3 for general text analysis and extraction",
|
|
106
|
+
service_api=ServiceApi.ANTHROPIC,
|
|
107
|
+
created_at=datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc),
|
|
108
|
+
updated_at=datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc),
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class TestInitializeSystemDataUseCase:
|
|
113
|
+
"""Test the InitializeSystemDataUseCase."""
|
|
114
|
+
|
|
115
|
+
@pytest.mark.asyncio
|
|
116
|
+
async def test_execute_success_creates_configs_from_fixture(
|
|
117
|
+
self,
|
|
118
|
+
use_case: InitializeSystemDataUseCase,
|
|
119
|
+
memory_config_repository: MemoryKnowledgeServiceConfigRepository,
|
|
120
|
+
fixture_configs: list[dict],
|
|
121
|
+
) -> None:
|
|
122
|
+
"""Test successful execution creates configs from fixture."""
|
|
123
|
+
# Execute use case
|
|
124
|
+
await use_case.execute()
|
|
125
|
+
|
|
126
|
+
# Verify all configs were created
|
|
127
|
+
saved_configs = await memory_config_repository.list_all()
|
|
128
|
+
assert len(saved_configs) == len(fixture_configs)
|
|
129
|
+
|
|
130
|
+
# Verify configs were created with correct IDs from fixture
|
|
131
|
+
|
|
132
|
+
saved_ids = {config.knowledge_service_id for config in saved_configs}
|
|
133
|
+
expected_ids = {config["knowledge_service_id"] for config in fixture_configs}
|
|
134
|
+
assert saved_ids == expected_ids
|
|
135
|
+
|
|
136
|
+
# Verify first config matches fixture data
|
|
137
|
+
first_fixture = fixture_configs[0]
|
|
138
|
+
first_saved = next(
|
|
139
|
+
config
|
|
140
|
+
for config in saved_configs
|
|
141
|
+
if config.knowledge_service_id == first_fixture["knowledge_service_id"]
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
assert first_saved.name == first_fixture["name"]
|
|
145
|
+
assert first_saved.description == first_fixture["description"]
|
|
146
|
+
assert first_saved.service_api.value == first_fixture["service_api"]
|
|
147
|
+
|
|
148
|
+
@pytest.mark.asyncio
|
|
149
|
+
async def test_execute_success_configs_already_exist(
|
|
150
|
+
self,
|
|
151
|
+
use_case: InitializeSystemDataUseCase,
|
|
152
|
+
memory_config_repository: MemoryKnowledgeServiceConfigRepository,
|
|
153
|
+
sample_anthropic_config: KnowledgeServiceConfig,
|
|
154
|
+
) -> None:
|
|
155
|
+
"""Test successful execution when configs already exist."""
|
|
156
|
+
# Setup - add existing config to repository
|
|
157
|
+
await memory_config_repository.save(sample_anthropic_config)
|
|
158
|
+
|
|
159
|
+
# Execute use case
|
|
160
|
+
await use_case.execute()
|
|
161
|
+
|
|
162
|
+
# Verify only the existing config is in the repository (no duplicates)
|
|
163
|
+
all_configs = await memory_config_repository.list_all()
|
|
164
|
+
config_ids = [c.knowledge_service_id for c in all_configs]
|
|
165
|
+
assert sample_anthropic_config.knowledge_service_id in config_ids
|
|
166
|
+
|
|
167
|
+
@pytest.mark.asyncio
|
|
168
|
+
async def test_execute_mixed_existing_and_new_configs(
|
|
169
|
+
self,
|
|
170
|
+
use_case: InitializeSystemDataUseCase,
|
|
171
|
+
memory_config_repository: MemoryKnowledgeServiceConfigRepository,
|
|
172
|
+
sample_anthropic_config: KnowledgeServiceConfig,
|
|
173
|
+
fixture_configs: list[dict],
|
|
174
|
+
) -> None:
|
|
175
|
+
"""Test execution with mix of existing and new configs."""
|
|
176
|
+
# Setup - add one existing config to repository
|
|
177
|
+
await memory_config_repository.save(sample_anthropic_config)
|
|
178
|
+
|
|
179
|
+
# Execute use case
|
|
180
|
+
await use_case.execute()
|
|
181
|
+
|
|
182
|
+
# Verify all configs from fixture exist (including pre-existing one)
|
|
183
|
+
final_configs = await memory_config_repository.list_all()
|
|
184
|
+
final_count = len(final_configs)
|
|
185
|
+
|
|
186
|
+
# Should have all fixture configs (some were new, one already existed)
|
|
187
|
+
expected_total = len(fixture_configs)
|
|
188
|
+
assert final_count >= expected_total
|
|
189
|
+
|
|
190
|
+
# Verify the existing config is still there
|
|
191
|
+
config_ids = [c.knowledge_service_id for c in final_configs]
|
|
192
|
+
assert sample_anthropic_config.knowledge_service_id in config_ids
|
|
193
|
+
|
|
194
|
+
# NOTE: Error handling tests commented out as they don't work well with
|
|
195
|
+
# memory repositories. These would need mock repositories or integration
|
|
196
|
+
# tests with actual Minio failures to test error scenarios properly.
|
|
197
|
+
|
|
198
|
+
# @pytest.mark.asyncio
|
|
199
|
+
# async def test_execute_handles_repository_get_error(...)
|
|
200
|
+
# @pytest.mark.asyncio
|
|
201
|
+
# async def test_execute_handles_repository_save_error(...)
|
|
202
|
+
|
|
203
|
+
@pytest.mark.asyncio
|
|
204
|
+
async def test_config_creation_uses_correct_values_from_fixture(
|
|
205
|
+
self,
|
|
206
|
+
use_case: InitializeSystemDataUseCase,
|
|
207
|
+
memory_config_repository: MemoryKnowledgeServiceConfigRepository,
|
|
208
|
+
fixture_configs: list[dict],
|
|
209
|
+
) -> None:
|
|
210
|
+
"""Test that created configs have correct values from fixture."""
|
|
211
|
+
# Execute use case
|
|
212
|
+
await use_case.execute()
|
|
213
|
+
|
|
214
|
+
# Get all saved configs
|
|
215
|
+
saved_configs = await memory_config_repository.list_all()
|
|
216
|
+
|
|
217
|
+
# Verify each saved config matches fixture data
|
|
218
|
+
for fixture_config in fixture_configs:
|
|
219
|
+
saved_config = next(
|
|
220
|
+
config
|
|
221
|
+
for config in saved_configs
|
|
222
|
+
if config.knowledge_service_id == fixture_config["knowledge_service_id"]
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
# Verify all fixture values are correctly applied
|
|
226
|
+
assert (
|
|
227
|
+
saved_config.knowledge_service_id
|
|
228
|
+
== fixture_config["knowledge_service_id"]
|
|
229
|
+
)
|
|
230
|
+
assert saved_config.name == fixture_config["name"]
|
|
231
|
+
assert saved_config.description == fixture_config["description"]
|
|
232
|
+
assert saved_config.service_api.value == fixture_config["service_api"]
|
|
233
|
+
assert saved_config.created_at is not None
|
|
234
|
+
assert saved_config.updated_at is not None
|
|
235
|
+
assert isinstance(saved_config.created_at, datetime)
|
|
236
|
+
assert isinstance(saved_config.updated_at, datetime)
|
|
237
|
+
|
|
238
|
+
@pytest.mark.asyncio
|
|
239
|
+
async def test_use_case_is_idempotent(
|
|
240
|
+
self,
|
|
241
|
+
use_case: InitializeSystemDataUseCase,
|
|
242
|
+
memory_config_repository: MemoryKnowledgeServiceConfigRepository,
|
|
243
|
+
fixture_configs: list[dict],
|
|
244
|
+
) -> None:
|
|
245
|
+
"""Test that running the use case multiple times is safe."""
|
|
246
|
+
# First run - configs don't exist, get created
|
|
247
|
+
await use_case.execute()
|
|
248
|
+
first_run_configs = await memory_config_repository.list_all()
|
|
249
|
+
first_run_count = len(first_run_configs)
|
|
250
|
+
|
|
251
|
+
# Second run - configs now exist, should not create duplicates
|
|
252
|
+
await use_case.execute()
|
|
253
|
+
second_run_configs = await memory_config_repository.list_all()
|
|
254
|
+
second_run_count = len(second_run_configs)
|
|
255
|
+
|
|
256
|
+
# Verify idempotency - same number of configs after second run
|
|
257
|
+
assert first_run_count == second_run_count
|
|
258
|
+
|
|
259
|
+
# Verify all fixture configs are present
|
|
260
|
+
config_ids = [c.knowledge_service_id for c in second_run_configs]
|
|
261
|
+
for fixture_config in fixture_configs:
|
|
262
|
+
assert fixture_config["knowledge_service_id"] in config_ids
|
|
263
|
+
|
|
264
|
+
def test_use_case_initialization(
|
|
265
|
+
self,
|
|
266
|
+
memory_config_repository: MemoryKnowledgeServiceConfigRepository,
|
|
267
|
+
memory_document_repository: MemoryDocumentRepository,
|
|
268
|
+
memory_query_repository: MemoryKnowledgeServiceQueryRepository,
|
|
269
|
+
memory_assembly_spec_repository: MemoryAssemblySpecificationRepository,
|
|
270
|
+
) -> None:
|
|
271
|
+
"""Test use case initialization with repositories."""
|
|
272
|
+
use_case = InitializeSystemDataUseCase(
|
|
273
|
+
memory_config_repository,
|
|
274
|
+
memory_document_repository,
|
|
275
|
+
memory_query_repository,
|
|
276
|
+
memory_assembly_spec_repository,
|
|
277
|
+
)
|
|
278
|
+
assert use_case.config_repo is memory_config_repository
|
|
279
|
+
assert use_case.document_repo is memory_document_repository
|
|
280
|
+
assert use_case.query_repo is memory_query_repository
|
|
281
|
+
assert use_case.assembly_spec_repo is memory_assembly_spec_repository
|
|
282
|
+
assert use_case.logger is not None
|
|
283
|
+
|
|
284
|
+
@pytest.mark.asyncio
|
|
285
|
+
async def test_config_initialization_only(
|
|
286
|
+
self,
|
|
287
|
+
memory_config_repository: MemoryKnowledgeServiceConfigRepository,
|
|
288
|
+
memory_document_repository: MemoryDocumentRepository,
|
|
289
|
+
memory_query_repository: MemoryKnowledgeServiceQueryRepository,
|
|
290
|
+
memory_assembly_spec_repository: MemoryAssemblySpecificationRepository,
|
|
291
|
+
fixture_configs: list[dict],
|
|
292
|
+
) -> None:
|
|
293
|
+
"""Test only the config initialization part."""
|
|
294
|
+
use_case = InitializeSystemDataUseCase(
|
|
295
|
+
memory_config_repository,
|
|
296
|
+
memory_document_repository,
|
|
297
|
+
memory_query_repository,
|
|
298
|
+
memory_assembly_spec_repository,
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
# Execute the use case to initialize configs
|
|
302
|
+
await use_case.execute()
|
|
303
|
+
|
|
304
|
+
# Verify configs were created
|
|
305
|
+
saved_configs = await memory_config_repository.list_all()
|
|
306
|
+
assert len(saved_configs) == len(fixture_configs)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
class TestYamlFixtureIntegration:
|
|
310
|
+
"""Test integration with actual YAML fixture file."""
|
|
311
|
+
|
|
312
|
+
def test_fixture_file_exists_and_is_valid(self) -> None:
|
|
313
|
+
"""Test that the fixture file exists and contains valid data."""
|
|
314
|
+
# Get the fixture file path
|
|
315
|
+
current_file = Path(__file__)
|
|
316
|
+
julee_dir = current_file.parent.parent.parent.parent
|
|
317
|
+
fixture_path = julee_dir / "fixtures" / "knowledge_service_configs.yaml"
|
|
318
|
+
|
|
319
|
+
# Verify file exists
|
|
320
|
+
assert fixture_path.exists(), f"Fixture file not found: {fixture_path}"
|
|
321
|
+
|
|
322
|
+
# Verify file can be parsed
|
|
323
|
+
with open(fixture_path, "r", encoding="utf-8") as f:
|
|
324
|
+
fixture_data = yaml.safe_load(f)
|
|
325
|
+
|
|
326
|
+
# Verify structure
|
|
327
|
+
assert isinstance(fixture_data, dict)
|
|
328
|
+
assert "knowledge_services" in fixture_data
|
|
329
|
+
assert isinstance(fixture_data["knowledge_services"], list)
|
|
330
|
+
assert len(fixture_data["knowledge_services"]) > 0
|
|
331
|
+
|
|
332
|
+
def test_fixture_configs_have_required_fields(
|
|
333
|
+
self, fixture_configs: list[dict]
|
|
334
|
+
) -> None:
|
|
335
|
+
"""Test that all fixture configs have required fields."""
|
|
336
|
+
required_fields = [
|
|
337
|
+
"knowledge_service_id",
|
|
338
|
+
"name",
|
|
339
|
+
"description",
|
|
340
|
+
"service_api",
|
|
341
|
+
]
|
|
342
|
+
|
|
343
|
+
for config in fixture_configs:
|
|
344
|
+
for field in required_fields:
|
|
345
|
+
assert field in config, (
|
|
346
|
+
f"Missing required field '{field}' in config "
|
|
347
|
+
f"{config.get('knowledge_service_id', 'unknown')}"
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
# Verify service_api is valid
|
|
351
|
+
assert config["service_api"] in [api.value for api in ServiceApi], (
|
|
352
|
+
f"Invalid service_api '{config['service_api']}' in config "
|
|
353
|
+
f"{config['knowledge_service_id']}"
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
# Verify IDs are not empty
|
|
357
|
+
assert config["knowledge_service_id"].strip(), "Empty knowledge_service_id"
|
|
358
|
+
assert config["name"].strip(), "Empty name"
|
|
359
|
+
assert config["description"].strip(), "Empty description"
|
|
360
|
+
|
|
361
|
+
def test_fixture_configs_have_unique_ids(self, fixture_configs: list[dict]) -> None:
|
|
362
|
+
"""Test that all fixture configs have unique IDs."""
|
|
363
|
+
config_ids = [config["knowledge_service_id"] for config in fixture_configs]
|
|
364
|
+
assert len(config_ids) == len(
|
|
365
|
+
set(config_ids)
|
|
366
|
+
), "Duplicate knowledge_service_id found in fixture"
|
|
367
|
+
|
|
368
|
+
@pytest.mark.asyncio
|
|
369
|
+
async def test_load_fixture_configurations_method(
|
|
370
|
+
self, use_case: InitializeSystemDataUseCase
|
|
371
|
+
) -> None:
|
|
372
|
+
"""Test the _load_fixture_configurations method directly."""
|
|
373
|
+
configs = use_case._load_fixture_configurations()
|
|
374
|
+
|
|
375
|
+
assert isinstance(configs, list)
|
|
376
|
+
assert len(configs) > 0
|
|
377
|
+
|
|
378
|
+
# Verify each config has required structure
|
|
379
|
+
for config in configs:
|
|
380
|
+
assert isinstance(config, dict)
|
|
381
|
+
assert "knowledge_service_id" in config
|
|
382
|
+
assert "name" in config
|
|
383
|
+
assert "description" in config
|
|
384
|
+
assert "service_api" in config
|
|
385
|
+
|
|
386
|
+
@pytest.mark.asyncio
|
|
387
|
+
async def test_create_config_from_fixture_data_method(
|
|
388
|
+
self,
|
|
389
|
+
use_case: InitializeSystemDataUseCase,
|
|
390
|
+
fixture_configs: list[dict],
|
|
391
|
+
) -> None:
|
|
392
|
+
"""Test the _create_config_from_fixture_data method directly."""
|
|
393
|
+
fixture_config = fixture_configs[0]
|
|
394
|
+
|
|
395
|
+
created_config = use_case._create_config_from_fixture_data(fixture_config)
|
|
396
|
+
|
|
397
|
+
assert isinstance(created_config, KnowledgeServiceConfig)
|
|
398
|
+
assert (
|
|
399
|
+
created_config.knowledge_service_id
|
|
400
|
+
== fixture_config["knowledge_service_id"]
|
|
401
|
+
)
|
|
402
|
+
assert created_config.name == fixture_config["name"]
|
|
403
|
+
assert created_config.description == fixture_config["description"]
|
|
404
|
+
assert created_config.service_api.value == fixture_config["service_api"]
|
|
405
|
+
assert created_config.created_at is not None
|
|
406
|
+
assert created_config.updated_at is not None
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
class TestInitializeSystemDataUseCaseIntegration:
|
|
410
|
+
"""Integration-style tests for the use case."""
|
|
411
|
+
|
|
412
|
+
@pytest.mark.asyncio
|
|
413
|
+
async def test_full_workflow_new_system(
|
|
414
|
+
self,
|
|
415
|
+
use_case: InitializeSystemDataUseCase,
|
|
416
|
+
memory_config_repository: MemoryKnowledgeServiceConfigRepository,
|
|
417
|
+
fixture_configs: list[dict],
|
|
418
|
+
) -> None:
|
|
419
|
+
"""Test complete workflow for a new system with no existing data."""
|
|
420
|
+
# Setup - repository starts empty
|
|
421
|
+
|
|
422
|
+
# Execute initialization
|
|
423
|
+
await use_case.execute()
|
|
424
|
+
|
|
425
|
+
# Verify all configs were created
|
|
426
|
+
saved_configs = await memory_config_repository.list_all()
|
|
427
|
+
assert len(saved_configs) == len(fixture_configs)
|
|
428
|
+
|
|
429
|
+
# Verify configs were created with correct IDs from fixture
|
|
430
|
+
saved_ids = {config.knowledge_service_id for config in saved_configs}
|
|
431
|
+
expected_ids = {config["knowledge_service_id"] for config in fixture_configs}
|
|
432
|
+
assert saved_ids == expected_ids
|
|
433
|
+
|
|
434
|
+
@pytest.mark.asyncio
|
|
435
|
+
async def test_full_workflow_existing_system(
|
|
436
|
+
self,
|
|
437
|
+
use_case: InitializeSystemDataUseCase,
|
|
438
|
+
memory_config_repository: MemoryKnowledgeServiceConfigRepository,
|
|
439
|
+
sample_anthropic_config: KnowledgeServiceConfig,
|
|
440
|
+
fixture_configs: list[dict],
|
|
441
|
+
) -> None:
|
|
442
|
+
"""Test complete workflow for existing system with data present."""
|
|
443
|
+
# Setup - add existing config to repository
|
|
444
|
+
await memory_config_repository.save(sample_anthropic_config)
|
|
445
|
+
|
|
446
|
+
# Execute initialization
|
|
447
|
+
await use_case.execute()
|
|
448
|
+
|
|
449
|
+
# Verify configs exist and no duplicates were created
|
|
450
|
+
final_configs = await memory_config_repository.list_all()
|
|
451
|
+
|
|
452
|
+
# Should have all fixture configs (including pre-existing)
|
|
453
|
+
config_ids = [c.knowledge_service_id for c in final_configs]
|
|
454
|
+
assert sample_anthropic_config.knowledge_service_id in config_ids
|
|
455
|
+
assert len(final_configs) >= len(fixture_configs)
|