1 package web
2
3 import (
4 "fmt"
5 "reflect"
6 "testing"
7
8 berrors "github.com/letsencrypt/boulder/errors"
9 "github.com/letsencrypt/boulder/identifier"
10 "github.com/letsencrypt/boulder/probs"
11 "github.com/letsencrypt/boulder/test"
12 )
13
14 func TestProblemDetailsFromError(t *testing.T) {
15
16
17 const errMsg = "testError"
18
19
20 const detailMsg = "testDetail"
21
22
23 fullDetail := fmt.Sprintf("%s :: %s", errMsg, detailMsg)
24 testCases := []struct {
25 err error
26 statusCode int
27 problem probs.ProblemType
28 detail string
29 }{
30
31
32 {berrors.InternalServerError(detailMsg), 500, probs.ServerInternalProblem, errMsg},
33
34 {berrors.MalformedError(detailMsg), 400, probs.MalformedProblem, fullDetail},
35 {berrors.UnauthorizedError(detailMsg), 403, probs.UnauthorizedProblem, fullDetail},
36 {berrors.NotFoundError(detailMsg), 404, probs.MalformedProblem, fullDetail},
37 {berrors.RateLimitError(0, detailMsg), 429, probs.RateLimitedProblem, fullDetail + ": see https://letsencrypt.org/docs/rate-limits/"},
38 {berrors.InvalidEmailError(detailMsg), 400, probs.InvalidContactProblem, fullDetail},
39 {berrors.RejectedIdentifierError(detailMsg), 400, probs.RejectedIdentifierProblem, fullDetail},
40 }
41 for _, c := range testCases {
42 p := ProblemDetailsForError(c.err, errMsg)
43 if p.HTTPStatus != c.statusCode {
44 t.Errorf("Incorrect status code for %s. Expected %d, got %d", reflect.TypeOf(c.err).Name(), c.statusCode, p.HTTPStatus)
45 }
46 if p.Type != c.problem {
47 t.Errorf("Expected problem urn %#v, got %#v", c.problem, p.Type)
48 }
49 if p.Detail != c.detail {
50 t.Errorf("Expected detailed message %q, got %q", c.detail, p.Detail)
51 }
52 }
53
54 expected := &probs.ProblemDetails{
55 Type: probs.MalformedProblem,
56 HTTPStatus: 200,
57 Detail: "gotcha",
58 }
59 p := ProblemDetailsForError(expected, "k")
60 test.AssertDeepEquals(t, expected, p)
61 }
62
63 func TestSubProblems(t *testing.T) {
64 topErr := (&berrors.BoulderError{
65 Type: berrors.CAA,
66 Detail: "CAA policy forbids issuance",
67 }).WithSubErrors(
68 []berrors.SubBoulderError{
69 {
70 Identifier: identifier.DNSIdentifier("threeletter.agency"),
71 BoulderError: &berrors.BoulderError{
72 Type: berrors.CAA,
73 Detail: "Forbidden by ■■■■■■■■■■■ and directive ■■■■",
74 },
75 },
76 {
77 Identifier: identifier.DNSIdentifier("area51.threeletter.agency"),
78 BoulderError: &berrors.BoulderError{
79 Type: berrors.NotFound,
80 Detail: "No Such Area...",
81 },
82 },
83 })
84
85 prob := problemDetailsForBoulderError(topErr, "problem with subproblems")
86 test.AssertEquals(t, len(prob.SubProblems), len(topErr.SubErrors))
87
88 subProbsMap := make(map[string]probs.SubProblemDetails, len(prob.SubProblems))
89
90 for _, subProb := range prob.SubProblems {
91 subProbsMap[subProb.Identifier.Value] = subProb
92 }
93
94 subProbA, foundA := subProbsMap["threeletter.agency"]
95 subProbB, foundB := subProbsMap["area51.threeletter.agency"]
96 test.AssertEquals(t, foundA, true)
97 test.AssertEquals(t, foundB, true)
98
99 test.AssertEquals(t, subProbA.Type, probs.CAAProblem)
100 test.AssertEquals(t, subProbB.Type, probs.MalformedProblem)
101 }
102
View as plain text