test(api): cover [JsonProperty] path + fail loudly on rename collision (#198, review)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 7m59s
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 14s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 10m31s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped

Adversarial-review follow-ups:

- OpenApiSerializerContractTests: add a fifth case, a fully-populated
  ChannelResponseModel — the only DTO with a [JsonProperty("ffmpegProfile")]
  override, i.e. the attribute path of NewtonsoftSchemaNamingTransformer that
  the existing four cases never exercised.
- NewtonsoftSchemaNamingTransformer: a rename colliding with an existing schema
  key now throws InvalidOperationException (naming the type and keys) instead of
  silently overwriting/dropping a property — the generator must never emit a
  lossy spec.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-09 20:06:26 +02:00
co-authored by Claude Fable 5
parent d9faa8be7b
commit e0d30c9b7b
2 changed files with 28 additions and 2 deletions
@@ -67,11 +67,18 @@ public static class NewtonsoftSchemaNamingTransformer
return Task.CompletedTask;
}
// Rebuild Properties preserving insertion order.
// Rebuild Properties preserving insertion order. A rename colliding with an existing key
// would silently drop a property from the spec — fail loudly instead (near-unreachable,
// but the generator must never emit a lossy document).
var renamedProperties = new Dictionary<string, IOpenApiSchema>(properties.Count, StringComparer.Ordinal);
foreach ((string key, IOpenApiSchema value) in properties)
{
renamedProperties[renames.TryGetValue(key, out string newKey) ? newKey : key] = value;
string finalKey = renames.TryGetValue(key, out string newKey) ? newKey : key;
if (!renamedProperties.TryAdd(finalKey, value))
{
throw new InvalidOperationException(
$"OpenAPI schema property rename collision on '{clrType.FullName}': renaming '{key}' to '{finalKey}' would overwrite an existing property.");
}
}
schema.Properties = renamedProperties;