Skip to content

Commit e319c6a

Browse files
authored
chore: post migration cleanup (#34)
* Deleted useAsyncTask * Auth forms autocomplete * Tag import fix * Run tests on local sqlite only * Improved backend test config * Removed update button from the Reset switchboard panel
1 parent 91c4dab commit e319c6a

9 files changed

Lines changed: 64 additions & 86 deletions

File tree

backend/app/modules/admin/io/service.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
from app.modules.events.models import Event
77
from app.modules.fields.models import Field
8-
from app.modules.tags.crud import get_or_create_tags
98
from app.modules.tags.models import Tag
109
from app.shared.models import EventField, EventTag
1110
from app.shared.service import assert_db_empty
@@ -82,14 +81,19 @@ def import_bundle(bundle: ImportBundle, db: Session):
8281
example=field_data.example,
8382
)
8483
db.add(field)
85-
db.flush() # Ensures ID is available before linking
84+
db.flush()
8685
field_map[field.name] = field
8786

88-
all_tag_ids = {tag.id for tag in bundle.tags}
87+
tag_definitions = {tag.id: tag for tag in bundle.tags}
88+
89+
all_tag_ids = set(tag_definitions.keys())
8990
for event in bundle.events:
9091
all_tag_ids.update(event.tags)
9192

92-
_ = get_or_create_tags(db, list(all_tag_ids))
93+
for tag_id in all_tag_ids:
94+
tag_def = tag_definitions.get(tag_id)
95+
db.add(Tag(id=tag_id, description=tag_def.description if tag_def else None))
96+
9397
db.flush()
9498

9599
for event_data in bundle.events:

backend/poetry.lock

