DEV Community

John Builds
John Builds

Posted on

A history field that reads live settings is not a history field

Last week I almost shipped an API field that was supposed to tell you what a generated post was written under: which topics the plan had at the time.

The implementation was one line. Look up the post's parent plan, return its topics, label the result recorded.

The plan's topics are user-editable. Change them in September and every post from August now reports September's topics as the ones it was written under. Nothing errors. The field rewrites history each time someone edits their settings.

Why the tests were green

Every test did the same thing: create a plan, create a post, read the field, assert the value. The settings never changed between the write and the read, so a live lookup and a stored fact returned identical output. The suite asserted the value and never the mechanism, which means it could not tell the two apart.

I had fixed this exact bug in the field next door earlier the same day, and written down why the tests missed it. Then a reviewer found it again one field over. My fix had been scoped to the field that got reported, and the blind spot belonged to the whole class.

What changed

  1. The field now returns not_recorded instead of guessing. We never stored the topics at creation time, so there is no honest answer. An empty answer routes people to a fallback. A wrong answer gets served as fact.
  2. The new test creates the post, then edits the plan's topics, then asserts the output did not move. Revert the fix and it goes red. That is the only kind of test that can see this bug.
  3. I went through every sibling field with one question: what mutable thing could change this value after the record was created?

If the answer to that question is "a settings page", you need a column written at creation time. A lookup is a claim that the two values will agree forever.

Top comments (0)