Skip to content

Commit

Permalink
Merge pull request #158 from strideynet/strideynet/more-testing
Browse files Browse the repository at this point in the history
Add a few more tests and reorganise some code
  • Loading branch information
strideynet authored Aug 22, 2023
2 parents 77c4d99 + ed345f1 commit 28693da
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 68 deletions.
15 changes: 10 additions & 5 deletions api/server.go → api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,16 @@ func jsonHandler(log *zap.Logger, h func(r *http.Request) (any, error)) http.Han
}
}

type feedService interface {
Metas() []feed.Meta
GetFeedPosts(ctx context.Context, feedKey string, cursor string, limit int) (posts []feed.Post, err error)
}

func New(
log *zap.Logger,
hostname string,
listenAddr string,
feedRegistry *feed.Service,
feedService feedService,
pgxStore *store.PGXStore,
bskyCredentials *bluesky.Credentials,
authEngine *AuthEngine,
Expand All @@ -75,13 +80,13 @@ func New(
})

// Mount xrpc handlers
didEndpointPath, didHandler, err := didHandler(hostname)
didEndpointPath, didHandler, err := didHandler(log, hostname)
if err != nil {
return nil, fmt.Errorf("creating did handler: %w", err)
}
mux.Handle(didEndpointPath, didHandler)
mux.Handle(getFeedSkeletonHandler(log, feedRegistry))
mux.Handle(describeFeedGeneratorHandler(log, hostname, feedRegistry))
mux.Handle(getFeedSkeletonHandler(log, feedService))
mux.Handle(describeFeedGeneratorHandler(log, hostname, feedService))

