Update projektu
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
SCRIPTS = Path(__file__).parent.parent / "scripts"
|
||||
@@ -8,6 +8,7 @@ sys.path.insert(0, str(SCRIPTS))
|
||||
|
||||
from db import get_db, init_db
|
||||
import remind_cli
|
||||
import store
|
||||
|
||||
|
||||
def _run(db_path, argv):
|
||||
@@ -22,6 +23,19 @@ def _run(db_path, argv):
|
||||
remind_cli.DB_PATH = original_db_path
|
||||
|
||||
|
||||
def _seed_duplicate(db_path, text, cron):
|
||||
"""Insert a reminder directly via store, bypassing the CLI duplicate guard.
|
||||
|
||||
Used to construct pre-existing duplicate texts that the disambiguation code
|
||||
(`--id`, ambiguous keyword) must still handle even though `add` now blocks them.
|
||||
"""
|
||||
with store.transaction(db_path) as conn:
|
||||
now = datetime.now(timezone.utc).isoformat(timespec="seconds")
|
||||
rid = store.insert_reminder(conn, text, now)
|
||||
store.insert_schedules(conn, rid, None, [cron], None)
|
||||
return rid
|
||||
|
||||
|
||||
def test_add_list(tmp_path, capsys):
|
||||
db_path = tmp_path / "test.sqlite"
|
||||
init_db(db_path)
|
||||
@@ -193,12 +207,65 @@ def test_add_random_validation(tmp_path, capsys):
|
||||
assert "window" in captured.err.lower() or "gap" in captured.err.lower()
|
||||
|
||||
|
||||
def test_add_rejects_duplicate_text(tmp_path, capsys):
|
||||
db_path = tmp_path / "test.sqlite"
|
||||
init_db(db_path)
|
||||
|
||||
ret = _run(db_path, ["add", "--text", "call mom", "--at", "2026-12-01T08:00:00"])
|
||||
capsys.readouterr()
|
||||
assert ret == 0
|
||||
|
||||
ret = _run(db_path, ["add", "--text", "call mom", "--at", "2026-12-01T20:00:00"])
|
||||
captured = capsys.readouterr()
|
||||
assert ret == 1
|
||||
err = json.loads(captured.err)
|
||||
assert err["error"] == "duplicate text"
|
||||
assert err["display_id"] == 1
|
||||
|
||||
# The first reminder is untouched — no second record was created.
|
||||
ret = _run(db_path, ["list"])
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out.count("call mom") == 1
|
||||
|
||||
|
||||
def test_add_duplicate_case_and_diacritics_insensitive(tmp_path, capsys):
|
||||
db_path = tmp_path / "test.sqlite"
|
||||
init_db(db_path)
|
||||
|
||||
_run(db_path, ["add", "--text", "Čaj", "--cron", "0 9 * * *"])
|
||||
capsys.readouterr()
|
||||
|
||||
ret = _run(db_path, ["add", "--text", " čaj ", "--cron", "0 10 * * *"])
|
||||
captured = capsys.readouterr()
|
||||
assert ret == 1
|
||||
assert json.loads(captured.err)["error"] == "duplicate text"
|
||||
|
||||
|
||||
def test_edit_text_collision_rejected(tmp_path, capsys):
|
||||
db_path = tmp_path / "test.sqlite"
|
||||
init_db(db_path)
|
||||
|
||||
_run(db_path, ["add", "--text", "buy milk", "--cron", "0 9 * * *"])
|
||||
_run(db_path, ["add", "--text", "buy bread", "--cron", "0 10 * * *"])
|
||||
capsys.readouterr()
|
||||
|
||||
ret = _run(db_path, ["edit", "--id", "2", "--text", "buy milk"])
|
||||
captured = capsys.readouterr()
|
||||
assert ret == 1
|
||||
assert json.loads(captured.err)["error"] == "duplicate text"
|
||||
|
||||
# Editing a reminder's text to itself (no real change) must still work.
|
||||
ret = _run(db_path, ["edit", "--id", "1", "--text", "buy milk"])
|
||||
captured = capsys.readouterr()
|
||||
assert ret == 0
|
||||
|
||||
|
||||
def test_remove_by_id_disambiguates_duplicates(tmp_path, capsys):
|
||||
db_path = tmp_path / "test.sqlite"
|
||||
init_db(db_path)
|
||||
|
||||
_run(db_path, ["add", "--text", "drink water", "--cron", "0 9 * * *"])
|
||||
_run(db_path, ["add", "--text", "drink water", "--cron", "0 10 * * *"])
|
||||
_seed_duplicate(db_path, "drink water", "0 10 * * *")
|
||||
capsys.readouterr()
|
||||
|
||||
ret = _run(db_path, ["remove", "--keyword", "drink water"])
|
||||
@@ -261,7 +328,7 @@ def test_ambiguous_keyword_returns_display_ids(tmp_path, capsys):
|
||||
init_db(db_path)
|
||||
|
||||
_run(db_path, ["add", "--text", "drink water", "--cron", "0 9 * * *"])
|
||||
_run(db_path, ["add", "--text", "drink water", "--cron", "0 10 * * *"])
|
||||
_seed_duplicate(db_path, "drink water", "0 10 * * *")
|
||||
capsys.readouterr()
|
||||
|
||||
ret = _run(db_path, ["remove", "--keyword", "drink"])
|
||||
|
||||
Reference in New Issue
Block a user