From 77c5d74113d4c3956e69c96cbbeed19782eb3f3d Mon Sep 17 00:00:00 2001 From: tobi <31960611+tsmethurst@users.noreply.github.com> Date: Wed, 18 Oct 2023 12:17:26 +0200 Subject: [PATCH] [bugfix] Postgres error wrapping fix (#2276) --- internal/db/bundb/errors.go | 2 +- internal/db/bundb/errors_test.go | 114 +++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 internal/db/bundb/errors_test.go diff --git a/internal/db/bundb/errors.go b/internal/db/bundb/errors.go index 46735ca80..c8f39aebd 100644 --- a/internal/db/bundb/errors.go +++ b/internal/db/bundb/errors.go @@ -20,7 +20,7 @@ import ( "errors" - "github.com/jackc/pgconn" + "github.com/jackc/pgx/v5/pgconn" "github.com/superseriousbusiness/gotosocial/internal/db" "modernc.org/sqlite" sqlite3 "modernc.org/sqlite/lib" diff --git a/internal/db/bundb/errors_test.go b/internal/db/bundb/errors_test.go new file mode 100644 index 000000000..400780196 --- /dev/null +++ b/internal/db/bundb/errors_test.go @@ -0,0 +1,114 @@ +// 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 . + +package bundb_test + +import ( + "context" + "errors" + "testing" + + "github.com/stretchr/testify/suite" + "github.com/superseriousbusiness/gotosocial/internal/db" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" +) + +type ErrorsTestSuite struct { + BunDBStandardTestSuite +} + +func (suite *ErrorsTestSuite) TestErrorAlreadyExists() { + type testType struct { + follow *gtsmodel.Follow + expected error + } + + var ( + ctx = context.Background() + initialFollow = >smodel.Follow{ + ID: "01HD11D8JH5V64GJRFDA7VFNDX", + URI: "https://example.org/unique_uri", + AccountID: "01HD11E9Y02HVXZ4YB20SG4QR9", + TargetAccountID: "01HD11EPJWM919DRP9JCKDZBX6", + } + editFollow = func(f func(*gtsmodel.Follow)) *gtsmodel.Follow { + edited := new(gtsmodel.Follow) + *edited = *initialFollow + + f(edited) + return edited + } + ) + + // Put the initial follow so we have + // a constraint in place to fail on. + if err := suite.db.PutFollow(ctx, initialFollow); err != nil { + suite.FailNow(err.Error()) + } + + for i, test := range []testType{ + { + // Try to put the initial follow in again. + follow: initialFollow, + expected: db.ErrAlreadyExists, + }, + { + // Different ID but same URI, + // should fail on URI constraint. + follow: editFollow(func(f *gtsmodel.Follow) { + f.ID = "01HD12ASEEBZ7MRY8AK51RJ20Y" + }), + expected: db.ErrAlreadyExists, + }, + { + // Different URI but same ID, + // should fail on ID constraint. + follow: editFollow(func(f *gtsmodel.Follow) { + f.URI = "https://example.org/new_uri" + }), + expected: db.ErrAlreadyExists, + }, + { + // Different ID and URI, but same account and + // target. Should fail on unique constraint. + follow: editFollow(func(f *gtsmodel.Follow) { + f.ID = "01HD12ASEEBZ7MRY8AK51RJ20Y" + f.URI = "https://example.org/new_uri" + }), + expected: db.ErrAlreadyExists, + }, + { + // Put a follow with different ID, URI, + // and AccountID. This should work fine. + follow: editFollow(func(f *gtsmodel.Follow) { + f.ID = "01HD12ASEEBZ7MRY8AK51RJ20Y" + f.URI = "https://example.org/new_uri" + f.AccountID = "01HD12DTPDR8A96S5K5M7SJAF3" + }), + expected: nil, + }, + } { + err := suite.db.PutFollow(ctx, test.follow) + if !errors.Is(err, test.expected) { + suite.Fail("", "test number %d expected %v, got %v", i+1, test.expected, err) + } + } +} + +func TestErrorsTestSuite(t *testing.T) { + suite.Run(t, new(ErrorsTestSuite)) +}