package console
import (
"encoding/json"
"fmt"
"strings"
"testing"
"time"
)
// TestFaqContentDecode pins the Docker-free decoding of a Winter FAQ export
// row: content as a JSON list, as JSON text, as an object keyed by row
// number (in numeric order), or null; the required name, slug and locale
// code; PHP-shaped flags, ids and timestamps; and the refusals.
func TestFaqContentDecode(t *testing.T) {
for _, tc := range []struct {
raw string
want string
}{
{`[{"question":"Q1","answer":"
A1
"},{"question":"Q2","answer":null}]`, `[map[answer:A1
question:Q1] map[answer: question:Q2]]`},
{`"[{\"question\":\"Q\",\"answer\":\"A\"}]"`, `[map[answer:A question:Q]]`},
{`{"10":{"question":"ten"},"2":{"question":"two"},"1":{"question":"one"}}`, `[map[question:one] map[question:two] map[question:ten]]`},
{`[]`, `[]`},
{`null`, `[]`},
{`"null"`, `[]`},
{``, `[]`},
} {
got, err := decodeContent(json.RawMessage(tc.raw))
if err != nil {
t.Fatalf("decodeContent(%s): %v", tc.raw, err)
}
if s := fmt.Sprint(got); s != tc.want {
t.Fatalf("decodeContent(%s) = %s, want %s", tc.raw, s, tc.want)
}
}
for _, raw := range []string{`"x"`, `5`, `[1,2]`, `{"a":1}`, `true`} {
if _, err := decodeContent(json.RawMessage(raw)); err == nil {
t.Fatalf("decodeContent(%s) accepted", raw)
}
}
row := func(raw string) map[string]json.RawMessage {
t.Helper()
var out map[string]json.RawMessage
if err := json.Unmarshal([]byte(raw), &out); err != nil {
t.Fatal(err)
}
return out
}
faq, code, err := decodeFAQ(row(`{"id": "12", "name": "Shipping", "slug": "shipping", "locale_code": "pl", "is_active": "1", "description": 5, "content": [{"question":"Q","answer":"A"}], "created_at": "2024-03-01 10:00:00.000000", "updated_at": null}`))
if err != nil {
t.Fatal(err)
}
if faq.ID != 12 || faq.Name != "Shipping" || faq.Slug != "shipping" || code != "pl" || !faq.IsActive || faq.Description == nil || *faq.Description != "5" ||
len(faq.Items()) != 1 || !faq.Content.Valid || faq.CreatedAt == nil || !faq.CreatedAt.Equal(time.Date(2024, 3, 1, 10, 0, 0, 0, time.UTC)) || faq.UpdatedAt != nil {
t.Fatalf("decoded = %+v code=%s", faq, code)
}
if faq, _, err := decodeFAQ(row(`{"id": 1, "name": "A", "slug": "a", "locale_code": "en", "is_active": 0, "content": null}`)); err != nil || faq.IsActive || faq.Content.Valid || faq.Description != nil {
t.Fatalf("null content row = %+v %v", faq, err)
}
for raw, want := range map[string]string{
`{"id": 0, "name": "A", "slug": "a", "locale_code": "en"}`: "id",
`{"name": "A", "slug": "a", "locale_code": "en"}`: "id",
`{"id": 1, "slug": "a", "locale_code": "en"}`: "name is missing",
`{"id": 1, "name": "A", "slug": " ", "locale_code": "en"}`: "slug is missing",
`{"id": 1, "name": "A", "slug": "a"}`: "locale_code is missing",
`{"id": 1, "name": "A", "slug": "a", "locale_code": "en", "content": "oops"}`: "content",
`{"id": 1, "name": "A", "slug": "a", "locale_code": "en", "is_active": [1]}`: "is_active",
`{"id": 1, "name": "A", "slug": "a", "locale_code": "en", "created_at": "x"}`: "created_at",
`{"id": 1, "name": "A", "slug": "a", "locale_code": "en", "description": {}}`: "description",
} {
if _, _, err := decodeFAQ(row(raw)); err == nil || !strings.Contains(err.Error(), want) {
t.Errorf("decodeFAQ(%s) = %v, want %q", raw, err, want)
}
}
}