Skip to content

Commit

Permalink
add filtering cluster list by author
Browse files Browse the repository at this point in the history
  • Loading branch information
Southclaws committed Oct 18, 2023
1 parent 35e6735 commit f36b201
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 42 deletions.
5 changes: 5 additions & 0 deletions api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,11 @@ paths:
required: false
in: query
schema: { $ref: "#/components/schemas/Identifier" }
- name: author
description: Show only results owned by this account.
required: false
in: query
schema: { $ref: "#/components/schemas/AccountHandle" }
responses:
default: { $ref: "#/components/responses/InternalServerError" }
"404": { $ref: "#/components/responses/NotFound" }
Expand Down
16 changes: 14 additions & 2 deletions app/resources/cluster_traversal/cluster_traversal.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,19 @@ import (
)

type Repository interface {
Root(ctx context.Context) ([]*datagraph.Cluster, error)
Subtree(ctx context.Context, id datagraph.ClusterID) ([]*datagraph.Cluster, error)
Root(ctx context.Context, opts ...Filter) ([]*datagraph.Cluster, error)
Subtree(ctx context.Context, id datagraph.ClusterID, opts ...Filter) ([]*datagraph.Cluster, error)
FilterSubtree(ctx context.Context, id datagraph.ClusterID, filter string) ([]*datagraph.Cluster, error)
}

type filters struct {
accountSlug *string
}

type Filter func(*filters)

func WithOwner(v string) Filter {
return func(f *filters) {
f.accountSlug = &v
}
}
33 changes: 27 additions & 6 deletions app/resources/cluster_traversal/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import (
"github.com/jmoiron/sqlx"
"github.com/rs/xid"

"github.com/Southclaws/storyden/app/resources/account"
account_repo "github.com/Southclaws/storyden/app/resources/account"
"github.com/Southclaws/storyden/app/resources/datagraph"
"github.com/Southclaws/storyden/app/resources/profile"
"github.com/Southclaws/storyden/internal/ent"
"github.com/Southclaws/storyden/internal/ent/account"
"github.com/Southclaws/storyden/internal/ent/cluster"
)

Expand All @@ -28,9 +29,18 @@ func New(db *ent.Client, raw *sqlx.DB) Repository {
return &database{db, raw}
}

