mirror of
https://github.com/kopia/kopia.git
synced 2026-01-25 06:48:48 -05:00
* feat(general): various notifications improvements * added API to test notification profiles * added --http-header to webhook notification configuration * refactored configuration to always apply defaults before persisting options in the repository * added 'notification profile show --profile-name=X' command * more tests * more test coverage * report notification code coverage
163 lines
4.6 KiB
Go
163 lines
4.6 KiB
Go
package server_test
|
|
|
|
import (
|
|
"sync/atomic"
|
|
"testing"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/kopia/kopia/internal/apiclient"
|
|
"github.com/kopia/kopia/internal/repotesting"
|
|
"github.com/kopia/kopia/internal/serverapi"
|
|
"github.com/kopia/kopia/internal/servertesting"
|
|
"github.com/kopia/kopia/notification/notifyprofile"
|
|
"github.com/kopia/kopia/notification/sender"
|
|
"github.com/kopia/kopia/notification/sender/testsender"
|
|
)
|
|
|
|
func TestNotificationProfile(t *testing.T) {
|
|
ctx, env := repotesting.NewEnvironment(t, repotesting.FormatNotImportant)
|
|
|
|
var (
|
|
numMessagesSent atomic.Int32
|
|
nextSendErr error
|
|
)
|
|
|
|
ctx = testsender.CaptureMessagesWithHandler(ctx, func(msg *sender.Message) error {
|
|
var returnErr error
|
|
|
|
numMessagesSent.Add(1)
|
|
|
|
returnErr, nextSendErr = nextSendErr, nil
|
|
|
|
return returnErr
|
|
})
|
|
|
|
srvInfo := servertesting.StartServerContext(ctx, t, env, false)
|
|
|
|
cli, err := apiclient.NewKopiaAPIClient(apiclient.Options{
|
|
BaseURL: srvInfo.BaseURL,
|
|
TrustedServerCertificateFingerprint: srvInfo.TrustedServerCertificateFingerprint,
|
|
Username: servertesting.TestUIUsername,
|
|
Password: servertesting.TestUIPassword,
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, cli.FetchCSRFTokenForTesting(ctx))
|
|
|
|
var profiles []notifyprofile.Config
|
|
|
|
require.NoError(t, cli.Get(ctx, "notificationProfiles", nil, &profiles))
|
|
require.Empty(t, profiles)
|
|
|
|
// test new profile
|
|
require.EqualValues(t, 0, numMessagesSent.Load())
|
|
|
|
require.ErrorContains(t, cli.Post(ctx, "testNotificationProfile", ¬ifyprofile.Config{
|
|
ProfileName: "profile1",
|
|
MethodConfig: sender.MethodConfig{
|
|
Type: "invalid-type",
|
|
Config: testsender.Options{
|
|
Format: "txt",
|
|
},
|
|
},
|
|
MinSeverity: 3,
|
|
}, &serverapi.Empty{}), "malformed request body")
|
|
|
|
require.ErrorContains(t, cli.Post(ctx, "testNotificationProfile", ¬ifyprofile.Config{
|
|
ProfileName: "profile1",
|
|
MethodConfig: sender.MethodConfig{
|
|
Type: "testsender",
|
|
Config: testsender.Options{
|
|
Format: "txt",
|
|
Invalid: true,
|
|
},
|
|
},
|
|
MinSeverity: 3,
|
|
}, &serverapi.Empty{}), "unable to construct sender")
|
|
|
|
// nothing was sent
|
|
require.EqualValues(t, 0, numMessagesSent.Load())
|
|
|
|
nextSendErr = errors.Errorf("test error")
|
|
|
|
require.ErrorContains(t, cli.Post(ctx, "testNotificationProfile", ¬ifyprofile.Config{
|
|
ProfileName: "profile1",
|
|
MethodConfig: sender.MethodConfig{
|
|
Type: "testsender",
|
|
Config: testsender.Options{
|
|
Format: "txt",
|
|
},
|
|
},
|
|
MinSeverity: 3,
|
|
}, &serverapi.Empty{}), "test error")
|
|
|
|
// expect one message to be sent
|
|
require.EqualValues(t, 1, numMessagesSent.Load())
|
|
|
|
require.NoError(t, cli.Post(ctx, "testNotificationProfile", ¬ifyprofile.Config{
|
|
ProfileName: "profile1",
|
|
MethodConfig: sender.MethodConfig{
|
|
Type: "testsender",
|
|
Config: testsender.Options{
|
|
Format: "txt",
|
|
},
|
|
},
|
|
MinSeverity: 3,
|
|
}, &serverapi.Empty{}))
|
|
require.EqualValues(t, 2, numMessagesSent.Load())
|
|
|
|
// define new profile
|
|
require.NoError(t, cli.Post(ctx, "notificationProfiles", ¬ifyprofile.Config{
|
|
ProfileName: "profile1",
|
|
MethodConfig: sender.MethodConfig{
|
|
Type: "testsender",
|
|
Config: testsender.Options{
|
|
Format: "txt",
|
|
},
|
|
},
|
|
MinSeverity: 3,
|
|
}, &serverapi.Empty{}))
|
|
|
|
// define invalid profile
|
|
require.ErrorContains(t, cli.Post(ctx, "notificationProfiles", ¬ifyprofile.Config{
|
|
ProfileName: "profile2",
|
|
MethodConfig: sender.MethodConfig{
|
|
Type: "no-such-type",
|
|
Config: testsender.Options{
|
|
Format: "txt",
|
|
},
|
|
},
|
|
MinSeverity: 3,
|
|
}, &serverapi.Empty{}), "malformed request body")
|
|
|
|
var cfg notifyprofile.Config
|
|
|
|
// get profile and verify
|
|
require.NoError(t, cli.Get(ctx, "notificationProfiles/profile1", nil, &cfg))
|
|
require.Equal(t, "profile1", cfg.ProfileName)
|
|
require.Equal(t, sender.Method("testsender"), cfg.MethodConfig.Type)
|
|
|
|
opt, ok := cfg.MethodConfig.Config.(map[string]any)
|
|
require.True(t, ok)
|
|
require.Equal(t, "txt", opt["format"])
|
|
|
|
// get non-existent profile
|
|
require.ErrorContains(t, cli.Get(ctx, "notificationProfiles/profile2", nil, &cfg), "profile not found")
|
|
|
|
// list profiles
|
|
require.NoError(t, cli.Get(ctx, "notificationProfiles", nil, &profiles))
|
|
require.Len(t, profiles, 1)
|
|
require.Equal(t, "profile1", profiles[0].ProfileName)
|
|
|
|
// delete the profile, ensure idempotent
|
|
require.NoError(t, cli.Delete(ctx, "notificationProfiles/profile1", nil, nil, &serverapi.Empty{}))
|
|
require.NoError(t, cli.Delete(ctx, "notificationProfiles/profile1", nil, nil, &serverapi.Empty{}))
|
|
|
|
// verify it's gone
|
|
require.NoError(t, cli.Get(ctx, "notificationProfiles", nil, &profiles))
|
|
require.Empty(t, profiles)
|
|
}
|