Spaces:
Running
Running
| """Coverage-focused tests for animetix.api.labs endpoints. | |
| Complements the existing per-feature labs tests (test_audio_lab, test_video_lab, | |
| test_manga_lab, test_spatial_lab, test_singularity_api, test_voice_cloning_api, | |
| test_diagnostics_api, test_voice_profile_api) by exercising the endpoints that | |
| were previously uncovered: latent-space / daily-challenge / transparency data | |
| views, the remaining Singularity POST actions (compile / plasticity / quantum / | |
| evolve_dynamic / swarm), the Liquid Neural Network lab, the Manga metadata + | |
| Manga-Voice orchestration, Video-RAG index/search, Tree-of-Thoughts, and the | |
| Singularity Command Center -- plus validation (400) and error (500) paths. | |
| Pattern: views receive their services via ``@inject``/``Provide[...]`` from the | |
| real DI container, so tests override the concrete providers | |
| (``container.<sub>.<service>.override(mock)``) and reset them afterwards with | |
| ``reset_override()`` on the provider (never on the container). Permission | |
| classes are bypassed via ``as_view(permission_classes=[])`` (same trick used in | |
| the existing audio/spatial tests) so we exercise the handler logic directly | |
| with a ``RequestFactory`` request. | |
| """ | |
| import json | |
| from unittest.mock import MagicMock, patch | |
| import numpy as np | |
| import pytest | |
| from animetix.api.labs import ( | |
| DailyChallengeDataView, | |
| LatentSpaceDataView, | |
| LiquidNeuralNetworkLabView, | |
| MangaLabDataView, | |
| MangaVoiceLabView, | |
| SingularityCommandCenterView, | |
| SingularityLabDataView, | |
| TreeOfThoughtsLabView, | |
| VideoRAGIndexView, | |
| VideoRAGSearchView, | |
| ) | |
| from animetix.containers import get_container | |
| from django.contrib.auth.models import User | |
| from django.core.files.uploadedfile import SimpleUploadedFile | |
| from django.test import RequestFactory | |
| from rest_framework.test import force_authenticate | |
| factory = RequestFactory() | |
| # --------------------------------------------------------------------------- # | |
| # LatentSpaceDataView | |
| # --------------------------------------------------------------------------- # | |
| def test_latent_space_data_view_404_when_missing(tmp_path): | |
| """No artifact files -> 404 with empty list body.""" | |
| request = factory.get("/api/v1/latent-space/?media=anime&type=thematic") | |
| view = LatentSpaceDataView.as_view() | |
| with patch("animetix.api.labs.dashboards.os.path.exists", return_value=False): | |
| response = view(request) | |
| assert response.status_code == 404 | |
| assert response.data == [] | |
| def test_latent_space_data_view_success(tmp_path): | |
| """Existing artifact file is read and returned verbatim.""" | |
| payload = [{"x": 1, "y": 2, "z": 3, "label": "Naruto"}] | |
| request = factory.get("/api/v1/latent-space/?media=manga&type=visual") | |
| view = LatentSpaceDataView.as_view() | |
| m = MagicMock() | |
| m.read.return_value = json.dumps(payload) | |
| with ( | |
| patch("animetix.api.labs.dashboards.os.path.exists", return_value=True), | |
| patch("animetix.api.labs.dashboards.json.load", return_value=payload), | |
| patch("builtins.open", MagicMock()), | |
| ): | |
| response = view(request) | |
| assert response.status_code == 200 | |
| assert response.data == payload | |
| def test_latent_space_data_view_read_error(): | |
| """Exception while reading the file -> 500 with error message.""" | |
| request = factory.get("/api/v1/latent-space/") | |
| view = LatentSpaceDataView.as_view() | |
| with ( | |
| patch("animetix.api.labs.dashboards.os.path.exists", return_value=True), | |
| patch("builtins.open", side_effect=OSError("disk gone")), | |
| ): | |
| response = view(request) | |
| assert response.status_code == 500 | |
| assert response.data["error"] == "Internal server error" | |
| # --------------------------------------------------------------------------- # | |
| # DailyChallengeDataView | |
| # --------------------------------------------------------------------------- # | |
| def test_daily_challenge_data_view_creates_and_returns(): | |
| request = factory.get("/api/v1/daily-challenge/") | |
| view = DailyChallengeDataView.as_view() | |
| response = view(request) | |
| assert response.status_code == 200 | |
| # Redesigned: one challenge per universe (anime / manga / character) with | |
| # date navigation, instead of a single top-level media_type + reward_xp. | |
| assert response.data["is_today"] is True | |
| assert "date" in response.data | |
| mode_ids = {m["id"] for m in response.data["modes"]} | |
| assert mode_ids == {"anime", "manga", "character"} | |
| assert response.data["modes"][0]["media_type"] == "Anime" | |
| def test_daily_challenge_data_view_authenticated_scores(): | |
| """Regression: the authenticated branch does ``from ...models import | |
| DailyResult`` — in the old monolithic ``labs.py`` (package ``animetix.api``) | |
| the 3-dot relative import climbed beyond the top-level package and raised | |
| ImportError on every authenticated request. The move into the | |
| ``animetix.api.labs`` package makes it resolve to ``animetix.models``. | |
| """ | |
| import datetime | |
| from animetix.models import DailyResult | |
| user = User.objects.create_user(username="daily_auth") | |
| DailyResult.objects.create( | |
| user=user, | |
| media_type="Anime", | |
| date=datetime.date.today(), | |
| score=42, | |
| attempts=3, | |
| ) | |
| request = factory.get("/api/v1/daily-challenge/") | |
| force_authenticate(request, user=user) | |
| view = DailyChallengeDataView.as_view() | |
| response = view(request) | |
| assert response.status_code == 200 | |
| assert response.data["total_score"] == 42 | |
| anime_mode = next(m for m in response.data["modes"] if m["id"] == "anime") | |
| assert anime_mode["completed"] is True | |
| assert anime_mode["score"] == 42 | |
| # --------------------------------------------------------------------------- # | |
| # SingularityLabDataView POST actions | |
| # --------------------------------------------------------------------------- # | |
| def _singularity_request(payload): | |
| request = factory.post( | |
| "/api/v1/singularity-lab/", json.dumps(payload), content_type="application/json" | |
| ) | |
| # force_authenticate bypasses SessionAuthentication's CSRF enforcement that | |
| # would otherwise 403 a POST coming from RequestFactory. | |
| force_authenticate(request, user=MagicMock(id=1)) | |
| return request | |
| def _run_singularity(payload, overrides=()): | |
| """Run SingularityLabDataView with the given (provider, mock) overrides. | |
| ``overrides`` is an iterable of ``(provider, mock)`` tuples; each provider | |
| is overridden before the request and reset (per provider — never | |
| ``container.reset_override()``) afterwards. | |
| """ | |
| request = _singularity_request(payload) | |
| # The view injects every singularity service in __init__: stub out the ones | |
| # the test does not care about so no real (heavy) service is constructed. | |
| container = get_container() | |
| default_providers = [ | |
| container.core.synaptic_plasticity_simulator, | |
| container.core.archetype_drift_service, | |
| container.core.self_evolving_compiler, | |
| container.core.quantum_cognitive_model, | |
| container.core.swarm_consensus_orchestrator, | |
| container.core.autonomous_domain_synthesizer, | |
| container.agentic.llm_service, | |
| ] | |
| overridden_providers = [provider for provider, _ in overrides] | |
| explicit_ids = {id(provider) for provider in overridden_providers} | |
| for provider in default_providers: | |
| if id(provider) not in explicit_ids: | |
| provider.override(MagicMock()) | |
| overridden_providers.append(provider) | |
| for provider, mock in overrides: | |
| provider.override(mock) | |
| d = patch("animetix.api.labs.singularity.deduct_berrix") | |
| d.start() | |
| try: | |
| view = SingularityLabDataView.as_view(permission_classes=[]) | |
| return view(request) | |
| finally: | |
| for provider in overridden_providers: | |
| provider.reset_last_overriding() | |
| d.stop() | |
| def test_singularity_compile_success(): | |
| compiler = MagicMock() | |
| compiler.mode = "jit" | |
| compiler.analyze_and_optimize.return_value = lambda a, b: 1.0 | |
| container = get_container() | |
| response = _run_singularity( | |
| {"action": "compile", "function_name": "cosine_similarity"}, | |
| [(container.core.self_evolving_compiler, compiler)], | |
| ) | |
| assert response.status_code == 200 | |
| assert response.data["status"] == "success" | |
| assert response.data["mode"] == "jit" | |
| def test_singularity_compile_disallowed_function(): | |
| response = _run_singularity({"action": "compile", "function_name": "os.system"}) | |
| assert response.status_code == 400 | |
| assert "not allowed" in response.data["error"] | |
| def test_singularity_compile_error(): | |
| compiler = MagicMock() | |
| compiler.analyze_and_optimize.side_effect = Exception("compile boom") | |
| container = get_container() | |
| response = _run_singularity( | |
| {"action": "compile", "function_name": "vector_norm"}, | |
| [(container.core.self_evolving_compiler, compiler)], | |
| ) | |
| assert response.status_code == 500 | |
| assert response.data["error"] == "Internal server error" | |
| def test_singularity_plasticity_success(): | |
| service = MagicMock() | |
| service.update_hebbian.return_value = np.zeros((10, 10)) | |
| service.update_stdp.return_value = 0.01 | |
| container = get_container() | |
| response = _run_singularity( | |
| {"action": "plasticity", "trigger_spikes": [0, 1], "learning_rate": 0.05}, | |
| [(container.core.synaptic_plasticity_simulator, service)], | |
| ) | |
| assert response.status_code == 200 | |
| assert response.data["status"] == "success" | |
| assert response.data["stdp_log"] # STDP appended for >=2 indices | |
| assert "weights_mean" in response.data | |
| def test_singularity_plasticity_error(): | |
| service = MagicMock() | |
| service.trigger_spikes.side_effect = Exception("spike fail") | |
| container = get_container() | |
| response = _run_singularity( | |
| {"action": "plasticity"}, | |
| [(container.core.synaptic_plasticity_simulator, service)], | |
| ) | |
| assert response.status_code == 500 | |
| assert response.data["error"] == "Internal server error" | |
| def test_singularity_quantum_success(): | |
| model = MagicMock() | |
| model.measure_preference.return_value = (0.73, "shonen") | |
| model.state = [1, 0, 0, 0] | |
| container = get_container() | |
| response = _run_singularity( | |
| {"action": "quantum", "theme": "Shonen"}, | |
| [(container.core.quantum_cognitive_model, model)], | |
| ) | |
| assert response.status_code == 200 | |
| assert response.data["theme"] == "shonen" | |
| assert response.data["probability"] == pytest.approx(0.73) | |
| assert response.data["outcome"] == "shonen" | |
| def test_singularity_quantum_error(): | |
| model = MagicMock() | |
| model.measure_preference.side_effect = Exception("decohere") | |
| container = get_container() | |
| response = _run_singularity( | |
| {"action": "quantum"}, | |
| [(container.core.quantum_cognitive_model, model)], | |
| ) | |
| assert response.status_code == 500 | |
| assert response.data["error"] == "Internal server error" | |
| def test_singularity_evolve_dynamic_success(): | |
| compiler = MagicMock() | |
| fn = MagicMock(return_value=42) | |
| fn.__name__ = "dynamic_kernel" | |
| compiler.evolve_with_llm.return_value = fn | |
| container = get_container() | |
| response = _run_singularity( | |
| {"action": "evolve_dynamic", "task": "dot_product"}, | |
| [ | |
| (container.core.self_evolving_compiler, compiler), | |
| (container.agentic.llm_service, MagicMock()), | |
| ], | |
| ) | |
| assert response.status_code == 200 | |
| assert response.data["kernel_name"] == "dynamic_kernel" | |
| assert response.data["result"] == "42" | |
| def test_singularity_evolve_dynamic_error(): | |
| compiler = MagicMock() | |
| compiler.evolve_with_llm.side_effect = Exception("llm down") | |
| container = get_container() | |
| response = _run_singularity( | |
| {"action": "evolve_dynamic"}, | |
| [(container.core.self_evolving_compiler, compiler)], | |
| ) | |
| assert response.status_code == 500 | |
| assert response.data["error"] == "Internal server error" | |
| def test_singularity_swarm_missing_fields(): | |
| response = _run_singularity({"action": "swarm", "fact": "x"}) | |
| assert response.status_code == 400 | |
| assert "fact and media" in response.data["error"] | |
| def test_singularity_swarm_success(): | |
| orchestrator = MagicMock() | |
| orchestrator.get_paxos_diagnostics.return_value = {"consensus": True, "round": 3} | |
| container = get_container() | |
| response = _run_singularity( | |
| {"action": "swarm", "fact": "Luffy is captain", "media": "One Piece"}, | |
| [(container.core.swarm_consensus_orchestrator, orchestrator)], | |
| ) | |
| assert response.status_code == 200 | |
| assert response.data["consensus"] is True | |
| def test_singularity_swarm_error(): | |
| orchestrator = MagicMock() | |
| orchestrator.get_paxos_diagnostics.side_effect = Exception("no quorum") | |
| container = get_container() | |
| response = _run_singularity( | |
| {"action": "swarm", "fact": "a", "media": "b"}, | |
| [(container.core.swarm_consensus_orchestrator, orchestrator)], | |
| ) | |
| assert response.status_code == 500 | |
| assert response.data["error"] == "Internal server error" | |
| # --------------------------------------------------------------------------- # | |
| # LiquidNeuralNetworkLabView | |
| # --------------------------------------------------------------------------- # | |
| def test_liquid_nn_success(): | |
| request = factory.post( | |
| "/api/v1/labs/liquid-nn/", | |
| json.dumps({"signal": [[0.5, 0.2]], "dt": 0.1}), | |
| content_type="application/json", | |
| ) | |
| lnn = MagicMock() | |
| lnn.process_continuous_signal.return_value = [[0.1, 0.2]] | |
| lnn.state = np.array([0.1, 0.2]) | |
| container = get_container() | |
| container.core.liquid_neural_network.override(lnn) | |
| try: | |
| view = LiquidNeuralNetworkLabView.as_view(permission_classes=[]) | |
| response = view(request) | |
| finally: | |
| container.core.liquid_neural_network.reset_last_overriding() | |
| assert response.status_code == 200 | |
| assert response.data["status"] == "success" | |
| assert response.data["final_state"] == [0.1, 0.2] | |
| def test_liquid_nn_error(): | |
| request = factory.post( | |
| "/api/v1/labs/liquid-nn/", | |
| json.dumps({"signal": [[0.5, 0.2]]}), | |
| content_type="application/json", | |
| ) | |
| lnn = MagicMock() | |
| lnn.process_continuous_signal.side_effect = Exception("diverged") | |
| container = get_container() | |
| container.core.liquid_neural_network.override(lnn) | |
| try: | |
| view = LiquidNeuralNetworkLabView.as_view(permission_classes=[]) | |
| response = view(request) | |
| finally: | |
| container.core.liquid_neural_network.reset_last_overriding() | |
| assert response.status_code == 500 | |
| assert response.data["error"] == "Internal server error" | |
| # --------------------------------------------------------------------------- # | |
| # MangaLabDataView | |
| # --------------------------------------------------------------------------- # | |
| def test_manga_lab_data_view(): | |
| request = factory.get("/api/v1/labs/manga-lab/") | |
| view = MangaLabDataView.as_view() | |
| response = view(request) | |
| assert response.status_code == 200 | |
| assert response.data["status"] == "active" | |
| ids = {t["id"] for t in response.data["tools"]} | |
| assert {"clean", "translate", "voice"} <= ids | |
| # --------------------------------------------------------------------------- # | |
| # MangaVoiceLabView | |
| # --------------------------------------------------------------------------- # | |
| def test_manga_voice_missing_payload(): | |
| request = factory.post( | |
| "/api/v1/labs/manga-voice/", | |
| json.dumps({"image": "x"}), | |
| content_type="application/json", | |
| ) | |
| force_authenticate(request, user=MagicMock(id=1)) | |
| view = MangaVoiceLabView.as_view(permission_classes=[]) | |
| response = view(request) | |
| assert response.status_code == 400 | |
| assert "Missing image or reference_audio" in response.data["error"] | |
| def test_manga_voice_local_fallback(): | |
| """Non-production path returns 202 with a task_id and seeds the cache.""" | |
| request = factory.post( | |
| "/api/v1/labs/manga-voice/", | |
| json.dumps( | |
| {"image": "img-b64", "reference_audio": "aud-b64", "target_lang": "English"} | |
| ), | |
| content_type="application/json", | |
| ) | |
| force_authenticate(request, user=MagicMock(id=1)) | |
| with ( | |
| patch("animetix.api.labs.manga.deduct_berrix"), | |
| patch("django.core.cache.cache.set") as mock_cache_set, | |
| patch("animetix.api.labs.manga.settings") as mock_settings, | |
| ): | |
| mock_settings.IS_PRODUCTION = False | |
| view = MangaVoiceLabView.as_view(permission_classes=[]) | |
| response = view(request) | |
| assert response.status_code == 202 | |
| assert "task_id" in response.data | |
| # cache seeded at least once (pending init + success result on the local path) | |
| assert mock_cache_set.called | |
| def test_manga_voice_production_success(): | |
| request = factory.post( | |
| "/api/v1/labs/manga-voice/", | |
| json.dumps({"image": "img", "reference_audio": "aud"}), | |
| content_type="application/json", | |
| ) | |
| force_authenticate(request, user=MagicMock(id=1)) | |
| with ( | |
| patch("animetix.api.labs.manga.deduct_berrix"), | |
| patch("django.core.cache.cache.set"), | |
| patch("animetix.api.labs.manga.settings") as mock_settings, | |
| patch("animetix.api.labs.manga.GCPWorkflowsClient") as mock_client_cls, | |
| ): | |
| mock_settings.IS_PRODUCTION = True | |
| client = mock_client_cls.return_value | |
| client.trigger_pipeline.return_value = "exec-123" | |
| view = MangaVoiceLabView.as_view(permission_classes=[]) | |
| response = view(request) | |
| assert response.status_code == 202 | |
| assert "task_id" in response.data | |
| client.trigger_pipeline.assert_called_once() | |
| client.enqueue_polling_task.assert_called_once() | |
| def test_manga_voice_production_error(): | |
| request = factory.post( | |
| "/api/v1/labs/manga-voice/", | |
| json.dumps({"image": "img", "reference_audio": "aud"}), | |
| content_type="application/json", | |
| ) | |
| force_authenticate(request, user=MagicMock(id=1)) | |
| with ( | |
| patch("animetix.api.labs.manga.deduct_berrix"), | |
| patch("django.core.cache.cache.set"), | |
| patch("animetix.api.labs.manga.settings") as mock_settings, | |
| patch("animetix.api.labs.manga.GCPWorkflowsClient") as mock_client_cls, | |
| ): | |
| mock_settings.IS_PRODUCTION = True | |
| mock_client_cls.return_value.trigger_pipeline.side_effect = Exception( | |
| "gcp boom" | |
| ) | |
| view = MangaVoiceLabView.as_view(permission_classes=[]) | |
| response = view(request) | |
| assert response.status_code == 500 | |
| assert "Failed to start workflow" in response.data["error"] | |
| # --------------------------------------------------------------------------- # | |
| # VideoRAGIndexView | |
| # --------------------------------------------------------------------------- # | |
| def test_video_rag_index_missing_fields(): | |
| user = User.objects.create_user(username="ragindex_missing") | |
| request = factory.post("/api/v1/labs/video/index/", {}) | |
| force_authenticate(request, user=user) | |
| view = VideoRAGIndexView.as_view(permission_classes=[]) | |
| response = view(request) | |
| assert response.status_code == 400 | |
| assert "video and video_id" in response.data["error"] | |
| def test_video_rag_index_success(): | |
| user = User.objects.create_user(username="ragindex_ok") | |
| video = SimpleUploadedFile("v.mp4", b"vid", content_type="video/mp4") | |
| request = factory.post( | |
| "/api/v1/labs/video/index/", {"video": video, "video_id": "ep1"} | |
| ) | |
| force_authenticate(request, user=user) | |
| mock_service = MagicMock() | |
| mock_service.index_video.return_value = 7 | |
| container = get_container() | |
| container.agentic.video_rag_service.override(mock_service) | |
| try: | |
| view = VideoRAGIndexView.as_view(permission_classes=[]) | |
| response = view(request) | |
| finally: | |
| container.agentic.video_rag_service.reset_last_overriding() | |
| assert response.status_code == 200 | |
| assert response.data["indexed_segments"] == 7 | |
| def test_video_rag_index_error(): | |
| user = User.objects.create_user(username="ragindex_err") | |
| video = SimpleUploadedFile("v.mp4", b"vid", content_type="video/mp4") | |
| request = factory.post( | |
| "/api/v1/labs/video/index/", {"video": video, "video_id": "ep1"} | |
| ) | |
| force_authenticate(request, user=user) | |
| mock_service = MagicMock() | |
| mock_service.index_video.side_effect = Exception("index fail") | |
| container = get_container() | |
| container.agentic.video_rag_service.override(mock_service) | |
| try: | |
| view = VideoRAGIndexView.as_view(permission_classes=[]) | |
| response = view(request) | |
| finally: | |
| container.agentic.video_rag_service.reset_last_overriding() | |
| assert response.status_code == 500 | |
| assert response.data["error"] == "Internal server error" | |
| # --------------------------------------------------------------------------- # | |
| # VideoRAGSearchView | |
| # --------------------------------------------------------------------------- # | |
| def test_video_rag_search_missing_query(): | |
| request = factory.get("/api/v1/labs/video/search/") | |
| force_authenticate(request, user=MagicMock(id=1)) | |
| view = VideoRAGSearchView.as_view(permission_classes=[]) | |
| response = view(request) | |
| assert response.status_code == 400 | |
| assert "query q is required" in response.data["error"] | |
| def test_video_rag_search_success(): | |
| request = factory.get("/api/v1/labs/video/search/?q=fight") | |
| force_authenticate(request, user=MagicMock(id=1)) | |
| mock_service = MagicMock() | |
| mock_service.search_video_segment.return_value = [{"ts": 12, "score": 0.9}] | |
| mock_usage = MagicMock() | |
| mock_usage.check_quota.return_value = True | |
| container = get_container() | |
| container.agentic.video_rag_service.override(mock_service) | |
| container.infrastructure.usage_port.override(mock_usage) | |
| d = patch("animetix.api.labs.video.deduct_berrix") | |
| d.start() | |
| try: | |
| view = VideoRAGSearchView.as_view(permission_classes=[]) | |
| response = view(request) | |
| finally: | |
| container.agentic.video_rag_service.reset_last_overriding() | |
| container.infrastructure.usage_port.reset_last_overriding() | |
| d.stop() | |
| assert response.status_code == 200 | |
| assert response.data["status"] == "success" | |
| assert response.data["results"][0]["ts"] == 12 | |
| def test_video_rag_search_error(): | |
| request = factory.get("/api/v1/labs/video/search/?q=fight") | |
| force_authenticate(request, user=MagicMock(id=1)) | |
| mock_service = MagicMock() | |
| mock_service.search_video_segment.side_effect = Exception("search down") | |
| mock_usage = MagicMock() | |
| mock_usage.check_quota.return_value = True | |
| container = get_container() | |
| container.agentic.video_rag_service.override(mock_service) | |
| container.infrastructure.usage_port.override(mock_usage) | |
| d = patch("animetix.api.labs.video.deduct_berrix") | |
| d.start() | |
| try: | |
| view = VideoRAGSearchView.as_view(permission_classes=[]) | |
| response = view(request) | |
| finally: | |
| container.agentic.video_rag_service.reset_last_overriding() | |
| container.infrastructure.usage_port.reset_last_overriding() | |
| d.stop() | |
| assert response.status_code == 500 | |
| assert response.data["error"] == "Internal server error" | |
| # --------------------------------------------------------------------------- # | |
| # TreeOfThoughtsLabView | |
| # --------------------------------------------------------------------------- # | |
| def test_tree_of_thoughts_missing_query(): | |
| request = factory.post( | |
| "/api/v1/labs/tot/", json.dumps({}), content_type="application/json" | |
| ) | |
| # GPU feature → login required (the "Query required" 400 is returned before | |
| # the Berrix charge, so no need to mock deduct_berrix here). | |
| force_authenticate(request, user=MagicMock(id=1)) | |
| view = TreeOfThoughtsLabView.as_view() | |
| response = view(request) | |
| assert response.status_code == 400 | |
| assert response.data["error"] == "Query required" | |
| def test_tree_of_thoughts_success(): | |
| request = factory.post( | |
| "/api/v1/labs/tot/", | |
| json.dumps({"query": "Solve X"}), | |
| content_type="application/json", | |
| ) | |
| force_authenticate(request, user=MagicMock(id=1)) | |
| view = TreeOfThoughtsLabView.as_view() | |
| # The injected service is an attribute on the instantiated view; patch it. | |
| with patch.object( | |
| TreeOfThoughtsLabView, | |
| "solve", | |
| create=True, | |
| ): | |
| instance_service = MagicMock() | |
| instance_service.solve_with_tree_of_thoughts.return_value = {"answer": "42"} | |
| with ( | |
| patch.object( | |
| TreeOfThoughtsLabView, | |
| "__init__", | |
| lambda self, **kw: setattr(self, "tot_service", instance_service) | |
| or super(TreeOfThoughtsLabView, self).__init__(), | |
| ), | |
| patch("animetix.api.labs.singularity.deduct_berrix"), | |
| ): | |
| response = view(request) | |
| assert response.status_code == 200 | |
| assert response.data["answer"] == "42" | |
| def test_tree_of_thoughts_error(): | |
| request = factory.post( | |
| "/api/v1/labs/tot/", | |
| json.dumps({"query": "Solve X"}), | |
| content_type="application/json", | |
| ) | |
| force_authenticate(request, user=MagicMock(id=1)) | |
| view = TreeOfThoughtsLabView.as_view() | |
| instance_service = MagicMock() | |
| instance_service.solve_with_tree_of_thoughts.side_effect = Exception("tot boom") | |
| with ( | |
| patch.object( | |
| TreeOfThoughtsLabView, | |
| "__init__", | |
| lambda self, **kw: setattr(self, "tot_service", instance_service) | |
| or super(TreeOfThoughtsLabView, self).__init__(), | |
| ), | |
| patch("animetix.api.labs.singularity.deduct_berrix"), | |
| ): | |
| response = view(request) | |
| assert response.status_code == 500 | |
| assert response.data["error"] == "Internal server error" | |
| # --------------------------------------------------------------------------- # | |
| # SingularityCommandCenterView | |
| # --------------------------------------------------------------------------- # | |
| def test_singularity_command_center(): | |
| request = factory.get("/api/v1/singularity-lab/command-center/") | |
| view = SingularityCommandCenterView.as_view(permission_classes=[]) | |
| response = view(request) | |
| assert response.status_code == 200 | |
| assert response.data["status"] == "operational" | |
| service_ids = {s["id"] for s in response.data["services"]} | |
| assert {"quantum", "plasticity", "swarm", "lnn"} <= service_ids | |
| assert len(response.data["events"]) == 3 | |