func (d *database) Root(ctx context.Context) ([]*datagraph.Cluster, error) {
func (d *database) Root(ctx context.Context, fs ...Filter) ([]*datagraph.Cluster, error) {
query := d.db.Cluster.Query().Where(cluster.ParentClusterIDIsNil()).WithOwner()

f := filters{}
for _, fn := range fs {
fn(&f)
}

if f.accountSlug != nil {
query.Where(cluster.HasOwnerWith(account.Handle(*f.accountSlug)))
}

cs, err := query.All(ctx)
if err != nil {
return nil, fault.Wrap(err, fctx.With(ctx))
Expand Down Expand Up @@ -132,7 +142,7 @@ func fromRow(r subtreeRow) (*datagraph.Cluster, error) {
ImageURL: opt.NewPtr(r.ClusterImageUrl),
Description: r.ClusterDescription,
Owner: profile.Profile{
ID: account.AccountID(r.OwnerId),
ID: account_repo.AccountID(r.OwnerId),
Handle: r.OwnerHandle,
Name: r.OwnerName,
Bio: opt.NewPtr(r.OwnerBio).OrZero(),
Expand All @@ -142,9 +152,20 @@ func fromRow(r subtreeRow) (*datagraph.Cluster, error) {
}, nil
}

func (d *database) Subtree(ctx context.Context, id datagraph.ClusterID) ([]*datagraph.Cluster, error) {
filters := ""
r, err := d.raw.QueryxContext(ctx, fmt.Sprintf(ddl, filters), id.String())
func (d *database) Subtree(ctx context.Context, id datagraph.ClusterID, fs ...Filter) ([]*datagraph.Cluster, error) {
f := filters{}
for _, fn := range fs {
fn(&f)
}

predicates := ""
predicateN := 2
if f.accountSlug != nil {
predicates = fmt.Sprintf("%s AND a.handle = $%d", predicates, predicateN)
// predicateN++ // Do this when more predicates are added.
}

r, err := d.raw.QueryxContext(ctx, fmt.Sprintf(ddl, predicates), id.String())
if err != nil {
return nil, fault.Wrap(err, fctx.With(ctx))
}
Expand Down
10 changes: 8 additions & 2 deletions app/transports/openapi/bindings/clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,24 @@ func (c *Clusters) ClusterList(ctx context.Context, request openapi.ClusterListR
var cs []*datagraph.Cluster
var err error

opts := []cluster_traversal.Filter{}

if v := request.Params.Author; v != nil {
opts = append(opts, cluster_traversal.WithOwner(*v))
}

if id := request.Params.ClusterId; id != nil {
cid, err := xid.FromString(*id)
if err != nil {
return nil, fault.Wrap(err, fctx.With(ctx), ftag.With(ftag.InvalidArgument))
}

cs, err = c.ctr.Subtree(ctx, datagraph.ClusterID(cid))
cs, err = c.ctr.Subtree(ctx, datagraph.ClusterID(cid), opts...)
if err != nil {
return nil, fault.Wrap(err, fctx.With(ctx))
}
} else {
cs, err = c.ctr.Root(ctx)
cs, err = c.ctr.Root(ctx, opts...)
if err != nil {
return nil, fault.Wrap(err, fctx.With(ctx))
}
Expand Down
90 changes: 58 additions & 32 deletions internal/openapi/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

70 changes: 70 additions & 0 deletions tests/cluster/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,76 @@ func TestClustersHappyPath(t *testing.T) {
}))
}

func TestClustersFiltering(t *testing.T) {
t.Parallel()

integration.Test(t, nil, e2e.Setup(), fx.Invoke(func(
lc fx.Lifecycle,
ctx context.Context,
cl *openapi.ClientWithResponses,
cj *bindings.CookieJar,
ar account.Repository,
) {
lc.Append(fx.StartHook(func() {
r := require.New(t)
a := assert.New(t)

ctx1, acc1 := e2e.WithAccount(ctx, ar, seed.Account_001_Odin)
ctx2, acc2 := e2e.WithAccount(ctx, ar, seed.Account_002_Frigg)

name1 := "test-cluster-owned-by-1"
slug1 := name1 + uuid.NewString()
content1 := "# Clusters\n\nOwned by Odin."
clus1, err := cl.ClusterCreateWithResponse(ctx, openapi.ClusterInitialProps{
Name: name1,
Slug: slug1,
Description: "testing clusters api",
Content: &content1,
}, e2e.WithSession(ctx1, cj))
r.NoError(err)
r.NotNil(clus1)
r.Equal(200, clus1.StatusCode())

name2 := "test-cluster-owned-by-2"
slug2 := name2 + uuid.NewString()
content2 := "# Clusters\n\nOwned by Frigg."
clus2, err := cl.ClusterCreateWithResponse(ctx, openapi.ClusterInitialProps{
Name: name2,
Slug: slug2,
Description: "testing clusters api",
Content: &content2,
}, e2e.WithSession(ctx2, cj))
r.NoError(err)
r.NotNil(clus1)
r.Equal(200, clus1.StatusCode())

clist, err := cl.ClusterListWithResponse(ctx, &openapi.ClusterListParams{
Author: &acc1.Handle,
})
r.NoError(err)
r.NotNil(clist)
r.Equal(200, clist.StatusCode())

ids := dt.Map(clist.JSON200.Clusters, func(c openapi.Cluster) string { return c.Id })

a.Contains(ids, clus1.JSON200.Id)
a.NotContains(ids, clus2.JSON200.Id)

clist2, err := cl.ClusterListWithResponse(ctx, &openapi.ClusterListParams{
Author: &acc2.Handle,
})
r.NoError(err)
r.NotNil(clist2)
r.Equal(200, clist2.StatusCode())

ids2 := dt.Map(clist2.JSON200.Clusters, func(c openapi.Cluster) string { return c.Id })

a.NotContains(ids2, clus1.JSON200.Id)
a.Contains(ids2, clus2.JSON200.Id)
}))
}))
}

func TestClustersErrors(t *testing.T) {
t.Parallel()

Expand Down

1 comment on commit f36b201

@vercel
Copy link

@vercel vercel bot commented on f36b201 Oct 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.