diff --git a/.github/workflows/pyrefly-diff.yml b/.github/workflows/pyrefly-diff.yml index 2d22231144..14338e85b3 100644 --- a/.github/workflows/pyrefly-diff.yml +++ b/.github/workflows/pyrefly-diff.yml @@ -29,20 +29,26 @@ jobs: - name: Install dependencies run: uv sync --project api --dev + - name: Prepare diagnostics extractor + run: | + git show ${{ github.event.pull_request.head.sha }}:api/libs/pyrefly_diagnostics.py > /tmp/pyrefly_diagnostics.py + - name: Run pyrefly on PR branch run: | - uv run --directory api pyrefly check > /tmp/pyrefly_pr.txt 2>&1 || true + uv run --directory api --dev pyrefly check 2>&1 \ + | uv run --directory api python /tmp/pyrefly_diagnostics.py > /tmp/pyrefly_pr.txt || true - name: Checkout base branch run: git checkout ${{ github.base_ref }} - name: Run pyrefly on base branch run: | - uv run --directory api pyrefly check > /tmp/pyrefly_base.txt 2>&1 || true + uv run --directory api --dev pyrefly check 2>&1 \ + | uv run --directory api python /tmp/pyrefly_diagnostics.py > /tmp/pyrefly_base.txt || true - name: Compute diff run: | - diff /tmp/pyrefly_base.txt /tmp/pyrefly_pr.txt > pyrefly_diff.txt || true + diff -u /tmp/pyrefly_base.txt /tmp/pyrefly_pr.txt > pyrefly_diff.txt || true - name: Save PR number run: | diff --git a/Makefile b/Makefile index 984e8676ee..0aff26b3e5 100644 --- a/Makefile +++ b/Makefile @@ -68,10 +68,9 @@ lint: @echo "βœ… Linting complete" type-check: - @echo "πŸ“ Running type checks (basedpyright + mypy + ty)..." + @echo "πŸ“ Running type checks (basedpyright + mypy)..." @./dev/basedpyright-check $(PATH_TO_CHECK) @uv --directory api run mypy --exclude-gitignore --exclude 'tests/' --exclude 'migrations/' --check-untyped-defs --disable-error-code=import-untyped . - @cd api && uv run ty check @echo "βœ… Type checks complete" test: @@ -132,7 +131,7 @@ help: @echo " make format - Format code with ruff" @echo " make check - Check code with ruff" @echo " make lint - Format, fix, and lint code (ruff, imports, dotenv)" - @echo " make type-check - Run type checks (basedpyright, mypy, ty)" + @echo " make type-check - Run type checks (basedpyright, mypy)" @echo " make test - Run backend unit tests (or TARGET_TESTS=./api/tests/)" @echo "" @echo "Docker Build Targets:" diff --git a/api/.importlinter b/api/.importlinter index 49cf70d61a..f74a1b667d 100644 --- a/api/.importlinter +++ b/api/.importlinter @@ -29,6 +29,8 @@ ignore_imports = core.workflow.nodes.iteration.iteration_node -> core.app.workflow.node_factory core.workflow.nodes.loop.loop_node -> core.app.workflow.node_factory + core.workflow.nodes.iteration.iteration_node -> core.app.workflow.layers.llm_quota + core.workflow.nodes.loop.loop_node -> core.app.workflow.layers.llm_quota core.workflow.nodes.iteration.iteration_node -> core.workflow.graph_engine core.workflow.nodes.iteration.iteration_node -> core.workflow.graph @@ -52,7 +54,6 @@ ignore_imports = core.workflow.nodes.agent.agent_node -> extensions.ext_database core.workflow.nodes.knowledge_index.knowledge_index_node -> extensions.ext_database core.workflow.nodes.llm.file_saver -> extensions.ext_database - core.workflow.nodes.llm.llm_utils -> extensions.ext_database core.workflow.nodes.llm.node -> extensions.ext_database core.workflow.nodes.tool.tool_node -> extensions.ext_database # TODO(QuantumGhost): use DI to avoid depending on global DB. @@ -107,14 +108,11 @@ ignore_imports = core.workflow.nodes.agent.agent_node -> core.tools.tool_manager core.workflow.nodes.document_extractor.node -> core.helper.ssrf_proxy core.workflow.nodes.iteration.iteration_node -> core.app.workflow.node_factory + core.workflow.nodes.iteration.iteration_node -> core.app.workflow.layers.llm_quota core.workflow.nodes.knowledge_index.knowledge_index_node -> core.rag.index_processor.index_processor_factory - core.workflow.nodes.llm.llm_utils -> configs core.workflow.nodes.llm.llm_utils -> core.model_manager core.workflow.nodes.llm.protocols -> core.model_manager core.workflow.nodes.llm.llm_utils -> core.model_runtime.model_providers.__base.large_language_model - core.workflow.nodes.llm.llm_utils -> models.model - core.workflow.nodes.llm.llm_utils -> models.provider - core.workflow.nodes.llm.llm_utils -> services.credit_pool_service core.workflow.nodes.llm.node -> core.tools.signature core.workflow.nodes.tool.tool_node -> core.callback_handler.workflow_tool_callback_handler core.workflow.nodes.tool.tool_node -> core.tools.tool_engine @@ -131,12 +129,10 @@ ignore_imports = core.workflow.nodes.parameter_extractor.parameter_extractor_node -> core.prompt.simple_prompt_transform core.workflow.nodes.parameter_extractor.parameter_extractor_node -> core.model_runtime.model_providers.__base.large_language_model core.workflow.nodes.question_classifier.question_classifier_node -> core.prompt.simple_prompt_transform - core.workflow.nodes.start.entities -> core.app.app_config.entities - core.workflow.nodes.start.start_node -> core.app.app_config.entities core.workflow.workflow_entry -> core.app.apps.exc core.workflow.workflow_entry -> core.app.entities.app_invoke_entities + core.workflow.workflow_entry -> core.app.workflow.layers.llm_quota core.workflow.workflow_entry -> core.app.workflow.node_factory - core.workflow.nodes.llm.llm_utils -> core.entities.provider_entities core.workflow.nodes.parameter_extractor.parameter_extractor_node -> core.model_manager core.workflow.nodes.question_classifier.question_classifier_node -> core.model_manager core.workflow.nodes.tool.tool_node -> core.tools.utils.message_transformer @@ -150,7 +146,6 @@ ignore_imports = core.workflow.nodes.llm.node -> core.model_manager core.workflow.nodes.agent.entities -> core.prompt.entities.advanced_prompt_entities core.workflow.nodes.llm.entities -> core.prompt.entities.advanced_prompt_entities - core.workflow.nodes.llm.llm_utils -> core.prompt.entities.advanced_prompt_entities core.workflow.nodes.llm.node -> core.prompt.entities.advanced_prompt_entities core.workflow.nodes.llm.node -> core.prompt.utils.prompt_message_util core.workflow.nodes.parameter_extractor.entities -> core.prompt.entities.advanced_prompt_entities @@ -172,7 +167,6 @@ ignore_imports = core.workflow.nodes.agent.agent_node -> extensions.ext_database core.workflow.nodes.knowledge_index.knowledge_index_node -> extensions.ext_database core.workflow.nodes.llm.file_saver -> extensions.ext_database - core.workflow.nodes.llm.llm_utils -> extensions.ext_database core.workflow.nodes.llm.node -> extensions.ext_database core.workflow.nodes.tool.tool_node -> extensions.ext_database core.workflow.nodes.human_input.human_input_node -> extensions.ext_database @@ -180,7 +174,7 @@ ignore_imports = core.workflow.workflow_entry -> extensions.otel.runtime core.workflow.nodes.agent.agent_node -> models core.workflow.nodes.base.node -> models.enums - core.workflow.nodes.llm.llm_utils -> models.provider_ids + core.workflow.nodes.loop.loop_node -> core.app.workflow.layers.llm_quota core.workflow.nodes.llm.node -> models.model core.workflow.workflow_entry -> models.enums core.workflow.nodes.agent.agent_node -> services diff --git a/api/controllers/mcp/mcp.py b/api/controllers/mcp/mcp.py index 90137a10ba..991a9166c7 100644 --- a/api/controllers/mcp/mcp.py +++ b/api/controllers/mcp/mcp.py @@ -8,9 +8,9 @@ from sqlalchemy.orm import Session from controllers.common.schema import register_schema_model from controllers.console.app.mcp_server import AppMCPServerStatus from controllers.mcp import mcp_ns -from core.app.app_config.entities import VariableEntity from core.mcp import types as mcp_types from core.mcp.server.streamable_http import handle_mcp_request +from core.workflow.variables.input_entities import VariableEntity from extensions.ext_database import db from libs import helper from models.model import App, AppMCPServer, AppMode, EndUser diff --git a/api/core/app/app_config/easy_ui_based_app/variables/manager.py b/api/core/app/app_config/easy_ui_based_app/variables/manager.py index 6375733448..22d602a190 100644 --- a/api/core/app/app_config/easy_ui_based_app/variables/manager.py +++ b/api/core/app/app_config/easy_ui_based_app/variables/manager.py @@ -1,7 +1,8 @@ import re -from core.app.app_config.entities import ExternalDataVariableEntity, VariableEntity, VariableEntityType +from core.app.app_config.entities import ExternalDataVariableEntity from core.external_data_tool.factory import ExternalDataToolFactory +from core.workflow.variables.input_entities import VariableEntity, VariableEntityType _ALLOWED_VARIABLE_ENTITY_TYPE = frozenset( [ diff --git a/api/core/app/app_config/entities.py b/api/core/app/app_config/entities.py index f8538d474c..062cc6a0b3 100644 --- a/api/core/app/app_config/entities.py +++ b/api/core/app/app_config/entities.py @@ -2,12 +2,12 @@ from collections.abc import Sequence from enum import StrEnum, auto from typing import Any, Literal -from jsonschema import Draft7Validator, SchemaError -from pydantic import BaseModel, Field, field_validator +from pydantic import BaseModel, Field from core.model_runtime.entities.llm_entities import LLMMode from core.model_runtime.entities.message_entities import PromptMessageRole -from core.workflow.file import FileTransferMethod, FileType, FileUploadConfig +from core.workflow.file import FileUploadConfig +from core.workflow.variables.input_entities import VariableEntity as WorkflowVariableEntity from models.model import AppMode @@ -90,61 +90,7 @@ class PromptTemplateEntity(BaseModel): advanced_completion_prompt_template: AdvancedCompletionPromptTemplateEntity | None = None -class VariableEntityType(StrEnum): - TEXT_INPUT = "text-input" - SELECT = "select" - PARAGRAPH = "paragraph" - NUMBER = "number" - EXTERNAL_DATA_TOOL = "external_data_tool" - FILE = "file" - FILE_LIST = "file-list" - CHECKBOX = "checkbox" - JSON_OBJECT = "json_object" - - -class VariableEntity(BaseModel): - """ - Variable Entity. - """ - - # `variable` records the name of the variable in user inputs. - variable: str - label: str - description: str = "" - type: VariableEntityType - required: bool = False - hide: bool = False - default: Any = None - max_length: int | None = None - options: Sequence[str] = Field(default_factory=list) - allowed_file_types: Sequence[FileType] | None = Field(default_factory=list) - allowed_file_extensions: Sequence[str] | None = Field(default_factory=list) - allowed_file_upload_methods: Sequence[FileTransferMethod] | None = Field(default_factory=list) - json_schema: dict | None = Field(default=None) - - @field_validator("description", mode="before") - @classmethod - def convert_none_description(cls, v: Any) -> str: - return v or "" - - @field_validator("options", mode="before") - @classmethod - def convert_none_options(cls, v: Any) -> Sequence[str]: - return v or [] - - @field_validator("json_schema") - @classmethod - def validate_json_schema(cls, schema: dict | None) -> dict | None: - if schema is None: - return None - try: - Draft7Validator.check_schema(schema) - except SchemaError as e: - raise ValueError(f"Invalid JSON schema: {e.message}") - return schema - - -class RagPipelineVariableEntity(VariableEntity): +class RagPipelineVariableEntity(WorkflowVariableEntity): """ Rag Pipeline Variable Entity. """ @@ -314,7 +260,7 @@ class AppConfig(BaseModel): app_id: str app_mode: AppMode additional_features: AppAdditionalFeatures | None = None - variables: list[VariableEntity] = [] + variables: list[WorkflowVariableEntity] = [] sensitive_word_avoidance: SensitiveWordAvoidanceEntity | None = None diff --git a/api/core/app/app_config/workflow_ui_based_app/variables/manager.py b/api/core/app/app_config/workflow_ui_based_app/variables/manager.py index 96b52712ae..ec7d85a09f 100644 --- a/api/core/app/app_config/workflow_ui_based_app/variables/manager.py +++ b/api/core/app/app_config/workflow_ui_based_app/variables/manager.py @@ -1,6 +1,7 @@ import re -from core.app.app_config.entities import RagPipelineVariableEntity, VariableEntity +from core.app.app_config.entities import RagPipelineVariableEntity +from core.workflow.variables.input_entities import VariableEntity from models.workflow import Workflow diff --git a/api/core/app/apps/base_app_generator.py b/api/core/app/apps/base_app_generator.py index 48742205f1..81617c5fb2 100644 --- a/api/core/app/apps/base_app_generator.py +++ b/api/core/app/apps/base_app_generator.py @@ -3,7 +3,6 @@ from typing import TYPE_CHECKING, Any, Union, final from sqlalchemy.orm import Session -from core.app.app_config.entities import VariableEntityType from core.app.entities.app_invoke_entities import InvokeFrom from core.workflow.enums import NodeType from core.workflow.file import File, FileUploadConfig @@ -12,13 +11,14 @@ from core.workflow.repositories.draft_variable_repository import ( DraftVariableSaverFactory, NoopDraftVariableSaver, ) +from core.workflow.variables.input_entities import VariableEntityType from factories import file_factory from libs.orjson import orjson_dumps from models import Account, EndUser from services.workflow_draft_variable_service import DraftVariableSaver as DraftVariableSaverImpl if TYPE_CHECKING: - from core.app.app_config.entities import VariableEntity + from core.workflow.variables.input_entities import VariableEntity class BaseAppGenerator: diff --git a/api/core/app/llm/__init__.py b/api/core/app/llm/__init__.py index 5ac76c8086..f069bede74 100644 --- a/api/core/app/llm/__init__.py +++ b/api/core/app/llm/__init__.py @@ -1 +1,5 @@ """LLM-related application services.""" + +from .quota import deduct_llm_quota, ensure_llm_quota_available + +__all__ = ["deduct_llm_quota", "ensure_llm_quota_available"] diff --git a/api/core/app/llm/quota.py b/api/core/app/llm/quota.py new file mode 100644 index 0000000000..1c66c8c1ff --- /dev/null +++ b/api/core/app/llm/quota.py @@ -0,0 +1,93 @@ +from sqlalchemy import update +from sqlalchemy.orm import Session + +from configs import dify_config +from core.entities.model_entities import ModelStatus +from core.entities.provider_entities import ProviderQuotaType, QuotaUnit +from core.errors.error import QuotaExceededError +from core.model_manager import ModelInstance +from core.model_runtime.entities.llm_entities import LLMUsage +from extensions.ext_database import db +from libs.datetime_utils import naive_utc_now +from models.provider import Provider, ProviderType +from models.provider_ids import ModelProviderID + + +def ensure_llm_quota_available(*, model_instance: ModelInstance) -> None: + provider_model_bundle = model_instance.provider_model_bundle + provider_configuration = provider_model_bundle.configuration + + if provider_configuration.using_provider_type != ProviderType.SYSTEM: + return + + provider_model = provider_configuration.get_provider_model( + model_type=model_instance.model_type_instance.model_type, + model=model_instance.model_name, + ) + if provider_model and provider_model.status == ModelStatus.QUOTA_EXCEEDED: + raise QuotaExceededError(f"Model provider {model_instance.provider} quota exceeded.") + + +def deduct_llm_quota(*, tenant_id: str, model_instance: ModelInstance, usage: LLMUsage) -> None: + provider_model_bundle = model_instance.provider_model_bundle + provider_configuration = provider_model_bundle.configuration + + if provider_configuration.using_provider_type != ProviderType.SYSTEM: + return + + system_configuration = provider_configuration.system_configuration + + quota_unit = None + for quota_configuration in system_configuration.quota_configurations: + if quota_configuration.quota_type == system_configuration.current_quota_type: + quota_unit = quota_configuration.quota_unit + + if quota_configuration.quota_limit == -1: + return + + break + + used_quota = None + if quota_unit: + if quota_unit == QuotaUnit.TOKENS: + used_quota = usage.total_tokens + elif quota_unit == QuotaUnit.CREDITS: + used_quota = dify_config.get_model_credits(model_instance.model_name) + else: + used_quota = 1 + + if used_quota is not None and system_configuration.current_quota_type is not None: + if system_configuration.current_quota_type == ProviderQuotaType.TRIAL: + from services.credit_pool_service import CreditPoolService + + CreditPoolService.check_and_deduct_credits( + tenant_id=tenant_id, + credits_required=used_quota, + ) + elif system_configuration.current_quota_type == ProviderQuotaType.PAID: + from services.credit_pool_service import CreditPoolService + + CreditPoolService.check_and_deduct_credits( + tenant_id=tenant_id, + credits_required=used_quota, + pool_type="paid", + ) + else: + with Session(db.engine) as session: + stmt = ( + update(Provider) + .where( + Provider.tenant_id == tenant_id, + # TODO: Use provider name with prefix after the data migration. + Provider.provider_name == ModelProviderID(model_instance.provider).provider_name, + Provider.provider_type == ProviderType.SYSTEM.value, + Provider.quota_type == system_configuration.current_quota_type.value, + Provider.quota_limit > Provider.quota_used, + ) + .values( + quota_used=Provider.quota_used + used_quota, + last_used=naive_utc_now(), + ) + ) + session.execute(stmt) + session.commit() diff --git a/api/core/app/workflow/layers/__init__.py b/api/core/app/workflow/layers/__init__.py index 945f75303c..7d5841275d 100644 --- a/api/core/app/workflow/layers/__init__.py +++ b/api/core/app/workflow/layers/__init__.py @@ -1,9 +1,11 @@ """Workflow-level GraphEngine layers that depend on outer infrastructure.""" +from .llm_quota import LLMQuotaLayer from .observability import ObservabilityLayer from .persistence import PersistenceWorkflowInfo, WorkflowPersistenceLayer __all__ = [ + "LLMQuotaLayer", "ObservabilityLayer", "PersistenceWorkflowInfo", "WorkflowPersistenceLayer", diff --git a/api/core/app/workflow/layers/llm_quota.py b/api/core/app/workflow/layers/llm_quota.py new file mode 100644 index 0000000000..45fb84c81f --- /dev/null +++ b/api/core/app/workflow/layers/llm_quota.py @@ -0,0 +1,128 @@ +""" +LLM quota deduction layer for GraphEngine. + +This layer centralizes model-quota deduction outside node implementations. +""" + +import logging +from typing import TYPE_CHECKING, cast, final + +from typing_extensions import override + +from core.app.llm import deduct_llm_quota, ensure_llm_quota_available +from core.errors.error import QuotaExceededError +from core.model_manager import ModelInstance +from core.workflow.enums import NodeType +from core.workflow.graph_engine.entities.commands import AbortCommand, CommandType +from core.workflow.graph_engine.layers.base import GraphEngineLayer +from core.workflow.graph_events import GraphEngineEvent, GraphNodeEventBase +from core.workflow.graph_events.node import NodeRunSucceededEvent +from core.workflow.nodes.base.node import Node + +if TYPE_CHECKING: + from core.workflow.nodes.llm.node import LLMNode + from core.workflow.nodes.parameter_extractor.parameter_extractor_node import ParameterExtractorNode + from core.workflow.nodes.question_classifier.question_classifier_node import QuestionClassifierNode + +logger = logging.getLogger(__name__) + + +@final +class LLMQuotaLayer(GraphEngineLayer): + """Graph layer that applies LLM quota deduction after node execution.""" + + def __init__(self) -> None: + super().__init__() + self._abort_sent = False + + @override + def on_graph_start(self) -> None: + self._abort_sent = False + + @override + def on_event(self, event: GraphEngineEvent) -> None: + _ = event + + @override + def on_graph_end(self, error: Exception | None) -> None: + _ = error + + @override + def on_node_run_start(self, node: Node) -> None: + if self._abort_sent: + return + + model_instance = self._extract_model_instance(node) + if model_instance is None: + return + + try: + ensure_llm_quota_available(model_instance=model_instance) + except QuotaExceededError as exc: + self._set_stop_event(node) + self._send_abort_command(reason=str(exc)) + logger.warning("LLM quota check failed, node_id=%s, error=%s", node.id, exc) + + @override + def on_node_run_end( + self, node: Node, error: Exception | None, result_event: GraphNodeEventBase | None = None + ) -> None: + if error is not None or not isinstance(result_event, NodeRunSucceededEvent): + return + + model_instance = self._extract_model_instance(node) + if model_instance is None: + return + + try: + deduct_llm_quota( + tenant_id=node.tenant_id, + model_instance=model_instance, + usage=result_event.node_run_result.llm_usage, + ) + except QuotaExceededError as exc: + self._set_stop_event(node) + self._send_abort_command(reason=str(exc)) + logger.warning("LLM quota deduction exceeded, node_id=%s, error=%s", node.id, exc) + except Exception: + logger.exception("LLM quota deduction failed, node_id=%s", node.id) + + @staticmethod + def _set_stop_event(node: Node) -> None: + stop_event = getattr(node.graph_runtime_state, "stop_event", None) + if stop_event is not None: + stop_event.set() + + def _send_abort_command(self, *, reason: str) -> None: + if not self.command_channel or self._abort_sent: + return + + try: + self.command_channel.send_command( + AbortCommand( + command_type=CommandType.ABORT, + reason=reason, + ) + ) + self._abort_sent = True + except Exception: + logger.exception("Failed to send quota abort command") + + @staticmethod + def _extract_model_instance(node: Node) -> ModelInstance | None: + try: + match node.node_type: + case NodeType.LLM: + return cast("LLMNode", node).model_instance + case NodeType.PARAMETER_EXTRACTOR: + return cast("ParameterExtractorNode", node).model_instance + case NodeType.QUESTION_CLASSIFIER: + return cast("QuestionClassifierNode", node).model_instance + case _: + return None + except AttributeError: + logger.warning( + "LLMQuotaLayer skipped quota deduction because node does not expose a model instance, node_id=%s", + node.id, + ) + return None diff --git a/api/core/app/workflow/node_factory.py b/api/core/app/workflow/node_factory.py index 41b8c9fd7b..3a82f0a45e 100644 --- a/api/core/app/workflow/node_factory.py +++ b/api/core/app/workflow/node_factory.py @@ -1,6 +1,8 @@ from collections.abc import Mapping from typing import TYPE_CHECKING, Any, cast, final +from sqlalchemy import select +from sqlalchemy.orm import Session from typing_extensions import override from configs import dify_config @@ -11,14 +13,16 @@ from core.helper.code_executor.code_executor import ( CodeExecutor, ) from core.helper.ssrf_proxy import ssrf_proxy +from core.memory.token_buffer_memory import TokenBufferMemory from core.model_manager import ModelInstance from core.model_runtime.entities.model_entities import ModelType +from core.model_runtime.memory import PromptMessageMemory from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel from core.prompt.entities.advanced_prompt_entities import MemoryConfig from core.rag.retrieval.dataset_retrieval import DatasetRetrieval from core.tools.tool_file_manager import ToolFileManager from core.workflow.entities.graph_config import NodeConfigDict -from core.workflow.enums import NodeType +from core.workflow.enums import NodeType, SystemVariableKey from core.workflow.file.file_manager import file_manager from core.workflow.graph.graph import NodeFactory from core.workflow.nodes.base.node import Node @@ -29,11 +33,9 @@ from core.workflow.nodes.datasource import DatasourceNode from core.workflow.nodes.document_extractor import DocumentExtractorNode, UnstructuredApiConfig from core.workflow.nodes.http_request import HttpRequestNode, build_http_request_config from core.workflow.nodes.knowledge_retrieval.knowledge_retrieval_node import KnowledgeRetrievalNode -from core.workflow.nodes.llm import llm_utils from core.workflow.nodes.llm.entities import ModelConfig from core.workflow.nodes.llm.exc import LLMModeRequiredError, ModelNotExistError from core.workflow.nodes.llm.node import LLMNode -from core.workflow.nodes.llm.protocols import PromptMessageMemory from core.workflow.nodes.node_mapping import LATEST_VERSION, NODE_TYPE_CLASSES_MAPPING from core.workflow.nodes.parameter_extractor.parameter_extractor_node import ParameterExtractorNode from core.workflow.nodes.question_classifier.question_classifier_node import QuestionClassifierNode @@ -41,12 +43,34 @@ from core.workflow.nodes.template_transform.template_renderer import ( CodeExecutorJinja2TemplateRenderer, ) from core.workflow.nodes.template_transform.template_transform_node import TemplateTransformNode +from core.workflow.variables.segments import StringSegment +from extensions.ext_database import db +from models.model import Conversation if TYPE_CHECKING: from core.workflow.entities import GraphInitParams from core.workflow.runtime import GraphRuntimeState +def fetch_memory( + *, + conversation_id: str | None, + app_id: str, + node_data_memory: MemoryConfig | None, + model_instance: ModelInstance, +) -> TokenBufferMemory | None: + if not node_data_memory or not conversation_id: + return None + + with Session(db.engine, expire_on_commit=False) as session: + stmt = select(Conversation).where(Conversation.app_id == app_id, Conversation.id == conversation_id) + conversation = session.scalar(stmt) + if not conversation: + return None + + return TokenBufferMemory(conversation=conversation, model_instance=model_instance) + + class DefaultWorkflowCodeExecutor: def execute( self, @@ -221,6 +245,7 @@ class DifyNodeFactory(NodeFactory): if node_type == NodeType.QUESTION_CLASSIFIER: model_instance = self._build_model_instance_for_llm_node(node_data) + memory = self._build_memory_for_llm_node(node_data=node_data, model_instance=model_instance) return QuestionClassifierNode( id=node_id, config=node_config, @@ -229,10 +254,12 @@ class DifyNodeFactory(NodeFactory): credentials_provider=self._llm_credentials_provider, model_factory=self._llm_model_factory, model_instance=model_instance, + memory=memory, ) if node_type == NodeType.PARAMETER_EXTRACTOR: model_instance = self._build_model_instance_for_llm_node(node_data) + memory = self._build_memory_for_llm_node(node_data=node_data, model_instance=model_instance) return ParameterExtractorNode( id=node_id, config=node_config, @@ -241,6 +268,7 @@ class DifyNodeFactory(NodeFactory): credentials_provider=self._llm_credentials_provider, model_factory=self._llm_model_factory, model_instance=model_instance, + memory=memory, ) return node_class( @@ -295,8 +323,14 @@ class DifyNodeFactory(NodeFactory): return None node_memory = MemoryConfig.model_validate(raw_memory_config) - return llm_utils.fetch_memory( - variable_pool=self.graph_runtime_state.variable_pool, + conversation_id_variable = self.graph_runtime_state.variable_pool.get( + ["sys", SystemVariableKey.CONVERSATION_ID] + ) + conversation_id = ( + conversation_id_variable.value if isinstance(conversation_id_variable, StringSegment) else None + ) + return fetch_memory( + conversation_id=conversation_id, app_id=self.graph_init_params.app_id, node_data_memory=node_memory, model_instance=model_instance, diff --git a/api/core/mcp/server/streamable_http.py b/api/core/mcp/server/streamable_http.py index 212c2eb073..da747d2c1f 100644 --- a/api/core/mcp/server/streamable_http.py +++ b/api/core/mcp/server/streamable_http.py @@ -4,10 +4,10 @@ from collections.abc import Mapping from typing import Any, cast from configs import dify_config -from core.app.app_config.entities import VariableEntity, VariableEntityType from core.app.entities.app_invoke_entities import InvokeFrom from core.app.features.rate_limiting.rate_limit import RateLimitGenerator from core.mcp import types as mcp_types +from core.workflow.variables.input_entities import VariableEntity, VariableEntityType from models.model import App, AppMCPServer, AppMode, EndUser from services.app_generate_service import AppGenerateService diff --git a/api/core/model_runtime/memory/__init__.py b/api/core/model_runtime/memory/__init__.py new file mode 100644 index 0000000000..2d954486c3 --- /dev/null +++ b/api/core/model_runtime/memory/__init__.py @@ -0,0 +1,3 @@ +from .prompt_message_memory import DEFAULT_MEMORY_MAX_TOKEN_LIMIT, PromptMessageMemory + +__all__ = ["DEFAULT_MEMORY_MAX_TOKEN_LIMIT", "PromptMessageMemory"] diff --git a/api/core/model_runtime/memory/prompt_message_memory.py b/api/core/model_runtime/memory/prompt_message_memory.py new file mode 100644 index 0000000000..4491ddfd05 --- /dev/null +++ b/api/core/model_runtime/memory/prompt_message_memory.py @@ -0,0 +1,18 @@ +from __future__ import annotations + +from collections.abc import Sequence +from typing import Protocol + +from core.model_runtime.entities import PromptMessage + +DEFAULT_MEMORY_MAX_TOKEN_LIMIT = 2000 + + +class PromptMessageMemory(Protocol): + """Port for loading memory as prompt messages.""" + + def get_history_prompt_messages( + self, max_token_limit: int = DEFAULT_MEMORY_MAX_TOKEN_LIMIT, message_limit: int | None = None + ) -> Sequence[PromptMessage]: + """Return historical prompt messages constrained by token/message limits.""" + ... diff --git a/api/core/plugin/backwards_invocation/model.py b/api/core/plugin/backwards_invocation/model.py index 6cdc047a64..4ecc22834d 100644 --- a/api/core/plugin/backwards_invocation/model.py +++ b/api/core/plugin/backwards_invocation/model.py @@ -2,6 +2,7 @@ import tempfile from binascii import hexlify, unhexlify from collections.abc import Generator +from core.app.llm import deduct_llm_quota from core.llm_generator.output_parser.structured_output import invoke_llm_with_structured_output from core.model_manager import ModelManager from core.model_runtime.entities.llm_entities import ( @@ -29,7 +30,6 @@ from core.plugin.entities.request import ( ) from core.tools.entities.tool_entities import ToolProviderType from core.tools.utils.model_invocation_utils import ModelInvocationUtils -from core.workflow.nodes.llm import llm_utils from models.account import Tenant @@ -63,16 +63,14 @@ class PluginModelBackwardsInvocation(BaseBackwardsInvocation): def handle() -> Generator[LLMResultChunk, None, None]: for chunk in response: if chunk.delta.usage: - llm_utils.deduct_llm_quota( - tenant_id=tenant.id, model_instance=model_instance, usage=chunk.delta.usage - ) + deduct_llm_quota(tenant_id=tenant.id, model_instance=model_instance, usage=chunk.delta.usage) chunk.prompt_messages = [] yield chunk return handle() else: if response.usage: - llm_utils.deduct_llm_quota(tenant_id=tenant.id, model_instance=model_instance, usage=response.usage) + deduct_llm_quota(tenant_id=tenant.id, model_instance=model_instance, usage=response.usage) def handle_non_streaming(response: LLMResult) -> Generator[LLMResultChunk, None, None]: yield LLMResultChunk( @@ -126,16 +124,14 @@ class PluginModelBackwardsInvocation(BaseBackwardsInvocation): def handle() -> Generator[LLMResultChunkWithStructuredOutput, None, None]: for chunk in response: if chunk.delta.usage: - llm_utils.deduct_llm_quota( - tenant_id=tenant.id, model_instance=model_instance, usage=chunk.delta.usage - ) + deduct_llm_quota(tenant_id=tenant.id, model_instance=model_instance, usage=chunk.delta.usage) chunk.prompt_messages = [] yield chunk return handle() else: if response.usage: - llm_utils.deduct_llm_quota(tenant_id=tenant.id, model_instance=model_instance, usage=response.usage) + deduct_llm_quota(tenant_id=tenant.id, model_instance=model_instance, usage=response.usage) def handle_non_streaming( response: LLMResultWithStructuredOutput, diff --git a/api/core/rag/datasource/vdb/analyticdb/analyticdb_vector_openapi.py b/api/core/rag/datasource/vdb/analyticdb/analyticdb_vector_openapi.py index 77a0fa6cf2..702200e0ac 100644 --- a/api/core/rag/datasource/vdb/analyticdb/analyticdb_vector_openapi.py +++ b/api/core/rag/datasource/vdb/analyticdb/analyticdb_vector_openapi.py @@ -192,8 +192,8 @@ class AnalyticdbVectorOpenAPI: collection=self._collection_name, metrics=self.config.metrics, include_values=True, - vector=None, # ty: ignore [invalid-argument-type] - content=None, # ty: ignore [invalid-argument-type] + vector=None, + content=None, top_k=1, filter=f"ref_doc_id='{id}'", ) @@ -211,7 +211,7 @@ class AnalyticdbVectorOpenAPI: namespace=self.config.namespace, namespace_password=self.config.namespace_password, collection=self._collection_name, - collection_data=None, # ty: ignore [invalid-argument-type] + collection_data=None, collection_data_filter=f"ref_doc_id IN {ids_str}", ) self._client.delete_collection_data(request) @@ -225,7 +225,7 @@ class AnalyticdbVectorOpenAPI: namespace=self.config.namespace, namespace_password=self.config.namespace_password, collection=self._collection_name, - collection_data=None, # ty: ignore [invalid-argument-type] + collection_data=None, collection_data_filter=f"metadata_ ->> '{key}' = '{value}'", ) self._client.delete_collection_data(request) @@ -249,7 +249,7 @@ class AnalyticdbVectorOpenAPI: include_values=kwargs.pop("include_values", True), metrics=self.config.metrics, vector=query_vector, - content=None, # ty: ignore [invalid-argument-type] + content=None, top_k=kwargs.get("top_k", 4), filter=where_clause, ) @@ -285,7 +285,7 @@ class AnalyticdbVectorOpenAPI: collection=self._collection_name, include_values=kwargs.pop("include_values", True), metrics=self.config.metrics, - vector=None, # ty: ignore [invalid-argument-type] + vector=None, content=query, top_k=kwargs.get("top_k", 4), filter=where_clause, diff --git a/api/core/rag/datasource/vdb/couchbase/couchbase_vector.py b/api/core/rag/datasource/vdb/couchbase/couchbase_vector.py index 6df909ca94..9a4a65cf6f 100644 --- a/api/core/rag/datasource/vdb/couchbase/couchbase_vector.py +++ b/api/core/rag/datasource/vdb/couchbase/couchbase_vector.py @@ -306,7 +306,7 @@ class CouchbaseVector(BaseVector): def search_by_full_text(self, query: str, **kwargs: Any) -> list[Document]: top_k = kwargs.get("top_k", 4) try: - CBrequest = search.SearchRequest.create(search.QueryStringQuery("text:" + query)) # ty: ignore [too-many-positional-arguments] + CBrequest = search.SearchRequest.create(search.QueryStringQuery("text:" + query)) search_iter = self._scope.search( self._collection_name + "_search", CBrequest, SearchOptions(limit=top_k, fields=["*"]) ) diff --git a/api/core/rag/index_processor/processor/paragraph_index_processor.py b/api/core/rag/index_processor/processor/paragraph_index_processor.py index cfeee4afc7..df5c89a522 100644 --- a/api/core/rag/index_processor/processor/paragraph_index_processor.py +++ b/api/core/rag/index_processor/processor/paragraph_index_processor.py @@ -8,6 +8,7 @@ from typing import Any, cast logger = logging.getLogger(__name__) +from core.app.llm import deduct_llm_quota from core.entities.knowledge_entities import PreviewDetail from core.llm_generator.prompts import DEFAULT_GENERATOR_SUMMARY_PROMPT from core.model_manager import ModelInstance @@ -35,7 +36,6 @@ from core.rag.models.document import AttachmentDocument, Document, MultimodalGen from core.rag.retrieval.retrieval_methods import RetrievalMethod from core.tools.utils.text_processing_utils import remove_leading_symbols from core.workflow.file import File, FileTransferMethod, FileType, file_manager -from core.workflow.nodes.llm import llm_utils from extensions.ext_database import db from factories.file_factory import build_from_mapping from libs import helper @@ -474,7 +474,7 @@ class ParagraphIndexProcessor(BaseIndexProcessor): # Deduct quota for summary generation (same as workflow nodes) try: - llm_utils.deduct_llm_quota(tenant_id=tenant_id, model_instance=model_instance, usage=usage) + deduct_llm_quota(tenant_id=tenant_id, model_instance=model_instance, usage=usage) except Exception as e: # Log but don't fail summary generation if quota deduction fails logger.warning("Failed to deduct quota for summary generation: %s", str(e)) diff --git a/api/core/rag/retrieval/router/multi_dataset_react_route.py b/api/core/rag/retrieval/router/multi_dataset_react_route.py index 8f3bec2704..fa2007122d 100644 --- a/api/core/rag/retrieval/router/multi_dataset_react_route.py +++ b/api/core/rag/retrieval/router/multi_dataset_react_route.py @@ -2,6 +2,7 @@ from collections.abc import Generator, Sequence from typing import Union from core.app.entities.app_invoke_entities import ModelConfigWithCredentialsEntity +from core.app.llm import deduct_llm_quota from core.model_manager import ModelInstance from core.model_runtime.entities.llm_entities import LLMResult, LLMUsage from core.model_runtime.entities.message_entities import PromptMessage, PromptMessageRole, PromptMessageTool @@ -9,7 +10,6 @@ from core.prompt.advanced_prompt_transform import AdvancedPromptTransform from core.prompt.entities.advanced_prompt_entities import ChatModelMessage, CompletionModelPromptTemplate from core.rag.retrieval.output_parser.react_output import ReactAction from core.rag.retrieval.output_parser.structured_chat import StructuredChatOutputParser -from core.workflow.nodes.llm import llm_utils PREFIX = """Respond to the human as helpfully and accurately as possible. You have access to the following tools:""" @@ -162,7 +162,7 @@ class ReactMultiDatasetRouter: text, usage = self._handle_invoke_result(invoke_result=invoke_result) # deduct quota - llm_utils.deduct_llm_quota(tenant_id=tenant_id, model_instance=model_instance, usage=usage) + deduct_llm_quota(tenant_id=tenant_id, model_instance=model_instance, usage=usage) return text, usage diff --git a/api/core/tools/builtin_tool/providers/webscraper/webscraper.yaml b/api/core/tools/builtin_tool/providers/webscraper/webscraper.yaml index 96edcf42fe..0edcdc4521 100644 --- a/api/core/tools/builtin_tool/providers/webscraper/webscraper.yaml +++ b/api/core/tools/builtin_tool/providers/webscraper/webscraper.yaml @@ -6,9 +6,9 @@ identity: zh_Hans: η½‘ι‘΅ζŠ“ε– pt_BR: WebScraper description: - en_US: Web Scrapper tool kit is used to scrape web + en_US: Web Scraper tool kit is used to scrape web zh_Hans: δΈ€δΈͺη”¨δΊŽζŠ“ε–η½‘ι‘΅ηš„ε·₯具。 - pt_BR: Web Scrapper tool kit is used to scrape web + pt_BR: Web Scraper tool kit is used to scrape web icon: icon.svg tags: - productivity diff --git a/api/core/tools/utils/workflow_configuration_sync.py b/api/core/tools/utils/workflow_configuration_sync.py index 186e1656ba..8e8c5e9c6a 100644 --- a/api/core/tools/utils/workflow_configuration_sync.py +++ b/api/core/tools/utils/workflow_configuration_sync.py @@ -1,11 +1,11 @@ from collections.abc import Mapping, Sequence from typing import Any -from core.app.app_config.entities import VariableEntity from core.tools.entities.tool_entities import WorkflowToolParameterConfiguration from core.tools.errors import WorkflowToolHumanInputNotSupportedError from core.workflow.enums import NodeType from core.workflow.nodes.base.entities import OutputVariableEntity +from core.workflow.variables.input_entities import VariableEntity class WorkflowToolConfigurationUtils: diff --git a/api/core/tools/workflow_as_tool/provider.py b/api/core/tools/workflow_as_tool/provider.py index a706f101ca..56faccb407 100644 --- a/api/core/tools/workflow_as_tool/provider.py +++ b/api/core/tools/workflow_as_tool/provider.py @@ -5,7 +5,6 @@ from collections.abc import Mapping from pydantic import Field from sqlalchemy.orm import Session -from core.app.app_config.entities import VariableEntity, VariableEntityType from core.app.apps.workflow.app_config_manager import WorkflowAppConfigManager from core.db.session_factory import session_factory from core.plugin.entities.parameters import PluginParameterOption @@ -23,6 +22,7 @@ from core.tools.entities.tool_entities import ( ) from core.tools.utils.workflow_configuration_sync import WorkflowToolConfigurationUtils from core.tools.workflow_as_tool.tool import WorkflowTool +from core.workflow.variables.input_entities import VariableEntity, VariableEntityType from extensions.ext_database import db from models.account import Account from models.model import App, AppMode diff --git a/api/core/workflow/graph_engine/graph_engine.py b/api/core/workflow/graph_engine/graph_engine.py index d5f0256ca7..7c46fc2239 100644 --- a/api/core/workflow/graph_engine/graph_engine.py +++ b/api/core/workflow/graph_engine/graph_engine.py @@ -9,7 +9,6 @@ from __future__ import annotations import logging import queue -import threading from collections.abc import Generator from typing import TYPE_CHECKING, cast, final @@ -77,13 +76,10 @@ class GraphEngine: config: GraphEngineConfig = _DEFAULT_CONFIG, ) -> None: """Initialize the graph engine with all subsystems and dependencies.""" - # stop event - self._stop_event = threading.Event() # Bind runtime state to current workflow context self._graph = graph self._graph_runtime_state = graph_runtime_state - self._graph_runtime_state.stop_event = self._stop_event self._graph_runtime_state.configure(graph=cast("GraphProtocol", graph)) self._command_channel = command_channel self._config = config @@ -163,7 +159,6 @@ class GraphEngine: layers=self._layers, execution_context=execution_context, config=self._config, - stop_event=self._stop_event, ) # === Orchestration === @@ -194,7 +189,6 @@ class GraphEngine: event_handler=self._event_handler_registry, execution_coordinator=self._execution_coordinator, event_emitter=self._event_manager, - stop_event=self._stop_event, ) # === Validation === @@ -314,7 +308,6 @@ class GraphEngine: def _start_execution(self, *, resume: bool = False) -> None: """Start execution subsystems.""" - self._stop_event.clear() paused_nodes: list[str] = [] deferred_nodes: list[str] = [] if resume: @@ -348,7 +341,6 @@ class GraphEngine: def _stop_execution(self) -> None: """Stop execution subsystems.""" - self._stop_event.set() self._dispatcher.stop() self._worker_pool.stop() # Don't mark complete here as the dispatcher already does it diff --git a/api/core/workflow/graph_engine/orchestration/dispatcher.py b/api/core/workflow/graph_engine/orchestration/dispatcher.py index d40d15c545..76dd1c7768 100644 --- a/api/core/workflow/graph_engine/orchestration/dispatcher.py +++ b/api/core/workflow/graph_engine/orchestration/dispatcher.py @@ -44,7 +44,6 @@ class Dispatcher: event_queue: queue.Queue[GraphNodeEventBase], event_handler: "EventHandler", execution_coordinator: ExecutionCoordinator, - stop_event: threading.Event, event_emitter: EventManager | None = None, ) -> None: """ @@ -62,7 +61,7 @@ class Dispatcher: self._event_emitter = event_emitter self._thread: threading.Thread | None = None - self._stop_event = stop_event + self._stop_event = threading.Event() self._start_time: float | None = None def start(self) -> None: @@ -70,12 +69,14 @@ class Dispatcher: if self._thread and self._thread.is_alive(): return + self._stop_event.clear() self._start_time = time.time() self._thread = threading.Thread(target=self._dispatcher_loop, name="GraphDispatcher", daemon=True) self._thread.start() def stop(self) -> None: """Stop the dispatcher thread.""" + self._stop_event.set() if self._thread and self._thread.is_alive(): self._thread.join(timeout=2.0) diff --git a/api/core/workflow/graph_engine/worker.py b/api/core/workflow/graph_engine/worker.py index 512df6ff86..9e218f6fa6 100644 --- a/api/core/workflow/graph_engine/worker.py +++ b/api/core/workflow/graph_engine/worker.py @@ -42,7 +42,6 @@ class Worker(threading.Thread): event_queue: queue.Queue[GraphNodeEventBase], graph: Graph, layers: Sequence[GraphEngineLayer], - stop_event: threading.Event, worker_id: int = 0, execution_context: IExecutionContext | None = None, ) -> None: @@ -63,16 +62,13 @@ class Worker(threading.Thread): self._graph = graph self._worker_id = worker_id self._execution_context = execution_context - self._stop_event = stop_event + self._stop_event = threading.Event() self._layers = layers if layers is not None else [] self._last_task_time = time.time() def stop(self) -> None: - """Worker is controlled via shared stop_event from GraphEngine. - - This method is a no-op retained for backward compatibility. - """ - pass + """Signal the worker to stop processing.""" + self._stop_event.set() @property def is_idle(self) -> bool: diff --git a/api/core/workflow/graph_engine/worker_management/worker_pool.py b/api/core/workflow/graph_engine/worker_management/worker_pool.py index 3bff566ac8..2c14f53746 100644 --- a/api/core/workflow/graph_engine/worker_management/worker_pool.py +++ b/api/core/workflow/graph_engine/worker_management/worker_pool.py @@ -37,7 +37,6 @@ class WorkerPool: event_queue: queue.Queue[GraphNodeEventBase], graph: Graph, layers: list[GraphEngineLayer], - stop_event: threading.Event, config: GraphEngineConfig, execution_context: IExecutionContext | None = None, ) -> None: @@ -64,7 +63,6 @@ class WorkerPool: self._worker_counter = 0 self._lock = threading.RLock() self._running = False - self._stop_event = stop_event # No longer tracking worker states with callbacks to avoid lock contention @@ -135,7 +133,6 @@ class WorkerPool: layers=self._layers, worker_id=worker_id, execution_context=self._execution_context, - stop_event=self._stop_event, ) worker.start() diff --git a/api/core/workflow/nodes/base/node.py b/api/core/workflow/nodes/base/node.py index 2b773b537c..976e8032b8 100644 --- a/api/core/workflow/nodes/base/node.py +++ b/api/core/workflow/nodes/base/node.py @@ -302,10 +302,6 @@ class Node(Generic[NodeDataT]): """ raise NotImplementedError - def _should_stop(self) -> bool: - """Check if execution should be stopped.""" - return self.graph_runtime_state.stop_event.is_set() - def run(self) -> Generator[GraphNodeEventBase, None, None]: execution_id = self.ensure_execution_id() self._start_at = naive_utc_now() @@ -374,21 +370,6 @@ class Node(Generic[NodeDataT]): yield event else: yield event - - if self._should_stop(): - error_message = "Execution cancelled" - yield NodeRunFailedEvent( - id=self.execution_id, - node_id=self._node_id, - node_type=self.node_type, - start_at=self._start_at, - node_run_result=NodeRunResult( - status=WorkflowNodeExecutionStatus.FAILED, - error=error_message, - ), - error=error_message, - ) - return except Exception as e: logger.exception("Node %s failed to run", self._node_id) result = NodeRunResult( diff --git a/api/core/workflow/nodes/iteration/iteration_node.py b/api/core/workflow/nodes/iteration/iteration_node.py index 5e7aa2a751..54b0561dd8 100644 --- a/api/core/workflow/nodes/iteration/iteration_node.py +++ b/api/core/workflow/nodes/iteration/iteration_node.py @@ -588,6 +588,7 @@ class IterationNode(LLMUsageTrackingMixin, Node[IterationNodeData]): def _create_graph_engine(self, index: int, item: object): # Import dependencies + from core.app.workflow.layers.llm_quota import LLMQuotaLayer from core.app.workflow.node_factory import DifyNodeFactory from core.workflow.entities import GraphInitParams from core.workflow.graph import Graph @@ -642,5 +643,6 @@ class IterationNode(LLMUsageTrackingMixin, Node[IterationNodeData]): command_channel=InMemoryChannel(), # Use InMemoryChannel for sub-graphs config=GraphEngineConfig(), ) + graph_engine.layer(LLMQuotaLayer()) return graph_engine diff --git a/api/core/workflow/nodes/llm/llm_utils.py b/api/core/workflow/nodes/llm/llm_utils.py index f753e19897..72f150d920 100644 --- a/api/core/workflow/nodes/llm/llm_utils.py +++ b/api/core/workflow/nodes/llm/llm_utils.py @@ -1,26 +1,19 @@ from collections.abc import Sequence from typing import cast -from sqlalchemy import select, update -from sqlalchemy.orm import Session - -from configs import dify_config -from core.entities.provider_entities import ProviderQuotaType, QuotaUnit -from core.memory.token_buffer_memory import TokenBufferMemory from core.model_manager import ModelInstance -from core.model_runtime.entities.llm_entities import LLMUsage +from core.model_runtime.entities import PromptMessageRole +from core.model_runtime.entities.message_entities import ( + ImagePromptMessageContent, + PromptMessage, + TextPromptMessageContent, +) from core.model_runtime.entities.model_entities import AIModelEntity +from core.model_runtime.memory import PromptMessageMemory from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel -from core.prompt.entities.advanced_prompt_entities import MemoryConfig -from core.workflow.enums import SystemVariableKey from core.workflow.file.models import File from core.workflow.runtime import VariablePool -from core.workflow.variables.segments import ArrayAnySegment, ArrayFileSegment, FileSegment, NoneSegment, StringSegment -from extensions.ext_database import db -from libs.datetime_utils import naive_utc_now -from models.model import Conversation -from models.provider import Provider, ProviderType -from models.provider_ids import ModelProviderID +from core.workflow.variables.segments import ArrayAnySegment, ArrayFileSegment, FileSegment, NoneSegment from .exc import InvalidVariableTypeError @@ -48,88 +41,51 @@ def fetch_files(variable_pool: VariablePool, selector: Sequence[str]) -> Sequenc raise InvalidVariableTypeError(f"Invalid variable type: {type(variable)}") -def fetch_memory( - variable_pool: VariablePool, app_id: str, node_data_memory: MemoryConfig | None, model_instance: ModelInstance -) -> TokenBufferMemory | None: - if not node_data_memory: - return None - - # get conversation id - conversation_id_variable = variable_pool.get(["sys", SystemVariableKey.CONVERSATION_ID]) - if not isinstance(conversation_id_variable, StringSegment): - return None - conversation_id = conversation_id_variable.value - - with Session(db.engine, expire_on_commit=False) as session: - stmt = select(Conversation).where(Conversation.app_id == app_id, Conversation.id == conversation_id) - conversation = session.scalar(stmt) - if not conversation: - return None - - memory = TokenBufferMemory(conversation=conversation, model_instance=model_instance) - return memory - - -def deduct_llm_quota(tenant_id: str, model_instance: ModelInstance, usage: LLMUsage): - provider_model_bundle = model_instance.provider_model_bundle - provider_configuration = provider_model_bundle.configuration - - if provider_configuration.using_provider_type != ProviderType.SYSTEM: - return - - system_configuration = provider_configuration.system_configuration - - quota_unit = None - for quota_configuration in system_configuration.quota_configurations: - if quota_configuration.quota_type == system_configuration.current_quota_type: - quota_unit = quota_configuration.quota_unit - - if quota_configuration.quota_limit == -1: - return - - break - - used_quota = None - if quota_unit: - if quota_unit == QuotaUnit.TOKENS: - used_quota = usage.total_tokens - elif quota_unit == QuotaUnit.CREDITS: - used_quota = dify_config.get_model_credits(model_instance.model_name) +def convert_history_messages_to_text( + *, + history_messages: Sequence[PromptMessage], + human_prefix: str, + ai_prefix: str, +) -> str: + string_messages: list[str] = [] + for message in history_messages: + if message.role == PromptMessageRole.USER: + role = human_prefix + elif message.role == PromptMessageRole.ASSISTANT: + role = ai_prefix else: - used_quota = 1 + continue - if used_quota is not None and system_configuration.current_quota_type is not None: - if system_configuration.current_quota_type == ProviderQuotaType.TRIAL: - from services.credit_pool_service import CreditPoolService + if isinstance(message.content, list): + content_parts = [] + for content in message.content: + if isinstance(content, TextPromptMessageContent): + content_parts.append(content.data) + elif isinstance(content, ImagePromptMessageContent): + content_parts.append("[image]") - CreditPoolService.check_and_deduct_credits( - tenant_id=tenant_id, - credits_required=used_quota, - ) - elif system_configuration.current_quota_type == ProviderQuotaType.PAID: - from services.credit_pool_service import CreditPoolService - - CreditPoolService.check_and_deduct_credits( - tenant_id=tenant_id, - credits_required=used_quota, - pool_type="paid", - ) + inner_msg = "\n".join(content_parts) + string_messages.append(f"{role}: {inner_msg}") else: - with Session(db.engine) as session: - stmt = ( - update(Provider) - .where( - Provider.tenant_id == tenant_id, - # TODO: Use provider name with prefix after the data migration. - Provider.provider_name == ModelProviderID(model_instance.provider).provider_name, - Provider.provider_type == ProviderType.SYSTEM.value, - Provider.quota_type == system_configuration.current_quota_type.value, - Provider.quota_limit > Provider.quota_used, - ) - .values( - quota_used=Provider.quota_used + used_quota, - last_used=naive_utc_now(), - ) - ) - session.execute(stmt) - session.commit() + string_messages.append(f"{role}: {message.content}") + + return "\n".join(string_messages) + + +def fetch_memory_text( + *, + memory: PromptMessageMemory, + max_token_limit: int, + message_limit: int | None = None, + human_prefix: str = "Human", + ai_prefix: str = "Assistant", +) -> str: + history_messages = memory.get_history_prompt_messages( + max_token_limit=max_token_limit, + message_limit=message_limit, + ) + return convert_history_messages_to_text( + history_messages=history_messages, + human_prefix=human_prefix, + ai_prefix=ai_prefix, + ) diff --git a/api/core/workflow/nodes/llm/node.py b/api/core/workflow/nodes/llm/node.py index 057a144e89..c06db0dc16 100644 --- a/api/core/workflow/nodes/llm/node.py +++ b/api/core/workflow/nodes/llm/node.py @@ -37,6 +37,7 @@ from core.model_runtime.entities.message_entities import ( UserPromptMessage, ) from core.model_runtime.entities.model_entities import ModelFeature, ModelPropertyKey +from core.model_runtime.memory import PromptMessageMemory from core.model_runtime.utils.encoders import jsonable_encoder from core.prompt.entities.advanced_prompt_entities import CompletionModelPromptTemplate, MemoryConfig from core.prompt.utils.prompt_message_util import PromptMessageUtil @@ -62,7 +63,7 @@ from core.workflow.node_events import ( from core.workflow.nodes.base.entities import VariableSelector from core.workflow.nodes.base.node import Node from core.workflow.nodes.base.variable_template_parser import VariableTemplateParser -from core.workflow.nodes.llm.protocols import CredentialsProvider, ModelFactory, PromptMessageMemory +from core.workflow.nodes.llm.protocols import CredentialsProvider, ModelFactory from core.workflow.runtime import VariablePool from core.workflow.variables import ( ArrayFileSegment, @@ -278,8 +279,6 @@ class LLMNode(Node[LLMNodeData]): else None ) - # deduct quota - llm_utils.deduct_llm_quota(tenant_id=self.tenant_id, model_instance=model_instance, usage=usage) break elif isinstance(event, LLMStructuredOutput): structured_output = event @@ -1234,6 +1233,10 @@ class LLMNode(Node[LLMNodeData]): def retry(self) -> bool: return self.node_data.retry_config.retry_enabled + @property + def model_instance(self) -> ModelInstance: + return self._model_instance + def _combine_message_content_with_role( *, contents: str | list[PromptMessageContentUnionTypes] | None = None, role: PromptMessageRole @@ -1336,48 +1339,16 @@ def _handle_memory_completion_mode( ) if not memory_config.role_prefix: raise MemoryRolePrefixRequiredError("Memory role prefix is required for completion model.") - memory_messages = memory.get_history_prompt_messages( + memory_text = llm_utils.fetch_memory_text( + memory=memory, max_token_limit=rest_tokens, message_limit=memory_config.window.size if memory_config.window.enabled else None, - ) - memory_text = _convert_history_messages_to_text( - history_messages=memory_messages, human_prefix=memory_config.role_prefix.user, ai_prefix=memory_config.role_prefix.assistant, ) return memory_text -def _convert_history_messages_to_text( - *, - history_messages: Sequence[PromptMessage], - human_prefix: str, - ai_prefix: str, -) -> str: - string_messages: list[str] = [] - for message in history_messages: - if message.role == PromptMessageRole.USER: - role = human_prefix - elif message.role == PromptMessageRole.ASSISTANT: - role = ai_prefix - else: - continue - - if isinstance(message.content, list): - content_parts = [] - for content in message.content: - if isinstance(content, TextPromptMessageContent): - content_parts.append(content.data) - elif isinstance(content, ImagePromptMessageContent): - content_parts.append("[image]") - - inner_msg = "\n".join(content_parts) - string_messages.append(f"{role}: {inner_msg}") - else: - string_messages.append(f"{role}: {message.content}") - return "\n".join(string_messages) - - def _handle_completion_template( *, template: LLMNodeCompletionModelPromptTemplate, diff --git a/api/core/workflow/nodes/llm/protocols.py b/api/core/workflow/nodes/llm/protocols.py index 5bca04165a..8e0365299d 100644 --- a/api/core/workflow/nodes/llm/protocols.py +++ b/api/core/workflow/nodes/llm/protocols.py @@ -1,10 +1,8 @@ from __future__ import annotations -from collections.abc import Sequence from typing import Any, Protocol from core.model_manager import ModelInstance -from core.model_runtime.entities import PromptMessage class CredentialsProvider(Protocol): @@ -21,13 +19,3 @@ class ModelFactory(Protocol): def init_model_instance(self, provider_name: str, model_name: str) -> ModelInstance: """Create a model instance that is ready for schema lookup and invocation.""" ... - - -class PromptMessageMemory(Protocol): - """Port for loading memory as prompt messages for LLM nodes.""" - - def get_history_prompt_messages( - self, max_token_limit: int = 2000, message_limit: int | None = None - ) -> Sequence[PromptMessage]: - """Return historical prompt messages constrained by token/message limits.""" - ... diff --git a/api/core/workflow/nodes/loop/loop_node.py b/api/core/workflow/nodes/loop/loop_node.py index c546df1fba..40ec0cf8b1 100644 --- a/api/core/workflow/nodes/loop/loop_node.py +++ b/api/core/workflow/nodes/loop/loop_node.py @@ -413,6 +413,7 @@ class LoopNode(LLMUsageTrackingMixin, Node[LoopNodeData]): def _create_graph_engine(self, start_at: datetime, root_node_id: str): # Import dependencies + from core.app.workflow.layers.llm_quota import LLMQuotaLayer from core.app.workflow.node_factory import DifyNodeFactory from core.workflow.entities import GraphInitParams from core.workflow.graph import Graph @@ -454,5 +455,6 @@ class LoopNode(LLMUsageTrackingMixin, Node[LoopNodeData]): command_channel=InMemoryChannel(), # Use InMemoryChannel for sub-graphs config=GraphEngineConfig(), ) + graph_engine.layer(LLMQuotaLayer()) return graph_engine diff --git a/api/core/workflow/nodes/parameter_extractor/parameter_extractor_node.py b/api/core/workflow/nodes/parameter_extractor/parameter_extractor_node.py index 66ef17e585..4272b98116 100644 --- a/api/core/workflow/nodes/parameter_extractor/parameter_extractor_node.py +++ b/api/core/workflow/nodes/parameter_extractor/parameter_extractor_node.py @@ -5,7 +5,6 @@ import uuid from collections.abc import Mapping, Sequence from typing import TYPE_CHECKING, Any, cast -from core.memory.token_buffer_memory import TokenBufferMemory from core.model_manager import ModelInstance from core.model_runtime.entities import ImagePromptMessageContent from core.model_runtime.entities.llm_entities import LLMUsage @@ -18,13 +17,18 @@ from core.model_runtime.entities.message_entities import ( UserPromptMessage, ) from core.model_runtime.entities.model_entities import ModelFeature, ModelPropertyKey +from core.model_runtime.memory import PromptMessageMemory from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel from core.model_runtime.utils.encoders import jsonable_encoder from core.prompt.advanced_prompt_transform import AdvancedPromptTransform from core.prompt.entities.advanced_prompt_entities import ChatModelMessage, CompletionModelPromptTemplate from core.prompt.simple_prompt_transform import ModelMode from core.prompt.utils.prompt_message_util import PromptMessageUtil -from core.workflow.enums import NodeType, WorkflowNodeExecutionMetadataKey, WorkflowNodeExecutionStatus +from core.workflow.enums import ( + NodeType, + WorkflowNodeExecutionMetadataKey, + WorkflowNodeExecutionStatus, +) from core.workflow.file import File from core.workflow.node_events import NodeRunResult from core.workflow.nodes.base import variable_template_parser @@ -97,6 +101,7 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): _model_instance: ModelInstance _credentials_provider: "CredentialsProvider" _model_factory: "ModelFactory" + _memory: PromptMessageMemory | None def __init__( self, @@ -108,6 +113,7 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): credentials_provider: "CredentialsProvider", model_factory: "ModelFactory", model_instance: ModelInstance, + memory: PromptMessageMemory | None = None, ) -> None: super().__init__( id=id, @@ -118,6 +124,7 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): self._credentials_provider = credentials_provider self._model_factory = model_factory self._model_instance = model_instance + self._memory = memory @classmethod def get_default_config(cls, filters: Mapping[str, object] | None = None) -> Mapping[str, object]: @@ -163,13 +170,7 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): model_schema = llm_utils.fetch_model_schema(model_instance=model_instance) except ValueError as exc: raise ModelSchemaNotFoundError("Model schema not found") from exc - # fetch memory - memory = llm_utils.fetch_memory( - variable_pool=variable_pool, - app_id=self.app_id, - node_data_memory=node_data.memory, - model_instance=model_instance, - ) + memory = self._memory if ( set(model_schema.features or []) & {ModelFeature.TOOL_CALL, ModelFeature.MULTI_TOOL_CALL} @@ -308,9 +309,6 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): usage = invoke_result.usage tool_call = invoke_result.message.tool_calls[0] if invoke_result.message.tool_calls else None - # deduct quota - llm_utils.deduct_llm_quota(tenant_id=self.tenant_id, model_instance=model_instance, usage=usage) - return text, usage, tool_call def _generate_function_call_prompt( @@ -319,7 +317,7 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): query: str, variable_pool: VariablePool, model_instance: ModelInstance, - memory: TokenBufferMemory | None, + memory: PromptMessageMemory | None, files: Sequence[File], vision_detail: ImagePromptMessageContent.DETAIL | None = None, ) -> tuple[list[PromptMessage], list[PromptMessageTool]]: @@ -407,7 +405,7 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): query: str, variable_pool: VariablePool, model_instance: ModelInstance, - memory: TokenBufferMemory | None, + memory: PromptMessageMemory | None, files: Sequence[File], vision_detail: ImagePromptMessageContent.DETAIL | None = None, ) -> list[PromptMessage]: @@ -445,7 +443,7 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): query: str, variable_pool: VariablePool, model_instance: ModelInstance, - memory: TokenBufferMemory | None, + memory: PromptMessageMemory | None, files: Sequence[File], vision_detail: ImagePromptMessageContent.DETAIL | None = None, ) -> list[PromptMessage]: @@ -470,7 +468,8 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): files=files, context="", memory_config=node_data.memory, - memory=memory, + # AdvancedPromptTransform is still typed against TokenBufferMemory. + memory=cast(Any, memory), model_instance=model_instance, image_detail_config=vision_detail, ) @@ -483,7 +482,7 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): query: str, variable_pool: VariablePool, model_instance: ModelInstance, - memory: TokenBufferMemory | None, + memory: PromptMessageMemory | None, files: Sequence[File], vision_detail: ImagePromptMessageContent.DETAIL | None = None, ) -> list[PromptMessage]: @@ -715,7 +714,7 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): node_data: ParameterExtractorNodeData, query: str, variable_pool: VariablePool, - memory: TokenBufferMemory | None, + memory: PromptMessageMemory | None, max_token_limit: int = 2000, ) -> list[ChatModelMessage]: model_mode = ModelMode(node_data.model.mode) @@ -724,8 +723,8 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): instruction = variable_pool.convert_template(node_data.instruction or "").text if memory and node_data.memory and node_data.memory.window: - memory_str = memory.get_history_prompt_text( - max_token_limit=max_token_limit, message_limit=node_data.memory.window.size + memory_str = llm_utils.fetch_memory_text( + memory=memory, max_token_limit=max_token_limit, message_limit=node_data.memory.window.size ) if model_mode == ModelMode.CHAT: system_prompt_messages = ChatModelMessage( @@ -742,7 +741,7 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): node_data: ParameterExtractorNodeData, query: str, variable_pool: VariablePool, - memory: TokenBufferMemory | None, + memory: PromptMessageMemory | None, max_token_limit: int = 2000, ): model_mode = ModelMode(node_data.model.mode) @@ -751,8 +750,8 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): instruction = variable_pool.convert_template(node_data.instruction or "").text if memory and node_data.memory and node_data.memory.window: - memory_str = memory.get_history_prompt_text( - max_token_limit=max_token_limit, message_limit=node_data.memory.window.size + memory_str = llm_utils.fetch_memory_text( + memory=memory, max_token_limit=max_token_limit, message_limit=node_data.memory.window.size ) if model_mode == ModelMode.CHAT: system_prompt_messages = ChatModelMessage( @@ -828,6 +827,10 @@ class ParameterExtractorNode(Node[ParameterExtractorNodeData]): return rest_tokens + @property + def model_instance(self) -> ModelInstance: + return self._model_instance + @classmethod def _extract_variable_selector_to_variable_mapping( cls, diff --git a/api/core/workflow/nodes/question_classifier/question_classifier_node.py b/api/core/workflow/nodes/question_classifier/question_classifier_node.py index 464d9b6b9c..6005bff1a6 100644 --- a/api/core/workflow/nodes/question_classifier/question_classifier_node.py +++ b/api/core/workflow/nodes/question_classifier/question_classifier_node.py @@ -3,9 +3,9 @@ import re from collections.abc import Mapping, Sequence from typing import TYPE_CHECKING, Any -from core.memory.token_buffer_memory import TokenBufferMemory from core.model_manager import ModelInstance from core.model_runtime.entities import LLMUsage, ModelPropertyKey, PromptMessageRole +from core.model_runtime.memory import PromptMessageMemory from core.model_runtime.utils.encoders import jsonable_encoder from core.prompt.simple_prompt_transform import ModelMode from core.prompt.utils.prompt_message_util import PromptMessageUtil @@ -56,6 +56,7 @@ class QuestionClassifierNode(Node[QuestionClassifierNodeData]): _credentials_provider: "CredentialsProvider" _model_factory: "ModelFactory" _model_instance: ModelInstance + _memory: PromptMessageMemory | None def __init__( self, @@ -67,6 +68,7 @@ class QuestionClassifierNode(Node[QuestionClassifierNodeData]): credentials_provider: "CredentialsProvider", model_factory: "ModelFactory", model_instance: ModelInstance, + memory: PromptMessageMemory | None = None, llm_file_saver: LLMFileSaver | None = None, ): super().__init__( @@ -81,6 +83,7 @@ class QuestionClassifierNode(Node[QuestionClassifierNodeData]): self._credentials_provider = credentials_provider self._model_factory = model_factory self._model_instance = model_instance + self._memory = memory if llm_file_saver is None: llm_file_saver = FileSaverImpl( @@ -103,13 +106,7 @@ class QuestionClassifierNode(Node[QuestionClassifierNodeData]): variables = {"query": query} # fetch model instance model_instance = self._model_instance - # fetch memory - memory = llm_utils.fetch_memory( - variable_pool=variable_pool, - app_id=self.app_id, - node_data_memory=node_data.memory, - model_instance=model_instance, - ) + memory = self._memory # fetch instruction node_data.instruction = node_data.instruction or "" node_data.instruction = variable_pool.convert_template(node_data.instruction).text @@ -240,6 +237,10 @@ class QuestionClassifierNode(Node[QuestionClassifierNodeData]): llm_usage=usage, ) + @property + def model_instance(self) -> ModelInstance: + return self._model_instance + @classmethod def _extract_variable_selector_to_variable_mapping( cls, @@ -323,7 +324,7 @@ class QuestionClassifierNode(Node[QuestionClassifierNodeData]): self, node_data: QuestionClassifierNodeData, query: str, - memory: TokenBufferMemory | None, + memory: PromptMessageMemory | None, max_token_limit: int = 2000, ): model_mode = ModelMode(node_data.model.mode) @@ -336,7 +337,8 @@ class QuestionClassifierNode(Node[QuestionClassifierNodeData]): input_text = query memory_str = "" if memory: - memory_str = memory.get_history_prompt_text( + memory_str = llm_utils.fetch_memory_text( + memory=memory, max_token_limit=max_token_limit, message_limit=node_data.memory.window.size if node_data.memory and node_data.memory.window else None, ) diff --git a/api/core/workflow/nodes/start/entities.py b/api/core/workflow/nodes/start/entities.py index 594d1b7bab..3a99e2cbc2 100644 --- a/api/core/workflow/nodes/start/entities.py +++ b/api/core/workflow/nodes/start/entities.py @@ -2,8 +2,8 @@ from collections.abc import Sequence from pydantic import Field -from core.app.app_config.entities import VariableEntity from core.workflow.nodes.base import BaseNodeData +from core.workflow.variables.input_entities import VariableEntity class StartNodeData(BaseNodeData): diff --git a/api/core/workflow/nodes/start/start_node.py b/api/core/workflow/nodes/start/start_node.py index 53c1b4ee6b..4e5545d330 100644 --- a/api/core/workflow/nodes/start/start_node.py +++ b/api/core/workflow/nodes/start/start_node.py @@ -2,12 +2,12 @@ from typing import Any from jsonschema import Draft7Validator, ValidationError -from core.app.app_config.entities import VariableEntityType from core.workflow.constants import SYSTEM_VARIABLE_NODE_ID from core.workflow.enums import NodeExecutionType, NodeType, WorkflowNodeExecutionStatus from core.workflow.node_events import NodeRunResult from core.workflow.nodes.base.node import Node from core.workflow.nodes.start.entities import StartNodeData +from core.workflow.variables.input_entities import VariableEntityType class StartNode(Node[StartNodeData]): diff --git a/api/core/workflow/runtime/graph_runtime_state.py b/api/core/workflow/runtime/graph_runtime_state.py index c3061f33e6..0af6bf49bc 100644 --- a/api/core/workflow/runtime/graph_runtime_state.py +++ b/api/core/workflow/runtime/graph_runtime_state.py @@ -2,7 +2,6 @@ from __future__ import annotations import importlib import json -import threading from collections.abc import Mapping, Sequence from copy import deepcopy from dataclasses import dataclass @@ -219,8 +218,6 @@ class GraphRuntimeState: self._pending_graph_node_states: dict[str, NodeState] | None = None self._pending_graph_edge_states: dict[str, NodeState] | None = None - self.stop_event: threading.Event = threading.Event() - if graph is not None: self.attach_graph(graph) diff --git a/api/core/workflow/variables/__init__.py b/api/core/workflow/variables/__init__.py index 7498224923..be3fc8d97a 100644 --- a/api/core/workflow/variables/__init__.py +++ b/api/core/workflow/variables/__init__.py @@ -1,3 +1,4 @@ +from .input_entities import VariableEntity, VariableEntityType from .segment_group import SegmentGroup from .segments import ( ArrayAnySegment, @@ -64,4 +65,6 @@ __all__ = [ "StringVariable", "Variable", "VariableBase", + "VariableEntity", + "VariableEntityType", ] diff --git a/api/core/workflow/variables/input_entities.py b/api/core/workflow/variables/input_entities.py new file mode 100644 index 0000000000..9a42012f0a --- /dev/null +++ b/api/core/workflow/variables/input_entities.py @@ -0,0 +1,62 @@ +from collections.abc import Sequence +from enum import StrEnum +from typing import Any + +from jsonschema import Draft7Validator, SchemaError +from pydantic import BaseModel, Field, field_validator + +from core.workflow.file import FileTransferMethod, FileType + + +class VariableEntityType(StrEnum): + TEXT_INPUT = "text-input" + SELECT = "select" + PARAGRAPH = "paragraph" + NUMBER = "number" + EXTERNAL_DATA_TOOL = "external_data_tool" + FILE = "file" + FILE_LIST = "file-list" + CHECKBOX = "checkbox" + JSON_OBJECT = "json_object" + + +class VariableEntity(BaseModel): + """ + Shared variable entity used by workflow runtime and app configuration. + """ + + # `variable` records the name of the variable in user inputs. + variable: str + label: str + description: str = "" + type: VariableEntityType + required: bool = False + hide: bool = False + default: Any = None + max_length: int | None = None + options: Sequence[str] = Field(default_factory=list) + allowed_file_types: Sequence[FileType] | None = Field(default_factory=list) + allowed_file_extensions: Sequence[str] | None = Field(default_factory=list) + allowed_file_upload_methods: Sequence[FileTransferMethod] | None = Field(default_factory=list) + json_schema: dict[str, Any] | None = Field(default=None) + + @field_validator("description", mode="before") + @classmethod + def convert_none_description(cls, value: Any) -> str: + return value or "" + + @field_validator("options", mode="before") + @classmethod + def convert_none_options(cls, value: Any) -> Sequence[str]: + return value or [] + + @field_validator("json_schema") + @classmethod + def validate_json_schema(cls, schema: dict[str, Any] | None) -> dict[str, Any] | None: + if schema is None: + return None + try: + Draft7Validator.check_schema(schema) + except SchemaError as error: + raise ValueError(f"Invalid JSON schema: {error.message}") + return schema diff --git a/api/core/workflow/workflow_entry.py b/api/core/workflow/workflow_entry.py index a724fbcab7..2ea4266b16 100644 --- a/api/core/workflow/workflow_entry.py +++ b/api/core/workflow/workflow_entry.py @@ -6,6 +6,7 @@ from typing import Any, cast from configs import dify_config from core.app.apps.exc import GenerateTaskStoppedError from core.app.entities.app_invoke_entities import InvokeFrom +from core.app.workflow.layers.llm_quota import LLMQuotaLayer from core.app.workflow.layers.observability import ObservabilityLayer from core.app.workflow.node_factory import DifyNodeFactory from core.workflow.constants import ENVIRONMENT_VARIABLE_NODE_ID @@ -106,6 +107,7 @@ class WorkflowEntry: max_steps=dify_config.WORKFLOW_MAX_EXECUTION_STEPS, max_time=dify_config.WORKFLOW_MAX_EXECUTION_TIME ) self.graph_engine.layer(limits_layer) + self.graph_engine.layer(LLMQuotaLayer()) # Add observability layer when OTel is enabled if dify_config.ENABLE_OTEL or is_instrument_flag_enabled(): diff --git a/api/libs/pyrefly_diagnostics.py b/api/libs/pyrefly_diagnostics.py new file mode 100644 index 0000000000..4d9df65099 --- /dev/null +++ b/api/libs/pyrefly_diagnostics.py @@ -0,0 +1,48 @@ +"""Helpers for producing concise pyrefly diagnostics for CI diff output.""" + +from __future__ import annotations + +import sys + +_DIAGNOSTIC_PREFIXES = ("ERROR ", "WARNING ") +_LOCATION_PREFIX = "-->" + + +def extract_diagnostics(raw_output: str) -> str: + """Extract stable diagnostic lines from pyrefly output. + + The full pyrefly output includes code excerpts and carets, which create noisy + diffs. This helper keeps only: + - diagnostic headline lines (``ERROR ...`` / ``WARNING ...``) + - the following location line (``--> path:line:column``), when present + """ + + lines = raw_output.splitlines() + diagnostics: list[str] = [] + + for index, line in enumerate(lines): + if line.startswith(_DIAGNOSTIC_PREFIXES): + diagnostics.append(line.rstrip()) + + next_index = index + 1 + if next_index < len(lines): + next_line = lines[next_index] + if next_line.lstrip().startswith(_LOCATION_PREFIX): + diagnostics.append(next_line.rstrip()) + + if not diagnostics: + return "" + + return "\n".join(diagnostics) + "\n" + + +def main() -> int: + """Read pyrefly output from stdin and print normalized diagnostics.""" + + raw_output = sys.stdin.read() + sys.stdout.write(extract_diagnostics(raw_output)) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/api/models/workflow.py b/api/models/workflow.py index 6a86251216..7da09a5a1b 100644 --- a/api/models/workflow.py +++ b/api/models/workflow.py @@ -787,7 +787,7 @@ class WorkflowNodeExecutionModel(Base): # This model is expected to have `offlo __tablename__ = "workflow_node_executions" - @declared_attr + @declared_attr.directive @classmethod def __table_args__(cls) -> Any: return ( diff --git a/api/pyproject.toml b/api/pyproject.toml index 24569504cc..f5e43f3ed1 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -68,7 +68,7 @@ dependencies = [ "pydantic~=2.12.5", "pydantic-extra-types~=2.10.3", "pydantic-settings~=2.12.0", - "pyjwt~=2.10.1", + "pyjwt~=2.11.0", "pypdfium2==5.2.0", "python-docx~=1.2.0", "python-dotenv==1.0.1", @@ -116,7 +116,6 @@ dev = [ "dotenv-linter~=0.5.0", "faker~=38.2.0", "lxml-stubs~=0.5.1", - "ty>=0.0.14", "basedpyright~=1.31.0", "ruff~=0.14.0", "pytest~=8.3.2", @@ -125,7 +124,7 @@ dev = [ "pytest-env~=1.1.3", "pytest-mock~=3.14.0", "testcontainers~=4.13.2", - "types-aiofiles~=24.1.0", + "types-aiofiles~=25.1.0", "types-beautifulsoup4~=4.12.0", "types-cachetools~=5.5.0", "types-colorama~=0.4.15", diff --git a/api/repositories/sqlalchemy_api_workflow_run_repository.py b/api/repositories/sqlalchemy_api_workflow_run_repository.py index 7935dfb225..5ba7a7e7e8 100644 --- a/api/repositories/sqlalchemy_api_workflow_run_repository.py +++ b/api/repositories/sqlalchemy_api_workflow_run_repository.py @@ -29,7 +29,7 @@ from typing import Any, cast import sqlalchemy as sa from pydantic import ValidationError -from sqlalchemy import and_, delete, func, null, or_, select +from sqlalchemy import and_, delete, func, null, or_, select, tuple_ from sqlalchemy.engine import CursorResult from sqlalchemy.orm import Session, selectinload, sessionmaker @@ -423,9 +423,10 @@ class DifyAPISQLAlchemyWorkflowRunRepository(APIWorkflowRunRepository): if last_seen: stmt = stmt.where( - or_( - WorkflowRun.created_at > last_seen[0], - and_(WorkflowRun.created_at == last_seen[0], WorkflowRun.id > last_seen[1]), + tuple_(WorkflowRun.created_at, WorkflowRun.id) + > tuple_( + sa.literal(last_seen[0], type_=sa.DateTime()), + sa.literal(last_seen[1], type_=WorkflowRun.id.type), ) ) diff --git a/api/services/workflow/workflow_converter.py b/api/services/workflow/workflow_converter.py index 809151b91a..5527c108a2 100644 --- a/api/services/workflow/workflow_converter.py +++ b/api/services/workflow/workflow_converter.py @@ -8,7 +8,6 @@ from core.app.app_config.entities import ( ExternalDataVariableEntity, ModelConfigEntity, PromptTemplateEntity, - VariableEntity, ) from core.app.apps.agent_chat.app_config_manager import AgentChatAppConfigManager from core.app.apps.chat.app_config_manager import ChatAppConfigManager @@ -20,6 +19,7 @@ from core.prompt.simple_prompt_transform import SimplePromptTransform from core.prompt.utils.prompt_template_parser import PromptTemplateParser from core.workflow.file.models import FileUploadConfig from core.workflow.nodes import NodeType +from core.workflow.variables.input_entities import VariableEntity from events.app_event import app_was_created from extensions.ext_database import db from models import Account diff --git a/api/services/workflow_service.py b/api/services/workflow_service.py index 406fdae525..3b448423e8 100644 --- a/api/services/workflow_service.py +++ b/api/services/workflow_service.py @@ -9,7 +9,6 @@ from sqlalchemy import exists, select from sqlalchemy.orm import Session, sessionmaker from configs import dify_config -from core.app.app_config.entities import VariableEntityType from core.app.apps.advanced_chat.app_config_manager import AdvancedChatAppConfigManager from core.app.apps.workflow.app_config_manager import WorkflowAppConfigManager from core.app.entities.app_invoke_entities import InvokeFrom @@ -40,6 +39,7 @@ from core.workflow.runtime import GraphRuntimeState, VariablePool from core.workflow.system_variable import SystemVariable from core.workflow.variable_loader import load_into_variable_pool from core.workflow.variables import VariableBase +from core.workflow.variables.input_entities import VariableEntityType from core.workflow.variables.variables import Variable from core.workflow.workflow_entry import WorkflowEntry from enums.cloud_plan import CloudPlan diff --git a/api/tasks/document_indexing_sync_task.py b/api/tasks/document_indexing_sync_task.py index 45b44438e7..fddd9199d1 100644 --- a/api/tasks/document_indexing_sync_task.py +++ b/api/tasks/document_indexing_sync_task.py @@ -1,3 +1,4 @@ +import json import logging import time @@ -125,7 +126,7 @@ def document_indexing_sync_task(dataset_id: str, document_id: str): data_source_info = document.data_source_info_dict data_source_info["last_edited_time"] = last_edited_time - document.data_source_info = data_source_info + document.data_source_info = json.dumps(data_source_info) document.indexing_status = "parsing" document.processing_started_at = naive_utc_now() diff --git a/api/tests/integration_tests/workflow/nodes/test_parameter_extractor.py b/api/tests/integration_tests/workflow/nodes/test_parameter_extractor.py index e791f12393..773074e92d 100644 --- a/api/tests/integration_tests/workflow/nodes/test_parameter_extractor.py +++ b/api/tests/integration_tests/workflow/nodes/test_parameter_extractor.py @@ -5,7 +5,7 @@ from unittest.mock import MagicMock from core.app.entities.app_invoke_entities import InvokeFrom from core.model_manager import ModelInstance -from core.model_runtime.entities import AssistantPromptMessage +from core.model_runtime.entities import AssistantPromptMessage, UserPromptMessage from core.workflow.entities import GraphInitParams from core.workflow.enums import WorkflowNodeExecutionStatus from core.workflow.nodes.llm.protocols import CredentialsProvider, ModelFactory @@ -22,19 +22,17 @@ from tests.integration_tests.model_runtime.__mock.plugin_daemon import setup_mod def get_mocked_fetch_memory(memory_text: str): class MemoryMock: - def get_history_prompt_text( + def get_history_prompt_messages( self, - human_prefix: str = "Human", - ai_prefix: str = "Assistant", max_token_limit: int = 2000, message_limit: int | None = None, ): - return memory_text + return [UserPromptMessage(content=memory_text), AssistantPromptMessage(content="mocked answer")] return MagicMock(return_value=MemoryMock()) -def init_parameter_extractor_node(config: dict): +def init_parameter_extractor_node(config: dict, memory=None): graph_config = { "edges": [ { @@ -79,6 +77,7 @@ def init_parameter_extractor_node(config: dict): credentials_provider=MagicMock(spec=CredentialsProvider), model_factory=MagicMock(spec=ModelFactory), model_instance=MagicMock(spec=ModelInstance), + memory=memory, ) return node @@ -350,7 +349,7 @@ def test_extract_json_from_tool_call(): assert result["location"] == "kawaii" -def test_chat_parameter_extractor_with_memory(setup_model_mock, monkeypatch): +def test_chat_parameter_extractor_with_memory(setup_model_mock): """ Test chat parameter extractor with memory. """ @@ -373,6 +372,7 @@ def test_chat_parameter_extractor_with_memory(setup_model_mock, monkeypatch): "memory": {"window": {"enabled": True, "size": 50}}, }, }, + memory=get_mocked_fetch_memory("customized memory")(), ) node._model_instance = get_mocked_fetch_model_instance( @@ -381,8 +381,6 @@ def test_chat_parameter_extractor_with_memory(setup_model_mock, monkeypatch): mode="chat", credentials={"openai_api_key": os.environ.get("OPENAI_API_KEY")}, )() - # Test the mock before running the actual test - monkeypatch.setattr("core.workflow.nodes.llm.llm_utils.fetch_memory", get_mocked_fetch_memory("customized memory")) db.session.close = MagicMock() result = node._run() diff --git a/api/tests/test_containers_integration_tests/services/workflow/test_workflow_converter.py b/api/tests/test_containers_integration_tests/services/workflow/test_workflow_converter.py index 2c5e719a58..2ffb884b82 100644 --- a/api/tests/test_containers_integration_tests/services/workflow/test_workflow_converter.py +++ b/api/tests/test_containers_integration_tests/services/workflow/test_workflow_converter.py @@ -10,11 +10,10 @@ from core.app.app_config.entities import ( ExternalDataVariableEntity, ModelConfigEntity, PromptTemplateEntity, - VariableEntity, - VariableEntityType, ) from core.model_runtime.entities.llm_entities import LLMMode from core.prompt.utils.prompt_template_parser import PromptTemplateParser +from core.workflow.variables.input_entities import VariableEntity, VariableEntityType from models import Account, Tenant from models.api_based_extension import APIBasedExtension from models.model import App, AppMode, AppModelConfig diff --git a/api/tests/test_containers_integration_tests/tasks/test_disable_segments_from_index_task.py b/api/tests/test_containers_integration_tests/tasks/test_disable_segments_from_index_task.py index 56b53a24b5..a93a80e231 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_disable_segments_from_index_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_disable_segments_from_index_task.py @@ -147,8 +147,7 @@ class TestDisableSegmentsFromIndexTask: document.cleaning_completed_at = fake.date_time_this_year() document.splitting_completed_at = fake.date_time_this_year() document.tokens = fake.random_int(min=50, max=500) - document.indexing_started_at = fake.date_time_this_year() - document.indexing_completed_at = fake.date_time_this_year() + document.completed_at = fake.date_time_this_year() document.indexing_status = "completed" document.enabled = True document.archived = False diff --git a/api/tests/test_containers_integration_tests/tasks/test_document_indexing_sync_task.py b/api/tests/test_containers_integration_tests/tasks/test_document_indexing_sync_task.py index 0b9e29fde9..df5c5dc54b 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_document_indexing_sync_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_document_indexing_sync_task.py @@ -12,8 +12,6 @@ from unittest.mock import Mock, patch from uuid import uuid4 import pytest -from psycopg2.extensions import register_adapter -from psycopg2.extras import Json from core.indexing_runner import DocumentIsPausedError, IndexingRunner from models import Account, Tenant, TenantAccountJoin, TenantAccountRole @@ -21,12 +19,6 @@ from models.dataset import Dataset, Document, DocumentSegment from tasks.document_indexing_sync_task import document_indexing_sync_task -@pytest.fixture(autouse=True) -def _register_dict_adapter_for_psycopg2(): - """Align test DB adapter behavior with dict payloads used in task update flow.""" - register_adapter(dict, Json) - - class DocumentIndexingSyncTaskTestDataFactory: """Create real DB entities for document indexing sync integration tests.""" diff --git a/api/tests/unit_tests/core/app/apps/test_base_app_generator.py b/api/tests/unit_tests/core/app/apps/test_base_app_generator.py index 1000d71399..04c8696525 100644 --- a/api/tests/unit_tests/core/app/apps/test_base_app_generator.py +++ b/api/tests/unit_tests/core/app/apps/test_base_app_generator.py @@ -1,7 +1,7 @@ import pytest -from core.app.app_config.entities import VariableEntity, VariableEntityType from core.app.apps.base_app_generator import BaseAppGenerator +from core.workflow.variables.input_entities import VariableEntity, VariableEntityType def test_validate_inputs_with_zero(): diff --git a/api/tests/unit_tests/core/mcp/server/test_streamable_http.py b/api/tests/unit_tests/core/mcp/server/test_streamable_http.py index fe9f0935d5..40a7700394 100644 --- a/api/tests/unit_tests/core/mcp/server/test_streamable_http.py +++ b/api/tests/unit_tests/core/mcp/server/test_streamable_http.py @@ -4,7 +4,6 @@ from unittest.mock import Mock, patch import jsonschema import pytest -from core.app.app_config.entities import VariableEntity, VariableEntityType from core.app.features.rate_limiting.rate_limit import RateLimitGenerator from core.mcp import types from core.mcp.server.streamable_http import ( @@ -19,6 +18,7 @@ from core.mcp.server.streamable_http import ( prepare_tool_arguments, process_mapping_response, ) +from core.workflow.variables.input_entities import VariableEntity, VariableEntityType from models.model import App, AppMCPServer, AppMode, EndUser diff --git a/api/tests/unit_tests/core/workflow/graph_engine/layers/test_llm_quota.py b/api/tests/unit_tests/core/workflow/graph_engine/layers/test_llm_quota.py new file mode 100644 index 0000000000..9a491d24e1 --- /dev/null +++ b/api/tests/unit_tests/core/workflow/graph_engine/layers/test_llm_quota.py @@ -0,0 +1,174 @@ +import threading +from datetime import datetime +from unittest.mock import MagicMock, patch + +from core.app.workflow.layers.llm_quota import LLMQuotaLayer +from core.errors.error import QuotaExceededError +from core.model_runtime.entities.llm_entities import LLMUsage +from core.workflow.enums import NodeType, WorkflowNodeExecutionStatus +from core.workflow.graph_engine.entities.commands import CommandType +from core.workflow.graph_events.node import NodeRunSucceededEvent +from core.workflow.node_events import NodeRunResult + + +def _build_succeeded_event() -> NodeRunSucceededEvent: + return NodeRunSucceededEvent( + id="execution-id", + node_id="llm-node-id", + node_type=NodeType.LLM, + start_at=datetime.now(), + node_run_result=NodeRunResult( + status=WorkflowNodeExecutionStatus.SUCCEEDED, + inputs={"question": "hello"}, + llm_usage=LLMUsage.empty_usage(), + ), + ) + + +def test_deduct_quota_called_for_successful_llm_node() -> None: + layer = LLMQuotaLayer() + node = MagicMock() + node.id = "llm-node-id" + node.execution_id = "execution-id" + node.node_type = NodeType.LLM + node.tenant_id = "tenant-id" + node.model_instance = object() + + result_event = _build_succeeded_event() + with patch("core.app.workflow.layers.llm_quota.deduct_llm_quota", autospec=True) as mock_deduct: + layer.on_node_run_end(node=node, error=None, result_event=result_event) + + mock_deduct.assert_called_once_with( + tenant_id="tenant-id", + model_instance=node.model_instance, + usage=result_event.node_run_result.llm_usage, + ) + + +def test_deduct_quota_called_for_question_classifier_node() -> None: + layer = LLMQuotaLayer() + node = MagicMock() + node.id = "question-classifier-node-id" + node.execution_id = "execution-id" + node.node_type = NodeType.QUESTION_CLASSIFIER + node.tenant_id = "tenant-id" + node.model_instance = object() + + result_event = _build_succeeded_event() + with patch("core.app.workflow.layers.llm_quota.deduct_llm_quota", autospec=True) as mock_deduct: + layer.on_node_run_end(node=node, error=None, result_event=result_event) + + mock_deduct.assert_called_once_with( + tenant_id="tenant-id", + model_instance=node.model_instance, + usage=result_event.node_run_result.llm_usage, + ) + + +def test_non_llm_node_is_ignored() -> None: + layer = LLMQuotaLayer() + node = MagicMock() + node.id = "start-node-id" + node.execution_id = "execution-id" + node.node_type = NodeType.START + node.tenant_id = "tenant-id" + node._model_instance = object() + + result_event = _build_succeeded_event() + with patch("core.app.workflow.layers.llm_quota.deduct_llm_quota", autospec=True) as mock_deduct: + layer.on_node_run_end(node=node, error=None, result_event=result_event) + + mock_deduct.assert_not_called() + + +def test_quota_error_is_handled_in_layer() -> None: + layer = LLMQuotaLayer() + node = MagicMock() + node.id = "llm-node-id" + node.execution_id = "execution-id" + node.node_type = NodeType.LLM + node.tenant_id = "tenant-id" + node.model_instance = object() + + result_event = _build_succeeded_event() + with patch( + "core.app.workflow.layers.llm_quota.deduct_llm_quota", + autospec=True, + side_effect=ValueError("quota exceeded"), + ): + layer.on_node_run_end(node=node, error=None, result_event=result_event) + + +def test_quota_deduction_exceeded_aborts_workflow_immediately() -> None: + layer = LLMQuotaLayer() + stop_event = threading.Event() + layer.command_channel = MagicMock() + + node = MagicMock() + node.id = "llm-node-id" + node.execution_id = "execution-id" + node.node_type = NodeType.LLM + node.tenant_id = "tenant-id" + node.model_instance = object() + node.graph_runtime_state = MagicMock() + node.graph_runtime_state.stop_event = stop_event + + result_event = _build_succeeded_event() + with patch( + "core.app.workflow.layers.llm_quota.deduct_llm_quota", + autospec=True, + side_effect=QuotaExceededError("No credits remaining"), + ): + layer.on_node_run_end(node=node, error=None, result_event=result_event) + + assert stop_event.is_set() + layer.command_channel.send_command.assert_called_once() + abort_command = layer.command_channel.send_command.call_args.args[0] + assert abort_command.command_type == CommandType.ABORT + assert abort_command.reason == "No credits remaining" + + +def test_quota_precheck_failure_aborts_workflow_immediately() -> None: + layer = LLMQuotaLayer() + stop_event = threading.Event() + layer.command_channel = MagicMock() + + node = MagicMock() + node.id = "llm-node-id" + node.node_type = NodeType.LLM + node.model_instance = object() + node.graph_runtime_state = MagicMock() + node.graph_runtime_state.stop_event = stop_event + + with patch( + "core.app.workflow.layers.llm_quota.ensure_llm_quota_available", + autospec=True, + side_effect=QuotaExceededError("Model provider openai quota exceeded."), + ): + layer.on_node_run_start(node) + + assert stop_event.is_set() + layer.command_channel.send_command.assert_called_once() + abort_command = layer.command_channel.send_command.call_args.args[0] + assert abort_command.command_type == CommandType.ABORT + assert abort_command.reason == "Model provider openai quota exceeded." + + +def test_quota_precheck_passes_without_abort() -> None: + layer = LLMQuotaLayer() + stop_event = threading.Event() + layer.command_channel = MagicMock() + + node = MagicMock() + node.id = "llm-node-id" + node.node_type = NodeType.LLM + node.model_instance = object() + node.graph_runtime_state = MagicMock() + node.graph_runtime_state.stop_event = stop_event + + with patch("core.app.workflow.layers.llm_quota.ensure_llm_quota_available", autospec=True) as mock_check: + layer.on_node_run_start(node) + + assert not stop_event.is_set() + mock_check.assert_called_once_with(model_instance=node.model_instance) + layer.command_channel.send_command.assert_not_called() diff --git a/api/tests/unit_tests/core/workflow/graph_engine/orchestration/test_dispatcher.py b/api/tests/unit_tests/core/workflow/graph_engine/orchestration/test_dispatcher.py index fe3ea576c1..c1fc4acd73 100644 --- a/api/tests/unit_tests/core/workflow/graph_engine/orchestration/test_dispatcher.py +++ b/api/tests/unit_tests/core/workflow/graph_engine/orchestration/test_dispatcher.py @@ -3,7 +3,6 @@ from __future__ import annotations import queue -import threading from unittest import mock from core.workflow.entities.pause_reason import SchedulingPause @@ -37,7 +36,6 @@ def test_dispatcher_should_consume_remains_events_after_pause(): event_queue=event_queue, event_handler=event_handler, execution_coordinator=execution_coordinator, - stop_event=threading.Event(), ) dispatcher._dispatcher_loop() assert event_queue.empty() @@ -98,7 +96,6 @@ def _run_dispatcher_for_event(event) -> int: event_queue=event_queue, event_handler=event_handler, execution_coordinator=coordinator, - stop_event=threading.Event(), ) dispatcher._dispatcher_loop() @@ -184,7 +181,6 @@ def test_dispatcher_drain_event_queue(): event_queue=event_queue, event_handler=event_handler, execution_coordinator=coordinator, - stop_event=threading.Event(), ) dispatcher._dispatcher_loop() diff --git a/api/tests/unit_tests/core/workflow/graph_engine/test_dispatcher_pause_drain.py b/api/tests/unit_tests/core/workflow/graph_engine/test_dispatcher_pause_drain.py index 6038a15211..bf8034487c 100644 --- a/api/tests/unit_tests/core/workflow/graph_engine/test_dispatcher_pause_drain.py +++ b/api/tests/unit_tests/core/workflow/graph_engine/test_dispatcher_pause_drain.py @@ -1,5 +1,4 @@ import queue -import threading from datetime import datetime from core.workflow.enums import NodeType, WorkflowNodeExecutionStatus @@ -65,7 +64,6 @@ def test_dispatcher_drains_events_when_paused() -> None: event_handler=handler, execution_coordinator=coordinator, event_emitter=None, - stop_event=threading.Event(), ) dispatcher._dispatcher_loop() diff --git a/api/tests/unit_tests/core/workflow/graph_engine/test_stop_event.py b/api/tests/unit_tests/core/workflow/graph_engine/test_stop_event.py deleted file mode 100644 index 6d2ce4cb71..0000000000 --- a/api/tests/unit_tests/core/workflow/graph_engine/test_stop_event.py +++ /dev/null @@ -1,550 +0,0 @@ -""" -Unit tests for stop_event functionality in GraphEngine. - -Tests the unified stop_event management by GraphEngine and its propagation -to WorkerPool, Worker, Dispatcher, and Nodes. -""" - -import threading -import time -from unittest.mock import MagicMock, Mock, patch - -from core.app.entities.app_invoke_entities import InvokeFrom -from core.workflow.entities.graph_init_params import GraphInitParams -from core.workflow.graph import Graph -from core.workflow.graph_engine import GraphEngine, GraphEngineConfig -from core.workflow.graph_engine.command_channels import InMemoryChannel -from core.workflow.graph_events import ( - GraphRunStartedEvent, - GraphRunSucceededEvent, - NodeRunStartedEvent, -) -from core.workflow.nodes.answer.answer_node import AnswerNode -from core.workflow.nodes.start.start_node import StartNode -from core.workflow.runtime import GraphRuntimeState, VariablePool -from models.enums import UserFrom - - -class TestStopEventPropagation: - """Test suite for stop_event propagation through GraphEngine components.""" - - def test_graph_engine_creates_stop_event(self): - """Test that GraphEngine creates a stop_event on initialization.""" - runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=time.perf_counter()) - mock_graph = MagicMock(spec=Graph) - mock_graph.nodes = {} - mock_graph.edges = {} - mock_graph.root_node = MagicMock() - - engine = GraphEngine( - workflow_id="test_workflow", - graph=mock_graph, - graph_runtime_state=runtime_state, - command_channel=InMemoryChannel(), - config=GraphEngineConfig(), - ) - - # Verify stop_event was created - assert engine._stop_event is not None - assert isinstance(engine._stop_event, threading.Event) - - # Verify it was set in graph_runtime_state - assert runtime_state.stop_event is not None - assert runtime_state.stop_event is engine._stop_event - - def test_stop_event_cleared_on_start(self): - """Test that stop_event is cleared when execution starts.""" - runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=time.perf_counter()) - mock_graph = MagicMock(spec=Graph) - mock_graph.nodes = {} - mock_graph.edges = {} - mock_graph.root_node = MagicMock() - mock_graph.root_node.id = "start" # Set proper id - - start_node = StartNode( - id="start", - config={"id": "start", "data": {"title": "start", "variables": []}}, - graph_init_params=GraphInitParams( - tenant_id="test_tenant", - app_id="test_app", - workflow_id="test_workflow", - graph_config={}, - user_id="test_user", - user_from=UserFrom.ACCOUNT, - invoke_from=InvokeFrom.DEBUGGER, - call_depth=0, - ), - graph_runtime_state=runtime_state, - ) - mock_graph.nodes["start"] = start_node - mock_graph.get_outgoing_edges = MagicMock(return_value=[]) - mock_graph.get_incoming_edges = MagicMock(return_value=[]) - - engine = GraphEngine( - workflow_id="test_workflow", - graph=mock_graph, - graph_runtime_state=runtime_state, - command_channel=InMemoryChannel(), - config=GraphEngineConfig(), - ) - - # Set the stop_event before running - engine._stop_event.set() - assert engine._stop_event.is_set() - - # Run the engine (should clear the stop_event) - events = list(engine.run()) - - # After running, stop_event should be set again (by _stop_execution) - # But during start it was cleared - assert any(isinstance(e, GraphRunStartedEvent) for e in events) - assert any(isinstance(e, GraphRunSucceededEvent) for e in events) - - def test_stop_event_set_on_stop(self): - """Test that stop_event is set when execution stops.""" - runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=time.perf_counter()) - mock_graph = MagicMock(spec=Graph) - mock_graph.nodes = {} - mock_graph.edges = {} - mock_graph.root_node = MagicMock() - mock_graph.root_node.id = "start" # Set proper id - - start_node = StartNode( - id="start", - config={"id": "start", "data": {"title": "start", "variables": []}}, - graph_init_params=GraphInitParams( - tenant_id="test_tenant", - app_id="test_app", - workflow_id="test_workflow", - graph_config={}, - user_id="test_user", - user_from=UserFrom.ACCOUNT, - invoke_from=InvokeFrom.DEBUGGER, - call_depth=0, - ), - graph_runtime_state=runtime_state, - ) - mock_graph.nodes["start"] = start_node - mock_graph.get_outgoing_edges = MagicMock(return_value=[]) - mock_graph.get_incoming_edges = MagicMock(return_value=[]) - - engine = GraphEngine( - workflow_id="test_workflow", - graph=mock_graph, - graph_runtime_state=runtime_state, - command_channel=InMemoryChannel(), - config=GraphEngineConfig(), - ) - - # Initially not set - assert not engine._stop_event.is_set() - - # Run the engine - list(engine.run()) - - # After execution completes, stop_event should be set - assert engine._stop_event.is_set() - - def test_stop_event_passed_to_worker_pool(self): - """Test that stop_event is passed to WorkerPool.""" - runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=time.perf_counter()) - mock_graph = MagicMock(spec=Graph) - mock_graph.nodes = {} - mock_graph.edges = {} - mock_graph.root_node = MagicMock() - - engine = GraphEngine( - workflow_id="test_workflow", - graph=mock_graph, - graph_runtime_state=runtime_state, - command_channel=InMemoryChannel(), - config=GraphEngineConfig(), - ) - - # Verify WorkerPool has the stop_event - assert engine._worker_pool._stop_event is not None - assert engine._worker_pool._stop_event is engine._stop_event - - def test_stop_event_passed_to_dispatcher(self): - """Test that stop_event is passed to Dispatcher.""" - runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=time.perf_counter()) - mock_graph = MagicMock(spec=Graph) - mock_graph.nodes = {} - mock_graph.edges = {} - mock_graph.root_node = MagicMock() - - engine = GraphEngine( - workflow_id="test_workflow", - graph=mock_graph, - graph_runtime_state=runtime_state, - command_channel=InMemoryChannel(), - config=GraphEngineConfig(), - ) - - # Verify Dispatcher has the stop_event - assert engine._dispatcher._stop_event is not None - assert engine._dispatcher._stop_event is engine._stop_event - - -class TestNodeStopCheck: - """Test suite for Node._should_stop() functionality.""" - - def test_node_should_stop_checks_runtime_state(self): - """Test that Node._should_stop() checks GraphRuntimeState.stop_event.""" - runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=time.perf_counter()) - - answer_node = AnswerNode( - id="answer", - config={"id": "answer", "data": {"title": "answer", "answer": "{{#start.result#}}"}}, - graph_init_params=GraphInitParams( - tenant_id="test_tenant", - app_id="test_app", - workflow_id="test_workflow", - graph_config={}, - user_id="test_user", - user_from=UserFrom.ACCOUNT, - invoke_from=InvokeFrom.DEBUGGER, - call_depth=0, - ), - graph_runtime_state=runtime_state, - ) - - # Initially stop_event is not set - assert not answer_node._should_stop() - - # Set the stop_event - runtime_state.stop_event.set() - - # Now _should_stop should return True - assert answer_node._should_stop() - - def test_node_run_checks_stop_event_between_yields(self): - """Test that Node.run() checks stop_event between yielding events.""" - runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=time.perf_counter()) - - # Create a simple node - answer_node = AnswerNode( - id="answer", - config={"id": "answer", "data": {"title": "answer", "answer": "hello"}}, - graph_init_params=GraphInitParams( - tenant_id="test_tenant", - app_id="test_app", - workflow_id="test_workflow", - graph_config={}, - user_id="test_user", - user_from=UserFrom.ACCOUNT, - invoke_from=InvokeFrom.DEBUGGER, - call_depth=0, - ), - graph_runtime_state=runtime_state, - ) - - # Set stop_event BEFORE running the node - runtime_state.stop_event.set() - - # Run the node - should yield start event then detect stop - # The node should check stop_event before processing - assert answer_node._should_stop(), "stop_event should be set" - - # Run and collect events - events = list(answer_node.run()) - - # Since stop_event is set at the start, we should get: - # 1. NodeRunStartedEvent (always yielded first) - # 2. Either NodeRunFailedEvent (if detected early) or NodeRunSucceededEvent (if too fast) - assert len(events) >= 2 - assert isinstance(events[0], NodeRunStartedEvent) - - # Note: AnswerNode is very simple and might complete before stop check - # The important thing is that _should_stop() returns True when stop_event is set - assert answer_node._should_stop() - - -class TestStopEventIntegration: - """Integration tests for stop_event in workflow execution.""" - - def test_simple_workflow_respects_stop_event(self): - """Test that a simple workflow respects stop_event.""" - runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=time.perf_counter()) - - mock_graph = MagicMock(spec=Graph) - mock_graph.nodes = {} - mock_graph.edges = {} - mock_graph.root_node = MagicMock() - mock_graph.root_node.id = "start" - - # Create start and answer nodes - start_node = StartNode( - id="start", - config={"id": "start", "data": {"title": "start", "variables": []}}, - graph_init_params=GraphInitParams( - tenant_id="test_tenant", - app_id="test_app", - workflow_id="test_workflow", - graph_config={}, - user_id="test_user", - user_from=UserFrom.ACCOUNT, - invoke_from=InvokeFrom.DEBUGGER, - call_depth=0, - ), - graph_runtime_state=runtime_state, - ) - - answer_node = AnswerNode( - id="answer", - config={"id": "answer", "data": {"title": "answer", "answer": "hello"}}, - graph_init_params=GraphInitParams( - tenant_id="test_tenant", - app_id="test_app", - workflow_id="test_workflow", - graph_config={}, - user_id="test_user", - user_from=UserFrom.ACCOUNT, - invoke_from=InvokeFrom.DEBUGGER, - call_depth=0, - ), - graph_runtime_state=runtime_state, - ) - - mock_graph.nodes["start"] = start_node - mock_graph.nodes["answer"] = answer_node - mock_graph.get_outgoing_edges = MagicMock(return_value=[]) - mock_graph.get_incoming_edges = MagicMock(return_value=[]) - - engine = GraphEngine( - workflow_id="test_workflow", - graph=mock_graph, - graph_runtime_state=runtime_state, - command_channel=InMemoryChannel(), - config=GraphEngineConfig(), - ) - - # Set stop_event before running - runtime_state.stop_event.set() - - # Run the engine - events = list(engine.run()) - - # Should get started event but not succeeded (due to stop) - assert any(isinstance(e, GraphRunStartedEvent) for e in events) - # The workflow should still complete (start node runs quickly) - # but answer node might be cancelled depending on timing - - def test_stop_event_with_concurrent_nodes(self): - """Test stop_event behavior with multiple concurrent nodes.""" - runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=time.perf_counter()) - - mock_graph = MagicMock(spec=Graph) - mock_graph.nodes = {} - mock_graph.edges = {} - mock_graph.root_node = MagicMock() - - # Create multiple nodes - for i in range(3): - answer_node = AnswerNode( - id=f"answer_{i}", - config={"id": f"answer_{i}", "data": {"title": f"answer_{i}", "answer": f"test{i}"}}, - graph_init_params=GraphInitParams( - tenant_id="test_tenant", - app_id="test_app", - workflow_id="test_workflow", - graph_config={}, - user_id="test_user", - user_from=UserFrom.ACCOUNT, - invoke_from=InvokeFrom.DEBUGGER, - call_depth=0, - ), - graph_runtime_state=runtime_state, - ) - mock_graph.nodes[f"answer_{i}"] = answer_node - - mock_graph.get_outgoing_edges = MagicMock(return_value=[]) - mock_graph.get_incoming_edges = MagicMock(return_value=[]) - - engine = GraphEngine( - workflow_id="test_workflow", - graph=mock_graph, - graph_runtime_state=runtime_state, - command_channel=InMemoryChannel(), - config=GraphEngineConfig(), - ) - - # All nodes should share the same stop_event - for node in mock_graph.nodes.values(): - assert node.graph_runtime_state.stop_event is runtime_state.stop_event - assert node.graph_runtime_state.stop_event is engine._stop_event - - -class TestStopEventTimeoutBehavior: - """Test stop_event behavior with join timeouts.""" - - @patch("core.workflow.graph_engine.orchestration.dispatcher.threading.Thread", autospec=True) - def test_dispatcher_uses_shorter_timeout(self, mock_thread_cls: MagicMock): - """Test that Dispatcher uses 2s timeout instead of 10s.""" - runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=time.perf_counter()) - mock_graph = MagicMock(spec=Graph) - mock_graph.nodes = {} - mock_graph.edges = {} - mock_graph.root_node = MagicMock() - - engine = GraphEngine( - workflow_id="test_workflow", - graph=mock_graph, - graph_runtime_state=runtime_state, - command_channel=InMemoryChannel(), - config=GraphEngineConfig(), - ) - - dispatcher = engine._dispatcher - dispatcher.start() # This will create and start the mocked thread - - mock_thread_instance = mock_thread_cls.return_value - mock_thread_instance.is_alive.return_value = True - - dispatcher.stop() - - mock_thread_instance.join.assert_called_once_with(timeout=2.0) - - @patch("core.workflow.graph_engine.worker_management.worker_pool.Worker", autospec=True) - def test_worker_pool_uses_shorter_timeout(self, mock_worker_cls: MagicMock): - """Test that WorkerPool uses 2s timeout instead of 10s.""" - runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=time.perf_counter()) - mock_graph = MagicMock(spec=Graph) - mock_graph.nodes = {} - mock_graph.edges = {} - mock_graph.root_node = MagicMock() - - engine = GraphEngine( - workflow_id="test_workflow", - graph=mock_graph, - graph_runtime_state=runtime_state, - command_channel=InMemoryChannel(), - config=GraphEngineConfig(), - ) - - worker_pool = engine._worker_pool - worker_pool.start(initial_count=1) # Start with one worker - - mock_worker_instance = mock_worker_cls.return_value - mock_worker_instance.is_alive.return_value = True - - worker_pool.stop() - - mock_worker_instance.join.assert_called_once_with(timeout=2.0) - - -class TestStopEventResumeBehavior: - """Test stop_event behavior during workflow resume.""" - - def test_stop_event_cleared_on_resume(self): - """Test that stop_event is cleared when resuming a paused workflow.""" - runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=time.perf_counter()) - mock_graph = MagicMock(spec=Graph) - mock_graph.nodes = {} - mock_graph.edges = {} - mock_graph.root_node = MagicMock() - mock_graph.root_node.id = "start" # Set proper id - - start_node = StartNode( - id="start", - config={"id": "start", "data": {"title": "start", "variables": []}}, - graph_init_params=GraphInitParams( - tenant_id="test_tenant", - app_id="test_app", - workflow_id="test_workflow", - graph_config={}, - user_id="test_user", - user_from=UserFrom.ACCOUNT, - invoke_from=InvokeFrom.DEBUGGER, - call_depth=0, - ), - graph_runtime_state=runtime_state, - ) - mock_graph.nodes["start"] = start_node - mock_graph.get_outgoing_edges = MagicMock(return_value=[]) - mock_graph.get_incoming_edges = MagicMock(return_value=[]) - - engine = GraphEngine( - workflow_id="test_workflow", - graph=mock_graph, - graph_runtime_state=runtime_state, - command_channel=InMemoryChannel(), - config=GraphEngineConfig(), - ) - - # Simulate a previous execution that set stop_event - engine._stop_event.set() - assert engine._stop_event.is_set() - - # Run the engine (should clear stop_event in _start_execution) - events = list(engine.run()) - - # Execution should complete successfully - assert any(isinstance(e, GraphRunStartedEvent) for e in events) - assert any(isinstance(e, GraphRunSucceededEvent) for e in events) - - -class TestWorkerStopBehavior: - """Test Worker behavior with shared stop_event.""" - - def test_worker_uses_shared_stop_event(self): - """Test that Worker uses shared stop_event from GraphEngine.""" - runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=time.perf_counter()) - mock_graph = MagicMock(spec=Graph) - mock_graph.nodes = {} - mock_graph.edges = {} - mock_graph.root_node = MagicMock() - - engine = GraphEngine( - workflow_id="test_workflow", - graph=mock_graph, - graph_runtime_state=runtime_state, - command_channel=InMemoryChannel(), - config=GraphEngineConfig(), - ) - - # Get the worker pool and check workers - worker_pool = engine._worker_pool - - # Start the worker pool to create workers - worker_pool.start() - - # Check that at least one worker was created - assert len(worker_pool._workers) > 0 - - # Verify workers use the shared stop_event - for worker in worker_pool._workers: - assert worker._stop_event is engine._stop_event - - # Clean up - worker_pool.stop() - - def test_worker_stop_is_noop(self): - """Test that Worker.stop() is now a no-op.""" - runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=time.perf_counter()) - - # Create a mock worker - from core.workflow.graph_engine.ready_queue import InMemoryReadyQueue - from core.workflow.graph_engine.worker import Worker - - ready_queue = InMemoryReadyQueue() - event_queue = MagicMock() - - # Create a proper mock graph with real dict - mock_graph = Mock(spec=Graph) - mock_graph.nodes = {} # Use real dict - - stop_event = threading.Event() - - worker = Worker( - ready_queue=ready_queue, - event_queue=event_queue, - graph=mock_graph, - layers=[], - stop_event=stop_event, - ) - - # Calling stop() should do nothing (no-op) - # and should NOT set the stop_event - worker.stop() - assert not stop_event.is_set() diff --git a/api/tests/unit_tests/core/workflow/nodes/test_start_node_json_object.py b/api/tests/unit_tests/core/workflow/nodes/test_start_node_json_object.py index 16b432bae6..8c7dc24868 100644 --- a/api/tests/unit_tests/core/workflow/nodes/test_start_node_json_object.py +++ b/api/tests/unit_tests/core/workflow/nodes/test_start_node_json_object.py @@ -4,12 +4,12 @@ import time import pytest from pydantic import ValidationError as PydanticValidationError -from core.app.app_config.entities import VariableEntity, VariableEntityType from core.workflow.entities import GraphInitParams from core.workflow.nodes.start.entities import StartNodeData from core.workflow.nodes.start.start_node import StartNode from core.workflow.runtime import GraphRuntimeState, VariablePool from core.workflow.system_variable import SystemVariable +from core.workflow.variables.input_entities import VariableEntity, VariableEntityType def make_start_node(user_inputs, variables): diff --git a/api/tests/unit_tests/libs/test_pyrefly_diagnostics.py b/api/tests/unit_tests/libs/test_pyrefly_diagnostics.py new file mode 100644 index 0000000000..704daa8fb4 --- /dev/null +++ b/api/tests/unit_tests/libs/test_pyrefly_diagnostics.py @@ -0,0 +1,51 @@ +from libs.pyrefly_diagnostics import extract_diagnostics + + +def test_extract_diagnostics_keeps_only_summary_and_location_lines() -> None: + # Arrange + raw_output = """INFO Checking project configured at `/tmp/project/pyrefly.toml` +ERROR `result` may be uninitialized [unbound-name] + --> controllers/console/app/annotation.py:126:16 + | +126 | return result, 200 + | ^^^^^^ + | +ERROR Object of class `App` has no attribute `access_mode` [missing-attribute] + --> controllers/console/app/app.py:574:13 + | +574 | app_model.access_mode = app_setting.access_mode + | ^^^^^^^^^^^^^^^^^^^^^ +""" + + # Act + diagnostics = extract_diagnostics(raw_output) + + # Assert + assert diagnostics == ( + "ERROR `result` may be uninitialized [unbound-name]\n" + " --> controllers/console/app/annotation.py:126:16\n" + "ERROR Object of class `App` has no attribute `access_mode` [missing-attribute]\n" + " --> controllers/console/app/app.py:574:13\n" + ) + + +def test_extract_diagnostics_handles_error_without_location_line() -> None: + # Arrange + raw_output = "ERROR unexpected pyrefly output format [bad-format]\n" + + # Act + diagnostics = extract_diagnostics(raw_output) + + # Assert + assert diagnostics == "ERROR unexpected pyrefly output format [bad-format]\n" + + +def test_extract_diagnostics_returns_empty_for_non_error_output() -> None: + # Arrange + raw_output = "INFO Checking project configured at `/tmp/project/pyrefly.toml`\n" + + # Act + diagnostics = extract_diagnostics(raw_output) + + # Assert + assert diagnostics == "" diff --git a/api/tests/unit_tests/services/workflow/test_workflow_converter.py b/api/tests/unit_tests/services/workflow/test_workflow_converter.py index 267c0a85a7..8ccbfbb16e 100644 --- a/api/tests/unit_tests/services/workflow/test_workflow_converter.py +++ b/api/tests/unit_tests/services/workflow/test_workflow_converter.py @@ -13,12 +13,11 @@ from core.app.app_config.entities import ( ExternalDataVariableEntity, ModelConfigEntity, PromptTemplateEntity, - VariableEntity, - VariableEntityType, ) from core.helper import encrypter from core.model_runtime.entities.llm_entities import LLMMode from core.model_runtime.entities.message_entities import PromptMessageRole +from core.workflow.variables.input_entities import VariableEntity, VariableEntityType from models.api_based_extension import APIBasedExtension, APIBasedExtensionPoint from models.model import AppMode from services.workflow.workflow_converter import WorkflowConverter diff --git a/api/tests/unit_tests/tasks/test_document_indexing_sync_task.py b/api/tests/unit_tests/tasks/test_document_indexing_sync_task.py index a68aad7606..3668416e36 100644 --- a/api/tests/unit_tests/tasks/test_document_indexing_sync_task.py +++ b/api/tests/unit_tests/tasks/test_document_indexing_sync_task.py @@ -5,6 +5,7 @@ These tests intentionally stay in unit scope because they validate call argument for external collaborators rather than SQL-backed state transitions. """ +import json import uuid from unittest.mock import MagicMock, Mock, patch @@ -196,3 +197,78 @@ class TestDocumentIndexingSyncTaskCollaboratorParams: provider="notion_datasource", plugin_id="langgenius/notion_datasource", ) + + +class TestDataSourceInfoSerialization: + """Regression test: data_source_info must be written as a JSON string, not a raw dict. + + See https://github.com/langgenius/dify/issues/32705 + psycopg2 raises ``ProgrammingError: can't adapt type 'dict'`` when a Python + dict is passed directly to a text/LongText column. + """ + + def test_data_source_info_serialized_as_json_string( + self, + mock_document, + mock_dataset, + dataset_id, + document_id, + ): + """data_source_info must be serialized with json.dumps before DB write.""" + with ( + patch("tasks.document_indexing_sync_task.session_factory") as mock_session_factory, + patch("tasks.document_indexing_sync_task.DatasourceProviderService") as mock_service_class, + patch("tasks.document_indexing_sync_task.NotionExtractor") as mock_extractor_class, + patch("tasks.document_indexing_sync_task.IndexProcessorFactory") as mock_ipf, + patch("tasks.document_indexing_sync_task.IndexingRunner") as mock_runner_class, + ): + # External collaborators + mock_service = MagicMock() + mock_service.get_datasource_credentials.return_value = {"integration_secret": "token"} + mock_service_class.return_value = mock_service + + mock_extractor = MagicMock() + # Return a *different* timestamp so the task enters the sync/update branch + mock_extractor.get_notion_last_edited_time.return_value = "2024-02-01T00:00:00Z" + mock_extractor_class.return_value = mock_extractor + + mock_ip = MagicMock() + mock_ipf.return_value.init_index_processor.return_value = mock_ip + + mock_runner = MagicMock() + mock_runner_class.return_value = mock_runner + + # DB session mock β€” shared across all ``session_factory.create_session()`` calls + session = MagicMock() + session.scalars.return_value.all.return_value = [] + # .where() path: session 1 reads document + dataset, session 2 reads dataset + session.query.return_value.where.return_value.first.side_effect = [ + mock_document, + mock_dataset, + mock_dataset, + ] + # .filter_by() path: session 3 (update), session 4 (indexing) + session.query.return_value.filter_by.return_value.first.side_effect = [ + mock_document, + mock_document, + ] + + begin_cm = MagicMock() + begin_cm.__enter__.return_value = session + begin_cm.__exit__.return_value = False + session.begin.return_value = begin_cm + + session_cm = MagicMock() + session_cm.__enter__.return_value = session + session_cm.__exit__.return_value = False + mock_session_factory.create_session.return_value = session_cm + + # Act + document_indexing_sync_task(dataset_id, document_id) + + # Assert: data_source_info must be a JSON *string*, not a dict + assert isinstance(mock_document.data_source_info, str), ( + f"data_source_info should be a JSON string, got {type(mock_document.data_source_info).__name__}" + ) + parsed = json.loads(mock_document.data_source_info) + assert parsed["last_edited_time"] == "2024-02-01T00:00:00Z" diff --git a/api/ty.toml b/api/ty.toml deleted file mode 100644 index ace2b7c0e8..0000000000 --- a/api/ty.toml +++ /dev/null @@ -1,50 +0,0 @@ -[src] -exclude = [ - # deps groups (A1/A2/B/C/D/E) - # B: app runner + prompt - "core/prompt", - "core/app/apps/base_app_runner.py", - "core/app/apps/workflow_app_runner.py", - "core/agent", - "core/plugin", - # C: services/controllers/fields/libs - "services", - "controllers/inner_api", - "controllers/console/app", - "controllers/console/explore", - "controllers/console/datasets", - "controllers/console/workspace", - "controllers/service_api/wraps.py", - "fields/conversation_fields.py", - "libs/external_api.py", - # D: observability + integrations - "core/ops", - "extensions", - # E: vector DB integrations - "core/rag/datasource/vdb", - # non-producition or generated code - "migrations", - "tests", - # targeted ignores for current type-check errors - # TODO(QuantumGhost): suppress type errors in HITL related code. - # fix the type error later - "configs/middleware/cache/redis_pubsub_config.py", - "extensions/ext_redis.py", - "models/execution_extra_content.py", - "tasks/workflow_execution_tasks.py", - "core/workflow/nodes/base/node.py", - "services/human_input_delivery_test_service.py", - "core/app/apps/advanced_chat/app_generator.py", - "controllers/console/human_input_form.py", - "controllers/console/app/workflow_run.py", - "repositories/sqlalchemy_api_workflow_node_execution_repository.py", - "extensions/logstore/repositories/logstore_api_workflow_run_repository.py", - "controllers/web/workflow_events.py", - "tasks/app_generate/workflow_execute_task.py", -] - - -[rules] -deprecated = "ignore" -unused-ignore-comment = "ignore" -# possibly-missing-attribute = "ignore" diff --git a/api/uv.lock b/api/uv.lock index 79886ca9a7..b9f660ce71 100644 --- a/api/uv.lock +++ b/api/uv.lock @@ -1483,7 +1483,6 @@ dev = [ { name = "scipy-stubs" }, { name = "sseclient-py" }, { name = "testcontainers" }, - { name = "ty" }, { name = "types-aiofiles" }, { name = "types-beautifulsoup4" }, { name = "types-cachetools" }, @@ -1637,7 +1636,7 @@ requires-dist = [ { name = "pydantic", specifier = "~=2.12.5" }, { name = "pydantic-extra-types", specifier = "~=2.10.3" }, { name = "pydantic-settings", specifier = "~=2.12.0" }, - { name = "pyjwt", specifier = "~=2.10.1" }, + { name = "pyjwt", specifier = "~=2.11.0" }, { name = "pypdfium2", specifier = "==5.2.0" }, { name = "python-docx", specifier = "~=1.2.0" }, { name = "python-dotenv", specifier = "==1.0.1" }, @@ -1684,8 +1683,7 @@ dev = [ { name = "scipy-stubs", specifier = ">=1.15.3.0" }, { name = "sseclient-py", specifier = ">=1.8.0" }, { name = "testcontainers", specifier = "~=4.13.2" }, - { name = "ty", specifier = ">=0.0.14" }, - { name = "types-aiofiles", specifier = "~=24.1.0" }, + { name = "types-aiofiles", specifier = "~=25.1.0" }, { name = "types-beautifulsoup4", specifier = "~=4.12.0" }, { name = "types-cachetools", specifier = "~=5.5.0" }, { name = "types-cffi", specifier = ">=1.17.0" }, @@ -4959,11 +4957,11 @@ wheels = [ [[package]] name = "pyjwt" -version = "2.10.1" +version = "2.11.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785, upload-time = "2024-11-28T03:43:29.933Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/5a/b46fa56bf322901eee5b0454a34343cdbdae202cd421775a8ee4e42fd519/pyjwt-2.11.0.tar.gz", hash = "sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623", size = 98019, upload-time = "2026-01-30T19:59:55.694Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997, upload-time = "2024-11-28T03:43:27.893Z" }, + { url = "https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl", hash = "sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469", size = 28224, upload-time = "2026-01-30T19:59:54.539Z" }, ] [package.optional-dependencies] @@ -6278,30 +6276,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/26/2591b48412bde75e33bfd292034103ffe41743cacd03120e3242516cd143/transformers-4.56.2-py3-none-any.whl", hash = "sha256:79c03d0e85b26cb573c109ff9eafa96f3c8d4febfd8a0774e8bba32702dd6dde", size = 11608055, upload-time = "2025-09-19T15:16:23.736Z" }, ] -[[package]] -name = "ty" -version = "0.0.14" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/57/22c3d6bf95c2229120c49ffc2f0da8d9e8823755a1c3194da56e51f1cc31/ty-0.0.14.tar.gz", hash = "sha256:a691010565f59dd7f15cf324cdcd1d9065e010c77a04f887e1ea070ba34a7de2", size = 5036573, upload-time = "2026-01-27T00:57:31.427Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/99/cb/cc6d1d8de59beb17a41f9a614585f884ec2d95450306c173b3b7cc090d2e/ty-0.0.14-py3-none-linux_armv6l.whl", hash = "sha256:32cf2a7596e693094621d3ae568d7ee16707dce28c34d1762947874060fdddaa", size = 10034228, upload-time = "2026-01-27T00:57:53.133Z" }, - { url = "https://files.pythonhosted.org/packages/f3/96/dd42816a2075a8f31542296ae687483a8d047f86a6538dfba573223eaf9a/ty-0.0.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f971bf9805f49ce8c0968ad53e29624d80b970b9eb597b7cbaba25d8a18ce9a2", size = 9939162, upload-time = "2026-01-27T00:57:43.857Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b4/73c4859004e0f0a9eead9ecb67021438b2e8e5fdd8d03e7f5aca77623992/ty-0.0.14-py3-none-macosx_11_0_arm64.whl", hash = "sha256:45448b9e4806423523268bc15e9208c4f3f2ead7c344f615549d2e2354d6e924", size = 9418661, upload-time = "2026-01-27T00:58:03.411Z" }, - { url = "https://files.pythonhosted.org/packages/58/35/839c4551b94613db4afa20ee555dd4f33bfa7352d5da74c5fa416ffa0fd2/ty-0.0.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee94a9b747ff40114085206bdb3205a631ef19a4d3fb89e302a88754cbbae54c", size = 9837872, upload-time = "2026-01-27T00:57:23.718Z" }, - { url = "https://files.pythonhosted.org/packages/41/2b/bbecf7e2faa20c04bebd35fc478668953ca50ee5847ce23e08acf20ea119/ty-0.0.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6756715a3c33182e9ab8ffca2bb314d3c99b9c410b171736e145773ee0ae41c3", size = 9848819, upload-time = "2026-01-27T00:57:58.501Z" }, - { url = "https://files.pythonhosted.org/packages/be/60/3c0ba0f19c0f647ad9d2b5b5ac68c0f0b4dc899001bd53b3a7537fb247a2/ty-0.0.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89d0038a2f698ba8b6fec5cf216a4e44e2f95e4a5095a8c0f57fe549f87087c2", size = 10324371, upload-time = "2026-01-27T00:57:29.291Z" }, - { url = "https://files.pythonhosted.org/packages/24/32/99d0a0b37d0397b0a989ffc2682493286aa3bc252b24004a6714368c2c3d/ty-0.0.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c64a83a2d669b77f50a4957039ca1450626fb474619f18f6f8a3eb885bf7544", size = 10865898, upload-time = "2026-01-27T00:57:33.542Z" }, - { url = "https://files.pythonhosted.org/packages/1a/88/30b583a9e0311bb474269cfa91db53350557ebec09002bfc3fb3fc364e8c/ty-0.0.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:242488bfb547ef080199f6fd81369ab9cb638a778bb161511d091ffd49c12129", size = 10555777, upload-time = "2026-01-27T00:58:05.853Z" }, - { url = "https://files.pythonhosted.org/packages/cd/a2/cb53fb6325dcf3d40f2b1d0457a25d55bfbae633c8e337bde8ec01a190eb/ty-0.0.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4790c3866f6c83a4f424fc7d09ebdb225c1f1131647ba8bdc6fcdc28f09ed0ff", size = 10412913, upload-time = "2026-01-27T00:57:38.834Z" }, - { url = "https://files.pythonhosted.org/packages/42/8f/f2f5202d725ed1e6a4e5ffaa32b190a1fe70c0b1a2503d38515da4130b4c/ty-0.0.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:950f320437f96d4ea9a2332bbfb5b68f1c1acd269ebfa4c09b6970cc1565bd9d", size = 9837608, upload-time = "2026-01-27T00:57:55.898Z" }, - { url = "https://files.pythonhosted.org/packages/f7/ba/59a2a0521640c489dafa2c546ae1f8465f92956fede18660653cce73b4c5/ty-0.0.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4a0ec3ee70d83887f86925bbc1c56f4628bd58a0f47f6f32ddfe04e1f05466df", size = 9884324, upload-time = "2026-01-27T00:57:46.786Z" }, - { url = "https://files.pythonhosted.org/packages/03/95/8d2a49880f47b638743212f011088552ecc454dd7a665ddcbdabea25772a/ty-0.0.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a1a4e6b6da0c58b34415955279eff754d6206b35af56a18bb70eb519d8d139ef", size = 10033537, upload-time = "2026-01-27T00:58:01.149Z" }, - { url = "https://files.pythonhosted.org/packages/e9/40/4523b36f2ce69f92ccf783855a9e0ebbbd0f0bb5cdce6211ee1737159ed3/ty-0.0.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:dc04384e874c5de4c5d743369c277c8aa73d1edea3c7fc646b2064b637db4db3", size = 10495910, upload-time = "2026-01-27T00:57:26.691Z" }, - { url = "https://files.pythonhosted.org/packages/08/d5/655beb51224d1bfd4f9ddc0bb209659bfe71ff141bcf05c418ab670698f0/ty-0.0.14-py3-none-win32.whl", hash = "sha256:b20e22cf54c66b3e37e87377635da412d9a552c9bf4ad9fc449fed8b2e19dad2", size = 9507626, upload-time = "2026-01-27T00:57:41.43Z" }, - { url = "https://files.pythonhosted.org/packages/b6/d9/c569c9961760e20e0a4bc008eeb1415754564304fd53997a371b7cf3f864/ty-0.0.14-py3-none-win_amd64.whl", hash = "sha256:e312ff9475522d1a33186657fe74d1ec98e4a13e016d66f5758a452c90ff6409", size = 10437980, upload-time = "2026-01-27T00:57:36.422Z" }, - { url = "https://files.pythonhosted.org/packages/ad/0c/186829654f5bfd9a028f6648e9caeb11271960a61de97484627d24443f91/ty-0.0.14-py3-none-win_arm64.whl", hash = "sha256:b6facdbe9b740cb2c15293a1d178e22ffc600653646452632541d01c36d5e378", size = 9885831, upload-time = "2026-01-27T00:57:49.747Z" }, -] - [[package]] name = "typer" version = "0.20.0" @@ -6319,11 +6293,11 @@ wheels = [ [[package]] name = "types-aiofiles" -version = "24.1.0.20250822" +version = "25.1.0.20251011" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/19/48/c64471adac9206cc844afb33ed311ac5a65d2f59df3d861e0f2d0cad7414/types_aiofiles-24.1.0.20250822.tar.gz", hash = "sha256:9ab90d8e0c307fe97a7cf09338301e3f01a163e39f3b529ace82466355c84a7b", size = 14484, upload-time = "2025-08-22T03:02:23.039Z" } +sdist = { url = "https://files.pythonhosted.org/packages/84/6c/6d23908a8217e36704aa9c79d99a620f2fdd388b66a4b7f72fbc6b6ff6c6/types_aiofiles-25.1.0.20251011.tar.gz", hash = "sha256:1c2b8ab260cb3cd40c15f9d10efdc05a6e1e6b02899304d80dfa0410e028d3ff", size = 14535, upload-time = "2025-10-11T02:44:51.237Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/8e/5e6d2215e1d8f7c2a94c6e9d0059ae8109ce0f5681956d11bb0a228cef04/types_aiofiles-24.1.0.20250822-py3-none-any.whl", hash = "sha256:0ec8f8909e1a85a5a79aed0573af7901f53120dd2a29771dd0b3ef48e12328b0", size = 14322, upload-time = "2025-08-22T03:02:21.918Z" }, + { url = "https://files.pythonhosted.org/packages/71/0f/76917bab27e270bb6c32addd5968d69e558e5b6f7fb4ac4cbfa282996a96/types_aiofiles-25.1.0.20251011-py3-none-any.whl", hash = "sha256:8ff8de7f9d42739d8f0dadcceeb781ce27cd8d8c4152d4a7c52f6b20edb8149c", size = 14338, upload-time = "2025-10-11T02:44:50.054Z" }, ] [[package]] diff --git a/docker/docker-compose-template.yaml b/docker/docker-compose-template.yaml index 18a12114da..fcd4800143 100644 --- a/docker/docker-compose-template.yaml +++ b/docker/docker-compose-template.yaml @@ -149,7 +149,6 @@ services: MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai} TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-} INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-} - PM2_INSTANCES: ${PM2_INSTANCES:-2} LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100} MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10} MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10} diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 003ecf8497..62421d7ec4 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -844,7 +844,6 @@ services: MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai} TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-} INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-} - PM2_INSTANCES: ${PM2_INSTANCES:-2} LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100} MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10} MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10} diff --git a/web/Dockerfile b/web/Dockerfile index d71b1b6ba6..fe4ea1a579 100644 --- a/web/Dockerfile +++ b/web/Dockerfile @@ -50,24 +50,18 @@ ENV MARKETPLACE_API_URL=https://marketplace.dify.ai ENV MARKETPLACE_URL=https://marketplace.dify.ai ENV PORT=3000 ENV NEXT_TELEMETRY_DISABLED=1 -ENV PM2_INSTANCES=2 # set timezone ENV TZ=UTC RUN ln -s /usr/share/zoneinfo/${TZ} /etc/localtime \ && echo ${TZ} > /etc/timezone -# global runtime packages -RUN pnpm add -g pm2 - - # Create non-root user ARG dify_uid=1001 RUN addgroup -S -g ${dify_uid} dify && \ adduser -S -u ${dify_uid} -G dify -s /bin/ash -h /home/dify dify && \ mkdir /app && \ - mkdir /.pm2 && \ - chown -R dify:dify /app /.pm2 + chown -R dify:dify /app WORKDIR /app/web diff --git a/web/README.md b/web/README.md index f069ec82b2..1e57e7c6a9 100644 --- a/web/README.md +++ b/web/README.md @@ -89,8 +89,6 @@ If you want to customize the host and port: pnpm run start --port=3001 --host=0.0.0.0 ``` -If you want to customize the number of instances launched by PM2, you can configure `PM2_INSTANCES` in `docker-compose.yaml` or `Dockerfile`. - ## Storybook This project uses [Storybook](https://storybook.js.org/) for UI component development. diff --git a/web/app/components/base/alert.spec.tsx b/web/app/components/base/__tests__/alert.spec.tsx similarity index 99% rename from web/app/components/base/alert.spec.tsx rename to web/app/components/base/__tests__/alert.spec.tsx index 1ad52ea201..10c1a6bbfa 100644 --- a/web/app/components/base/alert.spec.tsx +++ b/web/app/components/base/__tests__/alert.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import Alert from './alert' +import Alert from '../alert' describe('Alert', () => { const defaultProps = { diff --git a/web/app/components/base/app-unavailable.spec.tsx b/web/app/components/base/__tests__/app-unavailable.spec.tsx similarity index 98% rename from web/app/components/base/app-unavailable.spec.tsx rename to web/app/components/base/__tests__/app-unavailable.spec.tsx index 27fb359781..cce3240d20 100644 --- a/web/app/components/base/app-unavailable.spec.tsx +++ b/web/app/components/base/__tests__/app-unavailable.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import AppUnavailable from './app-unavailable' +import AppUnavailable from '../app-unavailable' describe('AppUnavailable', () => { beforeEach(() => { diff --git a/web/app/components/base/badge.spec.tsx b/web/app/components/base/__tests__/badge.spec.tsx similarity index 99% rename from web/app/components/base/badge.spec.tsx rename to web/app/components/base/__tests__/badge.spec.tsx index 5ca5cfe789..8da348ec90 100644 --- a/web/app/components/base/badge.spec.tsx +++ b/web/app/components/base/__tests__/badge.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import Badge from './badge' +import Badge from '../badge' describe('Badge', () => { describe('Rendering', () => { diff --git a/web/app/components/base/theme-selector.spec.tsx b/web/app/components/base/__tests__/theme-selector.spec.tsx similarity index 98% rename from web/app/components/base/theme-selector.spec.tsx rename to web/app/components/base/__tests__/theme-selector.spec.tsx index 8cd0028acf..1286ee73be 100644 --- a/web/app/components/base/theme-selector.spec.tsx +++ b/web/app/components/base/__tests__/theme-selector.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import ThemeSelector from './theme-selector' +import ThemeSelector from '../theme-selector' // Mock next-themes with controllable state let mockTheme = 'system' diff --git a/web/app/components/base/theme-switcher.spec.tsx b/web/app/components/base/__tests__/theme-switcher.spec.tsx similarity index 98% rename from web/app/components/base/theme-switcher.spec.tsx rename to web/app/components/base/__tests__/theme-switcher.spec.tsx index e19fbd3835..d8ed427d95 100644 --- a/web/app/components/base/theme-switcher.spec.tsx +++ b/web/app/components/base/__tests__/theme-switcher.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import ThemeSwitcher from './theme-switcher' +import ThemeSwitcher from '../theme-switcher' let mockTheme = 'system' const mockSetTheme = vi.fn() diff --git a/web/app/components/base/action-button/index.spec.tsx b/web/app/components/base/action-button/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/action-button/index.spec.tsx rename to web/app/components/base/action-button/__tests__/index.spec.tsx index 839cd9dcc3..949a980272 100644 --- a/web/app/components/base/action-button/index.spec.tsx +++ b/web/app/components/base/action-button/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import { ActionButton, ActionButtonState } from './index' +import { ActionButton, ActionButtonState } from '../index' describe('ActionButton', () => { it('renders button with default props', () => { diff --git a/web/app/components/base/agent-log-modal/detail.spec.tsx b/web/app/components/base/agent-log-modal/__tests__/detail.spec.tsx similarity index 99% rename from web/app/components/base/agent-log-modal/detail.spec.tsx rename to web/app/components/base/agent-log-modal/__tests__/detail.spec.tsx index dd663ac892..c77f144da2 100644 --- a/web/app/components/base/agent-log-modal/detail.spec.tsx +++ b/web/app/components/base/agent-log-modal/__tests__/detail.spec.tsx @@ -4,7 +4,7 @@ import type { AgentLogDetailResponse } from '@/models/log' import { fireEvent, render, screen, waitFor } from '@testing-library/react' import { ToastContext } from '@/app/components/base/toast' import { fetchAgentLogDetail } from '@/service/log' -import AgentLogDetail from './detail' +import AgentLogDetail from '../detail' vi.mock('@/service/log', () => ({ fetchAgentLogDetail: vi.fn(), diff --git a/web/app/components/base/agent-log-modal/index.spec.tsx b/web/app/components/base/agent-log-modal/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/agent-log-modal/index.spec.tsx rename to web/app/components/base/agent-log-modal/__tests__/index.spec.tsx index 17c9bc8cf1..6b59e90c77 100644 --- a/web/app/components/base/agent-log-modal/index.spec.tsx +++ b/web/app/components/base/agent-log-modal/__tests__/index.spec.tsx @@ -3,7 +3,7 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' import { useClickAway } from 'ahooks' import { ToastContext } from '@/app/components/base/toast' import { fetchAgentLogDetail } from '@/service/log' -import AgentLogModal from './index' +import AgentLogModal from '../index' vi.mock('@/service/log', () => ({ fetchAgentLogDetail: vi.fn(), diff --git a/web/app/components/base/agent-log-modal/iteration.spec.tsx b/web/app/components/base/agent-log-modal/__tests__/iteration.spec.tsx similarity index 98% rename from web/app/components/base/agent-log-modal/iteration.spec.tsx rename to web/app/components/base/agent-log-modal/__tests__/iteration.spec.tsx index 15d5b815fb..8266d2f460 100644 --- a/web/app/components/base/agent-log-modal/iteration.spec.tsx +++ b/web/app/components/base/agent-log-modal/__tests__/iteration.spec.tsx @@ -1,6 +1,6 @@ import type { AgentIteration } from '@/models/log' import { render, screen } from '@testing-library/react' -import Iteration from './iteration' +import Iteration from '../iteration' vi.mock('@/app/components/workflow/nodes/_base/components/editor/code-editor', () => ({ default: ({ title, value }: { title: React.ReactNode, value: string | object }) => ( diff --git a/web/app/components/base/agent-log-modal/result.spec.tsx b/web/app/components/base/agent-log-modal/__tests__/result.spec.tsx similarity index 98% rename from web/app/components/base/agent-log-modal/result.spec.tsx rename to web/app/components/base/agent-log-modal/__tests__/result.spec.tsx index 846d433cab..6fcf4c1859 100644 --- a/web/app/components/base/agent-log-modal/result.spec.tsx +++ b/web/app/components/base/agent-log-modal/__tests__/result.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import * as React from 'react' -import ResultPanel from './result' +import ResultPanel from '../result' vi.mock('@/app/components/workflow/nodes/_base/components/editor/code-editor', () => ({ default: ({ title, value }: { title: React.ReactNode, value: string | object }) => ( diff --git a/web/app/components/base/agent-log-modal/tool-call.spec.tsx b/web/app/components/base/agent-log-modal/__tests__/tool-call.spec.tsx similarity index 99% rename from web/app/components/base/agent-log-modal/tool-call.spec.tsx rename to web/app/components/base/agent-log-modal/__tests__/tool-call.spec.tsx index 496049a8a8..a5d6aa8d81 100644 --- a/web/app/components/base/agent-log-modal/tool-call.spec.tsx +++ b/web/app/components/base/agent-log-modal/__tests__/tool-call.spec.tsx @@ -2,7 +2,7 @@ import { fireEvent, render, screen } from '@testing-library/react' import * as React from 'react' import { describe, expect, it, vi } from 'vitest' import { BlockEnum } from '@/app/components/workflow/types' -import ToolCallItem from './tool-call' +import ToolCallItem from '../tool-call' vi.mock('@/app/components/workflow/nodes/_base/components/editor/code-editor', () => ({ default: ({ title, value }: { title: React.ReactNode, value: string | object }) => ( diff --git a/web/app/components/base/agent-log-modal/tracing.spec.tsx b/web/app/components/base/agent-log-modal/__tests__/tracing.spec.tsx similarity index 97% rename from web/app/components/base/agent-log-modal/tracing.spec.tsx rename to web/app/components/base/agent-log-modal/__tests__/tracing.spec.tsx index e0f4a81f99..0e2bb38476 100644 --- a/web/app/components/base/agent-log-modal/tracing.spec.tsx +++ b/web/app/components/base/agent-log-modal/__tests__/tracing.spec.tsx @@ -1,7 +1,7 @@ import type { AgentIteration } from '@/models/log' import { render, screen } from '@testing-library/react' import { describe, expect, it, vi } from 'vitest' -import TracingPanel from './tracing' +import TracingPanel from '../tracing' vi.mock('@/app/components/workflow/block-icon', () => ({ default: () =>
, diff --git a/web/app/components/base/answer-icon/index.spec.tsx b/web/app/components/base/answer-icon/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/answer-icon/index.spec.tsx rename to web/app/components/base/answer-icon/__tests__/index.spec.tsx index 72573fca5b..5bfb672202 100644 --- a/web/app/components/base/answer-icon/index.spec.tsx +++ b/web/app/components/base/answer-icon/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import AnswerIcon from '.' +import AnswerIcon from '..' describe('AnswerIcon', () => { it('renders default emoji when no icon or image is provided', () => { diff --git a/web/app/components/base/app-icon-picker/ImageInput.spec.tsx b/web/app/components/base/app-icon-picker/__tests__/ImageInput.spec.tsx similarity index 99% rename from web/app/components/base/app-icon-picker/ImageInput.spec.tsx rename to web/app/components/base/app-icon-picker/__tests__/ImageInput.spec.tsx index 8e0476823a..19825b4a1c 100644 --- a/web/app/components/base/app-icon-picker/ImageInput.spec.tsx +++ b/web/app/components/base/app-icon-picker/__tests__/ImageInput.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' -import ImageInput from './ImageInput' +import ImageInput from '../ImageInput' const createObjectURLMock = vi.fn(() => 'blob:mock-url') const revokeObjectURLMock = vi.fn() diff --git a/web/app/components/base/app-icon-picker/hooks.spec.tsx b/web/app/components/base/app-icon-picker/__tests__/hooks.spec.tsx similarity index 98% rename from web/app/components/base/app-icon-picker/hooks.spec.tsx rename to web/app/components/base/app-icon-picker/__tests__/hooks.spec.tsx index 58741a3ecf..e2aa203d23 100644 --- a/web/app/components/base/app-icon-picker/hooks.spec.tsx +++ b/web/app/components/base/app-icon-picker/__tests__/hooks.spec.tsx @@ -1,5 +1,5 @@ import { act, renderHook } from '@testing-library/react' -import { useDraggableUploader } from './hooks' +import { useDraggableUploader } from '../hooks' type MockDragEventOverrides = { dataTransfer?: { files: File[] } diff --git a/web/app/components/base/app-icon-picker/index.spec.tsx b/web/app/components/base/app-icon-picker/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/app-icon-picker/index.spec.tsx rename to web/app/components/base/app-icon-picker/__tests__/index.spec.tsx index 63d447e289..8334512047 100644 --- a/web/app/components/base/app-icon-picker/index.spec.tsx +++ b/web/app/components/base/app-icon-picker/__tests__/index.spec.tsx @@ -3,7 +3,7 @@ import type { ImageFile } from '@/types/app' import { fireEvent, render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { TransferMethod } from '@/types/app' -import AppIconPicker from './index' +import AppIconPicker from '../index' import 'vitest-canvas-mock' type LocalFileUploaderOptions = { @@ -93,7 +93,7 @@ vi.mock('react-easy-crop', () => ({ ), })) -vi.mock('../image-uploader/hooks', () => ({ +vi.mock('../../image-uploader/hooks', () => ({ useLocalFileUploader: (options: LocalFileUploaderOptions) => { mocks.onUpload = options.onUpload return { handleLocalFileUpload: mocks.handleLocalFileUpload } diff --git a/web/app/components/base/app-icon-picker/utils.spec.ts b/web/app/components/base/app-icon-picker/__tests__/utils.spec.ts similarity index 99% rename from web/app/components/base/app-icon-picker/utils.spec.ts rename to web/app/components/base/app-icon-picker/__tests__/utils.spec.ts index 778d384910..6b706417cf 100644 --- a/web/app/components/base/app-icon-picker/utils.spec.ts +++ b/web/app/components/base/app-icon-picker/__tests__/utils.spec.ts @@ -1,4 +1,4 @@ -import getCroppedImg, { checkIsAnimatedImage, createImage, getMimeType, getRadianAngle, rotateSize } from './utils' +import getCroppedImg, { checkIsAnimatedImage, createImage, getMimeType, getRadianAngle, rotateSize } from '../utils' type ImageLoadEventType = 'load' | 'error' diff --git a/web/app/components/base/app-icon/index.spec.tsx b/web/app/components/base/app-icon/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/app-icon/index.spec.tsx rename to web/app/components/base/app-icon/__tests__/index.spec.tsx index a4895332cd..de59780d7a 100644 --- a/web/app/components/base/app-icon/index.spec.tsx +++ b/web/app/components/base/app-icon/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import AppIcon from './index' +import AppIcon from '../index' // Mock emoji-mart initialization vi.mock('emoji-mart', () => ({ diff --git a/web/app/components/base/audio-btn/index.spec.tsx b/web/app/components/base/audio-btn/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/audio-btn/index.spec.tsx rename to web/app/components/base/audio-btn/__tests__/index.spec.tsx index 5b30f5f737..c8d8ee851b 100644 --- a/web/app/components/base/audio-btn/index.spec.tsx +++ b/web/app/components/base/audio-btn/__tests__/index.spec.tsx @@ -2,7 +2,7 @@ import { act, render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import i18next from 'i18next' import { useParams, usePathname } from 'next/navigation' -import AudioBtn from './index' +import AudioBtn from '../index' const mockPlayAudio = vi.fn() const mockPauseAudio = vi.fn() diff --git a/web/app/components/base/audio-gallery/AudioPlayer.spec.tsx b/web/app/components/base/audio-gallery/__tests__/AudioPlayer.spec.tsx similarity index 99% rename from web/app/components/base/audio-gallery/AudioPlayer.spec.tsx rename to web/app/components/base/audio-gallery/__tests__/AudioPlayer.spec.tsx index fca106867e..cd4371db2c 100644 --- a/web/app/components/base/audio-gallery/AudioPlayer.spec.tsx +++ b/web/app/components/base/audio-gallery/__tests__/AudioPlayer.spec.tsx @@ -4,7 +4,7 @@ import { vi } from 'vitest' import useThemeMock from '@/hooks/use-theme' import { Theme } from '@/types/app' -import AudioPlayer from './AudioPlayer' +import AudioPlayer from '../AudioPlayer' vi.mock('@/hooks/use-theme', () => ({ default: vi.fn(() => ({ theme: 'light' })), diff --git a/web/app/components/base/audio-gallery/index.spec.tsx b/web/app/components/base/audio-gallery/__tests__/index.spec.tsx similarity index 95% rename from web/app/components/base/audio-gallery/index.spec.tsx rename to web/app/components/base/audio-gallery/__tests__/index.spec.tsx index 9039d4995c..51d707a06e 100644 --- a/web/app/components/base/audio-gallery/index.spec.tsx +++ b/web/app/components/base/audio-gallery/__tests__/index.spec.tsx @@ -3,12 +3,12 @@ import * as React from 'react' // AudioGallery.spec.tsx import { describe, expect, it, vi } from 'vitest' -import AudioGallery from './index' +import AudioGallery from '../index' // Mock AudioPlayer so we only assert prop forwarding const audioPlayerMock = vi.fn() -vi.mock('./AudioPlayer', () => ({ +vi.mock('../AudioPlayer', () => ({ default: (props: { srcs: string[] }) => { audioPlayerMock(props) return
diff --git a/web/app/components/base/auto-height-textarea/index.spec.tsx b/web/app/components/base/auto-height-textarea/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/auto-height-textarea/index.spec.tsx rename to web/app/components/base/auto-height-textarea/__tests__/index.spec.tsx index f6ac0670df..08828d4752 100644 --- a/web/app/components/base/auto-height-textarea/index.spec.tsx +++ b/web/app/components/base/auto-height-textarea/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' import { sleep } from '@/utils' -import AutoHeightTextarea from './index' +import AutoHeightTextarea from '../index' vi.mock('@/utils', async () => { const actual = await vi.importActual('@/utils') diff --git a/web/app/components/base/avatar/index.spec.tsx b/web/app/components/base/avatar/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/avatar/index.spec.tsx rename to web/app/components/base/avatar/__tests__/index.spec.tsx index e85690880b..5fad1d0a90 100644 --- a/web/app/components/base/avatar/index.spec.tsx +++ b/web/app/components/base/avatar/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' -import Avatar from './index' +import Avatar from '../index' describe('Avatar', () => { beforeEach(() => { diff --git a/web/app/components/base/badge/index.spec.tsx b/web/app/components/base/badge/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/badge/index.spec.tsx rename to web/app/components/base/badge/__tests__/index.spec.tsx index 74162841cf..49e8bf4037 100644 --- a/web/app/components/base/badge/index.spec.tsx +++ b/web/app/components/base/badge/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import Badge, { BadgeState, BadgeVariants } from './index' +import Badge, { BadgeState, BadgeVariants } from '../index' describe('Badge', () => { describe('Rendering', () => { diff --git a/web/app/components/base/block-input/index.spec.tsx b/web/app/components/base/block-input/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/block-input/index.spec.tsx rename to web/app/components/base/block-input/__tests__/index.spec.tsx index 8d8729287d..3e1a6a9b90 100644 --- a/web/app/components/base/block-input/index.spec.tsx +++ b/web/app/components/base/block-input/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react' import * as React from 'react' import Toast from '@/app/components/base/toast' -import BlockInput, { getInputKeys } from './index' +import BlockInput, { getInputKeys } from '../index' vi.mock('@/utils/var', () => ({ checkKeys: vi.fn((_keys: string[]) => ({ diff --git a/web/app/components/base/button/add-button.spec.tsx b/web/app/components/base/button/__tests__/add-button.spec.tsx similarity index 97% rename from web/app/components/base/button/add-button.spec.tsx rename to web/app/components/base/button/__tests__/add-button.spec.tsx index ad27753211..1ad999ec49 100644 --- a/web/app/components/base/button/add-button.spec.tsx +++ b/web/app/components/base/button/__tests__/add-button.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import AddButton from './add-button' +import AddButton from '../add-button' describe('AddButton', () => { describe('Rendering', () => { diff --git a/web/app/components/base/button/index.spec.tsx b/web/app/components/base/button/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/button/index.spec.tsx rename to web/app/components/base/button/__tests__/index.spec.tsx index 0377fa334f..b43ae89403 100644 --- a/web/app/components/base/button/index.spec.tsx +++ b/web/app/components/base/button/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { cleanup, fireEvent, render } from '@testing-library/react' import * as React from 'react' -import Button from './index' +import Button from '../index' afterEach(cleanup) // https://testing-library.com/docs/queries/about diff --git a/web/app/components/base/button/sync-button.spec.tsx b/web/app/components/base/button/__tests__/sync-button.spec.tsx similarity index 97% rename from web/app/components/base/button/sync-button.spec.tsx rename to web/app/components/base/button/__tests__/sync-button.spec.tsx index 116aaaa7b0..c86a3c4314 100644 --- a/web/app/components/base/button/sync-button.spec.tsx +++ b/web/app/components/base/button/__tests__/sync-button.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import SyncButton from './sync-button' +import SyncButton from '../sync-button' describe('SyncButton', () => { describe('Rendering', () => { diff --git a/web/app/components/base/carousel/index.spec.tsx b/web/app/components/base/carousel/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/carousel/index.spec.tsx rename to web/app/components/base/carousel/__tests__/index.spec.tsx index 6bce414ee7..a10d25d016 100644 --- a/web/app/components/base/carousel/index.spec.tsx +++ b/web/app/components/base/carousel/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import type { Mock } from 'vitest' import { act, fireEvent, render, screen } from '@testing-library/react' import useEmblaCarousel from 'embla-carousel-react' -import { Carousel, useCarousel } from './index' +import { Carousel, useCarousel } from '../index' vi.mock('embla-carousel-react', () => ({ default: vi.fn(), diff --git a/web/app/components/base/chat/chat-with-history/chat-wrapper.spec.tsx b/web/app/components/base/chat/chat-with-history/__tests__/chat-wrapper.spec.tsx similarity index 99% rename from web/app/components/base/chat/chat-with-history/chat-wrapper.spec.tsx rename to web/app/components/base/chat/chat-with-history/__tests__/chat-wrapper.spec.tsx index 22d450b82d..bcaab17fef 100644 --- a/web/app/components/base/chat/chat-with-history/chat-wrapper.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/__tests__/chat-wrapper.spec.tsx @@ -1,5 +1,5 @@ -import type { ChatConfig, ChatItemInTree } from '../types' -import type { ChatWithHistoryContextValue } from './context' +import type { ChatConfig, ChatItemInTree } from '../../types' +import type { ChatWithHistoryContextValue } from '../context' import type { FileEntity } from '@/app/components/base/file-uploader/types' import type { AppData, AppMeta, ConversationItem } from '@/models/share' import type { HumanInputFormData } from '@/types/workflow' @@ -12,17 +12,17 @@ import { stopChatMessageResponding, } from '@/service/share' import { TransferMethod } from '@/types/app' -import { useChat } from '../chat/hooks' +import { useChat } from '../../chat/hooks' -import { isValidGeneratedAnswer } from '../utils' -import ChatWrapper from './chat-wrapper' -import { useChatWithHistoryContext } from './context' +import { isValidGeneratedAnswer } from '../../utils' +import ChatWrapper from '../chat-wrapper' +import { useChatWithHistoryContext } from '../context' -vi.mock('../chat/hooks', () => ({ +vi.mock('../../chat/hooks', () => ({ useChat: vi.fn(), })) -vi.mock('./context', () => ({ +vi.mock('../context', () => ({ useChatWithHistoryContext: vi.fn(), })) @@ -37,7 +37,7 @@ vi.mock('next/navigation', () => ({ useParams: vi.fn(() => ({ token: 'test-token' })), })) -vi.mock('../utils', () => ({ +vi.mock('../../utils', () => ({ isValidGeneratedAnswer: vi.fn(), getLastAnswer: vi.fn(), })) diff --git a/web/app/components/base/chat/chat-with-history/header-in-mobile.spec.tsx b/web/app/components/base/chat/chat-with-history/__tests__/header-in-mobile.spec.tsx similarity index 98% rename from web/app/components/base/chat/chat-with-history/header-in-mobile.spec.tsx rename to web/app/components/base/chat/chat-with-history/__tests__/header-in-mobile.spec.tsx index 6addaf30a8..5f14128742 100644 --- a/web/app/components/base/chat/chat-with-history/header-in-mobile.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/__tests__/header-in-mobile.spec.tsx @@ -1,12 +1,12 @@ -import type { ChatConfig } from '../types' -import type { ChatWithHistoryContextValue } from './context' +import type { ChatConfig } from '../../types' +import type { ChatWithHistoryContextValue } from '../context' import type { AppData, AppMeta, ConversationItem } from '@/models/share' import { fireEvent, render, screen, waitFor } from '@testing-library/react' import * as React from 'react' import { beforeEach, describe, expect, it, vi } from 'vitest' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' -import { useChatWithHistoryContext } from './context' -import HeaderInMobile from './header-in-mobile' +import { useChatWithHistoryContext } from '../context' +import HeaderInMobile from '../header-in-mobile' vi.mock('@/hooks/use-breakpoints', () => ({ default: vi.fn(), @@ -17,7 +17,7 @@ vi.mock('@/hooks/use-breakpoints', () => ({ }, })) -vi.mock('./context', () => ({ +vi.mock('../context', () => ({ useChatWithHistoryContext: vi.fn(), ChatWithHistoryContext: { Provider: ({ children }: { children: React.ReactNode }) =>
{children}
}, })) @@ -33,7 +33,7 @@ vi.mock('next/navigation', () => ({ useParams: vi.fn(() => ({})), })) -vi.mock('../embedded-chatbot/theme/theme-context', () => ({ +vi.mock('../../embedded-chatbot/theme/theme-context', () => ({ useThemeContext: vi.fn(() => ({ buildTheme: vi.fn(), })), diff --git a/web/app/components/base/chat/chat-with-history/hooks.spec.tsx b/web/app/components/base/chat/chat-with-history/__tests__/hooks.spec.tsx similarity index 97% rename from web/app/components/base/chat/chat-with-history/hooks.spec.tsx rename to web/app/components/base/chat/chat-with-history/__tests__/hooks.spec.tsx index 399f16716d..711c3c88f9 100644 --- a/web/app/components/base/chat/chat-with-history/hooks.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/__tests__/hooks.spec.tsx @@ -1,5 +1,5 @@ import type { ReactNode } from 'react' -import type { ChatConfig } from '../types' +import type { ChatConfig } from '../../types' import type { AppConversationData, AppData, AppMeta, ConversationItem } from '@/models/share' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { act, renderHook, waitFor } from '@testing-library/react' @@ -11,8 +11,8 @@ import { generationConversationName, } from '@/service/share' import { shareQueryKeys } from '@/service/use-share' -import { CONVERSATION_ID_INFO } from '../constants' -import { useChatWithHistory } from './hooks' +import { CONVERSATION_ID_INFO } from '../../constants' +import { useChatWithHistory } from '../hooks' vi.mock('@/hooks/use-app-favicon', () => ({ useAppFavicon: vi.fn(), @@ -40,8 +40,8 @@ vi.mock('@/context/web-app-context', () => ({ useWebAppStore: (selector?: (state: typeof mockStoreState) => unknown) => useWebAppStoreMock(selector), })) -vi.mock('../utils', async () => { - const actual = await vi.importActual('../utils') +vi.mock('../../utils', async () => { + const actual = await vi.importActual('../../utils') return { ...actual, getProcessedSystemVariablesFromUrlParams: vi.fn().mockResolvedValue({ user_id: 'user-1' }), diff --git a/web/app/components/base/chat/chat-with-history/index.spec.tsx b/web/app/components/base/chat/chat-with-history/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/chat/chat-with-history/index.spec.tsx rename to web/app/components/base/chat/chat-with-history/__tests__/index.spec.tsx index a02d05b427..452639f4b7 100644 --- a/web/app/components/base/chat/chat-with-history/index.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import type { RefObject } from 'react' -import type { ChatConfig } from '../types' +import type { ChatConfig } from '../../types' import type { InstalledApp } from '@/models/explore' import type { AppConversationData, AppData, AppMeta, ConversationItem } from '@/models/share' import { fireEvent, render, screen } from '@testing-library/react' @@ -7,11 +7,11 @@ import * as React from 'react' import { beforeEach, describe, expect, it, vi } from 'vitest' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import useDocumentTitle from '@/hooks/use-document-title' -import { useChatWithHistory } from './hooks' -import ChatWithHistory from './index' +import { useChatWithHistory } from '../hooks' +import ChatWithHistory from '../index' // --- Mocks --- -vi.mock('./hooks', () => ({ +vi.mock('../hooks', () => ({ useChatWithHistory: vi.fn(), })) @@ -40,7 +40,7 @@ vi.mock('next/navigation', () => ({ })) const mockBuildTheme = vi.fn() -vi.mock('../embedded-chatbot/theme/theme-context', () => ({ +vi.mock('../../embedded-chatbot/theme/theme-context', () => ({ useThemeContext: vi.fn(() => ({ buildTheme: mockBuildTheme, })), diff --git a/web/app/components/base/chat/chat-with-history/header/index.spec.tsx b/web/app/components/base/chat/chat-with-history/header/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/chat/chat-with-history/header/index.spec.tsx rename to web/app/components/base/chat/chat-with-history/header/__tests__/index.spec.tsx index 8ed5c96f61..2b428ac32f 100644 --- a/web/app/components/base/chat/chat-with-history/header/index.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/header/__tests__/index.spec.tsx @@ -1,13 +1,13 @@ -import type { ChatWithHistoryContextValue } from '../context' +import type { ChatWithHistoryContextValue } from '../../context' import type { AppData, ConversationItem } from '@/models/share' import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { beforeEach, describe, expect, it, vi } from 'vitest' -import { useChatWithHistoryContext } from '../context' -import Header from './index' +import { useChatWithHistoryContext } from '../../context' +import Header from '../index' // Mock context module -vi.mock('../context', () => ({ +vi.mock('../../context', () => ({ useChatWithHistoryContext: vi.fn(), })) diff --git a/web/app/components/base/chat/chat-with-history/header/mobile-operation-dropdown.spec.tsx b/web/app/components/base/chat/chat-with-history/header/__tests__/mobile-operation-dropdown.spec.tsx similarity index 97% rename from web/app/components/base/chat/chat-with-history/header/mobile-operation-dropdown.spec.tsx rename to web/app/components/base/chat/chat-with-history/header/__tests__/mobile-operation-dropdown.spec.tsx index 594b1353c9..295bebecac 100644 --- a/web/app/components/base/chat/chat-with-history/header/mobile-operation-dropdown.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/header/__tests__/mobile-operation-dropdown.spec.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import * as React from 'react' import { beforeEach, describe, expect, it, vi } from 'vitest' -import MobileOperationDropdown from './mobile-operation-dropdown' +import MobileOperationDropdown from '../mobile-operation-dropdown' describe('MobileOperationDropdown Component', () => { const defaultProps = { diff --git a/web/app/components/base/chat/chat-with-history/header/operation.spec.tsx b/web/app/components/base/chat/chat-with-history/header/__tests__/operation.spec.tsx similarity index 98% rename from web/app/components/base/chat/chat-with-history/header/operation.spec.tsx rename to web/app/components/base/chat/chat-with-history/header/__tests__/operation.spec.tsx index 0c37b0d2fd..454f20066e 100644 --- a/web/app/components/base/chat/chat-with-history/header/operation.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/header/__tests__/operation.spec.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import * as React from 'react' import { beforeEach, describe, expect, it, vi } from 'vitest' -import Operation from './operation' +import Operation from '../operation' describe('Operation Component', () => { const defaultProps = { diff --git a/web/app/components/base/chat/chat-with-history/inputs-form/content.spec.tsx b/web/app/components/base/chat/chat-with-history/inputs-form/__tests__/content.spec.tsx similarity index 98% rename from web/app/components/base/chat/chat-with-history/inputs-form/content.spec.tsx rename to web/app/components/base/chat/chat-with-history/inputs-form/__tests__/content.spec.tsx index 9d55e6df10..c1a0f3e294 100644 --- a/web/app/components/base/chat/chat-with-history/inputs-form/content.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/inputs-form/__tests__/content.spec.tsx @@ -1,10 +1,10 @@ -import type { ChatWithHistoryContextValue } from '../context' +import type { ChatWithHistoryContextValue } from '../../context' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import * as React from 'react' import { beforeEach, describe, expect, it, vi } from 'vitest' import { InputVarType } from '@/app/components/workflow/types' -import InputsFormContent from './content' +import InputsFormContent from '../content' // Keep lightweight mocks for non-base project components vi.mock('@/app/components/workflow/nodes/_base/components/before-run-form/bool-input', () => ({ @@ -90,7 +90,7 @@ const createMockContext = (overrides: Partial = {}) // Create a real context for testing to support controlled component behavior const MockContext = React.createContext(createMockContext()) -vi.mock('../context', () => ({ +vi.mock('../../context', () => ({ useChatWithHistoryContext: () => React.useContext(MockContext), })) diff --git a/web/app/components/base/chat/chat-with-history/inputs-form/index.spec.tsx b/web/app/components/base/chat/chat-with-history/inputs-form/__tests__/index.spec.tsx similarity index 96% rename from web/app/components/base/chat/chat-with-history/inputs-form/index.spec.tsx rename to web/app/components/base/chat/chat-with-history/inputs-form/__tests__/index.spec.tsx index 90deb4e02d..0ba41afd8a 100644 --- a/web/app/components/base/chat/chat-with-history/inputs-form/index.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/inputs-form/__tests__/index.spec.tsx @@ -1,11 +1,11 @@ -import type { ChatWithHistoryContextValue } from '../context' +import type { ChatWithHistoryContextValue } from '../../context' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import * as React from 'react' import { beforeEach, describe, expect, it, vi } from 'vitest' import { InputVarType } from '@/app/components/workflow/types' -import { useChatWithHistoryContext } from '../context' -import InputsFormNode from './index' +import { useChatWithHistoryContext } from '../../context' +import InputsFormNode from '../index' // Mocks for components used by InputsFormContent (the real sibling) vi.mock('@/app/components/workflow/nodes/_base/components/before-run-form/bool-input', () => ({ @@ -31,7 +31,7 @@ vi.mock('@/app/components/base/file-uploader', () => ({ ), })) -vi.mock('../context', () => ({ +vi.mock('../../context', () => ({ useChatWithHistoryContext: vi.fn(), })) diff --git a/web/app/components/base/chat/chat-with-history/inputs-form/view-form-dropdown.spec.tsx b/web/app/components/base/chat/chat-with-history/inputs-form/__tests__/view-form-dropdown.spec.tsx similarity index 94% rename from web/app/components/base/chat/chat-with-history/inputs-form/view-form-dropdown.spec.tsx rename to web/app/components/base/chat/chat-with-history/inputs-form/__tests__/view-form-dropdown.spec.tsx index 517828003d..64d3e67b8f 100644 --- a/web/app/components/base/chat/chat-with-history/inputs-form/view-form-dropdown.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/inputs-form/__tests__/view-form-dropdown.spec.tsx @@ -1,11 +1,11 @@ -import type { ChatWithHistoryContextValue } from '../context' +import type { ChatWithHistoryContextValue } from '../../context' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import * as React from 'react' import { beforeEach, describe, expect, it, vi } from 'vitest' import { InputVarType } from '@/app/components/workflow/types' -import { useChatWithHistoryContext } from '../context' -import ViewFormDropdown from './view-form-dropdown' +import { useChatWithHistoryContext } from '../../context' +import ViewFormDropdown from '../view-form-dropdown' // Mocks for components used by InputsFormContent (the real sibling) vi.mock('@/app/components/workflow/nodes/_base/components/before-run-form/bool-input', () => ({ @@ -31,7 +31,7 @@ vi.mock('@/app/components/base/file-uploader', () => ({ ), })) -vi.mock('../context', () => ({ +vi.mock('../../context', () => ({ useChatWithHistoryContext: vi.fn(), })) diff --git a/web/app/components/base/chat/chat-with-history/sidebar/index.spec.tsx b/web/app/components/base/chat/chat-with-history/sidebar/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/chat/chat-with-history/sidebar/index.spec.tsx rename to web/app/components/base/chat/chat-with-history/sidebar/__tests__/index.spec.tsx index f1378f5553..768bbe9284 100644 --- a/web/app/components/base/chat/chat-with-history/sidebar/index.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/sidebar/__tests__/index.spec.tsx @@ -1,13 +1,13 @@ -import type { ChatWithHistoryContextValue } from '../context' +import type { ChatWithHistoryContextValue } from '../../context' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import * as React from 'react' import { beforeEach, describe, expect, it, vi } from 'vitest' -import { useChatWithHistoryContext } from '../context' -import Sidebar from './index' +import { useChatWithHistoryContext } from '../../context' +import Sidebar from '../index' // Mock List to allow us to trigger operations -vi.mock('./list', () => ({ +vi.mock('../list', () => ({ default: ({ list, onOperate, title }: { list: Array<{ id: string, name: string }>, onOperate: (type: string, item: { id: string, name: string }) => void, title?: string }) => (
{title &&
{title}
} @@ -25,7 +25,7 @@ vi.mock('./list', () => ({ })) // Mock context hook -vi.mock('../context', () => ({ +vi.mock('../../context', () => ({ useChatWithHistoryContext: vi.fn(), })) diff --git a/web/app/components/base/chat/chat-with-history/sidebar/item.spec.tsx b/web/app/components/base/chat/chat-with-history/sidebar/__tests__/item.spec.tsx similarity index 99% rename from web/app/components/base/chat/chat-with-history/sidebar/item.spec.tsx rename to web/app/components/base/chat/chat-with-history/sidebar/__tests__/item.spec.tsx index 1388d1b5ed..075b5b6b1c 100644 --- a/web/app/components/base/chat/chat-with-history/sidebar/item.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/sidebar/__tests__/item.spec.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import * as React from 'react' import { beforeEach, describe, expect, it, vi } from 'vitest' -import Item from './item' +import Item from '../item' // Mock Operation to verify its usage vi.mock('@/app/components/base/chat/chat-with-history/sidebar/operation', () => ({ diff --git a/web/app/components/base/chat/chat-with-history/sidebar/list.spec.tsx b/web/app/components/base/chat/chat-with-history/sidebar/__tests__/list.spec.tsx similarity index 96% rename from web/app/components/base/chat/chat-with-history/sidebar/list.spec.tsx rename to web/app/components/base/chat/chat-with-history/sidebar/__tests__/list.spec.tsx index 7324a72aa6..a0d04fb271 100644 --- a/web/app/components/base/chat/chat-with-history/sidebar/list.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/sidebar/__tests__/list.spec.tsx @@ -1,10 +1,10 @@ import { render, screen } from '@testing-library/react' import * as React from 'react' import { describe, expect, it, vi } from 'vitest' -import List from './list' +import List from '../list' // Mock Item to verify its usage -vi.mock('./item', () => ({ +vi.mock('../item', () => ({ default: ({ item }: { item: { name: string } }) => (
{item.name} diff --git a/web/app/components/base/chat/chat-with-history/sidebar/operation.spec.tsx b/web/app/components/base/chat/chat-with-history/sidebar/__tests__/operation.spec.tsx similarity index 99% rename from web/app/components/base/chat/chat-with-history/sidebar/operation.spec.tsx rename to web/app/components/base/chat/chat-with-history/sidebar/__tests__/operation.spec.tsx index 3f7d11a837..e46b54872e 100644 --- a/web/app/components/base/chat/chat-with-history/sidebar/operation.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/sidebar/__tests__/operation.spec.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import * as React from 'react' import { beforeEach, describe, expect, it, vi } from 'vitest' -import Operation from './operation' +import Operation from '../operation' // Mock PortalToFollowElem components to render children in place vi.mock('@/app/components/base/portal-to-follow-elem', () => ({ diff --git a/web/app/components/base/chat/chat-with-history/sidebar/rename-modal.spec.tsx b/web/app/components/base/chat/chat-with-history/sidebar/__tests__/rename-modal.spec.tsx similarity index 98% rename from web/app/components/base/chat/chat-with-history/sidebar/rename-modal.spec.tsx rename to web/app/components/base/chat/chat-with-history/sidebar/__tests__/rename-modal.spec.tsx index 4feecd72b6..e20caa98da 100644 --- a/web/app/components/base/chat/chat-with-history/sidebar/rename-modal.spec.tsx +++ b/web/app/components/base/chat/chat-with-history/sidebar/__tests__/rename-modal.spec.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import * as React from 'react' import { beforeEach, describe, expect, it, vi } from 'vitest' -import RenameModal from './rename-modal' +import RenameModal from '../rename-modal' describe('RenameModal', () => { const defaultProps = { diff --git a/web/app/components/base/chat/chat/content-switch.spec.tsx b/web/app/components/base/chat/chat/__tests__/content-switch.spec.tsx similarity index 98% rename from web/app/components/base/chat/chat/content-switch.spec.tsx rename to web/app/components/base/chat/chat/__tests__/content-switch.spec.tsx index 5f87ceb6f2..e05151464a 100644 --- a/web/app/components/base/chat/chat/content-switch.spec.tsx +++ b/web/app/components/base/chat/chat/__tests__/content-switch.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import ContentSwitch from './content-switch' +import ContentSwitch from '../content-switch' describe('ContentSwitch', () => { const defaultProps = { diff --git a/web/app/components/base/chat/chat/context.spec.tsx b/web/app/components/base/chat/chat/__tests__/context.spec.tsx similarity index 94% rename from web/app/components/base/chat/chat/context.spec.tsx rename to web/app/components/base/chat/chat/__tests__/context.spec.tsx index de65a4d606..fd00156e59 100644 --- a/web/app/components/base/chat/chat/context.spec.tsx +++ b/web/app/components/base/chat/chat/__tests__/context.spec.tsx @@ -1,9 +1,9 @@ -import type { ChatItem } from '../types' -import type { ChatContextValue } from './context' +import type { ChatItem } from '../../types' +import type { ChatContextValue } from '../context' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { vi } from 'vitest' -import { ChatContextProvider, useChatContext } from './context' +import { ChatContextProvider, useChatContext } from '../context' const TestConsumer = () => { const context = useChatContext() diff --git a/web/app/components/base/chat/chat/hooks.multimodal.spec.ts b/web/app/components/base/chat/chat/__tests__/hooks.multimodal.spec.ts similarity index 100% rename from web/app/components/base/chat/chat/hooks.multimodal.spec.ts rename to web/app/components/base/chat/chat/__tests__/hooks.multimodal.spec.ts diff --git a/web/app/components/base/chat/chat/index.spec.tsx b/web/app/components/base/chat/chat/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/chat/chat/index.spec.tsx rename to web/app/components/base/chat/chat/__tests__/index.spec.tsx index 73c4aa8207..ba5bbaba6b 100644 --- a/web/app/components/base/chat/chat/index.spec.tsx +++ b/web/app/components/base/chat/chat/__tests__/index.spec.tsx @@ -1,10 +1,10 @@ -import type { ChatConfig, ChatItem, OnSend } from '../types' -import type { ChatProps } from './index' +import type { ChatConfig, ChatItem, OnSend } from '../../types' +import type { ChatProps } from '../index' import { act, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { useStore as useAppStore } from '@/app/components/app/store' -import Chat from './index' +import Chat from '../index' // ─── Why each mock exists ───────────────────────────────────────────────────── // @@ -24,7 +24,7 @@ import Chat from './index' // TryToAsk – only uses Button (base), Divider (base), i18n (global mock). // ───────────────────────────────────────────────────────────────────────────── -vi.mock('./answer', () => ({ +vi.mock('../answer', () => ({ default: ({ item, responding }: { item: ChatItem, responding?: boolean }) => (
({ ), })) -vi.mock('./question', () => ({ +vi.mock('../question', () => ({ default: ({ item }: { item: ChatItem }) => (
{item.content}
), })) -vi.mock('./chat-input-area', () => ({ +vi.mock('../chat-input-area', () => ({ default: ({ disabled, readonly }: { disabled?: boolean, readonly?: boolean }) => (
({ diff --git a/web/app/components/base/chat/chat/try-to-ask.spec.tsx b/web/app/components/base/chat/chat/__tests__/try-to-ask.spec.tsx similarity index 97% rename from web/app/components/base/chat/chat/try-to-ask.spec.tsx rename to web/app/components/base/chat/chat/__tests__/try-to-ask.spec.tsx index caeae028c6..e59e0865c1 100644 --- a/web/app/components/base/chat/chat/try-to-ask.spec.tsx +++ b/web/app/components/base/chat/chat/__tests__/try-to-ask.spec.tsx @@ -1,7 +1,7 @@ -import type { OnSend } from '../types' +import type { OnSend } from '../../types' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import TryToAsk from './try-to-ask' +import TryToAsk from '../try-to-ask' describe('TryToAsk', () => { const mockOnSend: OnSend = vi.fn() diff --git a/web/app/components/base/chat/chat/answer/agent-content.spec.tsx b/web/app/components/base/chat/chat/answer/__tests__/agent-content.spec.tsx similarity index 97% rename from web/app/components/base/chat/chat/answer/agent-content.spec.tsx rename to web/app/components/base/chat/chat/answer/__tests__/agent-content.spec.tsx index ef4143fa6f..57c1eefa1f 100644 --- a/web/app/components/base/chat/chat/answer/agent-content.spec.tsx +++ b/web/app/components/base/chat/chat/answer/__tests__/agent-content.spec.tsx @@ -1,9 +1,9 @@ -import type { ChatItem } from '../../types' +import type { ChatItem } from '../../../types' import type { IThoughtProps } from '@/app/components/base/chat/chat/thought' import type { FileEntity } from '@/app/components/base/file-uploader/types' import type { MarkdownProps } from '@/app/components/base/markdown' import { render, screen } from '@testing-library/react' -import AgentContent from './agent-content' +import AgentContent from '../agent-content' // Mock Markdown component used only in tests vi.mock('@/app/components/base/markdown', () => ({ diff --git a/web/app/components/base/chat/chat/answer/basic-content.spec.tsx b/web/app/components/base/chat/chat/answer/__tests__/basic-content.spec.tsx similarity index 97% rename from web/app/components/base/chat/chat/answer/basic-content.spec.tsx rename to web/app/components/base/chat/chat/answer/__tests__/basic-content.spec.tsx index 9a03ea9d40..77c1ea23cf 100644 --- a/web/app/components/base/chat/chat/answer/basic-content.spec.tsx +++ b/web/app/components/base/chat/chat/answer/__tests__/basic-content.spec.tsx @@ -1,7 +1,7 @@ -import type { ChatItem } from '../../types' +import type { ChatItem } from '../../../types' import type { MarkdownProps } from '@/app/components/base/markdown' import { render, screen } from '@testing-library/react' -import BasicContent from './basic-content' +import BasicContent from '../basic-content' // Mock Markdown component used only in tests vi.mock('@/app/components/base/markdown', () => ({ diff --git a/web/app/components/base/chat/chat/answer/human-input-filled-form-list.spec.tsx b/web/app/components/base/chat/chat/answer/__tests__/human-input-filled-form-list.spec.tsx similarity index 96% rename from web/app/components/base/chat/chat/answer/human-input-filled-form-list.spec.tsx rename to web/app/components/base/chat/chat/answer/__tests__/human-input-filled-form-list.spec.tsx index 5eceddd444..37556550ca 100644 --- a/web/app/components/base/chat/chat/answer/human-input-filled-form-list.spec.tsx +++ b/web/app/components/base/chat/chat/answer/__tests__/human-input-filled-form-list.spec.tsx @@ -1,7 +1,7 @@ import type { HumanInputFilledFormData } from '@/types/workflow' import { render, screen } from '@testing-library/react' import { describe, expect, it } from 'vitest' -import HumanInputFilledFormList from './human-input-filled-form-list' +import HumanInputFilledFormList from '../human-input-filled-form-list' /** * Type-safe factory. diff --git a/web/app/components/base/chat/chat/answer/human-input-form-list.spec.tsx b/web/app/components/base/chat/chat/answer/__tests__/human-input-form-list.spec.tsx similarity index 96% rename from web/app/components/base/chat/chat/answer/human-input-form-list.spec.tsx rename to web/app/components/base/chat/chat/answer/__tests__/human-input-form-list.spec.tsx index 4bfd3a7d97..cc8fdfffd0 100644 --- a/web/app/components/base/chat/chat/answer/human-input-form-list.spec.tsx +++ b/web/app/components/base/chat/chat/answer/__tests__/human-input-form-list.spec.tsx @@ -1,10 +1,10 @@ import type { HumanInputFormData } from '@/types/workflow' import { render, screen } from '@testing-library/react' import { DeliveryMethodType } from '@/app/components/workflow/nodes/human-input/types' -import HumanInputFormList from './human-input-form-list' +import HumanInputFormList from '../human-input-form-list' // Mock child components -vi.mock('./human-input-content/content-wrapper', () => ({ +vi.mock('../human-input-content/content-wrapper', () => ({ default: ({ children, nodeTitle }: { children: React.ReactNode, nodeTitle: string }) => (
{children} @@ -12,7 +12,7 @@ vi.mock('./human-input-content/content-wrapper', () => ({ ), })) -vi.mock('./human-input-content/unsubmitted', () => ({ +vi.mock('../human-input-content/unsubmitted', () => ({ UnsubmittedHumanInputContent: ({ showEmailTip, isEmailDebugMode, showDebugModeTip }: { showEmailTip: boolean, isEmailDebugMode: boolean, showDebugModeTip: boolean }) => (
{showEmailTip ? 'true' : 'false'} diff --git a/web/app/components/base/chat/chat/answer/more.spec.tsx b/web/app/components/base/chat/chat/answer/__tests__/more.spec.tsx similarity index 98% rename from web/app/components/base/chat/chat/answer/more.spec.tsx rename to web/app/components/base/chat/chat/answer/__tests__/more.spec.tsx index 551c15e659..6ff162f09f 100644 --- a/web/app/components/base/chat/chat/answer/more.spec.tsx +++ b/web/app/components/base/chat/chat/answer/__tests__/more.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import More from './more' +import More from '../more' describe('More', () => { const mockMoreData = { diff --git a/web/app/components/base/chat/chat/answer/operation.spec.tsx b/web/app/components/base/chat/chat/answer/__tests__/operation.spec.tsx similarity index 99% rename from web/app/components/base/chat/chat/answer/operation.spec.tsx rename to web/app/components/base/chat/chat/answer/__tests__/operation.spec.tsx index eb52dffe8f..0c5a43e62a 100644 --- a/web/app/components/base/chat/chat/answer/operation.spec.tsx +++ b/web/app/components/base/chat/chat/answer/__tests__/operation.spec.tsx @@ -1,5 +1,5 @@ -import type { ChatConfig, ChatItem } from '../../types' -import type { ChatContextValue } from '../context' +import type { ChatConfig, ChatItem } from '../../../types' +import type { ChatContextValue } from '../../context' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import copy from 'copy-to-clipboard' @@ -7,7 +7,7 @@ import * as React from 'react' import { vi } from 'vitest' import { useModalContext } from '@/context/modal-context' import { useProviderContext } from '@/context/provider-context' -import Operation from './operation' +import Operation from '../operation' const { mockSetShowAnnotationFullModal, @@ -158,7 +158,7 @@ const mockContextValue: ChatContextValue = { onAnnotationRemoved: vi.fn(), } -vi.mock('../context', () => ({ +vi.mock('../../context', () => ({ useChatContext: () => mockContextValue, })) diff --git a/web/app/components/base/chat/chat/answer/suggested-questions.spec.tsx b/web/app/components/base/chat/chat/answer/__tests__/suggested-questions.spec.tsx similarity index 93% rename from web/app/components/base/chat/chat/answer/suggested-questions.spec.tsx rename to web/app/components/base/chat/chat/answer/__tests__/suggested-questions.spec.tsx index 85a8a28609..16128759bd 100644 --- a/web/app/components/base/chat/chat/answer/suggested-questions.spec.tsx +++ b/web/app/components/base/chat/chat/answer/__tests__/suggested-questions.spec.tsx @@ -1,12 +1,12 @@ import type { Mock } from 'vitest' // Or 'jest' if using Jest -import type { IChatItem } from '../type' +import type { IChatItem } from '../../type' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { useChatContext } from '../context' -import SuggestedQuestions from './suggested-questions' +import { useChatContext } from '../../context' +import SuggestedQuestions from '../suggested-questions' // Mock the chat context -vi.mock('../context', () => ({ +vi.mock('../../context', () => ({ useChatContext: vi.fn(), })) diff --git a/web/app/components/base/chat/chat/answer/tool-detail.spec.tsx b/web/app/components/base/chat/chat/answer/__tests__/tool-detail.spec.tsx similarity index 96% rename from web/app/components/base/chat/chat/answer/tool-detail.spec.tsx rename to web/app/components/base/chat/chat/answer/__tests__/tool-detail.spec.tsx index 774adcc6e4..7ddeceeb83 100644 --- a/web/app/components/base/chat/chat/answer/tool-detail.spec.tsx +++ b/web/app/components/base/chat/chat/answer/__tests__/tool-detail.spec.tsx @@ -1,7 +1,7 @@ -import type { ToolInfoInThought } from '../type' +import type { ToolInfoInThought } from '../../type' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import ToolDetail from './tool-detail' +import ToolDetail from '../tool-detail' describe('ToolDetail', () => { const mockPayload: ToolInfoInThought = { diff --git a/web/app/components/base/chat/chat/answer/workflow-process.spec.tsx b/web/app/components/base/chat/chat/answer/__tests__/workflow-process.spec.tsx similarity index 98% rename from web/app/components/base/chat/chat/answer/workflow-process.spec.tsx rename to web/app/components/base/chat/chat/answer/__tests__/workflow-process.spec.tsx index 30fdb954ea..1e7d9f012e 100644 --- a/web/app/components/base/chat/chat/answer/workflow-process.spec.tsx +++ b/web/app/components/base/chat/chat/answer/__tests__/workflow-process.spec.tsx @@ -1,8 +1,8 @@ -import type { WorkflowProcess } from '../../types' +import type { WorkflowProcess } from '../../../types' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { WorkflowRunningStatus } from '@/app/components/workflow/types' -import WorkflowProcessItem from './workflow-process' +import WorkflowProcessItem from '../workflow-process' // Mock TracingPanel as it's a complex child component vi.mock('@/app/components/workflow/run/tracing-panel', () => ({ diff --git a/web/app/components/base/chat/chat/answer/human-input-content/content-item.spec.tsx b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/content-item.spec.tsx similarity index 98% rename from web/app/components/base/chat/chat/answer/human-input-content/content-item.spec.tsx rename to web/app/components/base/chat/chat/answer/human-input-content/__tests__/content-item.spec.tsx index 2c762f37b5..b1a6ec51ae 100644 --- a/web/app/components/base/chat/chat/answer/human-input-content/content-item.spec.tsx +++ b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/content-item.spec.tsx @@ -2,7 +2,7 @@ import type { FormInputItem } from '@/app/components/workflow/nodes/human-input/ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import ContentItem from './content-item' +import ContentItem from '../content-item' vi.mock('@/app/components/base/markdown', () => ({ Markdown: ({ content }: { content: string }) =>
{content}
, diff --git a/web/app/components/base/chat/chat/answer/human-input-content/content-wrapper.spec.tsx b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/content-wrapper.spec.tsx similarity index 97% rename from web/app/components/base/chat/chat/answer/human-input-content/content-wrapper.spec.tsx rename to web/app/components/base/chat/chat/answer/human-input-content/__tests__/content-wrapper.spec.tsx index 36f264a834..9e50c9c18b 100644 --- a/web/app/components/base/chat/chat/answer/human-input-content/content-wrapper.spec.tsx +++ b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/content-wrapper.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it } from 'vitest' -import ContentWrapper from './content-wrapper' +import ContentWrapper from '../content-wrapper' describe('ContentWrapper', () => { const defaultProps = { diff --git a/web/app/components/base/chat/chat/answer/human-input-content/executed-action.spec.tsx b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/executed-action.spec.tsx similarity index 94% rename from web/app/components/base/chat/chat/answer/human-input-content/executed-action.spec.tsx rename to web/app/components/base/chat/chat/answer/human-input-content/__tests__/executed-action.spec.tsx index 3f2e6e4beb..8c24209a0b 100644 --- a/web/app/components/base/chat/chat/answer/human-input-content/executed-action.spec.tsx +++ b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/executed-action.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import { describe, expect, it } from 'vitest' -import ExecutedAction from './executed-action' +import ExecutedAction from '../executed-action' describe('ExecutedAction', () => { it('should render the triggered action information', () => { diff --git a/web/app/components/base/chat/chat/answer/human-input-content/expiration-time.spec.tsx b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/expiration-time.spec.tsx similarity index 87% rename from web/app/components/base/chat/chat/answer/human-input-content/expiration-time.spec.tsx rename to web/app/components/base/chat/chat/answer/human-input-content/__tests__/expiration-time.spec.tsx index fdf3a3244b..b2ed03e71c 100644 --- a/web/app/components/base/chat/chat/answer/human-input-content/expiration-time.spec.tsx +++ b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/expiration-time.spec.tsx @@ -1,11 +1,11 @@ import { render, screen } from '@testing-library/react' import { describe, expect, it, vi } from 'vitest' -import ExpirationTime from './expiration-time' -import * as utils from './utils' +import ExpirationTime from '../expiration-time' +import * as utils from '../utils' // Mock utils to control time-based logic -vi.mock('./utils', async (importOriginal) => { - const actual = await importOriginal() +vi.mock('../utils', async (importOriginal) => { + const actual = await importOriginal() return { ...actual, getRelativeTime: vi.fn(), diff --git a/web/app/components/base/chat/chat/answer/human-input-content/human-input-form.spec.tsx b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/human-input-form.spec.tsx similarity index 98% rename from web/app/components/base/chat/chat/answer/human-input-content/human-input-form.spec.tsx rename to web/app/components/base/chat/chat/answer/human-input-content/__tests__/human-input-form.spec.tsx index e9d6fdee3c..89ba71b2d9 100644 --- a/web/app/components/base/chat/chat/answer/human-input-content/human-input-form.spec.tsx +++ b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/human-input-form.spec.tsx @@ -4,9 +4,9 @@ import { act, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' import { UserActionButtonType } from '@/app/components/workflow/nodes/human-input/types' -import HumanInputForm from './human-input-form' +import HumanInputForm from '../human-input-form' -vi.mock('./content-item', () => ({ +vi.mock('../content-item', () => ({ default: ({ content, onInputChange }: { content: string, onInputChange: (name: string, value: string) => void }) => (
{content} diff --git a/web/app/components/base/chat/chat/answer/human-input-content/submitted-content.spec.tsx b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/submitted-content.spec.tsx similarity index 92% rename from web/app/components/base/chat/chat/answer/human-input-content/submitted-content.spec.tsx rename to web/app/components/base/chat/chat/answer/human-input-content/__tests__/submitted-content.spec.tsx index f56b081370..172c1238a7 100644 --- a/web/app/components/base/chat/chat/answer/human-input-content/submitted-content.spec.tsx +++ b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/submitted-content.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import { describe, expect, it, vi } from 'vitest' -import SubmittedContent from './submitted-content' +import SubmittedContent from '../submitted-content' vi.mock('@/app/components/base/markdown', () => ({ Markdown: ({ content }: { content: string }) =>
{content}
, diff --git a/web/app/components/base/chat/chat/answer/human-input-content/submitted.spec.tsx b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/submitted.spec.tsx similarity index 95% rename from web/app/components/base/chat/chat/answer/human-input-content/submitted.spec.tsx rename to web/app/components/base/chat/chat/answer/human-input-content/__tests__/submitted.spec.tsx index 3ea4a25fcd..69f5054704 100644 --- a/web/app/components/base/chat/chat/answer/human-input-content/submitted.spec.tsx +++ b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/submitted.spec.tsx @@ -1,7 +1,7 @@ import type { HumanInputFilledFormData } from '@/types/workflow' import { render, screen } from '@testing-library/react' import { describe, expect, it, vi } from 'vitest' -import { SubmittedHumanInputContent } from './submitted' +import { SubmittedHumanInputContent } from '../submitted' vi.mock('@/app/components/base/markdown', () => ({ Markdown: ({ content }: { content: string }) =>
{content}
, diff --git a/web/app/components/base/chat/chat/answer/human-input-content/tips.spec.tsx b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/tips.spec.tsx similarity index 98% rename from web/app/components/base/chat/chat/answer/human-input-content/tips.spec.tsx rename to web/app/components/base/chat/chat/answer/human-input-content/__tests__/tips.spec.tsx index 44a92f0e0b..2c212fe3fa 100644 --- a/web/app/components/base/chat/chat/answer/human-input-content/tips.spec.tsx +++ b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/tips.spec.tsx @@ -2,7 +2,7 @@ import type { AppContextValue } from '@/context/app-context' import { render, screen } from '@testing-library/react' import { describe, expect, it, vi } from 'vitest' import { useSelector } from '@/context/app-context' -import Tips from './tips' +import Tips from '../tips' // Mock AppContext's useSelector to control user profile data vi.mock('@/context/app-context', async (importOriginal) => { diff --git a/web/app/components/base/chat/chat/answer/human-input-content/unsubmitted.spec.tsx b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/unsubmitted.spec.tsx similarity index 99% rename from web/app/components/base/chat/chat/answer/human-input-content/unsubmitted.spec.tsx rename to web/app/components/base/chat/chat/answer/human-input-content/__tests__/unsubmitted.spec.tsx index 192b4f08b4..046890157b 100644 --- a/web/app/components/base/chat/chat/answer/human-input-content/unsubmitted.spec.tsx +++ b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/unsubmitted.spec.tsx @@ -6,7 +6,7 @@ import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' import { UserActionButtonType } from '@/app/components/workflow/nodes/human-input/types' import { useSelector } from '@/context/app-context' -import { UnsubmittedHumanInputContent } from './unsubmitted' +import { UnsubmittedHumanInputContent } from '../unsubmitted' // Mock AppContext's useSelector to control user profile data vi.mock('@/context/app-context', async (importOriginal) => { diff --git a/web/app/components/base/chat/chat/chat-input-area/index.spec.tsx b/web/app/components/base/chat/chat/chat-input-area/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/chat/chat/chat-input-area/index.spec.tsx rename to web/app/components/base/chat/chat/chat-input-area/__tests__/index.spec.tsx index 11827f5291..a6d4570fcb 100644 --- a/web/app/components/base/chat/chat/chat-input-area/index.spec.tsx +++ b/web/app/components/base/chat/chat/chat-input-area/__tests__/index.spec.tsx @@ -5,7 +5,7 @@ import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import * as React from 'react' import { vi } from 'vitest' -import ChatInputArea from './index' +import ChatInputArea from '../index' // --------------------------------------------------------------------------- // Hoist shared mock references so they are available inside vi.mock factories @@ -106,7 +106,7 @@ vi.mock('@/app/components/base/toast', async () => { // --------------------------------------------------------------------------- let mockIsMultipleLine = false -vi.mock('./hooks', () => ({ +vi.mock('../hooks', () => ({ useTextAreaHeight: () => ({ wrapperRef: { current: document.createElement('div') }, textareaRef: { current: document.createElement('textarea') }, @@ -122,7 +122,7 @@ vi.mock('./hooks', () => ({ // --------------------------------------------------------------------------- // Input-forms validation hook – always passes by default // --------------------------------------------------------------------------- -vi.mock('../check-input-forms-hooks', () => ({ +vi.mock('../../check-input-forms-hooks', () => ({ useCheckInputsForms: () => ({ checkInputsForm: vi.fn().mockReturnValue(true), }), diff --git a/web/app/components/base/chat/chat/chat-input-area/operation.spec.tsx b/web/app/components/base/chat/chat/chat-input-area/__tests__/operation.spec.tsx similarity index 96% rename from web/app/components/base/chat/chat/chat-input-area/operation.spec.tsx rename to web/app/components/base/chat/chat/chat-input-area/__tests__/operation.spec.tsx index 914811015f..096b18d047 100644 --- a/web/app/components/base/chat/chat/chat-input-area/operation.spec.tsx +++ b/web/app/components/base/chat/chat/chat-input-area/__tests__/operation.spec.tsx @@ -1,9 +1,9 @@ -import type { EnableType } from '../../types' +import type { EnableType } from '../../../types' import type { FileUpload } from '@/app/components/base/features/types' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { Theme } from '../../embedded-chatbot/theme/theme-context' -import Operation from './operation' +import { Theme } from '../../../embedded-chatbot/theme/theme-context' +import Operation from '../operation' vi.mock('@/app/components/base/file-uploader', () => ({ FileUploaderInChatInput: ({ readonly }: { readonly?: boolean }) => ( diff --git a/web/app/components/base/chat/chat/citation/index.spec.tsx b/web/app/components/base/chat/chat/citation/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/chat/chat/citation/index.spec.tsx rename to web/app/components/base/chat/chat/citation/__tests__/index.spec.tsx index dbf90d005c..affd473538 100644 --- a/web/app/components/base/chat/chat/citation/index.spec.tsx +++ b/web/app/components/base/chat/chat/citation/__tests__/index.spec.tsx @@ -1,10 +1,10 @@ -import type { CitationItem } from '../type' +import type { CitationItem } from '../../type' import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest' -import Citation from './index' +import Citation from '../index' -vi.mock('./popup', () => ({ +vi.mock('../popup', () => ({ default: ({ data, showHitInfo }: { data: { documentName: string }, showHitInfo?: boolean }) => (
{data.documentName} diff --git a/web/app/components/base/chat/chat/citation/popup.spec.tsx b/web/app/components/base/chat/chat/citation/__tests__/popup.spec.tsx similarity index 99% rename from web/app/components/base/chat/chat/citation/popup.spec.tsx rename to web/app/components/base/chat/chat/citation/__tests__/popup.spec.tsx index 4e211eafed..69304ffb59 100644 --- a/web/app/components/base/chat/chat/citation/popup.spec.tsx +++ b/web/app/components/base/chat/chat/citation/__tests__/popup.spec.tsx @@ -1,11 +1,11 @@ -import type { Resources } from './index' +import type { Resources } from '../index' import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { beforeEach, describe, expect, it, vi } from 'vitest' import { useDocumentDownload } from '@/service/knowledge/use-document' import { downloadUrl } from '@/utils/download' -import Popup from './popup' +import Popup from '../popup' vi.mock('@/service/knowledge/use-document', () => ({ useDocumentDownload: vi.fn(), @@ -19,11 +19,11 @@ vi.mock('@/app/components/base/file-icon', () => ({ default: ({ type }: { type: string }) =>
, })) -vi.mock('./progress-tooltip', () => ({ +vi.mock('../progress-tooltip', () => ({ default: ({ data }: { data: number }) =>
{data}
, })) -vi.mock('./tooltip', () => ({ +vi.mock('../tooltip', () => ({ default: ({ text, data }: { text: string, data: number | string }) => (
{data}
), diff --git a/web/app/components/base/chat/chat/citation/progress-tooltip.spec.tsx b/web/app/components/base/chat/chat/citation/__tests__/progress-tooltip.spec.tsx similarity index 99% rename from web/app/components/base/chat/chat/citation/progress-tooltip.spec.tsx rename to web/app/components/base/chat/chat/citation/__tests__/progress-tooltip.spec.tsx index a24c60c614..a47123aafd 100644 --- a/web/app/components/base/chat/chat/citation/progress-tooltip.spec.tsx +++ b/web/app/components/base/chat/chat/citation/__tests__/progress-tooltip.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import ProgressTooltip from './progress-tooltip' +import ProgressTooltip from '../progress-tooltip' describe('ProgressTooltip', () => { describe('Rendering', () => { diff --git a/web/app/components/base/chat/chat/citation/tooltip.spec.tsx b/web/app/components/base/chat/chat/citation/__tests__/tooltip.spec.tsx similarity index 99% rename from web/app/components/base/chat/chat/citation/tooltip.spec.tsx rename to web/app/components/base/chat/chat/citation/__tests__/tooltip.spec.tsx index d5c1b57d76..45ac4b4fb4 100644 --- a/web/app/components/base/chat/chat/citation/tooltip.spec.tsx +++ b/web/app/components/base/chat/chat/citation/__tests__/tooltip.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it } from 'vitest' -import Tooltip from './tooltip' +import Tooltip from '../tooltip' const renderTooltip = (data: number | string = 42, text = 'Characters', icon = icon) => render() diff --git a/web/app/components/base/chat/chat/loading-anim/index.spec.tsx b/web/app/components/base/chat/chat/loading-anim/__tests__/index.spec.tsx similarity index 95% rename from web/app/components/base/chat/chat/loading-anim/index.spec.tsx rename to web/app/components/base/chat/chat/loading-anim/__tests__/index.spec.tsx index ddba3e38ca..48005f6949 100644 --- a/web/app/components/base/chat/chat/loading-anim/index.spec.tsx +++ b/web/app/components/base/chat/chat/loading-anim/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render } from '@testing-library/react' -import LoadingAnim from './index' +import LoadingAnim from '../index' describe('LoadingAnim', () => { it('should render correctly with text type', () => { diff --git a/web/app/components/base/chat/chat/log/index.spec.tsx b/web/app/components/base/chat/chat/log/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/chat/chat/log/index.spec.tsx rename to web/app/components/base/chat/chat/log/__tests__/index.spec.tsx index b74195bccb..b59f439f16 100644 --- a/web/app/components/base/chat/chat/log/index.spec.tsx +++ b/web/app/components/base/chat/chat/log/__tests__/index.spec.tsx @@ -3,7 +3,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { vi } from 'vitest' import { useStore as useAppStore } from '@/app/components/app/store' -import Log from './index' +import Log from '../index' vi.mock('@/app/components/app/store', () => ({ useStore: vi.fn(), diff --git a/web/app/components/base/chat/chat/thought/index.spec.tsx b/web/app/components/base/chat/chat/thought/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/chat/chat/thought/index.spec.tsx rename to web/app/components/base/chat/chat/thought/__tests__/index.spec.tsx index d6a2993f0a..8a4ea5717d 100644 --- a/web/app/components/base/chat/chat/thought/index.spec.tsx +++ b/web/app/components/base/chat/chat/thought/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ -import type { ThoughtItem } from '../type' +import type { ThoughtItem } from '../../type' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import Thought from './index' +import Thought from '../index' describe('Thought', () => { const createThought = (overrides?: Partial): ThoughtItem => ({ diff --git a/web/app/components/base/chat/embedded-chatbot/chat-wrapper.spec.tsx b/web/app/components/base/chat/embedded-chatbot/__tests__/chat-wrapper.spec.tsx similarity index 97% rename from web/app/components/base/chat/embedded-chatbot/chat-wrapper.spec.tsx rename to web/app/components/base/chat/embedded-chatbot/__tests__/chat-wrapper.spec.tsx index d0b23627f0..b9485bde60 100644 --- a/web/app/components/base/chat/embedded-chatbot/chat-wrapper.spec.tsx +++ b/web/app/components/base/chat/embedded-chatbot/__tests__/chat-wrapper.spec.tsx @@ -1,5 +1,5 @@ -import type { ChatConfig, ChatItem, ChatItemInTree } from '../types' -import type { EmbeddedChatbotContextValue } from './context' +import type { ChatConfig, ChatItem, ChatItemInTree } from '../../types' +import type { EmbeddedChatbotContextValue } from '../context' import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react' import { vi } from 'vitest' import { InputVarType } from '@/app/components/workflow/types' @@ -9,24 +9,24 @@ import { submitHumanInputForm, } from '@/service/share' import { submitHumanInputForm as submitHumanInputFormService } from '@/service/workflow' -import { useChat } from '../chat/hooks' -import ChatWrapper from './chat-wrapper' -import { useEmbeddedChatbotContext } from './context' +import { useChat } from '../../chat/hooks' +import ChatWrapper from '../chat-wrapper' +import { useEmbeddedChatbotContext } from '../context' -vi.mock('./context', () => ({ +vi.mock('../context', () => ({ useEmbeddedChatbotContext: vi.fn(), })) -vi.mock('../chat/hooks', () => ({ +vi.mock('../../chat/hooks', () => ({ useChat: vi.fn(), })) -vi.mock('./inputs-form', () => ({ +vi.mock('../inputs-form', () => ({ __esModule: true, default: () =>
inputs form
, })) -vi.mock('../chat', () => ({ +vi.mock('../../chat', () => ({ __esModule: true, default: ({ chatNode, @@ -87,7 +87,7 @@ vi.mock('@/service/workflow', () => ({ })) const mockIsDify = vi.fn(() => false) -vi.mock('./utils', () => ({ +vi.mock('../utils', () => ({ isDify: () => mockIsDify(), })) diff --git a/web/app/components/base/chat/embedded-chatbot/hooks.spec.tsx b/web/app/components/base/chat/embedded-chatbot/__tests__/hooks.spec.tsx similarity index 97% rename from web/app/components/base/chat/embedded-chatbot/hooks.spec.tsx rename to web/app/components/base/chat/embedded-chatbot/__tests__/hooks.spec.tsx index 06563832f1..9a3340b2af 100644 --- a/web/app/components/base/chat/embedded-chatbot/hooks.spec.tsx +++ b/web/app/components/base/chat/embedded-chatbot/__tests__/hooks.spec.tsx @@ -1,5 +1,5 @@ import type { ReactNode } from 'react' -import type { ChatConfig } from '../types' +import type { ChatConfig } from '../../types' import type { AppConversationData, AppData, AppMeta, ConversationItem } from '@/models/share' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { act, renderHook, waitFor } from '@testing-library/react' @@ -11,8 +11,8 @@ import { generationConversationName, } from '@/service/share' import { shareQueryKeys } from '@/service/use-share' -import { CONVERSATION_ID_INFO } from '../constants' -import { useEmbeddedChatbot } from './hooks' +import { CONVERSATION_ID_INFO } from '../../constants' +import { useEmbeddedChatbot } from '../hooks' vi.mock('@/i18n-config/client', () => ({ changeLanguage: vi.fn().mockResolvedValue(undefined), @@ -40,8 +40,8 @@ vi.mock('@/context/web-app-context', () => ({ useWebAppStore: (selector?: (state: typeof mockStoreState) => unknown) => useWebAppStoreMock(selector), })) -vi.mock('../utils', async () => { - const actual = await vi.importActual('../utils') +vi.mock('../../utils', async () => { + const actual = await vi.importActual('../../utils') return { ...actual, getProcessedInputsFromUrlParams: vi.fn().mockResolvedValue({}), diff --git a/web/app/components/base/chat/embedded-chatbot/index.spec.tsx b/web/app/components/base/chat/embedded-chatbot/__tests__/index.spec.tsx similarity index 95% rename from web/app/components/base/chat/embedded-chatbot/index.spec.tsx rename to web/app/components/base/chat/embedded-chatbot/__tests__/index.spec.tsx index 48fe16f7b3..a87c206412 100644 --- a/web/app/components/base/chat/embedded-chatbot/index.spec.tsx +++ b/web/app/components/base/chat/embedded-chatbot/__tests__/index.spec.tsx @@ -1,15 +1,15 @@ import type { RefObject } from 'react' -import type { ChatConfig } from '../types' +import type { ChatConfig } from '../../types' import type { AppData, AppMeta, ConversationItem } from '@/models/share' import { render, screen } from '@testing-library/react' import { vi } from 'vitest' import { useGlobalPublicStore } from '@/context/global-public-context' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import { defaultSystemFeatures } from '@/types/feature' -import { useEmbeddedChatbot } from './hooks' -import EmbeddedChatbot from './index' +import { useEmbeddedChatbot } from '../hooks' +import EmbeddedChatbot from '../index' -vi.mock('./hooks', () => ({ +vi.mock('../hooks', () => ({ useEmbeddedChatbot: vi.fn(), })) @@ -30,17 +30,17 @@ vi.mock('@/context/global-public-context', () => ({ useGlobalPublicStore: vi.fn(), })) -vi.mock('./chat-wrapper', () => ({ +vi.mock('../chat-wrapper', () => ({ __esModule: true, default: () =>
chat area
, })) -vi.mock('./header', () => ({ +vi.mock('../header', () => ({ __esModule: true, default: () =>
chat header
, })) -vi.mock('./theme/theme-context', () => ({ +vi.mock('../theme/theme-context', () => ({ useThemeContext: vi.fn(() => ({ buildTheme: vi.fn(), theme: { @@ -50,7 +50,7 @@ vi.mock('./theme/theme-context', () => ({ })) const mockIsDify = vi.fn(() => false) -vi.mock('./utils', () => ({ +vi.mock('../utils', () => ({ isDify: () => mockIsDify(), })) diff --git a/web/app/components/base/chat/embedded-chatbot/header/index.spec.tsx b/web/app/components/base/chat/embedded-chatbot/header/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/chat/embedded-chatbot/header/index.spec.tsx rename to web/app/components/base/chat/embedded-chatbot/header/__tests__/index.spec.tsx index 31323c7196..0ebcc647ac 100644 --- a/web/app/components/base/chat/embedded-chatbot/header/index.spec.tsx +++ b/web/app/components/base/chat/embedded-chatbot/header/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ /* eslint-disable next/no-img-element */ import type { ImgHTMLAttributes } from 'react' -import type { EmbeddedChatbotContextValue } from '../context' +import type { EmbeddedChatbotContextValue } from '../../context' import type { AppData } from '@/models/share' import type { SystemFeatures } from '@/types/feature' import { render, screen, waitFor } from '@testing-library/react' @@ -8,10 +8,10 @@ import userEvent from '@testing-library/user-event' import { vi } from 'vitest' import { useGlobalPublicStore } from '@/context/global-public-context' import { InstallationScope, LicenseStatus } from '@/types/feature' -import { useEmbeddedChatbotContext } from '../context' -import Header from './index' +import { useEmbeddedChatbotContext } from '../../context' +import Header from '../index' -vi.mock('../context', () => ({ +vi.mock('../../context', () => ({ useEmbeddedChatbotContext: vi.fn(), })) diff --git a/web/app/components/base/chat/embedded-chatbot/inputs-form/content.spec.tsx b/web/app/components/base/chat/embedded-chatbot/inputs-form/__tests__/content.spec.tsx similarity index 98% rename from web/app/components/base/chat/embedded-chatbot/inputs-form/content.spec.tsx rename to web/app/components/base/chat/embedded-chatbot/inputs-form/__tests__/content.spec.tsx index de7f810fcb..08c9a035e7 100644 --- a/web/app/components/base/chat/embedded-chatbot/inputs-form/content.spec.tsx +++ b/web/app/components/base/chat/embedded-chatbot/inputs-form/__tests__/content.spec.tsx @@ -2,10 +2,10 @@ import { fireEvent, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { InputVarType } from '@/app/components/workflow/types' -import { useEmbeddedChatbotContext } from '../context' -import InputsFormContent from './content' +import { useEmbeddedChatbotContext } from '../../context' +import InputsFormContent from '../content' -vi.mock('../context', () => ({ +vi.mock('../../context', () => ({ useEmbeddedChatbotContext: vi.fn(), })) diff --git a/web/app/components/base/chat/embedded-chatbot/inputs-form/index.spec.tsx b/web/app/components/base/chat/embedded-chatbot/inputs-form/__tests__/index.spec.tsx similarity index 96% rename from web/app/components/base/chat/embedded-chatbot/inputs-form/index.spec.tsx rename to web/app/components/base/chat/embedded-chatbot/inputs-form/__tests__/index.spec.tsx index 7568f606df..7ffedc581a 100644 --- a/web/app/components/base/chat/embedded-chatbot/inputs-form/index.spec.tsx +++ b/web/app/components/base/chat/embedded-chatbot/inputs-form/__tests__/index.spec.tsx @@ -2,15 +2,15 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { AppSourceType } from '@/service/share' -import { useEmbeddedChatbotContext } from '../context' -import InputsFormNode from './index' +import { useEmbeddedChatbotContext } from '../../context' +import InputsFormNode from '../index' -vi.mock('../context', () => ({ +vi.mock('../../context', () => ({ useEmbeddedChatbotContext: vi.fn(), })) // Mock InputsFormContent to avoid complex integration in this test -vi.mock('./content', () => ({ +vi.mock('../content', () => ({ default: () =>
, })) diff --git a/web/app/components/base/chat/embedded-chatbot/inputs-form/view-form-dropdown.spec.tsx b/web/app/components/base/chat/embedded-chatbot/inputs-form/__tests__/view-form-dropdown.spec.tsx similarity index 95% rename from web/app/components/base/chat/embedded-chatbot/inputs-form/view-form-dropdown.spec.tsx rename to web/app/components/base/chat/embedded-chatbot/inputs-form/__tests__/view-form-dropdown.spec.tsx index 9f7fa727fd..8e0ddedbe7 100644 --- a/web/app/components/base/chat/embedded-chatbot/inputs-form/view-form-dropdown.spec.tsx +++ b/web/app/components/base/chat/embedded-chatbot/inputs-form/__tests__/view-form-dropdown.spec.tsx @@ -1,9 +1,9 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import ViewFormDropdown from './view-form-dropdown' +import ViewFormDropdown from '../view-form-dropdown' // Mock InputsFormContent to avoid complex integration in this test -vi.mock('./content', () => ({ +vi.mock('../content', () => ({ default: () =>
, })) diff --git a/web/app/components/base/checkbox-list/index.spec.tsx b/web/app/components/base/checkbox-list/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/checkbox-list/index.spec.tsx rename to web/app/components/base/checkbox-list/__tests__/index.spec.tsx index 59ddfb69fc..17f3704666 100644 --- a/web/app/components/base/checkbox-list/index.spec.tsx +++ b/web/app/components/base/checkbox-list/__tests__/index.spec.tsx @@ -2,7 +2,7 @@ import type { ImgHTMLAttributes } from 'react' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import CheckboxList from '.' +import CheckboxList from '..' vi.mock('next/image', () => ({ default: (props: ImgHTMLAttributes) => , diff --git a/web/app/components/base/checkbox/index.spec.tsx b/web/app/components/base/checkbox/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/checkbox/index.spec.tsx rename to web/app/components/base/checkbox/__tests__/index.spec.tsx index e817f05afd..551f29c854 100644 --- a/web/app/components/base/checkbox/index.spec.tsx +++ b/web/app/components/base/checkbox/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import Checkbox from './index' +import Checkbox from '../index' describe('Checkbox Component', () => { const mockProps = { diff --git a/web/app/components/base/checkbox/assets/indeterminate-icon.spec.tsx b/web/app/components/base/checkbox/assets/__tests__/indeterminate-icon.spec.tsx similarity index 90% rename from web/app/components/base/checkbox/assets/indeterminate-icon.spec.tsx rename to web/app/components/base/checkbox/assets/__tests__/indeterminate-icon.spec.tsx index 3f39dd836f..e226562da7 100644 --- a/web/app/components/base/checkbox/assets/indeterminate-icon.spec.tsx +++ b/web/app/components/base/checkbox/assets/__tests__/indeterminate-icon.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import IndeterminateIcon from './indeterminate-icon' +import IndeterminateIcon from '../indeterminate-icon' describe('IndeterminateIcon', () => { describe('Rendering', () => { diff --git a/web/app/components/base/chip/index.spec.tsx b/web/app/components/base/chip/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/chip/index.spec.tsx rename to web/app/components/base/chip/__tests__/index.spec.tsx index c19cc77b39..24c04b51a5 100644 --- a/web/app/components/base/chip/index.spec.tsx +++ b/web/app/components/base/chip/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ -import type { Item } from './index' +import type { Item } from '../index' import { cleanup, fireEvent, render, screen } from '@testing-library/react' import * as React from 'react' -import Chip from './index' +import Chip from '../index' afterEach(cleanup) diff --git a/web/app/components/base/confirm/index.spec.tsx b/web/app/components/base/confirm/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/confirm/index.spec.tsx rename to web/app/components/base/confirm/__tests__/index.spec.tsx index c2f67cc35e..29be2d617e 100644 --- a/web/app/components/base/confirm/index.spec.tsx +++ b/web/app/components/base/confirm/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { act, fireEvent, render, screen } from '@testing-library/react' -import Confirm from '.' +import Confirm from '..' vi.mock('react-dom', async () => { const actual = await vi.importActual('react-dom') diff --git a/web/app/components/base/content-dialog/index.spec.tsx b/web/app/components/base/content-dialog/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/content-dialog/index.spec.tsx rename to web/app/components/base/content-dialog/__tests__/index.spec.tsx index a047fdf062..e987d306a1 100644 --- a/web/app/components/base/content-dialog/index.spec.tsx +++ b/web/app/components/base/content-dialog/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import ContentDialog from './index' +import ContentDialog from '../index' describe('ContentDialog', () => { it('renders children when show is true', async () => { diff --git a/web/app/components/base/copy-feedback/index.spec.tsx b/web/app/components/base/copy-feedback/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/copy-feedback/index.spec.tsx rename to web/app/components/base/copy-feedback/__tests__/index.spec.tsx index f89331c1bb..a7bc5bbbc2 100644 --- a/web/app/components/base/copy-feedback/index.spec.tsx +++ b/web/app/components/base/copy-feedback/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import CopyFeedback, { CopyFeedbackNew } from '.' +import CopyFeedback, { CopyFeedbackNew } from '..' const mockCopy = vi.fn() const mockReset = vi.fn() diff --git a/web/app/components/base/copy-icon/index.spec.tsx b/web/app/components/base/copy-icon/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/copy-icon/index.spec.tsx rename to web/app/components/base/copy-icon/__tests__/index.spec.tsx index b4cf192174..f25f0940c6 100644 --- a/web/app/components/base/copy-icon/index.spec.tsx +++ b/web/app/components/base/copy-icon/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render } from '@testing-library/react' -import CopyIcon from '.' +import CopyIcon from '..' const copy = vi.fn() const reset = vi.fn() diff --git a/web/app/components/base/corner-label/index.spec.tsx b/web/app/components/base/corner-label/__tests__/index.spec.tsx similarity index 95% rename from web/app/components/base/corner-label/index.spec.tsx rename to web/app/components/base/corner-label/__tests__/index.spec.tsx index 479eaeff0d..11a2c0c877 100644 --- a/web/app/components/base/corner-label/index.spec.tsx +++ b/web/app/components/base/corner-label/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import CornerLabel from '.' +import CornerLabel from '..' describe('CornerLabel', () => { it('renders the label correctly', () => { diff --git a/web/app/components/base/date-and-time-picker/hooks.spec.ts b/web/app/components/base/date-and-time-picker/__tests__/hooks.spec.ts similarity index 97% rename from web/app/components/base/date-and-time-picker/hooks.spec.ts rename to web/app/components/base/date-and-time-picker/__tests__/hooks.spec.ts index c3675b9d84..3595cb6600 100644 --- a/web/app/components/base/date-and-time-picker/hooks.spec.ts +++ b/web/app/components/base/date-and-time-picker/__tests__/hooks.spec.ts @@ -1,7 +1,7 @@ import { renderHook } from '@testing-library/react' -import { useDaysOfWeek, useMonths, useTimeOptions, useYearOptions } from './hooks' -import { Period } from './types' -import dayjs from './utils/dayjs' +import { useDaysOfWeek, useMonths, useTimeOptions, useYearOptions } from '../hooks' +import { Period } from '../types' +import dayjs from '../utils/dayjs' describe('date-and-time-picker hooks', () => { // Tests for useDaysOfWeek hook diff --git a/web/app/components/base/date-and-time-picker/calendar/days-of-week.spec.tsx b/web/app/components/base/date-and-time-picker/calendar/__tests__/days-of-week.spec.tsx similarity index 93% rename from web/app/components/base/date-and-time-picker/calendar/days-of-week.spec.tsx rename to web/app/components/base/date-and-time-picker/calendar/__tests__/days-of-week.spec.tsx index 334b6fdbe9..44d79c1fee 100644 --- a/web/app/components/base/date-and-time-picker/calendar/days-of-week.spec.tsx +++ b/web/app/components/base/date-and-time-picker/calendar/__tests__/days-of-week.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import { DaysOfWeek } from './days-of-week' +import { DaysOfWeek } from '../days-of-week' describe('DaysOfWeek', () => { // Rendering test diff --git a/web/app/components/base/date-and-time-picker/calendar/index.spec.tsx b/web/app/components/base/date-and-time-picker/calendar/__tests__/index.spec.tsx similarity index 96% rename from web/app/components/base/date-and-time-picker/calendar/index.spec.tsx rename to web/app/components/base/date-and-time-picker/calendar/__tests__/index.spec.tsx index 51104864bb..d8e00780b1 100644 --- a/web/app/components/base/date-and-time-picker/calendar/index.spec.tsx +++ b/web/app/components/base/date-and-time-picker/calendar/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ -import type { CalendarProps, Day } from '../types' +import type { CalendarProps, Day } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' -import dayjs from '../utils/dayjs' -import Calendar from './index' +import dayjs from '../../utils/dayjs' +import Calendar from '../index' // Mock scrollIntoView since jsdom doesn't implement it beforeAll(() => { diff --git a/web/app/components/base/date-and-time-picker/calendar/item.spec.tsx b/web/app/components/base/date-and-time-picker/calendar/__tests__/item.spec.tsx similarity index 97% rename from web/app/components/base/date-and-time-picker/calendar/item.spec.tsx rename to web/app/components/base/date-and-time-picker/calendar/__tests__/item.spec.tsx index 7fcfcaae1f..8bf8ac68b5 100644 --- a/web/app/components/base/date-and-time-picker/calendar/item.spec.tsx +++ b/web/app/components/base/date-and-time-picker/calendar/__tests__/item.spec.tsx @@ -1,7 +1,7 @@ -import type { CalendarItemProps, Day } from '../types' +import type { CalendarItemProps, Day } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' -import dayjs from '../utils/dayjs' -import Item from './item' +import dayjs from '../../utils/dayjs' +import Item from '../item' const createMockDay = (overrides: Partial = {}): Day => ({ date: dayjs('2024-06-15'), diff --git a/web/app/components/base/date-and-time-picker/common/option-list-item.spec.tsx b/web/app/components/base/date-and-time-picker/common/__tests__/option-list-item.spec.tsx similarity index 98% rename from web/app/components/base/date-and-time-picker/common/option-list-item.spec.tsx rename to web/app/components/base/date-and-time-picker/common/__tests__/option-list-item.spec.tsx index 760ba62ddc..8ccf8fab73 100644 --- a/web/app/components/base/date-and-time-picker/common/option-list-item.spec.tsx +++ b/web/app/components/base/date-and-time-picker/common/__tests__/option-list-item.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import OptionListItem from './option-list-item' +import OptionListItem from '../option-list-item' describe('OptionListItem', () => { let originalScrollIntoView: Element['scrollIntoView'] diff --git a/web/app/components/base/date-and-time-picker/date-picker/footer.spec.tsx b/web/app/components/base/date-and-time-picker/date-picker/__tests__/footer.spec.tsx similarity index 96% rename from web/app/components/base/date-and-time-picker/date-picker/footer.spec.tsx rename to web/app/components/base/date-and-time-picker/date-picker/__tests__/footer.spec.tsx index c164044484..b7ada71ca2 100644 --- a/web/app/components/base/date-and-time-picker/date-picker/footer.spec.tsx +++ b/web/app/components/base/date-and-time-picker/date-picker/__tests__/footer.spec.tsx @@ -1,7 +1,7 @@ -import type { DatePickerFooterProps } from '../types' +import type { DatePickerFooterProps } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' -import { ViewType } from '../types' -import Footer from './footer' +import { ViewType } from '../../types' +import Footer from '../footer' // Factory for Footer props const createFooterProps = (overrides: Partial = {}): DatePickerFooterProps => ({ diff --git a/web/app/components/base/date-and-time-picker/date-picker/header.spec.tsx b/web/app/components/base/date-and-time-picker/date-picker/__tests__/header.spec.tsx similarity index 95% rename from web/app/components/base/date-and-time-picker/date-picker/header.spec.tsx rename to web/app/components/base/date-and-time-picker/date-picker/__tests__/header.spec.tsx index 353b662eeb..dedb2ef68d 100644 --- a/web/app/components/base/date-and-time-picker/date-picker/header.spec.tsx +++ b/web/app/components/base/date-and-time-picker/date-picker/__tests__/header.spec.tsx @@ -1,7 +1,7 @@ -import type { DatePickerHeaderProps } from '../types' +import type { DatePickerHeaderProps } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' -import dayjs from '../utils/dayjs' -import Header from './header' +import dayjs from '../../utils/dayjs' +import Header from '../header' // Factory for Header props const createHeaderProps = (overrides: Partial = {}): DatePickerHeaderProps => ({ diff --git a/web/app/components/base/date-and-time-picker/date-picker/index.spec.tsx b/web/app/components/base/date-and-time-picker/date-picker/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/date-and-time-picker/date-picker/index.spec.tsx rename to web/app/components/base/date-and-time-picker/date-picker/__tests__/index.spec.tsx index 26ca3db1e1..5760a301dc 100644 --- a/web/app/components/base/date-and-time-picker/date-picker/index.spec.tsx +++ b/web/app/components/base/date-and-time-picker/date-picker/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ -import type { DatePickerProps } from '../types' +import type { DatePickerProps } from '../../types' import { act, fireEvent, render, screen, within } from '@testing-library/react' -import dayjs from '../utils/dayjs' -import DatePicker from './index' +import dayjs from '../../utils/dayjs' +import DatePicker from '../index' // Mock scrollIntoView beforeAll(() => { diff --git a/web/app/components/base/date-and-time-picker/time-picker/footer.spec.tsx b/web/app/components/base/date-and-time-picker/time-picker/__tests__/footer.spec.tsx similarity index 94% rename from web/app/components/base/date-and-time-picker/time-picker/footer.spec.tsx rename to web/app/components/base/date-and-time-picker/time-picker/__tests__/footer.spec.tsx index a11e6b94d6..d1060ffcfc 100644 --- a/web/app/components/base/date-and-time-picker/time-picker/footer.spec.tsx +++ b/web/app/components/base/date-and-time-picker/time-picker/__tests__/footer.spec.tsx @@ -1,6 +1,6 @@ -import type { TimePickerFooterProps } from '../types' +import type { TimePickerFooterProps } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' -import Footer from './footer' +import Footer from '../footer' // Factory for TimePickerFooter props const createFooterProps = (overrides: Partial = {}): TimePickerFooterProps => ({ diff --git a/web/app/components/base/date-and-time-picker/time-picker/header.spec.tsx b/web/app/components/base/date-and-time-picker/time-picker/__tests__/header.spec.tsx similarity index 96% rename from web/app/components/base/date-and-time-picker/time-picker/header.spec.tsx rename to web/app/components/base/date-and-time-picker/time-picker/__tests__/header.spec.tsx index 7f9872ff0f..afdadfda13 100644 --- a/web/app/components/base/date-and-time-picker/time-picker/header.spec.tsx +++ b/web/app/components/base/date-and-time-picker/time-picker/__tests__/header.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import Header from './header' +import Header from '../header' describe('TimePicker Header', () => { beforeEach(() => { diff --git a/web/app/components/base/date-and-time-picker/time-picker/index.spec.tsx b/web/app/components/base/date-and-time-picker/time-picker/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/date-and-time-picker/time-picker/index.spec.tsx rename to web/app/components/base/date-and-time-picker/time-picker/__tests__/index.spec.tsx index ee4e08f988..81e065c827 100644 --- a/web/app/components/base/date-and-time-picker/time-picker/index.spec.tsx +++ b/web/app/components/base/date-and-time-picker/time-picker/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ -import type { TimePickerProps } from '../types' +import type { TimePickerProps } from '../../types' import { fireEvent, render, screen, within } from '@testing-library/react' -import dayjs, { isDayjsObject } from '../utils/dayjs' -import TimePicker from './index' +import dayjs, { isDayjsObject } from '../../utils/dayjs' +import TimePicker from '../index' // Mock scrollIntoView since jsdom doesn't implement it beforeAll(() => { diff --git a/web/app/components/base/date-and-time-picker/time-picker/options.spec.tsx b/web/app/components/base/date-and-time-picker/time-picker/__tests__/options.spec.tsx similarity index 96% rename from web/app/components/base/date-and-time-picker/time-picker/options.spec.tsx rename to web/app/components/base/date-and-time-picker/time-picker/__tests__/options.spec.tsx index 9f169eb010..9d945dcf2e 100644 --- a/web/app/components/base/date-and-time-picker/time-picker/options.spec.tsx +++ b/web/app/components/base/date-and-time-picker/time-picker/__tests__/options.spec.tsx @@ -1,7 +1,7 @@ -import type { TimeOptionsProps } from '../types' +import type { TimeOptionsProps } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' -import dayjs from '../utils/dayjs' -import Options from './options' +import dayjs from '../../utils/dayjs' +import Options from '../options' beforeAll(() => { Element.prototype.scrollIntoView = vi.fn() diff --git a/web/app/components/base/date-and-time-picker/utils/dayjs-extended.spec.ts b/web/app/components/base/date-and-time-picker/utils/__tests__/dayjs-extended.spec.ts similarity index 99% rename from web/app/components/base/date-and-time-picker/utils/dayjs-extended.spec.ts rename to web/app/components/base/date-and-time-picker/utils/__tests__/dayjs-extended.spec.ts index a5c80ff35c..f5332e1917 100644 --- a/web/app/components/base/date-and-time-picker/utils/dayjs-extended.spec.ts +++ b/web/app/components/base/date-and-time-picker/utils/__tests__/dayjs-extended.spec.ts @@ -7,7 +7,7 @@ import dayjs, { getHourIn12Hour, parseDateWithFormat, toDayjs, -} from './dayjs' +} from '../dayjs' describe('dayjs extended utilities', () => { // Tests for cloneTime diff --git a/web/app/components/base/date-and-time-picker/utils/dayjs.spec.ts b/web/app/components/base/date-and-time-picker/utils/__tests__/dayjs.spec.ts similarity index 99% rename from web/app/components/base/date-and-time-picker/utils/dayjs.spec.ts rename to web/app/components/base/date-and-time-picker/utils/__tests__/dayjs.spec.ts index 5457fa13fb..e36fecd0b6 100644 --- a/web/app/components/base/date-and-time-picker/utils/dayjs.spec.ts +++ b/web/app/components/base/date-and-time-picker/utils/__tests__/dayjs.spec.ts @@ -3,7 +3,7 @@ import dayjs, { getDateWithTimezone, isDayjsObject, toDayjs, -} from './dayjs' +} from '../dayjs' describe('dayjs utilities', () => { const timezone = 'UTC' diff --git a/web/app/components/base/date-and-time-picker/year-and-month-picker/footer.spec.tsx b/web/app/components/base/date-and-time-picker/year-and-month-picker/__tests__/footer.spec.tsx similarity index 94% rename from web/app/components/base/date-and-time-picker/year-and-month-picker/footer.spec.tsx rename to web/app/components/base/date-and-time-picker/year-and-month-picker/__tests__/footer.spec.tsx index 7c3815d22f..f3d69461c9 100644 --- a/web/app/components/base/date-and-time-picker/year-and-month-picker/footer.spec.tsx +++ b/web/app/components/base/date-and-time-picker/year-and-month-picker/__tests__/footer.spec.tsx @@ -1,6 +1,6 @@ -import type { YearAndMonthPickerFooterProps } from '../types' +import type { YearAndMonthPickerFooterProps } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' -import Footer from './footer' +import Footer from '../footer' // Factory for Footer props const createFooterProps = (overrides: Partial = {}): YearAndMonthPickerFooterProps => ({ diff --git a/web/app/components/base/date-and-time-picker/year-and-month-picker/header.spec.tsx b/web/app/components/base/date-and-time-picker/year-and-month-picker/__tests__/header.spec.tsx similarity index 92% rename from web/app/components/base/date-and-time-picker/year-and-month-picker/header.spec.tsx rename to web/app/components/base/date-and-time-picker/year-and-month-picker/__tests__/header.spec.tsx index 91c0bc6947..fc30c8f221 100644 --- a/web/app/components/base/date-and-time-picker/year-and-month-picker/header.spec.tsx +++ b/web/app/components/base/date-and-time-picker/year-and-month-picker/__tests__/header.spec.tsx @@ -1,6 +1,6 @@ -import type { YearAndMonthPickerHeaderProps } from '../types' +import type { YearAndMonthPickerHeaderProps } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' -import Header from './header' +import Header from '../header' // Factory for Header props const createHeaderProps = (overrides: Partial = {}): YearAndMonthPickerHeaderProps => ({ diff --git a/web/app/components/base/date-and-time-picker/year-and-month-picker/options.spec.tsx b/web/app/components/base/date-and-time-picker/year-and-month-picker/__tests__/options.spec.tsx similarity index 95% rename from web/app/components/base/date-and-time-picker/year-and-month-picker/options.spec.tsx rename to web/app/components/base/date-and-time-picker/year-and-month-picker/__tests__/options.spec.tsx index 2ca448fed0..977462dfb6 100644 --- a/web/app/components/base/date-and-time-picker/year-and-month-picker/options.spec.tsx +++ b/web/app/components/base/date-and-time-picker/year-and-month-picker/__tests__/options.spec.tsx @@ -1,6 +1,6 @@ -import type { YearAndMonthPickerOptionsProps } from '../types' +import type { YearAndMonthPickerOptionsProps } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' -import Options from './options' +import Options from '../options' beforeAll(() => { Element.prototype.scrollIntoView = vi.fn() diff --git a/web/app/components/base/dialog/index.spec.tsx b/web/app/components/base/dialog/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/dialog/index.spec.tsx rename to web/app/components/base/dialog/__tests__/index.spec.tsx index c58724595f..241e89be26 100644 --- a/web/app/components/base/dialog/index.spec.tsx +++ b/web/app/components/base/dialog/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { act, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import CustomDialog from './index' +import CustomDialog from '../index' describe('CustomDialog Component', () => { const setup = () => userEvent.setup() diff --git a/web/app/components/base/divider/index.spec.tsx b/web/app/components/base/divider/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/divider/index.spec.tsx rename to web/app/components/base/divider/__tests__/index.spec.tsx index 7c7c52cd16..2630a0f6f6 100644 --- a/web/app/components/base/divider/index.spec.tsx +++ b/web/app/components/base/divider/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render } from '@testing-library/react' -import Divider from './index' +import Divider from '../index' describe('Divider', () => { it('renders with default props', () => { diff --git a/web/app/components/base/drawer-plus/index.spec.tsx b/web/app/components/base/drawer-plus/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/drawer-plus/index.spec.tsx rename to web/app/components/base/drawer-plus/__tests__/index.spec.tsx index e2d5c88df8..e6a530c299 100644 --- a/web/app/components/base/drawer-plus/index.spec.tsx +++ b/web/app/components/base/drawer-plus/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { fireEvent, render, screen } from '@testing-library/react' import * as React from 'react' -import DrawerPlus from '.' +import DrawerPlus from '..' vi.mock('@/hooks/use-breakpoints', () => ({ default: () => 'desktop', diff --git a/web/app/components/base/drawer/index.spec.tsx b/web/app/components/base/drawer/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/drawer/index.spec.tsx rename to web/app/components/base/drawer/__tests__/index.spec.tsx index 51cf0fa55c..83338b5630 100644 --- a/web/app/components/base/drawer/index.spec.tsx +++ b/web/app/components/base/drawer/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ -import type { IDrawerProps } from './index' +import type { IDrawerProps } from '../index' import { fireEvent, render, screen } from '@testing-library/react' import * as React from 'react' -import Drawer from './index' +import Drawer from '../index' // Capture dialog onClose for testing let capturedDialogOnClose: (() => void) | null = null diff --git a/web/app/components/base/dropdown/index.spec.tsx b/web/app/components/base/dropdown/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/dropdown/index.spec.tsx rename to web/app/components/base/dropdown/__tests__/index.spec.tsx index 7d61b332d4..9820554e3d 100644 --- a/web/app/components/base/dropdown/index.spec.tsx +++ b/web/app/components/base/dropdown/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { act, cleanup, fireEvent, render, screen } from '@testing-library/react' -import Dropdown from './index' +import Dropdown from '../index' describe('Dropdown Component', () => { const mockItems = [ diff --git a/web/app/components/base/effect/index.spec.tsx b/web/app/components/base/effect/__tests__/index.spec.tsx similarity index 91% rename from web/app/components/base/effect/index.spec.tsx rename to web/app/components/base/effect/__tests__/index.spec.tsx index 38410f6987..298abc3189 100644 --- a/web/app/components/base/effect/index.spec.tsx +++ b/web/app/components/base/effect/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render } from '@testing-library/react' -import Effect from '.' +import Effect from '..' describe('Effect', () => { it('applies custom class names', () => { diff --git a/web/app/components/base/emoji-picker/Inner.spec.tsx b/web/app/components/base/emoji-picker/__tests__/Inner.spec.tsx similarity index 99% rename from web/app/components/base/emoji-picker/Inner.spec.tsx rename to web/app/components/base/emoji-picker/__tests__/Inner.spec.tsx index cd993af9e8..eac18dd48a 100644 --- a/web/app/components/base/emoji-picker/Inner.spec.tsx +++ b/web/app/components/base/emoji-picker/__tests__/Inner.spec.tsx @@ -1,5 +1,5 @@ import { act, fireEvent, render, screen, waitFor } from '@testing-library/react' -import EmojiPickerInner from './Inner' +import EmojiPickerInner from '../Inner' vi.mock('@emoji-mart/data', () => ({ default: { diff --git a/web/app/components/base/emoji-picker/index.spec.tsx b/web/app/components/base/emoji-picker/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/emoji-picker/index.spec.tsx rename to web/app/components/base/emoji-picker/__tests__/index.spec.tsx index f554549cee..5eb6593213 100644 --- a/web/app/components/base/emoji-picker/index.spec.tsx +++ b/web/app/components/base/emoji-picker/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { act, fireEvent, render, screen } from '@testing-library/react' -import EmojiPicker from './index' +import EmojiPicker from '../index' vi.mock('@emoji-mart/data', () => ({ default: { diff --git a/web/app/components/base/encrypted-bottom/index.spec.tsx b/web/app/components/base/encrypted-bottom/__tests__/index.spec.tsx similarity index 94% rename from web/app/components/base/encrypted-bottom/index.spec.tsx rename to web/app/components/base/encrypted-bottom/__tests__/index.spec.tsx index aeeb546fe9..914cc7fcda 100644 --- a/web/app/components/base/encrypted-bottom/index.spec.tsx +++ b/web/app/components/base/encrypted-bottom/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import { EncryptedBottom } from '.' +import { EncryptedBottom } from '..' describe('EncryptedBottom', () => { it('applies custom class names', () => { diff --git a/web/app/components/base/error-boundary/index.spec.tsx b/web/app/components/base/error-boundary/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/error-boundary/index.spec.tsx rename to web/app/components/base/error-boundary/__tests__/index.spec.tsx index 1caca84d79..234f22833d 100644 --- a/web/app/components/base/error-boundary/index.spec.tsx +++ b/web/app/components/base/error-boundary/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' import * as React from 'react' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import ErrorBoundary, { ErrorFallback, useAsyncError, useErrorHandler, withErrorBoundary } from './index' +import ErrorBoundary, { ErrorFallback, useAsyncError, useErrorHandler, withErrorBoundary } from '../index' const mockConfig = vi.hoisted(() => ({ isDev: false, diff --git a/web/app/components/base/features/context.spec.tsx b/web/app/components/base/features/__tests__/context.spec.tsx similarity index 96% rename from web/app/components/base/features/context.spec.tsx rename to web/app/components/base/features/__tests__/context.spec.tsx index e57cbd82c2..64bfb256f2 100644 --- a/web/app/components/base/features/context.spec.tsx +++ b/web/app/components/base/features/__tests__/context.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import * as React from 'react' import { useContext } from 'react' -import { FeaturesContext, FeaturesProvider } from './context' +import { FeaturesContext, FeaturesProvider } from '../context' const TestConsumer = () => { const store = useContext(FeaturesContext) diff --git a/web/app/components/base/features/hooks.spec.ts b/web/app/components/base/features/__tests__/hooks.spec.ts similarity index 92% rename from web/app/components/base/features/hooks.spec.ts rename to web/app/components/base/features/__tests__/hooks.spec.ts index aa0aa1e85e..52f3e846ce 100644 --- a/web/app/components/base/features/hooks.spec.ts +++ b/web/app/components/base/features/__tests__/hooks.spec.ts @@ -1,8 +1,8 @@ import { renderHook } from '@testing-library/react' import * as React from 'react' -import { FeaturesContext } from './context' -import { useFeatures, useFeaturesStore } from './hooks' -import { createFeaturesStore } from './store' +import { FeaturesContext } from '../context' +import { useFeatures, useFeaturesStore } from '../hooks' +import { createFeaturesStore } from '../store' describe('useFeatures', () => { it('should return selected state from the store when useFeatures is called with selector', () => { diff --git a/web/app/components/base/features/store.spec.ts b/web/app/components/base/features/__tests__/store.spec.ts similarity index 99% rename from web/app/components/base/features/store.spec.ts rename to web/app/components/base/features/__tests__/store.spec.ts index fc2cf8822e..0a4f03d76a 100644 --- a/web/app/components/base/features/store.spec.ts +++ b/web/app/components/base/features/__tests__/store.spec.ts @@ -1,5 +1,5 @@ import { Resolution, TransferMethod } from '@/types/app' -import { createFeaturesStore } from './store' +import { createFeaturesStore } from '../store' describe('createFeaturesStore', () => { describe('Default State', () => { diff --git a/web/app/components/base/features/new-feature-panel/citation.spec.tsx b/web/app/components/base/features/new-feature-panel/__tests__/citation.spec.tsx similarity index 90% rename from web/app/components/base/features/new-feature-panel/citation.spec.tsx rename to web/app/components/base/features/new-feature-panel/__tests__/citation.spec.tsx index ed50ea9337..a6ad863071 100644 --- a/web/app/components/base/features/new-feature-panel/citation.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/__tests__/citation.spec.tsx @@ -1,8 +1,8 @@ -import type { OnFeaturesChange } from '../types' +import type { OnFeaturesChange } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' import * as React from 'react' -import { FeaturesProvider } from '../context' -import Citation from './citation' +import { FeaturesProvider } from '../../context' +import Citation from '../citation' const renderWithProvider = (props: { disabled?: boolean, onChange?: OnFeaturesChange } = {}) => { return render( diff --git a/web/app/components/base/features/new-feature-panel/dialog-wrapper.spec.tsx b/web/app/components/base/features/new-feature-panel/__tests__/dialog-wrapper.spec.tsx similarity index 98% rename from web/app/components/base/features/new-feature-panel/dialog-wrapper.spec.tsx rename to web/app/components/base/features/new-feature-panel/__tests__/dialog-wrapper.spec.tsx index b5f8f71d60..374976c366 100644 --- a/web/app/components/base/features/new-feature-panel/dialog-wrapper.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/__tests__/dialog-wrapper.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' -import DialogWrapper from './dialog-wrapper' +import DialogWrapper from '../dialog-wrapper' describe('DialogWrapper', () => { beforeEach(() => { diff --git a/web/app/components/base/features/new-feature-panel/feature-bar.spec.tsx b/web/app/components/base/features/new-feature-panel/__tests__/feature-bar.spec.tsx similarity index 97% rename from web/app/components/base/features/new-feature-panel/feature-bar.spec.tsx rename to web/app/components/base/features/new-feature-panel/__tests__/feature-bar.spec.tsx index a02b70c01e..48b91c4836 100644 --- a/web/app/components/base/features/new-feature-panel/feature-bar.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/__tests__/feature-bar.spec.tsx @@ -1,7 +1,7 @@ -import type { Features } from '../types' +import type { Features } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' -import { FeaturesProvider } from '../context' -import FeatureBar from './feature-bar' +import { FeaturesProvider } from '../../context' +import FeatureBar from '../feature-bar' const defaultFeatures: Features = { moreLikeThis: { enabled: false }, diff --git a/web/app/components/base/features/new-feature-panel/feature-card.spec.tsx b/web/app/components/base/features/new-feature-panel/__tests__/feature-card.spec.tsx similarity index 98% rename from web/app/components/base/features/new-feature-panel/feature-card.spec.tsx rename to web/app/components/base/features/new-feature-panel/__tests__/feature-card.spec.tsx index 1f4f1b9fad..0e925d9d02 100644 --- a/web/app/components/base/features/new-feature-panel/feature-card.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/__tests__/feature-card.spec.tsx @@ -1,6 +1,6 @@ import { fireEvent, render, screen } from '@testing-library/react' import * as React from 'react' -import FeatureCard from './feature-card' +import FeatureCard from '../feature-card' describe('FeatureCard', () => { const defaultProps = { diff --git a/web/app/components/base/features/new-feature-panel/follow-up.spec.tsx b/web/app/components/base/features/new-feature-panel/__tests__/follow-up.spec.tsx similarity index 90% rename from web/app/components/base/features/new-feature-panel/follow-up.spec.tsx rename to web/app/components/base/features/new-feature-panel/__tests__/follow-up.spec.tsx index 56df44df8f..0e7c6aa558 100644 --- a/web/app/components/base/features/new-feature-panel/follow-up.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/__tests__/follow-up.spec.tsx @@ -1,8 +1,8 @@ -import type { OnFeaturesChange } from '../types' +import type { OnFeaturesChange } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' import * as React from 'react' -import { FeaturesProvider } from '../context' -import FollowUp from './follow-up' +import { FeaturesProvider } from '../../context' +import FollowUp from '../follow-up' const renderWithProvider = (props: { disabled?: boolean, onChange?: OnFeaturesChange } = {}) => { return render( diff --git a/web/app/components/base/features/new-feature-panel/index.spec.tsx b/web/app/components/base/features/new-feature-panel/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/features/new-feature-panel/index.spec.tsx rename to web/app/components/base/features/new-feature-panel/__tests__/index.spec.tsx index 0122a148d3..20632c4954 100644 --- a/web/app/components/base/features/new-feature-panel/index.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ -import type { Features } from '../types' +import type { Features } from '../../types' import { render, screen } from '@testing-library/react' -import { FeaturesProvider } from '../context' -import NewFeaturePanel from './index' +import { FeaturesProvider } from '../../context' +import NewFeaturePanel from '../index' vi.mock('next/navigation', () => ({ useRouter: () => ({ push: vi.fn() }), diff --git a/web/app/components/base/features/new-feature-panel/more-like-this.spec.tsx b/web/app/components/base/features/new-feature-panel/__tests__/more-like-this.spec.tsx similarity index 91% rename from web/app/components/base/features/new-feature-panel/more-like-this.spec.tsx rename to web/app/components/base/features/new-feature-panel/__tests__/more-like-this.spec.tsx index 592e08a995..1d39b62f10 100644 --- a/web/app/components/base/features/new-feature-panel/more-like-this.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/__tests__/more-like-this.spec.tsx @@ -1,8 +1,8 @@ -import type { OnFeaturesChange } from '../types' +import type { OnFeaturesChange } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' import * as React from 'react' -import { FeaturesProvider } from '../context' -import MoreLikeThis from './more-like-this' +import { FeaturesProvider } from '../../context' +import MoreLikeThis from '../more-like-this' const renderWithProvider = (props: { disabled?: boolean, onChange?: OnFeaturesChange } = {}) => { return render( diff --git a/web/app/components/base/features/new-feature-panel/speech-to-text.spec.tsx b/web/app/components/base/features/new-feature-panel/__tests__/speech-to-text.spec.tsx similarity index 89% rename from web/app/components/base/features/new-feature-panel/speech-to-text.spec.tsx rename to web/app/components/base/features/new-feature-panel/__tests__/speech-to-text.spec.tsx index 341065fe21..75e0962745 100644 --- a/web/app/components/base/features/new-feature-panel/speech-to-text.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/__tests__/speech-to-text.spec.tsx @@ -1,8 +1,8 @@ -import type { OnFeaturesChange } from '../types' +import type { OnFeaturesChange } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' import * as React from 'react' -import { FeaturesProvider } from '../context' -import SpeechToText from './speech-to-text' +import { FeaturesProvider } from '../../context' +import SpeechToText from '../speech-to-text' const renderWithProvider = (props: { disabled?: boolean, onChange?: OnFeaturesChange } = {}) => { return render( diff --git a/web/app/components/base/features/new-feature-panel/annotation-reply/annotation-ctrl-button.spec.tsx b/web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/annotation-ctrl-button.spec.tsx similarity index 98% rename from web/app/components/base/features/new-feature-panel/annotation-reply/annotation-ctrl-button.spec.tsx rename to web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/annotation-ctrl-button.spec.tsx index 65f45d10de..e48bedff96 100644 --- a/web/app/components/base/features/new-feature-panel/annotation-reply/annotation-ctrl-button.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/annotation-ctrl-button.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' -import AnnotationCtrlButton from './annotation-ctrl-button' +import AnnotationCtrlButton from '../annotation-ctrl-button' const mockSetShowAnnotationFullModal = vi.fn() vi.mock('@/context/modal-context', () => ({ diff --git a/web/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal.spec.tsx b/web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/config-param-modal.spec.tsx similarity index 99% rename from web/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal.spec.tsx rename to web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/config-param-modal.spec.tsx index d541c006f6..1ef95e9e2d 100644 --- a/web/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/config-param-modal.spec.tsx @@ -1,6 +1,6 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' import Toast from '@/app/components/base/toast' -import ConfigParamModal from './config-param-modal' +import ConfigParamModal from '../config-param-modal' let mockHooksReturn: { modelList: { provider: { provider: string }, models: { model: string }[] }[] diff --git a/web/app/components/base/features/new-feature-panel/annotation-reply/config-param.spec.tsx b/web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/config-param.spec.tsx similarity index 96% rename from web/app/components/base/features/new-feature-panel/annotation-reply/config-param.spec.tsx rename to web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/config-param.spec.tsx index 8d8a8e55cb..35adef0a7d 100644 --- a/web/app/components/base/features/new-feature-panel/annotation-reply/config-param.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/config-param.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import { Item } from './config-param' +import { Item } from '../config-param' describe('ConfigParam Item', () => { it('should render title text', () => { diff --git a/web/app/components/base/features/new-feature-panel/annotation-reply/index.spec.tsx b/web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/features/new-feature-panel/annotation-reply/index.spec.tsx rename to web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/index.spec.tsx index ce9e2f7cf2..b7cf84a3a8 100644 --- a/web/app/components/base/features/new-feature-panel/annotation-reply/index.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/index.spec.tsx @@ -1,8 +1,8 @@ -import type { Features } from '../../types' +import type { Features } from '../../../types' import type { OnFeaturesChange } from '@/app/components/base/features/types' import { fireEvent, render, screen } from '@testing-library/react' -import { FeaturesProvider } from '../../context' -import AnnotationReply from './index' +import { FeaturesProvider } from '../../../context' +import AnnotationReply from '../index' const mockPush = vi.fn() vi.mock('next/navigation', () => ({ diff --git a/web/app/components/base/features/new-feature-panel/annotation-reply/type.spec.ts b/web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/type.spec.ts similarity index 83% rename from web/app/components/base/features/new-feature-panel/annotation-reply/type.spec.ts rename to web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/type.spec.ts index 0bbb6d695b..6d22b4d42f 100644 --- a/web/app/components/base/features/new-feature-panel/annotation-reply/type.spec.ts +++ b/web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/type.spec.ts @@ -1,4 +1,4 @@ -import { PageType } from './type' +import { PageType } from '../type' describe('PageType', () => { it('should have log and annotation values', () => { diff --git a/web/app/components/base/features/new-feature-panel/annotation-reply/use-annotation-config.spec.ts b/web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/use-annotation-config.spec.ts similarity index 99% rename from web/app/components/base/features/new-feature-panel/annotation-reply/use-annotation-config.spec.ts rename to web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/use-annotation-config.spec.ts index f7ea3a0117..7c1d94aea6 100644 --- a/web/app/components/base/features/new-feature-panel/annotation-reply/use-annotation-config.spec.ts +++ b/web/app/components/base/features/new-feature-panel/annotation-reply/__tests__/use-annotation-config.spec.ts @@ -1,6 +1,6 @@ import type { AnnotationReplyConfig } from '@/models/debug' import { act, renderHook } from '@testing-library/react' -import useAnnotationConfig from './use-annotation-config' +import useAnnotationConfig from '../use-annotation-config' let mockIsAnnotationFull = false vi.mock('@/context/provider-context', () => ({ diff --git a/web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/index.spec.tsx b/web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/index.spec.tsx rename to web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/__tests__/index.spec.tsx index 008c6369e1..2bc30e4ead 100644 --- a/web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/index.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import ScoreSlider from './index' +import ScoreSlider from '../index' vi.mock('@/app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider', () => ({ default: ({ value, onChange, min, max }: { value: number, onChange: (v: number) => void, min: number, max: number }) => ( diff --git a/web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider/index.spec.tsx b/web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider/index.spec.tsx rename to web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider/__tests__/index.spec.tsx index 21e187091c..815e8ffe49 100644 --- a/web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider/index.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import Slider from './index' +import Slider from '../index' describe('BaseSlider', () => { beforeEach(() => { diff --git a/web/app/components/base/features/new-feature-panel/conversation-opener/index.spec.tsx b/web/app/components/base/features/new-feature-panel/conversation-opener/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/features/new-feature-panel/conversation-opener/index.spec.tsx rename to web/app/components/base/features/new-feature-panel/conversation-opener/__tests__/index.spec.tsx index 20e85c9378..a21b34e4ea 100644 --- a/web/app/components/base/features/new-feature-panel/conversation-opener/index.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/conversation-opener/__tests__/index.spec.tsx @@ -1,8 +1,8 @@ -import type { Features } from '../../types' +import type { Features } from '../../../types' import type { OnFeaturesChange } from '@/app/components/base/features/types' import { fireEvent, render, screen } from '@testing-library/react' -import { FeaturesProvider } from '../../context' -import ConversationOpener from './index' +import { FeaturesProvider } from '../../../context' +import ConversationOpener from '../index' const mockSetShowOpeningModal = vi.fn() vi.mock('@/context/modal-context', () => ({ diff --git a/web/app/components/base/features/new-feature-panel/conversation-opener/modal.spec.tsx b/web/app/components/base/features/new-feature-panel/conversation-opener/__tests__/modal.spec.tsx similarity index 99% rename from web/app/components/base/features/new-feature-panel/conversation-opener/modal.spec.tsx rename to web/app/components/base/features/new-feature-panel/conversation-opener/__tests__/modal.spec.tsx index c5acda4bd5..f03763d192 100644 --- a/web/app/components/base/features/new-feature-panel/conversation-opener/modal.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/conversation-opener/__tests__/modal.spec.tsx @@ -3,7 +3,7 @@ import type { InputVar } from '@/app/components/workflow/types' import { act, fireEvent, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { InputVarType } from '@/app/components/workflow/types' -import OpeningSettingModal from './modal' +import OpeningSettingModal from '../modal' const getPromptEditor = () => { const editor = document.querySelector('[data-lexical-editor="true"]') diff --git a/web/app/components/base/features/new-feature-panel/file-upload/index.spec.tsx b/web/app/components/base/features/new-feature-panel/file-upload/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/features/new-feature-panel/file-upload/index.spec.tsx rename to web/app/components/base/features/new-feature-panel/file-upload/__tests__/index.spec.tsx index b39156c196..cc3ab3fcc0 100644 --- a/web/app/components/base/features/new-feature-panel/file-upload/index.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/file-upload/__tests__/index.spec.tsx @@ -1,8 +1,8 @@ -import type { Features } from '../../types' +import type { Features } from '../../../types' import type { OnFeaturesChange } from '@/app/components/base/features/types' import { fireEvent, render, screen, waitFor } from '@testing-library/react' -import { FeaturesProvider } from '../../context' -import FileUpload from './index' +import { FeaturesProvider } from '../../../context' +import FileUpload from '../index' vi.mock('@/service/use-common', () => ({ useFileUploadConfig: () => ({ data: undefined }), diff --git a/web/app/components/base/features/new-feature-panel/file-upload/setting-content.spec.tsx b/web/app/components/base/features/new-feature-panel/file-upload/__tests__/setting-content.spec.tsx similarity index 97% rename from web/app/components/base/features/new-feature-panel/file-upload/setting-content.spec.tsx rename to web/app/components/base/features/new-feature-panel/file-upload/__tests__/setting-content.spec.tsx index ca5b4677bf..37a0f38838 100644 --- a/web/app/components/base/features/new-feature-panel/file-upload/setting-content.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/file-upload/__tests__/setting-content.spec.tsx @@ -1,10 +1,10 @@ -import type { Features } from '../../types' +import type { Features } from '../../../types' import type { OnFeaturesChange } from '@/app/components/base/features/types' import { fireEvent, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { TransferMethod } from '@/types/app' -import { FeaturesProvider } from '../../context' -import SettingContent from './setting-content' +import { FeaturesProvider } from '../../../context' +import SettingContent from '../setting-content' vi.mock('@/app/components/workflow/nodes/_base/components/file-upload-setting', () => ({ default: ({ payload, onChange }: { payload: Record, onChange: (p: Record) => void }) => ( diff --git a/web/app/components/base/features/new-feature-panel/file-upload/setting-modal.spec.tsx b/web/app/components/base/features/new-feature-panel/file-upload/__tests__/setting-modal.spec.tsx similarity index 96% rename from web/app/components/base/features/new-feature-panel/file-upload/setting-modal.spec.tsx rename to web/app/components/base/features/new-feature-panel/file-upload/__tests__/setting-modal.spec.tsx index b3a78c438f..afa690f31a 100644 --- a/web/app/components/base/features/new-feature-panel/file-upload/setting-modal.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/file-upload/__tests__/setting-modal.spec.tsx @@ -1,8 +1,8 @@ -import type { Features } from '../../types' +import type { Features } from '../../../types' import { fireEvent, render, screen, waitFor } from '@testing-library/react' import { TransferMethod } from '@/types/app' -import { FeaturesProvider } from '../../context' -import FileUploadSettings from './setting-modal' +import { FeaturesProvider } from '../../../context' +import FileUploadSettings from '../setting-modal' vi.mock('@/service/use-common', () => ({ useFileUploadConfig: () => ({ data: undefined }), diff --git a/web/app/components/base/features/new-feature-panel/image-upload/index.spec.tsx b/web/app/components/base/features/new-feature-panel/image-upload/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/features/new-feature-panel/image-upload/index.spec.tsx rename to web/app/components/base/features/new-feature-panel/image-upload/__tests__/index.spec.tsx index 1590efdd75..321c0c353d 100644 --- a/web/app/components/base/features/new-feature-panel/image-upload/index.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/image-upload/__tests__/index.spec.tsx @@ -1,8 +1,8 @@ -import type { Features } from '../../types' +import type { Features } from '../../../types' import type { OnFeaturesChange } from '@/app/components/base/features/types' import { fireEvent, render, screen, waitFor } from '@testing-library/react' -import { FeaturesProvider } from '../../context' -import ImageUpload from './index' +import { FeaturesProvider } from '../../../context' +import ImageUpload from '../index' vi.mock('@/service/use-common', () => ({ useFileUploadConfig: () => ({ data: undefined }), diff --git a/web/app/components/base/features/new-feature-panel/moderation/form-generation.spec.tsx b/web/app/components/base/features/new-feature-panel/moderation/__tests__/form-generation.spec.tsx similarity index 98% rename from web/app/components/base/features/new-feature-panel/moderation/form-generation.spec.tsx rename to web/app/components/base/features/new-feature-panel/moderation/__tests__/form-generation.spec.tsx index 14f35dc6b4..c0d2594f28 100644 --- a/web/app/components/base/features/new-feature-panel/moderation/form-generation.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/moderation/__tests__/form-generation.spec.tsx @@ -1,7 +1,7 @@ import type { I18nText } from '@/i18n-config/language' import type { CodeBasedExtensionForm } from '@/models/common' import { fireEvent, render, screen } from '@testing-library/react' -import FormGeneration from './form-generation' +import FormGeneration from '../form-generation' const i18n = (en: string, zh = en): I18nText => ({ 'en-US': en, 'zh-Hans': zh }) as unknown as I18nText diff --git a/web/app/components/base/features/new-feature-panel/moderation/index.spec.tsx b/web/app/components/base/features/new-feature-panel/moderation/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/features/new-feature-panel/moderation/index.spec.tsx rename to web/app/components/base/features/new-feature-panel/moderation/__tests__/index.spec.tsx index 5c829f3560..0a8ba930ee 100644 --- a/web/app/components/base/features/new-feature-panel/moderation/index.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/moderation/__tests__/index.spec.tsx @@ -1,8 +1,8 @@ -import type { Features } from '../../types' +import type { Features } from '../../../types' import type { OnFeaturesChange } from '@/app/components/base/features/types' import { fireEvent, render, screen } from '@testing-library/react' -import { FeaturesProvider } from '../../context' -import Moderation from './index' +import { FeaturesProvider } from '../../../context' +import Moderation from '../index' const mockSetShowModerationSettingModal = vi.fn() vi.mock('@/context/modal-context', () => ({ diff --git a/web/app/components/base/features/new-feature-panel/moderation/moderation-content.spec.tsx b/web/app/components/base/features/new-feature-panel/moderation/__tests__/moderation-content.spec.tsx similarity index 98% rename from web/app/components/base/features/new-feature-panel/moderation/moderation-content.spec.tsx rename to web/app/components/base/features/new-feature-panel/moderation/__tests__/moderation-content.spec.tsx index ef9bb8ebd4..9caa38d5d4 100644 --- a/web/app/components/base/features/new-feature-panel/moderation/moderation-content.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/moderation/__tests__/moderation-content.spec.tsx @@ -1,6 +1,6 @@ import type { ModerationContentConfig } from '@/models/debug' import { fireEvent, render, screen } from '@testing-library/react' -import ModerationContent from './moderation-content' +import ModerationContent from '../moderation-content' const defaultConfig: ModerationContentConfig = { enabled: false, diff --git a/web/app/components/base/features/new-feature-panel/moderation/moderation-setting-modal.spec.tsx b/web/app/components/base/features/new-feature-panel/moderation/__tests__/moderation-setting-modal.spec.tsx similarity index 99% rename from web/app/components/base/features/new-feature-panel/moderation/moderation-setting-modal.spec.tsx rename to web/app/components/base/features/new-feature-panel/moderation/__tests__/moderation-setting-modal.spec.tsx index 79098f6816..3c690635da 100644 --- a/web/app/components/base/features/new-feature-panel/moderation/moderation-setting-modal.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/moderation/__tests__/moderation-setting-modal.spec.tsx @@ -1,6 +1,6 @@ import type { ModerationConfig } from '@/models/debug' import { fireEvent, render, screen } from '@testing-library/react' -import ModerationSettingModal from './moderation-setting-modal' +import ModerationSettingModal from '../moderation-setting-modal' const mockNotify = vi.fn() vi.mock('@/app/components/base/toast', () => ({ diff --git a/web/app/components/base/features/new-feature-panel/text-to-speech/index.spec.tsx b/web/app/components/base/features/new-feature-panel/text-to-speech/__tests__/index.spec.tsx similarity index 96% rename from web/app/components/base/features/new-feature-panel/text-to-speech/index.spec.tsx rename to web/app/components/base/features/new-feature-panel/text-to-speech/__tests__/index.spec.tsx index a9623a8215..62d1a43925 100644 --- a/web/app/components/base/features/new-feature-panel/text-to-speech/index.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/text-to-speech/__tests__/index.spec.tsx @@ -1,9 +1,9 @@ -import type { Features } from '../../types' +import type { Features } from '../../../types' import type { OnFeaturesChange } from '@/app/components/base/features/types' import { fireEvent, render, screen } from '@testing-library/react' import { TtsAutoPlay } from '@/types/app' -import { FeaturesProvider } from '../../context' -import TextToSpeech from './index' +import { FeaturesProvider } from '../../../context' +import TextToSpeech from '../index' vi.mock('@/i18n-config/language', () => ({ languages: [ diff --git a/web/app/components/base/features/new-feature-panel/text-to-speech/param-config-content.spec.tsx b/web/app/components/base/features/new-feature-panel/text-to-speech/__tests__/param-config-content.spec.tsx similarity index 98% rename from web/app/components/base/features/new-feature-panel/text-to-speech/param-config-content.spec.tsx rename to web/app/components/base/features/new-feature-panel/text-to-speech/__tests__/param-config-content.spec.tsx index b4a0dafd91..66d870f28f 100644 --- a/web/app/components/base/features/new-feature-panel/text-to-speech/param-config-content.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/text-to-speech/__tests__/param-config-content.spec.tsx @@ -1,10 +1,10 @@ -import type { Features } from '../../types' +import type { Features } from '../../../types' import type { OnFeaturesChange } from '@/app/components/base/features/types' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { TtsAutoPlay } from '@/types/app' -import { FeaturesProvider } from '../../context' -import ParamConfigContent from './param-config-content' +import { FeaturesProvider } from '../../../context' +import ParamConfigContent from '../param-config-content' let mockLanguages = [ { value: 'en-US', name: 'English', example: 'Hello world' }, diff --git a/web/app/components/base/features/new-feature-panel/text-to-speech/voice-settings.spec.tsx b/web/app/components/base/features/new-feature-panel/text-to-speech/__tests__/voice-settings.spec.tsx similarity index 95% rename from web/app/components/base/features/new-feature-panel/text-to-speech/voice-settings.spec.tsx rename to web/app/components/base/features/new-feature-panel/text-to-speech/__tests__/voice-settings.spec.tsx index d88d302f92..ce67d7a8d5 100644 --- a/web/app/components/base/features/new-feature-panel/text-to-speech/voice-settings.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/text-to-speech/__tests__/voice-settings.spec.tsx @@ -1,7 +1,7 @@ -import type { Features } from '../../types' +import type { Features } from '../../../types' import { fireEvent, render, screen } from '@testing-library/react' -import { FeaturesProvider } from '../../context' -import VoiceSettings from './voice-settings' +import { FeaturesProvider } from '../../../context' +import VoiceSettings from '../voice-settings' vi.mock('next/navigation', () => ({ usePathname: () => '/app/test-app-id/configuration', diff --git a/web/app/components/base/file-icon/index.spec.tsx b/web/app/components/base/file-icon/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/file-icon/index.spec.tsx rename to web/app/components/base/file-icon/__tests__/index.spec.tsx index 526a889f34..7061b51627 100644 --- a/web/app/components/base/file-icon/index.spec.tsx +++ b/web/app/components/base/file-icon/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render } from '@testing-library/react' -import FileIcon from '.' +import FileIcon from '..' describe('File icon component', () => { const testCases = [ diff --git a/web/app/components/base/file-thumb/image-render.spec.tsx b/web/app/components/base/file-thumb/__tests__/image-render.spec.tsx similarity index 92% rename from web/app/components/base/file-thumb/image-render.spec.tsx rename to web/app/components/base/file-thumb/__tests__/image-render.spec.tsx index cef41b912c..7ccd3391df 100644 --- a/web/app/components/base/file-thumb/image-render.spec.tsx +++ b/web/app/components/base/file-thumb/__tests__/image-render.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import ImageRender from './image-render' +import ImageRender from '../image-render' describe('ImageRender Component', () => { const mockProps = { diff --git a/web/app/components/base/file-thumb/index.spec.tsx b/web/app/components/base/file-thumb/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/file-thumb/index.spec.tsx rename to web/app/components/base/file-thumb/__tests__/index.spec.tsx index 205e6f8d6f..368f14ae75 100644 --- a/web/app/components/base/file-thumb/index.spec.tsx +++ b/web/app/components/base/file-thumb/__tests__/index.spec.tsx @@ -2,7 +2,7 @@ import type { ImgHTMLAttributes } from 'react' import { fireEvent, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import FileThumb from './index' +import FileThumb from '../index' vi.mock('next/image', () => ({ __esModule: true, diff --git a/web/app/components/base/file-uploader/audio-preview.spec.tsx b/web/app/components/base/file-uploader/__tests__/audio-preview.spec.tsx similarity index 98% rename from web/app/components/base/file-uploader/audio-preview.spec.tsx rename to web/app/components/base/file-uploader/__tests__/audio-preview.spec.tsx index a2034b202a..5a5740ef0d 100644 --- a/web/app/components/base/file-uploader/audio-preview.spec.tsx +++ b/web/app/components/base/file-uploader/__tests__/audio-preview.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import AudioPreview from './audio-preview' +import AudioPreview from '../audio-preview' describe('AudioPreview', () => { beforeEach(() => { diff --git a/web/app/components/base/file-uploader/constants.spec.ts b/web/app/components/base/file-uploader/__tests__/constants.spec.ts similarity index 99% rename from web/app/components/base/file-uploader/constants.spec.ts rename to web/app/components/base/file-uploader/__tests__/constants.spec.ts index abe44aa842..7225fbcf04 100644 --- a/web/app/components/base/file-uploader/constants.spec.ts +++ b/web/app/components/base/file-uploader/__tests__/constants.spec.ts @@ -5,7 +5,7 @@ import { IMG_SIZE_LIMIT, MAX_FILE_UPLOAD_LIMIT, VIDEO_SIZE_LIMIT, -} from './constants' +} from '../constants' describe('file-uploader constants', () => { describe('size limit constants', () => { diff --git a/web/app/components/base/file-uploader/file-image-render.spec.tsx b/web/app/components/base/file-uploader/__tests__/file-image-render.spec.tsx similarity index 97% rename from web/app/components/base/file-uploader/file-image-render.spec.tsx rename to web/app/components/base/file-uploader/__tests__/file-image-render.spec.tsx index fa85011f5c..84c3b06e85 100644 --- a/web/app/components/base/file-uploader/file-image-render.spec.tsx +++ b/web/app/components/base/file-uploader/__tests__/file-image-render.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import FileImageRender from './file-image-render' +import FileImageRender from '../file-image-render' describe('FileImageRender', () => { beforeEach(() => { diff --git a/web/app/components/base/file-uploader/file-input.spec.tsx b/web/app/components/base/file-uploader/__tests__/file-input.spec.tsx similarity index 97% rename from web/app/components/base/file-uploader/file-input.spec.tsx rename to web/app/components/base/file-uploader/__tests__/file-input.spec.tsx index 73c7690e29..ac0070f9df 100644 --- a/web/app/components/base/file-uploader/file-input.spec.tsx +++ b/web/app/components/base/file-uploader/__tests__/file-input.spec.tsx @@ -1,12 +1,12 @@ -import type { FileEntity } from './types' +import type { FileEntity } from '../types' import type { FileUpload } from '@/app/components/base/features/types' import { fireEvent, render } from '@testing-library/react' -import FileInput from './file-input' -import { FileContextProvider } from './store' +import FileInput from '../file-input' +import { FileContextProvider } from '../store' const mockHandleLocalFileUpload = vi.fn() -vi.mock('./hooks', () => ({ +vi.mock('../hooks', () => ({ useFile: () => ({ handleLocalFileUpload: mockHandleLocalFileUpload, }), diff --git a/web/app/components/base/file-uploader/file-list-in-log.spec.tsx b/web/app/components/base/file-uploader/__tests__/file-list-in-log.spec.tsx similarity index 98% rename from web/app/components/base/file-uploader/file-list-in-log.spec.tsx rename to web/app/components/base/file-uploader/__tests__/file-list-in-log.spec.tsx index 0c1dff8759..f184850936 100644 --- a/web/app/components/base/file-uploader/file-list-in-log.spec.tsx +++ b/web/app/components/base/file-uploader/__tests__/file-list-in-log.spec.tsx @@ -1,7 +1,7 @@ -import type { FileEntity } from './types' +import type { FileEntity } from '../types' import { fireEvent, render, screen } from '@testing-library/react' import { TransferMethod } from '@/types/app' -import FileListInLog from './file-list-in-log' +import FileListInLog from '../file-list-in-log' const createFile = (overrides: Partial = {}): FileEntity => ({ id: `file-${Math.random()}`, diff --git a/web/app/components/base/file-uploader/file-type-icon.spec.tsx b/web/app/components/base/file-uploader/__tests__/file-type-icon.spec.tsx similarity index 96% rename from web/app/components/base/file-uploader/file-type-icon.spec.tsx rename to web/app/components/base/file-uploader/__tests__/file-type-icon.spec.tsx index 89b42b489d..1da3804878 100644 --- a/web/app/components/base/file-uploader/file-type-icon.spec.tsx +++ b/web/app/components/base/file-uploader/__tests__/file-type-icon.spec.tsx @@ -1,6 +1,6 @@ -import type { FileAppearanceTypeEnum } from './types' +import type { FileAppearanceTypeEnum } from '../types' import { render } from '@testing-library/react' -import FileTypeIcon from './file-type-icon' +import FileTypeIcon from '../file-type-icon' describe('FileTypeIcon', () => { beforeEach(() => { diff --git a/web/app/components/base/file-uploader/hooks.spec.ts b/web/app/components/base/file-uploader/__tests__/hooks.spec.ts similarity index 99% rename from web/app/components/base/file-uploader/hooks.spec.ts rename to web/app/components/base/file-uploader/__tests__/hooks.spec.ts index 5577b87649..00c64224aa 100644 --- a/web/app/components/base/file-uploader/hooks.spec.ts +++ b/web/app/components/base/file-uploader/__tests__/hooks.spec.ts @@ -1,8 +1,8 @@ -import type { FileEntity } from './types' +import type { FileEntity } from '../types' import type { FileUpload } from '@/app/components/base/features/types' import type { FileUploadConfigResponse } from '@/models/common' import { act, renderHook } from '@testing-library/react' -import { useFile, useFileSizeLimit } from './hooks' +import { useFile, useFileSizeLimit } from '../hooks' const mockNotify = vi.fn() @@ -19,7 +19,7 @@ vi.mock('@/app/components/base/toast', () => ({ const mockSetFiles = vi.fn() let mockStoreFiles: FileEntity[] = [] -vi.mock('./store', () => ({ +vi.mock('../store', () => ({ useFileStore: () => ({ getState: () => ({ files: mockStoreFiles, @@ -31,7 +31,7 @@ vi.mock('./store', () => ({ const mockFileUpload = vi.fn() const mockIsAllowedFileExtension = vi.fn().mockReturnValue(true) const mockGetSupportFileType = vi.fn().mockReturnValue('document') -vi.mock('./utils', () => ({ +vi.mock('../utils', () => ({ fileUpload: (...args: unknown[]) => mockFileUpload(...args), getFileUploadErrorMessage: vi.fn().mockReturnValue('Upload error'), getSupportFileType: (...args: unknown[]) => mockGetSupportFileType(...args), diff --git a/web/app/components/base/file-uploader/pdf-preview.spec.tsx b/web/app/components/base/file-uploader/__tests__/pdf-preview.spec.tsx similarity index 98% rename from web/app/components/base/file-uploader/pdf-preview.spec.tsx rename to web/app/components/base/file-uploader/__tests__/pdf-preview.spec.tsx index df07a592ef..b3c48a7061 100644 --- a/web/app/components/base/file-uploader/pdf-preview.spec.tsx +++ b/web/app/components/base/file-uploader/__tests__/pdf-preview.spec.tsx @@ -1,8 +1,8 @@ import type { ReactNode } from 'react' import { fireEvent, render, screen } from '@testing-library/react' -import PdfPreview from './pdf-preview' +import PdfPreview from '../pdf-preview' -vi.mock('./pdf-highlighter-adapter', () => ({ +vi.mock('../pdf-highlighter-adapter', () => ({ PdfLoader: ({ children, beforeLoad }: { children: (doc: unknown) => ReactNode, beforeLoad: ReactNode }) => (
{beforeLoad} diff --git a/web/app/components/base/file-uploader/store.spec.tsx b/web/app/components/base/file-uploader/__tests__/store.spec.tsx similarity index 98% rename from web/app/components/base/file-uploader/store.spec.tsx rename to web/app/components/base/file-uploader/__tests__/store.spec.tsx index 96053498d9..89516873cc 100644 --- a/web/app/components/base/file-uploader/store.spec.tsx +++ b/web/app/components/base/file-uploader/__tests__/store.spec.tsx @@ -1,7 +1,7 @@ -import type { FileEntity } from './types' +import type { FileEntity } from '../types' import { render, renderHook, screen } from '@testing-library/react' import { TransferMethod } from '@/types/app' -import { createFileStore, FileContext, FileContextProvider, useFileStore, useStore } from './store' +import { createFileStore, FileContext, FileContextProvider, useFileStore, useStore } from '../store' const createMockFile = (overrides: Partial = {}): FileEntity => ({ id: 'file-1', diff --git a/web/app/components/base/file-uploader/utils.spec.ts b/web/app/components/base/file-uploader/__tests__/utils.spec.ts similarity index 98% rename from web/app/components/base/file-uploader/utils.spec.ts rename to web/app/components/base/file-uploader/__tests__/utils.spec.ts index 358fc586eb..7a4956307d 100644 --- a/web/app/components/base/file-uploader/utils.spec.ts +++ b/web/app/components/base/file-uploader/__tests__/utils.spec.ts @@ -1,9 +1,9 @@ -import type { FileEntity } from './types' +import type { FileEntity } from '../types' import { SupportUploadFileTypes } from '@/app/components/workflow/types' import { upload } from '@/service/base' import { TransferMethod } from '@/types/app' -import { FILE_EXTS } from '../prompt-editor/constants' -import { FileAppearanceTypeEnum } from './types' +import { FILE_EXTS } from '../../prompt-editor/constants' +import { FileAppearanceTypeEnum } from '../types' import { fileIsUploaded, fileUpload, @@ -17,7 +17,7 @@ import { getSupportFileExtensionList, getSupportFileType, isAllowedFileExtension, -} from './utils' +} from '../utils' vi.mock('@/service/base', () => ({ upload: vi.fn(), @@ -866,14 +866,14 @@ describe('file-uploader utils', () => { expect(fileIsUploaded({ uploadedId: '123', progress: 100, - } as any)).toBe(true) + } as Partial as FileEntity)).toBe(true) }) it('should identify remote files as uploaded', () => { expect(fileIsUploaded({ transferMethod: TransferMethod.remote_url, progress: 100, - } as any)).toBe(true) + } as Partial as FileEntity)).toBe(true) }) }) }) diff --git a/web/app/components/base/file-uploader/video-preview.spec.tsx b/web/app/components/base/file-uploader/__tests__/video-preview.spec.tsx similarity index 98% rename from web/app/components/base/file-uploader/video-preview.spec.tsx rename to web/app/components/base/file-uploader/__tests__/video-preview.spec.tsx index 2384281c8e..c95455caf3 100644 --- a/web/app/components/base/file-uploader/video-preview.spec.tsx +++ b/web/app/components/base/file-uploader/__tests__/video-preview.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render } from '@testing-library/react' -import VideoPreview from './video-preview' +import VideoPreview from '../video-preview' describe('VideoPreview', () => { beforeEach(() => { diff --git a/web/app/components/base/file-uploader/file-from-link-or-local/index.spec.tsx b/web/app/components/base/file-uploader/file-from-link-or-local/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/file-uploader/file-from-link-or-local/index.spec.tsx rename to web/app/components/base/file-uploader/file-from-link-or-local/__tests__/index.spec.tsx index 5227b9b2b2..9847aa863e 100644 --- a/web/app/components/base/file-uploader/file-from-link-or-local/index.spec.tsx +++ b/web/app/components/base/file-uploader/file-from-link-or-local/__tests__/index.spec.tsx @@ -1,8 +1,8 @@ -import type { FileEntity } from '../types' +import type { FileEntity } from '../../types' import type { FileUpload } from '@/app/components/base/features/types' import { fireEvent, render, screen } from '@testing-library/react' -import { FileContextProvider } from '../store' -import FileFromLinkOrLocal from './index' +import { FileContextProvider } from '../../store' +import FileFromLinkOrLocal from '../index' let mockFiles: FileEntity[] = [] @@ -11,7 +11,7 @@ function createStubFile(id: string): FileEntity { } const mockHandleLoadFileFromLink = vi.fn() -vi.mock('../hooks', () => ({ +vi.mock('../../hooks', () => ({ useFile: () => ({ handleLoadFileFromLink: mockHandleLoadFileFromLink, }), diff --git a/web/app/components/base/file-uploader/file-uploader-in-attachment/file-item.spec.tsx b/web/app/components/base/file-uploader/file-uploader-in-attachment/__tests__/file-item.spec.tsx similarity index 99% rename from web/app/components/base/file-uploader/file-uploader-in-attachment/file-item.spec.tsx rename to web/app/components/base/file-uploader/file-uploader-in-attachment/__tests__/file-item.spec.tsx index 72d4643955..b2198680f5 100644 --- a/web/app/components/base/file-uploader/file-uploader-in-attachment/file-item.spec.tsx +++ b/web/app/components/base/file-uploader/file-uploader-in-attachment/__tests__/file-item.spec.tsx @@ -1,8 +1,8 @@ -import type { FileEntity } from '../types' +import type { FileEntity } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' import { PreviewMode } from '@/app/components/base/features/types' import { TransferMethod } from '@/types/app' -import FileInAttachmentItem from './file-item' +import FileInAttachmentItem from '../file-item' vi.mock('@/utils/download', () => ({ downloadUrl: vi.fn(), diff --git a/web/app/components/base/file-uploader/file-uploader-in-attachment/index.spec.tsx b/web/app/components/base/file-uploader/file-uploader-in-attachment/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/file-uploader/file-uploader-in-attachment/index.spec.tsx rename to web/app/components/base/file-uploader/file-uploader-in-attachment/__tests__/index.spec.tsx index 81946e0d1c..895c960ae9 100644 --- a/web/app/components/base/file-uploader/file-uploader-in-attachment/index.spec.tsx +++ b/web/app/components/base/file-uploader/file-uploader-in-attachment/__tests__/index.spec.tsx @@ -1,12 +1,12 @@ -import type { FileEntity } from '../types' +import type { FileEntity } from '../../types' import type { FileUpload } from '@/app/components/base/features/types' import { fireEvent, render, screen } from '@testing-library/react' import { TransferMethod } from '@/types/app' -import FileUploaderInAttachmentWrapper from './index' +import FileUploaderInAttachmentWrapper from '../index' const mockHandleRemoveFile = vi.fn() const mockHandleReUploadFile = vi.fn() -vi.mock('../hooks', () => ({ +vi.mock('../../hooks', () => ({ useFile: () => ({ handleRemoveFile: mockHandleRemoveFile, handleReUploadFile: mockHandleReUploadFile, diff --git a/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-image-item.spec.tsx b/web/app/components/base/file-uploader/file-uploader-in-chat-input/__tests__/file-image-item.spec.tsx similarity index 99% rename from web/app/components/base/file-uploader/file-uploader-in-chat-input/file-image-item.spec.tsx rename to web/app/components/base/file-uploader/file-uploader-in-chat-input/__tests__/file-image-item.spec.tsx index e30c6c886c..2bc418cf1d 100644 --- a/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-image-item.spec.tsx +++ b/web/app/components/base/file-uploader/file-uploader-in-chat-input/__tests__/file-image-item.spec.tsx @@ -1,7 +1,7 @@ -import type { FileEntity } from '../types' +import type { FileEntity } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' import { TransferMethod } from '@/types/app' -import FileImageItem from './file-image-item' +import FileImageItem from '../file-image-item' vi.mock('@/utils/download', () => ({ downloadUrl: vi.fn(), diff --git a/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-item.spec.tsx b/web/app/components/base/file-uploader/file-uploader-in-chat-input/__tests__/file-item.spec.tsx similarity index 98% rename from web/app/components/base/file-uploader/file-uploader-in-chat-input/file-item.spec.tsx rename to web/app/components/base/file-uploader/file-uploader-in-chat-input/__tests__/file-item.spec.tsx index 92ce1a5e9e..c03f009cee 100644 --- a/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-item.spec.tsx +++ b/web/app/components/base/file-uploader/file-uploader-in-chat-input/__tests__/file-item.spec.tsx @@ -1,7 +1,7 @@ -import type { FileEntity } from '../types' +import type { FileEntity } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' import { TransferMethod } from '@/types/app' -import FileItem from './file-item' +import FileItem from '../file-item' vi.mock('@/utils/download', () => ({ downloadUrl: vi.fn(), @@ -11,7 +11,7 @@ vi.mock('@/utils/format', () => ({ formatFileSize: (size: number) => `${size}B`, })) -vi.mock('../dynamic-pdf-preview', () => ({ +vi.mock('../../dynamic-pdf-preview', () => ({ default: ({ url, onCancel }: { url: string, onCancel: () => void }) => (
diff --git a/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-list.spec.tsx b/web/app/components/base/file-uploader/file-uploader-in-chat-input/__tests__/file-list.spec.tsx similarity index 95% rename from web/app/components/base/file-uploader/file-uploader-in-chat-input/file-list.spec.tsx rename to web/app/components/base/file-uploader/file-uploader-in-chat-input/__tests__/file-list.spec.tsx index cae64eb6cb..de0ae72e35 100644 --- a/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-list.spec.tsx +++ b/web/app/components/base/file-uploader/file-uploader-in-chat-input/__tests__/file-list.spec.tsx @@ -1,11 +1,11 @@ -import type { FileEntity } from '../types' +import type { FileEntity } from '../../types' import type { FileUpload } from '@/app/components/base/features/types' import { render, screen } from '@testing-library/react' import { TransferMethod } from '@/types/app' -import { FileContextProvider } from '../store' -import { FileList, FileListInChatInput } from './file-list' +import { FileContextProvider } from '../../store' +import { FileList, FileListInChatInput } from '../file-list' -vi.mock('../hooks', () => ({ +vi.mock('../../hooks', () => ({ useFile: () => ({ handleRemoveFile: vi.fn(), handleReUploadFile: vi.fn(), diff --git a/web/app/components/base/file-uploader/file-uploader-in-chat-input/index.spec.tsx b/web/app/components/base/file-uploader/file-uploader-in-chat-input/__tests__/index.spec.tsx similarity index 95% rename from web/app/components/base/file-uploader/file-uploader-in-chat-input/index.spec.tsx rename to web/app/components/base/file-uploader/file-uploader-in-chat-input/__tests__/index.spec.tsx index 0cdde4835d..233dba7c8e 100644 --- a/web/app/components/base/file-uploader/file-uploader-in-chat-input/index.spec.tsx +++ b/web/app/components/base/file-uploader/file-uploader-in-chat-input/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import type { FileUpload } from '@/app/components/base/features/types' import { fireEvent, render, screen } from '@testing-library/react' -import { FileContextProvider } from '../store' -import FileUploaderInChatInput from './index' +import { FileContextProvider } from '../../store' +import FileUploaderInChatInput from '../index' vi.mock('@/types/app', async (importOriginal) => { const actual = await importOriginal() @@ -14,7 +14,7 @@ vi.mock('@/types/app', async (importOriginal) => { } }) -vi.mock('../hooks', () => ({ +vi.mock('../../hooks', () => ({ useFile: () => ({ handleLoadFileFromLink: vi.fn(), }), diff --git a/web/app/components/base/float-right-container/index.spec.tsx b/web/app/components/base/float-right-container/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/float-right-container/index.spec.tsx rename to web/app/components/base/float-right-container/__tests__/index.spec.tsx index 4cf87b189c..ee820230d8 100644 --- a/web/app/components/base/float-right-container/index.spec.tsx +++ b/web/app/components/base/float-right-container/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import FloatRightContainer from './index' +import FloatRightContainer from '../index' describe('FloatRightContainer', () => { beforeEach(() => { diff --git a/web/app/components/base/form/index.spec.tsx b/web/app/components/base/form/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/form/index.spec.tsx rename to web/app/components/base/form/__tests__/index.spec.tsx index 27dab0c9dc..683c43a8db 100644 --- a/web/app/components/base/form/index.spec.tsx +++ b/web/app/components/base/form/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' -import { useAppForm, withForm } from './index' +import { useAppForm, withForm } from '../index' const FormHarness = ({ onSubmit }: { onSubmit: (value: Record) => void }) => { const form = useAppForm({ diff --git a/web/app/components/base/form/types.spec.ts b/web/app/components/base/form/__tests__/types.spec.ts similarity index 88% rename from web/app/components/base/form/types.spec.ts rename to web/app/components/base/form/__tests__/types.spec.ts index 38d032bac7..baf76f99b1 100644 --- a/web/app/components/base/form/types.spec.ts +++ b/web/app/components/base/form/__tests__/types.spec.ts @@ -1,4 +1,4 @@ -import { FormItemValidateStatusEnum, FormTypeEnum } from './types' +import { FormItemValidateStatusEnum, FormTypeEnum } from '../types' describe('form types', () => { it('should expose expected form type values', () => { diff --git a/web/app/components/base/form/components/label.spec.tsx b/web/app/components/base/form/components/__tests__/label.spec.tsx similarity index 98% rename from web/app/components/base/form/components/label.spec.tsx rename to web/app/components/base/form/components/__tests__/label.spec.tsx index ebda6d5039..a3f564dafe 100644 --- a/web/app/components/base/form/components/label.spec.tsx +++ b/web/app/components/base/form/components/__tests__/label.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import Label from './label' +import Label from '../label' describe('Label', () => { const defaultProps = { diff --git a/web/app/components/base/form/components/base/base-field.spec.tsx b/web/app/components/base/form/components/base/__tests__/base-field.spec.tsx similarity index 99% rename from web/app/components/base/form/components/base/base-field.spec.tsx rename to web/app/components/base/form/components/base/__tests__/base-field.spec.tsx index 7c50b524a5..898dc8a821 100644 --- a/web/app/components/base/form/components/base/base-field.spec.tsx +++ b/web/app/components/base/form/components/base/__tests__/base-field.spec.tsx @@ -3,7 +3,7 @@ import type { FormSchema } from '@/app/components/base/form/types' import { useForm } from '@tanstack/react-form' import { fireEvent, render, screen } from '@testing-library/react' import { FormItemValidateStatusEnum, FormTypeEnum } from '@/app/components/base/form/types' -import BaseField from './base-field' +import BaseField from '../base-field' const mockDynamicOptions = vi.fn() diff --git a/web/app/components/base/form/components/base/base-form.spec.tsx b/web/app/components/base/form/components/base/__tests__/base-form.spec.tsx similarity index 98% rename from web/app/components/base/form/components/base/base-form.spec.tsx rename to web/app/components/base/form/components/base/__tests__/base-form.spec.tsx index 5d2c662aa3..f887aaea64 100644 --- a/web/app/components/base/form/components/base/base-form.spec.tsx +++ b/web/app/components/base/form/components/base/__tests__/base-form.spec.tsx @@ -1,7 +1,7 @@ import type { FormRefObject, FormSchema } from '@/app/components/base/form/types' import { act, fireEvent, render, screen } from '@testing-library/react' import { FormTypeEnum } from '@/app/components/base/form/types' -import BaseForm from './base-form' +import BaseForm from '../base-form' vi.mock('@/service/use-triggers', () => ({ useTriggerPluginDynamicOptions: () => ({ diff --git a/web/app/components/base/form/components/base/index.spec.tsx b/web/app/components/base/form/components/base/__tests__/index.spec.tsx similarity index 83% rename from web/app/components/base/form/components/base/index.spec.tsx rename to web/app/components/base/form/components/base/__tests__/index.spec.tsx index 16f9806b27..81190d75bd 100644 --- a/web/app/components/base/form/components/base/index.spec.tsx +++ b/web/app/components/base/form/components/base/__tests__/index.spec.tsx @@ -1,4 +1,4 @@ -import { BaseField, BaseForm } from '.' +import { BaseField, BaseForm } from '..' describe('base component exports', () => { it('should export BaseField', () => { diff --git a/web/app/components/base/form/components/field/checkbox.spec.tsx b/web/app/components/base/form/components/field/__tests__/checkbox.spec.tsx similarity index 92% rename from web/app/components/base/form/components/field/checkbox.spec.tsx rename to web/app/components/base/form/components/field/__tests__/checkbox.spec.tsx index ee7d8ee6ab..6005d9261b 100644 --- a/web/app/components/base/form/components/field/checkbox.spec.tsx +++ b/web/app/components/base/form/components/field/__tests__/checkbox.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import CheckboxField from './checkbox' +import CheckboxField from '../checkbox' const mockField = { name: 'checkbox-field', @@ -9,7 +9,7 @@ const mockField = { handleChange: vi.fn(), } -vi.mock('../..', () => ({ +vi.mock('../../..', () => ({ useFieldContext: () => mockField, })) diff --git a/web/app/components/base/form/components/field/custom-select.spec.tsx b/web/app/components/base/form/components/field/__tests__/custom-select.spec.tsx similarity index 93% rename from web/app/components/base/form/components/field/custom-select.spec.tsx rename to web/app/components/base/form/components/field/__tests__/custom-select.spec.tsx index 97f13758ec..5470df58a3 100644 --- a/web/app/components/base/form/components/field/custom-select.spec.tsx +++ b/web/app/components/base/form/components/field/__tests__/custom-select.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import CustomSelectField from './custom-select' +import CustomSelectField from '../custom-select' const mockField = { name: 'custom-select-field', @@ -9,7 +9,7 @@ const mockField = { handleChange: vi.fn(), } -vi.mock('../..', () => ({ +vi.mock('../../..', () => ({ useFieldContext: () => mockField, })) diff --git a/web/app/components/base/form/components/field/file-types.spec.tsx b/web/app/components/base/form/components/field/__tests__/file-types.spec.tsx similarity index 98% rename from web/app/components/base/form/components/field/file-types.spec.tsx rename to web/app/components/base/form/components/field/__tests__/file-types.spec.tsx index 0c2a95c655..971e04f258 100644 --- a/web/app/components/base/form/components/field/file-types.spec.tsx +++ b/web/app/components/base/form/components/field/__tests__/file-types.spec.tsx @@ -1,6 +1,6 @@ import { fireEvent, render, screen } from '@testing-library/react' import { SupportUploadFileTypes } from '@/app/components/workflow/types' -import FileTypesField from './file-types' +import FileTypesField from '../file-types' type FileTypeValue = { allowedFileTypes: string[] @@ -18,7 +18,7 @@ const mockField = { handleChange: vi.fn(), } -vi.mock('../..', () => ({ +vi.mock('../../..', () => ({ useFieldContext: () => mockField, })) diff --git a/web/app/components/base/form/components/field/file-uploader.spec.tsx b/web/app/components/base/form/components/field/__tests__/file-uploader.spec.tsx similarity index 96% rename from web/app/components/base/form/components/field/file-uploader.spec.tsx rename to web/app/components/base/form/components/field/__tests__/file-uploader.spec.tsx index c32d370346..dee7c97222 100644 --- a/web/app/components/base/form/components/field/file-uploader.spec.tsx +++ b/web/app/components/base/form/components/field/__tests__/file-uploader.spec.tsx @@ -1,7 +1,7 @@ import { fireEvent, render, screen } from '@testing-library/react' import { SupportUploadFileTypes } from '@/app/components/workflow/types' import { TransferMethod } from '@/types/app' -import FileUploaderField from './file-uploader' +import FileUploaderField from '../file-uploader' const mockField = { name: 'files', @@ -23,7 +23,7 @@ const mockField = { handleChange: vi.fn(), } -vi.mock('../..', () => ({ +vi.mock('../../..', () => ({ useFieldContext: () => mockField, })) diff --git a/web/app/components/base/form/components/field/number-input.spec.tsx b/web/app/components/base/form/components/field/__tests__/number-input.spec.tsx similarity index 90% rename from web/app/components/base/form/components/field/number-input.spec.tsx rename to web/app/components/base/form/components/field/__tests__/number-input.spec.tsx index 85c46f1df2..049e19d75e 100644 --- a/web/app/components/base/form/components/field/number-input.spec.tsx +++ b/web/app/components/base/form/components/field/__tests__/number-input.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import NumberInputField from './number-input' +import NumberInputField from '../number-input' const mockField = { name: 'number-field', @@ -10,7 +10,7 @@ const mockField = { handleBlur: vi.fn(), } -vi.mock('../..', () => ({ +vi.mock('../../..', () => ({ useFieldContext: () => mockField, })) diff --git a/web/app/components/base/form/components/field/number-slider.spec.tsx b/web/app/components/base/form/components/field/__tests__/number-slider.spec.tsx similarity index 93% rename from web/app/components/base/form/components/field/number-slider.spec.tsx rename to web/app/components/base/form/components/field/__tests__/number-slider.spec.tsx index a9676c4338..ca0e83462f 100644 --- a/web/app/components/base/form/components/field/number-slider.spec.tsx +++ b/web/app/components/base/form/components/field/__tests__/number-slider.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import NumberSliderField from './number-slider' +import NumberSliderField from '../number-slider' const mockField = { name: 'slider-field', @@ -9,7 +9,7 @@ const mockField = { handleChange: vi.fn(), } -vi.mock('../..', () => ({ +vi.mock('../../..', () => ({ useFieldContext: () => mockField, })) diff --git a/web/app/components/base/form/components/field/options.spec.tsx b/web/app/components/base/form/components/field/__tests__/options.spec.tsx similarity index 94% rename from web/app/components/base/form/components/field/options.spec.tsx rename to web/app/components/base/form/components/field/__tests__/options.spec.tsx index a7860079c6..93f956a4c5 100644 --- a/web/app/components/base/form/components/field/options.spec.tsx +++ b/web/app/components/base/form/components/field/__tests__/options.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import OptionsField from './options' +import OptionsField from '../options' const mockField = { name: 'options-field', @@ -9,7 +9,7 @@ const mockField = { handleChange: vi.fn(), } -vi.mock('../..', () => ({ +vi.mock('../../..', () => ({ useFieldContext: () => mockField, })) diff --git a/web/app/components/base/form/components/field/select.spec.tsx b/web/app/components/base/form/components/field/__tests__/select.spec.tsx similarity index 94% rename from web/app/components/base/form/components/field/select.spec.tsx rename to web/app/components/base/form/components/field/__tests__/select.spec.tsx index d38a9ac511..0bf6b4e022 100644 --- a/web/app/components/base/form/components/field/select.spec.tsx +++ b/web/app/components/base/form/components/field/__tests__/select.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import SelectField from './select' +import SelectField from '../select' const mockField = { name: 'select-field', @@ -9,7 +9,7 @@ const mockField = { handleChange: vi.fn(), } -vi.mock('../..', () => ({ +vi.mock('../../..', () => ({ useFieldContext: () => mockField, })) diff --git a/web/app/components/base/form/components/field/text-area.spec.tsx b/web/app/components/base/form/components/field/__tests__/text-area.spec.tsx similarity index 92% rename from web/app/components/base/form/components/field/text-area.spec.tsx rename to web/app/components/base/form/components/field/__tests__/text-area.spec.tsx index 78b1be14e5..00033cdad5 100644 --- a/web/app/components/base/form/components/field/text-area.spec.tsx +++ b/web/app/components/base/form/components/field/__tests__/text-area.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import TextAreaField from './text-area' +import TextAreaField from '../text-area' const mockField = { name: 'text-area-field', @@ -10,7 +10,7 @@ const mockField = { handleBlur: vi.fn(), } -vi.mock('../..', () => ({ +vi.mock('../../..', () => ({ useFieldContext: () => mockField, })) diff --git a/web/app/components/base/form/components/field/text.spec.tsx b/web/app/components/base/form/components/field/__tests__/text.spec.tsx similarity index 92% rename from web/app/components/base/form/components/field/text.spec.tsx rename to web/app/components/base/form/components/field/__tests__/text.spec.tsx index 5a3010c6b4..5ebc82e858 100644 --- a/web/app/components/base/form/components/field/text.spec.tsx +++ b/web/app/components/base/form/components/field/__tests__/text.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import TextField from './text' +import TextField from '../text' const mockField = { name: 'text-field', @@ -10,7 +10,7 @@ const mockField = { handleBlur: vi.fn(), } -vi.mock('../..', () => ({ +vi.mock('../../..', () => ({ useFieldContext: () => mockField, })) diff --git a/web/app/components/base/form/components/field/upload-method.spec.tsx b/web/app/components/base/form/components/field/__tests__/upload-method.spec.tsx similarity index 95% rename from web/app/components/base/form/components/field/upload-method.spec.tsx rename to web/app/components/base/form/components/field/__tests__/upload-method.spec.tsx index 27d937ffb2..652f1e9171 100644 --- a/web/app/components/base/form/components/field/upload-method.spec.tsx +++ b/web/app/components/base/form/components/field/__tests__/upload-method.spec.tsx @@ -1,6 +1,6 @@ import { fireEvent, render, screen } from '@testing-library/react' import { TransferMethod } from '@/types/app' -import UploadMethodField from './upload-method' +import UploadMethodField from '../upload-method' const mockField = { name: 'upload-method', @@ -10,7 +10,7 @@ const mockField = { handleChange: vi.fn(), } -vi.mock('../..', () => ({ +vi.mock('../../..', () => ({ useFieldContext: () => mockField, })) diff --git a/web/app/components/base/form/components/field/variable-or-constant-input.spec.tsx b/web/app/components/base/form/components/field/__tests__/variable-or-constant-input.spec.tsx similarity index 96% rename from web/app/components/base/form/components/field/variable-or-constant-input.spec.tsx rename to web/app/components/base/form/components/field/__tests__/variable-or-constant-input.spec.tsx index 57db5ec0d6..5842f5c75b 100644 --- a/web/app/components/base/form/components/field/variable-or-constant-input.spec.tsx +++ b/web/app/components/base/form/components/field/__tests__/variable-or-constant-input.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import VariableOrConstantInputField from './variable-or-constant-input' +import VariableOrConstantInputField from '../variable-or-constant-input' vi.mock('@/app/components/workflow/nodes/_base/components/variable/var-reference-picker', () => ({ default: ({ onChange }: { onChange?: () => void }) => ( diff --git a/web/app/components/base/form/components/field/variable-selector.spec.tsx b/web/app/components/base/form/components/field/__tests__/variable-selector.spec.tsx similarity index 94% rename from web/app/components/base/form/components/field/variable-selector.spec.tsx rename to web/app/components/base/form/components/field/__tests__/variable-selector.spec.tsx index ba9e0e9ca7..df6f6b2531 100644 --- a/web/app/components/base/form/components/field/variable-selector.spec.tsx +++ b/web/app/components/base/form/components/field/__tests__/variable-selector.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import VariableSelectorField from './variable-selector' +import VariableSelectorField from '../variable-selector' vi.mock('@/app/components/workflow/nodes/_base/components/variable/var-reference-picker', () => ({ default: ({ onChange }: { onChange?: () => void }) => ( diff --git a/web/app/components/base/form/components/field/input-type-select/hooks.spec.tsx b/web/app/components/base/form/components/field/input-type-select/__tests__/hooks.spec.tsx similarity index 93% rename from web/app/components/base/form/components/field/input-type-select/hooks.spec.tsx rename to web/app/components/base/form/components/field/input-type-select/__tests__/hooks.spec.tsx index a556697db1..236bcc95ea 100644 --- a/web/app/components/base/form/components/field/input-type-select/hooks.spec.tsx +++ b/web/app/components/base/form/components/field/input-type-select/__tests__/hooks.spec.tsx @@ -1,5 +1,5 @@ import { renderHook } from '@testing-library/react' -import { useInputTypeOptions } from './hooks' +import { useInputTypeOptions } from '../hooks' describe('useInputTypeOptions', () => { it('should include file options when supportFile is true', () => { diff --git a/web/app/components/base/form/components/field/input-type-select/index.spec.tsx b/web/app/components/base/form/components/field/input-type-select/__tests__/index.spec.tsx similarity index 93% rename from web/app/components/base/form/components/field/input-type-select/index.spec.tsx rename to web/app/components/base/form/components/field/input-type-select/__tests__/index.spec.tsx index e31cf17af5..bb7ae80a34 100644 --- a/web/app/components/base/form/components/field/input-type-select/index.spec.tsx +++ b/web/app/components/base/form/components/field/input-type-select/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import InputTypeSelectField from './index' +import InputTypeSelectField from '../index' const mockField = { name: 'input-type', @@ -9,7 +9,7 @@ const mockField = { handleChange: vi.fn(), } -vi.mock('../../..', () => ({ +vi.mock('../../../..', () => ({ useFieldContext: () => mockField, })) diff --git a/web/app/components/base/form/components/field/input-type-select/option.spec.tsx b/web/app/components/base/form/components/field/input-type-select/__tests__/option.spec.tsx similarity index 94% rename from web/app/components/base/form/components/field/input-type-select/option.spec.tsx rename to web/app/components/base/form/components/field/input-type-select/__tests__/option.spec.tsx index 475ef20410..a3dc91193b 100644 --- a/web/app/components/base/form/components/field/input-type-select/option.spec.tsx +++ b/web/app/components/base/form/components/field/input-type-select/__tests__/option.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import Option from './option' +import Option from '../option' const MockIcon = () => diff --git a/web/app/components/base/form/components/field/input-type-select/trigger.spec.tsx b/web/app/components/base/form/components/field/input-type-select/__tests__/trigger.spec.tsx similarity index 95% rename from web/app/components/base/form/components/field/input-type-select/trigger.spec.tsx rename to web/app/components/base/form/components/field/input-type-select/__tests__/trigger.spec.tsx index 0bd2274703..0957ac41c1 100644 --- a/web/app/components/base/form/components/field/input-type-select/trigger.spec.tsx +++ b/web/app/components/base/form/components/field/input-type-select/__tests__/trigger.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import Trigger from './trigger' +import Trigger from '../trigger' const MockIcon = () => diff --git a/web/app/components/base/form/components/field/input-type-select/types.spec.ts b/web/app/components/base/form/components/field/input-type-select/__tests__/types.spec.ts similarity index 89% rename from web/app/components/base/form/components/field/input-type-select/types.spec.ts rename to web/app/components/base/form/components/field/input-type-select/__tests__/types.spec.ts index 3260f54ce4..5d2215f1fa 100644 --- a/web/app/components/base/form/components/field/input-type-select/types.spec.ts +++ b/web/app/components/base/form/components/field/input-type-select/__tests__/types.spec.ts @@ -1,4 +1,4 @@ -import { InputTypeEnum } from './types' +import { InputTypeEnum } from '../types' describe('InputTypeEnum', () => { it('should accept valid input types', () => { diff --git a/web/app/components/base/form/components/field/mixed-variable-text-input/index.spec.tsx b/web/app/components/base/form/components/field/mixed-variable-text-input/__tests__/index.spec.tsx similarity index 93% rename from web/app/components/base/form/components/field/mixed-variable-text-input/index.spec.tsx rename to web/app/components/base/form/components/field/mixed-variable-text-input/__tests__/index.spec.tsx index 94a0c8746f..3a6be12c58 100644 --- a/web/app/components/base/form/components/field/mixed-variable-text-input/index.spec.tsx +++ b/web/app/components/base/form/components/field/mixed-variable-text-input/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import MixedVariableTextInput from './index' +import MixedVariableTextInput from '../index' describe('MixedVariableTextInput', () => { it('should render placeholder guidance and data type badge', () => { diff --git a/web/app/components/base/form/components/field/mixed-variable-text-input/placeholder.spec.tsx b/web/app/components/base/form/components/field/mixed-variable-text-input/__tests__/placeholder.spec.tsx similarity index 98% rename from web/app/components/base/form/components/field/mixed-variable-text-input/placeholder.spec.tsx rename to web/app/components/base/form/components/field/mixed-variable-text-input/__tests__/placeholder.spec.tsx index 6ce68c3b47..093131d01f 100644 --- a/web/app/components/base/form/components/field/mixed-variable-text-input/placeholder.spec.tsx +++ b/web/app/components/base/form/components/field/mixed-variable-text-input/__tests__/placeholder.spec.tsx @@ -5,7 +5,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { $getRoot } from 'lexical' import { CustomTextNode } from '@/app/components/base/prompt-editor/plugins/custom-text/node' -import Placeholder from './placeholder' +import Placeholder from '../placeholder' const config = { namespace: 'placeholder-test', diff --git a/web/app/components/base/form/components/form/actions.spec.tsx b/web/app/components/base/form/components/form/__tests__/actions.spec.tsx similarity index 92% rename from web/app/components/base/form/components/form/actions.spec.tsx rename to web/app/components/base/form/components/form/__tests__/actions.spec.tsx index eb4a6ea146..0bd6655cb5 100644 --- a/web/app/components/base/form/components/form/actions.spec.tsx +++ b/web/app/components/base/form/components/form/__tests__/actions.spec.tsx @@ -1,8 +1,8 @@ -import type { FormType } from '../..' -import type { CustomActionsProps } from './actions' +import type { FormType } from '../../..' +import type { CustomActionsProps } from '../actions' import { fireEvent, render, screen } from '@testing-library/react' -import { formContext } from '../..' -import Actions from './actions' +import { formContext } from '../../..' +import Actions from '../actions' const renderWithForm = ({ canSubmit, diff --git a/web/app/components/base/form/form-scenarios/auth/index.spec.tsx b/web/app/components/base/form/form-scenarios/auth/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/form/form-scenarios/auth/index.spec.tsx rename to web/app/components/base/form/form-scenarios/auth/__tests__/index.spec.tsx index 5560e7eada..e12397ed60 100644 --- a/web/app/components/base/form/form-scenarios/auth/index.spec.tsx +++ b/web/app/components/base/form/form-scenarios/auth/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen } from '@testing-library/react' import { FormTypeEnum } from '@/app/components/base/form/types' -import AuthForm from './index' +import AuthForm from '../index' const formSchemas = [{ type: FormTypeEnum.textInput, diff --git a/web/app/components/base/form/form-scenarios/base/field.spec.tsx b/web/app/components/base/form/form-scenarios/base/__tests__/field.spec.tsx similarity index 96% rename from web/app/components/base/form/form-scenarios/base/field.spec.tsx rename to web/app/components/base/form/form-scenarios/base/__tests__/field.spec.tsx index c05f291103..7de473e4c8 100644 --- a/web/app/components/base/form/form-scenarios/base/field.spec.tsx +++ b/web/app/components/base/form/form-scenarios/base/__tests__/field.spec.tsx @@ -1,10 +1,10 @@ -import type { BaseConfiguration } from './types' +import type { BaseConfiguration } from '../types' import { render, screen } from '@testing-library/react' import { useMemo } from 'react' import { TransferMethod } from '@/types/app' -import { useAppForm } from '../..' -import BaseField from './field' -import { BaseFieldType } from './types' +import { useAppForm } from '../../..' +import BaseField from '../field' +import { BaseFieldType } from '../types' vi.mock('next/navigation', () => ({ useParams: () => ({}), diff --git a/web/app/components/base/form/form-scenarios/base/index.spec.tsx b/web/app/components/base/form/form-scenarios/base/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/form/form-scenarios/base/index.spec.tsx rename to web/app/components/base/form/form-scenarios/base/__tests__/index.spec.tsx index fc1aa325f2..c8d215b1d7 100644 --- a/web/app/components/base/form/form-scenarios/base/index.spec.tsx +++ b/web/app/components/base/form/form-scenarios/base/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' -import BaseForm from './index' -import { BaseFieldType } from './types' +import BaseForm from '../index' +import { BaseFieldType } from '../types' const baseConfigurations = [{ type: BaseFieldType.textInput, diff --git a/web/app/components/base/form/form-scenarios/base/types.spec.ts b/web/app/components/base/form/form-scenarios/base/__tests__/types.spec.ts similarity index 87% rename from web/app/components/base/form/form-scenarios/base/types.spec.ts rename to web/app/components/base/form/form-scenarios/base/__tests__/types.spec.ts index b565b5cd2a..33e402b78e 100644 --- a/web/app/components/base/form/form-scenarios/base/types.spec.ts +++ b/web/app/components/base/form/form-scenarios/base/__tests__/types.spec.ts @@ -1,4 +1,4 @@ -import { BaseFieldType } from './types' +import { BaseFieldType } from '../types' describe('base scenario types', () => { it('should include all supported base field types', () => { diff --git a/web/app/components/base/form/form-scenarios/base/utils.spec.ts b/web/app/components/base/form/form-scenarios/base/__tests__/utils.spec.ts similarity index 94% rename from web/app/components/base/form/form-scenarios/base/utils.spec.ts rename to web/app/components/base/form/form-scenarios/base/__tests__/utils.spec.ts index 2c11acd205..36a2cc1dd4 100644 --- a/web/app/components/base/form/form-scenarios/base/utils.spec.ts +++ b/web/app/components/base/form/form-scenarios/base/__tests__/utils.spec.ts @@ -1,5 +1,5 @@ -import { BaseFieldType } from './types' -import { generateZodSchema } from './utils' +import { BaseFieldType } from '../types' +import { generateZodSchema } from '../utils' describe('base scenario schema generator', () => { it('should validate required text fields with max length', () => { diff --git a/web/app/components/base/form/form-scenarios/demo/contact-fields.spec.tsx b/web/app/components/base/form/form-scenarios/demo/__tests__/contact-fields.spec.tsx similarity index 83% rename from web/app/components/base/form/form-scenarios/demo/contact-fields.spec.tsx rename to web/app/components/base/form/form-scenarios/demo/__tests__/contact-fields.spec.tsx index 7a97d3a48b..b8f67d58b9 100644 --- a/web/app/components/base/form/form-scenarios/demo/contact-fields.spec.tsx +++ b/web/app/components/base/form/form-scenarios/demo/__tests__/contact-fields.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' -import { useAppForm } from '../..' -import ContactFields from './contact-fields' -import { demoFormOpts } from './shared-options' +import { useAppForm } from '../../..' +import ContactFields from '../contact-fields' +import { demoFormOpts } from '../shared-options' const ContactFieldsHarness = () => { const form = useAppForm({ diff --git a/web/app/components/base/form/form-scenarios/demo/index.spec.tsx b/web/app/components/base/form/form-scenarios/demo/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/form/form-scenarios/demo/index.spec.tsx rename to web/app/components/base/form/form-scenarios/demo/__tests__/index.spec.tsx index d6534e8df7..e2a83b7ad4 100644 --- a/web/app/components/base/form/form-scenarios/demo/index.spec.tsx +++ b/web/app/components/base/form/form-scenarios/demo/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' -import DemoForm from './index' +import DemoForm from '../index' describe('DemoForm', () => { const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) diff --git a/web/app/components/base/form/form-scenarios/demo/shared-options.spec.tsx b/web/app/components/base/form/form-scenarios/demo/__tests__/shared-options.spec.tsx similarity index 86% rename from web/app/components/base/form/form-scenarios/demo/shared-options.spec.tsx rename to web/app/components/base/form/form-scenarios/demo/__tests__/shared-options.spec.tsx index 5e44747612..70e078fcf5 100644 --- a/web/app/components/base/form/form-scenarios/demo/shared-options.spec.tsx +++ b/web/app/components/base/form/form-scenarios/demo/__tests__/shared-options.spec.tsx @@ -1,4 +1,4 @@ -import { demoFormOpts } from './shared-options' +import { demoFormOpts } from '../shared-options' describe('demoFormOpts', () => { it('should provide expected default values', () => { diff --git a/web/app/components/base/form/form-scenarios/demo/types.spec.ts b/web/app/components/base/form/form-scenarios/demo/__tests__/types.spec.ts similarity index 94% rename from web/app/components/base/form/form-scenarios/demo/types.spec.ts rename to web/app/components/base/form/form-scenarios/demo/__tests__/types.spec.ts index 8e81f24c1c..e164a190c8 100644 --- a/web/app/components/base/form/form-scenarios/demo/types.spec.ts +++ b/web/app/components/base/form/form-scenarios/demo/__tests__/types.spec.ts @@ -1,4 +1,4 @@ -import { ContactMethods, UserSchema } from './types' +import { ContactMethods, UserSchema } from '../types' describe('demo scenario types', () => { it('should expose contact methods with capitalized labels', () => { diff --git a/web/app/components/base/form/form-scenarios/input-field/field.spec.tsx b/web/app/components/base/form/form-scenarios/input-field/__tests__/field.spec.tsx similarity index 96% rename from web/app/components/base/form/form-scenarios/input-field/field.spec.tsx rename to web/app/components/base/form/form-scenarios/input-field/__tests__/field.spec.tsx index 0416c1532c..d89952f569 100644 --- a/web/app/components/base/form/form-scenarios/input-field/field.spec.tsx +++ b/web/app/components/base/form/form-scenarios/input-field/__tests__/field.spec.tsx @@ -1,9 +1,9 @@ -import type { InputFieldConfiguration } from './types' +import type { InputFieldConfiguration } from '../types' import { render, screen } from '@testing-library/react' import { useMemo } from 'react' -import { useAppForm } from '../..' -import InputField from './field' -import { InputFieldType } from './types' +import { useAppForm } from '../../..' +import InputField from '../field' +import { InputFieldType } from '../types' const createConfig = (overrides: Partial = {}): InputFieldConfiguration => ({ type: InputFieldType.textInput, diff --git a/web/app/components/base/form/form-scenarios/input-field/types.spec.ts b/web/app/components/base/form/form-scenarios/input-field/__tests__/types.spec.ts similarity index 89% rename from web/app/components/base/form/form-scenarios/input-field/types.spec.ts rename to web/app/components/base/form/form-scenarios/input-field/__tests__/types.spec.ts index b9328b2089..9347d1bb58 100644 --- a/web/app/components/base/form/form-scenarios/input-field/types.spec.ts +++ b/web/app/components/base/form/form-scenarios/input-field/__tests__/types.spec.ts @@ -1,4 +1,4 @@ -import { InputFieldType } from './types' +import { InputFieldType } from '../types' describe('input-field scenario types', () => { it('should include expected input field types', () => { diff --git a/web/app/components/base/form/form-scenarios/input-field/utils.spec.ts b/web/app/components/base/form/form-scenarios/input-field/__tests__/utils.spec.ts similarity index 97% rename from web/app/components/base/form/form-scenarios/input-field/utils.spec.ts rename to web/app/components/base/form/form-scenarios/input-field/__tests__/utils.spec.ts index 7f91d3cd70..fdb958b4ae 100644 --- a/web/app/components/base/form/form-scenarios/input-field/utils.spec.ts +++ b/web/app/components/base/form/form-scenarios/input-field/__tests__/utils.spec.ts @@ -1,5 +1,5 @@ -import { InputFieldType } from './types' -import { generateZodSchema } from './utils' +import { InputFieldType } from '../types' +import { generateZodSchema } from '../utils' describe('input-field scenario schema generator', () => { it('should validate required text input with max length', () => { diff --git a/web/app/components/base/form/form-scenarios/node-panel/field.spec.tsx b/web/app/components/base/form/form-scenarios/node-panel/__tests__/field.spec.tsx similarity index 96% rename from web/app/components/base/form/form-scenarios/node-panel/field.spec.tsx rename to web/app/components/base/form/form-scenarios/node-panel/__tests__/field.spec.tsx index b8388206c0..25808cfdda 100644 --- a/web/app/components/base/form/form-scenarios/node-panel/field.spec.tsx +++ b/web/app/components/base/form/form-scenarios/node-panel/__tests__/field.spec.tsx @@ -1,12 +1,12 @@ import type { ReactNode } from 'react' -import type { InputFieldConfiguration } from './types' +import type { InputFieldConfiguration } from '../types' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen } from '@testing-library/react' import { useMemo } from 'react' import { ReactFlowProvider } from 'reactflow' -import { useAppForm } from '../..' -import NodePanelField from './field' -import { InputFieldType } from './types' +import { useAppForm } from '../../..' +import NodePanelField from '../field' +import { InputFieldType } from '../types' vi.mock('@/app/components/workflow/nodes/_base/components/variable/var-reference-picker', () => ({ default: () =>
Variable Picker
, diff --git a/web/app/components/base/form/form-scenarios/node-panel/types.spec.ts b/web/app/components/base/form/form-scenarios/node-panel/__tests__/types.spec.ts similarity index 81% rename from web/app/components/base/form/form-scenarios/node-panel/types.spec.ts rename to web/app/components/base/form/form-scenarios/node-panel/__tests__/types.spec.ts index 8cd27eab08..b80e29652d 100644 --- a/web/app/components/base/form/form-scenarios/node-panel/types.spec.ts +++ b/web/app/components/base/form/form-scenarios/node-panel/__tests__/types.spec.ts @@ -1,4 +1,4 @@ -import { InputFieldType } from './types' +import { InputFieldType } from '../types' describe('node-panel scenario types', () => { it('should include variableOrConstant field type', () => { diff --git a/web/app/components/base/form/hooks/index.spec.ts b/web/app/components/base/form/hooks/__tests__/index.spec.ts similarity index 57% rename from web/app/components/base/form/hooks/index.spec.ts rename to web/app/components/base/form/hooks/__tests__/index.spec.ts index d76743702a..9c0ced74a7 100644 --- a/web/app/components/base/form/hooks/index.spec.ts +++ b/web/app/components/base/form/hooks/__tests__/index.spec.ts @@ -1,7 +1,7 @@ -import * as hookExports from './index' -import { useCheckValidated } from './use-check-validated' -import { useGetFormValues } from './use-get-form-values' -import { useGetValidators } from './use-get-validators' +import * as hookExports from '../index' +import { useCheckValidated } from '../use-check-validated' +import { useGetFormValues } from '../use-get-form-values' +import { useGetValidators } from '../use-get-validators' describe('hooks index exports', () => { it('should re-export all hook modules', () => { diff --git a/web/app/components/base/form/hooks/use-check-validated.spec.ts b/web/app/components/base/form/hooks/__tests__/use-check-validated.spec.ts similarity index 96% rename from web/app/components/base/form/hooks/use-check-validated.spec.ts rename to web/app/components/base/form/hooks/__tests__/use-check-validated.spec.ts index a8f15b403e..b9d60594f7 100644 --- a/web/app/components/base/form/hooks/use-check-validated.spec.ts +++ b/web/app/components/base/form/hooks/__tests__/use-check-validated.spec.ts @@ -1,7 +1,7 @@ import type { AnyFormApi } from '@tanstack/react-form' import { renderHook } from '@testing-library/react' -import { FormTypeEnum } from '../types' -import { useCheckValidated } from './use-check-validated' +import { FormTypeEnum } from '../../types' +import { useCheckValidated } from '../use-check-validated' const mockNotify = vi.fn() diff --git a/web/app/components/base/form/hooks/use-get-form-values.spec.ts b/web/app/components/base/form/hooks/__tests__/use-get-form-values.spec.ts similarity index 91% rename from web/app/components/base/form/hooks/use-get-form-values.spec.ts rename to web/app/components/base/form/hooks/__tests__/use-get-form-values.spec.ts index 163f959eff..8457bdcb8c 100644 --- a/web/app/components/base/form/hooks/use-get-form-values.spec.ts +++ b/web/app/components/base/form/hooks/__tests__/use-get-form-values.spec.ts @@ -1,18 +1,18 @@ import type { AnyFormApi } from '@tanstack/react-form' import { renderHook } from '@testing-library/react' -import { FormTypeEnum } from '../types' -import { useGetFormValues } from './use-get-form-values' +import { FormTypeEnum } from '../../types' +import { useGetFormValues } from '../use-get-form-values' const mockCheckValidated = vi.fn() const mockTransform = vi.fn() -vi.mock('./use-check-validated', () => ({ +vi.mock('../use-check-validated', () => ({ useCheckValidated: () => ({ checkValidated: mockCheckValidated, }), })) -vi.mock('../utils/secret-input', () => ({ +vi.mock('../../utils/secret-input', () => ({ getTransformedValuesWhenSecretInputPristine: (...args: unknown[]) => mockTransform(...args), })) diff --git a/web/app/components/base/form/hooks/use-get-validators.spec.ts b/web/app/components/base/form/hooks/__tests__/use-get-validators.spec.ts similarity index 96% rename from web/app/components/base/form/hooks/use-get-validators.spec.ts rename to web/app/components/base/form/hooks/__tests__/use-get-validators.spec.ts index 73c7b3f86d..b99056e44f 100644 --- a/web/app/components/base/form/hooks/use-get-validators.spec.ts +++ b/web/app/components/base/form/hooks/__tests__/use-get-validators.spec.ts @@ -1,7 +1,7 @@ import { renderHook } from '@testing-library/react' import { createElement } from 'react' -import { FormTypeEnum } from '../types' -import { useGetValidators } from './use-get-validators' +import { FormTypeEnum } from '../../types' +import { useGetValidators } from '../use-get-validators' vi.mock('@/hooks/use-i18n', () => ({ useRenderI18nObject: () => (obj: Record) => obj.en_US, diff --git a/web/app/components/base/form/utils/zod-submit-validator.spec.ts b/web/app/components/base/form/utils/__tests__/zod-submit-validator.spec.ts similarity index 94% rename from web/app/components/base/form/utils/zod-submit-validator.spec.ts rename to web/app/components/base/form/utils/__tests__/zod-submit-validator.spec.ts index 74635ae844..81bc77c7c3 100644 --- a/web/app/components/base/form/utils/zod-submit-validator.spec.ts +++ b/web/app/components/base/form/utils/__tests__/zod-submit-validator.spec.ts @@ -1,5 +1,5 @@ import * as z from 'zod' -import { zodSubmitValidator } from './zod-submit-validator' +import { zodSubmitValidator } from '../zod-submit-validator' describe('zodSubmitValidator', () => { it('should return undefined for valid values', () => { diff --git a/web/app/components/base/form/utils/secret-input/index.spec.ts b/web/app/components/base/form/utils/secret-input/__tests__/index.spec.ts similarity index 95% rename from web/app/components/base/form/utils/secret-input/index.spec.ts rename to web/app/components/base/form/utils/secret-input/__tests__/index.spec.ts index c5722007b6..c7e683841c 100644 --- a/web/app/components/base/form/utils/secret-input/index.spec.ts +++ b/web/app/components/base/form/utils/secret-input/__tests__/index.spec.ts @@ -1,6 +1,6 @@ import type { AnyFormApi } from '@tanstack/react-form' -import { FormTypeEnum } from '../../types' -import { getTransformedValuesWhenSecretInputPristine, transformFormSchemasSecretInput } from './index' +import { FormTypeEnum } from '../../../types' +import { getTransformedValuesWhenSecretInputPristine, transformFormSchemasSecretInput } from '../index' describe('secret input utilities', () => { it('should mask only selected truthy values in transformFormSchemasSecretInput', () => { diff --git a/web/app/components/base/fullscreen-modal/index.spec.tsx b/web/app/components/base/fullscreen-modal/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/fullscreen-modal/index.spec.tsx rename to web/app/components/base/fullscreen-modal/__tests__/index.spec.tsx index cf1484fc63..8affae3d57 100644 --- a/web/app/components/base/fullscreen-modal/index.spec.tsx +++ b/web/app/components/base/fullscreen-modal/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { act, fireEvent, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import FullScreenModal from './index' +import FullScreenModal from '../index' describe('FullScreenModal Component', () => { it('should not render anything when open is false', () => { diff --git a/web/app/components/base/ga/index.spec.tsx b/web/app/components/base/ga/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/ga/index.spec.tsx rename to web/app/components/base/ga/__tests__/index.spec.tsx index 954e0eba83..ee7f7a2a9d 100644 --- a/web/app/components/base/ga/index.spec.tsx +++ b/web/app/components/base/ga/__tests__/index.spec.tsx @@ -61,7 +61,7 @@ vi.mock('next/script', () => ({ })) const loadComponent = async () => { - const mod = await import('./index') + const mod = await import('../index') // mod.default is either an async function (server component) or // a React.memo object whose .type is the async function. const rawExport = mod.default as unknown diff --git a/web/app/components/base/grid-mask/index.spec.tsx b/web/app/components/base/grid-mask/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/grid-mask/index.spec.tsx rename to web/app/components/base/grid-mask/__tests__/index.spec.tsx index 28d806a69b..5aa4868c33 100644 --- a/web/app/components/base/grid-mask/index.spec.tsx +++ b/web/app/components/base/grid-mask/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' -import GridMask from './index' -import Style from './style.module.css' +import GridMask from '../index' +import Style from '../style.module.css' function renderGridMask(props: Partial> = {}, children: React.ReactNode = Child) { const { container } = render({children}) diff --git a/web/app/components/base/icons/IconBase.spec.tsx b/web/app/components/base/icons/__tests__/IconBase.spec.tsx similarity index 92% rename from web/app/components/base/icons/IconBase.spec.tsx rename to web/app/components/base/icons/__tests__/IconBase.spec.tsx index ba5efd8429..e833d5355b 100644 --- a/web/app/components/base/icons/IconBase.spec.tsx +++ b/web/app/components/base/icons/__tests__/IconBase.spec.tsx @@ -1,11 +1,11 @@ -import type { IconData } from './IconBase' +import type { IconData } from '../IconBase' import { fireEvent, render, screen } from '@testing-library/react' import * as React from 'react' -import IconBase from './IconBase' -import * as utils from './utils' +import IconBase from '../IconBase' +import * as utils from '../utils' // Mock the utils module -vi.mock('./utils', () => ({ +vi.mock('../utils', () => ({ generate: vi.fn((icon, key, props) => ( { describe('normalizeAttrs', () => { diff --git a/web/app/components/base/image-gallery/index.spec.tsx b/web/app/components/base/image-gallery/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/image-gallery/index.spec.tsx rename to web/app/components/base/image-gallery/__tests__/index.spec.tsx index 96967b541c..61187f1c5f 100644 --- a/web/app/components/base/image-gallery/index.spec.tsx +++ b/web/app/components/base/image-gallery/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import ImageGallery, { ImageGalleryTest } from '.' +import ImageGallery, { ImageGalleryTest } from '..' const getImages = (container: HTMLElement) => container.querySelectorAll('img') diff --git a/web/app/components/base/image-uploader/audio-preview.spec.tsx b/web/app/components/base/image-uploader/__tests__/audio-preview.spec.tsx similarity index 98% rename from web/app/components/base/image-uploader/audio-preview.spec.tsx rename to web/app/components/base/image-uploader/__tests__/audio-preview.spec.tsx index 72cfa7621d..0c92afba0a 100644 --- a/web/app/components/base/image-uploader/audio-preview.spec.tsx +++ b/web/app/components/base/image-uploader/__tests__/audio-preview.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import AudioPreview from './audio-preview' +import AudioPreview from '../audio-preview' describe('AudioPreview', () => { const defaultProps = { diff --git a/web/app/components/base/image-uploader/chat-image-uploader.spec.tsx b/web/app/components/base/image-uploader/__tests__/chat-image-uploader.spec.tsx similarity index 98% rename from web/app/components/base/image-uploader/chat-image-uploader.spec.tsx rename to web/app/components/base/image-uploader/__tests__/chat-image-uploader.spec.tsx index 80ef06410d..97954f79b0 100644 --- a/web/app/components/base/image-uploader/chat-image-uploader.spec.tsx +++ b/web/app/components/base/image-uploader/__tests__/chat-image-uploader.spec.tsx @@ -1,9 +1,9 @@ -import type { useLocalFileUploader } from './hooks' +import type { useLocalFileUploader } from '../hooks' import type { ImageFile, VisionSettings } from '@/types/app' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { Resolution, TransferMethod } from '@/types/app' -import ChatImageUploader from './chat-image-uploader' +import ChatImageUploader from '../chat-image-uploader' type LocalUploaderArgs = Parameters[0] @@ -12,7 +12,7 @@ const mocks = vi.hoisted(() => ({ handleLocalFileUpload: vi.fn<(file: File) => void>(), })) -vi.mock('./hooks', () => ({ +vi.mock('../hooks', () => ({ useLocalFileUploader: (args: LocalUploaderArgs) => { mocks.hookArgs = args return { diff --git a/web/app/components/base/image-uploader/hooks.spec.ts b/web/app/components/base/image-uploader/__tests__/hooks.spec.ts similarity index 99% rename from web/app/components/base/image-uploader/hooks.spec.ts rename to web/app/components/base/image-uploader/__tests__/hooks.spec.ts index 1de5691690..4d150830d0 100644 --- a/web/app/components/base/image-uploader/hooks.spec.ts +++ b/web/app/components/base/image-uploader/__tests__/hooks.spec.ts @@ -2,7 +2,7 @@ import type { ClipboardEvent, DragEvent } from 'react' import type { ImageFile, VisionSettings } from '@/types/app' import { act, renderHook } from '@testing-library/react' import { Resolution, TransferMethod } from '@/types/app' -import { useClipboardUploader, useDraggableUploader, useImageFiles, useLocalFileUploader } from './hooks' +import { useClipboardUploader, useDraggableUploader, useImageFiles, useLocalFileUploader } from '../hooks' const mockNotify = vi.fn() vi.mock('@/app/components/base/toast', () => ({ @@ -17,7 +17,7 @@ const { mockImageUpload, mockGetImageUploadErrorMessage } = vi.hoisted(() => ({ mockImageUpload: vi.fn(), mockGetImageUploadErrorMessage: vi.fn(() => 'Upload error'), })) -vi.mock('./utils', () => ({ +vi.mock('../utils', () => ({ imageUpload: mockImageUpload, getImageUploadErrorMessage: mockGetImageUploadErrorMessage, })) diff --git a/web/app/components/base/image-uploader/image-link-input.spec.tsx b/web/app/components/base/image-uploader/__tests__/image-link-input.spec.tsx similarity index 99% rename from web/app/components/base/image-uploader/image-link-input.spec.tsx rename to web/app/components/base/image-uploader/__tests__/image-link-input.spec.tsx index 209c5d4c0c..0e8fdaf72d 100644 --- a/web/app/components/base/image-uploader/image-link-input.spec.tsx +++ b/web/app/components/base/image-uploader/__tests__/image-link-input.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { TransferMethod } from '@/types/app' -import ImageLinkInput from './image-link-input' +import ImageLinkInput from '../image-link-input' describe('ImageLinkInput', () => { const defaultProps = { diff --git a/web/app/components/base/image-uploader/image-list.spec.tsx b/web/app/components/base/image-uploader/__tests__/image-list.spec.tsx similarity index 99% rename from web/app/components/base/image-uploader/image-list.spec.tsx rename to web/app/components/base/image-uploader/__tests__/image-list.spec.tsx index a00d6551f6..44353ca19f 100644 --- a/web/app/components/base/image-uploader/image-list.spec.tsx +++ b/web/app/components/base/image-uploader/__tests__/image-list.spec.tsx @@ -2,7 +2,7 @@ import type { ImageFile } from '@/types/app' import { fireEvent, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { TransferMethod } from '@/types/app' -import ImageList from './image-list' +import ImageList from '../image-list' const createLocalFile = (overrides: Partial = {}): ImageFile => ({ type: TransferMethod.local_file, diff --git a/web/app/components/base/image-uploader/image-preview.spec.tsx b/web/app/components/base/image-uploader/__tests__/image-preview.spec.tsx similarity index 99% rename from web/app/components/base/image-uploader/image-preview.spec.tsx rename to web/app/components/base/image-uploader/__tests__/image-preview.spec.tsx index 949ce01842..f7641f071f 100644 --- a/web/app/components/base/image-uploader/image-preview.spec.tsx +++ b/web/app/components/base/image-uploader/__tests__/image-preview.spec.tsx @@ -1,6 +1,6 @@ import { act, render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import ImagePreview from './image-preview' +import ImagePreview from '../image-preview' type HotkeyHandler = () => void diff --git a/web/app/components/base/image-uploader/text-generation-image-uploader.spec.tsx b/web/app/components/base/image-uploader/__tests__/text-generation-image-uploader.spec.tsx similarity index 98% rename from web/app/components/base/image-uploader/text-generation-image-uploader.spec.tsx rename to web/app/components/base/image-uploader/__tests__/text-generation-image-uploader.spec.tsx index 5bba9135b7..90f5a96169 100644 --- a/web/app/components/base/image-uploader/text-generation-image-uploader.spec.tsx +++ b/web/app/components/base/image-uploader/__tests__/text-generation-image-uploader.spec.tsx @@ -1,9 +1,9 @@ -import type { useLocalFileUploader } from './hooks' +import type { useLocalFileUploader } from '../hooks' import type { ImageFile, VisionSettings } from '@/types/app' import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { Resolution, TransferMethod } from '@/types/app' -import TextGenerationImageUploader from './text-generation-image-uploader' +import TextGenerationImageUploader from '../text-generation-image-uploader' type LocalUploaderArgs = Parameters[0] @@ -18,7 +18,7 @@ const mocks = vi.hoisted(() => ({ localUploaderArgs: undefined as LocalUploaderArgs | undefined, })) -vi.mock('./hooks', () => ({ +vi.mock('../hooks', () => ({ useImageFiles: () => ({ files: mocks.files, onUpload: mocks.onUpload, diff --git a/web/app/components/base/image-uploader/uploader.spec.tsx b/web/app/components/base/image-uploader/__tests__/uploader.spec.tsx similarity index 97% rename from web/app/components/base/image-uploader/uploader.spec.tsx rename to web/app/components/base/image-uploader/__tests__/uploader.spec.tsx index 7fd916a497..416a56fec5 100644 --- a/web/app/components/base/image-uploader/uploader.spec.tsx +++ b/web/app/components/base/image-uploader/__tests__/uploader.spec.tsx @@ -1,9 +1,9 @@ import type { ComponentProps } from 'react' -import type { useLocalFileUploader } from './hooks' +import type { useLocalFileUploader } from '../hooks' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { ALLOW_FILE_EXTENSIONS } from '@/types/app' -import Uploader from './uploader' +import Uploader from '../uploader' type LocalUploaderArgs = Parameters[0] @@ -12,7 +12,7 @@ const mocks = vi.hoisted(() => ({ handleLocalFileUpload: vi.fn<(file: File) => void>(), })) -vi.mock('./hooks', () => ({ +vi.mock('../hooks', () => ({ useLocalFileUploader: (args: LocalUploaderArgs) => { mocks.hookArgs = args return { diff --git a/web/app/components/base/image-uploader/utils.spec.ts b/web/app/components/base/image-uploader/__tests__/utils.spec.ts similarity index 98% rename from web/app/components/base/image-uploader/utils.spec.ts rename to web/app/components/base/image-uploader/__tests__/utils.spec.ts index dff7fa25c3..0596287654 100644 --- a/web/app/components/base/image-uploader/utils.spec.ts +++ b/web/app/components/base/image-uploader/__tests__/utils.spec.ts @@ -1,7 +1,7 @@ import type { TFunction } from 'i18next' import { waitFor } from '@testing-library/react' import { upload } from '@/service/base' -import { getImageUploadErrorMessage, imageUpload } from './utils' +import { getImageUploadErrorMessage, imageUpload } from '../utils' vi.mock('@/service/base', () => ({ upload: vi.fn(), diff --git a/web/app/components/base/image-uploader/video-preview.spec.tsx b/web/app/components/base/image-uploader/__tests__/video-preview.spec.tsx similarity index 98% rename from web/app/components/base/image-uploader/video-preview.spec.tsx rename to web/app/components/base/image-uploader/__tests__/video-preview.spec.tsx index c9501b9059..f56a4b82e4 100644 --- a/web/app/components/base/image-uploader/video-preview.spec.tsx +++ b/web/app/components/base/image-uploader/__tests__/video-preview.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import VideoPreview from './video-preview' +import VideoPreview from '../video-preview' const getOverlay = () => screen.getByTestId('video-preview') const getCloseButton = () => screen.getByTestId('close-button') diff --git a/web/app/components/base/inline-delete-confirm/index.spec.tsx b/web/app/components/base/inline-delete-confirm/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/inline-delete-confirm/index.spec.tsx rename to web/app/components/base/inline-delete-confirm/__tests__/index.spec.tsx index b770fccc88..6d615554dc 100644 --- a/web/app/components/base/inline-delete-confirm/index.spec.tsx +++ b/web/app/components/base/inline-delete-confirm/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { cleanup, fireEvent, render } from '@testing-library/react' import * as React from 'react' import { createReactI18nextMock } from '@/test/i18n-mock' -import InlineDeleteConfirm from './index' +import InlineDeleteConfirm from '../index' // Mock react-i18next with custom translations for test assertions vi.mock('react-i18next', () => createReactI18nextMock({ diff --git a/web/app/components/base/input-number/index.spec.tsx b/web/app/components/base/input-number/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/input-number/index.spec.tsx rename to web/app/components/base/input-number/__tests__/index.spec.tsx index 0d6c8ac59b..7c4d7c512e 100644 --- a/web/app/components/base/input-number/index.spec.tsx +++ b/web/app/components/base/input-number/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import { InputNumber } from './index' +import { InputNumber } from '../index' describe('InputNumber Component', () => { const defaultProps = { diff --git a/web/app/components/base/input-with-copy/index.spec.tsx b/web/app/components/base/input-with-copy/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/input-with-copy/index.spec.tsx rename to web/app/components/base/input-with-copy/__tests__/index.spec.tsx index a5628c473f..2fcee9021c 100644 --- a/web/app/components/base/input-with-copy/index.spec.tsx +++ b/web/app/components/base/input-with-copy/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { fireEvent, render, screen } from '@testing-library/react' import * as React from 'react' import { createReactI18nextMock } from '@/test/i18n-mock' -import InputWithCopy from './index' +import InputWithCopy from '../index' // Create a controllable mock for useClipboard const mockCopy = vi.fn() diff --git a/web/app/components/base/input/index.spec.tsx b/web/app/components/base/input/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/input/index.spec.tsx rename to web/app/components/base/input/__tests__/index.spec.tsx index 0aaaf51af5..e62d2701d0 100644 --- a/web/app/components/base/input/index.spec.tsx +++ b/web/app/components/base/input/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { fireEvent, render, screen } from '@testing-library/react' import * as React from 'react' import { createReactI18nextMock } from '@/test/i18n-mock' -import Input, { inputVariants } from './index' +import Input, { inputVariants } from '../index' // Mock the i18n hook with custom translations for test assertions vi.mock('react-i18next', () => createReactI18nextMock({ @@ -103,7 +103,7 @@ describe('Input component', () => { }) it('applies large size variant correctly', () => { - render() + render() const input = screen.getByPlaceholderText('Please input') expect(input.className).toContain(inputVariants({ size: 'large' })) }) diff --git a/web/app/components/base/linked-apps-panel/index.spec.tsx b/web/app/components/base/linked-apps-panel/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/linked-apps-panel/index.spec.tsx rename to web/app/components/base/linked-apps-panel/__tests__/index.spec.tsx index fb7e2e7e2b..27408531c4 100644 --- a/web/app/components/base/linked-apps-panel/index.spec.tsx +++ b/web/app/components/base/linked-apps-panel/__tests__/index.spec.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react' import * as React from 'react' import { vi } from 'vitest' import { AppModeEnum } from '@/types/app' -import LinkedAppsPanel from './index' +import LinkedAppsPanel from '../index' vi.mock('next/link', () => ({ default: ({ children, href, className }: { children: React.ReactNode, href: string, className: string }) => ( diff --git a/web/app/components/base/list-empty/horizontal-line.spec.tsx b/web/app/components/base/list-empty/__tests__/horizontal-line.spec.tsx similarity index 95% rename from web/app/components/base/list-empty/horizontal-line.spec.tsx rename to web/app/components/base/list-empty/__tests__/horizontal-line.spec.tsx index 934183f1d3..c0d7178274 100644 --- a/web/app/components/base/list-empty/horizontal-line.spec.tsx +++ b/web/app/components/base/list-empty/__tests__/horizontal-line.spec.tsx @@ -1,6 +1,6 @@ import { render } from '@testing-library/react' import * as React from 'react' -import HorizontalLine from './horizontal-line' +import HorizontalLine from '../horizontal-line' describe('HorizontalLine', () => { describe('Render', () => { diff --git a/web/app/components/base/list-empty/index.spec.tsx b/web/app/components/base/list-empty/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/list-empty/index.spec.tsx rename to web/app/components/base/list-empty/__tests__/index.spec.tsx index aac1480a60..60523b29fa 100644 --- a/web/app/components/base/list-empty/index.spec.tsx +++ b/web/app/components/base/list-empty/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import * as React from 'react' -import ListEmpty from './index' +import ListEmpty from '../index' describe('ListEmpty Component', () => { describe('Render', () => { diff --git a/web/app/components/base/list-empty/vertical-line.spec.tsx b/web/app/components/base/list-empty/__tests__/vertical-line.spec.tsx similarity index 96% rename from web/app/components/base/list-empty/vertical-line.spec.tsx rename to web/app/components/base/list-empty/__tests__/vertical-line.spec.tsx index 47e071d7fa..2ff9934725 100644 --- a/web/app/components/base/list-empty/vertical-line.spec.tsx +++ b/web/app/components/base/list-empty/__tests__/vertical-line.spec.tsx @@ -1,6 +1,6 @@ import { render } from '@testing-library/react' import * as React from 'react' -import VerticalLine from './vertical-line' +import VerticalLine from '../vertical-line' describe('VerticalLine', () => { describe('Render', () => { diff --git a/web/app/components/base/loading/index.spec.tsx b/web/app/components/base/loading/__tests__/index.spec.tsx similarity index 96% rename from web/app/components/base/loading/index.spec.tsx rename to web/app/components/base/loading/__tests__/index.spec.tsx index 5140f1216b..06847e453a 100644 --- a/web/app/components/base/loading/index.spec.tsx +++ b/web/app/components/base/loading/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { render } from '@testing-library/react' import * as React from 'react' -import Loading from './index' +import Loading from '../index' describe('Loading Component', () => { it('renders correctly with default props', () => { diff --git a/web/app/components/base/logo/dify-logo.spec.tsx b/web/app/components/base/logo/__tests__/dify-logo.spec.tsx similarity index 98% rename from web/app/components/base/logo/dify-logo.spec.tsx rename to web/app/components/base/logo/__tests__/dify-logo.spec.tsx index 834fb8f28e..f465c47e03 100644 --- a/web/app/components/base/logo/dify-logo.spec.tsx +++ b/web/app/components/base/logo/__tests__/dify-logo.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import useTheme from '@/hooks/use-theme' import { Theme } from '@/types/app' -import DifyLogo from './dify-logo' +import DifyLogo from '../dify-logo' vi.mock('@/hooks/use-theme', () => ({ default: vi.fn(), diff --git a/web/app/components/base/logo/logo-embedded-chat-avatar.spec.tsx b/web/app/components/base/logo/__tests__/logo-embedded-chat-avatar.spec.tsx similarity index 93% rename from web/app/components/base/logo/logo-embedded-chat-avatar.spec.tsx rename to web/app/components/base/logo/__tests__/logo-embedded-chat-avatar.spec.tsx index f3c374dbd9..bfb15c1389 100644 --- a/web/app/components/base/logo/logo-embedded-chat-avatar.spec.tsx +++ b/web/app/components/base/logo/__tests__/logo-embedded-chat-avatar.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import LogoEmbeddedChatAvatar from './logo-embedded-chat-avatar' +import LogoEmbeddedChatAvatar from '../logo-embedded-chat-avatar' vi.mock('@/utils/var', () => ({ basePath: '/test-base-path', diff --git a/web/app/components/base/logo/logo-embedded-chat-header.spec.tsx b/web/app/components/base/logo/__tests__/logo-embedded-chat-header.spec.tsx similarity index 94% rename from web/app/components/base/logo/logo-embedded-chat-header.spec.tsx rename to web/app/components/base/logo/__tests__/logo-embedded-chat-header.spec.tsx index 74247036d3..66184ef46e 100644 --- a/web/app/components/base/logo/logo-embedded-chat-header.spec.tsx +++ b/web/app/components/base/logo/__tests__/logo-embedded-chat-header.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import LogoEmbeddedChatHeader from './logo-embedded-chat-header' +import LogoEmbeddedChatHeader from '../logo-embedded-chat-header' vi.mock('@/utils/var', () => ({ basePath: '/test-base-path', diff --git a/web/app/components/base/logo/logo-site.spec.tsx b/web/app/components/base/logo/__tests__/logo-site.spec.tsx similarity index 94% rename from web/app/components/base/logo/logo-site.spec.tsx rename to web/app/components/base/logo/__tests__/logo-site.spec.tsx index 956485305b..0ea8f42800 100644 --- a/web/app/components/base/logo/logo-site.spec.tsx +++ b/web/app/components/base/logo/__tests__/logo-site.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import LogoSite from './logo-site' +import LogoSite from '../logo-site' vi.mock('@/utils/var', () => ({ basePath: '/test-base-path', diff --git a/web/app/components/base/markdown-blocks/audio-block.spec.tsx b/web/app/components/base/markdown-blocks/__tests__/audio-block.spec.tsx similarity index 98% rename from web/app/components/base/markdown-blocks/audio-block.spec.tsx rename to web/app/components/base/markdown-blocks/__tests__/audio-block.spec.tsx index 166de39a16..b24bc9a074 100644 --- a/web/app/components/base/markdown-blocks/audio-block.spec.tsx +++ b/web/app/components/base/markdown-blocks/__tests__/audio-block.spec.tsx @@ -5,7 +5,7 @@ import * as React from 'react' // AudioBlock.integration.spec.tsx import { beforeEach, describe, expect, it, vi } from 'vitest' -import AudioBlock from './audio-block' +import AudioBlock from '../audio-block' // Mock the nested AudioPlayer used by AudioGallery (do not mock AudioGallery itself) const audioPlayerMock = vi.fn() diff --git a/web/app/components/base/markdown-blocks/button.spec.tsx b/web/app/components/base/markdown-blocks/__tests__/button.spec.tsx similarity index 98% rename from web/app/components/base/markdown-blocks/button.spec.tsx rename to web/app/components/base/markdown-blocks/__tests__/button.spec.tsx index 7a1b8e5827..305896f4f1 100644 --- a/web/app/components/base/markdown-blocks/button.spec.tsx +++ b/web/app/components/base/markdown-blocks/__tests__/button.spec.tsx @@ -7,11 +7,11 @@ import * as React from 'react' import { beforeEach, describe, expect, it, vi } from 'vitest' import { ChatContextProvider } from '@/app/components/base/chat/chat/context' -import MarkdownButton from './button' +import MarkdownButton from '../button' // Only mock the URL utility so behavior is deterministic const isValidUrlSpy = vi.fn() -vi.mock('./utils', () => ({ +vi.mock('../utils', () => ({ isValidUrl: (u: string) => isValidUrlSpy(u), })) // test subject diff --git a/web/app/components/base/markdown-blocks/code-block.spec.tsx b/web/app/components/base/markdown-blocks/__tests__/code-block.spec.tsx similarity index 99% rename from web/app/components/base/markdown-blocks/code-block.spec.tsx rename to web/app/components/base/markdown-blocks/__tests__/code-block.spec.tsx index c0e4434f9a..190825647a 100644 --- a/web/app/components/base/markdown-blocks/code-block.spec.tsx +++ b/web/app/components/base/markdown-blocks/__tests__/code-block.spec.tsx @@ -4,7 +4,7 @@ import userEvent from '@testing-library/user-event' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { Theme } from '@/types/app' -import CodeBlock from './code-block' +import CodeBlock from '../code-block' type UseThemeReturn = { theme: Theme diff --git a/web/app/components/base/markdown-blocks/form.spec.tsx b/web/app/components/base/markdown-blocks/__tests__/form.spec.tsx similarity index 99% rename from web/app/components/base/markdown-blocks/form.spec.tsx rename to web/app/components/base/markdown-blocks/__tests__/form.spec.tsx index 0331c3653d..91c7da702d 100644 --- a/web/app/components/base/markdown-blocks/form.spec.tsx +++ b/web/app/components/base/markdown-blocks/__tests__/form.spec.tsx @@ -1,7 +1,7 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import dayjs from '@/app/components/base/date-and-time-picker/utils/dayjs' -import MarkdownForm from './form' +import MarkdownForm from '../form' type TextNode = { type: 'text' diff --git a/web/app/components/base/markdown-blocks/link.spec.tsx b/web/app/components/base/markdown-blocks/__tests__/link.spec.tsx similarity index 98% rename from web/app/components/base/markdown-blocks/link.spec.tsx rename to web/app/components/base/markdown-blocks/__tests__/link.spec.tsx index 6fb0915cd9..ca68b2839d 100644 --- a/web/app/components/base/markdown-blocks/link.spec.tsx +++ b/web/app/components/base/markdown-blocks/__tests__/link.spec.tsx @@ -1,7 +1,7 @@ import { fireEvent, render, screen } from '@testing-library/react' import * as React from 'react' import { beforeEach, describe, expect, it, vi } from 'vitest' -import Link from './link' +import Link from '../link' // ---- mocks ---- const mockOnSend = vi.fn() @@ -13,7 +13,7 @@ vi.mock('@/app/components/base/chat/chat/context', () => ({ })) const mockIsValidUrl = vi.fn() -vi.mock('./utils', () => ({ +vi.mock('../utils', () => ({ isValidUrl: (url: string) => mockIsValidUrl(url), })) diff --git a/web/app/components/base/markdown-blocks/music.spec.tsx b/web/app/components/base/markdown-blocks/__tests__/music.spec.tsx similarity index 97% rename from web/app/components/base/markdown-blocks/music.spec.tsx rename to web/app/components/base/markdown-blocks/__tests__/music.spec.tsx index 450c0b1c2c..111148cab0 100644 --- a/web/app/components/base/markdown-blocks/music.spec.tsx +++ b/web/app/components/base/markdown-blocks/__tests__/music.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' import ErrorBoundary from '@/app/components/base/markdown/error-boundary' -import MarkdownMusic from './music' +import MarkdownMusic from '../music' describe('MarkdownMusic', () => { beforeEach(() => { diff --git a/web/app/components/base/markdown-blocks/paragraph.spec.tsx b/web/app/components/base/markdown-blocks/__tests__/paragraph.spec.tsx similarity index 98% rename from web/app/components/base/markdown-blocks/paragraph.spec.tsx rename to web/app/components/base/markdown-blocks/__tests__/paragraph.spec.tsx index 1abfe246ba..557eb96197 100644 --- a/web/app/components/base/markdown-blocks/paragraph.spec.tsx +++ b/web/app/components/base/markdown-blocks/__tests__/paragraph.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import { describe, expect, it, vi } from 'vitest' -import Paragraph from './paragraph' +import Paragraph from '../paragraph' vi.mock('@/app/components/base/image-gallery', () => ({ default: ({ srcs }: { srcs: string[] }) => ( diff --git a/web/app/components/base/markdown-blocks/plugin-img.spec.tsx b/web/app/components/base/markdown-blocks/__tests__/plugin-img.spec.tsx similarity index 97% rename from web/app/components/base/markdown-blocks/plugin-img.spec.tsx rename to web/app/components/base/markdown-blocks/__tests__/plugin-img.spec.tsx index 0022542edb..a16699ccf4 100644 --- a/web/app/components/base/markdown-blocks/plugin-img.spec.tsx +++ b/web/app/components/base/markdown-blocks/__tests__/plugin-img.spec.tsx @@ -2,7 +2,7 @@ import { cleanup, render, screen } from '@testing-library/react' import * as React from 'react' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { PluginImg } from './plugin-img' +import { PluginImg } from '../plugin-img' /* -------------------- Mocks -------------------- */ @@ -19,7 +19,7 @@ vi.mock('@/service/use-plugins', () => ({ })) const mockGetMarkdownImageURL = vi.fn() -vi.mock('./utils', () => ({ +vi.mock('../utils', () => ({ getMarkdownImageURL: (src: string, pluginId?: string) => mockGetMarkdownImageURL(src, pluginId), })) diff --git a/web/app/components/base/markdown-blocks/plugin-paragraph.spec.tsx b/web/app/components/base/markdown-blocks/__tests__/plugin-paragraph.spec.tsx similarity index 97% rename from web/app/components/base/markdown-blocks/plugin-paragraph.spec.tsx rename to web/app/components/base/markdown-blocks/__tests__/plugin-paragraph.spec.tsx index 5479ab81ac..4e6637d337 100644 --- a/web/app/components/base/markdown-blocks/plugin-paragraph.spec.tsx +++ b/web/app/components/base/markdown-blocks/__tests__/plugin-paragraph.spec.tsx @@ -3,15 +3,15 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { beforeEach, describe, expect, it, vi } from 'vitest' import { usePluginReadmeAsset } from '@/service/use-plugins' -import { PluginParagraph } from './plugin-paragraph' -import { getMarkdownImageURL } from './utils' +import { PluginParagraph } from '../plugin-paragraph' +import { getMarkdownImageURL } from '../utils' // Mock dependencies vi.mock('@/service/use-plugins', () => ({ usePluginReadmeAsset: vi.fn(), })) -vi.mock('./utils', () => ({ +vi.mock('../utils', () => ({ getMarkdownImageURL: vi.fn(), })) diff --git a/web/app/components/base/markdown-blocks/pre-code.spec.tsx b/web/app/components/base/markdown-blocks/__tests__/pre-code.spec.tsx similarity index 98% rename from web/app/components/base/markdown-blocks/pre-code.spec.tsx rename to web/app/components/base/markdown-blocks/__tests__/pre-code.spec.tsx index a3cc234e8f..fa3d37301d 100644 --- a/web/app/components/base/markdown-blocks/pre-code.spec.tsx +++ b/web/app/components/base/markdown-blocks/__tests__/pre-code.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import * as React from 'react' import { describe, expect, it } from 'vitest' -import PreCode from './pre-code' +import PreCode from '../pre-code' describe('PreCode Component', () => { it('renders children correctly inside the pre tag', () => { diff --git a/web/app/components/base/markdown-blocks/script-block.spec.tsx b/web/app/components/base/markdown-blocks/__tests__/script-block.spec.tsx similarity index 97% rename from web/app/components/base/markdown-blocks/script-block.spec.tsx rename to web/app/components/base/markdown-blocks/__tests__/script-block.spec.tsx index 4bf0abc301..02db3205b7 100644 --- a/web/app/components/base/markdown-blocks/script-block.spec.tsx +++ b/web/app/components/base/markdown-blocks/__tests__/script-block.spec.tsx @@ -1,7 +1,7 @@ import { cleanup, render } from '@testing-library/react' import * as React from 'react' import { afterEach, describe, expect, it } from 'vitest' -import ScriptBlock from './script-block' +import ScriptBlock from '../script-block' afterEach(() => { cleanup() diff --git a/web/app/components/base/markdown-blocks/think-block.spec.tsx b/web/app/components/base/markdown-blocks/__tests__/think-block.spec.tsx similarity index 99% rename from web/app/components/base/markdown-blocks/think-block.spec.tsx rename to web/app/components/base/markdown-blocks/__tests__/think-block.spec.tsx index a155b240b9..2cd31f9a49 100644 --- a/web/app/components/base/markdown-blocks/think-block.spec.tsx +++ b/web/app/components/base/markdown-blocks/__tests__/think-block.spec.tsx @@ -1,7 +1,7 @@ import { act, render, screen } from '@testing-library/react' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { ChatContextProvider } from '@/app/components/base/chat/chat/context' -import ThinkBlock from './think-block' +import ThinkBlock from '../think-block' // Mock react-i18next vi.mock('react-i18next', () => ({ diff --git a/web/app/components/base/markdown-blocks/video-block.spec.tsx b/web/app/components/base/markdown-blocks/__tests__/video-block.spec.tsx similarity index 96% rename from web/app/components/base/markdown-blocks/video-block.spec.tsx rename to web/app/components/base/markdown-blocks/__tests__/video-block.spec.tsx index 46f810453f..eabeb1fca1 100644 --- a/web/app/components/base/markdown-blocks/video-block.spec.tsx +++ b/web/app/components/base/markdown-blocks/__tests__/video-block.spec.tsx @@ -2,8 +2,8 @@ import { render } from '@testing-library/react' import * as React from 'react' import { describe, expect, it } from 'vitest' -import VideoGallery from '../video-gallery' -import VideoBlock from './video-block' +import VideoGallery from '../../video-gallery' +import VideoBlock from '../video-block' type ChildNode = { properties?: { diff --git a/web/app/components/base/markdown/error-boundary.spec.tsx b/web/app/components/base/markdown/__tests__/error-boundary.spec.tsx similarity index 96% rename from web/app/components/base/markdown/error-boundary.spec.tsx rename to web/app/components/base/markdown/__tests__/error-boundary.spec.tsx index 40a37d4504..f9afed4e94 100644 --- a/web/app/components/base/markdown/error-boundary.spec.tsx +++ b/web/app/components/base/markdown/__tests__/error-boundary.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import * as React from 'react' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import ErrorBoundary from './error-boundary' +import ErrorBoundary from '../error-boundary' import '@testing-library/jest-dom' describe('ErrorBoundary', () => { diff --git a/web/app/components/base/markdown/index.spec.tsx b/web/app/components/base/markdown/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/markdown/index.spec.tsx rename to web/app/components/base/markdown/__tests__/index.spec.tsx index bf315360ca..9a87811e30 100644 --- a/web/app/components/base/markdown/index.spec.tsx +++ b/web/app/components/base/markdown/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ -import type { SimplePluginInfo } from './react-markdown-wrapper' +import type { SimplePluginInfo } from '../react-markdown-wrapper' import { render, screen } from '@testing-library/react' -import { Markdown } from './index' +import { Markdown } from '../index' const { mockReactMarkdownWrapper } = vi.hoisted(() => ({ mockReactMarkdownWrapper: vi.fn(), diff --git a/web/app/components/base/markdown/markdown-utils.spec.ts b/web/app/components/base/markdown/__tests__/markdown-utils.spec.ts similarity index 97% rename from web/app/components/base/markdown/markdown-utils.spec.ts rename to web/app/components/base/markdown/__tests__/markdown-utils.spec.ts index 952dd52f73..dbdc419095 100644 --- a/web/app/components/base/markdown/markdown-utils.spec.ts +++ b/web/app/components/base/markdown/__tests__/markdown-utils.spec.ts @@ -9,11 +9,11 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' const loadModuleWithConfig = async (allowDataScheme: boolean) => { vi.resetModules() vi.doMock('@/config', () => ({ ALLOW_UNSAFE_DATA_SCHEME: allowDataScheme })) - return await import('./markdown-utils') + return await import('../markdown-utils') } describe('preprocessLaTeX', () => { - let mod: typeof import('./markdown-utils') + let mod: typeof import('../markdown-utils') beforeEach(async () => { // config value doesn't matter for LaTeX preprocessing, mock it false @@ -67,7 +67,7 @@ describe('preprocessLaTeX', () => { }) describe('preprocessThinkTag', () => { - let mod: typeof import('./markdown-utils') + let mod: typeof import('../markdown-utils') beforeEach(async () => { mod = await loadModuleWithConfig(false) diff --git a/web/app/components/base/markdown/react-markdown-wrapper.spec.tsx b/web/app/components/base/markdown/__tests__/react-markdown-wrapper.spec.tsx similarity index 98% rename from web/app/components/base/markdown/react-markdown-wrapper.spec.tsx rename to web/app/components/base/markdown/__tests__/react-markdown-wrapper.spec.tsx index 735222011b..46aa74b20a 100644 --- a/web/app/components/base/markdown/react-markdown-wrapper.spec.tsx +++ b/web/app/components/base/markdown/__tests__/react-markdown-wrapper.spec.tsx @@ -1,6 +1,6 @@ import type { PropsWithChildren, ReactNode } from 'react' import { render, screen } from '@testing-library/react' -import { ReactMarkdownWrapper } from './react-markdown-wrapper' +import { ReactMarkdownWrapper } from '../react-markdown-wrapper' vi.mock('@/app/components/base/markdown-blocks', () => ({ AudioBlock: ({ children }: PropsWithChildren) =>
{children}
, diff --git a/web/app/components/base/mermaid/index.spec.tsx b/web/app/components/base/mermaid/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/mermaid/index.spec.tsx rename to web/app/components/base/mermaid/__tests__/index.spec.tsx index 198f4de003..90f3559e63 100644 --- a/web/app/components/base/mermaid/index.spec.tsx +++ b/web/app/components/base/mermaid/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { act, fireEvent, render, screen, waitFor } from '@testing-library/react' import mermaid from 'mermaid' -import Flowchart from './index' +import Flowchart from '../index' vi.mock('mermaid', () => ({ default: { @@ -12,7 +12,7 @@ vi.mock('mermaid', () => ({ }, })) -vi.mock('./utils', async (importOriginal) => { +vi.mock('../utils', async (importOriginal) => { const actual = await importOriginal() as Record return { ...actual, @@ -231,7 +231,7 @@ describe('Mermaid Flowchart Component Module Isolation', () => { describe('Error Handling', () => { it('should handle initialization failure', async () => { const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => { }) - const { default: FlowchartFresh } = await import('./index') + const { default: FlowchartFresh } = await import('../index') vi.mocked(mermaidFresh.initialize).mockImplementationOnce(() => { throw new Error('Init fail') @@ -251,7 +251,7 @@ describe('Mermaid Flowchart Component Module Isolation', () => { // @ts-expect-error need to set undefined for testing mermaidFresh.mermaidAPI = undefined - const { default: FlowchartFresh } = await import('./index') + const { default: FlowchartFresh } = await import('../index') const { container } = render() @@ -284,7 +284,7 @@ describe('Mermaid Flowchart Component Module Isolation', () => { throw new Error('Config fail') }) const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => { }) - const { default: FlowchartFresh } = await import('./index') + const { default: FlowchartFresh } = await import('../index') await act(async () => { render() diff --git a/web/app/components/base/mermaid/utils.spec.ts b/web/app/components/base/mermaid/__tests__/utils.spec.ts similarity index 99% rename from web/app/components/base/mermaid/utils.spec.ts rename to web/app/components/base/mermaid/__tests__/utils.spec.ts index d698e1234c..6d237810db 100644 --- a/web/app/components/base/mermaid/utils.spec.ts +++ b/web/app/components/base/mermaid/__tests__/utils.spec.ts @@ -1,4 +1,4 @@ -import { cleanUpSvgCode, isMermaidCodeComplete, prepareMermaidCode, processSvgForTheme, sanitizeMermaidCode, svgToBase64, waitForDOMElement } from './utils' +import { cleanUpSvgCode, isMermaidCodeComplete, prepareMermaidCode, processSvgForTheme, sanitizeMermaidCode, svgToBase64, waitForDOMElement } from '../utils' describe('cleanUpSvgCode', () => { it('should replace old-style
tags with self-closing
', () => { diff --git a/web/app/components/base/message-log-modal/index.spec.tsx b/web/app/components/base/message-log-modal/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/message-log-modal/index.spec.tsx rename to web/app/components/base/message-log-modal/__tests__/index.spec.tsx index 10793c2ba0..1f01c87633 100644 --- a/web/app/components/base/message-log-modal/index.spec.tsx +++ b/web/app/components/base/message-log-modal/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import type { IChatItem } from '@/app/components/base/chat/chat/type' import { fireEvent, render, screen } from '@testing-library/react' import { useStore } from '@/app/components/app/store' -import MessageLogModal from './index' +import MessageLogModal from '../index' let clickAwayHandler: (() => void) | null = null vi.mock('ahooks', () => ({ diff --git a/web/app/components/base/modal-like-wrap/index.spec.tsx b/web/app/components/base/modal-like-wrap/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/modal-like-wrap/index.spec.tsx rename to web/app/components/base/modal-like-wrap/__tests__/index.spec.tsx index 60e3a4ca8c..dc7b0758fa 100644 --- a/web/app/components/base/modal-like-wrap/index.spec.tsx +++ b/web/app/components/base/modal-like-wrap/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { act, fireEvent, render, screen } from '@testing-library/react' -import ModalLikeWrap from '.' +import ModalLikeWrap from '..' describe('ModalLikeWrap', () => { const defaultProps = { diff --git a/web/app/components/base/modal/index.spec.tsx b/web/app/components/base/modal/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/modal/index.spec.tsx rename to web/app/components/base/modal/__tests__/index.spec.tsx index cab95c7cb1..da417b43ad 100644 --- a/web/app/components/base/modal/index.spec.tsx +++ b/web/app/components/base/modal/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { act, fireEvent, render, screen } from '@testing-library/react' -import Modal from '.' +import Modal from '..' describe('Modal', () => { describe('Render', () => { diff --git a/web/app/components/base/modal/modal.spec.tsx b/web/app/components/base/modal/__tests__/modal.spec.tsx similarity index 99% rename from web/app/components/base/modal/modal.spec.tsx rename to web/app/components/base/modal/__tests__/modal.spec.tsx index df2c3bd15d..c67b9a803b 100644 --- a/web/app/components/base/modal/modal.spec.tsx +++ b/web/app/components/base/modal/__tests__/modal.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import Modal from './modal' +import Modal from '../modal' describe('Modal Component', () => { const defaultProps = { diff --git a/web/app/components/base/new-audio-button/index.spec.tsx b/web/app/components/base/new-audio-button/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/new-audio-button/index.spec.tsx rename to web/app/components/base/new-audio-button/__tests__/index.spec.tsx index a30b06535a..64dd590012 100644 --- a/web/app/components/base/new-audio-button/index.spec.tsx +++ b/web/app/components/base/new-audio-button/__tests__/index.spec.tsx @@ -3,7 +3,7 @@ import userEvent from '@testing-library/user-event' import i18next from 'i18next' import { useParams, usePathname } from 'next/navigation' import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest' -import AudioBtn from './index' +import AudioBtn from '../index' const mockPlayAudio = vi.fn() const mockPauseAudio = vi.fn() diff --git a/web/app/components/base/node-status/index.spec.tsx b/web/app/components/base/node-status/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/node-status/index.spec.tsx rename to web/app/components/base/node-status/__tests__/index.spec.tsx index 566a537653..f74af4965e 100644 --- a/web/app/components/base/node-status/index.spec.tsx +++ b/web/app/components/base/node-status/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import NodeStatus, { NodeStatusEnum } from '.' +import NodeStatus, { NodeStatusEnum } from '..' describe('NodeStatus', () => { it('renders with default status (warning) and default message', () => { diff --git a/web/app/components/base/notion-connector/index.spec.tsx b/web/app/components/base/notion-connector/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/notion-connector/index.spec.tsx rename to web/app/components/base/notion-connector/__tests__/index.spec.tsx index 7ee799d002..578ffffdca 100644 --- a/web/app/components/base/notion-connector/index.spec.tsx +++ b/web/app/components/base/notion-connector/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import NotionConnector from './index' +import NotionConnector from '../index' describe('NotionConnector', () => { it('should render the layout and actual sub-components (Icons & Button)', () => { diff --git a/web/app/components/base/notion-icon/index.spec.tsx b/web/app/components/base/notion-icon/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/notion-icon/index.spec.tsx rename to web/app/components/base/notion-icon/__tests__/index.spec.tsx index 582beab054..26a2c7640e 100644 --- a/web/app/components/base/notion-icon/index.spec.tsx +++ b/web/app/components/base/notion-icon/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import NotionIcon from '.' +import NotionIcon from '..' describe('Notion Icon', () => { it('applies custom class names', () => { diff --git a/web/app/components/base/notion-page-selector/base.spec.tsx b/web/app/components/base/notion-page-selector/__tests__/base.spec.tsx similarity index 98% rename from web/app/components/base/notion-page-selector/base.spec.tsx rename to web/app/components/base/notion-page-selector/__tests__/base.spec.tsx index e978056667..e06ca0a53e 100644 --- a/web/app/components/base/notion-page-selector/base.spec.tsx +++ b/web/app/components/base/notion-page-selector/__tests__/base.spec.tsx @@ -1,4 +1,4 @@ -import type { DataSourceCredential } from '../../header/account-setting/data-source-page-new/types' +import type { DataSourceCredential } from '../../../header/account-setting/data-source-page-new/types' import type { DataSourceNotionWorkspace } from '@/models/common' import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' @@ -7,7 +7,7 @@ import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/con import { CredentialTypeEnum } from '@/app/components/plugins/plugin-auth/types' import { useModalContextSelector } from '@/context/modal-context' import { useInvalidPreImportNotionPages, usePreImportNotionPages } from '@/service/knowledge/use-import' -import NotionPageSelector from './base' +import NotionPageSelector from '../base' vi.mock('@/service/knowledge/use-import', () => ({ usePreImportNotionPages: vi.fn(), diff --git a/web/app/components/base/notion-page-selector/credential-selector/index.spec.tsx b/web/app/components/base/notion-page-selector/credential-selector/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/notion-page-selector/credential-selector/index.spec.tsx rename to web/app/components/base/notion-page-selector/credential-selector/__tests__/index.spec.tsx index ff194a0086..efcf015ea5 100644 --- a/web/app/components/base/notion-page-selector/credential-selector/index.spec.tsx +++ b/web/app/components/base/notion-page-selector/credential-selector/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import CredentialSelector from './index' +import CredentialSelector from '../index' // Mock CredentialIcon since it's likely a complex component or uses next/image vi.mock('@/app/components/datasets/common/credential-icon', () => ({ diff --git a/web/app/components/base/notion-page-selector/page-selector/index.spec.tsx b/web/app/components/base/notion-page-selector/page-selector/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/notion-page-selector/page-selector/index.spec.tsx rename to web/app/components/base/notion-page-selector/page-selector/__tests__/index.spec.tsx index 1b0cc6653a..bfe3e7e0ef 100644 --- a/web/app/components/base/notion-page-selector/page-selector/index.spec.tsx +++ b/web/app/components/base/notion-page-selector/page-selector/__tests__/index.spec.tsx @@ -2,7 +2,7 @@ import type { DataSourceNotionPage, DataSourceNotionPageMap } from '@/models/com import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { beforeEach, describe, expect, it, vi } from 'vitest' -import PageSelector from './index' +import PageSelector from '../index' const buildPage = (overrides: Partial): DataSourceNotionPage => ({ page_id: 'page-id', diff --git a/web/app/components/base/notion-page-selector/search-input/index.spec.tsx b/web/app/components/base/notion-page-selector/search-input/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/notion-page-selector/search-input/index.spec.tsx rename to web/app/components/base/notion-page-selector/search-input/__tests__/index.spec.tsx index ecab087d71..39e7e09cf8 100644 --- a/web/app/components/base/notion-page-selector/search-input/index.spec.tsx +++ b/web/app/components/base/notion-page-selector/search-input/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import SearchInput from './index' +import SearchInput from '../index' describe('SearchInput', () => { it('should render with placeholder', () => { diff --git a/web/app/components/base/pagination/hook.spec.ts b/web/app/components/base/pagination/__tests__/hook.spec.ts similarity index 99% rename from web/app/components/base/pagination/hook.spec.ts rename to web/app/components/base/pagination/__tests__/hook.spec.ts index 284032df47..b65feab8f3 100644 --- a/web/app/components/base/pagination/hook.spec.ts +++ b/web/app/components/base/pagination/__tests__/hook.spec.ts @@ -1,5 +1,5 @@ import { renderHook } from '@testing-library/react' -import usePagination from './hook' +import usePagination from '../hook' const defaultProps = { currentPage: 0, diff --git a/web/app/components/base/pagination/index.spec.tsx b/web/app/components/base/pagination/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/pagination/index.spec.tsx rename to web/app/components/base/pagination/__tests__/index.spec.tsx index ef924c290b..aa3cf8e5f2 100644 --- a/web/app/components/base/pagination/index.spec.tsx +++ b/web/app/components/base/pagination/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { act, fireEvent, render, screen } from '@testing-library/react' -import CustomizedPagination from './index' +import CustomizedPagination from '../index' describe('CustomizedPagination', () => { const defaultProps = { diff --git a/web/app/components/base/pagination/pagination.spec.tsx b/web/app/components/base/pagination/__tests__/pagination.spec.tsx similarity index 99% rename from web/app/components/base/pagination/pagination.spec.tsx rename to web/app/components/base/pagination/__tests__/pagination.spec.tsx index 2374f8257a..21c3b41bff 100644 --- a/web/app/components/base/pagination/pagination.spec.tsx +++ b/web/app/components/base/pagination/__tests__/pagination.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import { Pagination } from './pagination' +import { Pagination } from '../pagination' // Helper to render Pagination with common defaults function renderPagination({ diff --git a/web/app/components/base/param-item/index-slider.spec.tsx b/web/app/components/base/param-item/__tests__/index-slider.spec.tsx similarity index 97% rename from web/app/components/base/param-item/index-slider.spec.tsx rename to web/app/components/base/param-item/__tests__/index-slider.spec.tsx index b0fa28a2d5..0048b89644 100644 --- a/web/app/components/base/param-item/index-slider.spec.tsx +++ b/web/app/components/base/param-item/__tests__/index-slider.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import ParamItem from '.' +import ParamItem from '..' describe('ParamItem Slider onChange', () => { const defaultProps = { diff --git a/web/app/components/base/param-item/index.spec.tsx b/web/app/components/base/param-item/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/param-item/index.spec.tsx rename to web/app/components/base/param-item/__tests__/index.spec.tsx index 45e0c2a5b3..60bcbebcf9 100644 --- a/web/app/components/base/param-item/index.spec.tsx +++ b/web/app/components/base/param-item/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { useState } from 'react' -import ParamItem from '.' +import ParamItem from '..' describe('ParamItem', () => { const defaultProps = { @@ -95,7 +95,7 @@ describe('ParamItem', () => { { + onChange={(key: string, nextValue: number) => { defaultProps.onChange(key, nextValue) setValue(nextValue) }} diff --git a/web/app/components/base/param-item/score-threshold-item.spec.tsx b/web/app/components/base/param-item/__tests__/score-threshold-item.spec.tsx similarity index 98% rename from web/app/components/base/param-item/score-threshold-item.spec.tsx rename to web/app/components/base/param-item/__tests__/score-threshold-item.spec.tsx index ce0a396249..d59768dacb 100644 --- a/web/app/components/base/param-item/score-threshold-item.spec.tsx +++ b/web/app/components/base/param-item/__tests__/score-threshold-item.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { useState } from 'react' -import ScoreThresholdItem from './score-threshold-item' +import ScoreThresholdItem from '../score-threshold-item' describe('ScoreThresholdItem', () => { const defaultProps = { diff --git a/web/app/components/base/param-item/top-k-item.spec.tsx b/web/app/components/base/param-item/__tests__/top-k-item.spec.tsx similarity index 99% rename from web/app/components/base/param-item/top-k-item.spec.tsx rename to web/app/components/base/param-item/__tests__/top-k-item.spec.tsx index 2031e4a83e..177b51e768 100644 --- a/web/app/components/base/param-item/top-k-item.spec.tsx +++ b/web/app/components/base/param-item/__tests__/top-k-item.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import TopKItem from './top-k-item' +import TopKItem from '../top-k-item' vi.mock('@/env', () => ({ env: { diff --git a/web/app/components/base/popover/index.spec.tsx b/web/app/components/base/popover/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/popover/index.spec.tsx rename to web/app/components/base/popover/__tests__/index.spec.tsx index f90a024bcf..ba86c96296 100644 --- a/web/app/components/base/popover/index.spec.tsx +++ b/web/app/components/base/popover/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { act, fireEvent, render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import CustomPopover from '.' +import CustomPopover from '..' const CloseButtonContent = ({ onClick }: { onClick?: () => void }) => ( @@ -227,7 +227,7 @@ describe('CustomPopover', () => { render( open ? 'btn-open' : 'btn-closed'} + btnClassName={(open: boolean) => open ? 'btn-open' : 'btn-closed'} />, ) diff --git a/web/app/components/base/portal-to-follow-elem/index.spec.tsx b/web/app/components/base/portal-to-follow-elem/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/portal-to-follow-elem/index.spec.tsx rename to web/app/components/base/portal-to-follow-elem/__tests__/index.spec.tsx index f320cd2a74..3aeb1fb475 100644 --- a/web/app/components/base/portal-to-follow-elem/index.spec.tsx +++ b/web/app/components/base/portal-to-follow-elem/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { cleanup, fireEvent, render } from '@testing-library/react' import * as React from 'react' -import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '.' +import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '..' const useFloatingMock = vi.fn() diff --git a/web/app/components/base/premium-badge/index.spec.tsx b/web/app/components/base/premium-badge/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/premium-badge/index.spec.tsx rename to web/app/components/base/premium-badge/__tests__/index.spec.tsx index a589aef828..af8ace22f0 100644 --- a/web/app/components/base/premium-badge/index.spec.tsx +++ b/web/app/components/base/premium-badge/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import PremiumBadge from './index' +import PremiumBadge from '../index' describe('PremiumBadge', () => { it('renders with default props', () => { diff --git a/web/app/components/base/progress-bar/progress-circle.spec.tsx b/web/app/components/base/progress-bar/__tests__/progress-circle.spec.tsx similarity index 98% rename from web/app/components/base/progress-bar/progress-circle.spec.tsx rename to web/app/components/base/progress-bar/__tests__/progress-circle.spec.tsx index 9acc525d90..4a3ee2e653 100644 --- a/web/app/components/base/progress-bar/progress-circle.spec.tsx +++ b/web/app/components/base/progress-bar/__tests__/progress-circle.spec.tsx @@ -1,5 +1,5 @@ import { render } from '@testing-library/react' -import ProgressCircle from './progress-circle' +import ProgressCircle from '../progress-circle' const extractLargeArcFlag = (pathData: string): string => { const afterA = pathData.slice(pathData.indexOf('A') + 1) diff --git a/web/app/components/base/prompt-editor/constants.spec.tsx b/web/app/components/base/prompt-editor/__tests__/constants.spec.tsx similarity index 97% rename from web/app/components/base/prompt-editor/constants.spec.tsx rename to web/app/components/base/prompt-editor/__tests__/constants.spec.tsx index 862c386383..9817f70487 100644 --- a/web/app/components/base/prompt-editor/constants.spec.tsx +++ b/web/app/components/base/prompt-editor/__tests__/constants.spec.tsx @@ -1,4 +1,4 @@ -import { SupportUploadFileTypes } from '../../workflow/types' +import { SupportUploadFileTypes } from '../../../workflow/types' import { checkHasContextBlock, checkHasHistoryBlock, @@ -16,7 +16,7 @@ import { REQUEST_URL_PLACEHOLDER_TEXT, UPDATE_DATASETS_EVENT_EMITTER, UPDATE_HISTORY_EVENT_EMITTER, -} from './constants' +} from '../constants' describe('prompt-editor constants', () => { describe('placeholder and event constants', () => { diff --git a/web/app/components/base/prompt-editor/hooks.spec.tsx b/web/app/components/base/prompt-editor/__tests__/hooks.spec.tsx similarity index 97% rename from web/app/components/base/prompt-editor/hooks.spec.tsx rename to web/app/components/base/prompt-editor/__tests__/hooks.spec.tsx index 4f2d6f3e0d..89d76c2709 100644 --- a/web/app/components/base/prompt-editor/hooks.spec.tsx +++ b/web/app/components/base/prompt-editor/__tests__/hooks.spec.tsx @@ -8,13 +8,13 @@ import { useLexicalTextEntity, useSelectOrDelete, useTrigger, -} from './hooks' +} from '../hooks' import { DELETE_CONTEXT_BLOCK_COMMAND, -} from './plugins/context-block' -import { ContextBlockNode } from './plugins/context-block/node' -import { DELETE_QUERY_BLOCK_COMMAND } from './plugins/query-block' -import { QueryBlockNode } from './plugins/query-block/node' +} from '../plugins/context-block' +import { ContextBlockNode } from '../plugins/context-block/node' +import { DELETE_QUERY_BLOCK_COMMAND } from '../plugins/query-block' +import { QueryBlockNode } from '../plugins/query-block/node' type MockNode = { isDecorator?: boolean diff --git a/web/app/components/base/prompt-editor/index.spec.tsx b/web/app/components/base/prompt-editor/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/prompt-editor/index.spec.tsx rename to web/app/components/base/prompt-editor/__tests__/index.spec.tsx index a8bdc4a637..40ca8c3d76 100644 --- a/web/app/components/base/prompt-editor/index.spec.tsx +++ b/web/app/components/base/prompt-editor/__tests__/index.spec.tsx @@ -1,14 +1,14 @@ import type { FocusEvent as ReactFocusEvent, ReactNode } from 'react' -import type { PromptEditorProps } from './index' -import type { ContextBlockType, HistoryBlockType } from './types' +import type { PromptEditorProps } from '../index' +import type { ContextBlockType, HistoryBlockType } from '../types' import { render, screen, waitFor } from '@testing-library/react' import { BLUR_COMMAND, FOCUS_COMMAND } from 'lexical' import * as React from 'react' import { UPDATE_DATASETS_EVENT_EMITTER, UPDATE_HISTORY_EVENT_EMITTER, -} from './constants' -import PromptEditor from './index' +} from '../constants' +import PromptEditor from '../index' const mocks = vi.hoisted(() => { const commandHandlers = new Map boolean>() diff --git a/web/app/components/base/prompt-editor/utils.spec.ts b/web/app/components/base/prompt-editor/__tests__/utils.spec.ts similarity index 98% rename from web/app/components/base/prompt-editor/utils.spec.ts rename to web/app/components/base/prompt-editor/__tests__/utils.spec.ts index d445966057..d400e145ff 100644 --- a/web/app/components/base/prompt-editor/utils.spec.ts +++ b/web/app/components/base/prompt-editor/__tests__/utils.spec.ts @@ -5,15 +5,15 @@ import type { RangeSelection, TextNode, } from 'lexical' -import type { CustomTextNode } from './plugins/custom-text/node' -import type { MenuTextMatch } from './types' +import type { CustomTextNode } from '../plugins/custom-text/node' +import type { MenuTextMatch } from '../types' import { $splitNodeContainingQuery, decoratorTransform, getSelectedNode, registerLexicalTextEntity, textToEditorState, -} from './utils' +} from '../utils' const mockState = vi.hoisted(() => ({ isAtNodeEnd: false, @@ -36,7 +36,7 @@ vi.mock('lexical', async (importOriginal) => { } }) -vi.mock('./plugins/custom-text/node', () => ({ +vi.mock('../plugins/custom-text/node', () => ({ CustomTextNode: class MockCustomTextNode {}, })) diff --git a/web/app/components/base/prompt-editor/plugins/on-blur-or-focus-block.spec.tsx b/web/app/components/base/prompt-editor/plugins/__tests__/on-blur-or-focus-block.spec.tsx similarity index 97% rename from web/app/components/base/prompt-editor/plugins/on-blur-or-focus-block.spec.tsx rename to web/app/components/base/prompt-editor/plugins/__tests__/on-blur-or-focus-block.spec.tsx index 54acb0267a..dd2f74f7e5 100644 --- a/web/app/components/base/prompt-editor/plugins/on-blur-or-focus-block.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/__tests__/on-blur-or-focus-block.spec.tsx @@ -7,9 +7,9 @@ import { FOCUS_COMMAND, KEY_ESCAPE_COMMAND, } from 'lexical' -import OnBlurBlock from './on-blur-or-focus-block' -import { CaptureEditorPlugin } from './test-utils' -import { CLEAR_HIDE_MENU_TIMEOUT } from './workflow-variable-block' +import OnBlurBlock from '../on-blur-or-focus-block' +import { CaptureEditorPlugin } from '../test-utils' +import { CLEAR_HIDE_MENU_TIMEOUT } from '../workflow-variable-block' const renderOnBlurBlock = (props?: { onBlur?: () => void diff --git a/web/app/components/base/prompt-editor/plugins/placeholder.spec.tsx b/web/app/components/base/prompt-editor/plugins/__tests__/placeholder.spec.tsx similarity index 97% rename from web/app/components/base/prompt-editor/plugins/placeholder.spec.tsx rename to web/app/components/base/prompt-editor/plugins/__tests__/placeholder.spec.tsx index 2386b355b0..577f15bb97 100644 --- a/web/app/components/base/prompt-editor/plugins/placeholder.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/__tests__/placeholder.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import Placeholder from './placeholder' +import Placeholder from '../placeholder' describe('Placeholder', () => { beforeEach(() => { diff --git a/web/app/components/base/prompt-editor/plugins/tree-view.spec.tsx b/web/app/components/base/prompt-editor/plugins/__tests__/tree-view.spec.tsx similarity index 95% rename from web/app/components/base/prompt-editor/plugins/tree-view.spec.tsx rename to web/app/components/base/prompt-editor/plugins/__tests__/tree-view.spec.tsx index cc32ab6ea3..c2c9fe9237 100644 --- a/web/app/components/base/prompt-editor/plugins/tree-view.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/__tests__/tree-view.spec.tsx @@ -1,8 +1,8 @@ import type { LexicalEditor } from 'lexical' import { LexicalComposer } from '@lexical/react/LexicalComposer' import { render, screen, waitFor } from '@testing-library/react' -import { CaptureEditorPlugin } from './test-utils' -import TreeViewPlugin from './tree-view' +import { CaptureEditorPlugin } from '../test-utils' +import TreeViewPlugin from '../tree-view' const { mockTreeView } = vi.hoisted(() => ({ mockTreeView: vi.fn(), diff --git a/web/app/components/base/prompt-editor/plugins/update-block.spec.tsx b/web/app/components/base/prompt-editor/plugins/__tests__/update-block.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/update-block.spec.tsx rename to web/app/components/base/prompt-editor/plugins/__tests__/update-block.spec.tsx index f5576c4109..8f6a72a7de 100644 --- a/web/app/components/base/prompt-editor/plugins/update-block.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/__tests__/update-block.spec.tsx @@ -2,13 +2,13 @@ import type { LexicalEditor } from 'lexical' import { LexicalComposer } from '@lexical/react/LexicalComposer' import { act, render, waitFor } from '@testing-library/react' import { $getRoot, COMMAND_PRIORITY_EDITOR } from 'lexical' -import { CustomTextNode } from './custom-text/node' -import { CaptureEditorPlugin } from './test-utils' +import { CustomTextNode } from '../custom-text/node' +import { CaptureEditorPlugin } from '../test-utils' import UpdateBlock, { PROMPT_EDITOR_INSERT_QUICKLY, PROMPT_EDITOR_UPDATE_VALUE_BY_EVENT_EMITTER, -} from './update-block' -import { CLEAR_HIDE_MENU_TIMEOUT } from './workflow-variable-block' +} from '../update-block' +import { CLEAR_HIDE_MENU_TIMEOUT } from '../workflow-variable-block' const { mockUseEventEmitterContextContext } = vi.hoisted(() => ({ mockUseEventEmitterContextContext: vi.fn(), diff --git a/web/app/components/base/prompt-editor/plugins/component-picker-block/hooks.spec.tsx b/web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/hooks.spec.tsx similarity index 99% rename from web/app/components/base/prompt-editor/plugins/component-picker-block/hooks.spec.tsx rename to web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/hooks.spec.tsx index 3ed5d12a86..e28304dd15 100644 --- a/web/app/components/base/prompt-editor/plugins/component-picker-block/hooks.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/hooks.spec.tsx @@ -12,7 +12,7 @@ import type { RequestURLBlockType, VariableBlockType, WorkflowVariableBlockType, -} from '../../types' +} from '../../../types' import type { NodeOutPutVar } from '@/app/components/workflow/types' import { LexicalComposer } from '@lexical/react/LexicalComposer' import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' @@ -20,13 +20,13 @@ import { renderHook } from '@testing-library/react' import * as React from 'react' import { GeneratorType } from '@/app/components/app/configuration/config/automatic/types' import { VarType } from '@/app/components/workflow/types' -import { CustomTextNode } from '../custom-text/node' +import { CustomTextNode } from '../../custom-text/node' import { useExternalToolOptions, useOptions, usePromptOptions, useVariableOptions, -} from './hooks' +} from '../hooks' // ─── Helpers ───────────────────────────────────────────────────────────────── diff --git a/web/app/components/base/prompt-editor/plugins/component-picker-block/index.spec.tsx b/web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/prompt-editor/plugins/component-picker-block/index.spec.tsx rename to web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/index.spec.tsx index fd623d39ad..2deec561e9 100644 --- a/web/app/components/base/prompt-editor/plugins/component-picker-block/index.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/index.spec.tsx @@ -8,7 +8,7 @@ import type { QueryBlockType, VariableBlockType, WorkflowVariableBlockType, -} from '../../types' +} from '../../../types' import type { NodeOutPutVar, Var } from '@/app/components/workflow/types' import type { EventEmitterValue } from '@/context/event-emitter' import { LexicalComposer } from '@lexical/react/LexicalComposer' @@ -29,13 +29,13 @@ import * as React from 'react' import { GeneratorType } from '@/app/components/app/configuration/config/automatic/types' import { VarType } from '@/app/components/workflow/types' import { EventEmitterContextProvider, useEventEmitterContextContext } from '@/context/event-emitter' -import { INSERT_CONTEXT_BLOCK_COMMAND } from '../context-block' -import { INSERT_CURRENT_BLOCK_COMMAND } from '../current-block' -import { INSERT_ERROR_MESSAGE_BLOCK_COMMAND } from '../error-message-block' -import { INSERT_LAST_RUN_BLOCK_COMMAND } from '../last-run-block' -import { INSERT_VARIABLE_VALUE_BLOCK_COMMAND } from '../variable-block' -import { INSERT_WORKFLOW_VARIABLE_BLOCK_COMMAND } from '../workflow-variable-block' -import ComponentPicker from './index' +import { INSERT_CONTEXT_BLOCK_COMMAND } from '../../context-block' +import { INSERT_CURRENT_BLOCK_COMMAND } from '../../current-block' +import { INSERT_ERROR_MESSAGE_BLOCK_COMMAND } from '../../error-message-block' +import { INSERT_LAST_RUN_BLOCK_COMMAND } from '../../last-run-block' +import { INSERT_VARIABLE_VALUE_BLOCK_COMMAND } from '../../variable-block' +import { INSERT_WORKFLOW_VARIABLE_BLOCK_COMMAND } from '../../workflow-variable-block' +import ComponentPicker from '../index' // Mock Range.getClientRects / getBoundingClientRect for Lexical menu positioning in JSDOM. // This mirrors the pattern used by other prompt-editor plugin tests in this repo. diff --git a/web/app/components/base/prompt-editor/plugins/component-picker-block/menu.spec.tsx b/web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/menu.spec.tsx similarity index 98% rename from web/app/components/base/prompt-editor/plugins/component-picker-block/menu.spec.tsx rename to web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/menu.spec.tsx index 2ee4fb7e0b..5796589a9d 100644 --- a/web/app/components/base/prompt-editor/plugins/component-picker-block/menu.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/menu.spec.tsx @@ -1,6 +1,6 @@ import { render } from '@testing-library/react' import { Fragment } from 'react' -import { PickerBlockMenuOption } from './menu' +import { PickerBlockMenuOption } from '../menu' describe('PickerBlockMenuOption', () => { // Define the render props type locally to match the component's internal type accurately diff --git a/web/app/components/base/prompt-editor/plugins/component-picker-block/prompt-option.spec.tsx b/web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/prompt-option.spec.tsx similarity index 98% rename from web/app/components/base/prompt-editor/plugins/component-picker-block/prompt-option.spec.tsx rename to web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/prompt-option.spec.tsx index c48c52a0b7..2d8356da3d 100644 --- a/web/app/components/base/prompt-editor/plugins/component-picker-block/prompt-option.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/prompt-option.spec.tsx @@ -1,5 +1,5 @@ import { createEvent, fireEvent, render, screen } from '@testing-library/react' -import { PromptMenuItem } from './prompt-option' +import { PromptMenuItem } from '../prompt-option' describe('PromptMenuItem', () => { const defaultProps = { diff --git a/web/app/components/base/prompt-editor/plugins/component-picker-block/variable-option.spec.tsx b/web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/variable-option.spec.tsx similarity index 98% rename from web/app/components/base/prompt-editor/plugins/component-picker-block/variable-option.spec.tsx rename to web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/variable-option.spec.tsx index 228f2ac657..7925765e14 100644 --- a/web/app/components/base/prompt-editor/plugins/component-picker-block/variable-option.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/component-picker-block/__tests__/variable-option.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import { VariableMenuItem } from './variable-option' +import { VariableMenuItem } from '../variable-option' describe('VariableMenuItem', () => { const defaultProps = { diff --git a/web/app/components/base/prompt-editor/plugins/context-block/component.spec.tsx b/web/app/components/base/prompt-editor/plugins/context-block/__tests__/component.spec.tsx similarity index 98% rename from web/app/components/base/prompt-editor/plugins/context-block/component.spec.tsx rename to web/app/components/base/prompt-editor/plugins/context-block/__tests__/component.spec.tsx index 716f4285de..3b571e9ee1 100644 --- a/web/app/components/base/prompt-editor/plugins/context-block/component.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/context-block/__tests__/component.spec.tsx @@ -1,12 +1,12 @@ import { act, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { UPDATE_DATASETS_EVENT_EMITTER } from '../../constants' -import ContextBlockComponent from './component' +import { UPDATE_DATASETS_EVENT_EMITTER } from '../../../constants' +import ContextBlockComponent from '../component' // Mock the hooks used by ContextBlockComponent const mockUseSelectOrDelete = vi.fn() const mockUseTrigger = vi.fn() -vi.mock('../../hooks', () => ({ +vi.mock('../../../hooks', () => ({ useSelectOrDelete: (...args: unknown[]) => mockUseSelectOrDelete(...args), useTrigger: (...args: unknown[]) => mockUseTrigger(...args), })) diff --git a/web/app/components/base/prompt-editor/plugins/context-block/context-block-replacement-block.spec.tsx b/web/app/components/base/prompt-editor/plugins/context-block/__tests__/context-block-replacement-block.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/context-block/context-block-replacement-block.spec.tsx rename to web/app/components/base/prompt-editor/plugins/context-block/__tests__/context-block-replacement-block.spec.tsx index 217ff336c6..09ff3f9b90 100644 --- a/web/app/components/base/prompt-editor/plugins/context-block/context-block-replacement-block.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/context-block/__tests__/context-block-replacement-block.spec.tsx @@ -5,12 +5,12 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext import { render } from '@testing-library/react' import { $createParagraphNode, $getRoot, $nodesOfType } from 'lexical' import * as React from 'react' -import { ContextBlockNode } from '../context-block/node' -import { $createCustomTextNode, CustomTextNode } from '../custom-text/node' -import ContextBlockReplacementBlock from './context-block-replacement-block' +import { ContextBlockNode } from '../../context-block/node' +import { $createCustomTextNode, CustomTextNode } from '../../custom-text/node' +import ContextBlockReplacementBlock from '../context-block-replacement-block' // Mock the component rendered by ContextBlockNode.decorate() -vi.mock('./component', () => ({ +vi.mock('../component', () => ({ default: () => null, })) diff --git a/web/app/components/base/prompt-editor/plugins/context-block/index.spec.tsx b/web/app/components/base/prompt-editor/plugins/context-block/__tests__/index.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/context-block/index.spec.tsx rename to web/app/components/base/prompt-editor/plugins/context-block/__tests__/index.spec.tsx index 93be3d022a..8ca0d80ef2 100644 --- a/web/app/components/base/prompt-editor/plugins/context-block/index.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/context-block/__tests__/index.spec.tsx @@ -1,18 +1,18 @@ import type { LexicalEditor } from 'lexical' import type { ReactNode } from 'react' -import type { Dataset } from './index' +import type { Dataset } from '../index' import { LexicalComposer } from '@lexical/react/LexicalComposer' import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' import { render } from '@testing-library/react' import { $createParagraphNode, $getRoot } from 'lexical' import * as React from 'react' -import { ContextBlock, DELETE_CONTEXT_BLOCK_COMMAND, INSERT_CONTEXT_BLOCK_COMMAND } from './index' -import { ContextBlockNode } from './node' +import { ContextBlock, DELETE_CONTEXT_BLOCK_COMMAND, INSERT_CONTEXT_BLOCK_COMMAND } from '../index' +import { ContextBlockNode } from '../node' const mockCreateContextBlockNode = vi.fn() -vi.mock('./node', async () => { - const actual = await vi.importActual('./node') +vi.mock('../node', async () => { + const actual = await vi.importActual('../node') return { ...actual, @@ -23,7 +23,7 @@ vi.mock('./node', async () => { } }) -vi.mock('./component', () => ({ +vi.mock('../component', () => ({ default: () => null, })) diff --git a/web/app/components/base/prompt-editor/plugins/context-block/node.spec.tsx b/web/app/components/base/prompt-editor/plugins/context-block/__tests__/node.spec.tsx similarity index 98% rename from web/app/components/base/prompt-editor/plugins/context-block/node.spec.tsx rename to web/app/components/base/prompt-editor/plugins/context-block/__tests__/node.spec.tsx index 556f50badf..14567894e0 100644 --- a/web/app/components/base/prompt-editor/plugins/context-block/node.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/context-block/__tests__/node.spec.tsx @@ -1,6 +1,6 @@ import { $getRoot } from 'lexical' -import { createTestEditor, withEditorUpdate } from '../__tests__/utils' -import { $createContextBlockNode, $isContextBlockNode, ContextBlockNode } from './node' +import { createTestEditor, withEditorUpdate } from '../../__tests__/utils' +import { $createContextBlockNode, $isContextBlockNode, ContextBlockNode } from '../node' const mockDatasets = [ { id: '1', name: 'Dataset A', type: 'text' }, diff --git a/web/app/components/base/prompt-editor/plugins/current-block/component.spec.tsx b/web/app/components/base/prompt-editor/plugins/current-block/__tests__/component.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/current-block/component.spec.tsx rename to web/app/components/base/prompt-editor/plugins/current-block/__tests__/component.spec.tsx index e2669af862..45099bba8a 100644 --- a/web/app/components/base/prompt-editor/plugins/current-block/component.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/current-block/__tests__/component.spec.tsx @@ -3,15 +3,15 @@ import { LexicalComposer } from '@lexical/react/LexicalComposer' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { GeneratorType } from '@/app/components/app/configuration/config/automatic/types' -import { CurrentBlockNode, DELETE_CURRENT_BLOCK_COMMAND } from '.' -import { CustomTextNode } from '../custom-text/node' -import CurrentBlockComponent from './component' +import { CurrentBlockNode, DELETE_CURRENT_BLOCK_COMMAND } from '..' +import { CustomTextNode } from '../../custom-text/node' +import CurrentBlockComponent from '../component' const { mockUseSelectOrDelete } = vi.hoisted(() => ({ mockUseSelectOrDelete: vi.fn(), })) -vi.mock('../../hooks', () => ({ +vi.mock('../../../hooks', () => ({ useSelectOrDelete: (...args: unknown[]) => mockUseSelectOrDelete(...args), })) diff --git a/web/app/components/base/prompt-editor/plugins/current-block/current-block-replacement-block.spec.tsx b/web/app/components/base/prompt-editor/plugins/current-block/__tests__/current-block-replacement-block.spec.tsx similarity index 93% rename from web/app/components/base/prompt-editor/plugins/current-block/current-block-replacement-block.spec.tsx rename to web/app/components/base/prompt-editor/plugins/current-block/__tests__/current-block-replacement-block.spec.tsx index 16b75834fe..c7bd628e48 100644 --- a/web/app/components/base/prompt-editor/plugins/current-block/current-block-replacement-block.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/current-block/__tests__/current-block-replacement-block.spec.tsx @@ -3,17 +3,17 @@ import { LexicalComposer } from '@lexical/react/LexicalComposer' import { render, waitFor } from '@testing-library/react' import { $nodesOfType } from 'lexical' import { GeneratorType } from '@/app/components/app/configuration/config/automatic/types' -import { CURRENT_PLACEHOLDER_TEXT } from '../../constants' -import { CustomTextNode } from '../custom-text/node' +import { CURRENT_PLACEHOLDER_TEXT } from '../../../constants' +import { CustomTextNode } from '../../custom-text/node' import { getNodeCount, readEditorStateValue, renderLexicalEditor, setEditorRootText, waitForEditorReady, -} from '../test-helpers' -import CurrentBlockReplacementBlock from './current-block-replacement-block' -import { CurrentBlockNode } from './index' +} from '../../test-helpers' +import CurrentBlockReplacementBlock from '../current-block-replacement-block' +import { CurrentBlockNode } from '../index' const renderReplacementPlugin = (props?: { generatorType?: GeneratorType diff --git a/web/app/components/base/prompt-editor/plugins/current-block/index.spec.tsx b/web/app/components/base/prompt-editor/plugins/current-block/__tests__/index.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/current-block/index.spec.tsx rename to web/app/components/base/prompt-editor/plugins/current-block/__tests__/index.spec.tsx index 39085c5925..88f0e6d779 100644 --- a/web/app/components/base/prompt-editor/plugins/current-block/index.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/current-block/__tests__/index.spec.tsx @@ -3,8 +3,8 @@ import { LexicalComposer } from '@lexical/react/LexicalComposer' import { act, render, waitFor } from '@testing-library/react' import { $nodesOfType } from 'lexical' import { GeneratorType } from '@/app/components/app/configuration/config/automatic/types' -import { CURRENT_PLACEHOLDER_TEXT } from '../../constants' -import { CustomTextNode } from '../custom-text/node' +import { CURRENT_PLACEHOLDER_TEXT } from '../../../constants' +import { CustomTextNode } from '../../custom-text/node' import { getNodeCount, readEditorStateValue, @@ -12,13 +12,13 @@ import { renderLexicalEditor, selectRootEnd, waitForEditorReady, -} from '../test-helpers' +} from '../../test-helpers' import { CurrentBlock, CurrentBlockNode, DELETE_CURRENT_BLOCK_COMMAND, INSERT_CURRENT_BLOCK_COMMAND, -} from './index' +} from '../index' const renderCurrentBlock = (props?: { generatorType?: GeneratorType diff --git a/web/app/components/base/prompt-editor/plugins/current-block/node.spec.tsx b/web/app/components/base/prompt-editor/plugins/current-block/__tests__/node.spec.tsx similarity index 98% rename from web/app/components/base/prompt-editor/plugins/current-block/node.spec.tsx rename to web/app/components/base/prompt-editor/plugins/current-block/__tests__/node.spec.tsx index 26063fb8a7..23cb0421e4 100644 --- a/web/app/components/base/prompt-editor/plugins/current-block/node.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/current-block/__tests__/node.spec.tsx @@ -7,13 +7,13 @@ import { GeneratorType } from '@/app/components/app/configuration/config/automat import { createLexicalTestEditor, expectInlineWrapperDom, -} from '../test-helpers' -import CurrentBlockComponent from './component' +} from '../../test-helpers' +import CurrentBlockComponent from '../component' import { $createCurrentBlockNode, $isCurrentBlockNode, CurrentBlockNode, -} from './node' +} from '../node' const createTestEditor = () => { return createLexicalTestEditor('current-block-node-test', [CurrentBlockNode]) diff --git a/web/app/components/base/prompt-editor/plugins/custom-text/node.spec.tsx b/web/app/components/base/prompt-editor/plugins/custom-text/__tests__/node.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/custom-text/node.spec.tsx rename to web/app/components/base/prompt-editor/plugins/custom-text/__tests__/node.spec.tsx index 9688049950..52d2a19313 100644 --- a/web/app/components/base/prompt-editor/plugins/custom-text/node.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/custom-text/__tests__/node.spec.tsx @@ -1,7 +1,7 @@ import type { EditorConfig, LexicalEditor } from 'lexical' import { $createParagraphNode, $getRoot } from 'lexical' -import { createTestEditor, withEditorUpdate } from '../__tests__/utils' -import { $createCustomTextNode, CustomTextNode } from './node' +import { createTestEditor, withEditorUpdate } from '../../__tests__/utils' +import { $createCustomTextNode, CustomTextNode } from '../node' const createCustomTextTestEditor = () => createTestEditor([CustomTextNode]) diff --git a/web/app/components/base/prompt-editor/plugins/draggable-plugin/index.spec.tsx b/web/app/components/base/prompt-editor/plugins/draggable-plugin/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/prompt-editor/plugins/draggable-plugin/index.spec.tsx rename to web/app/components/base/prompt-editor/plugins/draggable-plugin/__tests__/index.spec.tsx index 1ee548fbcc..0e02525e17 100644 --- a/web/app/components/base/prompt-editor/plugins/draggable-plugin/index.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/draggable-plugin/__tests__/index.spec.tsx @@ -3,7 +3,7 @@ import { ContentEditable } from '@lexical/react/LexicalContentEditable' import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary' import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin' import { fireEvent, render, screen, waitFor } from '@testing-library/react' -import DraggableBlockPlugin from '.' +import DraggableBlockPlugin from '..' const CONTENT_EDITABLE_TEST_ID = 'draggable-content-editable' let namespaceCounter = 0 diff --git a/web/app/components/base/prompt-editor/plugins/error-message-block/component.spec.tsx b/web/app/components/base/prompt-editor/plugins/error-message-block/__tests__/component.spec.tsx similarity index 95% rename from web/app/components/base/prompt-editor/plugins/error-message-block/component.spec.tsx rename to web/app/components/base/prompt-editor/plugins/error-message-block/__tests__/component.spec.tsx index 7f03aa8ba1..b9576f35b5 100644 --- a/web/app/components/base/prompt-editor/plugins/error-message-block/component.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/error-message-block/__tests__/component.spec.tsx @@ -4,11 +4,11 @@ import type { ReactElement } from 'react' import { LexicalComposerContext } from '@lexical/react/LexicalComposerContext' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { useSelectOrDelete } from '../../hooks' -import ErrorMessageBlockComponent from './component' -import { DELETE_ERROR_MESSAGE_COMMAND, ErrorMessageBlockNode } from './index' +import { useSelectOrDelete } from '../../../hooks' +import ErrorMessageBlockComponent from '../component' +import { DELETE_ERROR_MESSAGE_COMMAND, ErrorMessageBlockNode } from '../index' -vi.mock('../../hooks') +vi.mock('../../../hooks') const mockHasNodes = vi.fn() diff --git a/web/app/components/base/prompt-editor/plugins/error-message-block/error-message-block-replacement-block.spec.tsx b/web/app/components/base/prompt-editor/plugins/error-message-block/__tests__/error-message-block-replacement-block.spec.tsx similarity index 93% rename from web/app/components/base/prompt-editor/plugins/error-message-block/error-message-block-replacement-block.spec.tsx rename to web/app/components/base/prompt-editor/plugins/error-message-block/__tests__/error-message-block-replacement-block.spec.tsx index 30737abf36..ccef57867a 100644 --- a/web/app/components/base/prompt-editor/plugins/error-message-block/error-message-block-replacement-block.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/error-message-block/__tests__/error-message-block-replacement-block.spec.tsx @@ -6,16 +6,16 @@ import { LexicalComposerContext } from '@lexical/react/LexicalComposerContext' import { mergeRegister } from '@lexical/utils' import { render } from '@testing-library/react' import { $applyNodeReplacement } from 'lexical' -import { ERROR_MESSAGE_PLACEHOLDER_TEXT } from '../../constants' -import { decoratorTransform } from '../../utils' -import { CustomTextNode } from '../custom-text/node' -import ErrorMessageBlockReplacementBlock from './error-message-block-replacement-block' -import { $createErrorMessageBlockNode, ErrorMessageBlockNode } from './node' +import { ERROR_MESSAGE_PLACEHOLDER_TEXT } from '../../../constants' +import { decoratorTransform } from '../../../utils' +import { CustomTextNode } from '../../custom-text/node' +import ErrorMessageBlockReplacementBlock from '../error-message-block-replacement-block' +import { $createErrorMessageBlockNode, ErrorMessageBlockNode } from '../node' vi.mock('@lexical/utils') vi.mock('lexical') -vi.mock('../../utils') -vi.mock('./node') +vi.mock('../../../utils') +vi.mock('../node') const mockHasNodes = vi.fn() const mockRegisterNodeTransform = vi.fn() diff --git a/web/app/components/base/prompt-editor/plugins/error-message-block/index.spec.tsx b/web/app/components/base/prompt-editor/plugins/error-message-block/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/prompt-editor/plugins/error-message-block/index.spec.tsx rename to web/app/components/base/prompt-editor/plugins/error-message-block/__tests__/index.spec.tsx index 938fda1555..fa52df0a23 100644 --- a/web/app/components/base/prompt-editor/plugins/error-message-block/index.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/error-message-block/__tests__/index.spec.tsx @@ -10,8 +10,8 @@ import { ErrorMessageBlock, ErrorMessageBlockNode, INSERT_ERROR_MESSAGE_BLOCK_COMMAND, -} from './index' -import { $createErrorMessageBlockNode } from './node' +} from '../index' +import { $createErrorMessageBlockNode } from '../node' vi.mock('@lexical/utils') vi.mock('lexical', async () => { @@ -23,7 +23,7 @@ vi.mock('lexical', async () => { COMMAND_PRIORITY_EDITOR: 1, } }) -vi.mock('./node') +vi.mock('../node') const mockHasNodes = vi.fn() const mockRegisterCommand = vi.fn() diff --git a/web/app/components/base/prompt-editor/plugins/error-message-block/node.spec.tsx b/web/app/components/base/prompt-editor/plugins/error-message-block/__tests__/node.spec.tsx similarity index 98% rename from web/app/components/base/prompt-editor/plugins/error-message-block/node.spec.tsx rename to web/app/components/base/prompt-editor/plugins/error-message-block/__tests__/node.spec.tsx index 6c28091f27..1e952d08c9 100644 --- a/web/app/components/base/prompt-editor/plugins/error-message-block/node.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/error-message-block/__tests__/node.spec.tsx @@ -1,6 +1,6 @@ import type { Klass, LexicalEditor, LexicalNode } from 'lexical' import { createEditor } from 'lexical' -import { $createErrorMessageBlockNode, $isErrorMessageBlockNode, ErrorMessageBlockNode } from './node' +import { $createErrorMessageBlockNode, $isErrorMessageBlockNode, ErrorMessageBlockNode } from '../node' describe('ErrorMessageBlockNode', () => { let editor: LexicalEditor diff --git a/web/app/components/base/prompt-editor/plugins/history-block/component.spec.tsx b/web/app/components/base/prompt-editor/plugins/history-block/__tests__/component.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/history-block/component.spec.tsx rename to web/app/components/base/prompt-editor/plugins/history-block/__tests__/component.spec.tsx index 5ba2f92b0e..4dc85a3081 100644 --- a/web/app/components/base/prompt-editor/plugins/history-block/component.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/history-block/__tests__/component.spec.tsx @@ -1,10 +1,10 @@ import type { Dispatch, RefObject, SetStateAction } from 'react' -import type { RoleName } from './index' +import type { RoleName } from '../index' import { act, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { UPDATE_HISTORY_EVENT_EMITTER } from '../../constants' -import HistoryBlockComponent from './component' -import { DELETE_HISTORY_BLOCK_COMMAND } from './index' +import { UPDATE_HISTORY_EVENT_EMITTER } from '../../../constants' +import HistoryBlockComponent from '../component' +import { DELETE_HISTORY_BLOCK_COMMAND } from '../index' type HistoryEventPayload = { type?: string @@ -19,7 +19,7 @@ const { mockUseSelectOrDelete, mockUseTrigger, mockUseEventEmitterContextContext mockUseEventEmitterContextContext: vi.fn(), })) -vi.mock('../../hooks', () => ({ +vi.mock('../../../hooks', () => ({ useSelectOrDelete: (...args: unknown[]) => mockUseSelectOrDelete(...args), useTrigger: (...args: unknown[]) => mockUseTrigger(...args), })) diff --git a/web/app/components/base/prompt-editor/plugins/history-block/history-block-replacement-block.spec.tsx b/web/app/components/base/prompt-editor/plugins/history-block/__tests__/history-block-replacement-block.spec.tsx similarity index 91% rename from web/app/components/base/prompt-editor/plugins/history-block/history-block-replacement-block.spec.tsx rename to web/app/components/base/prompt-editor/plugins/history-block/__tests__/history-block-replacement-block.spec.tsx index af74f39a1d..a6e40ab6ed 100644 --- a/web/app/components/base/prompt-editor/plugins/history-block/history-block-replacement-block.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/history-block/__tests__/history-block-replacement-block.spec.tsx @@ -1,19 +1,19 @@ import type { LexicalEditor } from 'lexical' -import type { RoleName } from './index' +import type { RoleName } from '../index' import { LexicalComposer } from '@lexical/react/LexicalComposer' import { render, waitFor } from '@testing-library/react' import { $nodesOfType } from 'lexical' -import { HISTORY_PLACEHOLDER_TEXT } from '../../constants' -import { CustomTextNode } from '../custom-text/node' +import { HISTORY_PLACEHOLDER_TEXT } from '../../../constants' +import { CustomTextNode } from '../../custom-text/node' import { getNodeCount, readEditorStateValue, renderLexicalEditor, setEditorRootText, waitForEditorReady, -} from '../test-helpers' -import HistoryBlockReplacementBlock from './history-block-replacement-block' -import { HistoryBlockNode } from './node' +} from '../../test-helpers' +import HistoryBlockReplacementBlock from '../history-block-replacement-block' +import { HistoryBlockNode } from '../node' const createRoleName = (overrides?: Partial): RoleName => ({ user: 'user-role', diff --git a/web/app/components/base/prompt-editor/plugins/history-block/index.spec.tsx b/web/app/components/base/prompt-editor/plugins/history-block/__tests__/index.spec.tsx similarity index 95% rename from web/app/components/base/prompt-editor/plugins/history-block/index.spec.tsx rename to web/app/components/base/prompt-editor/plugins/history-block/__tests__/index.spec.tsx index e41a8f7c63..682ec90a63 100644 --- a/web/app/components/base/prompt-editor/plugins/history-block/index.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/history-block/__tests__/index.spec.tsx @@ -1,10 +1,10 @@ import type { LexicalEditor } from 'lexical' -import type { RoleName } from './index' +import type { RoleName } from '../index' import { LexicalComposer } from '@lexical/react/LexicalComposer' import { act, render, waitFor } from '@testing-library/react' import { $nodesOfType } from 'lexical' -import { HISTORY_PLACEHOLDER_TEXT } from '../../constants' -import { CustomTextNode } from '../custom-text/node' +import { HISTORY_PLACEHOLDER_TEXT } from '../../../constants' +import { CustomTextNode } from '../../custom-text/node' import { getNodeCount, readEditorStateValue, @@ -12,14 +12,14 @@ import { renderLexicalEditor, selectRootEnd, waitForEditorReady, -} from '../test-helpers' +} from '../../test-helpers' import { DELETE_HISTORY_BLOCK_COMMAND, HistoryBlock, HistoryBlockNode, INSERT_HISTORY_BLOCK_COMMAND, -} from './index' +} from '../index' const createRoleName = (overrides?: Partial): RoleName => ({ user: 'user-role', diff --git a/web/app/components/base/prompt-editor/plugins/history-block/node.spec.tsx b/web/app/components/base/prompt-editor/plugins/history-block/__tests__/node.spec.tsx similarity index 97% rename from web/app/components/base/prompt-editor/plugins/history-block/node.spec.tsx rename to web/app/components/base/prompt-editor/plugins/history-block/__tests__/node.spec.tsx index b8603ef4fe..c7960d658e 100644 --- a/web/app/components/base/prompt-editor/plugins/history-block/node.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/history-block/__tests__/node.spec.tsx @@ -1,17 +1,17 @@ -import type { SerializedNode as SerializedHistoryBlockNode } from './node' +import type { SerializedNode as SerializedHistoryBlockNode } from '../node' import { act } from '@testing-library/react' import { $getNodeByKey, $getRoot } from 'lexical' import { createLexicalTestEditor, expectInlineWrapperDom, -} from '../test-helpers' -import HistoryBlockComponent from './component' +} from '../../test-helpers' +import HistoryBlockComponent from '../component' import { $createHistoryBlockNode, $isHistoryBlockNode, HistoryBlockNode, -} from './node' +} from '../node' const createRoleName = (overrides?: { user?: string, assistant?: string }) => ({ user: 'user-role', diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/component.spec.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/component.spec.tsx similarity index 97% rename from web/app/components/base/prompt-editor/plugins/hitl-input-block/component.spec.tsx rename to web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/component.spec.tsx index eb76728939..97085e694a 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/component.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/component.spec.tsx @@ -3,17 +3,17 @@ import type { FormInputItem } from '@/app/components/workflow/nodes/human-input/ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { InputVarType } from '@/app/components/workflow/types' -import HITLInputComponent from './component' +import HITLInputComponent from '../component' const { mockUseSelectOrDelete } = vi.hoisted(() => ({ mockUseSelectOrDelete: vi.fn(), })) -vi.mock('../../hooks', () => ({ +vi.mock('../../../hooks', () => ({ useSelectOrDelete: (...args: unknown[]) => mockUseSelectOrDelete(...args), })) -vi.mock('./component-ui', () => ({ +vi.mock('../component-ui', () => ({ default: ({ formInput, onChange }: { formInput?: FormInputItem, onChange: (payload: FormInputItem) => void }) => { const basePayload: FormInputItem = formInput ?? { type: InputVarType.paragraph, diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/hitl-input-block-replacement-block.spec.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/hitl-input-block-replacement-block.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/hitl-input-block/hitl-input-block-replacement-block.spec.tsx rename to web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/hitl-input-block-replacement-block.spec.tsx index d01cab70c2..57f1db1fa3 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/hitl-input-block-replacement-block.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/hitl-input-block-replacement-block.spec.tsx @@ -1,5 +1,5 @@ import type { LexicalEditor } from 'lexical' -import type { GetVarType } from '../../types' +import type { GetVarType } from '../../../types' import type { FormInputItem } from '@/app/components/workflow/nodes/human-input/types' import type { NodeOutPutVar, Var } from '@/app/components/workflow/types' import { LexicalComposer } from '@lexical/react/LexicalComposer' @@ -10,16 +10,16 @@ import { BlockEnum, InputVarType, } from '@/app/components/workflow/types' -import { CustomTextNode } from '../custom-text/node' +import { CustomTextNode } from '../../custom-text/node' import { getNodesByType, readEditorStateValue, renderLexicalEditor, setEditorRootText, waitForEditorReady, -} from '../test-helpers' -import HITLInputReplacementBlock from './hitl-input-block-replacement-block' -import { HITLInputNode } from './node' +} from '../../test-helpers' +import HITLInputReplacementBlock from '../hitl-input-block-replacement-block' +import { HITLInputNode } from '../node' const createWorkflowNodesMap = () => ({ 'node-1': { diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/index.spec.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/prompt-editor/plugins/hitl-input-block/index.spec.tsx rename to web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/index.spec.tsx index dc94b0b319..b5f38cdd1b 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/index.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/index.spec.tsx @@ -10,21 +10,21 @@ import { BlockEnum, InputVarType, } from '@/app/components/workflow/types' -import { CustomTextNode } from '../custom-text/node' +import { CustomTextNode } from '../../custom-text/node' import { getNodeCount, readRootTextContent, renderLexicalEditor, selectRootEnd, waitForEditorReady, -} from '../test-helpers' +} from '../../test-helpers' import { DELETE_HITL_INPUT_BLOCK_COMMAND, HITLInputBlock, HITLInputNode, INSERT_HITL_INPUT_BLOCK_COMMAND, UPDATE_WORKFLOW_NODES_MAP, -} from './index' +} from '../index' type UpdateWorkflowNodesMapPluginProps = { onUpdate: (payload: unknown) => void diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/input-field.spec.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/input-field.spec.tsx similarity index 99% rename from web/app/components/base/prompt-editor/plugins/hitl-input-block/input-field.spec.tsx rename to web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/input-field.spec.tsx index b7518e8895..949295a8a8 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/input-field.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/input-field.spec.tsx @@ -2,7 +2,7 @@ import type { FormInputItem } from '@/app/components/workflow/nodes/human-input/ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { InputVarType } from '@/app/components/workflow/types' -import InputField from './input-field' +import InputField from '../input-field' type VarReferencePickerProps = { onChange: (value: string[]) => void diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/node.spec.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/node.spec.tsx similarity index 98% rename from web/app/components/base/prompt-editor/plugins/hitl-input-block/node.spec.tsx rename to web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/node.spec.tsx index ef2a0e0c51..f4ab8ff90a 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/node.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/node.spec.tsx @@ -8,13 +8,13 @@ import { import { createLexicalTestEditor, expectInlineWrapperDom, -} from '../test-helpers' -import HITLInputBlockComponent from './component' +} from '../../test-helpers' +import HITLInputBlockComponent from '../component' import { $createHITLInputNode, $isHITLInputNode, HITLInputNode, -} from './node' +} from '../node' const createFormInput = (): FormInputItem => ({ type: InputVarType.paragraph, diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/pre-populate.spec.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/pre-populate.spec.tsx similarity index 98% rename from web/app/components/base/prompt-editor/plugins/hitl-input-block/pre-populate.spec.tsx rename to web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/pre-populate.spec.tsx index be95aea062..880ad509b3 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/pre-populate.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/pre-populate.spec.tsx @@ -2,7 +2,7 @@ import type { Var } from '@/app/components/workflow/types' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { useState } from 'react' -import PrePopulate from './pre-populate' +import PrePopulate from '../pre-populate' const { mockVarReferencePicker } = vi.hoisted(() => ({ mockVarReferencePicker: vi.fn(), diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/tag-label.spec.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/tag-label.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/hitl-input-block/tag-label.spec.tsx rename to web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/tag-label.spec.tsx index c39b66e545..d85224ca74 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/tag-label.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/tag-label.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import TagLabel from './tag-label' +import TagLabel from '../tag-label' describe('TagLabel', () => { beforeEach(() => { diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/type-switch.spec.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/type-switch.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/hitl-input-block/type-switch.spec.tsx rename to web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/type-switch.spec.tsx index b3d1376eb9..a23ef088f9 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/type-switch.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/type-switch.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import TypeSwitch from './type-switch' +import TypeSwitch from '../type-switch' describe('TypeSwitch', () => { beforeEach(() => { diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/variable-block.spec.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/variable-block.spec.tsx similarity index 95% rename from web/app/components/base/prompt-editor/plugins/hitl-input-block/variable-block.spec.tsx rename to web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/variable-block.spec.tsx index 727bc664d3..f16951aed1 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/variable-block.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/__tests__/variable-block.spec.tsx @@ -1,5 +1,5 @@ import type { LexicalEditor } from 'lexical' -import type { WorkflowNodesMap } from '../workflow-variable-block/node' +import type { WorkflowNodesMap } from '../../workflow-variable-block/node' import type { Var } from '@/app/components/workflow/types' import { LexicalComposer } from '@lexical/react/LexicalComposer' import { act, render, screen, waitFor } from '@testing-library/react' @@ -10,10 +10,10 @@ import { Type } from '@/app/components/workflow/nodes/llm/types' import { BlockEnum, } from '@/app/components/workflow/types' -import { CaptureEditorPlugin } from '../test-utils' -import { UPDATE_WORKFLOW_NODES_MAP } from '../workflow-variable-block' -import { HITLInputNode } from './node' -import HITLInputVariableBlockComponent from './variable-block' +import { CaptureEditorPlugin } from '../../test-utils' +import { UPDATE_WORKFLOW_NODES_MAP } from '../../workflow-variable-block' +import { HITLInputNode } from '../node' +import HITLInputVariableBlockComponent from '../variable-block' const createWorkflowNodesMap = (title = 'Node One'): WorkflowNodesMap => ({ 'node-1': { diff --git a/web/app/components/base/prompt-editor/plugins/last-run-block/component.spec.tsx b/web/app/components/base/prompt-editor/plugins/last-run-block/__tests__/component.spec.tsx similarity index 93% rename from web/app/components/base/prompt-editor/plugins/last-run-block/component.spec.tsx rename to web/app/components/base/prompt-editor/plugins/last-run-block/__tests__/component.spec.tsx index 29da9e4e9c..8a777be096 100644 --- a/web/app/components/base/prompt-editor/plugins/last-run-block/component.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/last-run-block/__tests__/component.spec.tsx @@ -2,15 +2,15 @@ import type { RefObject } from 'react' import { LexicalComposer } from '@lexical/react/LexicalComposer' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { LastRunBlockNode } from '.' -import { CustomTextNode } from '../custom-text/node' -import LastRunBlockComponent from './component' +import { LastRunBlockNode } from '..' +import { CustomTextNode } from '../../custom-text/node' +import LastRunBlockComponent from '../component' const { mockUseSelectOrDelete } = vi.hoisted(() => ({ mockUseSelectOrDelete: vi.fn(), })) -vi.mock('../../hooks', () => ({ +vi.mock('../../../hooks', () => ({ useSelectOrDelete: (...args: unknown[]) => mockUseSelectOrDelete(...args), })) diff --git a/web/app/components/base/prompt-editor/plugins/last-run-block/index.spec.tsx b/web/app/components/base/prompt-editor/plugins/last-run-block/__tests__/index.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/last-run-block/index.spec.tsx rename to web/app/components/base/prompt-editor/plugins/last-run-block/__tests__/index.spec.tsx index 7a28bf847d..73af3ee857 100644 --- a/web/app/components/base/prompt-editor/plugins/last-run-block/index.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/last-run-block/__tests__/index.spec.tsx @@ -1,20 +1,20 @@ import { LexicalComposer } from '@lexical/react/LexicalComposer' import { act, render, waitFor } from '@testing-library/react' -import { LAST_RUN_PLACEHOLDER_TEXT } from '../../constants' -import { CustomTextNode } from '../custom-text/node' +import { LAST_RUN_PLACEHOLDER_TEXT } from '../../../constants' +import { CustomTextNode } from '../../custom-text/node' import { getNodeCount, readRootTextContent, renderLexicalEditor, selectRootEnd, waitForEditorReady, -} from '../test-helpers' +} from '../../test-helpers' import { DELETE_LAST_RUN_COMMAND, INSERT_LAST_RUN_BLOCK_COMMAND, LastRunBlock, LastRunBlockNode, -} from './index' +} from '../index' const renderLastRunBlock = (props?: { onInsert?: () => void diff --git a/web/app/components/base/prompt-editor/plugins/last-run-block/last-run-block-replacement-block.spec.tsx b/web/app/components/base/prompt-editor/plugins/last-run-block/__tests__/last-run-block-replacement-block.spec.tsx similarity index 91% rename from web/app/components/base/prompt-editor/plugins/last-run-block/last-run-block-replacement-block.spec.tsx rename to web/app/components/base/prompt-editor/plugins/last-run-block/__tests__/last-run-block-replacement-block.spec.tsx index ba144c9e5f..c0adc2275a 100644 --- a/web/app/components/base/prompt-editor/plugins/last-run-block/last-run-block-replacement-block.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/last-run-block/__tests__/last-run-block-replacement-block.spec.tsx @@ -1,15 +1,15 @@ import { LexicalComposer } from '@lexical/react/LexicalComposer' import { render, waitFor } from '@testing-library/react' -import { LAST_RUN_PLACEHOLDER_TEXT } from '../../constants' -import { CustomTextNode } from '../custom-text/node' +import { LAST_RUN_PLACEHOLDER_TEXT } from '../../../constants' +import { CustomTextNode } from '../../custom-text/node' import { getNodeCount, renderLexicalEditor, setEditorRootText, waitForEditorReady, -} from '../test-helpers' -import { LastRunBlockNode } from './index' -import LastRunReplacementBlock from './last-run-block-replacement-block' +} from '../../test-helpers' +import { LastRunBlockNode } from '../index' +import LastRunReplacementBlock from '../last-run-block-replacement-block' const renderReplacementPlugin = (props?: { onInsert?: () => void diff --git a/web/app/components/base/prompt-editor/plugins/last-run-block/node.spec.tsx b/web/app/components/base/prompt-editor/plugins/last-run-block/__tests__/node.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/last-run-block/node.spec.tsx rename to web/app/components/base/prompt-editor/plugins/last-run-block/__tests__/node.spec.tsx index dcc75b56c6..e7752b0ddc 100644 --- a/web/app/components/base/prompt-editor/plugins/last-run-block/node.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/last-run-block/__tests__/node.spec.tsx @@ -2,13 +2,13 @@ import { act } from '@testing-library/react' import { createLexicalTestEditor, expectInlineWrapperDom, -} from '../test-helpers' -import LastRunBlockComponent from './component' +} from '../../test-helpers' +import LastRunBlockComponent from '../component' import { $createLastRunBlockNode, $isLastRunBlockNode, LastRunBlockNode, -} from './node' +} from '../node' const createTestEditor = () => { return createLexicalTestEditor('last-run-block-node-test', [LastRunBlockNode]) diff --git a/web/app/components/base/prompt-editor/plugins/query-block/component.spec.tsx b/web/app/components/base/prompt-editor/plugins/query-block/__tests__/component.spec.tsx similarity index 92% rename from web/app/components/base/prompt-editor/plugins/query-block/component.spec.tsx rename to web/app/components/base/prompt-editor/plugins/query-block/__tests__/component.spec.tsx index 28f439cafe..9b7ebf0399 100644 --- a/web/app/components/base/prompt-editor/plugins/query-block/component.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/query-block/__tests__/component.spec.tsx @@ -1,13 +1,13 @@ import type { RefObject } from 'react' import { render, screen } from '@testing-library/react' -import QueryBlockComponent from './component' -import { DELETE_QUERY_BLOCK_COMMAND } from './index' +import QueryBlockComponent from '../component' +import { DELETE_QUERY_BLOCK_COMMAND } from '../index' const { mockUseSelectOrDelete } = vi.hoisted(() => ({ mockUseSelectOrDelete: vi.fn(), })) -vi.mock('../../hooks', () => ({ +vi.mock('../../../hooks', () => ({ useSelectOrDelete: (...args: unknown[]) => mockUseSelectOrDelete(...args), })) diff --git a/web/app/components/base/prompt-editor/plugins/query-block/index.spec.tsx b/web/app/components/base/prompt-editor/plugins/query-block/__tests__/index.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/query-block/index.spec.tsx rename to web/app/components/base/prompt-editor/plugins/query-block/__tests__/index.spec.tsx index 08f6109b7c..f17018f12c 100644 --- a/web/app/components/base/prompt-editor/plugins/query-block/index.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/query-block/__tests__/index.spec.tsx @@ -1,20 +1,20 @@ import { LexicalComposer } from '@lexical/react/LexicalComposer' import { act, render, waitFor } from '@testing-library/react' -import { QUERY_PLACEHOLDER_TEXT } from '../../constants' -import { CustomTextNode } from '../custom-text/node' +import { QUERY_PLACEHOLDER_TEXT } from '../../../constants' +import { CustomTextNode } from '../../custom-text/node' import { getNodeCount, readRootTextContent, renderLexicalEditor, selectRootEnd, waitForEditorReady, -} from '../test-helpers' +} from '../../test-helpers' import { DELETE_QUERY_BLOCK_COMMAND, INSERT_QUERY_BLOCK_COMMAND, QueryBlock, QueryBlockNode, -} from './index' +} from '../index' const renderQueryBlock = (props: { onInsert?: () => void diff --git a/web/app/components/base/prompt-editor/plugins/query-block/node.spec.tsx b/web/app/components/base/prompt-editor/plugins/query-block/__tests__/node.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/query-block/node.spec.tsx rename to web/app/components/base/prompt-editor/plugins/query-block/__tests__/node.spec.tsx index e91714e098..e927856e1a 100644 --- a/web/app/components/base/prompt-editor/plugins/query-block/node.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/query-block/__tests__/node.spec.tsx @@ -2,13 +2,13 @@ import { act } from '@testing-library/react' import { createLexicalTestEditor, expectInlineWrapperDom, -} from '../test-helpers' -import QueryBlockComponent from './component' +} from '../../test-helpers' +import QueryBlockComponent from '../component' import { $createQueryBlockNode, $isQueryBlockNode, QueryBlockNode, -} from './node' +} from '../node' describe('QueryBlockNode', () => { const createTestEditor = () => { diff --git a/web/app/components/base/prompt-editor/plugins/query-block/query-block-replacement-block.spec.tsx b/web/app/components/base/prompt-editor/plugins/query-block/__tests__/query-block-replacement-block.spec.tsx similarity index 91% rename from web/app/components/base/prompt-editor/plugins/query-block/query-block-replacement-block.spec.tsx rename to web/app/components/base/prompt-editor/plugins/query-block/__tests__/query-block-replacement-block.spec.tsx index 379128df2e..9a92aba3c0 100644 --- a/web/app/components/base/prompt-editor/plugins/query-block/query-block-replacement-block.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/query-block/__tests__/query-block-replacement-block.spec.tsx @@ -1,15 +1,15 @@ import { LexicalComposer } from '@lexical/react/LexicalComposer' import { render, waitFor } from '@testing-library/react' -import { QUERY_PLACEHOLDER_TEXT } from '../../constants' -import { CustomTextNode } from '../custom-text/node' +import { QUERY_PLACEHOLDER_TEXT } from '../../../constants' +import { CustomTextNode } from '../../custom-text/node' import { getNodeCount, renderLexicalEditor, setEditorRootText, waitForEditorReady, -} from '../test-helpers' -import { QueryBlockNode } from './index' -import QueryBlockReplacementBlock from './query-block-replacement-block' +} from '../../test-helpers' +import { QueryBlockNode } from '../index' +import QueryBlockReplacementBlock from '../query-block-replacement-block' const renderReplacementPlugin = (props: { onInsert?: () => void diff --git a/web/app/components/base/prompt-editor/plugins/request-url-block/component.spec.tsx b/web/app/components/base/prompt-editor/plugins/request-url-block/__tests__/component.spec.tsx similarity index 92% rename from web/app/components/base/prompt-editor/plugins/request-url-block/component.spec.tsx rename to web/app/components/base/prompt-editor/plugins/request-url-block/__tests__/component.spec.tsx index f1b97d9417..811eaf462f 100644 --- a/web/app/components/base/prompt-editor/plugins/request-url-block/component.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/request-url-block/__tests__/component.spec.tsx @@ -1,13 +1,13 @@ import type { RefObject } from 'react' import { render, screen } from '@testing-library/react' -import RequestURLBlockComponent from './component' -import { DELETE_REQUEST_URL_BLOCK_COMMAND } from './index' +import RequestURLBlockComponent from '../component' +import { DELETE_REQUEST_URL_BLOCK_COMMAND } from '../index' const { mockUseSelectOrDelete } = vi.hoisted(() => ({ mockUseSelectOrDelete: vi.fn(), })) -vi.mock('../../hooks', () => ({ +vi.mock('../../../hooks', () => ({ useSelectOrDelete: (...args: unknown[]) => mockUseSelectOrDelete(...args), })) diff --git a/web/app/components/base/prompt-editor/plugins/request-url-block/index.spec.tsx b/web/app/components/base/prompt-editor/plugins/request-url-block/__tests__/index.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/request-url-block/index.spec.tsx rename to web/app/components/base/prompt-editor/plugins/request-url-block/__tests__/index.spec.tsx index 431acdb0df..2b479edd09 100644 --- a/web/app/components/base/prompt-editor/plugins/request-url-block/index.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/request-url-block/__tests__/index.spec.tsx @@ -1,20 +1,20 @@ import { LexicalComposer } from '@lexical/react/LexicalComposer' import { act, render, waitFor } from '@testing-library/react' -import { REQUEST_URL_PLACEHOLDER_TEXT } from '../../constants' -import { CustomTextNode } from '../custom-text/node' +import { REQUEST_URL_PLACEHOLDER_TEXT } from '../../../constants' +import { CustomTextNode } from '../../custom-text/node' import { getNodeCount, readRootTextContent, renderLexicalEditor, selectRootEnd, waitForEditorReady, -} from '../test-helpers' +} from '../../test-helpers' import { DELETE_REQUEST_URL_BLOCK_COMMAND, INSERT_REQUEST_URL_BLOCK_COMMAND, RequestURLBlock, RequestURLBlockNode, -} from './index' +} from '../index' const renderRequestURLBlock = (props: { onInsert?: () => void diff --git a/web/app/components/base/prompt-editor/plugins/request-url-block/node.spec.tsx b/web/app/components/base/prompt-editor/plugins/request-url-block/__tests__/node.spec.tsx similarity index 96% rename from web/app/components/base/prompt-editor/plugins/request-url-block/node.spec.tsx rename to web/app/components/base/prompt-editor/plugins/request-url-block/__tests__/node.spec.tsx index aa8a661512..fddbff4deb 100644 --- a/web/app/components/base/prompt-editor/plugins/request-url-block/node.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/request-url-block/__tests__/node.spec.tsx @@ -2,13 +2,13 @@ import { act } from '@testing-library/react' import { createLexicalTestEditor, expectInlineWrapperDom, -} from '../test-helpers' -import RequestURLBlockComponent from './component' +} from '../../test-helpers' +import RequestURLBlockComponent from '../component' import { $createRequestURLBlockNode, $isRequestURLBlockNode, RequestURLBlockNode, -} from './node' +} from '../node' describe('RequestURLBlockNode', () => { const createTestEditor = () => { diff --git a/web/app/components/base/prompt-editor/plugins/request-url-block/request-url-block-replacement-block.spec.tsx b/web/app/components/base/prompt-editor/plugins/request-url-block/__tests__/request-url-block-replacement-block.spec.tsx similarity index 90% rename from web/app/components/base/prompt-editor/plugins/request-url-block/request-url-block-replacement-block.spec.tsx rename to web/app/components/base/prompt-editor/plugins/request-url-block/__tests__/request-url-block-replacement-block.spec.tsx index 77c78d0e50..1df74ed4e6 100644 --- a/web/app/components/base/prompt-editor/plugins/request-url-block/request-url-block-replacement-block.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/request-url-block/__tests__/request-url-block-replacement-block.spec.tsx @@ -1,15 +1,15 @@ import { LexicalComposer } from '@lexical/react/LexicalComposer' import { render, waitFor } from '@testing-library/react' -import { REQUEST_URL_PLACEHOLDER_TEXT } from '../../constants' -import { CustomTextNode } from '../custom-text/node' +import { REQUEST_URL_PLACEHOLDER_TEXT } from '../../../constants' +import { CustomTextNode } from '../../custom-text/node' import { getNodeCount, renderLexicalEditor, setEditorRootText, waitForEditorReady, -} from '../test-helpers' -import { RequestURLBlockNode } from './index' -import RequestURLBlockReplacementBlock from './request-url-block-replacement-block' +} from '../../test-helpers' +import { RequestURLBlockNode } from '../index' +import RequestURLBlockReplacementBlock from '../request-url-block-replacement-block' const renderReplacementPlugin = (props: { onInsert?: () => void diff --git a/web/app/components/base/prompt-editor/plugins/shortcuts-popup-plugin/index.spec.tsx b/web/app/components/base/prompt-editor/plugins/shortcuts-popup-plugin/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/prompt-editor/plugins/shortcuts-popup-plugin/index.spec.tsx rename to web/app/components/base/prompt-editor/plugins/shortcuts-popup-plugin/__tests__/index.spec.tsx index ad44970187..6e636845a6 100644 --- a/web/app/components/base/prompt-editor/plugins/shortcuts-popup-plugin/index.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/shortcuts-popup-plugin/__tests__/index.spec.tsx @@ -5,7 +5,7 @@ import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin' import { fireEvent, render, screen, waitFor } from '@testing-library/react' import * as React from 'react' import { useState } from 'react' -import ShortcutsPopupPlugin, { SHORTCUTS_EMPTY_CONTENT } from './index' +import ShortcutsPopupPlugin, { SHORTCUTS_EMPTY_CONTENT } from '../index' import '@testing-library/jest-dom' // Mock Range.getClientRects and getBoundingClientRect for JSDOM diff --git a/web/app/components/base/prompt-editor/plugins/variable-block/index.spec.tsx b/web/app/components/base/prompt-editor/plugins/variable-block/__tests__/index.spec.tsx similarity index 95% rename from web/app/components/base/prompt-editor/plugins/variable-block/index.spec.tsx rename to web/app/components/base/prompt-editor/plugins/variable-block/__tests__/index.spec.tsx index f835ec07ef..f28dcab4ba 100644 --- a/web/app/components/base/prompt-editor/plugins/variable-block/index.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/variable-block/__tests__/index.spec.tsx @@ -1,15 +1,15 @@ import { act, waitFor } from '@testing-library/react' -import { CustomTextNode } from '../custom-text/node' +import { CustomTextNode } from '../../custom-text/node' import { readRootTextContent, renderLexicalEditor, selectRootEnd, waitForEditorReady, -} from '../test-helpers' +} from '../../test-helpers' import VariableBlock, { INSERT_VARIABLE_BLOCK_COMMAND, INSERT_VARIABLE_VALUE_BLOCK_COMMAND, -} from './index' +} from '../index' const renderVariableBlock = () => { return renderLexicalEditor({ diff --git a/web/app/components/base/prompt-editor/plugins/variable-value-block/index.spec.tsx b/web/app/components/base/prompt-editor/plugins/variable-value-block/__tests__/index.spec.tsx similarity index 94% rename from web/app/components/base/prompt-editor/plugins/variable-value-block/index.spec.tsx rename to web/app/components/base/prompt-editor/plugins/variable-value-block/__tests__/index.spec.tsx index 7398cad558..a77c62859b 100644 --- a/web/app/components/base/prompt-editor/plugins/variable-value-block/index.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/variable-value-block/__tests__/index.spec.tsx @@ -4,12 +4,12 @@ import type { LexicalEditor } from 'lexical' import type { ReactElement } from 'react' import { LexicalComposerContext } from '@lexical/react/LexicalComposerContext' import { render } from '@testing-library/react' -import { useLexicalTextEntity } from '../../hooks' -import VariableValueBlock from './index' -import { $createVariableValueBlockNode, VariableValueBlockNode } from './node' +import { useLexicalTextEntity } from '../../../hooks' +import VariableValueBlock from '../index' +import { $createVariableValueBlockNode, VariableValueBlockNode } from '../node' -vi.mock('../../hooks') -vi.mock('./node') +vi.mock('../../../hooks') +vi.mock('../node') const mockHasNodes = vi.fn() diff --git a/web/app/components/base/prompt-editor/plugins/variable-value-block/node.spec.tsx b/web/app/components/base/prompt-editor/plugins/variable-value-block/__tests__/node.spec.tsx similarity index 99% rename from web/app/components/base/prompt-editor/plugins/variable-value-block/node.spec.tsx rename to web/app/components/base/prompt-editor/plugins/variable-value-block/__tests__/node.spec.tsx index f78a76166d..a81b59d454 100644 --- a/web/app/components/base/prompt-editor/plugins/variable-value-block/node.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/variable-value-block/__tests__/node.spec.tsx @@ -4,7 +4,7 @@ import { $createVariableValueBlockNode, $isVariableValueNodeBlock, VariableValueBlockNode, -} from './node' +} from '../node' describe('VariableValueBlockNode', () => { let editor: LexicalEditor diff --git a/web/app/components/base/prompt-editor/plugins/workflow-variable-block/component.spec.tsx b/web/app/components/base/prompt-editor/plugins/workflow-variable-block/__tests__/component.spec.tsx similarity index 98% rename from web/app/components/base/prompt-editor/plugins/workflow-variable-block/component.spec.tsx rename to web/app/components/base/prompt-editor/plugins/workflow-variable-block/__tests__/component.spec.tsx index b07ed7de42..ff064f2a99 100644 --- a/web/app/components/base/prompt-editor/plugins/workflow-variable-block/component.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/workflow-variable-block/__tests__/component.spec.tsx @@ -7,10 +7,10 @@ import userEvent from '@testing-library/user-event' import { useReactFlow, useStoreApi } from 'reactflow' import { Type } from '@/app/components/workflow/nodes/llm/types' import { BlockEnum, VarType } from '@/app/components/workflow/types' -import { useSelectOrDelete } from '../../hooks' -import WorkflowVariableBlockComponent from './component' -import { UPDATE_WORKFLOW_NODES_MAP } from './index' -import { WorkflowVariableBlockNode } from './node' +import { useSelectOrDelete } from '../../../hooks' +import WorkflowVariableBlockComponent from '../component' +import { UPDATE_WORKFLOW_NODES_MAP } from '../index' +import { WorkflowVariableBlockNode } from '../node' const { mockVarLabel, mockIsExceptionVariable, mockForcedVariableKind } = vi.hoisted(() => ({ mockVarLabel: vi.fn(), @@ -21,7 +21,7 @@ const { mockVarLabel, mockIsExceptionVariable, mockForcedVariableKind } = vi.hoi vi.mock('@lexical/react/LexicalComposerContext') vi.mock('@lexical/utils') vi.mock('reactflow') -vi.mock('../../hooks') +vi.mock('../../../hooks') vi.mock('@/app/components/workflow/utils', async (importOriginal) => { const actual = await importOriginal() return { diff --git a/web/app/components/base/prompt-editor/plugins/workflow-variable-block/index.spec.tsx b/web/app/components/base/prompt-editor/plugins/workflow-variable-block/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/prompt-editor/plugins/workflow-variable-block/index.spec.tsx rename to web/app/components/base/prompt-editor/plugins/workflow-variable-block/__tests__/index.spec.tsx index d36f55bc47..ca4973b830 100644 --- a/web/app/components/base/prompt-editor/plugins/workflow-variable-block/index.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/workflow-variable-block/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import type { LexicalComposerContextWithEditor } from '@lexical/react/LexicalComposerContext' import type { LexicalEditor } from 'lexical' import type { ReactElement } from 'react' -import type { WorkflowNodesMap } from './node' +import type { WorkflowNodesMap } from '../node' import { LexicalComposerContext } from '@lexical/react/LexicalComposerContext' import { mergeRegister } from '@lexical/utils' import { render } from '@testing-library/react' @@ -15,8 +15,8 @@ import { UPDATE_WORKFLOW_NODES_MAP, WorkflowVariableBlock, WorkflowVariableBlockNode, -} from './index' -import { $createWorkflowVariableBlockNode } from './node' +} from '../index' +import { $createWorkflowVariableBlockNode } from '../node' vi.mock('@lexical/utils') vi.mock('lexical', async () => { @@ -28,7 +28,7 @@ vi.mock('lexical', async () => { COMMAND_PRIORITY_EDITOR: 1, } }) -vi.mock('./node') +vi.mock('../node') const mockHasNodes = vi.fn() const mockRegisterCommand = vi.fn() diff --git a/web/app/components/base/prompt-editor/plugins/workflow-variable-block/node.spec.tsx b/web/app/components/base/prompt-editor/plugins/workflow-variable-block/__tests__/node.spec.tsx similarity index 99% rename from web/app/components/base/prompt-editor/plugins/workflow-variable-block/node.spec.tsx rename to web/app/components/base/prompt-editor/plugins/workflow-variable-block/__tests__/node.spec.tsx index 6f894690ab..8d7a1cc33d 100644 --- a/web/app/components/base/prompt-editor/plugins/workflow-variable-block/node.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/workflow-variable-block/__tests__/node.spec.tsx @@ -7,7 +7,7 @@ import { $createWorkflowVariableBlockNode, $isWorkflowVariableBlockNode, WorkflowVariableBlockNode, -} from './node' +} from '../node' describe('WorkflowVariableBlockNode', () => { let editor: LexicalEditor diff --git a/web/app/components/base/prompt-editor/plugins/workflow-variable-block/workflow-variable-block-replacement-block.spec.tsx b/web/app/components/base/prompt-editor/plugins/workflow-variable-block/__tests__/workflow-variable-block-replacement-block.spec.tsx similarity index 94% rename from web/app/components/base/prompt-editor/plugins/workflow-variable-block/workflow-variable-block-replacement-block.spec.tsx rename to web/app/components/base/prompt-editor/plugins/workflow-variable-block/__tests__/workflow-variable-block-replacement-block.spec.tsx index 71ef39d02c..b9cb1faa37 100644 --- a/web/app/components/base/prompt-editor/plugins/workflow-variable-block/workflow-variable-block-replacement-block.spec.tsx +++ b/web/app/components/base/prompt-editor/plugins/workflow-variable-block/__tests__/workflow-variable-block-replacement-block.spec.tsx @@ -2,7 +2,7 @@ import type { LexicalComposerContextWithEditor } from '@lexical/react/LexicalCom import type { EntityMatch } from '@lexical/text' import type { LexicalEditor, LexicalNode } from 'lexical' import type { ReactElement } from 'react' -import type { WorkflowNodesMap } from './node' +import type { WorkflowNodesMap } from '../node' import type { NodeOutPutVar } from '@/app/components/workflow/types' import { LexicalComposerContext } from '@lexical/react/LexicalComposerContext' import { mergeRegister } from '@lexical/utils' @@ -10,16 +10,16 @@ import { render } from '@testing-library/react' import { $applyNodeReplacement } from 'lexical' import { Type } from '@/app/components/workflow/nodes/llm/types' import { BlockEnum, VarType } from '@/app/components/workflow/types' -import { decoratorTransform } from '../../utils' -import { CustomTextNode } from '../custom-text/node' -import { WorkflowVariableBlockNode } from './index' -import { $createWorkflowVariableBlockNode } from './node' -import WorkflowVariableBlockReplacementBlock from './workflow-variable-block-replacement-block' +import { decoratorTransform } from '../../../utils' +import { CustomTextNode } from '../../custom-text/node' +import { WorkflowVariableBlockNode } from '../index' +import { $createWorkflowVariableBlockNode } from '../node' +import WorkflowVariableBlockReplacementBlock from '../workflow-variable-block-replacement-block' vi.mock('@lexical/utils') vi.mock('lexical') -vi.mock('../../utils') -vi.mock('./node') +vi.mock('../../../utils') +vi.mock('../node') const mockHasNodes = vi.fn() const mockRegisterNodeTransform = vi.fn() diff --git a/web/app/components/base/prompt-log-modal/card.spec.tsx b/web/app/components/base/prompt-log-modal/__tests__/card.spec.tsx similarity index 96% rename from web/app/components/base/prompt-log-modal/card.spec.tsx rename to web/app/components/base/prompt-log-modal/__tests__/card.spec.tsx index 500e9db941..3b312343d9 100644 --- a/web/app/components/base/prompt-log-modal/card.spec.tsx +++ b/web/app/components/base/prompt-log-modal/__tests__/card.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import Card from './card' +import Card from '../card' describe('PromptLogModal Card', () => { it('renders single log entry correctly', () => { diff --git a/web/app/components/base/prompt-log-modal/index.spec.tsx b/web/app/components/base/prompt-log-modal/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/prompt-log-modal/index.spec.tsx rename to web/app/components/base/prompt-log-modal/__tests__/index.spec.tsx index c04e668026..05c1e5d093 100644 --- a/web/app/components/base/prompt-log-modal/index.spec.tsx +++ b/web/app/components/base/prompt-log-modal/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import PromptLogModal from '.' +import PromptLogModal from '..' describe('PromptLogModal', () => { const defaultProps = { diff --git a/web/app/components/base/qrcode/index.spec.tsx b/web/app/components/base/qrcode/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/qrcode/index.spec.tsx rename to web/app/components/base/qrcode/__tests__/index.spec.tsx index 3e1d5ff6d9..fbad4163c4 100644 --- a/web/app/components/base/qrcode/index.spec.tsx +++ b/web/app/components/base/qrcode/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { downloadUrl } from '@/utils/download' -import ShareQRCode from '.' +import ShareQRCode from '..' vi.mock('@/utils/download', () => ({ downloadUrl: vi.fn(), diff --git a/web/app/components/base/radio-card/index.spec.tsx b/web/app/components/base/radio-card/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/radio-card/index.spec.tsx rename to web/app/components/base/radio-card/__tests__/index.spec.tsx index f1368476bf..f4bc7a5b0e 100644 --- a/web/app/components/base/radio-card/index.spec.tsx +++ b/web/app/components/base/radio-card/__tests__/index.spec.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' // index.spec.tsx import { describe, expect, it, vi } from 'vitest' -import RadioCard from './index' +import RadioCard from '../index' describe('RadioCard', () => { it('renders icon, title and description', () => { diff --git a/web/app/components/base/radio-card/simple/index.spec.tsx b/web/app/components/base/radio-card/simple/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/radio-card/simple/index.spec.tsx rename to web/app/components/base/radio-card/simple/__tests__/index.spec.tsx index 42e03484e8..d04cefe61a 100644 --- a/web/app/components/base/radio-card/simple/index.spec.tsx +++ b/web/app/components/base/radio-card/simple/__tests__/index.spec.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' // index.spec.tsx import { describe, expect, it, vi } from 'vitest' -import RadioCard from './index' +import RadioCard from '../index' describe('RadioCard', () => { it('renders title and description', () => { diff --git a/web/app/components/base/radio/index.spec.tsx b/web/app/components/base/radio/__tests__/index.spec.tsx similarity index 95% rename from web/app/components/base/radio/index.spec.tsx rename to web/app/components/base/radio/__tests__/index.spec.tsx index 838a0eb0ef..6a81648400 100644 --- a/web/app/components/base/radio/index.spec.tsx +++ b/web/app/components/base/radio/__tests__/index.spec.tsx @@ -2,8 +2,8 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' // index.spec.tsx import { describe, expect, it, vi } from 'vitest' -import Group from './component/group' -import Radio from './index' +import Group from '../component/group' +import Radio from '../index' describe('Radio (index)', () => { it('attaches Group as a property on the default export', () => { diff --git a/web/app/components/base/radio/ui.spec.tsx b/web/app/components/base/radio/__tests__/ui.spec.tsx similarity index 98% rename from web/app/components/base/radio/ui.spec.tsx rename to web/app/components/base/radio/__tests__/ui.spec.tsx index 7dec5f3660..cb8d18e0b8 100644 --- a/web/app/components/base/radio/ui.spec.tsx +++ b/web/app/components/base/radio/__tests__/ui.spec.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' // radio-ui.spec.tsx import { describe, expect, it, vi } from 'vitest' -import RadioUI from './ui' +import RadioUI from '../ui' describe('RadioUI component', () => { it('renders with correct role and aria attributes', () => { diff --git a/web/app/components/base/radio/component/group/index.spec.tsx b/web/app/components/base/radio/component/group/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/radio/component/group/index.spec.tsx rename to web/app/components/base/radio/component/group/__tests__/index.spec.tsx index e417c2a203..32ca0f2d86 100644 --- a/web/app/components/base/radio/component/group/index.spec.tsx +++ b/web/app/components/base/radio/component/group/__tests__/index.spec.tsx @@ -3,8 +3,8 @@ import userEvent from '@testing-library/user-event' import { useContextSelector } from 'use-context-selector' // Group.test.tsx import { describe, expect, it, vi } from 'vitest' -import RadioGroupContext from '../../context' -import Group from './index' +import RadioGroupContext from '../../../context' +import Group from '../index' // small consumer that uses the same context as your component function ContextConsumer({ showButton = true }: { showButton?: boolean }) { diff --git a/web/app/components/base/radio/component/radio/index.spec.tsx b/web/app/components/base/radio/component/radio/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/radio/component/radio/index.spec.tsx rename to web/app/components/base/radio/component/radio/__tests__/index.spec.tsx index cdf0587453..bab5d64e38 100644 --- a/web/app/components/base/radio/component/radio/index.spec.tsx +++ b/web/app/components/base/radio/component/radio/__tests__/index.spec.tsx @@ -2,8 +2,8 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' // index.spec.tsx import { describe, expect, it, vi } from 'vitest' -import RadioGroupContext from '../../context' -import Radio from './index' +import RadioGroupContext from '../../../context' +import Radio from '../index' describe('Radio component', () => { it('renders label children and assigns an id to the label', () => { diff --git a/web/app/components/base/radio/context/index.spec.tsx b/web/app/components/base/radio/context/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/radio/context/index.spec.tsx rename to web/app/components/base/radio/context/__tests__/index.spec.tsx index 105bbbed3c..17b40c58e8 100644 --- a/web/app/components/base/radio/context/index.spec.tsx +++ b/web/app/components/base/radio/context/__tests__/index.spec.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react' import { useContextSelector } from 'use-context-selector' // context.spec.tsx import { describe, expect, it } from 'vitest' -import RadioGroupContext from './index' +import RadioGroupContext from '../index' function Consumer() { const value = useContextSelector(RadioGroupContext, v => v) diff --git a/web/app/components/base/search-input/index.spec.tsx b/web/app/components/base/search-input/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/search-input/index.spec.tsx rename to web/app/components/base/search-input/__tests__/index.spec.tsx index db70087d85..44c13b9d48 100644 --- a/web/app/components/base/search-input/index.spec.tsx +++ b/web/app/components/base/search-input/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import SearchInput from '.' +import SearchInput from '..' describe('SearchInput', () => { describe('Render', () => { diff --git a/web/app/components/base/segmented-control/index.spec.tsx b/web/app/components/base/segmented-control/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/segmented-control/index.spec.tsx rename to web/app/components/base/segmented-control/__tests__/index.spec.tsx index d83ec58757..f92d5b29b0 100644 --- a/web/app/components/base/segmented-control/index.spec.tsx +++ b/web/app/components/base/segmented-control/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import SegmentedControl from './index' +import SegmentedControl from '../index' describe('SegmentedControl', () => { const options = [ diff --git a/web/app/components/base/select/custom.spec.tsx b/web/app/components/base/select/__tests__/custom.spec.tsx similarity index 98% rename from web/app/components/base/select/custom.spec.tsx rename to web/app/components/base/select/__tests__/custom.spec.tsx index 994045610c..8868d70fc4 100644 --- a/web/app/components/base/select/custom.spec.tsx +++ b/web/app/components/base/select/__tests__/custom.spec.tsx @@ -1,7 +1,7 @@ -import type { Option } from './custom' +import type { Option } from '../custom' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import CustomSelect from './custom' +import CustomSelect from '../custom' const options: Option[] = [ { label: 'First option', value: 'first' }, diff --git a/web/app/components/base/select/index.spec.tsx b/web/app/components/base/select/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/select/index.spec.tsx rename to web/app/components/base/select/__tests__/index.spec.tsx index b30381942b..b3e518eaf1 100644 --- a/web/app/components/base/select/index.spec.tsx +++ b/web/app/components/base/select/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ -import type { Item } from './index' +import type { Item } from '../index' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import Select, { PortalSelect, SimpleSelect } from './index' +import Select, { PortalSelect, SimpleSelect } from '../index' const items: Item[] = [ { value: 'apple', name: 'Apple' }, diff --git a/web/app/components/base/select/locale-signin.spec.tsx b/web/app/components/base/select/__tests__/locale-signin.spec.tsx similarity index 98% rename from web/app/components/base/select/locale-signin.spec.tsx rename to web/app/components/base/select/__tests__/locale-signin.spec.tsx index ec08de30b6..1eca2b1aed 100644 --- a/web/app/components/base/select/locale-signin.spec.tsx +++ b/web/app/components/base/select/__tests__/locale-signin.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import LocaleSigninSelect from './locale-signin' +import LocaleSigninSelect from '../locale-signin' const localeItems = [ { value: 'en-US', name: 'English (US)' }, diff --git a/web/app/components/base/select/locale.spec.tsx b/web/app/components/base/select/__tests__/locale.spec.tsx similarity index 98% rename from web/app/components/base/select/locale.spec.tsx rename to web/app/components/base/select/__tests__/locale.spec.tsx index 10e32ff9f7..2c1c83bf95 100644 --- a/web/app/components/base/select/locale.spec.tsx +++ b/web/app/components/base/select/__tests__/locale.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import LocaleSelect from './locale' +import LocaleSelect from '../locale' const localeItems = [ { value: 'en-US', name: 'English (US)' }, diff --git a/web/app/components/base/select/pure.spec.tsx b/web/app/components/base/select/__tests__/pure.spec.tsx similarity index 98% rename from web/app/components/base/select/pure.spec.tsx rename to web/app/components/base/select/__tests__/pure.spec.tsx index fb7fc3ab07..885ee99c52 100644 --- a/web/app/components/base/select/pure.spec.tsx +++ b/web/app/components/base/select/__tests__/pure.spec.tsx @@ -1,7 +1,7 @@ -import type { Option } from './pure' +import type { Option } from '../pure' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import PureSelect from './pure' +import PureSelect from '../pure' const options: Option[] = [ { label: 'Apple', value: 'apple' }, diff --git a/web/app/components/base/simple-pie-chart/index.spec.tsx b/web/app/components/base/simple-pie-chart/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/simple-pie-chart/index.spec.tsx rename to web/app/components/base/simple-pie-chart/__tests__/index.spec.tsx index f1403ffe20..2f511e8392 100644 --- a/web/app/components/base/simple-pie-chart/index.spec.tsx +++ b/web/app/components/base/simple-pie-chart/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { render } from '@testing-library/react' -import SimplePieChart from '.' +import SimplePieChart from '..' describe('SimplePieChart', () => { describe('Rendering', () => { diff --git a/web/app/components/base/skeleton/index.spec.tsx b/web/app/components/base/skeleton/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/skeleton/index.spec.tsx rename to web/app/components/base/skeleton/__tests__/index.spec.tsx index 8f0d9a6837..00852f7031 100644 --- a/web/app/components/base/skeleton/index.spec.tsx +++ b/web/app/components/base/skeleton/__tests__/index.spec.tsx @@ -6,7 +6,7 @@ import { SkeletonPoint, SkeletonRectangle, SkeletonRow, -} from './index' +} from '../index' describe('Skeleton Components', () => { describe('Individual Components', () => { diff --git a/web/app/components/base/slider/index.spec.tsx b/web/app/components/base/slider/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/slider/index.spec.tsx rename to web/app/components/base/slider/__tests__/index.spec.tsx index c9ebabd63e..bb1f030689 100644 --- a/web/app/components/base/slider/index.spec.tsx +++ b/web/app/components/base/slider/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { act, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import Slider from './index' +import Slider from '../index' describe('Slider Component', () => { it('should render with correct default ARIA limits and current value', () => { diff --git a/web/app/components/base/sort/index.spec.tsx b/web/app/components/base/sort/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/sort/index.spec.tsx rename to web/app/components/base/sort/__tests__/index.spec.tsx index 92ea2b44f9..e51ec23805 100644 --- a/web/app/components/base/sort/index.spec.tsx +++ b/web/app/components/base/sort/__tests__/index.spec.tsx @@ -2,7 +2,7 @@ import { render, screen, waitFor, within } from '@testing-library/react' import userEvent from '@testing-library/user-event' import * as React from 'react' import { describe, expect, it, vi } from 'vitest' -import Sort from './index' +import Sort from '../index' const mockItems = [ { value: 'created_at', name: 'Date Created' }, diff --git a/web/app/components/base/spinner/index.spec.tsx b/web/app/components/base/spinner/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/spinner/index.spec.tsx rename to web/app/components/base/spinner/__tests__/index.spec.tsx index 652d061206..50cf2d3b04 100644 --- a/web/app/components/base/spinner/index.spec.tsx +++ b/web/app/components/base/spinner/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { render } from '@testing-library/react' import * as React from 'react' -import Spinner from './index' +import Spinner from '../index' describe('Spinner component', () => { it('should render correctly when loading is true', () => { diff --git a/web/app/components/base/svg-gallery/index.spec.tsx b/web/app/components/base/svg-gallery/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/svg-gallery/index.spec.tsx rename to web/app/components/base/svg-gallery/__tests__/index.spec.tsx index 01994f0a16..c990f0211f 100644 --- a/web/app/components/base/svg-gallery/index.spec.tsx +++ b/web/app/components/base/svg-gallery/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { act, fireEvent, render, screen, waitFor } from '@testing-library/react' -import SVGRenderer from '.' +import SVGRenderer from '..' const mockClick = vi.fn() const mockSvg = vi.fn().mockReturnValue({ diff --git a/web/app/components/base/svg/index.spec.tsx b/web/app/components/base/svg/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/svg/index.spec.tsx rename to web/app/components/base/svg/__tests__/index.spec.tsx index fd05af0e70..88d5969729 100644 --- a/web/app/components/base/svg/index.spec.tsx +++ b/web/app/components/base/svg/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/react' -import SVGBtn from '.' +import SVGBtn from '..' describe('SVGBtn', () => { describe('Rendering', () => { diff --git a/web/app/components/base/switch/index.spec.tsx b/web/app/components/base/switch/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/switch/index.spec.tsx rename to web/app/components/base/switch/__tests__/index.spec.tsx index d4788939c6..127efc987f 100644 --- a/web/app/components/base/switch/index.spec.tsx +++ b/web/app/components/base/switch/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import Switch from './index' +import Switch from '../index' describe('Switch', () => { it('should render in unchecked state when value is false', () => { diff --git a/web/app/components/base/tab-header/index.spec.tsx b/web/app/components/base/tab-header/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/tab-header/index.spec.tsx rename to web/app/components/base/tab-header/__tests__/index.spec.tsx index df0a827e57..ee10415154 100644 --- a/web/app/components/base/tab-header/index.spec.tsx +++ b/web/app/components/base/tab-header/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { render, screen, within } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import TabHeader from './index' +import TabHeader from '../index' describe('TabHeader Component', () => { const mockItems = [ diff --git a/web/app/components/base/tab-slider-new/index.spec.tsx b/web/app/components/base/tab-slider-new/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/tab-slider-new/index.spec.tsx rename to web/app/components/base/tab-slider-new/__tests__/index.spec.tsx index d47afb2aed..a8772093c3 100644 --- a/web/app/components/base/tab-slider-new/index.spec.tsx +++ b/web/app/components/base/tab-slider-new/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import TabSliderNew from './index' +import TabSliderNew from '../index' describe('TabSliderNew Component', () => { const mockOptions = [ diff --git a/web/app/components/base/tab-slider-plain/index.spec.tsx b/web/app/components/base/tab-slider-plain/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/tab-slider-plain/index.spec.tsx rename to web/app/components/base/tab-slider-plain/__tests__/index.spec.tsx index 40c5b8c329..898ff99ce9 100644 --- a/web/app/components/base/tab-slider-plain/index.spec.tsx +++ b/web/app/components/base/tab-slider-plain/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { render, screen, within } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import TabSlider from './index' +import TabSlider from '../index' describe('TabSlider Component', () => { const mockOptions = [ diff --git a/web/app/components/base/tab-slider/index.spec.tsx b/web/app/components/base/tab-slider/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/tab-slider/index.spec.tsx rename to web/app/components/base/tab-slider/__tests__/index.spec.tsx index 373c984d59..51794a7087 100644 --- a/web/app/components/base/tab-slider/index.spec.tsx +++ b/web/app/components/base/tab-slider/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { cleanup, fireEvent, render, screen } from '@testing-library/react' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { useInstalledPluginList } from '@/service/use-plugins' -import TabSlider from './index' +import TabSlider from '../index' // Mock the service hook vi.mock('@/service/use-plugins', () => ({ diff --git a/web/app/components/base/tag-input/index.spec.tsx b/web/app/components/base/tag-input/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/tag-input/index.spec.tsx rename to web/app/components/base/tag-input/__tests__/index.spec.tsx index 077f938570..b091d9cd03 100644 --- a/web/app/components/base/tag-input/index.spec.tsx +++ b/web/app/components/base/tag-input/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react' import { createEvent, fireEvent, render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import TagInput from './index' +import TagInput from '../index' const mockNotify = vi.fn() diff --git a/web/app/components/base/tag-management/filter.spec.tsx b/web/app/components/base/tag-management/__tests__/filter.spec.tsx similarity index 99% rename from web/app/components/base/tag-management/filter.spec.tsx rename to web/app/components/base/tag-management/__tests__/filter.spec.tsx index 0f5b4d9ac6..3cffac29b2 100644 --- a/web/app/components/base/tag-management/filter.spec.tsx +++ b/web/app/components/base/tag-management/__tests__/filter.spec.tsx @@ -3,8 +3,8 @@ import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { act } from 'react' import * as React from 'react' -import TagFilter from './filter' -import { useStore as useTagStore } from './store' +import TagFilter from '../filter' +import { useStore as useTagStore } from '../store' const { fetchTagList } = vi.hoisted(() => ({ fetchTagList: vi.fn(), diff --git a/web/app/components/base/tag-management/index.spec.tsx b/web/app/components/base/tag-management/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/tag-management/index.spec.tsx rename to web/app/components/base/tag-management/__tests__/index.spec.tsx index 846c23484b..5e01aeaf19 100644 --- a/web/app/components/base/tag-management/index.spec.tsx +++ b/web/app/components/base/tag-management/__tests__/index.spec.tsx @@ -3,8 +3,8 @@ import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import * as React from 'react' import { act } from 'react' -import TagManagementModal from './index' -import { useStore as useTagStore } from './store' +import TagManagementModal from '../index' +import { useStore as useTagStore } from '../store' // Hoisted mocks const { fetchTagList, createTag } = vi.hoisted(() => ({ diff --git a/web/app/components/base/tag-management/panel.spec.tsx b/web/app/components/base/tag-management/__tests__/panel.spec.tsx similarity index 99% rename from web/app/components/base/tag-management/panel.spec.tsx rename to web/app/components/base/tag-management/__tests__/panel.spec.tsx index d3b3279c12..c91c72e583 100644 --- a/web/app/components/base/tag-management/panel.spec.tsx +++ b/web/app/components/base/tag-management/__tests__/panel.spec.tsx @@ -4,8 +4,8 @@ import userEvent from '@testing-library/user-event' import * as React from 'react' import { act } from 'react' import { ToastContext } from '@/app/components/base/toast' -import Panel from './panel' -import { useStore as useTagStore } from './store' +import Panel from '../panel' +import { useStore as useTagStore } from '../store' // Hoisted mocks const { createTag, bindTag, unBindTag, contextOverrides } = vi.hoisted(() => ({ diff --git a/web/app/components/base/tag-management/selector.spec.tsx b/web/app/components/base/tag-management/__tests__/selector.spec.tsx similarity index 98% rename from web/app/components/base/tag-management/selector.spec.tsx rename to web/app/components/base/tag-management/__tests__/selector.spec.tsx index 6c66c83703..dc58ca37e6 100644 --- a/web/app/components/base/tag-management/selector.spec.tsx +++ b/web/app/components/base/tag-management/__tests__/selector.spec.tsx @@ -4,8 +4,8 @@ import userEvent from '@testing-library/user-event' import * as React from 'react' import { act } from 'react' import { ToastContext } from '@/app/components/base/toast' -import TagSelector from './selector' -import { useStore as useTagStore } from './store' +import TagSelector from '../selector' +import { useStore as useTagStore } from '../store' // Hoisted mocks const { fetchTagList, createTag, bindTag, unBindTag } = vi.hoisted(() => ({ @@ -43,6 +43,7 @@ vi.mock('@/app/components/base/popover', () => { : btnClassName const content = React.isValidElement(htmlContent) + // eslint-disable-next-line react/no-clone-element ? React.cloneElement(htmlContent as React.ReactElement, { open: isOpen, onClose: () => setIsOpen(false), diff --git a/web/app/components/base/tag-management/tag-item-editor.spec.tsx b/web/app/components/base/tag-management/__tests__/tag-item-editor.spec.tsx similarity index 98% rename from web/app/components/base/tag-management/tag-item-editor.spec.tsx rename to web/app/components/base/tag-management/__tests__/tag-item-editor.spec.tsx index 5dfd90f283..3043f0327f 100644 --- a/web/app/components/base/tag-management/tag-item-editor.spec.tsx +++ b/web/app/components/base/tag-management/__tests__/tag-item-editor.spec.tsx @@ -3,8 +3,8 @@ import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import * as React from 'react' import { act } from 'react' -import { useStore as useTagStore } from './store' -import TagItemEditor from './tag-item-editor' +import { useStore as useTagStore } from '../store' +import TagItemEditor from '../tag-item-editor' const { updateTag, deleteTag, mockNotify } = vi.hoisted(() => ({ updateTag: vi.fn(), diff --git a/web/app/components/base/tag-management/tag-remove-modal.spec.tsx b/web/app/components/base/tag-management/__tests__/tag-remove-modal.spec.tsx similarity index 97% rename from web/app/components/base/tag-management/tag-remove-modal.spec.tsx rename to web/app/components/base/tag-management/__tests__/tag-remove-modal.spec.tsx index 65e4879739..943b7bc8ff 100644 --- a/web/app/components/base/tag-management/tag-remove-modal.spec.tsx +++ b/web/app/components/base/tag-management/__tests__/tag-remove-modal.spec.tsx @@ -1,7 +1,7 @@ -import type { Tag } from './constant' +import type { Tag } from '../constant' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import TagRemoveModal from './tag-remove-modal' +import TagRemoveModal from '../tag-remove-modal' const mockTag: Tag = { id: 'tag-1', diff --git a/web/app/components/base/tag-management/trigger.spec.tsx b/web/app/components/base/tag-management/__tests__/trigger.spec.tsx similarity index 98% rename from web/app/components/base/tag-management/trigger.spec.tsx rename to web/app/components/base/tag-management/__tests__/trigger.spec.tsx index d7787c503a..e188c4fed9 100644 --- a/web/app/components/base/tag-management/trigger.spec.tsx +++ b/web/app/components/base/tag-management/__tests__/trigger.spec.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react' -import Trigger from './trigger' +import Trigger from '../trigger' describe('Trigger', () => { beforeEach(() => { diff --git a/web/app/components/base/tag/index.spec.tsx b/web/app/components/base/tag/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/tag/index.spec.tsx rename to web/app/components/base/tag/__tests__/index.spec.tsx index 76d2915ba8..5fafa568b3 100644 --- a/web/app/components/base/tag/index.spec.tsx +++ b/web/app/components/base/tag/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import { describe, expect, it } from 'vitest' -import Tag from './index' +import Tag from '../index' import '@testing-library/jest-dom/vitest' describe('Tag Component', () => { diff --git a/web/app/components/base/text-generation/hooks.spec.ts b/web/app/components/base/text-generation/__tests__/hooks.spec.ts similarity index 99% rename from web/app/components/base/text-generation/hooks.spec.ts rename to web/app/components/base/text-generation/__tests__/hooks.spec.ts index f25dd3b945..cab06f1c8a 100644 --- a/web/app/components/base/text-generation/hooks.spec.ts +++ b/web/app/components/base/text-generation/__tests__/hooks.spec.ts @@ -1,6 +1,6 @@ import type { IOtherOptions } from '@/service/base' import { act, renderHook } from '@testing-library/react' -import { useTextGeneration } from './hooks' +import { useTextGeneration } from '../hooks' const mockNotify = vi.fn() const mockSsePost = vi.fn<(url: string, fetchOptions: { body: Record }, otherOptions: IOtherOptions) => void>() diff --git a/web/app/components/base/textarea/index.spec.tsx b/web/app/components/base/textarea/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/textarea/index.spec.tsx rename to web/app/components/base/textarea/__tests__/index.spec.tsx index 404785d2e4..7de2d7e0f9 100644 --- a/web/app/components/base/textarea/index.spec.tsx +++ b/web/app/components/base/textarea/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import TextArea from './index' +import TextArea from '../index' describe('TextArea', () => { it('should render correctly with default props', () => { diff --git a/web/app/components/base/timezone-label/index.spec.tsx b/web/app/components/base/timezone-label/__tests__/index.spec.tsx similarity index 97% rename from web/app/components/base/timezone-label/index.spec.tsx rename to web/app/components/base/timezone-label/__tests__/index.spec.tsx index c43aa61936..4beb72d165 100644 --- a/web/app/components/base/timezone-label/index.spec.tsx +++ b/web/app/components/base/timezone-label/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import { describe, expect, it } from 'vitest' -import TimezoneLabel from './index' +import TimezoneLabel from '../index' describe('TimezoneLabel', () => { it('should render correctly with various timezones', () => { diff --git a/web/app/components/base/toast/index.spec.tsx b/web/app/components/base/toast/__tests__/index.spec.tsx similarity index 98% rename from web/app/components/base/toast/index.spec.tsx rename to web/app/components/base/toast/__tests__/index.spec.tsx index cc5a1e7c6d..f526290fa1 100644 --- a/web/app/components/base/toast/index.spec.tsx +++ b/web/app/components/base/toast/__tests__/index.spec.tsx @@ -2,7 +2,7 @@ import type { ReactNode } from 'react' import { act, render, screen, waitFor } from '@testing-library/react' import { noop } from 'es-toolkit/function' import * as React from 'react' -import Toast, { ToastProvider, useToastContext } from '.' +import Toast, { ToastProvider, useToastContext } from '..' const TestComponent = () => { const { notify, close } = useToastContext() diff --git a/web/app/components/base/tooltip/content.spec.tsx b/web/app/components/base/tooltip/__tests__/content.spec.tsx similarity index 97% rename from web/app/components/base/tooltip/content.spec.tsx rename to web/app/components/base/tooltip/__tests__/content.spec.tsx index 314c773ce1..fa5d86756e 100644 --- a/web/app/components/base/tooltip/content.spec.tsx +++ b/web/app/components/base/tooltip/__tests__/content.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' -import { ToolTipContent } from './content' +import { ToolTipContent } from '../content' describe('ToolTipContent', () => { it('should render children correctly', () => { diff --git a/web/app/components/base/tooltip/index.spec.tsx b/web/app/components/base/tooltip/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/tooltip/index.spec.tsx rename to web/app/components/base/tooltip/__tests__/index.spec.tsx index 66d3157ddc..7ee31b59c7 100644 --- a/web/app/components/base/tooltip/index.spec.tsx +++ b/web/app/components/base/tooltip/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { act, cleanup, fireEvent, render, screen } from '@testing-library/react' import * as React from 'react' -import Tooltip from './index' +import Tooltip from '../index' afterEach(cleanup) diff --git a/web/app/components/base/video-gallery/VideoPlayer.spec.tsx b/web/app/components/base/video-gallery/__tests__/VideoPlayer.spec.tsx similarity index 99% rename from web/app/components/base/video-gallery/VideoPlayer.spec.tsx rename to web/app/components/base/video-gallery/__tests__/VideoPlayer.spec.tsx index 04d9ccc4c8..3e1890c573 100644 --- a/web/app/components/base/video-gallery/VideoPlayer.spec.tsx +++ b/web/app/components/base/video-gallery/__tests__/VideoPlayer.spec.tsx @@ -1,7 +1,7 @@ import { act, fireEvent, render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { beforeEach, describe, expect, it, vi } from 'vitest' -import VideoPlayer from './VideoPlayer' +import VideoPlayer from '../VideoPlayer' describe('VideoPlayer', () => { const mockSrc = 'video.mp4' diff --git a/web/app/components/base/video-gallery/index.spec.tsx b/web/app/components/base/video-gallery/__tests__/index.spec.tsx similarity index 95% rename from web/app/components/base/video-gallery/index.spec.tsx rename to web/app/components/base/video-gallery/__tests__/index.spec.tsx index 717e57e1ff..d32f627c2c 100644 --- a/web/app/components/base/video-gallery/index.spec.tsx +++ b/web/app/components/base/video-gallery/__tests__/index.spec.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react' import { describe, expect, it } from 'vitest' -import VideoGallery from './index' +import VideoGallery from '../index' describe('VideoGallery', () => { const mockSrcs = ['video1.mp4', 'video2.mp4'] diff --git a/web/app/components/base/voice-input/index.spec.tsx b/web/app/components/base/voice-input/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/voice-input/index.spec.tsx rename to web/app/components/base/voice-input/__tests__/index.spec.tsx index fa32f0425f..8d7940fb08 100644 --- a/web/app/components/base/voice-input/index.spec.tsx +++ b/web/app/components/base/voice-input/__tests__/index.spec.tsx @@ -2,7 +2,7 @@ import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { beforeEach, describe, expect, it, vi } from 'vitest' import { audioToText } from '@/service/share' -import VoiceInput from './index' +import VoiceInput from '../index' const { mockState, MockRecorder } = vi.hoisted(() => { const state = { @@ -50,7 +50,7 @@ vi.mock('next/navigation', () => ({ usePathname: vi.fn(() => mockState.pathname), })) -vi.mock('./utils', () => ({ +vi.mock('../utils', () => ({ convertToMp3: vi.fn(() => new Blob(['test'], { type: 'audio/mp3' })), })) diff --git a/web/app/components/base/with-input-validation/index.spec.tsx b/web/app/components/base/with-input-validation/__tests__/index.spec.tsx similarity index 85% rename from web/app/components/base/with-input-validation/index.spec.tsx rename to web/app/components/base/with-input-validation/__tests__/index.spec.tsx index 3bfcbfc9e4..6c3337ba00 100644 --- a/web/app/components/base/with-input-validation/index.spec.tsx +++ b/web/app/components/base/with-input-validation/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import { noop } from 'es-toolkit/function' import * as z from 'zod' -import withValidation from '.' +import withValidation from '..' describe('withValidation HOC', () => { // schema for validation @@ -35,12 +35,12 @@ describe('withValidation HOC', () => { }) it('renders the component when props is invalid but not in schema ', () => { - render() + render() expect(screen.getByText('Valid Name - aaa')).toBeInTheDocument() }) it('does not render the component when validation fails', () => { - render() + render() expect(screen.queryByText('123 - 30')).toBeNull() }) }) diff --git a/web/app/components/base/zendesk/index.spec.tsx b/web/app/components/base/zendesk/__tests__/index.spec.tsx similarity index 99% rename from web/app/components/base/zendesk/index.spec.tsx rename to web/app/components/base/zendesk/__tests__/index.spec.tsx index abf0210f37..4ab84a0088 100644 --- a/web/app/components/base/zendesk/index.spec.tsx +++ b/web/app/components/base/zendesk/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import type { ReactNode } from 'react' import { render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' -import Zendesk from './index' +import Zendesk from '../index' // Shared state for mocks let mockIsCeEdition = false diff --git a/web/app/layout.tsx b/web/app/layout.tsx index a19d5e1e57..64f0e5ac3b 100644 --- a/web/app/layout.tsx +++ b/web/app/layout.tsx @@ -57,38 +57,40 @@ const LocaleLayout = async ({ - - - - - - - - - - - - {children} - - - - - - - - - - - +
+ + + + + + + + + + + + {children} + + + + + + + + + + + +
) diff --git a/web/docker/entrypoint.sh b/web/docker/entrypoint.sh index 7e1aca680b..034ed96491 100755 --- a/web/docker/entrypoint.sh +++ b/web/docker/entrypoint.sh @@ -43,4 +43,4 @@ export NEXT_PUBLIC_MAX_PARALLEL_LIMIT=${MAX_PARALLEL_LIMIT} export NEXT_PUBLIC_MAX_ITERATIONS_NUM=${MAX_ITERATIONS_NUM} export NEXT_PUBLIC_MAX_TREE_DEPTH=${MAX_TREE_DEPTH} -pm2 start /app/web/server.js --name dify-web --cwd /app/web -i ${PM2_INSTANCES} --no-daemon +exec node /app/web/server.js diff --git a/web/docker/pm2.json b/web/docker/pm2.json deleted file mode 100644 index 85e5171203..0000000000 --- a/web/docker/pm2.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "apps": [ - { - "name": "dify-web", - "script": "/app/web/server.js", - "cwd": "/app/web", - "exec_mode": "cluster", - "instances": 2 - } - ] -} diff --git a/web/vite.config.ts b/web/vite.config.ts index 676173e3de..1fdef49d0c 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -1,15 +1,78 @@ import type { Plugin } from 'vite' +import fs from 'node:fs' import path from 'node:path' import { fileURLToPath } from 'node:url' import react from '@vitejs/plugin-react' +import { codeInspectorPlugin } from 'code-inspector-plugin' import vinext from 'vinext' import { defineConfig } from 'vite' import tsconfigPaths from 'vite-tsconfig-paths' const __dirname = path.dirname(fileURLToPath(import.meta.url)) const isCI = !!process.env.CI +const inspectorPort = 5678 +const inspectorInjectTarget = path.resolve(__dirname, 'app/components/browser-initializer.tsx') +const inspectorRuntimeFile = path.resolve( + __dirname, + `node_modules/code-inspector-plugin/dist/append-code-${inspectorPort}.js`, +) + +const getInspectorRuntimeSnippet = (): string => { + if (!fs.existsSync(inspectorRuntimeFile)) + return '' + + const raw = fs.readFileSync(inspectorRuntimeFile, 'utf-8') + // Remove the helper module default export from append file to avoid duplicate default exports. + return raw.replace( + /\s*export default function CodeInspectorEmptyElement\(\)\s*\{[\s\S]*$/, + '', + ) +} + +const normalizeInspectorModuleId = (id: string): string => { + const withoutQuery = id.split('?', 1)[0] + + // Vite/vinext may pass absolute fs modules as "/@fs/". + if (withoutQuery.startsWith('/@fs/')) + return withoutQuery.slice('/@fs'.length) + + return withoutQuery +} + +const createCodeInspectorPlugin = (): Plugin => { + return codeInspectorPlugin({ + bundler: 'vite', + port: inspectorPort, + injectTo: inspectorInjectTarget, + exclude: [/^(?!.*\.(?:js|ts|mjs|mts|jsx|tsx|vue|svelte|html)(?:$|\?)).*/], + }) as Plugin +} + +const createForceInspectorClientInjectionPlugin = (): Plugin => { + const clientSnippet = getInspectorRuntimeSnippet() + + return { + name: 'vinext-force-code-inspector-client', + apply: 'serve', + enforce: 'pre', + transform(code, id) { + if (!clientSnippet) + return null + + const cleanId = normalizeInspectorModuleId(id) + if (cleanId !== inspectorInjectTarget) + return null + if (code.includes('code-inspector-component')) + return null + + return `${clientSnippet}\n${code}` + }, + } +} export default defineConfig(({ mode }) => { + const isDev = mode === 'development' + return { plugins: mode === 'test' ? [ @@ -26,6 +89,12 @@ export default defineConfig(({ mode }) => { } as Plugin, ] : [ + ...(isDev + ? [ + createCodeInspectorPlugin(), + createForceInspectorClientInjectionPlugin(), + ] + : []), vinext(), ], resolve: {