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,192 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for MinioDocumentPolicyValidationRepository implementation.
|
|
3
|
+
|
|
4
|
+
This module provides tests for the Minio-based document policy validation
|
|
5
|
+
repository implementation, focusing on functionality specific to this
|
|
6
|
+
repository that differs from the inherited mixins. Uses the fake client to
|
|
7
|
+
avoid external dependencies during testing.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
from datetime import datetime, timezone
|
|
12
|
+
|
|
13
|
+
from julee.domain.models.policy import (
|
|
14
|
+
DocumentPolicyValidation,
|
|
15
|
+
DocumentPolicyValidationStatus,
|
|
16
|
+
)
|
|
17
|
+
from julee.repositories.minio.document_policy_validation import (
|
|
18
|
+
MinioDocumentPolicyValidationRepository,
|
|
19
|
+
)
|
|
20
|
+
from .fake_client import FakeMinioClient
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@pytest.fixture
|
|
24
|
+
def fake_client() -> FakeMinioClient:
|
|
25
|
+
"""Create a fresh fake Minio client for each test."""
|
|
26
|
+
return FakeMinioClient()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@pytest.fixture
|
|
30
|
+
def validation_repo(
|
|
31
|
+
fake_client: FakeMinioClient,
|
|
32
|
+
) -> MinioDocumentPolicyValidationRepository:
|
|
33
|
+
"""Create validation repository with fake client."""
|
|
34
|
+
return MinioDocumentPolicyValidationRepository(fake_client)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@pytest.fixture
|
|
38
|
+
def sample_validation() -> DocumentPolicyValidation:
|
|
39
|
+
"""Create a sample document policy validation for testing."""
|
|
40
|
+
return DocumentPolicyValidation(
|
|
41
|
+
validation_id="validation-test-123",
|
|
42
|
+
input_document_id="doc-123",
|
|
43
|
+
policy_id="policy-456",
|
|
44
|
+
status=DocumentPolicyValidationStatus.PASSED,
|
|
45
|
+
validation_scores=[
|
|
46
|
+
("quality-check-query", 85),
|
|
47
|
+
("completeness-check", 92),
|
|
48
|
+
],
|
|
49
|
+
transformed_document_id="doc-123-transformed",
|
|
50
|
+
post_transform_validation_scores=[
|
|
51
|
+
("quality-check-query", 95),
|
|
52
|
+
("completeness-check", 88),
|
|
53
|
+
],
|
|
54
|
+
started_at=datetime.now(timezone.utc),
|
|
55
|
+
completed_at=datetime.now(timezone.utc),
|
|
56
|
+
passed=True,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class TestMinioDocumentPolicyValidationRepositorySpecific:
|
|
61
|
+
"""Test functionality specific to DocumentPolicyValidation Minio
|
|
62
|
+
repository."""
|
|
63
|
+
|
|
64
|
+
@pytest.mark.asyncio
|
|
65
|
+
async def test_initialization_creates_correct_bucket(
|
|
66
|
+
self, fake_client: FakeMinioClient
|
|
67
|
+
) -> None:
|
|
68
|
+
"""Test that repository initialization creates the correct bucket."""
|
|
69
|
+
# Check bucket doesn't exist initially
|
|
70
|
+
assert "document-policy-validations" not in fake_client._buckets
|
|
71
|
+
|
|
72
|
+
# Create repository - should create bucket
|
|
73
|
+
repo = MinioDocumentPolicyValidationRepository(fake_client)
|
|
74
|
+
|
|
75
|
+
# Check bucket was created
|
|
76
|
+
assert "document-policy-validations" in fake_client._buckets
|
|
77
|
+
assert repo.validations_bucket == "document-policy-validations"
|
|
78
|
+
|
|
79
|
+
@pytest.mark.asyncio
|
|
80
|
+
async def test_generate_id_prefix(
|
|
81
|
+
self, validation_repo: MinioDocumentPolicyValidationRepository
|
|
82
|
+
) -> None:
|
|
83
|
+
"""Test that generated IDs use the correct prefix for validations."""
|
|
84
|
+
id1 = await validation_repo.generate_id()
|
|
85
|
+
id2 = await validation_repo.generate_id()
|
|
86
|
+
|
|
87
|
+
assert isinstance(id1, str)
|
|
88
|
+
assert isinstance(id2, str)
|
|
89
|
+
assert id1 != id2
|
|
90
|
+
assert len(id1) > 0
|
|
91
|
+
assert len(id2) > 0
|
|
92
|
+
assert id1.startswith("validation-")
|
|
93
|
+
assert id2.startswith("validation-")
|
|
94
|
+
|
|
95
|
+
@pytest.mark.asyncio
|
|
96
|
+
async def test_save_and_retrieve_validation(
|
|
97
|
+
self,
|
|
98
|
+
validation_repo: MinioDocumentPolicyValidationRepository,
|
|
99
|
+
sample_validation: DocumentPolicyValidation,
|
|
100
|
+
) -> None:
|
|
101
|
+
"""Test that save and retrieve operations work correctly."""
|
|
102
|
+
# Save the validation
|
|
103
|
+
await validation_repo.save(sample_validation)
|
|
104
|
+
|
|
105
|
+
# Retrieve and verify all fields are preserved
|
|
106
|
+
retrieved = await validation_repo.get(sample_validation.validation_id)
|
|
107
|
+
|
|
108
|
+
assert retrieved is not None
|
|
109
|
+
assert retrieved.validation_id == sample_validation.validation_id
|
|
110
|
+
assert retrieved.input_document_id == sample_validation.input_document_id
|
|
111
|
+
assert retrieved.policy_id == sample_validation.policy_id
|
|
112
|
+
assert retrieved.status == sample_validation.status
|
|
113
|
+
assert retrieved.validation_scores == sample_validation.validation_scores
|
|
114
|
+
assert (
|
|
115
|
+
retrieved.transformed_document_id
|
|
116
|
+
== sample_validation.transformed_document_id
|
|
117
|
+
)
|
|
118
|
+
assert (
|
|
119
|
+
retrieved.post_transform_validation_scores
|
|
120
|
+
== sample_validation.post_transform_validation_scores
|
|
121
|
+
)
|
|
122
|
+
assert retrieved.passed == sample_validation.passed
|
|
123
|
+
|
|
124
|
+
@pytest.mark.asyncio
|
|
125
|
+
async def test_get_nonexistent_validation_returns_none(
|
|
126
|
+
self, validation_repo: MinioDocumentPolicyValidationRepository
|
|
127
|
+
) -> None:
|
|
128
|
+
"""Test retrieving a non-existent validation returns None."""
|
|
129
|
+
result = await validation_repo.get("nonexistent-validation")
|
|
130
|
+
assert result is None
|
|
131
|
+
|
|
132
|
+
@pytest.mark.asyncio
|
|
133
|
+
async def test_save_preserves_timestamps(
|
|
134
|
+
self, validation_repo: MinioDocumentPolicyValidationRepository
|
|
135
|
+
) -> None:
|
|
136
|
+
"""Test that save operation preserves existing timestamps."""
|
|
137
|
+
# Create validation with specific timestamps
|
|
138
|
+
original_time = datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc)
|
|
139
|
+
validation = DocumentPolicyValidation(
|
|
140
|
+
validation_id="validation-timestamp-test",
|
|
141
|
+
input_document_id="doc-timestamp",
|
|
142
|
+
policy_id="policy-timestamp",
|
|
143
|
+
status=DocumentPolicyValidationStatus.PENDING,
|
|
144
|
+
validation_scores=[],
|
|
145
|
+
started_at=original_time,
|
|
146
|
+
completed_at=None,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
# Save and retrieve the validation
|
|
150
|
+
await validation_repo.save(validation)
|
|
151
|
+
retrieved = await validation_repo.get("validation-timestamp-test")
|
|
152
|
+
|
|
153
|
+
# Check that timestamps are preserved correctly
|
|
154
|
+
assert retrieved is not None
|
|
155
|
+
assert retrieved.started_at == original_time
|
|
156
|
+
assert retrieved.completed_at is None
|
|
157
|
+
|
|
158
|
+
@pytest.mark.asyncio
|
|
159
|
+
async def test_save_with_transformation_data(
|
|
160
|
+
self, validation_repo: MinioDocumentPolicyValidationRepository
|
|
161
|
+
) -> None:
|
|
162
|
+
"""Test saving and retrieving validation with transformation data."""
|
|
163
|
+
validation_with_transforms = DocumentPolicyValidation(
|
|
164
|
+
validation_id="validation-transform-test",
|
|
165
|
+
input_document_id="doc-original",
|
|
166
|
+
policy_id="policy-transform",
|
|
167
|
+
status=DocumentPolicyValidationStatus.TRANSFORMATION_COMPLETE,
|
|
168
|
+
validation_scores=[("initial-check", 70)],
|
|
169
|
+
transformed_document_id="doc-transformed",
|
|
170
|
+
post_transform_validation_scores=[("final-check", 85)],
|
|
171
|
+
passed=True,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Save and retrieve the validation
|
|
175
|
+
await validation_repo.save(validation_with_transforms)
|
|
176
|
+
retrieved = await validation_repo.get("validation-transform-test")
|
|
177
|
+
|
|
178
|
+
# Verify transformation data is preserved
|
|
179
|
+
assert retrieved is not None
|
|
180
|
+
assert retrieved.transformed_document_id == "doc-transformed"
|
|
181
|
+
assert retrieved.post_transform_validation_scores == [("final-check", 85)]
|
|
182
|
+
assert retrieved.passed is True
|
|
183
|
+
assert retrieved.validation_scores == [("initial-check", 70)]
|
|
184
|
+
|
|
185
|
+
@pytest.mark.asyncio
|
|
186
|
+
async def test_repository_logger_configuration(
|
|
187
|
+
self, validation_repo: MinioDocumentPolicyValidationRepository
|
|
188
|
+
) -> None:
|
|
189
|
+
"""Test that repository logger is configured correctly."""
|
|
190
|
+
assert validation_repo.logger is not None
|
|
191
|
+
# Logger name should reflect the repository class
|
|
192
|
+
assert "MinioDocumentPolicyValidationRepository" in validation_repo.logger.name
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for MinioKnowledgeServiceConfigRepository implementation.
|
|
3
|
+
|
|
4
|
+
This module provides comprehensive tests for the Minio-based knowledge service
|
|
5
|
+
configuration repository implementation, using the fake client to avoid
|
|
6
|
+
external dependencies during testing.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
from datetime import datetime, timezone
|
|
11
|
+
|
|
12
|
+
from julee.domain.models.knowledge_service_config import (
|
|
13
|
+
KnowledgeServiceConfig,
|
|
14
|
+
)
|
|
15
|
+
from julee.domain.models.knowledge_service_config import ServiceApi
|
|
16
|
+
from julee.repositories.minio.knowledge_service_config import (
|
|
17
|
+
MinioKnowledgeServiceConfigRepository,
|
|
18
|
+
)
|
|
19
|
+
from .fake_client import FakeMinioClient
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@pytest.fixture
|
|
23
|
+
def fake_client() -> FakeMinioClient:
|
|
24
|
+
"""Create a fresh fake Minio client for each test."""
|
|
25
|
+
return FakeMinioClient()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@pytest.fixture
|
|
29
|
+
def knowledge_service_config_repo(
|
|
30
|
+
fake_client: FakeMinioClient,
|
|
31
|
+
) -> MinioKnowledgeServiceConfigRepository:
|
|
32
|
+
"""Create knowledge service config repository with fake client."""
|
|
33
|
+
return MinioKnowledgeServiceConfigRepository(fake_client)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@pytest.fixture
|
|
37
|
+
def sample_knowledge_service_config() -> KnowledgeServiceConfig:
|
|
38
|
+
"""Create a sample knowledge service config for testing."""
|
|
39
|
+
return KnowledgeServiceConfig(
|
|
40
|
+
knowledge_service_id="ks-test-123",
|
|
41
|
+
name="Test Anthropic Service",
|
|
42
|
+
description="A test knowledge service using Anthropic API",
|
|
43
|
+
service_api=ServiceApi.ANTHROPIC,
|
|
44
|
+
created_at=datetime.now(timezone.utc),
|
|
45
|
+
updated_at=datetime.now(timezone.utc),
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class TestMinioKnowledgeServiceConfigRepositoryBasicOperations:
|
|
50
|
+
"""Test basic CRUD operations on knowledge service configurations."""
|
|
51
|
+
|
|
52
|
+
@pytest.mark.asyncio
|
|
53
|
+
async def test_save_and_get_knowledge_service_config(
|
|
54
|
+
self,
|
|
55
|
+
knowledge_service_config_repo: MinioKnowledgeServiceConfigRepository,
|
|
56
|
+
sample_knowledge_service_config: KnowledgeServiceConfig,
|
|
57
|
+
) -> None:
|
|
58
|
+
"""Test saving and retrieving a knowledge service configuration."""
|
|
59
|
+
# Save knowledge service config
|
|
60
|
+
await knowledge_service_config_repo.save(sample_knowledge_service_config)
|
|
61
|
+
|
|
62
|
+
# Retrieve knowledge service config
|
|
63
|
+
retrieved = await knowledge_service_config_repo.get(
|
|
64
|
+
sample_knowledge_service_config.knowledge_service_id
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
assert retrieved is not None
|
|
68
|
+
assert (
|
|
69
|
+
retrieved.knowledge_service_id
|
|
70
|
+
== sample_knowledge_service_config.knowledge_service_id
|
|
71
|
+
)
|
|
72
|
+
assert retrieved.name == sample_knowledge_service_config.name
|
|
73
|
+
assert retrieved.description == sample_knowledge_service_config.description
|
|
74
|
+
assert retrieved.service_api == sample_knowledge_service_config.service_api
|
|
75
|
+
assert retrieved.created_at is not None
|
|
76
|
+
assert retrieved.updated_at is not None
|
|
77
|
+
|
|
78
|
+
@pytest.mark.asyncio
|
|
79
|
+
async def test_get_nonexistent_knowledge_service_config(
|
|
80
|
+
self,
|
|
81
|
+
knowledge_service_config_repo: MinioKnowledgeServiceConfigRepository,
|
|
82
|
+
) -> None:
|
|
83
|
+
"""Test retrieving a non-existent knowledge service config returns
|
|
84
|
+
None."""
|
|
85
|
+
result = await knowledge_service_config_repo.get("nonexistent-ks-config")
|
|
86
|
+
assert result is None
|
|
87
|
+
|
|
88
|
+
@pytest.mark.asyncio
|
|
89
|
+
async def test_generate_id(
|
|
90
|
+
self,
|
|
91
|
+
knowledge_service_config_repo: MinioKnowledgeServiceConfigRepository,
|
|
92
|
+
) -> None:
|
|
93
|
+
"""Test generating unique knowledge service configuration IDs."""
|
|
94
|
+
id1 = await knowledge_service_config_repo.generate_id()
|
|
95
|
+
id2 = await knowledge_service_config_repo.generate_id()
|
|
96
|
+
|
|
97
|
+
assert isinstance(id1, str)
|
|
98
|
+
assert isinstance(id2, str)
|
|
99
|
+
assert id1 != id2
|
|
100
|
+
assert len(id1) > 0
|
|
101
|
+
assert len(id2) > 0
|
|
102
|
+
assert id1.startswith("ks-")
|
|
103
|
+
assert id2.startswith("ks-")
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class TestMinioKnowledgeServiceConfigRepositoryUpdates:
|
|
107
|
+
"""Test knowledge service configuration update operations."""
|
|
108
|
+
|
|
109
|
+
@pytest.mark.asyncio
|
|
110
|
+
async def test_update_knowledge_service_config(
|
|
111
|
+
self,
|
|
112
|
+
knowledge_service_config_repo: MinioKnowledgeServiceConfigRepository,
|
|
113
|
+
sample_knowledge_service_config: KnowledgeServiceConfig,
|
|
114
|
+
) -> None:
|
|
115
|
+
"""Test updating a knowledge service configuration."""
|
|
116
|
+
# Save initial config
|
|
117
|
+
await knowledge_service_config_repo.save(sample_knowledge_service_config)
|
|
118
|
+
|
|
119
|
+
# Update the config
|
|
120
|
+
sample_knowledge_service_config.name = "Updated Test Service"
|
|
121
|
+
sample_knowledge_service_config.description = (
|
|
122
|
+
"Updated description for the test service"
|
|
123
|
+
)
|
|
124
|
+
await knowledge_service_config_repo.save(sample_knowledge_service_config)
|
|
125
|
+
|
|
126
|
+
# Verify update
|
|
127
|
+
retrieved = await knowledge_service_config_repo.get(
|
|
128
|
+
sample_knowledge_service_config.knowledge_service_id
|
|
129
|
+
)
|
|
130
|
+
assert retrieved is not None
|
|
131
|
+
assert retrieved.name == "Updated Test Service"
|
|
132
|
+
assert retrieved.description == "Updated description for the test service"
|
|
133
|
+
assert retrieved.service_api == sample_knowledge_service_config.service_api
|
|
134
|
+
|
|
135
|
+
@pytest.mark.asyncio
|
|
136
|
+
async def test_save_updates_timestamp(
|
|
137
|
+
self,
|
|
138
|
+
knowledge_service_config_repo: MinioKnowledgeServiceConfigRepository,
|
|
139
|
+
sample_knowledge_service_config: KnowledgeServiceConfig,
|
|
140
|
+
) -> None:
|
|
141
|
+
"""Test that save operations update the updated_at timestamp."""
|
|
142
|
+
original_updated_at = sample_knowledge_service_config.updated_at
|
|
143
|
+
|
|
144
|
+
# Save config
|
|
145
|
+
await knowledge_service_config_repo.save(sample_knowledge_service_config)
|
|
146
|
+
|
|
147
|
+
# Retrieve and check timestamp was updated
|
|
148
|
+
retrieved = await knowledge_service_config_repo.get(
|
|
149
|
+
sample_knowledge_service_config.knowledge_service_id
|
|
150
|
+
)
|
|
151
|
+
assert retrieved is not None
|
|
152
|
+
assert retrieved.updated_at is not None
|
|
153
|
+
assert original_updated_at is not None
|
|
154
|
+
assert retrieved.updated_at > original_updated_at
|
|
155
|
+
|
|
156
|
+
@pytest.mark.asyncio
|
|
157
|
+
async def test_save_sets_created_at_for_new_config(
|
|
158
|
+
self,
|
|
159
|
+
knowledge_service_config_repo: MinioKnowledgeServiceConfigRepository,
|
|
160
|
+
) -> None:
|
|
161
|
+
"""Test that save operations set created_at for new configurations."""
|
|
162
|
+
# Create config without created_at
|
|
163
|
+
config = KnowledgeServiceConfig(
|
|
164
|
+
knowledge_service_id="ks-new-test",
|
|
165
|
+
name="New Test Service",
|
|
166
|
+
description="A new test service",
|
|
167
|
+
service_api=ServiceApi.ANTHROPIC,
|
|
168
|
+
created_at=None, # Explicitly set to None
|
|
169
|
+
updated_at=None, # Explicitly set to None
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
# Save config
|
|
173
|
+
await knowledge_service_config_repo.save(config)
|
|
174
|
+
|
|
175
|
+
# Retrieve and check timestamps were set
|
|
176
|
+
retrieved = await knowledge_service_config_repo.get("ks-new-test")
|
|
177
|
+
assert retrieved is not None
|
|
178
|
+
assert retrieved.created_at is not None
|
|
179
|
+
assert retrieved.updated_at is not None
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class TestMinioKnowledgeServiceConfigRepositoryIdempotency:
|
|
183
|
+
"""Test idempotent operations on knowledge service configurations."""
|
|
184
|
+
|
|
185
|
+
@pytest.mark.asyncio
|
|
186
|
+
async def test_save_idempotency(
|
|
187
|
+
self,
|
|
188
|
+
knowledge_service_config_repo: MinioKnowledgeServiceConfigRepository,
|
|
189
|
+
sample_knowledge_service_config: KnowledgeServiceConfig,
|
|
190
|
+
) -> None:
|
|
191
|
+
"""Test that saving the same config multiple times is idempotent."""
|
|
192
|
+
# Save config first time
|
|
193
|
+
await knowledge_service_config_repo.save(sample_knowledge_service_config)
|
|
194
|
+
|
|
195
|
+
# Get the config to check initial state
|
|
196
|
+
retrieved1 = await knowledge_service_config_repo.get(
|
|
197
|
+
sample_knowledge_service_config.knowledge_service_id
|
|
198
|
+
)
|
|
199
|
+
assert retrieved1 is not None
|
|
200
|
+
first_updated_at = retrieved1.updated_at
|
|
201
|
+
|
|
202
|
+
# Save same config again (should update timestamp but maintain other
|
|
203
|
+
# data)
|
|
204
|
+
await knowledge_service_config_repo.save(sample_knowledge_service_config)
|
|
205
|
+
|
|
206
|
+
# Verify config is still there with updated timestamp
|
|
207
|
+
retrieved2 = await knowledge_service_config_repo.get(
|
|
208
|
+
sample_knowledge_service_config.knowledge_service_id
|
|
209
|
+
)
|
|
210
|
+
assert retrieved2 is not None
|
|
211
|
+
assert (
|
|
212
|
+
retrieved2.knowledge_service_id
|
|
213
|
+
== sample_knowledge_service_config.knowledge_service_id
|
|
214
|
+
)
|
|
215
|
+
assert retrieved2.name == sample_knowledge_service_config.name
|
|
216
|
+
assert retrieved2.description == sample_knowledge_service_config.description
|
|
217
|
+
assert retrieved2.service_api == sample_knowledge_service_config.service_api
|
|
218
|
+
assert retrieved2.updated_at is not None
|
|
219
|
+
assert first_updated_at is not None
|
|
220
|
+
assert retrieved2.updated_at > first_updated_at
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
class TestMinioKnowledgeServiceConfigRepositoryServiceApiTypes:
|
|
224
|
+
"""Test handling of different service API types."""
|
|
225
|
+
|
|
226
|
+
@pytest.mark.asyncio
|
|
227
|
+
async def test_anthropic_service_api(
|
|
228
|
+
self,
|
|
229
|
+
knowledge_service_config_repo: MinioKnowledgeServiceConfigRepository,
|
|
230
|
+
) -> None:
|
|
231
|
+
"""Test saving and retrieving config with Anthropic service API."""
|
|
232
|
+
config = KnowledgeServiceConfig(
|
|
233
|
+
knowledge_service_id="ks-anthropic-test",
|
|
234
|
+
name="Anthropic Service",
|
|
235
|
+
description="Service using Anthropic API",
|
|
236
|
+
service_api=ServiceApi.ANTHROPIC,
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
await knowledge_service_config_repo.save(config)
|
|
240
|
+
retrieved = await knowledge_service_config_repo.get("ks-anthropic-test")
|
|
241
|
+
|
|
242
|
+
assert retrieved is not None
|
|
243
|
+
assert retrieved.service_api == ServiceApi.ANTHROPIC
|
|
244
|
+
assert retrieved.service_api.value == "anthropic"
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
class TestMinioKnowledgeServiceConfigRepositoryRoundtrip:
|
|
248
|
+
"""Test full round-trip scenarios."""
|
|
249
|
+
|
|
250
|
+
@pytest.mark.asyncio
|
|
251
|
+
async def test_full_knowledge_service_config_lifecycle(
|
|
252
|
+
self,
|
|
253
|
+
knowledge_service_config_repo: MinioKnowledgeServiceConfigRepository,
|
|
254
|
+
) -> None:
|
|
255
|
+
"""Test complete knowledge service config lifecycle."""
|
|
256
|
+
# Generate new config ID
|
|
257
|
+
config_id = await knowledge_service_config_repo.generate_id()
|
|
258
|
+
|
|
259
|
+
# Create and save initial config
|
|
260
|
+
config = KnowledgeServiceConfig(
|
|
261
|
+
knowledge_service_id=config_id,
|
|
262
|
+
name="Lifecycle Test Service",
|
|
263
|
+
description="Testing full lifecycle",
|
|
264
|
+
service_api=ServiceApi.ANTHROPIC,
|
|
265
|
+
)
|
|
266
|
+
await knowledge_service_config_repo.save(config)
|
|
267
|
+
|
|
268
|
+
# Retrieve and verify initial state
|
|
269
|
+
retrieved = await knowledge_service_config_repo.get(config_id)
|
|
270
|
+
assert retrieved is not None
|
|
271
|
+
assert retrieved.name == "Lifecycle Test Service"
|
|
272
|
+
assert retrieved.service_api == ServiceApi.ANTHROPIC
|
|
273
|
+
|
|
274
|
+
# Update the configuration
|
|
275
|
+
config.name = "Updated Lifecycle Service"
|
|
276
|
+
config.description = "Updated description after lifecycle test"
|
|
277
|
+
await knowledge_service_config_repo.save(config)
|
|
278
|
+
|
|
279
|
+
# Final verification
|
|
280
|
+
final_config = await knowledge_service_config_repo.get(config_id)
|
|
281
|
+
assert final_config is not None
|
|
282
|
+
assert final_config.name == "Updated Lifecycle Service"
|
|
283
|
+
assert final_config.description == "Updated description after lifecycle test"
|
|
284
|
+
assert final_config.service_api == ServiceApi.ANTHROPIC
|
|
285
|
+
assert final_config.created_at is not None
|
|
286
|
+
assert final_config.updated_at is not None
|
|
287
|
+
|
|
288
|
+
@pytest.mark.asyncio
|
|
289
|
+
async def test_multiple_configs_independence(
|
|
290
|
+
self,
|
|
291
|
+
knowledge_service_config_repo: MinioKnowledgeServiceConfigRepository,
|
|
292
|
+
) -> None:
|
|
293
|
+
"""Test that multiple configs are stored and retrieved
|
|
294
|
+
independently."""
|
|
295
|
+
# Create multiple configs
|
|
296
|
+
config1 = KnowledgeServiceConfig(
|
|
297
|
+
knowledge_service_id="ks-test-1",
|
|
298
|
+
name="Service One",
|
|
299
|
+
description="First test service",
|
|
300
|
+
service_api=ServiceApi.ANTHROPIC,
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
config2 = KnowledgeServiceConfig(
|
|
304
|
+
knowledge_service_id="ks-test-2",
|
|
305
|
+
name="Service Two",
|
|
306
|
+
description="Second test service",
|
|
307
|
+
service_api=ServiceApi.ANTHROPIC,
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
# Save both configs
|
|
311
|
+
await knowledge_service_config_repo.save(config1)
|
|
312
|
+
await knowledge_service_config_repo.save(config2)
|
|
313
|
+
|
|
314
|
+
# Retrieve both and verify independence
|
|
315
|
+
retrieved1 = await knowledge_service_config_repo.get("ks-test-1")
|
|
316
|
+
retrieved2 = await knowledge_service_config_repo.get("ks-test-2")
|
|
317
|
+
|
|
318
|
+
assert retrieved1 is not None
|
|
319
|
+
assert retrieved2 is not None
|
|
320
|
+
assert retrieved1.knowledge_service_id == "ks-test-1"
|
|
321
|
+
assert retrieved2.knowledge_service_id == "ks-test-2"
|
|
322
|
+
assert retrieved1.name == "Service One"
|
|
323
|
+
assert retrieved2.name == "Service Two"
|
|
324
|
+
assert retrieved1.description == "First test service"
|
|
325
|
+
assert retrieved2.description == "Second test service"
|
|
326
|
+
|
|
327
|
+
# Update one config and verify the other is unchanged
|
|
328
|
+
config1.name = "Updated Service One"
|
|
329
|
+
await knowledge_service_config_repo.save(config1)
|
|
330
|
+
|
|
331
|
+
retrieved1_updated = await knowledge_service_config_repo.get("ks-test-1")
|
|
332
|
+
retrieved2_unchanged = await knowledge_service_config_repo.get("ks-test-2")
|
|
333
|
+
|
|
334
|
+
assert retrieved1_updated is not None
|
|
335
|
+
assert retrieved2_unchanged is not None
|
|
336
|
+
assert retrieved1_updated.name == "Updated Service One"
|
|
337
|
+
assert retrieved2_unchanged.name == "Service Two" # Should be unchanged
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
class TestMinioKnowledgeServiceConfigRepositoryEdgeCases:
|
|
341
|
+
"""Test edge cases and error conditions."""
|
|
342
|
+
|
|
343
|
+
@pytest.mark.asyncio
|
|
344
|
+
async def test_empty_string_id_handling(
|
|
345
|
+
self,
|
|
346
|
+
knowledge_service_config_repo: MinioKnowledgeServiceConfigRepository,
|
|
347
|
+
) -> None:
|
|
348
|
+
"""Test handling of empty string knowledge service ID."""
|
|
349
|
+
result = await knowledge_service_config_repo.get("")
|
|
350
|
+
assert result is None
|
|
351
|
+
|
|
352
|
+
@pytest.mark.asyncio
|
|
353
|
+
async def test_special_characters_in_id(
|
|
354
|
+
self,
|
|
355
|
+
knowledge_service_config_repo: MinioKnowledgeServiceConfigRepository,
|
|
356
|
+
) -> None:
|
|
357
|
+
"""Test handling knowledge service IDs with special characters."""
|
|
358
|
+
# Note: This test ensures the repository can handle various ID formats
|
|
359
|
+
# that might be generated by different ID generation strategies
|
|
360
|
+
special_id = "ks-test-with-dashes-and-numbers-123"
|
|
361
|
+
|
|
362
|
+
config = KnowledgeServiceConfig(
|
|
363
|
+
knowledge_service_id=special_id,
|
|
364
|
+
name="Special ID Service",
|
|
365
|
+
description="Service with special characters in ID",
|
|
366
|
+
service_api=ServiceApi.ANTHROPIC,
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
await knowledge_service_config_repo.save(config)
|
|
370
|
+
retrieved = await knowledge_service_config_repo.get(special_id)
|
|
371
|
+
|
|
372
|
+
assert retrieved is not None
|
|
373
|
+
assert retrieved.knowledge_service_id == special_id
|
|
374
|
+
assert retrieved.name == "Special ID Service"
|