mirror of
https://github.com/langgenius/dify.git
synced 2026-04-05 16:36:28 +08:00
Merge branch 'main' into jzh
This commit is contained in:
34
.github/workflows/autofix.yml
vendored
34
.github/workflows/autofix.yml
vendored
@@ -2,6 +2,9 @@ name: autofix.ci
|
||||
on:
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
merge_group:
|
||||
branches: ["main"]
|
||||
types: [checks_requested]
|
||||
push:
|
||||
branches: ["main"]
|
||||
permissions:
|
||||
@@ -12,9 +15,15 @@ jobs:
|
||||
if: github.repository == 'langgenius/dify'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Complete merge group check
|
||||
if: github.event_name == 'merge_group'
|
||||
run: echo "autofix.ci updates pull request branches, not merge group refs."
|
||||
|
||||
- if: github.event_name != 'merge_group'
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Check Docker Compose inputs
|
||||
if: github.event_name != 'merge_group'
|
||||
id: docker-compose-changes
|
||||
uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5
|
||||
with:
|
||||
@@ -24,30 +33,34 @@ jobs:
|
||||
docker/docker-compose-template.yaml
|
||||
docker/docker-compose.yaml
|
||||
- name: Check web inputs
|
||||
if: github.event_name != 'merge_group'
|
||||
id: web-changes
|
||||
uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5
|
||||
with:
|
||||
files: |
|
||||
web/**
|
||||
- name: Check api inputs
|
||||
if: github.event_name != 'merge_group'
|
||||
id: api-changes
|
||||
uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5
|
||||
with:
|
||||
files: |
|
||||
api/**
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
- if: github.event_name != 'merge_group'
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
|
||||
- if: github.event_name != 'merge_group'
|
||||
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
|
||||
|
||||
- name: Generate Docker Compose
|
||||
if: steps.docker-compose-changes.outputs.any_changed == 'true'
|
||||
if: github.event_name != 'merge_group' && steps.docker-compose-changes.outputs.any_changed == 'true'
|
||||
run: |
|
||||
cd docker
|
||||
./generate_docker_compose
|
||||
|
||||
- if: steps.api-changes.outputs.any_changed == 'true'
|
||||
- if: github.event_name != 'merge_group' && steps.api-changes.outputs.any_changed == 'true'
|
||||
run: |
|
||||
cd api
|
||||
uv sync --dev
|
||||
@@ -59,13 +72,13 @@ jobs:
|
||||
uv run ruff format ..
|
||||
|
||||
- name: count migration progress
|
||||
if: steps.api-changes.outputs.any_changed == 'true'
|
||||
if: github.event_name != 'merge_group' && steps.api-changes.outputs.any_changed == 'true'
|
||||
run: |
|
||||
cd api
|
||||
./cnt_base.sh
|
||||
|
||||
- name: ast-grep
|
||||
if: steps.api-changes.outputs.any_changed == 'true'
|
||||
if: github.event_name != 'merge_group' && steps.api-changes.outputs.any_changed == 'true'
|
||||
run: |
|
||||
# ast-grep exits 1 if no matches are found; allow idempotent runs.
|
||||
uvx --from ast-grep-cli ast-grep --pattern 'db.session.query($WHATEVER).filter($HERE)' --rewrite 'db.session.query($WHATEVER).where($HERE)' -l py --update-all || true
|
||||
@@ -95,13 +108,14 @@ jobs:
|
||||
find . -name "*.py.bak" -type f -delete
|
||||
|
||||
- name: Setup web environment
|
||||
if: steps.web-changes.outputs.any_changed == 'true'
|
||||
if: github.event_name != 'merge_group' && steps.web-changes.outputs.any_changed == 'true'
|
||||
uses: ./.github/actions/setup-web
|
||||
|
||||
- name: ESLint autofix
|
||||
if: steps.web-changes.outputs.any_changed == 'true'
|
||||
if: github.event_name != 'merge_group' && steps.web-changes.outputs.any_changed == 'true'
|
||||
run: |
|
||||
cd web
|
||||
vp exec eslint --concurrency=2 --prune-suppressions --quiet || true
|
||||
|
||||
- uses: autofix-ci/action@7a166d7532b277f34e16238930461bf77f9d7ed8 # v1.3.3
|
||||
- if: github.event_name != 'merge_group'
|
||||
uses: autofix-ci/action@7a166d7532b277f34e16238930461bf77f9d7ed8 # v1.3.3
|
||||
|
||||
189
.github/workflows/main-ci.yml
vendored
189
.github/workflows/main-ci.yml
vendored
@@ -3,6 +3,9 @@ name: Main CI Pipeline
|
||||
on:
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
merge_group:
|
||||
branches: ["main"]
|
||||
types: [checks_requested]
|
||||
push:
|
||||
branches: ["main"]
|
||||
|
||||
@@ -50,33 +53,201 @@ jobs:
|
||||
- 'api/migrations/**'
|
||||
- '.github/workflows/db-migration-test.yml'
|
||||
|
||||
# Run tests in parallel
|
||||
api-tests:
|
||||
name: API Tests
|
||||
# Run tests in parallel while always emitting stable required checks.
|
||||
api-tests-run:
|
||||
name: Run API Tests
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.api-changed == 'true'
|
||||
uses: ./.github/workflows/api-tests.yml
|
||||
secrets: inherit
|
||||
|
||||
web-tests:
|
||||
name: Web Tests
|
||||
api-tests-skip:
|
||||
name: Skip API Tests
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.api-changed != 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Report skipped API tests
|
||||
run: echo "No API-related changes detected; skipping API tests."
|
||||
|
||||
api-tests:
|
||||
name: API Tests
|
||||
if: ${{ always() }}
|
||||
needs:
|
||||
- check-changes
|
||||
- api-tests-run
|
||||
- api-tests-skip
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Finalize API Tests status
|
||||
env:
|
||||
TESTS_CHANGED: ${{ needs.check-changes.outputs.api-changed }}
|
||||
RUN_RESULT: ${{ needs.api-tests-run.result }}
|
||||
SKIP_RESULT: ${{ needs.api-tests-skip.result }}
|
||||
run: |
|
||||
if [[ "$TESTS_CHANGED" == 'true' ]]; then
|
||||
if [[ "$RUN_RESULT" == 'success' ]]; then
|
||||
echo "API tests ran successfully."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "API tests were required but finished with result: $RUN_RESULT" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$SKIP_RESULT" == 'success' ]]; then
|
||||
echo "API tests were skipped because no API-related files changed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "API tests were not required, but the skip job finished with result: $SKIP_RESULT" >&2
|
||||
exit 1
|
||||
|
||||
web-tests-run:
|
||||
name: Run Web Tests
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.web-changed == 'true'
|
||||
uses: ./.github/workflows/web-tests.yml
|
||||
secrets: inherit
|
||||
|
||||
web-tests-skip:
|
||||
name: Skip Web Tests
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.web-changed != 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Report skipped web tests
|
||||
run: echo "No web-related changes detected; skipping web tests."
|
||||
|
||||
web-tests:
|
||||
name: Web Tests
|
||||
if: ${{ always() }}
|
||||
needs:
|
||||
- check-changes
|
||||
- web-tests-run
|
||||
- web-tests-skip
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Finalize Web Tests status
|
||||
env:
|
||||
TESTS_CHANGED: ${{ needs.check-changes.outputs.web-changed }}
|
||||
RUN_RESULT: ${{ needs.web-tests-run.result }}
|
||||
SKIP_RESULT: ${{ needs.web-tests-skip.result }}
|
||||
run: |
|
||||
if [[ "$TESTS_CHANGED" == 'true' ]]; then
|
||||
if [[ "$RUN_RESULT" == 'success' ]]; then
|
||||
echo "Web tests ran successfully."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Web tests were required but finished with result: $RUN_RESULT" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$SKIP_RESULT" == 'success' ]]; then
|
||||
echo "Web tests were skipped because no web-related files changed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Web tests were not required, but the skip job finished with result: $SKIP_RESULT" >&2
|
||||
exit 1
|
||||
|
||||
style-check:
|
||||
name: Style Check
|
||||
uses: ./.github/workflows/style.yml
|
||||
|
||||
vdb-tests:
|
||||
name: VDB Tests
|
||||
vdb-tests-run:
|
||||
name: Run VDB Tests
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.vdb-changed == 'true'
|
||||
uses: ./.github/workflows/vdb-tests.yml
|
||||
|
||||
db-migration-test:
|
||||
name: DB Migration Test
|
||||
vdb-tests-skip:
|
||||
name: Skip VDB Tests
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.vdb-changed != 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Report skipped VDB tests
|
||||
run: echo "No VDB-related changes detected; skipping VDB tests."
|
||||
|
||||
vdb-tests:
|
||||
name: VDB Tests
|
||||
if: ${{ always() }}
|
||||
needs:
|
||||
- check-changes
|
||||
- vdb-tests-run
|
||||
- vdb-tests-skip
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Finalize VDB Tests status
|
||||
env:
|
||||
TESTS_CHANGED: ${{ needs.check-changes.outputs.vdb-changed }}
|
||||
RUN_RESULT: ${{ needs.vdb-tests-run.result }}
|
||||
SKIP_RESULT: ${{ needs.vdb-tests-skip.result }}
|
||||
run: |
|
||||
if [[ "$TESTS_CHANGED" == 'true' ]]; then
|
||||
if [[ "$RUN_RESULT" == 'success' ]]; then
|
||||
echo "VDB tests ran successfully."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "VDB tests were required but finished with result: $RUN_RESULT" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$SKIP_RESULT" == 'success' ]]; then
|
||||
echo "VDB tests were skipped because no VDB-related files changed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "VDB tests were not required, but the skip job finished with result: $SKIP_RESULT" >&2
|
||||
exit 1
|
||||
|
||||
db-migration-test-run:
|
||||
name: Run DB Migration Test
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.migration-changed == 'true'
|
||||
uses: ./.github/workflows/db-migration-test.yml
|
||||
|
||||
db-migration-test-skip:
|
||||
name: Skip DB Migration Test
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.migration-changed != 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Report skipped DB migration tests
|
||||
run: echo "No migration-related changes detected; skipping DB migration tests."
|
||||
|
||||
db-migration-test:
|
||||
name: DB Migration Test
|
||||
if: ${{ always() }}
|
||||
needs:
|
||||
- check-changes
|
||||
- db-migration-test-run
|
||||
- db-migration-test-skip
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Finalize DB Migration Test status
|
||||
env:
|
||||
TESTS_CHANGED: ${{ needs.check-changes.outputs.migration-changed }}
|
||||
RUN_RESULT: ${{ needs.db-migration-test-run.result }}
|
||||
SKIP_RESULT: ${{ needs.db-migration-test-skip.result }}
|
||||
run: |
|
||||
if [[ "$TESTS_CHANGED" == 'true' ]]; then
|
||||
if [[ "$RUN_RESULT" == 'success' ]]; then
|
||||
echo "DB migration tests ran successfully."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "DB migration tests were required but finished with result: $RUN_RESULT" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$SKIP_RESULT" == 'success' ]]; then
|
||||
echo "DB migration tests were skipped because no migration-related files changed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "DB migration tests were not required, but the skip job finished with result: $SKIP_RESULT" >&2
|
||||
exit 1
|
||||
|
||||
7
.github/workflows/semantic-pull-request.yml
vendored
7
.github/workflows/semantic-pull-request.yml
vendored
@@ -7,6 +7,9 @@ on:
|
||||
- edited
|
||||
- reopened
|
||||
- synchronize
|
||||
merge_group:
|
||||
branches: ["main"]
|
||||
types: [checks_requested]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
@@ -15,7 +18,11 @@ jobs:
|
||||
pull-requests: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Complete merge group check
|
||||
if: github.event_name == 'merge_group'
|
||||
run: echo "Semantic PR title validation is handled on pull requests."
|
||||
- name: Check title
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import timedelta
|
||||
from decimal import Decimal
|
||||
from uuid import uuid4
|
||||
|
||||
from graphon.nodes.human_input.entities import FormDefinition, UserAction
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from models.account import Account, Tenant, TenantAccountJoin
|
||||
from models.enums import ConversationFromSource, InvokeFrom
|
||||
from models.execution_extra_content import HumanInputContent
|
||||
@@ -117,7 +118,7 @@ def create_human_input_message_fixture(db_session) -> HumanInputMessageFixture:
|
||||
inputs=[],
|
||||
user_actions=[UserAction(id=action_id, title=action_text)],
|
||||
rendered_content="Rendered block",
|
||||
expiration_time=datetime.utcnow() + timedelta(days=1),
|
||||
expiration_time=naive_utc_now() + timedelta(days=1),
|
||||
node_title=node_title,
|
||||
display_in_ui=True,
|
||||
)
|
||||
@@ -129,7 +130,7 @@ def create_human_input_message_fixture(db_session) -> HumanInputMessageFixture:
|
||||
form_definition=form_definition.model_dump_json(),
|
||||
rendered_content="Rendered block",
|
||||
status=HumanInputFormStatus.SUBMITTED,
|
||||
expiration_time=datetime.utcnow() + timedelta(days=1),
|
||||
expiration_time=naive_utc_now() + timedelta(days=1),
|
||||
selected_action_id=action_id,
|
||||
)
|
||||
db_session.add(form)
|
||||
|
||||
@@ -7,7 +7,7 @@ from __future__ import annotations
|
||||
|
||||
from collections.abc import Generator
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import timedelta
|
||||
from decimal import Decimal
|
||||
from uuid import uuid4
|
||||
|
||||
@@ -17,6 +17,7 @@ from sqlalchemy.orm import Session, sessionmaker
|
||||
|
||||
from graphon.nodes.human_input.entities import FormDefinition, UserAction
|
||||
from graphon.nodes.human_input.enums import HumanInputFormStatus
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from models.account import Account, Tenant, TenantAccountJoin, TenantAccountRole
|
||||
from models.enums import ConversationFromSource, InvokeFrom
|
||||
from models.execution_extra_content import ExecutionExtraContent, HumanInputContent
|
||||
@@ -174,7 +175,7 @@ def _create_submitted_form(
|
||||
action_title: str = "Approve",
|
||||
node_title: str = "Approval",
|
||||
) -> HumanInputForm:
|
||||
expiration_time = datetime.utcnow() + timedelta(days=1)
|
||||
expiration_time = naive_utc_now() + timedelta(days=1)
|
||||
form_definition = FormDefinition(
|
||||
form_content="content",
|
||||
inputs=[],
|
||||
@@ -207,7 +208,7 @@ def _create_waiting_form(
|
||||
workflow_run_id: str,
|
||||
default_values: dict | None = None,
|
||||
) -> HumanInputForm:
|
||||
expiration_time = datetime.utcnow() + timedelta(days=1)
|
||||
expiration_time = naive_utc_now() + timedelta(days=1)
|
||||
form_definition = FormDefinition(
|
||||
form_content="content",
|
||||
inputs=[],
|
||||
|
||||
@@ -26,6 +26,7 @@ from controllers.console.datasets.rag_pipeline.rag_pipeline_workflow import (
|
||||
RagPipelineWorkflowLastRunApi,
|
||||
)
|
||||
from controllers.web.error import InvokeRateLimitError as InvokeRateLimitHttpError
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from services.errors.app import IsDraftWorkflowError, WorkflowHashNotEqualError, WorkflowNotFoundError
|
||||
from services.errors.llm import InvokeRateLimitError
|
||||
|
||||
@@ -372,7 +373,7 @@ class TestPublishedPipelineApis:
|
||||
|
||||
workflow = MagicMock(
|
||||
id="w1",
|
||||
created_at=datetime.utcnow(),
|
||||
created_at=naive_utc_now(),
|
||||
)
|
||||
|
||||
session = MagicMock()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from datetime import datetime
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
@@ -25,6 +24,7 @@ from controllers.console.datasets.error import (
|
||||
)
|
||||
from core.errors.error import LLMBadRequestError, ProviderTokenNotInitError
|
||||
from core.rag.index_processor.constant.index_type import IndexStructureType
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from models.dataset import ChildChunk, DocumentSegment
|
||||
from models.model import UploadFile
|
||||
|
||||
@@ -54,8 +54,8 @@ def _segment():
|
||||
disabled_by=None,
|
||||
status="normal",
|
||||
created_by="u1",
|
||||
created_at=datetime.utcnow(),
|
||||
updated_at=datetime.utcnow(),
|
||||
created_at=naive_utc_now(),
|
||||
updated_at=naive_utc_now(),
|
||||
updated_by="u1",
|
||||
indexing_at=None,
|
||||
completed_at=None,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from datetime import datetime
|
||||
from io import BytesIO
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
@@ -26,6 +25,7 @@ from controllers.console.workspace.workspace import (
|
||||
WorkspacePermissionApi,
|
||||
)
|
||||
from enums.cloud_plan import CloudPlan
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from models.account import TenantStatus
|
||||
|
||||
|
||||
@@ -44,13 +44,13 @@ class TestTenantListApi:
|
||||
id="t1",
|
||||
name="Tenant 1",
|
||||
status="active",
|
||||
created_at=datetime.utcnow(),
|
||||
created_at=naive_utc_now(),
|
||||
)
|
||||
tenant2 = MagicMock(
|
||||
id="t2",
|
||||
name="Tenant 2",
|
||||
status="active",
|
||||
created_at=datetime.utcnow(),
|
||||
created_at=naive_utc_now(),
|
||||
)
|
||||
|
||||
with (
|
||||
@@ -97,13 +97,13 @@ class TestTenantListApi:
|
||||
id="t1",
|
||||
name="Tenant 1",
|
||||
status="active",
|
||||
created_at=datetime.utcnow(),
|
||||
created_at=naive_utc_now(),
|
||||
)
|
||||
tenant2 = MagicMock(
|
||||
id="t2",
|
||||
name="Tenant 2",
|
||||
status="active",
|
||||
created_at=datetime.utcnow(),
|
||||
created_at=naive_utc_now(),
|
||||
)
|
||||
|
||||
features_t2 = MagicMock()
|
||||
@@ -152,13 +152,13 @@ class TestTenantListApi:
|
||||
id="t1",
|
||||
name="Tenant 1",
|
||||
status="active",
|
||||
created_at=datetime.utcnow(),
|
||||
created_at=naive_utc_now(),
|
||||
)
|
||||
tenant2 = MagicMock(
|
||||
id="t2",
|
||||
name="Tenant 2",
|
||||
status="active",
|
||||
created_at=datetime.utcnow(),
|
||||
created_at=naive_utc_now(),
|
||||
)
|
||||
|
||||
features = MagicMock()
|
||||
@@ -204,7 +204,7 @@ class TestTenantListApi:
|
||||
id="t1",
|
||||
name="Tenant",
|
||||
status="active",
|
||||
created_at=datetime.utcnow(),
|
||||
created_at=naive_utc_now(),
|
||||
)
|
||||
|
||||
features = MagicMock()
|
||||
@@ -243,13 +243,13 @@ class TestTenantListApi:
|
||||
id="t1",
|
||||
name="Tenant 1",
|
||||
status="active",
|
||||
created_at=datetime.utcnow(),
|
||||
created_at=naive_utc_now(),
|
||||
)
|
||||
tenant2 = MagicMock(
|
||||
id="t2",
|
||||
name="Tenant 2",
|
||||
status="active",
|
||||
created_at=datetime.utcnow(),
|
||||
created_at=naive_utc_now(),
|
||||
)
|
||||
|
||||
with (
|
||||
@@ -305,7 +305,7 @@ class TestWorkspaceListApi:
|
||||
api = WorkspaceListApi()
|
||||
method = unwrap(api.get)
|
||||
|
||||
tenant = MagicMock(id="t1", name="T", status="active", created_at=datetime.utcnow())
|
||||
tenant = MagicMock(id="t1", name="T", status="active", created_at=naive_utc_now())
|
||||
|
||||
paginate_result = MagicMock(
|
||||
items=[tenant],
|
||||
@@ -331,7 +331,7 @@ class TestWorkspaceListApi:
|
||||
id="t1",
|
||||
name="T",
|
||||
status="active",
|
||||
created_at=datetime.utcnow(),
|
||||
created_at=naive_utc_now(),
|
||||
)
|
||||
|
||||
paginate_result = MagicMock(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from contextlib import contextmanager
|
||||
from datetime import datetime
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
@@ -45,6 +44,7 @@ from core.base.tts.app_generator_tts_publisher import AudioTrunk
|
||||
from core.workflow.system_variables import build_system_variables
|
||||
from graphon.enums import BuiltinNodeTypes
|
||||
from graphon.runtime import GraphRuntimeState, VariablePool
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from models.enums import MessageStatus
|
||||
from models.model import AppMode, EndUser
|
||||
from tests.workflow_test_utils import build_test_variable_pool
|
||||
@@ -76,7 +76,7 @@ def _make_pipeline():
|
||||
message = SimpleNamespace(
|
||||
id="message-id",
|
||||
query="hello",
|
||||
created_at=datetime.utcnow(),
|
||||
created_at=naive_utc_now(),
|
||||
status=MessageStatus.NORMAL,
|
||||
answer="",
|
||||
)
|
||||
@@ -257,7 +257,7 @@ class TestAdvancedChatGenerateTaskPipeline:
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
node_title="LLM",
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
node_run_index=1,
|
||||
)
|
||||
iter_next = QueueIterationNextEvent(
|
||||
@@ -273,7 +273,7 @@ class TestAdvancedChatGenerateTaskPipeline:
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
node_title="LLM",
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
node_run_index=1,
|
||||
)
|
||||
loop_start = QueueLoopStartEvent(
|
||||
@@ -281,7 +281,7 @@ class TestAdvancedChatGenerateTaskPipeline:
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
node_title="LLM",
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
node_run_index=1,
|
||||
)
|
||||
loop_next = QueueLoopNextEvent(
|
||||
@@ -297,7 +297,7 @@ class TestAdvancedChatGenerateTaskPipeline:
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
node_title="LLM",
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
node_run_index=1,
|
||||
)
|
||||
|
||||
@@ -360,7 +360,7 @@ class TestAdvancedChatGenerateTaskPipeline:
|
||||
node_execution_id="exec",
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
inputs={},
|
||||
outputs={},
|
||||
process_data={},
|
||||
@@ -370,7 +370,7 @@ class TestAdvancedChatGenerateTaskPipeline:
|
||||
node_execution_id="exec",
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
inputs={},
|
||||
outputs={},
|
||||
process_data={},
|
||||
@@ -473,7 +473,7 @@ class TestAdvancedChatGenerateTaskPipeline:
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
node_title="title",
|
||||
expiration_time=datetime.utcnow(),
|
||||
expiration_time=naive_utc_now(),
|
||||
)
|
||||
|
||||
assert list(pipeline._handle_human_input_form_filled_event(filled_event)) == ["filled"]
|
||||
@@ -591,7 +591,7 @@ class TestAdvancedChatGenerateTaskPipeline:
|
||||
node_execution_id="exec",
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
inputs={},
|
||||
outputs={},
|
||||
process_data={},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from contextlib import contextmanager
|
||||
from datetime import datetime
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
@@ -47,6 +46,7 @@ from core.base.tts.app_generator_tts_publisher import AudioTrunk
|
||||
from core.workflow.system_variables import build_system_variables, system_variables_to_mapping
|
||||
from graphon.enums import BuiltinNodeTypes, WorkflowExecutionStatus
|
||||
from graphon.runtime import GraphRuntimeState, VariablePool
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from models.enums import CreatorUserRole
|
||||
from models.model import AppMode, EndUser
|
||||
from tests.workflow_test_utils import build_test_variable_pool
|
||||
@@ -192,7 +192,7 @@ class TestWorkflowGenerateTaskPipeline:
|
||||
node_execution_id="exec",
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.START,
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
inputs={},
|
||||
outputs={},
|
||||
process_data={},
|
||||
@@ -245,7 +245,7 @@ class TestWorkflowGenerateTaskPipeline:
|
||||
node_execution_id="exec",
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.START,
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
inputs={},
|
||||
outputs={},
|
||||
process_data={},
|
||||
@@ -303,7 +303,7 @@ class TestWorkflowGenerateTaskPipeline:
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
node_title="LLM",
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
node_run_index=1,
|
||||
)
|
||||
iter_next = QueueIterationNextEvent(
|
||||
@@ -319,7 +319,7 @@ class TestWorkflowGenerateTaskPipeline:
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
node_title="LLM",
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
node_run_index=1,
|
||||
)
|
||||
loop_start = QueueLoopStartEvent(
|
||||
@@ -327,7 +327,7 @@ class TestWorkflowGenerateTaskPipeline:
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
node_title="LLM",
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
node_run_index=1,
|
||||
)
|
||||
loop_next = QueueLoopNextEvent(
|
||||
@@ -343,7 +343,7 @@ class TestWorkflowGenerateTaskPipeline:
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
node_title="LLM",
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
node_run_index=1,
|
||||
)
|
||||
filled_event = QueueHumanInputFormFilledEvent(
|
||||
@@ -359,7 +359,7 @@ class TestWorkflowGenerateTaskPipeline:
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
node_title="title",
|
||||
expiration_time=datetime.utcnow(),
|
||||
expiration_time=naive_utc_now(),
|
||||
)
|
||||
agent_event = QueueAgentLogEvent(
|
||||
id="log",
|
||||
@@ -648,7 +648,7 @@ class TestWorkflowGenerateTaskPipeline:
|
||||
node_title="title",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
node_run_index=1,
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
provider_type="provider",
|
||||
provider_id="provider-id",
|
||||
error="error",
|
||||
@@ -660,7 +660,7 @@ class TestWorkflowGenerateTaskPipeline:
|
||||
node_title="title",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
node_run_index=1,
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
provider_type="provider",
|
||||
provider_id="provider-id",
|
||||
)
|
||||
@@ -685,7 +685,7 @@ class TestWorkflowGenerateTaskPipeline:
|
||||
node_execution_id="exec-id",
|
||||
node_id="node",
|
||||
node_type=BuiltinNodeTypes.START,
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
inputs={},
|
||||
outputs={},
|
||||
process_data={},
|
||||
@@ -836,7 +836,7 @@ class TestWorkflowGenerateTaskPipeline:
|
||||
node_id="node-id",
|
||||
node_type=BuiltinNodeTypes.START,
|
||||
in_loop_id="loop-id",
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
process_data={"k": "v"},
|
||||
outputs={"out": 1},
|
||||
)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from collections.abc import Sequence
|
||||
from datetime import datetime
|
||||
from unittest.mock import Mock
|
||||
|
||||
from core.app.layers.conversation_variable_persist_layer import ConversationVariablePersistenceLayer
|
||||
@@ -12,6 +11,7 @@ from graphon.node_events import NodeRunResult
|
||||
from graphon.runtime.graph_runtime_state_protocol import ReadOnlyGraphRuntimeState
|
||||
from graphon.variables import StringVariable
|
||||
from graphon.variables.segments import Segment, StringSegment
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
|
||||
|
||||
class MockReadOnlyVariablePool:
|
||||
@@ -48,7 +48,7 @@ def _build_node_run_succeeded_event() -> NodeRunSucceededEvent:
|
||||
id="node-exec-id",
|
||||
node_id="assigner",
|
||||
node_type=BuiltinNodeTypes.LLM,
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
node_run_result=NodeRunResult(
|
||||
status=WorkflowNodeExecutionStatus.SUCCEEDED,
|
||||
outputs={},
|
||||
|
||||
@@ -274,7 +274,7 @@ def _make_form_definition() -> str:
|
||||
inputs=[],
|
||||
user_actions=[UserAction(id="submit", title="Submit")],
|
||||
rendered_content="<p>hello</p>",
|
||||
expiration_time=datetime.utcnow(),
|
||||
expiration_time=naive_utc_now(),
|
||||
).model_dump_json()
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import queue
|
||||
from datetime import datetime
|
||||
|
||||
from graphon.enums import BuiltinNodeTypes, WorkflowNodeExecutionStatus
|
||||
from graphon.graph_engine.orchestration.dispatcher import Dispatcher
|
||||
from graphon.graph_events import NodeRunSucceededEvent
|
||||
from graphon.node_events import NodeRunResult
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
|
||||
|
||||
class StubExecutionCoordinator:
|
||||
@@ -52,7 +52,7 @@ def test_dispatcher_drains_events_when_paused() -> None:
|
||||
id="exec-1",
|
||||
node_id="node-1",
|
||||
node_type=BuiltinNodeTypes.START,
|
||||
start_at=datetime.utcnow(),
|
||||
start_at=naive_utc_now(),
|
||||
node_run_result=NodeRunResult(status=WorkflowNodeExecutionStatus.SUCCEEDED),
|
||||
)
|
||||
event_queue.put(event)
|
||||
|
||||
@@ -6,6 +6,7 @@ from typing import Any
|
||||
|
||||
from graphon.nodes.human_input.entities import FormInput
|
||||
from graphon.nodes.human_input.enums import TimeoutUnit
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
|
||||
|
||||
# Exceptions
|
||||
@@ -49,7 +50,7 @@ class HumanInputForm:
|
||||
timeout: int
|
||||
timeout_unit: TimeoutUnit
|
||||
form_token: str | None = None
|
||||
created_at: datetime = field(default_factory=datetime.utcnow)
|
||||
created_at: datetime = field(default_factory=naive_utc_now)
|
||||
expires_at: datetime | None = None
|
||||
submitted_at: datetime | None = None
|
||||
submitted_data: dict[str, Any] | None = None
|
||||
@@ -61,7 +62,7 @@ class HumanInputForm:
|
||||
|
||||
@property
|
||||
def is_expired(self) -> bool:
|
||||
return self.expires_at is not None and datetime.utcnow() > self.expires_at
|
||||
return self.expires_at is not None and naive_utc_now() > self.expires_at
|
||||
|
||||
@property
|
||||
def is_submitted(self) -> bool:
|
||||
@@ -70,7 +71,7 @@ class HumanInputForm:
|
||||
def mark_submitted(self, inputs: dict[str, Any], action: str) -> None:
|
||||
self.submitted_data = inputs
|
||||
self.submitted_action = action
|
||||
self.submitted_at = datetime.utcnow()
|
||||
self.submitted_at = naive_utc_now()
|
||||
|
||||
def submit(self, inputs: dict[str, Any], action: str) -> None:
|
||||
self.mark_submitted(inputs, action)
|
||||
@@ -107,7 +108,7 @@ class FormSubmissionData:
|
||||
form_id: str
|
||||
inputs: dict[str, Any]
|
||||
action: str
|
||||
submitted_at: datetime = field(default_factory=datetime.utcnow)
|
||||
submitted_at: datetime = field(default_factory=naive_utc_now)
|
||||
|
||||
@classmethod
|
||||
def from_request(cls, form_id: str, request: FormSubmissionRequest) -> FormSubmissionData: # type: ignore
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Unit tests for FormService.
|
||||
"""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import timedelta
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -142,7 +142,7 @@ class TestFormService:
|
||||
|
||||
# Manually expire the form by modifying expiry time
|
||||
form = form_service.get_form_by_id("form-123")
|
||||
form.expires_at = datetime.utcnow() - timedelta(hours=1)
|
||||
form.expires_at = naive_utc_now() - timedelta(hours=1)
|
||||
form_service.repository.save(form)
|
||||
|
||||
# Should raise FormExpiredError
|
||||
@@ -227,7 +227,7 @@ class TestFormService:
|
||||
|
||||
# Manually expire the form
|
||||
form = form_service.get_form_by_id("form-123")
|
||||
form.expires_at = datetime.utcnow() - timedelta(hours=1)
|
||||
form.expires_at = naive_utc_now() - timedelta(hours=1)
|
||||
form_service.repository.save(form)
|
||||
|
||||
# Try to submit expired form
|
||||
|
||||
@@ -14,6 +14,7 @@ from graphon.nodes.human_input.enums import (
|
||||
FormInputType,
|
||||
TimeoutUnit,
|
||||
)
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
|
||||
from .support import FormSubmissionData, FormSubmissionRequest, HumanInputForm
|
||||
|
||||
@@ -83,7 +84,7 @@ class TestHumanInputForm:
|
||||
def test_form_expiry_property_expired(self, sample_form_data):
|
||||
"""Test is_expired property for expired form."""
|
||||
# Create form with past expiry
|
||||
past_time = datetime.utcnow() - timedelta(hours=1)
|
||||
past_time = naive_utc_now() - timedelta(hours=1)
|
||||
sample_form_data["created_at"] = past_time
|
||||
|
||||
form = HumanInputForm(**sample_form_data)
|
||||
@@ -111,9 +112,9 @@ class TestHumanInputForm:
|
||||
"""Test form submit method."""
|
||||
form = HumanInputForm(**sample_form_data)
|
||||
|
||||
submission_time_before = datetime.utcnow()
|
||||
submission_time_before = naive_utc_now()
|
||||
form.submit({"input": "test value"}, "submit")
|
||||
submission_time_after = datetime.utcnow()
|
||||
submission_time_after = naive_utc_now()
|
||||
|
||||
assert form.is_submitted
|
||||
assert form.submitted_data == {"input": "test value"}
|
||||
@@ -213,11 +214,11 @@ class TestFormSubmissionData:
|
||||
|
||||
def test_submission_data_timestamps(self):
|
||||
"""Test submission data timestamp handling."""
|
||||
before_time = datetime.utcnow()
|
||||
before_time = naive_utc_now()
|
||||
|
||||
submission_data = FormSubmissionData(form_id="form-123", inputs={"test": "value"}, action="submit")
|
||||
|
||||
after_time = datetime.utcnow()
|
||||
after_time = naive_utc_now()
|
||||
|
||||
assert before_time <= submission_data.submitted_at <= after_time
|
||||
|
||||
|
||||
@@ -6,13 +6,14 @@ Tests are organized by functionality and include edge cases, error handling,
|
||||
and both positive and negative test scenarios.
|
||||
"""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import timedelta
|
||||
from unittest.mock import MagicMock, Mock, create_autospec, patch
|
||||
|
||||
import pytest
|
||||
from sqlalchemy import asc, desc
|
||||
|
||||
from core.app.entities.app_invoke_entities import InvokeFrom
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from libs.infinite_scroll_pagination import InfiniteScrollPagination
|
||||
from models import Account, ConversationVariable
|
||||
from models.enums import ConversationFromSource
|
||||
@@ -122,8 +123,8 @@ class ConversationServiceTestDataFactory:
|
||||
conversation.is_deleted = kwargs.get("is_deleted", False)
|
||||
conversation.name = kwargs.get("name", "Test Conversation")
|
||||
conversation.status = kwargs.get("status", "normal")
|
||||
conversation.created_at = kwargs.get("created_at", datetime.utcnow())
|
||||
conversation.updated_at = kwargs.get("updated_at", datetime.utcnow())
|
||||
conversation.created_at = kwargs.get("created_at", naive_utc_now())
|
||||
conversation.updated_at = kwargs.get("updated_at", naive_utc_now())
|
||||
for key, value in kwargs.items():
|
||||
setattr(conversation, key, value)
|
||||
return conversation
|
||||
@@ -152,7 +153,7 @@ class ConversationServiceTestDataFactory:
|
||||
message.conversation_id = conversation_id
|
||||
message.app_id = app_id
|
||||
message.query = kwargs.get("query", "Test message content")
|
||||
message.created_at = kwargs.get("created_at", datetime.utcnow())
|
||||
message.created_at = kwargs.get("created_at", naive_utc_now())
|
||||
for key, value in kwargs.items():
|
||||
setattr(message, key, value)
|
||||
return message
|
||||
@@ -181,8 +182,8 @@ class ConversationServiceTestDataFactory:
|
||||
variable.conversation_id = conversation_id
|
||||
variable.app_id = app_id
|
||||
variable.data = {"name": kwargs.get("name", "test_var"), "value": kwargs.get("value", "test_value")}
|
||||
variable.created_at = kwargs.get("created_at", datetime.utcnow())
|
||||
variable.updated_at = kwargs.get("updated_at", datetime.utcnow())
|
||||
variable.created_at = kwargs.get("created_at", naive_utc_now())
|
||||
variable.updated_at = kwargs.get("updated_at", naive_utc_now())
|
||||
|
||||
# Mock to_variable method
|
||||
mock_variable = Mock()
|
||||
@@ -302,7 +303,7 @@ class TestConversationServiceHelpers:
|
||||
"""
|
||||
# Arrange
|
||||
mock_conversation = ConversationServiceTestDataFactory.create_conversation_mock()
|
||||
mock_conversation.updated_at = datetime.utcnow()
|
||||
mock_conversation.updated_at = naive_utc_now()
|
||||
|
||||
# Act
|
||||
condition = ConversationService._build_filter_condition(
|
||||
@@ -323,7 +324,7 @@ class TestConversationServiceHelpers:
|
||||
"""
|
||||
# Arrange
|
||||
mock_conversation = ConversationServiceTestDataFactory.create_conversation_mock()
|
||||
mock_conversation.created_at = datetime.utcnow()
|
||||
mock_conversation.created_at = naive_utc_now()
|
||||
|
||||
# Act
|
||||
condition = ConversationService._build_filter_condition(
|
||||
@@ -668,9 +669,9 @@ class TestConversationServiceConversationalVariable:
|
||||
mock_session_factory.create_session.return_value.__enter__.return_value = mock_session
|
||||
|
||||
last_variable = ConversationServiceTestDataFactory.create_conversation_variable_mock(
|
||||
created_at=datetime.utcnow() - timedelta(hours=1)
|
||||
created_at=naive_utc_now() - timedelta(hours=1)
|
||||
)
|
||||
variable = ConversationServiceTestDataFactory.create_conversation_variable_mock(created_at=datetime.utcnow())
|
||||
variable = ConversationServiceTestDataFactory.create_conversation_variable_mock(created_at=naive_utc_now())
|
||||
|
||||
mock_session.scalar.return_value = last_variable
|
||||
mock_session.scalars.return_value.all.return_value = [variable]
|
||||
|
||||
@@ -15,6 +15,7 @@ from graphon.nodes.human_input.entities import (
|
||||
UserAction,
|
||||
)
|
||||
from graphon.nodes.human_input.enums import FormInputType, HumanInputFormKind, HumanInputFormStatus
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from models.human_input import RecipientType
|
||||
from services.human_input_service import (
|
||||
Form,
|
||||
@@ -51,11 +52,11 @@ def sample_form_record():
|
||||
inputs=[],
|
||||
user_actions=[UserAction(id="submit", title="Submit")],
|
||||
rendered_content="<p>hello</p>",
|
||||
expiration_time=datetime.utcnow() + timedelta(hours=1),
|
||||
expiration_time=naive_utc_now() + timedelta(hours=1),
|
||||
),
|
||||
rendered_content="<p>hello</p>",
|
||||
created_at=datetime.utcnow(),
|
||||
expiration_time=datetime.utcnow() + timedelta(hours=1),
|
||||
created_at=naive_utc_now(),
|
||||
expiration_time=naive_utc_now() + timedelta(hours=1),
|
||||
status=HumanInputFormStatus.WAITING,
|
||||
selected_action_id=None,
|
||||
submitted_data=None,
|
||||
@@ -101,8 +102,8 @@ def test_ensure_form_active_respects_global_timeout(monkeypatch, sample_form_rec
|
||||
service = HumanInputService(session_factory)
|
||||
expired_record = dataclasses.replace(
|
||||
sample_form_record,
|
||||
created_at=datetime.utcnow() - timedelta(hours=2),
|
||||
expiration_time=datetime.utcnow() + timedelta(hours=2),
|
||||
created_at=naive_utc_now() - timedelta(hours=2),
|
||||
expiration_time=naive_utc_now() + timedelta(hours=2),
|
||||
)
|
||||
monkeypatch.setattr(human_input_service_module.dify_config, "HUMAN_INPUT_GLOBAL_TIMEOUT_SECONDS", 3600)
|
||||
|
||||
@@ -391,7 +392,7 @@ def test_ensure_form_active_errors(sample_form_record, mock_session_factory):
|
||||
service = HumanInputService(session_factory)
|
||||
|
||||
# Submitted
|
||||
submitted_record = dataclasses.replace(sample_form_record, submitted_at=datetime.utcnow())
|
||||
submitted_record = dataclasses.replace(sample_form_record, submitted_at=naive_utc_now())
|
||||
with pytest.raises(human_input_service_module.FormSubmittedError):
|
||||
service.ensure_form_active(Form(submitted_record))
|
||||
|
||||
@@ -402,7 +403,7 @@ def test_ensure_form_active_errors(sample_form_record, mock_session_factory):
|
||||
|
||||
# Expired time
|
||||
expired_time_record = dataclasses.replace(
|
||||
sample_form_record, expiration_time=datetime.utcnow() - timedelta(minutes=1)
|
||||
sample_form_record, expiration_time=naive_utc_now() - timedelta(minutes=1)
|
||||
)
|
||||
with pytest.raises(FormExpiredError):
|
||||
service.ensure_form_active(Form(expired_time_record))
|
||||
@@ -411,7 +412,7 @@ def test_ensure_form_active_errors(sample_form_record, mock_session_factory):
|
||||
def test_ensure_not_submitted_raises(sample_form_record, mock_session_factory):
|
||||
session_factory, _ = mock_session_factory
|
||||
service = HumanInputService(session_factory)
|
||||
submitted_record = dataclasses.replace(sample_form_record, submitted_at=datetime.utcnow())
|
||||
submitted_record = dataclasses.replace(sample_form_record, submitted_at=naive_utc_now())
|
||||
|
||||
with pytest.raises(human_input_service_module.FormSubmittedError):
|
||||
service._ensure_not_submitted(Form(submitted_record))
|
||||
|
||||
Reference in New Issue
Block a user