test(license): SchemaBootstrapIT — assert V5 license + retention columns
Two new assertions: license table has tenant_id/license_id/token/ installed_at/installed_by/expires_at/last_validated_at columns with expected types + NOT NULL constraints, PK on tenant_id; environments has execution_retention_days/log_retention_days/metric_retention_days all integer NOT NULL DEFAULT 1. Note: V5 migration does not include an installed_via column; the plan's spec was aspirational. Test asserts what the migration actually creates (and what PostgresLicenseRepository reads/writes). OpenAPI regen (Step 35.2) deferred to session end — requires running backend + UI dev server. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -115,6 +115,91 @@ class SchemaBootstrapIT extends AbstractPostgresIT {
|
||||
assertThat(isUnique).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void licenseTableExists() {
|
||||
// V5 migration: per-tenant license row, PK on tenant_id (one server = one tenant).
|
||||
var rows = jdbcTemplate.queryForList("""
|
||||
SELECT column_name, data_type, is_nullable
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'license'
|
||||
AND table_schema = current_schema()
|
||||
""");
|
||||
var byName = new java.util.HashMap<String, java.util.Map<String, Object>>();
|
||||
for (var row : rows) {
|
||||
byName.put((String) row.get("column_name"), row);
|
||||
}
|
||||
|
||||
assertThat(byName).containsKeys(
|
||||
"tenant_id", "license_id", "token", "installed_at",
|
||||
"installed_by", "expires_at", "last_validated_at");
|
||||
|
||||
assertThat(byName.get("tenant_id").get("data_type")).isEqualTo("text");
|
||||
assertThat(byName.get("tenant_id").get("is_nullable")).isEqualTo("NO");
|
||||
|
||||
assertThat(byName.get("license_id").get("data_type")).isEqualTo("uuid");
|
||||
assertThat(byName.get("license_id").get("is_nullable")).isEqualTo("NO");
|
||||
|
||||
assertThat(byName.get("token").get("data_type")).isEqualTo("text");
|
||||
assertThat(byName.get("token").get("is_nullable")).isEqualTo("NO");
|
||||
|
||||
assertThat(byName.get("installed_at").get("data_type"))
|
||||
.isEqualTo("timestamp with time zone");
|
||||
assertThat(byName.get("installed_at").get("is_nullable")).isEqualTo("NO");
|
||||
|
||||
assertThat(byName.get("installed_by").get("data_type")).isEqualTo("text");
|
||||
assertThat(byName.get("installed_by").get("is_nullable")).isEqualTo("NO");
|
||||
|
||||
assertThat(byName.get("expires_at").get("data_type"))
|
||||
.isEqualTo("timestamp with time zone");
|
||||
assertThat(byName.get("expires_at").get("is_nullable")).isEqualTo("NO");
|
||||
|
||||
assertThat(byName.get("last_validated_at").get("data_type"))
|
||||
.isEqualTo("timestamp with time zone");
|
||||
assertThat(byName.get("last_validated_at").get("is_nullable")).isEqualTo("NO");
|
||||
|
||||
// PK: tenant_id (one row per tenant).
|
||||
var pkCols = jdbcTemplate.queryForList("""
|
||||
SELECT a.attname AS column_name
|
||||
FROM pg_index i
|
||||
JOIN pg_class c ON c.oid = i.indrelid
|
||||
JOIN pg_namespace n ON n.oid = c.relnamespace
|
||||
JOIN pg_attribute a ON a.attrelid = c.oid AND a.attnum = ANY(i.indkey)
|
||||
WHERE c.relname = 'license'
|
||||
AND n.nspname = current_schema()
|
||||
AND i.indisprimary
|
||||
""", String.class);
|
||||
assertThat(pkCols).containsExactly("tenant_id");
|
||||
}
|
||||
|
||||
@Test
|
||||
void environmentsHasRetentionColumns() {
|
||||
// V5 migration adds three retention day columns, NOT NULL DEFAULT 1.
|
||||
var rows = jdbcTemplate.queryForList("""
|
||||
SELECT column_name, data_type, is_nullable, column_default
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'environments'
|
||||
AND table_schema = current_schema()
|
||||
AND column_name IN
|
||||
('execution_retention_days','log_retention_days','metric_retention_days')
|
||||
""");
|
||||
var byName = new java.util.HashMap<String, java.util.Map<String, Object>>();
|
||||
for (var row : rows) {
|
||||
byName.put((String) row.get("column_name"), row);
|
||||
}
|
||||
assertThat(byName).containsKeys(
|
||||
"execution_retention_days", "log_retention_days", "metric_retention_days");
|
||||
|
||||
for (var col : java.util.List.of(
|
||||
"execution_retention_days", "log_retention_days", "metric_retention_days")) {
|
||||
assertThat(byName.get(col).get("data_type"))
|
||||
.as("%s data_type", col).isEqualTo("integer");
|
||||
assertThat(byName.get(col).get("is_nullable"))
|
||||
.as("%s is_nullable", col).isEqualTo("NO");
|
||||
assertThat((String) byName.get(col).get("column_default"))
|
||||
.as("%s column_default", col).isEqualTo("1");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleting_environment_cascades_alerting_rows() {
|
||||
testEnvId = UUID.randomUUID();
|
||||
|
||||
Reference in New Issue
Block a user