snapshot of https://github.com/ory/keto.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
CI / Run lints and checks (push) Failing after 47s
CI / Run tests (push) Failing after 1s
CI / Run race tests (push) Failing after 5s
CI / Build CLI docs (push) Has been skipped
CI / Run buf actions (push) Failing after 5s
CodeQL / Analyze (go) (push) Failing after 3s
CodeQL / Analyze (javascript) (push) Failing after 2s
Docker Image Scanners / scanners (push) Failing after 3s
Format / format (push) Failing after 3s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Draft newsletter (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:
upstream-mirror
2026-09-16 01:08:34 +05:00
commit 9456a4e922
2560 changed files with 120911 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0
package expand_test
import (
"bytes"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/ory/x/httprouterx"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/ory/keto/internal/driver"
"github.com/ory/keto/internal/expand"
"github.com/ory/keto/internal/namespace"
"github.com/ory/keto/internal/testhelpers"
"github.com/ory/keto/ketoapi"
)
func TestRESTHandler(t *testing.T) {
nspace := &namespace.Namespace{
Name: "expand handler",
}
reg := driver.NewSqliteTestRegistry(t, driver.WithNamespaces([]*namespace.Namespace{nspace}))
h := expand.NewHandler(reg)
r := httprouterx.NewRouterPublic()
h.RegisterReadRoutes(r)
ts := httptest.NewServer(r)
defer ts.Close()
t.Run("case=returns bad request on malformed int", func(t *testing.T) {
resp, err := ts.Client().Get(ts.URL + expand.RouteBase + "?max-depth=foo")
require.NoError(t, err)
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
assert.Contains(t, string(body), "invalid syntax")
})
t.Run("case=returns not found on unknown namespace", func(t *testing.T) {
resp, err := ts.Client().Get(ts.URL + expand.RouteBase + "?" + url.Values{
"max-depth": {"10"},
"namespace": {"not " + nspace.Name},
}.Encode())
require.NoError(t, err)
assert.Equal(t, http.StatusNotFound, resp.StatusCode)
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
assert.Contains(t, string(body), "Unknown namespace")
})
t.Run("case=returns not found on unknown namespace", func(t *testing.T) {
resp, err := ts.Client().Get(ts.URL + expand.RouteBase + "?" + url.Values{
"max-depth": {"10"},
"namespace": {"not " + nspace.Name},
}.Encode())
require.NoError(t, err)
assert.Equal(t, http.StatusNotFound, resp.StatusCode)
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
assert.Contains(t, string(body), "Unknown namespace")
})
t.Run("case=returns expand tree", func(t *testing.T) {
rootSub := &ketoapi.SubjectSet{
Namespace: nspace.Name,
Object: "root",
Relation: "parent of",
}
expectedTree := &ketoapi.Tree[*ketoapi.RelationTuple]{
Type: ketoapi.TreeNodeUnion,
Tuple: &ketoapi.RelationTuple{
SubjectSet: rootSub,
},
Children: []*ketoapi.Tree[*ketoapi.RelationTuple]{
{
Type: ketoapi.TreeNodeLeaf,
Tuple: &ketoapi.RelationTuple{
SubjectID: new("child0"),
},
},
{
Type: ketoapi.TreeNodeLeaf,
Tuple: &ketoapi.RelationTuple{
SubjectID: new("child1"),
},
},
},
}
testhelpers.MapAndInsertTuples(t, reg,
&ketoapi.RelationTuple{
Namespace: nspace.Name,
Object: rootSub.Object,
Relation: rootSub.Relation,
SubjectID: expectedTree.Children[0].Tuple.SubjectID,
},
&ketoapi.RelationTuple{
Namespace: nspace.Name,
Object: rootSub.Object,
Relation: rootSub.Relation,
SubjectID: expectedTree.Children[1].Tuple.SubjectID,
},
)
qs := rootSub.ToURLQuery()
qs.Set("max-depth", "2")
resp, err := ts.Client().Get(ts.URL + expand.RouteBase + "?" + qs.Encode())
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
actualTree := ketoapi.Tree[*ketoapi.RelationTuple]{}
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
t.Logf("body: %s", string(body))
require.NoError(t, json.NewDecoder(bytes.NewBuffer(body)).Decode(&actualTree))
expand.AssertExternalTreesAreEqual(t, expectedTree, &actualTree)
})
}