diff --git a/provider/internal/resources_core/org_ip_allocation_test.go b/provider/internal/resources_core/org_ip_allocation_test.go index 5dfcaf9..7e7bb23 100644 --- a/provider/internal/resources_core/org_ip_allocation_test.go +++ b/provider/internal/resources_core/org_ip_allocation_test.go @@ -51,6 +51,35 @@ func TestFormatVipConfigure_Canonical(t *testing.T) { } } +// Канонизация пользовательского ввода: terraform jsonencode сортирует ключи по алфавиту +// (count раньше name), а канон у нас — name,count. Без канонизации план ≠ state → вечный diff +// (баг воспроизведён через `terraform console`, см. NOTES/20_prompts/prompt_for_opus_review_modify_resources_2026-09-24.md). +func TestCanonicalVipConfigure_NormalizesJsonencodeForm(t *testing.T) { + raw := `[{"count":"3","name":"internet-ipv4-v1"}]` // так отдаёт jsonencode + want := `[{"name":"internet-ipv4-v1","count":"3"}]` + if got := canonicalVipConfigure(raw); got != want { + t.Fatalf("получено %q, ожидалось %q", got, want) + } +} + +func TestCanonicalVipConfigure_CompactsAndDropsEmptyElements(t *testing.T) { + raw := `[ { "count" : "4" , "name" : "internet-ipv4-v1" }, {} ]` + want := `[{"name":"internet-ipv4-v1","count":"4"}]` + if got := canonicalVipConfigure(raw); got != want { + t.Fatalf("получено %q, ожидалось %q", got, want) + } + if got := canonicalVipConfigure(`[{}]`); got != "[]" { + t.Fatalf("для [{}] ожидалось \"[]\", получено %q", got) + } +} + +func TestCanonicalVipConfigure_InvalidJSONLeftAsIs(t *testing.T) { + raw := `{not json` + if got := canonicalVipConfigure(raw); got != raw { + t.Fatalf("невалидный JSON должен остаться как есть: %q → %q", raw, got) + } +} + func TestParseVipConfigure_RoundTripIsStable(t *testing.T) { raw := `[{"name":"internet-ipv4-v1","count":"4"}]` items, err := parseVipConfigure(raw)