3
0
Fork 0

fix: render human-friendly datetime for such fields in version diff

still render the "raw" value but include human-friendly for convenience
This commit is contained in:
Lance Edgar 2026-03-14 16:19:17 -05:00
parent 6f26120640
commit d08ba5fe51
2 changed files with 119 additions and 5 deletions

View file

@ -1,5 +1,14 @@
# -*- coding: utf-8; -*-
import datetime
import re
from unittest.mock import patch
import sqlalchemy as sa
from sqlalchemy import orm
from wuttjamaican.util import get_timezone_by_name
from wuttaweb import diffs as mod
from wuttaweb.testing import WebTestCase, VersionWebTestCase
@ -70,7 +79,7 @@ class TestVersionDiff(VersionWebTestCase):
["active", "person_uuid", "prevent_edit", "username", "uuid"],
)
def test_render_version_value(self):
def test_render_version_value_with_objref(self):
import sqlalchemy_continuum as continuum
model = self.app.model
@ -130,3 +139,91 @@ class TestVersionDiff(VersionWebTestCase):
self.assertIn(str(person.uuid), html)
self.assertIn("Fred Flintstone", html)
self.assertEqual(diff.render_new_value("person_uuid"), "")
def test_render_version_value_with_datetime(self):
import sqlalchemy_continuum as continuum
tzlocal = get_timezone_by_name("America/Los_Angeles")
with patch.object(self.app, "get_timezone", return_value=tzlocal):
# make one person
model = self.app.model
person = model.Person(full_name="Fred Flintstone")
self.session.add(person)
self.session.commit()
# get its one version record
txncls = continuum.transaction_class(model.Person)
vercls = continuum.version_class(model.Person)
version = self.session.query(vercls).order_by(vercls.transaction_id).one()
# make a diff, but we have to mock some things up for the test
# coverage, since we don't currently have a versioned datetime
# field in the base model.
diff = self.make_diff(version)
mock_column = sa.Column("timestamp", sa.DateTime())
mock_property = orm.ColumnProperty(column=mock_column)
class MockMapper:
def __init__(self, mapper):
self.mapper = mapper
def __getattr__(self, name):
if hasattr(self.mapper, name):
return getattr(self.mapper, name)
raise AttributeError(f"attr not found: {name}")
def has_property(self, field):
if field == "timestamp":
return True
return self.mapper.has_property(field)
def get_property(self, field):
if field == "timestamp":
return mock_property
return self.mapper.get_property(field)
mock_mapper = MockMapper(diff.mapper)
with patch.object(diff, "mapper", new=mock_mapper):
# zone-aware local time
dt = datetime.datetime(2026, 3, 14, 14, 0, tzinfo=tzlocal)
html = diff.render_version_value(version, "timestamp", dt)
self.assertTrue(
re.search(
r'<span style="[^"]+"><span title="[^"]+">\d{4}-\d{2}-\d{2} \d{2}:\d{2}-\d{4}</span></span>',
html,
)
)
self.assertTrue(
re.search(
r'<span style="[^"]+"><span title="[^"]+">2026-03-14 14:00-0700</span></span>',
html,
)
)
# zone-naive (presumed UTC)
dt = datetime.datetime(2026, 3, 14, 21, 0)
html = diff.render_version_value(version, "timestamp", dt)
self.assertTrue(
re.search(
r'<span style="[^"]+"><span title="[^"]+">\d{4}-\d{2}-\d{2} \d{2}:\d{2}-\d{4}</span></span>',
html,
)
)
self.assertTrue(
re.search(
r'<span style="[^"]+"><span title="[^"]+">2026-03-14 14:00-0700</span></span>',
html,
)
)
# null
html = diff.render_version_value(version, "timestamp", None)
self.assertFalse(
re.search(
r'<span style="[^"]+"><span title="[^"]+">\d{4}-\d{2}-\d{2} \d{2}:\d{2}-\d{4}</span></span>',
html,
)
)