// Mount Buf Connect services
modSvcHandler := &ModerationServiceHandler{
Expand All @@ -106,7 +111,7 @@ func New(
mux.Handle(
bffv1pbconnect.NewPublicServiceHandler(
&PublicServiceHandler{
feedMetaSourcer: feedRegistry,
feedService: feedService,
},
interceptors,
),
Expand Down
30 changes: 26 additions & 4 deletions api/server_test.go → api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"connectrpc.com/connect"
"context"
"errors"
"fmt"
indigoTest "github.com/bluesky-social/indigo/testing"
"github.com/stretchr/testify/require"
"github.com/strideynet/bsky-furry-feed/bluesky"
Expand All @@ -24,6 +25,18 @@ func actorAuthInterceptor(actor *indigoTest.TestUser) connect.UnaryInterceptorFu
}
}

type fakeFeedService struct {
metas []feed.Meta
}

func (m *fakeFeedService) Metas() []feed.Meta {
return m.metas
}

func (m *fakeFeedService) GetFeedPosts(ctx context.Context, feedKey string, cursor string, limit int) (posts []feed.Post, err error) {
return nil, fmt.Errorf("unimplemented")
}

type apiHarness struct {
*testenv.Harness
APIAddr string
Expand All @@ -33,12 +46,23 @@ func startAPIHarness(ctx context.Context, t *testing.T) *apiHarness {
harness := testenv.StartHarness(ctx, t)

// Create PDS user for the API taking actions as the feed
lis, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)

_ = harness.PDS.MustNewUser(t, "bff.tpds")
srv, err := New(
harness.Log,
"feed.test.furryli.st",
"",
"",
&feed.Service{},
&fakeFeedService{
metas: []feed.Meta{
{
ID: "fake-1",
DisplayName: "Fake",
Description: "My Description",
},
},
},
harness.Store,
&bluesky.Credentials{
Identifier: "bff.tpds",
Expand All @@ -53,8 +77,6 @@ func startAPIHarness(ctx context.Context, t *testing.T) *apiHarness {
t.Cleanup(func() {
srv.Close()
})
lis, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)

go func() {
err := srv.Serve(lis)
Expand Down
9 changes: 5 additions & 4 deletions api/describe_feed_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package api

import (
"fmt"
"github.com/strideynet/bsky-furry-feed/feed"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.uber.org/zap"
"net/http"
Expand All @@ -20,20 +19,22 @@ type describeFeedGeneratorResponse struct {
func describeFeedGeneratorHandler(
log *zap.Logger,
hostname string,
registry *feed.Service,
feedService feedService,
) (string, http.Handler) {
feedURI := func(feedName string) string {
return fmt.Sprintf(
// TODO(noah): This should be returning the profile that owns the
// content not the serverDID
"at://%s/app.bsky.feed.generator/%s",
serverDID(hostname),
feedName,
)
}

feeds := []describeFeedGeneratorResponseFeed{}
for _, id := range registry.IDs() {
for _, meta := range feedService.Metas() {
feeds = append(feeds, describeFeedGeneratorResponseFeed{
URI: feedURI(id),
URI: feedURI(meta.ID),
})
}

Expand Down
28 changes: 28 additions & 0 deletions api/describe_feed_generator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package api

import (
"context"
"github.com/stretchr/testify/require"
"io"
"net/http"
"testing"
)

func TestAPI_DescribeFeedGenerator(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
t.Parallel()

ctx := context.Background()
harness := startAPIHarness(ctx, t)
resp, err := http.Get(harness.APIAddr + "/xrpc/app.bsky.feed.describeFeedGenerator")
require.NoError(t, err)
defer resp.Body.Close()
require.Equal(t, http.StatusOK, resp.StatusCode)
bytes, err := io.ReadAll(resp.Body)
require.NoError(t, err)

want := `{"did":"did:web:feed.test.furryli.st","feeds":[{"uri":"at://did:web:feed.test.furryli.st/app.bsky.feed.generator/fake-1"}]}` + "\n"
require.Equal(t, want, string(bytes))
}
49 changes: 24 additions & 25 deletions api/did.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package api

import (
"encoding/json"
"fmt"
"go.uber.org/zap"
"net/http"

"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
Expand All @@ -12,33 +12,32 @@ func serverDID(hostname string) string {
return fmt.Sprintf("did:web:%s", hostname)
}

func generateDIDJSON(hostname string) ([]byte, error) {
type Object map[string]any

did := Object{
"@context": []string{"https://www.w3.org/ns/did/v1"},
"id": serverDID(hostname),
"service": []Object{{
"id": "#bsky_fg",
"type": "BskyFeedGenerator",
"serviceEndpoint": fmt.Sprintf("https://%s", hostname),
}},
}

return json.Marshal(did)
type WebDIDService struct {
ID string `json:"id"`
Type string `json:"type"`
ServiceEndpoint string `json:"serviceEndpoint"`
}

func didHandler(hostname string) (string, http.Handler, error) {
did, err := generateDIDJSON(hostname)
if err != nil {
return "", nil, fmt.Errorf("generating did json: %w", err)
}

var h http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
type WebDID struct {
Context []string `json:"@context"`
ID string `json:"id"`
Service []WebDIDService `json:"service"`
}

_, _ = w.Write(did)
}
func didHandler(log *zap.Logger, hostname string) (string, http.Handler, error) {
h := jsonHandler(log, func(r *http.Request) (any, error) {
return WebDID{
Context: []string{"https://www.w3.org/ns/did/v1"},
ID: serverDID(hostname),
Service: []WebDIDService{
{
ID: "#bsky_fg",
Type: "BskyFeedGenerator",
ServiceEndpoint: fmt.Sprintf("https://%s", hostname),
},
},
}, nil
})

return "/.well-known/did.json", otelhttp.NewHandler(h, "get_well_known_did"), nil
}
28 changes: 28 additions & 0 deletions api/did_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package api

import (
"context"
"github.com/stretchr/testify/require"
"io"
"net/http"
"testing"
)

func TestAPI_WellKnownDID(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
t.Parallel()

ctx := context.Background()
harness := startAPIHarness(ctx, t)
resp, err := http.Get(harness.APIAddr + "/.well-known/did.json")
require.NoError(t, err)
defer resp.Body.Close()
require.Equal(t, http.StatusOK, resp.StatusCode)
bytes, err := io.ReadAll(resp.Body)
require.NoError(t, err)

want := `{"@context":["https://www.w3.org/ns/did/v1"],"id":"did:web:feed.test.furryli.st","service":[{"id":"#bsky_fg","type":"BskyFeedGenerator","serviceEndpoint":"https://feed.test.furryli.st"}]}` + "\n"
require.Equal(t, want, string(bytes))
}
5 changes: 2 additions & 3 deletions api/get_feed_skeleton.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package api

import (
"fmt"
"github.com/strideynet/bsky-furry-feed/feed"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.uber.org/zap"
"net/http"
Expand Down Expand Up @@ -64,7 +63,7 @@ type getFeedSkeletonResponse struct {
}

func getFeedSkeletonHandler(
log *zap.Logger, registry *feed.Service,
log *zap.Logger, feedService feedService,
) (string, http.Handler) {
h := jsonHandler(log, func(r *http.Request) (any, error) {
ctx := r.Context()
Expand All @@ -80,7 +79,7 @@ func getFeedSkeletonHandler(
zap.Int("limit", params.limit),
)

posts, err := registry.GetFeedPosts(ctx, params.feed, params.cursor, params.limit)
posts, err := feedService.GetFeedPosts(ctx, params.feed, params.cursor, params.limit)
if err != nil {
return nil, fmt.Errorf("fetching feed %q: %w", params.feed, err)
}
Expand Down
2 changes: 1 addition & 1 deletion api/moderation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"testing"
)

func TestModerationServiceHandler_CreateActor(t *testing.T) {
func TestAPI_ModerationServiceHandler_CreateActor(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
Expand Down
9 changes: 2 additions & 7 deletions api/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,16 @@ import (
"connectrpc.com/connect"
"context"
"fmt"
"github.com/strideynet/bsky-furry-feed/feed"
v1 "github.com/strideynet/bsky-furry-feed/proto/bff/v1"
)

type feedMetaSourcer interface {
Metas() []feed.Meta
}

type PublicServiceHandler struct {
feedMetaSourcer feedMetaSourcer
feedService feedService
}

func (p *PublicServiceHandler) ListFeeds(_ context.Context, _ *connect.Request[v1.ListFeedsRequest]) (*connect.Response[v1.ListFeedsResponse], error) {
feeds := []*v1.Feed{}
for _, f := range p.feedMetaSourcer.Metas() {
for _, f := range p.feedService.Metas() {
feeds = append(feeds, &v1.Feed{
Id: f.ID,
// TODO(noah): Take BLUESKY_USERNAME and inject that instead of this
Expand Down
10 changes: 1 addition & 9 deletions api/public_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,8 @@ import (
"testing"
)

type fakeMetaSourcer struct {
metas []feed.Meta
}

func (m *fakeMetaSourcer) Metas() []feed.Meta {
return m.metas
}

func TestPublicServiceHandler_ListFeeds(t *testing.T) {
h := PublicServiceHandler{feedMetaSourcer: &fakeMetaSourcer{
h := PublicServiceHandler{feedService: &fakeFeedService{
metas: []feed.Meta{
{
ID: "foo",
Expand Down
2 changes: 1 addition & 1 deletion api/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"testing"
)

func TestUserServiceHandler_GetMe(t *testing.T) {
func TestAPI_UserServiceHandler_GetMe(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
Expand Down
9 changes: 0 additions & 9 deletions feed/feed.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,6 @@ func (s *Service) Register(m Meta, generateFunc GenerateFunc) {
}
}

// IDs returns a slice of the IDs of feeds which are eligible for generation.
func (s *Service) IDs() []string {
ids := make([]string, 0, len(s.feeds))
for _, f := range s.feeds {
ids = append(ids, f.meta.ID)
}
return ids
}

func (s *Service) Metas() []Meta {
metas := make([]Meta, 0, len(s.feeds))
for _, f := range s.feeds {
Expand Down

1 comment on commit 28693da

@vercel
Copy link

@vercel vercel bot commented on 28693da Aug 22, 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.