snapshot of https://github.com/ory/kratos.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
133
selfservice/errorx/handler_test.go
Normal file
133
selfservice/errorx/handler_test.go
Normal file
@@ -0,0 +1,133 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package errorx_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/ory/herodot"
|
||||
"github.com/ory/kratos/pkg"
|
||||
"github.com/ory/kratos/pkg/testhelpers"
|
||||
"github.com/ory/kratos/selfservice/errorx"
|
||||
"github.com/ory/kratos/x"
|
||||
"github.com/ory/kratos/x/nosurfx"
|
||||
"github.com/ory/nosurf"
|
||||
"github.com/ory/x/assertx"
|
||||
"github.com/ory/x/errorsx"
|
||||
"github.com/ory/x/httprouterx"
|
||||
)
|
||||
|
||||
func TestHandler(t *testing.T) {
|
||||
_, reg := pkg.NewFastRegistryWithMocks(t)
|
||||
h := errorx.NewHandler(reg)
|
||||
|
||||
t.Run("case=public authorization", func(t *testing.T) {
|
||||
router := httprouterx.NewRouterPublic()
|
||||
ns := nosurfx.NewTestCSRFHandler(router, reg)
|
||||
|
||||
h.RegisterPublicRoutes(router)
|
||||
router.GET("/regen", func(w http.ResponseWriter, r *http.Request) {
|
||||
ns.RegenerateToken(w, r)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
})
|
||||
router.GET("/set-error", func(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := reg.SelfServiceErrorPersister().CreateErrorContainer(context.Background(), nosurf.Token(r), herodot.ErrNotFound().WithReason("foobar"))
|
||||
require.NoError(t, err)
|
||||
_, _ = w.Write([]byte(id.String()))
|
||||
})
|
||||
|
||||
ts := httptest.NewServer(ns)
|
||||
defer ts.Close()
|
||||
|
||||
getBody := func(t *testing.T, hc *http.Client, path string, expectedCode int) []byte {
|
||||
res, err := hc.Get(ts.URL + path)
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = res.Body.Close() }()
|
||||
require.EqualValues(t, expectedCode, res.StatusCode)
|
||||
body, err := io.ReadAll(res.Body)
|
||||
require.NoError(t, err)
|
||||
return body
|
||||
}
|
||||
expectedError := x.MustEncodeJSON(t, herodot.ErrNotFound().WithReason("foobar"))
|
||||
|
||||
t.Run("call with valid csrf cookie", func(t *testing.T) {
|
||||
hc := testhelpers.NewTestClient(t)
|
||||
id := getBody(t, hc, "/set-error", http.StatusOK)
|
||||
actual := getBody(t, hc, errorx.RouteGet+"?id="+string(id), http.StatusOK)
|
||||
assert.JSONEq(t, expectedError, gjson.GetBytes(actual, "error").Raw, "%s", actual)
|
||||
|
||||
// We expect a forbid error if the error is not found, regardless of CSRF
|
||||
_ = getBody(t, hc, errorx.RouteGet+"?id=does-not-exist", http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("case=stubs", func(t *testing.T) {
|
||||
router := httprouterx.NewRouterPublic()
|
||||
h.RegisterPublicRoutes(router)
|
||||
ts := httptest.NewServer(router)
|
||||
defer ts.Close()
|
||||
|
||||
res, err := ts.Client().Get(ts.URL + errorx.RouteGet + "?id=stub:500")
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, http.StatusOK, res.StatusCode)
|
||||
|
||||
actual, err := io.ReadAll(res.Body)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.EqualValues(t, "This is a stub error.", gjson.GetBytes(actual, "error.reason").String())
|
||||
})
|
||||
|
||||
t.Run("case=errors types", func(t *testing.T) {
|
||||
router := httprouterx.NewRouterPublic()
|
||||
h.RegisterPublicRoutes(router)
|
||||
ts := httptest.NewServer(router)
|
||||
defer ts.Close()
|
||||
|
||||
for k, tc := range []struct {
|
||||
gave error
|
||||
}{
|
||||
{gave: herodot.ErrNotFound().WithReason("foobar")},
|
||||
{gave: herodot.ErrNotFound().WithReason("foobar")},
|
||||
{gave: errors.WithStack(herodot.ErrNotFound().WithReason("foobar"))},
|
||||
{gave: errors.WithStack(herodot.ErrNotFound().WithReason("foobar").WithTrace(errors.New("asdf")))},
|
||||
} {
|
||||
t.Run(fmt.Sprintf("case=%d", k), func(t *testing.T) {
|
||||
csrf := x.NewUUID()
|
||||
id, err := reg.SelfServiceErrorPersister().CreateErrorContainer(context.Background(), csrf.String(), tc.gave)
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err := ts.Client().Get(ts.URL + errorx.RouteGet + "?id=" + id.String())
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = res.Body.Close() }()
|
||||
assert.EqualValues(t, http.StatusOK, res.StatusCode)
|
||||
|
||||
actual, err := io.ReadAll(res.Body)
|
||||
require.NoError(t, err)
|
||||
|
||||
gg := errorsx.Cause(tc.gave)
|
||||
expected, err := json.Marshal(errorx.ErrorContainer{
|
||||
ID: id,
|
||||
Errors: x.RequireJSONMarshal(t, gg),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
assertx.EqualAsJSONExcept(t, json.RawMessage(expected), json.RawMessage(actual), []string{"created_at", "updated_at"})
|
||||
assert.Empty(t, gjson.GetBytes(actual, "csrf_token").String())
|
||||
assert.JSONEq(t, string(x.RequireJSONMarshal(t, gg)), gjson.GetBytes(actual, "error").Raw)
|
||||
t.Logf("%s", actual)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user