1package errors
2
3import (
4	"encoding/json"
5	"errors"
6	"net/http"
7	"testing"
8
9	"github.com/flimzy/diff"
10)
11
12func TestStatusf(t *testing.T) {
13	e := Statusf(400, "foo %d", 123)
14	result := e.(*statusError)
15	expected := &statusError{
16		message:    "foo 123",
17		statusCode: 400,
18	}
19	if d := diff.Interface(expected, result); d != nil {
20		t.Error(d)
21	}
22}
23
24func TestWrapStatus(t *testing.T) {
25	e := WrapStatus(400, errors.New("foo"))
26	expected := &wrappedError{
27		err:        errors.New("foo"),
28		statusCode: 400,
29	}
30	result := e.(*wrappedError)
31	if d := diff.Interface(expected, result); d != nil {
32		t.Error(d)
33	}
34}
35
36func TestErrorJSON(t *testing.T) {
37	tests := []struct {
38		name     string
39		err      error
40		expected string
41	}{
42		{
43			name:     "statusError not found",
44			err:      &statusError{statusCode: http.StatusNotFound, message: "no_db_file"},
45			expected: `{"error":"not_found", "reason":"no_db_file"}`,
46		},
47		{
48			name:     "statusError unknown code",
49			err:      &statusError{statusCode: 999, message: "somethin' bad happened"},
50			expected: `{"error":"unknown", "reason": "somethin' bad happened"}`,
51		},
52		{
53			name:     "statusError unauthorized",
54			err:      &statusError{statusCode: http.StatusUnauthorized, message: "You are not a server admin."},
55			expected: `{"error":"unauthorized", "reason":"You are not a server admin."}`,
56		},
57		{
58			name:     "statusError precondition failed",
59			err:      &statusError{statusCode: http.StatusPreconditionFailed, message: "The database could not be created, the file already exists."},
60			expected: `{"error":"precondition_failed", "reason":"The database could not be created, the file already exists."}`,
61		},
62	}
63	for _, test := range tests {
64		t.Run(test.name, func(t *testing.T) {
65			result, err := json.Marshal(test.err)
66			if err != nil {
67				t.Fatal(err)
68			}
69			if d := diff.JSON([]byte(test.expected), result); d != nil {
70				t.Error(d)
71			}
72		})
73	}
74}
75
76func TestReason(t *testing.T) {
77	tests := []struct {
78		name   string
79		err    error
80		reason string
81	}{
82		{
83			name:   "nil error",
84			err:    nil,
85			reason: "",
86		},
87		{
88			name:   "standard error",
89			err:    errors.New("foo"),
90			reason: "",
91		},
92		{
93			name:   "StatusError",
94			err:    &statusError{statusCode: 400, message: "foo"},
95			reason: "foo",
96		},
97	}
98	for _, test := range tests {
99		t.Run(test.name, func(t *testing.T) {
100			reason := Reason(test.err)
101			if reason != test.reason {
102				t.Errorf("Unexpected reason: %s", reason)
103			}
104		})
105	}
106}
107
108func TestStatusCode(t *testing.T) {
109	tests := []struct {
110		name         string
111		input        error
112		expectedCode int
113	}{
114		{
115			name:         "nil",
116			input:        nil,
117			expectedCode: 0,
118		},
119		{
120			name:         "status coder",
121			input:        Status(400, "foo"),
122			expectedCode: 400,
123		},
124		{
125			name:         "non status coder",
126			input:        New("foo"),
127			expectedCode: 500,
128		},
129	}
130	for _, test := range tests {
131		t.Run(test.name, func(t *testing.T) {
132			code := StatusCode(test.input)
133			if test.expectedCode != code {
134				t.Errorf("Unexpected code: %d", code)
135			}
136		})
137	}
138}
139
140func TestStatusCodeOK(t *testing.T) {
141	tests := []struct {
142		name         string
143		input        error
144		expectedCode int
145		expectedOK   bool
146	}{
147		{
148			name:         "nil",
149			input:        nil,
150			expectedCode: 0,
151			expectedOK:   false,
152		},
153		{
154			name:         "status coder",
155			input:        Status(400, "foo"),
156			expectedCode: 400,
157			expectedOK:   true,
158		},
159		{
160			name:         "non status coder",
161			input:        New("foo"),
162			expectedCode: 0,
163			expectedOK:   false,
164		},
165	}
166	for _, test := range tests {
167		t.Run(test.name, func(t *testing.T) {
168			code, ok := StatusCodeOK(test.input)
169			if test.expectedCode != code {
170				t.Errorf("Unexpected code: %d", code)
171			}
172			if test.expectedOK != ok {
173				t.Errorf("Unexpected ok: %t", ok)
174			}
175		})
176	}
177}
178