mirror of
1
Fork 0

[bugfix] Use gtserror package for WrongType errs (#1930)

* [bugfix] Use gtserror package for WrongType errs

* test
This commit is contained in:
tobi 2023-06-27 11:37:42 +02:00 committed by GitHub
parent e3e0f673cc
commit d98b6318ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 112 additions and 89 deletions

View File

@ -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()

View File

@ -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}
}

View File

@ -26,7 +26,7 @@ import (
) )
type ExtractAttachmentsTestSuite struct { type ExtractAttachmentsTestSuite struct {
ExtractTestSuite APTestSuite
} }
func (suite *ExtractAttachmentsTestSuite) TestExtractAttachmentMissingURL() { func (suite *ExtractAttachmentsTestSuite) TestExtractAttachmentMissingURL() {

View File

@ -25,7 +25,7 @@ import (
) )
type ExtractContentTestSuite struct { type ExtractContentTestSuite struct {
ExtractTestSuite APTestSuite
} }
func (suite *ExtractContentTestSuite) TestExtractContent1() { func (suite *ExtractContentTestSuite) TestExtractContent1() {

View File

@ -25,7 +25,7 @@ import (
) )
type ExtractMentionsTestSuite struct { type ExtractMentionsTestSuite struct {
ExtractTestSuite APTestSuite
} }
func (suite *ExtractMentionsTestSuite) TestExtractMentions() { func (suite *ExtractMentionsTestSuite) TestExtractMentions() {

View File

@ -25,7 +25,7 @@ import (
) )
type ExtractSensitiveTestSuite struct { type ExtractSensitiveTestSuite struct {
ExtractTestSuite APTestSuite
} }
func (suite *ExtractMentionsTestSuite) TestExtractSensitive() { func (suite *ExtractMentionsTestSuite) TestExtractSensitive() {

View File

@ -26,7 +26,7 @@ import (
) )
type ExtractVisibilityTestSuite struct { type ExtractVisibilityTestSuite struct {
ExtractTestSuite APTestSuite
} }
func (suite *ExtractVisibilityTestSuite) TestExtractVisibilityPublic() { func (suite *ExtractVisibilityTestSuite) TestExtractVisibilityPublic() {

View File

@ -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{}) {

View File

@ -20,10 +20,10 @@ package ap
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 @@ import (
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)

View 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{})
}

View File

@ -40,26 +40,35 @@ const (
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