Initial project import
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from services.storage.database_storage import (
|
||||
AccountModel,
|
||||
AuthKeyModel,
|
||||
DatabaseStorageBackend,
|
||||
)
|
||||
|
||||
|
||||
def _account_rows(backend: DatabaseStorageBackend) -> dict[str, AccountModel]:
|
||||
session = backend.Session()
|
||||
try:
|
||||
return {
|
||||
row.access_token: row
|
||||
for row in session.query(AccountModel).order_by(AccountModel.id).all()
|
||||
}
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
|
||||
def test_save_accounts_preserves_existing_rows_and_updates_only_changed_data(tmp_path):
|
||||
backend = DatabaseStorageBackend(f"sqlite:///{tmp_path / 'accounts.db'}")
|
||||
backend.save_accounts(
|
||||
[
|
||||
{"access_token": "token-a", "name": "A"},
|
||||
{"access_token": "token-b", "name": "B"},
|
||||
]
|
||||
)
|
||||
|
||||
before = _account_rows(backend)
|
||||
before_ids = {token: row.id for token, row in before.items()}
|
||||
before_b_data = before["token-b"].data
|
||||
|
||||
backend.save_accounts(
|
||||
[
|
||||
{"access_token": "token-b", "name": "B"},
|
||||
{"access_token": "token-a", "name": "A updated"},
|
||||
{"access_token": "token-c", "name": "C"},
|
||||
]
|
||||
)
|
||||
|
||||
after = _account_rows(backend)
|
||||
assert set(after) == {"token-a", "token-b", "token-c"}
|
||||
assert after["token-a"].id == before_ids["token-a"]
|
||||
assert after["token-b"].id == before_ids["token-b"]
|
||||
assert after["token-b"].data == before_b_data
|
||||
assert json.loads(after["token-a"].data)["name"] == "A updated"
|
||||
|
||||
|
||||
def test_save_accounts_deletes_only_rows_missing_from_new_snapshot(tmp_path):
|
||||
backend = DatabaseStorageBackend(f"sqlite:///{tmp_path / 'accounts.db'}")
|
||||
backend.save_accounts(
|
||||
[
|
||||
{"access_token": "token-a", "name": "A"},
|
||||
{"access_token": "token-b", "name": "B"},
|
||||
]
|
||||
)
|
||||
before = _account_rows(backend)
|
||||
token_b_id = before["token-b"].id
|
||||
|
||||
backend.save_accounts([{"access_token": "token-b", "name": "B"}])
|
||||
|
||||
after = _account_rows(backend)
|
||||
assert set(after) == {"token-b"}
|
||||
assert after["token-b"].id == token_b_id
|
||||
|
||||
|
||||
def test_save_accounts_rejects_duplicate_tokens_and_rolls_back(tmp_path):
|
||||
backend = DatabaseStorageBackend(f"sqlite:///{tmp_path / 'accounts.db'}")
|
||||
original = {"access_token": "token-a", "name": "A"}
|
||||
backend.save_accounts([original])
|
||||
|
||||
with pytest.raises(ValueError, match="Duplicate access_token") as exc_info:
|
||||
backend.save_accounts(
|
||||
[
|
||||
{"access_token": "token-a", "name": "first update"},
|
||||
{"access_token": "token-a", "name": "second update"},
|
||||
]
|
||||
)
|
||||
|
||||
assert "token-a" not in str(exc_info.value)
|
||||
assert backend.load_accounts() == [original]
|
||||
|
||||
|
||||
def test_save_accounts_rejects_duplicate_new_tokens_and_rolls_back(tmp_path):
|
||||
backend = DatabaseStorageBackend(f"sqlite:///{tmp_path / 'accounts.db'}")
|
||||
original = {"access_token": "token-a", "name": "A"}
|
||||
backend.save_accounts([original])
|
||||
|
||||
with pytest.raises(ValueError, match="Duplicate access_token") as exc_info:
|
||||
backend.save_accounts(
|
||||
[
|
||||
original,
|
||||
{"access_token": "token-b", "name": "first new"},
|
||||
{"access_token": "token-b", "name": "second new"},
|
||||
]
|
||||
)
|
||||
|
||||
assert "token-b" not in str(exc_info.value)
|
||||
assert backend.load_accounts() == [original]
|
||||
|
||||
|
||||
def test_save_auth_keys_preserves_ids_with_target_key_mapping(tmp_path):
|
||||
backend = DatabaseStorageBackend(f"sqlite:///{tmp_path / 'auth-keys.db'}")
|
||||
backend.save_auth_keys(
|
||||
[
|
||||
{"id": "key-a", "name": "A"},
|
||||
{"id": "key-b", "name": "B"},
|
||||
]
|
||||
)
|
||||
|
||||
session = backend.Session()
|
||||
try:
|
||||
before_ids = {
|
||||
row.key_id: row.id
|
||||
for row in session.query(AuthKeyModel).order_by(AuthKeyModel.id).all()
|
||||
}
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
backend.save_auth_keys(
|
||||
[
|
||||
{"id": "key-b", "name": "B"},
|
||||
{"id": "key-a", "name": "A updated"},
|
||||
{"id": "key-c", "name": "C"},
|
||||
]
|
||||
)
|
||||
|
||||
session = backend.Session()
|
||||
try:
|
||||
after = {
|
||||
row.key_id: row
|
||||
for row in session.query(AuthKeyModel).order_by(AuthKeyModel.id).all()
|
||||
}
|
||||
assert set(after) == {"key-a", "key-b", "key-c"}
|
||||
assert after["key-a"].id == before_ids["key-a"]
|
||||
assert after["key-b"].id == before_ids["key-b"]
|
||||
assert json.loads(after["key-a"].data)["name"] == "A updated"
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
|
||||
def test_save_auth_keys_rejects_duplicate_ids_and_rolls_back(tmp_path):
|
||||
backend = DatabaseStorageBackend(f"sqlite:///{tmp_path / 'auth-keys.db'}")
|
||||
original = {"id": "key-a", "name": "A"}
|
||||
backend.save_auth_keys([original])
|
||||
|
||||
with pytest.raises(ValueError, match="Duplicate id") as exc_info:
|
||||
backend.save_auth_keys(
|
||||
[
|
||||
{"id": "key-a", "name": "first update"},
|
||||
{"id": "key-a", "name": "second update"},
|
||||
]
|
||||
)
|
||||
|
||||
assert "key-a" not in str(exc_info.value)
|
||||
assert backend.load_auth_keys() == [original]
|
||||
Reference in New Issue
Block a user