mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-11-01 06:50: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
|
return note
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExtractTestSuite struct {
|
type APTestSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
document1 vocab.ActivityStreamsDocument
|
document1 vocab.ActivityStreamsDocument
|
||||||
attachment1 vocab.ActivityStreamsAttachmentProperty
|
attachment1 vocab.ActivityStreamsAttachmentProperty
|
||||||
|
@ -196,7 +196,36 @@ type ExtractTestSuite struct {
|
||||||
addressable5 ap.Addressable
|
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.document1 = document1()
|
||||||
suite.attachment1 = attachment1()
|
suite.attachment1 = attachment1()
|
||||||
suite.noteWithMentions1 = noteWithMentions1()
|
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 @@
|
||||||
)
|
)
|
||||||
|
|
||||||
type ExtractAttachmentsTestSuite struct {
|
type ExtractAttachmentsTestSuite struct {
|
||||||
ExtractTestSuite
|
APTestSuite
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ExtractAttachmentsTestSuite) TestExtractAttachmentMissingURL() {
|
func (suite *ExtractAttachmentsTestSuite) TestExtractAttachmentMissingURL() {
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
)
|
)
|
||||||
|
|
||||||
type ExtractContentTestSuite struct {
|
type ExtractContentTestSuite struct {
|
||||||
ExtractTestSuite
|
APTestSuite
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ExtractContentTestSuite) TestExtractContent1() {
|
func (suite *ExtractContentTestSuite) TestExtractContent1() {
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
)
|
)
|
||||||
|
|
||||||
type ExtractMentionsTestSuite struct {
|
type ExtractMentionsTestSuite struct {
|
||||||
ExtractTestSuite
|
APTestSuite
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ExtractMentionsTestSuite) TestExtractMentions() {
|
func (suite *ExtractMentionsTestSuite) TestExtractMentions() {
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
)
|
)
|
||||||
|
|
||||||
type ExtractSensitiveTestSuite struct {
|
type ExtractSensitiveTestSuite struct {
|
||||||
ExtractTestSuite
|
APTestSuite
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ExtractMentionsTestSuite) TestExtractSensitive() {
|
func (suite *ExtractMentionsTestSuite) TestExtractSensitive() {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
)
|
)
|
||||||
|
|
||||||
type ExtractVisibilityTestSuite struct {
|
type ExtractVisibilityTestSuite struct {
|
||||||
ExtractTestSuite
|
APTestSuite
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ExtractVisibilityTestSuite) TestExtractVisibilityPublic() {
|
func (suite *ExtractVisibilityTestSuite) TestExtractVisibilityPublic() {
|
||||||
|
|
|
@ -18,48 +18,16 @@
|
||||||
package ap_test
|
package ap_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
"github.com/superseriousbusiness/activity/streams"
|
|
||||||
"github.com/superseriousbusiness/activity/streams/vocab"
|
"github.com/superseriousbusiness/activity/streams/vocab"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
||||||
"github.com/superseriousbusiness/gotosocial/testrig"
|
"github.com/superseriousbusiness/gotosocial/testrig"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NormalizeTestSuite struct {
|
type NormalizeTestSuite struct {
|
||||||
suite.Suite
|
APTestSuite
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *NormalizeTestSuite) getStatusable() (vocab.ActivityStreamsNote, map[string]interface{}) {
|
func (suite *NormalizeTestSuite) getStatusable() (vocab.ActivityStreamsNote, map[string]interface{}) {
|
||||||
|
|
|
@ -20,10 +20,10 @@
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/superseriousbusiness/activity/streams"
|
"github.com/superseriousbusiness/activity/streams"
|
||||||
"github.com/superseriousbusiness/activity/streams/vocab"
|
"github.com/superseriousbusiness/activity/streams/vocab"
|
||||||
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResolveStatusable tries to resolve the given bytes into an ActivityPub Statusable representation.
|
// ResolveStatusable tries to resolve the given bytes into an ActivityPub Statusable representation.
|
||||||
|
@ -33,12 +33,12 @@
|
||||||
func ResolveStatusable(ctx context.Context, b []byte) (Statusable, error) {
|
func ResolveStatusable(ctx context.Context, b []byte) (Statusable, error) {
|
||||||
rawStatusable := make(map[string]interface{})
|
rawStatusable := make(map[string]interface{})
|
||||||
if err := json.Unmarshal(b, &rawStatusable); err != nil {
|
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)
|
t, err := streams.ToType(ctx, rawStatusable)
|
||||||
if err != nil {
|
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 (
|
var (
|
||||||
|
@ -68,8 +68,8 @@ func ResolveStatusable(ctx context.Context, b []byte) (Statusable, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
err = fmt.Errorf("ResolveStatusable: could not resolve %T to Statusable", t)
|
err = gtserror.Newf("could not resolve %T to Statusable", t)
|
||||||
return nil, newErrWrongType(err)
|
return nil, gtserror.SetWrongType(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
NormalizeIncomingContent(statusable, rawStatusable)
|
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) {
|
func ResolveAccountable(ctx context.Context, b []byte) (Accountable, error) {
|
||||||
rawAccountable := make(map[string]interface{})
|
rawAccountable := make(map[string]interface{})
|
||||||
if err := json.Unmarshal(b, &rawAccountable); err != nil {
|
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)
|
t, err := streams.ToType(ctx, rawAccountable)
|
||||||
if err != nil {
|
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 (
|
var (
|
||||||
|
@ -114,8 +114,8 @@ func ResolveAccountable(ctx context.Context, b []byte) (Accountable, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
err = fmt.Errorf("ResolveAccountable: could not resolve %T to Accountable", t)
|
err = gtserror.Newf("could not resolve %T to Accountable", t)
|
||||||
return nil, newErrWrongType(err)
|
return nil, gtserror.SetWrongType(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
NormalizeIncomingSummary(accountable, rawAccountable)
|
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 @@
|
||||||
TypeSMTP ErrorType = "smtp" // smtp (mail)
|
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 {
|
func Unretrievable(err error) bool {
|
||||||
_, ok := errors.Value(err, unrtrvableKey).(struct{})
|
_, ok := errors.Value(err, unrtrvableKey).(struct{})
|
||||||
return ok
|
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 {
|
func SetUnretrievable(err error) error {
|
||||||
return errors.WithValue(err, unrtrvableKey, struct{}{})
|
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 {
|
func WrongType(err error) bool {
|
||||||
_, ok := errors.Value(err, wrongTypeKey).(struct{})
|
_, ok := errors.Value(err, wrongTypeKey).(struct{})
|
||||||
return ok
|
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 {
|
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
|
// StatusCode checks error for a stored status code value. For example
|
||||||
|
|
Loading…
Reference in a new issue