mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-11-24 01:11:00 +00:00
[bugfix] Use gtserror package for WrongType errs (#1930)
* [bugfix] Use gtserror package for WrongType errs * test
This commit is contained in:
parent
e3e0f673cc
commit
d98b6318ac
11 changed files with 112 additions and 89 deletions
|
@ -184,7 +184,7 @@ func addressable5() ap.Addressable {
|
|||
return note
|
||||
}
|
||||
|
||||
type ExtractTestSuite struct {
|
||||
type APTestSuite struct {
|
||||
suite.Suite
|
||||
document1 vocab.ActivityStreamsDocument
|
||||
attachment1 vocab.ActivityStreamsAttachmentProperty
|
||||
|
@ -196,7 +196,36 @@ type ExtractTestSuite struct {
|
|||
addressable5 ap.Addressable
|
||||
}
|
||||
|
||||
func (suite *ExtractTestSuite) SetupTest() {
|
||||
func (suite *APTestSuite) jsonToType(rawJson string) (vocab.Type, map[string]interface{}) {
|
||||
var raw map[string]interface{}
|
||||
err := json.Unmarshal([]byte(rawJson), &raw)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
t, err := streams.ToType(context.Background(), raw)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return t, raw
|
||||
}
|
||||
|
||||
func (suite *APTestSuite) typeToJson(t vocab.Type) string {
|
||||
m, err := ap.Serialize(t)
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
||||
b, err := json.MarshalIndent(m, "", " ")
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (suite *APTestSuite) SetupTest() {
|
||||
suite.document1 = document1()
|
||||
suite.attachment1 = attachment1()
|
||||
suite.noteWithMentions1 = noteWithMentions1()
|
|
@ -1,35 +0,0 @@
|
|||
// GoToSocial
|
||||
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package ap
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ErrWrongType indicates that we tried to resolve a type into
|
||||
// an interface that it's not compatible with, eg a Person into
|
||||
// a Statusable.
|
||||
type ErrWrongType struct {
|
||||
wrapped error
|
||||
}
|
||||
|
||||
func (err *ErrWrongType) Error() string {
|
||||
return fmt.Sprintf("wrong received type: %v", err.wrapped)
|
||||
}
|
||||
|
||||
func newErrWrongType(err error) error {
|
||||
return &ErrWrongType{wrapped: err}
|
||||
}
|
|
@ -26,7 +26,7 @@ import (
|
|||
)
|
||||
|
||||
type ExtractAttachmentsTestSuite struct {
|
||||
ExtractTestSuite
|
||||
APTestSuite
|
||||
}
|
||||
|
||||
func (suite *ExtractAttachmentsTestSuite) TestExtractAttachmentMissingURL() {
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
)
|
||||
|
||||
type ExtractContentTestSuite struct {
|
||||
ExtractTestSuite
|
||||
APTestSuite
|
||||
}
|
||||
|
||||
func (suite *ExtractContentTestSuite) TestExtractContent1() {
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
)
|
||||
|
||||
type ExtractMentionsTestSuite struct {
|
||||
ExtractTestSuite
|
||||
APTestSuite
|
||||
}
|
||||
|
||||
func (suite *ExtractMentionsTestSuite) TestExtractMentions() {
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
)
|
||||
|
||||
type ExtractSensitiveTestSuite struct {
|
||||
ExtractTestSuite
|
||||
APTestSuite
|
||||
}
|
||||
|
||||
func (suite *ExtractMentionsTestSuite) TestExtractSensitive() {
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
)
|
||||
|
||||
type ExtractVisibilityTestSuite struct {
|
||||
ExtractTestSuite
|
||||
APTestSuite
|
||||
}
|
||||
|
||||
func (suite *ExtractVisibilityTestSuite) TestExtractVisibilityPublic() {
|
||||
|
|
|
@ -18,48 +18,16 @@
|
|||
package ap_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/activity/streams"
|
||||
"github.com/superseriousbusiness/activity/streams/vocab"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
||||
"github.com/superseriousbusiness/gotosocial/testrig"
|
||||
)
|
||||
|
||||
type NormalizeTestSuite struct {
|
||||
suite.Suite
|
||||
}
|
||||
|
||||
func (suite *NormalizeTestSuite) jsonToType(rawJson string) (vocab.Type, map[string]interface{}) {
|
||||
var raw map[string]interface{}
|
||||
err := json.Unmarshal([]byte(rawJson), &raw)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
t, err := streams.ToType(context.Background(), raw)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return t, raw
|
||||
}
|
||||
|
||||
func (suite *NormalizeTestSuite) typeToJson(t vocab.Type) string {
|
||||
m, err := ap.Serialize(t)
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
||||
b, err := json.MarshalIndent(m, "", " ")
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
||||
return string(b)
|
||||
APTestSuite
|
||||
}
|
||||
|
||||
func (suite *NormalizeTestSuite) getStatusable() (vocab.ActivityStreamsNote, map[string]interface{}) {
|
||||
|
|
|
@ -20,10 +20,10 @@ package ap
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/superseriousbusiness/activity/streams"
|
||||
"github.com/superseriousbusiness/activity/streams/vocab"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||
)
|
||||
|
||||
// ResolveStatusable tries to resolve the given bytes into an ActivityPub Statusable representation.
|
||||
|
@ -33,12 +33,12 @@ import (
|
|||
func ResolveStatusable(ctx context.Context, b []byte) (Statusable, error) {
|
||||
rawStatusable := make(map[string]interface{})
|
||||
if err := json.Unmarshal(b, &rawStatusable); err != nil {
|
||||
return nil, fmt.Errorf("ResolveStatusable: error unmarshalling bytes into json: %w", err)
|
||||
return nil, gtserror.Newf("error unmarshalling bytes into json: %w", err)
|
||||
}
|
||||
|
||||
t, err := streams.ToType(ctx, rawStatusable)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ResolveStatusable: error resolving json into ap vocab type: %w", err)
|
||||
return nil, gtserror.Newf("error resolving json into ap vocab type: %w", err)
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -68,8 +68,8 @@ func ResolveStatusable(ctx context.Context, b []byte) (Statusable, error) {
|
|||
}
|
||||
|
||||
if !ok {
|
||||
err = fmt.Errorf("ResolveStatusable: could not resolve %T to Statusable", t)
|
||||
return nil, newErrWrongType(err)
|
||||
err = gtserror.Newf("could not resolve %T to Statusable", t)
|
||||
return nil, gtserror.SetWrongType(err)
|
||||
}
|
||||
|
||||
NormalizeIncomingContent(statusable, rawStatusable)
|
||||
|
@ -87,12 +87,12 @@ func ResolveStatusable(ctx context.Context, b []byte) (Statusable, error) {
|
|||
func ResolveAccountable(ctx context.Context, b []byte) (Accountable, error) {
|
||||
rawAccountable := make(map[string]interface{})
|
||||
if err := json.Unmarshal(b, &rawAccountable); err != nil {
|
||||
return nil, fmt.Errorf("ResolveAccountable: error unmarshalling bytes into json: %w", err)
|
||||
return nil, gtserror.Newf("error unmarshalling bytes into json: %w", err)
|
||||
}
|
||||
|
||||
t, err := streams.ToType(ctx, rawAccountable)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ResolveAccountable: error resolving json into ap vocab type: %w", err)
|
||||
return nil, gtserror.Newf("error resolving json into ap vocab type: %w", err)
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -114,8 +114,8 @@ func ResolveAccountable(ctx context.Context, b []byte) (Accountable, error) {
|
|||
}
|
||||
|
||||
if !ok {
|
||||
err = fmt.Errorf("ResolveAccountable: could not resolve %T to Accountable", t)
|
||||
return nil, newErrWrongType(err)
|
||||
err = gtserror.Newf("could not resolve %T to Accountable", t)
|
||||
return nil, gtserror.SetWrongType(err)
|
||||
}
|
||||
|
||||
NormalizeIncomingSummary(accountable, rawAccountable)
|
||||
|
|
52
internal/ap/resolve_test.go
Normal file
52
internal/ap/resolve_test.go
Normal file
|
@ -0,0 +1,52 @@
|
|||
// GoToSocial
|
||||
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package ap_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||
)
|
||||
|
||||
type ResolveTestSuite struct {
|
||||
APTestSuite
|
||||
}
|
||||
|
||||
func (suite *ResolveTestSuite) TestResolveDocumentAsStatusable() {
|
||||
b := []byte(suite.typeToJson(suite.document1))
|
||||
|
||||
statusable, err := ap.ResolveStatusable(context.Background(), b)
|
||||
suite.NoError(err)
|
||||
suite.NotNil(statusable)
|
||||
}
|
||||
|
||||
func (suite *ResolveTestSuite) TestResolveDocumentAsAccountable() {
|
||||
b := []byte(suite.typeToJson(suite.document1))
|
||||
|
||||
accountable, err := ap.ResolveAccountable(context.Background(), b)
|
||||
suite.True(gtserror.WrongType(err))
|
||||
suite.EqualError(err, "ResolveAccountable: could not resolve *typedocument.ActivityStreamsDocument to Accountable")
|
||||
suite.Nil(accountable)
|
||||
}
|
||||
|
||||
func TestResolveTestSuite(t *testing.T) {
|
||||
suite.Run(t, &ResolveTestSuite{})
|
||||
}
|
|
@ -40,26 +40,35 @@ const (
|
|||
TypeSMTP ErrorType = "smtp" // smtp (mail)
|
||||
)
|
||||
|
||||
// Unretrievable ...
|
||||
// Unretrievable checks error for a stored "unretrievable" flag.
|
||||
//
|
||||
// Unretrievable indicates that a call to retrieve a resource
|
||||
// (account, status, etc) could not be fulfilled, either because
|
||||
// it was not found locally, or because some prerequisite remote
|
||||
// resource call failed, making it impossible to return the item.
|
||||
func Unretrievable(err error) bool {
|
||||
_, ok := errors.Value(err, unrtrvableKey).(struct{})
|
||||
return ok
|
||||
}
|
||||
|
||||
// SetUnretrievable ...
|
||||
// SetUnretrievable will wrap the given error to store an "unretrievable"
|
||||
// flag, returning wrapped error. See "Unretrievable" for example use-cases.
|
||||
func SetUnretrievable(err error) error {
|
||||
return errors.WithValue(err, unrtrvableKey, struct{}{})
|
||||
}
|
||||
|
||||
// WrongType ...
|
||||
// WrongType checks error for a stored "wrong type" flag. Wrong type
|
||||
// indicates that an ActivityPub URI returned a type we weren't expecting:
|
||||
// Statusable instead of Accountable, or vice versa, for example.
|
||||
func WrongType(err error) bool {
|
||||
_, ok := errors.Value(err, wrongTypeKey).(struct{})
|
||||
return ok
|
||||
}
|
||||
|
||||
// SetWrongType ...
|
||||
// SetWrongType will wrap the given error to store a "wrong type" flag,
|
||||
// returning wrapped error. See "WrongType" for example use-cases.
|
||||
func SetWrongType(err error) error {
|
||||
return errors.WithValue(err, unrtrvableKey, struct{}{})
|
||||
return errors.WithValue(err, wrongTypeKey, struct{}{})
|
||||
}
|
||||
|
||||
// StatusCode checks error for a stored status code value. For example
|
||||
|
|
Loading…
Reference in a new issue