bump project

This commit is contained in:
2026-05-01 21:24:21 +03:30
parent dc4b1a1400
commit 139b3e26da
83 changed files with 2455 additions and 18349 deletions

49
tests/conftest.py Normal file
View File

@@ -0,0 +1,49 @@
from __future__ import annotations
import pytest
from app import create_app
from app.extensions import db
from app.models import Account, Role
@pytest.fixture()
def app():
app = create_app(
"testing",
{
"SECRET_KEY": "test-secret",
"SQLALCHEMY_DATABASE_URI": "sqlite:///:memory:",
},
)
with app.app_context():
db.create_all()
yield app
db.session.remove()
db.drop_all()
@pytest.fixture()
def client(app):
return app.test_client()
def create_account(username: str = "admin", role: str = Role.ADMIN.value) -> Account:
account = Account(
username=username,
email=f"{username}@example.com",
full_name=username.title(),
role=role,
)
account.set_password("Password12345")
db.session.add(account)
db.session.commit()
return account
def login(client, username: str = "admin", password: str = "Password12345"):
return client.post(
"/auth/login",
data={"username": username, "password": password},
follow_redirects=True,
)

44
tests/test_attendance.py Normal file
View File

@@ -0,0 +1,44 @@
from __future__ import annotations
from app.extensions import db
from app.models import AttendanceEvent, AttendanceType, Person, Role
from tests.conftest import create_account, login
def test_operator_can_record_attendance(app, client):
with app.app_context():
create_account(username="operator", role=Role.OPERATOR.value)
person = Person(full_name="Ada Lovelace", employee_id="EMP-001")
db.session.add(person)
db.session.commit()
person_id = person.id
login(client, "operator")
response = client.post(
"/attendance/events",
data={"person_id": person_id, "event_type": AttendanceType.CHECK_IN.value},
headers={"Accept": "application/json"},
)
assert response.status_code == 200
assert response.get_json()["event_type"] == "Check in"
with app.app_context():
assert AttendanceEvent.query.count() == 1
def test_viewer_cannot_record_attendance(app, client):
with app.app_context():
create_account(username="viewer", role=Role.VIEWER.value)
person = Person(full_name="Grace Hopper", employee_id="EMP-002")
db.session.add(person)
db.session.commit()
person_id = person.id
login(client, "viewer")
response = client.post(
"/attendance/events",
data={"person_id": person_id, "event_type": AttendanceType.CHECK_OUT.value},
headers={"Accept": "application/json"},
)
assert response.status_code == 403

55
tests/test_auth.py Normal file
View File

@@ -0,0 +1,55 @@
from __future__ import annotations
from app.models import Account, Role
from tests.conftest import create_account, login
def test_passwords_are_hashed(app):
with app.app_context():
account = create_account()
assert account.password_hash != "Password12345"
assert account.check_password("Password12345")
def test_login_redirects_to_dashboard(app, client):
with app.app_context():
create_account()
response = login(client)
assert response.status_code == 200
assert b"Dashboard" in response.data
def test_admin_can_create_operator_account(app, client):
with app.app_context():
create_account()
login(client)
response = client.post(
"/admin/accounts/new",
data={
"full_name": "Operations User",
"username": "operator",
"email": "operator@example.com",
"role": Role.OPERATOR.value,
"password": "Password12345",
"confirm_password": "Password12345",
},
follow_redirects=True,
)
assert response.status_code == 200
with app.app_context():
account = Account.query.filter_by(username="operator").one()
assert account.role == Role.OPERATOR.value
def test_operator_cannot_manage_accounts(app, client):
with app.app_context():
create_account(username="operator", role=Role.OPERATOR.value)
login(client, "operator")
response = client.get("/admin/accounts")
assert response.status_code == 403