check / check (push) Waiting to run
Target.MaxRetries (max_retries) becomes Target.MaxAttempts (max_attempts), and the form field, parser and ceiling are renamed to match. The column is NOT NULL and a check constraint refuses a value below 1, so every target, whatever its type, is stored with at least 1. 1 is a single attempt with no circuit breaker; above 1 retries behind the breaker up to that many attempts. Both target forms refuse 0 and less; a blank field on the add target form gives 1, and on the edit form keeps the stored value. The target page shows the plain number, and the README's two paragraphs on 0 against 1 become one sentence. Model: opus-5-5
45 lines
1.1 KiB
Go
45 lines
1.1 KiB
Go
package database_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"sneak.berlin/go/webhooker/internal/database"
|
|
)
|
|
|
|
// newHTTPTarget returns an http target that makes maxAttempts attempts
|
|
// at each delivery.
|
|
func newHTTPTarget(maxAttempts int) *database.Target {
|
|
return &database.Target{
|
|
WebhookID: uuid.New().String(),
|
|
Name: "target",
|
|
Type: database.TargetTypeHTTP,
|
|
Config: `{"url":"https://example.com/"}`,
|
|
MaxAttempts: maxAttempts,
|
|
}
|
|
}
|
|
|
|
// TestTargetCreate_RefusesZeroAttempts relies on the targets table
|
|
// alone: nothing in the model checks the number, so the check
|
|
// constraint is what keeps a target with 0 attempts out of the
|
|
// database.
|
|
func TestTargetCreate_RefusesZeroAttempts(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
db := startedTestDB(t)
|
|
|
|
err := db.Create(newHTTPTarget(0)).Error
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "CHECK constraint failed")
|
|
}
|
|
|
|
func TestTargetCreate_AcceptsOneAttempt(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
db := startedTestDB(t)
|
|
|
|
require.NoError(t, db.Create(newHTTPTarget(1)).Error)
|
|
}
|