Files
query-orchestration/internal/database/repository/milestone2_sqlc_queries_test.go
T

167 lines
5.8 KiB
Go
Raw Normal View History

//go:build milestone2
// Package repository_test — Milestone 2 §2.3 failing SQLC query presence
// tests.
//
// Build tag: gated behind `milestone2` so the default `task fullsuite:ci`
// run does not execute it. See the comment in milestone2_migrations_test.go
// for the workflow the golang engineer follows to flip these tests from
// RED to GREEN.
//
// These tests prove that the next batch of SQLC queries required by
// Milestone 2 (plan Section 6.3 / tracking §2.3) are available on the
// generated *Queries type once the golang engineer runs `task generate`
// against a new internal/database/queries/custommetadata.sql query file.
//
// They use reflection to introspect the *Queries receiver rather than
// calling the methods directly so the test file can compile before the
// queries exist — a hard compile-time reference would break the whole
// package build and the rest of Milestone 1's tests with it.
//
// When the golang engineer adds the new SQL query blocks and re-runs
// `task generate`, sqlc will emit the corresponding Go methods and
// these tests will flip from failing to passing without any further
// edits.
package repository_test
import (
"reflect"
"testing"
"queryorchestration/internal/database/repository"
"github.com/stretchr/testify/require"
)
// milestone2RequiredQueries is the full list of new SQLC-generated
// method names that §2.3 of the v4 tracking doc requires. Every row
// maps to a block in the forthcoming internal/database/queries/custommetadata.sql
// file. The comment after each name traces back to the tracking line.
//
// Deliberately NOT in this list (see the "v4" notes in the tracking doc):
// - DocumentHasLegacyExtractions: reuse existing HasFieldExtraction
// - DeleteDocumentCustomMetadata: FK cascade replaces it
// - NullifyDocumentCustomSchemaId: reset-metadata uses a direct UPDATE
// - DeleteClientMetadataSchemas: FK cascade replaces it
// - LockDocumentCustomMetadataForVersion: v3 name, replaced by
// LockDocumentForMetadataWrite
var milestone2RequiredQueries = []struct {
method string
trackRef string
}{
{
method: "CreateDocumentCustomMetadata",
trackRef: "§2.3 CreateDocumentCustomMetadata (no schema_id parameter)",
},
{
method: "GetCurrentDocumentCustomMetadata",
trackRef: "§2.3 GetCurrentDocumentCustomMetadata (ORDER BY version DESC LIMIT 1, joins documents + client_metadata_schemas)",
},
{
method: "GetDocumentCustomMetadataByVersion",
trackRef: "§2.3 GetDocumentCustomMetadataByVersion (same join)",
},
{
method: "GetDocumentCustomMetadataHistory",
trackRef: "§2.3 GetDocumentCustomMetadataHistory (no schema join)",
},
{
method: "LockDocumentForMetadataWrite",
trackRef: "§2.3 LockDocumentForMetadataWrite (parent-row lock replacing v3's LockDocumentCustomMetadataForVersion)",
},
{
method: "GetMaxDocumentMetadataVersion",
trackRef: "§2.3 GetMaxDocumentMetadataVersion (COALESCE(MAX(version), 0))",
},
{
method: "SetDocumentCustomSchemaId",
trackRef: "§2.3 SetDocumentCustomSchemaId",
},
{
method: "GetDocumentCustomSchemaId",
trackRef: "§2.3 GetDocumentCustomSchemaId",
},
}
// TestMilestone2_RequiredSQLCQueries asserts every method in
// milestone2RequiredQueries is present on the generated *repository.Queries
// type. Uses reflection so this file compiles even before the query file
// lands — a hard Go reference would break the whole test binary and
// every other Milestone 1 test with it.
//
// This test FAILS intentionally until the golang engineer adds the query
// blocks to internal/database/queries/custommetadata.sql and runs
// `task generate`.
func TestMilestone2_RequiredSQLCQueries(t *testing.T) {
t.Parallel()
// No DB needed — this is a pure type-introspection check.
// We still run under short mode since the assertion is a static
// shape check and should be part of the fast unit sweep.
var q repository.Queries
qType := reflect.TypeOf(&q)
for _, want := range milestone2RequiredQueries {
want := want
t.Run(want.method, func(t *testing.T) {
t.Parallel()
_, ok := qType.MethodByName(want.method)
require.Truef(t, ok,
"generated *repository.Queries must have method %q — source of truth: %s. "+
"Add the SQL block to internal/database/queries/custommetadata.sql and run `task generate`.",
want.method, want.trackRef)
})
}
}
// TestMilestone2_RemovedV3QueriesAbsent asserts the v3 query names that
// v4 deliberately dropped never sneak back into the generated code. If a
// future contributor copies a v3 snippet into custommetadata.sql these
// assertions will fail loudly with a pointer to the tracking doc's
// "v4 removed" notes.
func TestMilestone2_RemovedV3QueriesAbsent(t *testing.T) {
t.Parallel()
forbidden := []struct {
method string
why string
}{
{
method: "DocumentHasLegacyExtractions",
why: "v4 reuses existing HasFieldExtraction — see §2.3 'Reuse existing query'",
},
{
method: "DeleteDocumentCustomMetadata",
why: "v4 relies on ON DELETE CASCADE via the document_id FK",
},
{
method: "NullifyDocumentCustomSchemaId",
why: "v4 resets via direct UPDATE documents SET custom_schema_id = NULL",
},
{
method: "DeleteClientMetadataSchemas",
why: "v4 relies on ON DELETE CASCADE via the client_id FK",
},
{
method: "LockDocumentCustomMetadataForVersion",
why: "v4 uses LockDocumentForMetadataWrite (parent-row lock) instead",
},
{
method: "GetSchemaMetadataRecordCount",
why: "v4 computes canDelete from GetSchemaDocumentCount alone",
},
}
var q repository.Queries
qType := reflect.TypeOf(&q)
for _, bad := range forbidden {
bad := bad
t.Run(bad.method, func(t *testing.T) {
t.Parallel()
_, ok := qType.MethodByName(bad.method)
require.Falsef(t, ok,
"*repository.Queries must NOT have method %q — %s",
bad.method, bad.why)
})
}
}