Folded back handlers typer functionality into the activitypub package
This commit is contained in:
commit
051d30fa3f
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2017 Marius Orcsik
|
||||
Copyright (c) 2017 Golang ActitvityPub
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -143,18 +143,12 @@ type Collection struct {
|
|||
|
||||
type (
|
||||
// FollowersCollection is a collection of followers
|
||||
FollowersCollection = Followers
|
||||
|
||||
// Followers is a Collection type
|
||||
Followers = Collection
|
||||
FollowersCollection = Collection
|
||||
|
||||
// FollowingCollection is a list of everybody that the actor has followed, added as a side effect.
|
||||
// The following collection MUST be either an OrderedCollection or a Collection and MAY
|
||||
// be filtered on privileges of an authenticated user or as appropriate when no authentication is given.
|
||||
FollowingCollection = Following
|
||||
|
||||
// Following is a type alias for a simple Collection
|
||||
Following = Collection
|
||||
FollowingCollection = Collection
|
||||
)
|
||||
|
||||
// CollectionNew initializes a new Collection
|
||||
|
@ -347,20 +341,6 @@ func ToCollection(it Item) (*Collection, error) {
|
|||
return nil, ErrorInvalidType[Collection](it)
|
||||
}
|
||||
|
||||
// FollowingNew initializes a new Following
|
||||
func FollowingNew() *Following {
|
||||
id := ID("following")
|
||||
|
||||
i := Following{ID: id, Type: CollectionType}
|
||||
i.Name = NaturalLanguageValuesNew()
|
||||
i.Content = NaturalLanguageValuesNew()
|
||||
i.Summary = NaturalLanguageValuesNew()
|
||||
|
||||
i.TotalItems = 0
|
||||
|
||||
return &i
|
||||
}
|
||||
|
||||
// ItemsMatch
|
||||
func (c Collection) ItemsMatch(col ...Item) bool {
|
||||
for _, it := range col {
|
||||
|
|
|
@ -27,7 +27,7 @@ func TestCollection_Append(t *testing.T) {
|
|||
c.Append(val)
|
||||
|
||||
if c.Count() != 1 {
|
||||
t.Errorf("Inbox collection of %q should have one element", c.GetID())
|
||||
t.Errorf("Inbox collectionPath of %q should have one element", c.GetID())
|
||||
}
|
||||
if !reflect.DeepEqual(c.Items[0], val) {
|
||||
t.Errorf("First item in Inbox is does not match %q", val.ID)
|
||||
|
|
2
go.mod
2
go.mod
|
@ -4,6 +4,8 @@ go 1.18
|
|||
|
||||
require (
|
||||
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20200411073322-f0bcc40f0bf2
|
||||
github.com/go-ap/errors v0.0.0-20220529131844-4c7dbeabb369
|
||||
github.com/go-ap/jsonld v0.0.0-20200327122108-fafac2de2660
|
||||
github.com/go-ap/storage v0.0.0-20220529132413-43d0dcf851c6
|
||||
github.com/valyala/fastjson v1.6.3
|
||||
)
|
||||
|
|
21
helpers.go
21
helpers.go
|
@ -40,6 +40,27 @@ type WithOrderedCollectionPageFn func(*OrderedCollectionPage) error
|
|||
// WithItemCollectionFn represents a function type that can be used as a parameter for OnItemCollection helper function
|
||||
type WithItemCollectionFn func(*ItemCollection) error
|
||||
|
||||
/*
|
||||
func To[T Objects](it Item) (*T, error) {
|
||||
ob, ok := it.(T)
|
||||
if !ok {
|
||||
return nil, errors.New("Invalid cast to %T for object %T", T, it)
|
||||
}
|
||||
return &ob, nil
|
||||
}
|
||||
|
||||
func On[T Objects](it Item, fn func(ob *T)) error {
|
||||
if IsNil(it) {
|
||||
return nil
|
||||
}
|
||||
ob, err := To[T](it)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return fn(ob)
|
||||
}
|
||||
*/
|
||||
|
||||
// OnLink calls function fn on it Item if it can be asserted to type *Link
|
||||
//
|
||||
// This function should be safe to use for all types with a structure compatible
|
||||
|
|
|
@ -126,45 +126,30 @@ type (
|
|||
// In general, the owner of an inbox is likely to be able to access all of their inbox contents.
|
||||
// Depending on access control, some other content may be public, whereas other content may
|
||||
// require authentication for non-owner users, if they can access the inbox at all.
|
||||
InboxStream = Inbox
|
||||
|
||||
// Inbox is a type alias for an Ordered Collection
|
||||
Inbox = OrderedCollection
|
||||
InboxStream = OrderedCollection
|
||||
|
||||
// LikedCollection is a list of every object from all of the actor's Like activities,
|
||||
// added as a side effect. The liked collection MUST be either an OrderedCollection or
|
||||
// a Collection and MAY be filtered on privileges of an authenticated user or as
|
||||
// appropriate when no authentication is given.
|
||||
LikedCollection = Liked
|
||||
|
||||
// Liked is a type alias for an Ordered Collection
|
||||
Liked = OrderedCollection
|
||||
LikedCollection = OrderedCollection
|
||||
|
||||
// LikesCollection is a list of all Like activities with this object as the object property,
|
||||
// added as a side effect. The likes collection MUST be either an OrderedCollection or a Collection
|
||||
// and MAY be filtered on privileges of an authenticated user or as appropriate when
|
||||
// no authentication is given.
|
||||
LikesCollection = Likes
|
||||
|
||||
// Likes is a type alias for an Ordered Collection
|
||||
Likes = OrderedCollection
|
||||
LikesCollection = OrderedCollection
|
||||
|
||||
// OutboxStream contains activities the user has published,
|
||||
// subject to the ability of the requestor to retrieve the activity (that is,
|
||||
// the contents of the outbox are filtered by the permissions of the person reading it).
|
||||
OutboxStream = Outbox
|
||||
|
||||
// Outbox is a type alias for an Ordered Collection
|
||||
Outbox = OrderedCollection
|
||||
OutboxStream = OrderedCollection
|
||||
|
||||
// SharesCollection is a list of all Announce activities with this object as the object property,
|
||||
// added as a side effect. The shares collection MUST be either an OrderedCollection or a Collection
|
||||
// and MAY be filtered on privileges of an authenticated user or as appropriate when no authentication
|
||||
// is given.
|
||||
SharesCollection = Shares
|
||||
|
||||
// Shares is a type alias for an Ordered Collection
|
||||
Shares = OrderedCollection
|
||||
SharesCollection = OrderedCollection
|
||||
)
|
||||
|
||||
// GetType returns the OrderedCollection's type
|
||||
|
@ -382,71 +367,6 @@ func copyOrderedCollectionToPage(c *OrderedCollection, p *OrderedCollectionPage)
|
|||
return nil
|
||||
}
|
||||
|
||||
// InboxNew initializes a new Inbox
|
||||
func InboxNew() *OrderedCollection {
|
||||
id := ID("inbox")
|
||||
|
||||
i := OrderedCollection{ID: id, Type: CollectionType}
|
||||
i.Name = NaturalLanguageValuesNew()
|
||||
i.Content = NaturalLanguageValuesNew()
|
||||
|
||||
i.TotalItems = 0
|
||||
|
||||
return &i
|
||||
}
|
||||
|
||||
// LikedCollection initializes a new outbox
|
||||
func LikedNew() *OrderedCollection {
|
||||
id := ID("liked")
|
||||
|
||||
l := OrderedCollection{ID: id, Type: CollectionType}
|
||||
l.Name = NaturalLanguageValuesNew()
|
||||
l.Content = NaturalLanguageValuesNew()
|
||||
|
||||
l.TotalItems = 0
|
||||
|
||||
return &l
|
||||
}
|
||||
|
||||
// LikesCollection initializes a new outbox
|
||||
func LikesNew() *Likes {
|
||||
id := ID("likes")
|
||||
|
||||
l := Likes{ID: id, Type: CollectionType}
|
||||
l.Name = NaturalLanguageValuesNew()
|
||||
l.Content = NaturalLanguageValuesNew()
|
||||
|
||||
l.TotalItems = 0
|
||||
|
||||
return &l
|
||||
}
|
||||
|
||||
// OutboxNew initializes a new outbox
|
||||
func OutboxNew() *Outbox {
|
||||
id := ID("outbox")
|
||||
|
||||
i := Outbox{ID: id, Type: OrderedCollectionType}
|
||||
i.Name = NaturalLanguageValuesNew()
|
||||
i.Content = NaturalLanguageValuesNew()
|
||||
i.TotalItems = 0
|
||||
i.OrderedItems = make(ItemCollection, 0)
|
||||
|
||||
return &i
|
||||
}
|
||||
|
||||
// SharesNew initializes a new Shares
|
||||
func SharesNew() *Shares {
|
||||
id := ID("Shares")
|
||||
|
||||
i := Shares{ID: id, Type: CollectionType}
|
||||
i.Name = NaturalLanguageValuesNew()
|
||||
i.Content = NaturalLanguageValuesNew()
|
||||
|
||||
i.TotalItems = 0
|
||||
|
||||
return &i
|
||||
}
|
||||
|
||||
// ItemsMatch
|
||||
func (o OrderedCollection) ItemsMatch(col ...Item) bool {
|
||||
for _, it := range col {
|
||||
|
|
|
@ -269,77 +269,6 @@ func TestOrderedCollection_Contains(t *testing.T) {
|
|||
t.Skipf("TODO")
|
||||
}
|
||||
|
||||
func TestInboxNew(t *testing.T) {
|
||||
i := InboxNew()
|
||||
|
||||
id := ID("inbox")
|
||||
if i.ID != id {
|
||||
t.Errorf("%T should be initialized with %q as %T", i, id, id)
|
||||
}
|
||||
if len(i.Name) != 0 {
|
||||
t.Errorf("%T should be initialized with 0 length Name", i)
|
||||
}
|
||||
if len(i.Content) != 0 {
|
||||
t.Errorf("%T should be initialized with 0 length Content", i)
|
||||
}
|
||||
if len(i.Summary) != 0 {
|
||||
t.Errorf("%T should be initialized with 0 length Summary", i)
|
||||
}
|
||||
if i.TotalItems != 0 {
|
||||
t.Errorf("%T should be initialized with 0 TotalItems", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLikedNew(t *testing.T) {
|
||||
l := LikedNew()
|
||||
|
||||
id := ID("liked")
|
||||
if l.ID != id {
|
||||
t.Errorf("%T should be initialized with %q as %T", l, id, id)
|
||||
}
|
||||
if len(l.Name) != 0 {
|
||||
t.Errorf("%T should be initialized with 0 length Name", l)
|
||||
}
|
||||
if len(l.Content) != 0 {
|
||||
t.Errorf("%T should be initialized with 0 length Content", l)
|
||||
}
|
||||
if len(l.Summary) != 0 {
|
||||
t.Errorf("%T should be initialized with 0 length Summary", l)
|
||||
}
|
||||
if l.TotalItems != 0 {
|
||||
t.Errorf("%T should be initialized with 0 TotalItems", l)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLikesNew(t *testing.T) {
|
||||
t.Skipf("TODO")
|
||||
}
|
||||
|
||||
func TestOutboxNew(t *testing.T) {
|
||||
o := OutboxNew()
|
||||
|
||||
id := ID("outbox")
|
||||
if o.ID != id {
|
||||
t.Errorf("%T should be initialized with %q as %T", o, id, id)
|
||||
}
|
||||
if len(o.Name) != 0 {
|
||||
t.Errorf("%T should be initialized with 0 length Name", o)
|
||||
}
|
||||
if len(o.Content) != 0 {
|
||||
t.Errorf("%T should be initialized with 0 length Content", o)
|
||||
}
|
||||
if len(o.Summary) != 0 {
|
||||
t.Errorf("%T should be initialized with 0 length Summary", o)
|
||||
}
|
||||
if o.TotalItems != 0 {
|
||||
t.Errorf("%T should be initialized with 0 TotalItems", o)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSharesNew(t *testing.T) {
|
||||
t.Skipf("TODO")
|
||||
}
|
||||
|
||||
func TestOrderedCollection_MarshalJSON(t *testing.T) {
|
||||
t.Skipf("TODO")
|
||||
}
|
||||
|
|
292
typer.go
Normal file
292
typer.go
Normal file
|
@ -0,0 +1,292 @@
|
|||
package activitypub
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/go-ap/errors"
|
||||
)
|
||||
|
||||
// collectionPath
|
||||
type collectionPath string
|
||||
|
||||
// CollectionPaths
|
||||
type CollectionPaths []collectionPath
|
||||
|
||||
const (
|
||||
Unknown = collectionPath("")
|
||||
Outbox = collectionPath("outbox")
|
||||
Inbox = collectionPath("inbox")
|
||||
Shares = collectionPath("shares")
|
||||
Replies = collectionPath("replies") // activitystreams
|
||||
Following = collectionPath("following")
|
||||
Followers = collectionPath("followers")
|
||||
Liked = collectionPath("liked")
|
||||
Likes = collectionPath("likes")
|
||||
)
|
||||
|
||||
func CollectionPath(s string) collectionPath {
|
||||
return collectionPath(s)
|
||||
}
|
||||
|
||||
// Typer is the static package variable that determines a collectionPath type for a particular request
|
||||
// It can be overloaded from outside packages.
|
||||
// @TODO(marius): This should be moved as a property on an instantiable package object, instead of keeping it here
|
||||
var Typer CollectionTyper = pathTyper{}
|
||||
|
||||
// CollectionTyper allows external packages to tell us which collectionPath the current HTTP request addresses
|
||||
type CollectionTyper interface {
|
||||
Type(r *http.Request) collectionPath
|
||||
}
|
||||
|
||||
type pathTyper struct{}
|
||||
|
||||
func (d pathTyper) Type(r *http.Request) collectionPath {
|
||||
if r.URL == nil || len(r.URL.Path) == 0 {
|
||||
return Unknown
|
||||
}
|
||||
col := Unknown
|
||||
pathElements := strings.Split(r.URL.Path[1:], "/") // Skip first /
|
||||
for i := len(pathElements) - 1; i >= 0; i-- {
|
||||
col = collectionPath(pathElements[i])
|
||||
if typ := getValidActivityCollection(col); typ != Unknown {
|
||||
return typ
|
||||
}
|
||||
if typ := getValidObjectCollection(col); typ != Unknown {
|
||||
return typ
|
||||
}
|
||||
}
|
||||
|
||||
return col
|
||||
}
|
||||
|
||||
var (
|
||||
validActivityCollection = CollectionPaths{
|
||||
Outbox,
|
||||
Inbox,
|
||||
Likes,
|
||||
Shares,
|
||||
Replies, // activitystreams
|
||||
}
|
||||
OfObject = CollectionPaths{
|
||||
Likes,
|
||||
Shares,
|
||||
Replies,
|
||||
}
|
||||
OfActor = CollectionPaths{
|
||||
Outbox,
|
||||
Inbox,
|
||||
Liked,
|
||||
Following,
|
||||
Followers,
|
||||
}
|
||||
|
||||
ActivityPubCollections = CollectionPaths{
|
||||
Outbox,
|
||||
Inbox,
|
||||
Liked,
|
||||
Following,
|
||||
Followers,
|
||||
Likes,
|
||||
Shares,
|
||||
Replies,
|
||||
}
|
||||
)
|
||||
|
||||
func (t CollectionPaths) Contains(typ collectionPath) bool {
|
||||
for _, tt := range t {
|
||||
if strings.ToLower(string(typ)) == string(tt) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Split splits the IRI in an actor IRI and its collectionPath
|
||||
// if the collectionPath is found in the elements in the t CollectionPaths slice
|
||||
func (t CollectionPaths) Split(i IRI) (IRI, collectionPath) {
|
||||
maybeActor, maybeCol := path.Split(i.String())
|
||||
tt := collectionPath(maybeCol)
|
||||
if !t.Contains(tt) {
|
||||
tt = ""
|
||||
maybeActor = i.String()
|
||||
}
|
||||
iri := IRI(strings.TrimRight(maybeActor, "/"))
|
||||
return iri, tt
|
||||
}
|
||||
|
||||
// IRIf formats an IRI from an existing IRI and the collectionPath type
|
||||
func IRIf(i IRI, t collectionPath) IRI {
|
||||
onePastLast := len(i)
|
||||
if onePastLast > 1 && i[onePastLast-1] == '/' {
|
||||
i = i[:onePastLast-1]
|
||||
}
|
||||
return IRI(fmt.Sprintf("%s/%s", i, t))
|
||||
}
|
||||
|
||||
// IRI gives us the IRI of the t collectionPath type corresponding to the i Item,
|
||||
// or generates a new one if not found.
|
||||
func (t collectionPath) IRI(i Item) IRI {
|
||||
if IsNil(i) {
|
||||
return IRIf("", t)
|
||||
}
|
||||
if IsObject(i) {
|
||||
if it := t.Of(i); !IsNil(it) {
|
||||
return it.GetLink()
|
||||
}
|
||||
}
|
||||
return IRIf(i.GetLink(), t)
|
||||
}
|
||||
|
||||
// Of gives us the property of the i Item that corresponds to the t collectionPath type.
|
||||
func (t collectionPath) Of(i Item) Item {
|
||||
if IsNil(i) || !i.IsObject() {
|
||||
return nil
|
||||
}
|
||||
var it Item
|
||||
if OfActor.Contains(t) && ActorTypes.Contains(i.GetType()) {
|
||||
OnActor(i, func(a *Actor) error {
|
||||
switch t {
|
||||
case Inbox:
|
||||
it = a.Inbox
|
||||
case Outbox:
|
||||
it = a.Outbox
|
||||
case Liked:
|
||||
it = a.Liked
|
||||
case Following:
|
||||
it = a.Following
|
||||
case Followers:
|
||||
it = a.Followers
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
OnObject(i, func(o *Object) error {
|
||||
switch t {
|
||||
case Likes:
|
||||
it = o.Likes
|
||||
case Shares:
|
||||
it = o.Shares
|
||||
case Replies:
|
||||
it = o.Replies
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return it
|
||||
}
|
||||
|
||||
// OfActor returns the base IRI of received i, if i represents an IRI matching collectionPath type t
|
||||
func (t collectionPath) OfActor(i IRI) (IRI, error) {
|
||||
maybeActor, maybeCol := path.Split(i.String())
|
||||
if strings.ToLower(maybeCol) == strings.ToLower(string(t)) {
|
||||
maybeActor = strings.TrimRight(maybeActor, "/")
|
||||
return IRI(maybeActor), nil
|
||||
}
|
||||
return EmptyIRI, errors.Newf("IRI does not represent a valid %s collectionPath", t)
|
||||
}
|
||||
|
||||
// Split returns the base IRI of received i, if i represents an IRI matching collectionPath type t
|
||||
func Split(i IRI) (IRI, collectionPath) {
|
||||
return ActivityPubCollections.Split(i)
|
||||
}
|
||||
|
||||
func getValidActivityCollection(t collectionPath) collectionPath {
|
||||
if validActivityCollection.Contains(t) {
|
||||
return t
|
||||
}
|
||||
return Unknown
|
||||
}
|
||||
|
||||
// ValidActivityCollection shows if the current ActivityPub end-point type is a valid one for handling Activities
|
||||
func ValidActivityCollection(typ collectionPath) bool {
|
||||
return getValidActivityCollection(typ) != Unknown
|
||||
}
|
||||
|
||||
var validObjectCollection = []collectionPath{
|
||||
Following,
|
||||
Followers,
|
||||
Liked,
|
||||
}
|
||||
|
||||
func getValidObjectCollection(typ collectionPath) collectionPath {
|
||||
for _, t := range validObjectCollection {
|
||||
if strings.ToLower(string(typ)) == string(t) {
|
||||
return t
|
||||
}
|
||||
}
|
||||
return Unknown
|
||||
}
|
||||
|
||||
// ValidActivityCollection shows if the current ActivityPub end-point type is a valid one for handling Objects
|
||||
func ValidObjectCollection(typ collectionPath) bool {
|
||||
return getValidObjectCollection(typ) != Unknown
|
||||
}
|
||||
|
||||
func getValidCollection(typ collectionPath) collectionPath {
|
||||
if typ := getValidActivityCollection(typ); typ != Unknown {
|
||||
return typ
|
||||
}
|
||||
if typ := getValidObjectCollection(typ); typ != Unknown {
|
||||
return typ
|
||||
}
|
||||
return Unknown
|
||||
}
|
||||
|
||||
func ValidCollection(typ collectionPath) bool {
|
||||
return getValidCollection(typ) != Unknown
|
||||
}
|
||||
|
||||
func ValidCollectionIRI(i IRI) bool {
|
||||
_, t := Split(i)
|
||||
return getValidCollection(t) != Unknown
|
||||
}
|
||||
|
||||
// AddTo adds collectionPath type IRI on the corresponding property of the i Item
|
||||
func (t collectionPath) AddTo(i Item) (IRI, bool) {
|
||||
if IsNil(i) || !i.IsObject() {
|
||||
return NilIRI, false
|
||||
}
|
||||
status := false
|
||||
var iri IRI
|
||||
if OfActor.Contains(t) {
|
||||
OnActor(i, func(a *Actor) error {
|
||||
if status = t == Inbox && IsNil(a.Inbox); status {
|
||||
a.Inbox = IRIf(a.GetLink(), t)
|
||||
iri = a.Inbox.GetLink()
|
||||
} else if status = t == Outbox && IsNil(a.Outbox); status {
|
||||
a.Outbox = IRIf(a.GetLink(), t)
|
||||
iri = a.Outbox.GetLink()
|
||||
} else if status = t == Liked && IsNil(a.Liked); status {
|
||||
a.Liked = IRIf(a.GetLink(), t)
|
||||
iri = a.Liked.GetLink()
|
||||
} else if status = t == Following && IsNil(a.Following); status {
|
||||
a.Following = IRIf(a.GetLink(), t)
|
||||
iri = a.Following.GetLink()
|
||||
} else if status = t == Followers && IsNil(a.Followers); status {
|
||||
a.Followers = IRIf(a.GetLink(), t)
|
||||
iri = a.Followers.GetLink()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
} else if OfObject.Contains(t) {
|
||||
OnObject(i, func(o *Object) error {
|
||||
if status = t == Likes && IsNil(o.Likes); status {
|
||||
o.Likes = IRIf(o.GetLink(), t)
|
||||
iri = o.Likes.GetLink()
|
||||
} else if status = t == Shares && IsNil(o.Shares); status {
|
||||
o.Shares = IRIf(o.GetLink(), t)
|
||||
iri = o.Shares.GetLink()
|
||||
} else if status = t == Replies && IsNil(o.Replies); status {
|
||||
o.Replies = IRIf(o.GetLink(), t)
|
||||
iri = o.Replies.GetLink()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
} else {
|
||||
iri = IRIf(i.GetLink(), t)
|
||||
}
|
||||
return iri, status
|
||||
}
|
282
typer_test.go
Normal file
282
typer_test.go
Normal file
|
@ -0,0 +1,282 @@
|
|||
package activitypub
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPathTyper_Type(t *testing.T) {
|
||||
t.Skipf("TODO")
|
||||
}
|
||||
|
||||
func TestValidActivityCollection(t *testing.T) {
|
||||
t.Skipf("TODO")
|
||||
}
|
||||
|
||||
func TestValidCollection(t *testing.T) {
|
||||
t.Skipf("TODO")
|
||||
}
|
||||
|
||||
func TestValidObjectCollection(t *testing.T) {
|
||||
t.Skipf("TODO")
|
||||
}
|
||||
|
||||
func TestValidCollectionIRI(t *testing.T) {
|
||||
t.Skipf("TODO")
|
||||
}
|
||||
|
||||
func TestSplit(t *testing.T) {
|
||||
t.Skipf("TODO")
|
||||
}
|
||||
|
||||
func TestCollectionTypes_Of(t *testing.T) {
|
||||
type args struct {
|
||||
o Item
|
||||
t collectionPath
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want Item
|
||||
}{
|
||||
{
|
||||
name: "nil from nil object",
|
||||
args: args{
|
||||
o: nil,
|
||||
t: "likes",
|
||||
},
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
name: "nil from invalid collectionPath type",
|
||||
args: args{
|
||||
o: Object{
|
||||
Likes: IRI("test"),
|
||||
},
|
||||
t: "like",
|
||||
},
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
name: "nil from nil collectionPath type",
|
||||
args: args{
|
||||
o: Object{
|
||||
Likes: nil,
|
||||
},
|
||||
t: "likes",
|
||||
},
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
name: "get likes iri",
|
||||
args: args{
|
||||
o: Object{
|
||||
Likes: IRI("test"),
|
||||
},
|
||||
t: "likes",
|
||||
},
|
||||
want: IRI("test"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if ob := test.args.t.Of(test.args.o); ob != test.want {
|
||||
t.Errorf("Object received %#v is different, expected #%v", ob, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectionType_IRI(t *testing.T) {
|
||||
type args struct {
|
||||
o Item
|
||||
t collectionPath
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want IRI
|
||||
}{
|
||||
{
|
||||
name: "just path from nil object",
|
||||
args: args{
|
||||
o: nil,
|
||||
t: "likes",
|
||||
},
|
||||
want: IRI("/likes"),
|
||||
},
|
||||
{
|
||||
name: "emptyIRI from invalid collectionPath type",
|
||||
args: args{
|
||||
o: Object{
|
||||
Likes: IRI("test"),
|
||||
},
|
||||
t: "like",
|
||||
},
|
||||
want: "/like",
|
||||
},
|
||||
{
|
||||
name: "just path from object without ID",
|
||||
args: args{
|
||||
o: Object{},
|
||||
t: "likes",
|
||||
},
|
||||
want: IRI("/likes"),
|
||||
},
|
||||
{
|
||||
name: "likes iri on object",
|
||||
args: args{
|
||||
o: Object{
|
||||
ID: "http://example.com",
|
||||
Likes: IRI("test"),
|
||||
},
|
||||
t: "likes",
|
||||
},
|
||||
want: IRI("test"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if ob := test.args.t.IRI(test.args.o); ob != test.want {
|
||||
t.Errorf("IRI received %q is different, expected %q", ob, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectionType_OfActor(t *testing.T) {
|
||||
t.Skipf("TODO")
|
||||
}
|
||||
|
||||
func TestCollectionTypes_Contains(t *testing.T) {
|
||||
t.Skipf("TODO")
|
||||
}
|
||||
|
||||
func TestIRIf(t *testing.T) {
|
||||
type args struct {
|
||||
i IRI
|
||||
t collectionPath
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want IRI
|
||||
}{
|
||||
{
|
||||
name: "empty iri",
|
||||
args: args{
|
||||
i: "",
|
||||
t: "inbox",
|
||||
},
|
||||
want: "/inbox",
|
||||
},
|
||||
{
|
||||
name: "plain concat",
|
||||
args: args{
|
||||
i: "https://example.com",
|
||||
t: "inbox",
|
||||
},
|
||||
want: "https://example.com/inbox",
|
||||
},
|
||||
{
|
||||
name: "strip root from iri",
|
||||
args: args{
|
||||
i: "https://example.com/",
|
||||
t: "inbox",
|
||||
},
|
||||
want: "https://example.com/inbox",
|
||||
},
|
||||
{
|
||||
name: "invalid iri",
|
||||
args: args{
|
||||
i: "example.com",
|
||||
t: "test",
|
||||
},
|
||||
want: "example.com/test",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := IRIf(tt.args.i, tt.args.t); got != tt.want {
|
||||
t.Errorf("IRIf() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectionType_AddTo(t *testing.T) {
|
||||
type args struct {
|
||||
i Item
|
||||
}
|
||||
var i Item
|
||||
var o *Object
|
||||
tests := []struct {
|
||||
name string
|
||||
t collectionPath
|
||||
args args
|
||||
want IRI
|
||||
want1 bool
|
||||
}{
|
||||
{
|
||||
name: "simple",
|
||||
t: "test",
|
||||
args: args{
|
||||
i: &Object{ID: "http://example.com/addTo"},
|
||||
},
|
||||
want: "http://example.com/addTo/test",
|
||||
want1: false, // this seems to always be false
|
||||
},
|
||||
{
|
||||
name: "on-nil-item",
|
||||
t: "test",
|
||||
args: args{
|
||||
i: i,
|
||||
},
|
||||
want: NilIRI,
|
||||
want1: false,
|
||||
},
|
||||
{
|
||||
name: "on-nil",
|
||||
t: "test",
|
||||
args: args{
|
||||
i: nil,
|
||||
},
|
||||
want: NilIRI,
|
||||
want1: false,
|
||||
},
|
||||
{
|
||||
name: "on-nil-object",
|
||||
t: "test",
|
||||
args: args{
|
||||
i: o,
|
||||
},
|
||||
want: NilIRI,
|
||||
want1: false,
|
||||
},
|
||||
{
|
||||
name: "on-nil-item",
|
||||
t: "test",
|
||||
args: args{
|
||||
i: i,
|
||||
},
|
||||
want: NilIRI,
|
||||
want1: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, got1 := tt.t.AddTo(tt.args.i)
|
||||
if got != tt.want {
|
||||
t.Errorf("AddTo() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
if got1 != tt.want1 {
|
||||
t.Errorf("AddTo() got1 = %v, want %v", got1, tt.want1)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectionTypes_Split(t *testing.T) {
|
||||
t.Skipf("TODO")
|
||||
}
|
Reference in a new issue