test(helpers): setSystemSettingRestored — leave shared settings as found

The testuser-experience rule: the suite must leave shared settings
exactly as it found them. setSystemSettingRestored snapshots the prior
system_settings row, writes through the sanctioned API path (the only
one that reloads the settings registry — raw SQL leaves the cache
stale), and registers a cleanup restoring what WAS there, never a
hardcoded value.

setExtractorVersion now rides it, so the ev-pin tests no longer
restore scan_extractor_version to a hardcoded 1: a deliberate dev bump
of the extractor version survives a suite run instead of being
silently cancelled (the live dev server obeys that setting on its next
poll and would stop re-extracting parser fixes). The now-redundant
explicit t.Cleanup restores are removed from
TestExtractorVersionReextract and pinExtractorVersionOne.
This commit is contained in:
John O'Keefe committed 2026-10-21 20:24:44 -04:00
1 parent f62b46fb15
commit 3ed852515b
3 files changed
+60 -14

No files matched your search

+49
View File
@@ -25,6 +25,7 @@ import (
"github.com/go-playground/validator/v10"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgtype"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/labstack/echo/v5"
@@ -181,6 +182,54 @@ func getUploadPath() string {
return "./uploads" // Host path (left side of volume mount)
}
// setSystemSettingRestored writes a system setting through the sanctioned
// API path and registers a cleanup that restores the value the row had
// BEFORE the write. The testuser-experience rule: the suite must leave
// shared settings exactly as it found them — a hardcoded restore would
// silently clobber a deliberate dev bump (e.g. scan_extractor_version
// pinned mid-deploy), and the live dev server obeys this setting on its
// next poll, so what tests write here reaches real scans.
//
// Writes ride the settings API (never raw SQL) because the registry
// caches values and only the API path reloads it. If the row did not
// exist before the write, the test value is left in place and the test
// log says so — there is no sanctioned delete; settings rows that
// matter (scan_extractor_version) always exist.
func setSystemSettingRestored(t *testing.T, setup *TestServerSetup, key, value string) {
t.Helper()
var prior *string
err := setup.DBPool.QueryRow(context.Background(),
`SELECT setting_value FROM system_settings WHERE setting_key = $1`, key).Scan(&prior)
if err != nil && err != pgx.ErrNoRows {
require.NoError(t, err, "failed to read prior value of %s", key)
}
setSettingViaAPI(t, setup, key, value)
if prior == nil {
t.Logf("setSystemSettingRestored: %s had no prior row; leaving %q in place after the test", key, value)
return
}
priorValue := *prior
t.Cleanup(func() {
setSettingViaAPI(t, setup, key, priorValue)
})
}
// setSettingViaAPI PUTs one setting through /api/system/settings — the
// only sanctioned write path (the settings registry reloads here).
func setSettingViaAPI(t *testing.T, setup *TestServerSetup, key, value string) {
t.Helper()
body, _ := json.Marshal(map[string]string{"key": key, "value": value})
req, _ := http.NewRequest("PUT", setup.Server.URL+"/api/system/settings", bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+setup.Token)
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
defer func() { _ = resp.Body.Close() }()
require.Equal(t, http.StatusOK, resp.StatusCode, "settings API is the only sanctioned write path")
}
// getCachePath returns the appropriate cache path based on runtime environment
func getCachePath() string {
// Check for explicit override first