mirror of
https://github.com/elisiariocouto/leggen.git
synced 2025-12-14 08:32:33 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8228974c0c | ||
|
|
848eccb35b | ||
|
|
25747d7d37 |
26
CHANGELOG.md
26
CHANGELOG.md
@@ -1,4 +1,30 @@
|
|||||||
|
|
||||||
|
## 2025.9.17 (2025/09/18)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- **api:** Prevent duplicate notifications for existing transactions during sync. ([25747d7d](https://github.com/elisiariocouto/leggen/commit/25747d7d372e291090764a6814f9d8d0b76aea3b))
|
||||||
|
|
||||||
|
|
||||||
|
### Miscellaneous Tasks
|
||||||
|
|
||||||
|
- Format files. ([848eccb3](https://github.com/elisiariocouto/leggen/commit/848eccb35b910c8121d15611547dca8da0b12756))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 2025.9.17 (2025/09/18)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- **api:** Prevent duplicate notifications for existing transactions during sync. ([25747d7d](https://github.com/elisiariocouto/leggen/commit/25747d7d372e291090764a6814f9d8d0b76aea3b))
|
||||||
|
|
||||||
|
|
||||||
|
### Miscellaneous Tasks
|
||||||
|
|
||||||
|
- Format files. ([848eccb3](https://github.com/elisiariocouto/leggen/commit/848eccb35b910c8121d15611547dca8da0b12756))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 2025.9.16 (2025/09/18)
|
## 2025.9.16 (2025/09/18)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -857,6 +857,14 @@ class DatabaseService:
|
|||||||
|
|
||||||
for transaction in transactions:
|
for transaction in transactions:
|
||||||
try:
|
try:
|
||||||
|
# Check if transaction already exists before insertion
|
||||||
|
cursor.execute(
|
||||||
|
"""SELECT COUNT(*) FROM transactions
|
||||||
|
WHERE accountId = ? AND transactionId = ?""",
|
||||||
|
(transaction["accountId"], transaction["transactionId"]),
|
||||||
|
)
|
||||||
|
exists = cursor.fetchone()[0] > 0
|
||||||
|
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
insert_sql,
|
insert_sql,
|
||||||
(
|
(
|
||||||
@@ -873,7 +881,11 @@ class DatabaseService:
|
|||||||
json.dumps(transaction["rawTransaction"]),
|
json.dumps(transaction["rawTransaction"]),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
new_transactions.append(transaction)
|
|
||||||
|
# Only add to new_transactions if it didn't exist before
|
||||||
|
if not exists:
|
||||||
|
new_transactions.append(transaction)
|
||||||
|
|
||||||
except sqlite3.IntegrityError as e:
|
except sqlite3.IntegrityError as e:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"Failed to insert transaction {transaction.get('transactionId')}: {e}"
|
f"Failed to insert transaction {transaction.get('transactionId')}: {e}"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "leggen"
|
name = "leggen"
|
||||||
version = "2025.9.16"
|
version = "2025.9.17"
|
||||||
description = "An Open Banking CLI"
|
description = "An Open Banking CLI"
|
||||||
authors = [{ name = "Elisiário Couto", email = "elisiario@couto.io" }]
|
authors = [{ name = "Elisiário Couto", email = "elisiario@couto.io" }]
|
||||||
requires-python = "~=3.13.0"
|
requires-python = "~=3.13.0"
|
||||||
|
|||||||
@@ -324,6 +324,8 @@ class TestDatabaseService:
|
|||||||
with patch("sqlite3.connect") as mock_connect:
|
with patch("sqlite3.connect") as mock_connect:
|
||||||
mock_conn = mock_connect.return_value
|
mock_conn = mock_connect.return_value
|
||||||
mock_cursor = mock_conn.cursor.return_value
|
mock_cursor = mock_conn.cursor.return_value
|
||||||
|
# Mock fetchone to return (0,) indicating transaction doesn't exist yet
|
||||||
|
mock_cursor.fetchone.return_value = (0,)
|
||||||
|
|
||||||
result = await database_service._persist_transactions_sqlite(
|
result = await database_service._persist_transactions_sqlite(
|
||||||
"test-account-123", sample_transactions_db_format
|
"test-account-123", sample_transactions_db_format
|
||||||
@@ -338,6 +340,29 @@ class TestDatabaseService:
|
|||||||
mock_conn.commit.assert_called_once()
|
mock_conn.commit.assert_called_once()
|
||||||
mock_conn.close.assert_called_once()
|
mock_conn.close.assert_called_once()
|
||||||
|
|
||||||
|
async def test_persist_transactions_sqlite_duplicate_detection(
|
||||||
|
self, database_service, sample_transactions_db_format
|
||||||
|
):
|
||||||
|
"""Test that existing transactions are not returned as new."""
|
||||||
|
with patch("sqlite3.connect") as mock_connect:
|
||||||
|
mock_conn = mock_connect.return_value
|
||||||
|
mock_cursor = mock_conn.cursor.return_value
|
||||||
|
# Mock fetchone to return (1,) indicating transaction already exists
|
||||||
|
mock_cursor.fetchone.return_value = (1,)
|
||||||
|
|
||||||
|
result = await database_service._persist_transactions_sqlite(
|
||||||
|
"test-account-123", sample_transactions_db_format
|
||||||
|
)
|
||||||
|
|
||||||
|
# Should return empty list since all transactions already exist
|
||||||
|
assert len(result) == 0
|
||||||
|
|
||||||
|
# Verify database operations still happened (INSERT OR REPLACE executed)
|
||||||
|
mock_connect.assert_called()
|
||||||
|
mock_cursor.execute.assert_called()
|
||||||
|
mock_conn.commit.assert_called_once()
|
||||||
|
mock_conn.close.assert_called_once()
|
||||||
|
|
||||||
async def test_persist_transactions_sqlite_error(self, database_service):
|
async def test_persist_transactions_sqlite_error(self, database_service):
|
||||||
"""Test handling error during transaction persistence."""
|
"""Test handling error during transaction persistence."""
|
||||||
with patch("sqlite3.connect") as mock_connect:
|
with patch("sqlite3.connect") as mock_connect:
|
||||||
|
|||||||
2
uv.lock
generated
2
uv.lock
generated
@@ -220,7 +220,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leggen"
|
name = "leggen"
|
||||||
version = "2025.9.16"
|
version = "2025.9.17"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "apscheduler" },
|
{ name = "apscheduler" },
|
||||||
|
|||||||
Reference in New Issue
Block a user