A CPV code is now stored once, keeping its longest description

This commit is contained in:
bwilliams committed 2026-10-22 09:56:01 +01:00
1 parent b0f93fd437
commit 0a777792d8
5 files changed
+209 -8

No files matched your search

+75
View File
@@ -327,3 +327,78 @@ func TestFailedMigrationIsRolledBack(t *testing.T) {
t.Errorf("failed migration left %d objects behind", indexes)
}
}
// Migration 10 merges each CPV code's rows into the one with the longest
// description, moving the links to it (one link if an opportunity had both),
// and leaves other schemes' rows alone.
func TestMigration10MergesCPVDuplicates(t *testing.T) {
ctx := context.Background()
m, db := newMigrator(t)
if _, err := m.UpTo(ctx, 9); err != nil {
t.Fatal(err)
}
const full = "Petroleum products, fuel, electricity and other sources of energy"
setup := []string{
`INSERT INTO opportunities (uuid, uuid_type, title, status, latest_release_date)
VALUES ('a', 'ocid', 'A', 'active', '2026-10-01'),
('b', 'ocid', 'B', 'active', '2026-10-01')`,
`INSERT INTO classification_codes (id, is_cpv, code, classification) VALUES
(1, 1, '09000000', '` + full + `'),
(2, 1, '09000000', '` + full[:64] + `'),
(3, 0, '123', 'Scheme X'),
(4, 0, '123', 'Scheme X, amended')`,
// a links to both CPV rows, b only to the cut one.
`INSERT INTO opportunity_classifications VALUES
('a', 1), ('a', 2), ('b', 2), ('a', 3), ('b', 4)`,
}
for _, statement := range setup {
if _, err := db.ExecContext(ctx, statement); err != nil {
t.Fatal(err)
}
}
if _, err := m.UpTo(ctx, 10); err != nil {
t.Fatal(err)
}
var codes []string
rows, err := db.QueryContext(ctx,
`SELECT id || ':' || classification FROM classification_codes ORDER BY id`)
if err != nil {
t.Fatal(err)
}
for rows.Next() {
var code string
rows.Scan(&code)
codes = append(codes, code)
}
rows.Close()
want := "1:" + full + "|3:Scheme X|4:Scheme X, amended"
if got := strings.Join(codes, "|"); got != want {
t.Errorf("codes = %s; want %s", got, want)
}
var links []string
rows, err = db.QueryContext(ctx, `SELECT opportunity_uuid || classification_id
FROM opportunity_classifications ORDER BY 1`)
if err != nil {
t.Fatal(err)
}
for rows.Next() {
var link string
rows.Scan(&link)
links = append(links, link)
}
rows.Close()
if got := strings.Join(links, ","); got != "a1,a3,b1,b4" {
t.Errorf("links = %s; want a1,a3,b1,b4", got)
}
// A second row for the code is now refused.
_, err = db.ExecContext(ctx, `INSERT INTO classification_codes
(is_cpv, code, classification) VALUES (1, '09000000', 'Other')`)
if err == nil {
t.Error("a second row for a CPV code was accepted")
}
}