Watch history - fix for restock.previous_price returns the first-ever price once a watch has 3+ snapshots

This commit is contained in:
dgtlmoon
2026-07-22 09:52:08 +02:00
parent 71d332d5a0
commit d9e00e5041
2 changed files with 22 additions and 2 deletions
@@ -115,10 +115,13 @@ class Watch(BaseWatch):
history = self.history
if history and len(history) >=2:
"""Unfortunately for now timestamp is stored as string key"""
# Keys are stored oldest-first (ascending). worker.py saves the new snapshot
# BEFORE sending the notification, so the newest key ([-1]) is the current check
# and the previous check is the second-newest ([-2]). Guaranteed to exist here
# because len(history) >= 2.
sorted_keys = sorted(list(history), key=lambda x: int(x))
sorted_keys.reverse()
price_str = self.get_history_snapshot(timestamp=sorted_keys[-1])
price_str = self.get_history_snapshot(timestamp=sorted_keys[-2])
if price_str:
values['restock']['previous_price'] = get_price_from_history_str(price_str)
return values
@@ -405,6 +405,23 @@ def test_change_with_notification_values(client, live_server, measure_memory_usa
assert "title new price 1950.45" in notification
assert "previous price 960.45" in notification
# Regression for #4260: with 3+ snapshots, {{restock.previous_price}} must report the price at
# the PREVIOUS check (1950.45), not the first-ever price in history (960.45). Before the fix the
# newest-first history list was indexed at [-1] (the oldest snapshot), so from the 3rd check on
# this was stuck on the first price ever recorded. The two-snapshot case above passed only by
# coincidence (with two entries the oldest snapshot IS the previous check).
os.unlink(os.path.join(datastore_path, "notification.txt"))
set_original_response(props_markup=instock_props[0], price='2500.45', datastore_path=datastore_path)
client.get(url_for("ui.form_watch_checknow"))
wait_for_all_checks(client)
wait_for_notification_endpoint_output(datastore_path=datastore_path)
assert os.path.isfile(os.path.join(datastore_path, "notification.txt")), "Notification received"
with open(os.path.join(datastore_path, "notification.txt"), 'r') as f:
notification = f.read()
assert "new price 2500.45" in notification
assert "previous price 1950.45" in notification # the actual previous check
assert "previous price 960.45" not in notification # the pre-fix bug (first-ever price)
## Now test the "SEND TEST NOTIFICATION" is working
os.unlink(os.path.join(datastore_path, "notification.txt"))
uuid = next(iter(live_server.app.config['DATASTORE'].data['watching']))