fix: невалидное имя варианта проекта — предупреждение вместо ошибки
Имя варианта "main" или с недопустимыми символами больше не отклоняет запрос ошибкой 400 — теперь автоматически конвертируется в валидное (sanitizeProjectVariantName), а API/UI показывают variant_warning вместо блокировки создания/переименования варианта. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
006d7e87c5
commit
2f3bdc609a
@@ -1,37 +1,47 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"git.mchus.pro/mchus/quoteforge/internal/localdb"
|
||||
)
|
||||
|
||||
func TestProjectServiceCreateRejectsReservedMainVariant(t *testing.T) {
|
||||
// TestProjectServiceCreateSanitizesReservedMainVariant verifies that naming a new
|
||||
// variant "main" no longer errors: the name is auto-converted to a valid one and a
|
||||
// warning is returned instead of the request being rejected.
|
||||
func TestProjectServiceCreateSanitizesReservedMainVariant(t *testing.T) {
|
||||
local, err := newProjectTestLocalDB(t)
|
||||
if err != nil {
|
||||
t.Fatalf("open localdb: %v", err)
|
||||
}
|
||||
service := NewProjectService(local)
|
||||
|
||||
_, err = service.Create("tester", &CreateProjectRequest{
|
||||
project, warning, err := service.Create("tester", &CreateProjectRequest{
|
||||
Code: "OPS-1",
|
||||
Variant: "main",
|
||||
})
|
||||
if !errors.Is(err, ErrReservedMainVariant) {
|
||||
t.Fatalf("expected ErrReservedMainVariant, got %v", err)
|
||||
if err != nil {
|
||||
t.Fatalf("create project: %v", err)
|
||||
}
|
||||
if warning == "" {
|
||||
t.Fatalf("expected a warning about the reserved variant name")
|
||||
}
|
||||
if project.Variant == "" || normalizeProjectVariant(project.Variant) == "main" {
|
||||
t.Fatalf("expected variant to be converted away from 'main', got %q", project.Variant)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProjectServiceUpdateRejectsReservedMainVariant(t *testing.T) {
|
||||
// TestProjectServiceUpdateSanitizesReservedMainVariant mirrors the create case for
|
||||
// renaming an existing (non-main) variant to "main".
|
||||
func TestProjectServiceUpdateSanitizesReservedMainVariant(t *testing.T) {
|
||||
local, err := newProjectTestLocalDB(t)
|
||||
if err != nil {
|
||||
t.Fatalf("open localdb: %v", err)
|
||||
}
|
||||
service := NewProjectService(local)
|
||||
|
||||
created, err := service.Create("tester", &CreateProjectRequest{
|
||||
created, _, err := service.Create("tester", &CreateProjectRequest{
|
||||
Code: "OPS-1",
|
||||
Variant: "Lenovo",
|
||||
})
|
||||
@@ -40,11 +50,41 @@ func TestProjectServiceUpdateRejectsReservedMainVariant(t *testing.T) {
|
||||
}
|
||||
|
||||
mainName := "main"
|
||||
_, err = service.Update(created.UUID, "tester", &UpdateProjectRequest{
|
||||
updated, warning, err := service.Update(created.UUID, "tester", &UpdateProjectRequest{
|
||||
Variant: &mainName,
|
||||
})
|
||||
if !errors.Is(err, ErrReservedMainVariant) {
|
||||
t.Fatalf("expected ErrReservedMainVariant, got %v", err)
|
||||
if err != nil {
|
||||
t.Fatalf("update project: %v", err)
|
||||
}
|
||||
if warning == "" {
|
||||
t.Fatalf("expected a warning about the reserved variant name")
|
||||
}
|
||||
if updated.Variant == "" || normalizeProjectVariant(updated.Variant) == "main" {
|
||||
t.Fatalf("expected variant to be converted away from 'main', got %q", updated.Variant)
|
||||
}
|
||||
}
|
||||
|
||||
// TestSanitizeProjectVariantName_InvalidChars verifies disallowed characters are
|
||||
// stripped/replaced rather than rejected outright.
|
||||
func TestSanitizeProjectVariantName_InvalidChars(t *testing.T) {
|
||||
sanitized, warning := sanitizeProjectVariantName("Лендинг сервер!")
|
||||
if warning == "" {
|
||||
t.Fatalf("expected a warning for invalid characters")
|
||||
}
|
||||
if !projectCodeRe.MatchString(sanitized) {
|
||||
t.Fatalf("sanitized variant %q still fails projectCodeRe", sanitized)
|
||||
}
|
||||
}
|
||||
|
||||
// TestSanitizeProjectVariantName_ValidPassesThrough ensures already-valid names are
|
||||
// left untouched with no warning.
|
||||
func TestSanitizeProjectVariantName_ValidPassesThrough(t *testing.T) {
|
||||
sanitized, warning := sanitizeProjectVariantName("lenovo-2u")
|
||||
if warning != "" {
|
||||
t.Fatalf("expected no warning, got %q", warning)
|
||||
}
|
||||
if sanitized != "lenovo-2u" {
|
||||
t.Fatalf("expected unchanged variant, got %q", sanitized)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user