Lines changed: 4 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ authors = [
77
]
88
license = "MIT"
99
readme = "README.md"
10-
requires-python = ">=3.9,<4"
10+
requires-python = ">=3.10,<4"
1111
dependencies = [
1212
"fastapi[all] (>=0.115.12,<0.116.0)",
1313
"sqlalchemy (>=2.0.40,<3.0.0)",

backend/tests/conftest.py

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,36 @@
99
from app.modules.auth.token import create_access_token
1010
from app.settings import Settings
1111

12-
# Load test settings from .env.test
13-
test_settings = Settings(_env_file=".env.test")
1412

15-
# Initialize DB objects for test (engine + SessionLocal)
16-
test_engine, TestingSessionLocal = init_db(test_settings)
13+
@pytest.fixture(scope="session")
14+
def test_settings():
15+
"""Session-scoped fixture for test settings, using a file-based SQLite DB."""
16+
settings = Settings(_env_file=".env.test")
17+
settings.database_url = "sqlite:///./test.db"
18+
return settings
19+
1720

18-
# Create the test app
19-
app = create_app(test_settings, TestingSessionLocal)
21+
@pytest.fixture(scope="session")
22+
def db_engine_session(test_settings: Settings):
23+
"""Session-scoped fixture for the database engine and session factory."""
24+
engine, session_local = init_db(test_settings)
25+
return engine, session_local
2026

2127

22-
# Override FastAPI's get_db dependency
2328
@pytest.fixture(scope="session")
24-
def override_get_db():
29+
def app(test_settings: Settings, db_engine_session):
30+
"""Session-scoped fixture for the FastAPI application instance."""
31+
_, session_local = db_engine_session
32+
return create_app(test_settings, session_local)
33+
34+
35+
@pytest.fixture(scope="session")
36+
def override_get_db(db_engine_session):
37+
"""Session-scoped fixture to override the `get_db` dependency."""
38+
_, session_local = db_engine_session
39+
2540
def _override_get_db():
26-
db: Session = TestingSessionLocal()
41+
db: Session = session_local()
2742
try:
2843
yield db
2944
finally:
@@ -32,13 +47,16 @@ def _override_get_db():
3247
return _override_get_db
3348

3449

35-
# Set up and tear down the database
3650
@pytest.fixture(scope="session", autouse=True)
37-
def setup_database(override_get_db):
38-
Base.metadata.create_all(bind=test_engine)
51+
def setup_database(app, db_engine_session, override_get_db):
52+
"""
53+
Session-scoped, autouse fixture to set up the database schema and dependency overrides.
54+
"""
55+
engine, _ = db_engine_session
56+
Base.metadata.create_all(bind=engine)
3957
app.dependency_overrides[get_db] = override_get_db
4058
yield
41-
Base.metadata.drop_all(bind=test_engine)
59+
Base.metadata.drop_all(bind=engine)
4260

4361

4462
@pytest.fixture(scope="session")
@@ -56,19 +74,20 @@ def test_user(override_get_db):
5674

5775
@pytest.fixture(scope="session")
5876
def access_token(test_user):
77+
"""Create an access token for the test user."""
5978
return create_access_token({"sub": str(test_user.email)})
6079

6180

62-
# FastAPI test client
6381
@pytest.fixture(scope="module")
64-
def client():
82+
def client(app):
83+
"""Module-scoped test client for unauthenticated requests."""
6584
with TestClient(app) as c:
6685
yield c
6786

6887

6988
@pytest.fixture
70-
def auth_client(access_token):
71-
# Create a fresh client for authenticated requests to avoid polluting the shared client
89+
def auth_client(app, access_token):
90+
"""Function-scoped test client for authenticated requests."""
7291
with TestClient(app) as auth_client:
7392
auth_client.headers.update({"Authorization": f"Bearer {access_token}"})
7493
yield auth_client

backend/tests/test_events.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
@pytest.fixture
77
def sample_event():
8-
"""Тестовое событие"""
98
return EventCreate(
109
name="Test Event",
1110
description="Some event description.",

frontend/src/modules/auth/components/LoginForm.vue

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,12 @@ const onSubmit = handleSubmit(values => runLogin(values))
6565
<FormItem>
6666
<FormLabel>Email</FormLabel>
6767
<FormControl>
68-
<Input type="email" placeholder="name@example.com" v-bind="componentField" />
68+
<Input
69+
type="email"
70+
placeholder="name@example.com"
71+
v-bind="componentField"
72+
autocomplete="email"
73+
/>
6974
</FormControl>
7075
<FormMessage />
7176
</FormItem>
@@ -76,7 +81,7 @@ const onSubmit = handleSubmit(values => runLogin(values))
7681
<FormItem>
7782
<FormLabel>Password</FormLabel>
7883
<FormControl>
79-
<Input type="password" v-bind="componentField" />
84+
<Input type="password" v-bind="componentField" autocomplete="current-password" />
8085
</FormControl>
8186
<FormMessage />
8287
</FormItem>

frontend/src/modules/auth/components/SignupForm.vue

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,12 @@ const onSubmit = handleSubmit(values => runSignup(values))
6868
<FormItem>
6969
<FormLabel>Email</FormLabel>
7070
<FormControl>
71-
<Input type="email" placeholder="name@example.com" v-bind="componentField" />
71+
<Input
72+
type="email"
73+
placeholder="name@example.com"
74+
v-bind="componentField"
75+
autocomplete="email"
76+
/>
7277
</FormControl>
7378
<FormMessage />
7479
</FormItem>
@@ -79,7 +84,7 @@ const onSubmit = handleSubmit(values => runSignup(values))
7984
<FormItem>
8085
<FormLabel>Password</FormLabel>
8186
<FormControl>
82-
<Input type="password" v-bind="componentField" />
87+
<Input type="password" v-bind="componentField" autocomplete="new-password" />
8388
</FormControl>
8489
<FormMessage />
8590
</FormItem>

frontend/src/modules/switchboard/components/ResetPanel.vue

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,11 @@ import { Button } from '@/shared/ui/button'
66
import { useEnhancedToast } from '@/shared/composables/useEnhancedToast'
77
import type { ResetPreview } from '../types'
88
import { Badge } from '@/shared/ui/badge'
9-
import { Icon } from '@iconify/vue'
109
1110
const queryClient = useQueryClient()
1211
const { showSuccess } = useEnhancedToast()
1312
14-
const {
15-
data: preview,
16-
isLoading: isFetching,
17-
refetch: fetchPreview,
18-
} = useQuery({
13+
const { data: preview } = useQuery({
1914
queryKey: ['resetPreview'],
2015
queryFn: () => resetDatabase(true),
2116
select: data => (data as ResetPreview).would_delete,
@@ -57,16 +52,6 @@ const { mutate: handleReset, isPending: isResetting } = useMutation({
5752
<span v-if="preview" :key="preview.tags">{{ preview.tags }} tags</span>
5853
</Transition>
5954
</Badge>
60-
<Button
61-
variant="ghost"
62-
size="icon"
63-
:disabled="isFetching"
64-
@click="fetchPreview"
65-
title="Refresh counts"
66-
>
67-
<Icon v-if="isFetching" icon="radix-icons:reload" class="h-4 w-4 animate-spin" />
68-
<Icon v-else icon="radix-icons:reload" class="h-4 w-4" />
69-
</Button>
7055
</div>
7156
</div>
7257
</template>

frontend/src/shared/composables/useAsyncTask.ts

Lines changed: 0 additions & 38 deletions
This file was deleted.

0 commit comments

Comments
 (0)