- 모던 다크 미니멀 테마(NanumSquare 번들, 단일 accent #4DABF7, 8px radius, flat 버튼, 다크 기본값) - 라인 아이콘 시스템(ui/icons.py, QtSvg) — 앱 전반 이모지 교체 - 다크 깨짐 수정: 테이블 헤더/코너 흰색, 도움말 탭 흰 라인, 트레이/미니위젯 메뉴 - fix: 자동 적립 OFF가 자동 퇴근 경로에서 무시되던 버그(게이팅) - feat: 연장근무 적립 기록 삭제(우클릭) - 테스트 3건 추가 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
73 lines
2.9 KiB
Python
73 lines
2.9 KiB
Python
"""연장근무 자동 적립 가드 테스트.
|
|
|
|
auto_overtime(자동 적립)가 OFF면, 자동 퇴근 경로(근무일 경계 롤오버 등)에서도
|
|
은행 적립을 하지 않아야 한다 — clock_out() 대화상자에서 '아니오'를 고른 것과 동일한 의미.
|
|
|
|
handle_workday_rollover는 위젯 의존이 tail(load_today_data/update_overtime_balance)뿐이라,
|
|
__new__로 만든 인스턴스에 필요한 속성만 채워 단위 테스트한다 (QApplication 불필요).
|
|
"""
|
|
import os
|
|
import sys
|
|
from datetime import datetime, timedelta, time as dtime
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from core.database import Database
|
|
from core.time_calculator import TimeCalculator
|
|
from ui.main_window import MainWindow
|
|
|
|
|
|
def _rollover_balance(db, monkeypatch):
|
|
"""어제 미퇴근 상태에서 근무일 경계 롤오버를 실행하고 적립 잔액을 반환."""
|
|
from PyQt5.QtWidgets import QMessageBox
|
|
monkeypatch.setattr(QMessageBox, 'information',
|
|
staticmethod(lambda *a, **k: QMessageBox.Ok))
|
|
|
|
today = datetime.now().date()
|
|
y = today - timedelta(days=1)
|
|
db.add_work_record(y.isoformat(), '09:00:00', is_manual=True) # 어제: 미퇴근
|
|
|
|
w = MainWindow.__new__(MainWindow) # __init__ 우회 (위젯/타이머 없음)
|
|
w.db = db
|
|
w.time_calc = TimeCalculator(work_minutes=480)
|
|
w.clock_in_time = datetime.combine(y, dtime(9, 0, 0))
|
|
w.is_clocked_in = True
|
|
w.midnight_rollover_handled = False
|
|
w.is_on_break = False
|
|
w.lunch_break_enabled = False
|
|
w.dinner_break_enabled = False
|
|
w.load_today_data = lambda: None # tail UI refresh stub
|
|
w.update_overtime_balance = lambda: None # tail UI refresh stub
|
|
|
|
w.handle_workday_rollover(datetime.combine(today, dtime(7, 0, 0)))
|
|
return db.get_total_overtime_balance()
|
|
|
|
|
|
def test_rollover_does_not_accrue_when_auto_overtime_off(tmp_path, monkeypatch):
|
|
db = Database(str(tmp_path / 'off.db'))
|
|
db.set_setting('auto_overtime', 'false')
|
|
assert _rollover_balance(db, monkeypatch) == 0
|
|
|
|
|
|
def test_rollover_accrues_when_auto_overtime_on(tmp_path, monkeypatch):
|
|
db = Database(str(tmp_path / 'on.db'))
|
|
db.set_setting('auto_overtime', 'true')
|
|
assert _rollover_balance(db, monkeypatch) > 0
|
|
|
|
|
|
def test_delete_overtime_earned_reduces_balance(tmp_path):
|
|
"""적립(은행) 기록 삭제 시 잔액이 그만큼 감소한다."""
|
|
from datetime import date
|
|
db = Database(str(tmp_path / 'del.db'))
|
|
today = date.today().isoformat()
|
|
db.add_overtime_earned(None, 90, today)
|
|
assert db.get_total_overtime_balance() == 90
|
|
|
|
bank_id = db.get_connection().execute(
|
|
'SELECT id FROM overtime_bank').fetchone()[0]
|
|
assert db.delete_overtime_earned(bank_id) is True
|
|
assert db.get_total_overtime_balance() == 0
|
|
|
|
# 없는 id 삭제는 False
|
|
assert db.delete_overtime_earned(999999) is False
|