package gitcode
import (
"encoding/json"
"errors"
"testing"
)
func TestIssueIdentity001NumericIDFloat64(t *testing.T) {
body := `{"id":42,"number":42,"title":"numeric id"}`
var summary IssueSummary
if err := json.Unmarshal([]byte(body), &summary); err != nil {
t.Fatalf("unmarshal numeric id: %v", err)
}
if summary.ID != "42" {
t.Fatalf("ID: got %q, want \"42\"", summary.ID)
}
if summary.Number != 42 {
t.Fatalf("Number: got %d, want 42", summary.Number)
}
}
func TestIssueIdentity002StringID(t *testing.T) {
body := `{"id":"ISSUE-99","number":99,"title":"string id"}`
var summary IssueSummary
if err := json.Unmarshal([]byte(body), &summary); err != nil {
t.Fatalf("unmarshal string id: %v", err)
}
if summary.ID != "ISSUE-99" {
t.Fatalf("ID: got %q, want \"ISSUE-99\"", summary.ID)
}
if summary.Number != 99 {
t.Fatalf("Number: got %d, want 99", summary.Number)
}
}
func TestIssueIdentity003StringNumber(t *testing.T) {
body := `{"id":"1","number":"7","title":"string number"}`
var summary IssueSummary
if err := json.Unmarshal([]byte(body), &summary); err != nil {
t.Fatalf("unmarshal string number: %v", err)
}
if summary.Number != 7 {
t.Fatalf("Number: got %d, want 7", summary.Number)
}
}
func TestIssueIdentity004MissingID(t *testing.T) {
body := `{"number":1,"title":"missing id"}`
var summary IssueSummary
err := json.Unmarshal([]byte(body), &summary)
if err == nil {
t.Fatal("expected error for missing id, got nil")
}
var schemaErr *ErrSchemaDecode
if !errors.As(err, &schemaErr) {
t.Fatalf("expected *ErrSchemaDecode, got %T: %v", err, err)
}
if schemaErr.Field != "id" {
t.Fatalf("Field: got %q, want \"id\"", schemaErr.Field)
}
if schemaErr.DiagnosticCode() != "schema_decode" {
t.Fatalf("DiagnosticCode: got %q, want schema_decode", schemaErr.DiagnosticCode())
}
}
func TestIssueIdentity005IDZero(t *testing.T) {
body := `{"id":0,"number":1,"title":"id zero"}`
var summary IssueSummary
err := json.Unmarshal([]byte(body), &summary)
if err == nil {
t.Fatal("expected error for id=0, got nil")
}
var schemaErr *ErrSchemaDecode
if !errors.As(err, &schemaErr) {
t.Fatalf("expected *ErrSchemaDecode, got %T: %v", err, err)
}
if schemaErr.Field != "id" {
t.Fatalf("Field: got %q, want \"id\"", schemaErr.Field)
}
}
func TestIssueIdentity006MissingNumber(t *testing.T) {
body := `{"id":"42","title":"missing number"}`
var summary IssueSummary
err := json.Unmarshal([]byte(body), &summary)
if err == nil {
t.Fatal("expected error for missing number, got nil")
}
var schemaErr *ErrSchemaDecode
if !errors.As(err, &schemaErr) {
t.Fatalf("expected *ErrSchemaDecode, got %T: %v", err, err)
}
if schemaErr.Field != "number" {
t.Fatalf("Field: got %q, want \"number\"", schemaErr.Field)
}
}
func TestIssueIdentity007NumberZero(t *testing.T) {
body := `{"id":"7","number":0,"title":"number zero"}`
var summary IssueSummary
if err := json.Unmarshal([]byte(body), &summary); err != nil {
t.Fatalf("unmarshal number=0: %v", err)
}
if summary.ID != "7" {
t.Fatalf("ID: got %q, want \"7\"", summary.ID)
}
if summary.Number != 0 {
t.Fatalf("Number: got %d, want 0", summary.Number)
}
}
func TestIssueIdentity008NumberZeroString(t *testing.T) {
body := `{"id":"7","number":"0","title":"number zero string"}`
var summary IssueSummary
if err := json.Unmarshal([]byte(body), &summary); err != nil {
t.Fatalf("unmarshal number=\"0\": %v", err)
}
if summary.Number != 0 {
t.Fatalf("Number: got %d, want 0", summary.Number)
}
}
func TestIssueIdentity009RoundTripNumericIDStringNumber(t *testing.T) {
body := `{"id":7,"number":"7","title":"round trip"}`
var summary IssueSummary
if err := json.Unmarshal([]byte(body), &summary); err != nil {
t.Fatalf("unmarshal: %v", err)
}
if summary.ID != "7" {
t.Fatalf("ID: got %q, want \"7\"", summary.ID)
}
if summary.Number != 7 {
t.Fatalf("Number: got %d, want 7", summary.Number)
}
if summary.Title != "round trip" {
t.Fatalf("Title: got %q, want \"round trip\"", summary.Title)
}
var issue Issue
if err := json.Unmarshal([]byte(body), &issue); err != nil {
t.Fatalf("unmarshal Issue: %v", err)
}
if issue.ID != "7" || issue.Number != 7 || issue.Title != "round trip" {
t.Fatalf("Issue: id=%q number=%d title=%q", issue.ID, issue.Number, issue.Title)
}
}
func TestIssueIdentity010MalformedPayloadSchemaDecodeDistinct(t *testing.T) {
body := `{"number":"abc","title":"bad number"}`
var summary IssueSummary
err := json.Unmarshal([]byte(body), &summary)
if err == nil {
t.Fatal("expected error for malformed payload, got nil")
}
var schemaErr *ErrSchemaDecode
if !errors.As(err, &schemaErr) {
t.Fatalf("expected *ErrSchemaDecode, got %T: %v", err, err)
}
var netErr *ErrNetworkUnavailable
if errors.As(err, &netErr) {
t.Fatalf("schema decode error incorrectly matches ErrNetworkUnavailable")
}
}
func TestIssueIdentity011SchemaDecodeNotTransport(t *testing.T) {
body := `{"id":"","number":1,"title":"empty id string"}`
var summary IssueSummary
err := json.Unmarshal([]byte(body), &summary)
if err == nil {
t.Fatal("expected error for empty id string, got nil")
}
var schemaErr *ErrSchemaDecode
if !errors.As(err, &schemaErr) {
t.Fatalf("expected *ErrSchemaDecode, got %T: %v", err, err)
}
var netErr *ErrNetworkUnavailable
if errors.As(err, &netErr) {
t.Fatalf("schema decode error incorrectly matches ErrNetworkUnavailable")
}
}
func TestIssueIdentity012IDZeroStringInvalid(t *testing.T) {
body := `{"id":"0","number":1,"title":"zero string id"}`
var summary IssueSummary
err := json.Unmarshal([]byte(body), &summary)
if err == nil {
t.Fatal("expected error for id=\"0\", got nil")
}
var schemaErr *ErrSchemaDecode
if !errors.As(err, &schemaErr) {
t.Fatalf("expected *ErrSchemaDecode, got %T: %v", err, err)
}
if schemaErr.Field != "id" {
t.Fatalf("Field: got %q, want \"id\"", schemaErr.Field)
}
}
func TestIssueIdentity013ExistingFixtureStringIDsStillWork(t *testing.T) {
body := `{"id":"ISSUE-41","number":41,"title":"existing fixture"}`
var summary IssueSummary
if err := json.Unmarshal([]byte(body), &summary); err != nil {
t.Fatalf("unmarshal ISSUE-41: %v", err)
}
if summary.ID != "ISSUE-41" {
t.Fatalf("ID: got %q, want \"ISSUE-41\"", summary.ID)
}
body2 := `{"id":"ISSUE-42","number":42,"title":"another fixture"}`
if err := json.Unmarshal([]byte(body2), &summary); err != nil {
t.Fatalf("unmarshal ISSUE-42: %v", err)
}
if summary.ID != "ISSUE-42" {
t.Fatalf("ID: got %q, want \"ISSUE-42\"", summary.ID)
}
}
func TestIssueIdentity014NilID(t *testing.T) {
body := `{"id":null,"number":1,"title":"null id"}`
var summary IssueSummary
err := json.Unmarshal([]byte(body), &summary)
if err == nil {
t.Fatal("expected error for null id, got nil")
}
var schemaErr *ErrSchemaDecode
if !errors.As(err, &schemaErr) {
t.Fatalf("expected *ErrSchemaDecode, got %T: %v", err, err)
}
if schemaErr.Field != "id" {
t.Fatalf("Field: got %q, want \"id\"", schemaErr.Field)
}
}
func TestIssueIdentity015BoolIDRejected(t *testing.T) {
body := `{"id":true,"number":1,"title":"bool id"}`
var summary IssueSummary
err := json.Unmarshal([]byte(body), &summary)
if err == nil {
t.Fatal("expected error for bool id, got nil")
}
var schemaErr *ErrSchemaDecode
if !errors.As(err, &schemaErr) {
t.Fatalf("expected *ErrSchemaDecode, got %T: %v", err, err)
}
if schemaErr.Field != "id" {
t.Fatalf("Field: got %q, want \"id\"", schemaErr.Field)
}
}
func TestIssueIdentity016LabelsStillWorkWithNumericID(t *testing.T) {
body := `{"id":7,"number":"7","title":"Test","labels":[{"id":1,"name":"bug","color":"#FF0000"},{"id":2,"name":"enhancement","color":"#00FF00"}]}`
var summary IssueSummary
if err := json.Unmarshal([]byte(body), &summary); err != nil {
t.Fatalf("unmarshal with labels: %v", err)
}
if summary.ID != "7" {
t.Fatalf("ID: got %q, want \"7\"", summary.ID)
}
if len(summary.Labels) != 2 || summary.Labels[0] != "bug" || summary.Labels[1] != "enhancement" {
t.Fatalf("Labels: got %v, want [bug enhancement]", summary.Labels)
}
}