From 53c1817956bdceaee83f9ffe57b1c5297b6a4204 Mon Sep 17 00:00:00 2001 From: ThomasV Date: Wed, 17 Sep 2025 14:42:54 +0200 Subject: [PATCH] tests/test_jsondb.py: add tests that replace a StoredDict element after its parent has been removed. Related: #10000 --- tests/test_jsondb.py | 49 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/test_jsondb.py b/tests/test_jsondb.py index 16129e114..eeaf41079 100644 --- a/tests/test_jsondb.py +++ b/tests/test_jsondb.py @@ -1,6 +1,7 @@ import contextlib import copy import traceback +import json import jsonpatch from jsonpatch import JsonPatchException @@ -8,6 +9,7 @@ from jsonpointer import JsonPointerException from . import ElectrumTestCase +from electrum.json_db import JsonDB class TestJsonpatch(ElectrumTestCase): @@ -84,3 +86,50 @@ class TestJsonpatch(ElectrumTestCase): with self._customAssertRaises(JsonPointerException) as ctx: data2 = jpatch.apply(data1) fail_if_leaking_secret(ctx) + + +class TestJsonDB(ElectrumTestCase): + + async def test_jsonpatch_replace_after_remove(self): + data = { 'a':{} } + # op "add" + patches = [{"op": "add", "path": "/a/b", "value": "42"}] + jpatch = jsonpatch.JsonPatch(patches) + data = jpatch.apply(data) + # remove + patches = [{"op": "remove", "path": "/a/b"}] + jpatch = jsonpatch.JsonPatch(patches) + data = jpatch.apply(data) + # replace + patches = [{"op": "replace", "path": "/a/b", "value": "43"}] + jpatch = jsonpatch.JsonPatch(patches) + with self.assertRaises(JsonPatchException): + data = jpatch.apply(data) + + async def test_jsondb_replace_after_remove(self): + data = { 'a': {'b': {'c': 0}}} + db = JsonDB(repr(data)) + a = db.get_dict('a') + # remove + b = a.pop('b') + self.assertEqual(len(db.pending_changes), 1) + # replace item. this must not been written to db + b['c'] = 42 + self.assertEqual(len(db.pending_changes), 1) + patches = json.loads('[' + ','.join(db.pending_changes) + ']') + jpatch = jsonpatch.JsonPatch(patches) + data = jpatch.apply(data) + + async def test_jsondb_replace_after_remove_nested(self): + data = { 'a': {'b':{'c':0}}} + db = JsonDB(repr(data)) + # remove + a = db.data.pop('a') + self.assertEqual(len(db.pending_changes), 1) + b = a['b'] + # replace item. this must not be written to db + b['c'] = 42 + self.assertEqual(len(db.pending_changes), 1) + patches = json.loads('[' + ','.join(db.pending_changes) + ']') + jpatch = jsonpatch.JsonPatch(patches) + data = jpatch.apply(data)