mirror of https://github.com/artifacthub/hub.git
581 lines
13 KiB
Go
581 lines
13 KiB
Go
package webhook
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/artifacthub/hub/internal/hub"
|
|
"github.com/artifacthub/hub/internal/tests"
|
|
"github.com/artifacthub/hub/internal/util"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/mock"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const validUUID = "00000000-0000-0000-0000-000000000001"
|
|
|
|
func TestAdd(t *testing.T) {
|
|
ctx := context.WithValue(context.Background(), hub.UserIDKey, "userID")
|
|
|
|
wh := &hub.Webhook{
|
|
Name: "webhook1",
|
|
URL: "http://webhook1.url",
|
|
EventKinds: []hub.EventKind{hub.NewRelease},
|
|
Packages: []*hub.Package{
|
|
{PackageID: validUUID},
|
|
},
|
|
}
|
|
|
|
t.Run("user id not found in ctx", func(t *testing.T) {
|
|
t.Parallel()
|
|
m := NewManager(nil)
|
|
assert.Panics(t, func() {
|
|
_ = m.Add(context.Background(), "orgName", wh)
|
|
})
|
|
})
|
|
|
|
t.Run("invalid input", func(t *testing.T) {
|
|
testCases := []struct {
|
|
errMsg string
|
|
orgName string
|
|
wh *hub.Webhook
|
|
}{
|
|
{
|
|
"name not provided",
|
|
"org1",
|
|
&hub.Webhook{
|
|
Name: "",
|
|
},
|
|
},
|
|
{
|
|
"url not provided",
|
|
"org1",
|
|
&hub.Webhook{
|
|
Name: "webhook",
|
|
URL: "",
|
|
},
|
|
},
|
|
{
|
|
"invalid url",
|
|
"org1",
|
|
&hub.Webhook{
|
|
Name: "webhook",
|
|
URL: "invalidurl",
|
|
},
|
|
},
|
|
{
|
|
"invalid template",
|
|
"org1",
|
|
&hub.Webhook{
|
|
Name: "webhook",
|
|
URL: "http://webhook1.url",
|
|
Template: "{{ .",
|
|
},
|
|
},
|
|
{
|
|
"no event kinds provided",
|
|
"org1",
|
|
&hub.Webhook{
|
|
Name: "webhook",
|
|
URL: "http://webhook1.url",
|
|
},
|
|
},
|
|
{
|
|
"no packages provided",
|
|
"org1",
|
|
&hub.Webhook{
|
|
Name: "webhook",
|
|
URL: "http://webhook1.url",
|
|
EventKinds: []hub.EventKind{hub.NewRelease},
|
|
},
|
|
},
|
|
{
|
|
"invalid package id",
|
|
"org1",
|
|
&hub.Webhook{
|
|
Name: "webhook",
|
|
URL: "http://webhook1.url",
|
|
EventKinds: []hub.EventKind{hub.NewRelease},
|
|
Packages: []*hub.Package{
|
|
{PackageID: ""},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
t.Run(tc.errMsg, func(t *testing.T) {
|
|
t.Parallel()
|
|
m := NewManager(nil)
|
|
|
|
err := m.Add(ctx, tc.orgName, tc.wh)
|
|
assert.True(t, errors.Is(err, hub.ErrInvalidInput))
|
|
assert.Contains(t, err.Error(), tc.errMsg)
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("database error", func(t *testing.T) {
|
|
testCases := []struct {
|
|
dbErr error
|
|
expectedError error
|
|
}{
|
|
{
|
|
tests.ErrFakeDB,
|
|
tests.ErrFakeDB,
|
|
},
|
|
{
|
|
util.ErrDBInsufficientPrivilege,
|
|
hub.ErrInsufficientPrivilege,
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
t.Run(tc.dbErr.Error(), func(t *testing.T) {
|
|
t.Parallel()
|
|
db := &tests.DBMock{}
|
|
db.On("Exec", ctx, addWebhookDBQ, "userID", "orgName", mock.Anything).Return(tc.dbErr)
|
|
m := NewManager(db)
|
|
|
|
err := m.Add(ctx, "orgName", wh)
|
|
assert.Equal(t, tc.expectedError, err)
|
|
db.AssertExpectations(t)
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("add webhook succeeded", func(t *testing.T) {
|
|
t.Parallel()
|
|
db := &tests.DBMock{}
|
|
db.On("Exec", ctx, addWebhookDBQ, "userID", "orgName", mock.Anything).Return(nil)
|
|
m := NewManager(db)
|
|
|
|
err := m.Add(ctx, "orgName", wh)
|
|
assert.NoError(t, err)
|
|
db.AssertExpectations(t)
|
|
})
|
|
}
|
|
|
|
func TestDelete(t *testing.T) {
|
|
ctx := context.WithValue(context.Background(), hub.UserIDKey, "userID")
|
|
|
|
t.Run("user id not found in ctx", func(t *testing.T) {
|
|
t.Parallel()
|
|
m := NewManager(nil)
|
|
assert.Panics(t, func() {
|
|
_ = m.Delete(context.Background(), validUUID)
|
|
})
|
|
})
|
|
|
|
t.Run("invalid input", func(t *testing.T) {
|
|
t.Parallel()
|
|
m := NewManager(nil)
|
|
err := m.Delete(ctx, "")
|
|
assert.True(t, errors.Is(err, hub.ErrInvalidInput))
|
|
})
|
|
|
|
t.Run("database error", func(t *testing.T) {
|
|
testCases := []struct {
|
|
dbErr error
|
|
expectedError error
|
|
}{
|
|
{
|
|
tests.ErrFakeDB,
|
|
tests.ErrFakeDB,
|
|
},
|
|
{
|
|
util.ErrDBInsufficientPrivilege,
|
|
hub.ErrInsufficientPrivilege,
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
t.Run(tc.dbErr.Error(), func(t *testing.T) {
|
|
t.Parallel()
|
|
db := &tests.DBMock{}
|
|
db.On("Exec", ctx, deleteWebhookDBQ, "userID", validUUID).Return(tc.dbErr)
|
|
m := NewManager(db)
|
|
|
|
err := m.Delete(ctx, validUUID)
|
|
assert.Equal(t, tc.expectedError, err)
|
|
db.AssertExpectations(t)
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("delete webhook succeeded", func(t *testing.T) {
|
|
t.Parallel()
|
|
db := &tests.DBMock{}
|
|
db.On("Exec", ctx, deleteWebhookDBQ, "userID", validUUID).Return(nil)
|
|
m := NewManager(db)
|
|
|
|
err := m.Delete(ctx, validUUID)
|
|
assert.NoError(t, err)
|
|
db.AssertExpectations(t)
|
|
})
|
|
}
|
|
|
|
func TestGetJSON(t *testing.T) {
|
|
ctx := context.WithValue(context.Background(), hub.UserIDKey, "userID")
|
|
|
|
t.Run("user id not found in ctx", func(t *testing.T) {
|
|
t.Parallel()
|
|
m := NewManager(nil)
|
|
assert.Panics(t, func() {
|
|
_, _ = m.GetJSON(context.Background(), validUUID)
|
|
})
|
|
})
|
|
|
|
t.Run("invalid input", func(t *testing.T) {
|
|
t.Parallel()
|
|
m := NewManager(nil)
|
|
_, err := m.GetJSON(ctx, "")
|
|
assert.True(t, errors.Is(err, hub.ErrInvalidInput))
|
|
})
|
|
|
|
t.Run("database error", func(t *testing.T) {
|
|
testCases := []struct {
|
|
dbErr error
|
|
expectedError error
|
|
}{
|
|
{
|
|
tests.ErrFakeDB,
|
|
tests.ErrFakeDB,
|
|
},
|
|
{
|
|
util.ErrDBInsufficientPrivilege,
|
|
hub.ErrInsufficientPrivilege,
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
t.Run(tc.dbErr.Error(), func(t *testing.T) {
|
|
t.Parallel()
|
|
db := &tests.DBMock{}
|
|
db.On("QueryRow", ctx, getWebhookDBQ, "userID", validUUID).Return(nil, tc.dbErr)
|
|
m := NewManager(db)
|
|
|
|
dataJSON, err := m.GetJSON(ctx, validUUID)
|
|
assert.Equal(t, tc.expectedError, err)
|
|
assert.Nil(t, dataJSON)
|
|
db.AssertExpectations(t)
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("webhook data returned successfully", func(t *testing.T) {
|
|
t.Parallel()
|
|
db := &tests.DBMock{}
|
|
db.On("QueryRow", ctx, getWebhookDBQ, "userID", validUUID).Return([]byte("dataJSON"), nil)
|
|
m := NewManager(db)
|
|
|
|
dataJSON, err := m.GetJSON(ctx, validUUID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, []byte("dataJSON"), dataJSON)
|
|
db.AssertExpectations(t)
|
|
})
|
|
}
|
|
|
|
func TestGetOwnedByOrgJSON(t *testing.T) {
|
|
ctx := context.WithValue(context.Background(), hub.UserIDKey, "userID")
|
|
|
|
t.Run("user id not found in ctx", func(t *testing.T) {
|
|
t.Parallel()
|
|
m := NewManager(nil)
|
|
assert.Panics(t, func() {
|
|
_, _ = m.GetOwnedByOrgJSON(context.Background(), "orgName")
|
|
})
|
|
})
|
|
|
|
t.Run("invalid input", func(t *testing.T) {
|
|
t.Parallel()
|
|
m := NewManager(nil)
|
|
_, err := m.GetOwnedByOrgJSON(ctx, "")
|
|
assert.True(t, errors.Is(err, hub.ErrInvalidInput))
|
|
})
|
|
|
|
t.Run("database error", func(t *testing.T) {
|
|
t.Parallel()
|
|
db := &tests.DBMock{}
|
|
db.On("QueryRow", ctx, getOrgWebhooksDBQ, "userID", "orgName").Return(nil, tests.ErrFakeDB)
|
|
m := NewManager(db)
|
|
|
|
dataJSON, err := m.GetOwnedByOrgJSON(ctx, "orgName")
|
|
assert.Equal(t, tests.ErrFakeDB, err)
|
|
assert.Nil(t, dataJSON)
|
|
db.AssertExpectations(t)
|
|
})
|
|
|
|
t.Run("org webhooks data returned successfully", func(t *testing.T) {
|
|
t.Parallel()
|
|
db := &tests.DBMock{}
|
|
db.On("QueryRow", ctx, getOrgWebhooksDBQ, "userID", "orgName").Return([]byte("dataJSON"), nil)
|
|
m := NewManager(db)
|
|
|
|
dataJSON, err := m.GetOwnedByOrgJSON(ctx, "orgName")
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, []byte("dataJSON"), dataJSON)
|
|
db.AssertExpectations(t)
|
|
})
|
|
}
|
|
|
|
func TestGetOwnedByUserJSON(t *testing.T) {
|
|
ctx := context.WithValue(context.Background(), hub.UserIDKey, "userID")
|
|
|
|
t.Run("user id not found in ctx", func(t *testing.T) {
|
|
t.Parallel()
|
|
m := NewManager(nil)
|
|
assert.Panics(t, func() {
|
|
_, _ = m.GetOwnedByUserJSON(context.Background())
|
|
})
|
|
})
|
|
|
|
t.Run("database error", func(t *testing.T) {
|
|
t.Parallel()
|
|
db := &tests.DBMock{}
|
|
db.On("QueryRow", ctx, getUserWebhooksDBQ, "userID").Return(nil, tests.ErrFakeDB)
|
|
m := NewManager(db)
|
|
|
|
dataJSON, err := m.GetOwnedByUserJSON(ctx)
|
|
assert.Equal(t, tests.ErrFakeDB, err)
|
|
assert.Nil(t, dataJSON)
|
|
db.AssertExpectations(t)
|
|
})
|
|
|
|
t.Run("user webhooks data returned successfully", func(t *testing.T) {
|
|
t.Parallel()
|
|
db := &tests.DBMock{}
|
|
db.On("QueryRow", ctx, getUserWebhooksDBQ, "userID").Return([]byte("dataJSON"), nil)
|
|
m := NewManager(db)
|
|
|
|
dataJSON, err := m.GetOwnedByUserJSON(ctx)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, []byte("dataJSON"), dataJSON)
|
|
db.AssertExpectations(t)
|
|
})
|
|
}
|
|
|
|
func TestGetSubscribedTo(t *testing.T) {
|
|
ctx := context.WithValue(context.Background(), hub.UserIDKey, "userID")
|
|
e := &hub.Event{
|
|
EventKind: hub.NewRelease,
|
|
PackageID: validUUID,
|
|
}
|
|
|
|
t.Run("invalid input", func(t *testing.T) {
|
|
testCases := []struct {
|
|
errMsg string
|
|
e *hub.Event
|
|
}{
|
|
{
|
|
"invalid package id",
|
|
&hub.Event{
|
|
EventKind: hub.NewRelease,
|
|
PackageID: "invalid",
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
t.Run(tc.errMsg, func(t *testing.T) {
|
|
t.Parallel()
|
|
m := NewManager(nil)
|
|
|
|
webhooks, err := m.GetSubscribedTo(ctx, tc.e)
|
|
assert.True(t, errors.Is(err, hub.ErrInvalidInput))
|
|
assert.Contains(t, err.Error(), tc.errMsg)
|
|
assert.Nil(t, webhooks)
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("database error", func(t *testing.T) {
|
|
t.Parallel()
|
|
db := &tests.DBMock{}
|
|
db.On("QueryRow", ctx, getWebhooksSubscribedToPkgDBQ, hub.NewRelease, validUUID).Return(nil, tests.ErrFakeDB)
|
|
m := NewManager(db)
|
|
|
|
webhooks, err := m.GetSubscribedTo(ctx, e)
|
|
assert.Equal(t, tests.ErrFakeDB, err)
|
|
assert.Nil(t, webhooks)
|
|
db.AssertExpectations(t)
|
|
})
|
|
|
|
t.Run("webhooks returned successfully", func(t *testing.T) {
|
|
t.Parallel()
|
|
db := &tests.DBMock{}
|
|
db.On("QueryRow", ctx, getWebhooksSubscribedToPkgDBQ, hub.NewRelease, validUUID).Return([]byte(`
|
|
[{
|
|
"webhook_id": "00000000-0000-0000-0000-000000000001",
|
|
"name": "webhook1",
|
|
"url": "http://webhook1.url"
|
|
}, {
|
|
"webhook_id": "00000000-0000-0000-0000-000000000002",
|
|
"name": "webhook2",
|
|
"url": "http://webhook2.url"
|
|
}]
|
|
`), nil)
|
|
m := NewManager(db)
|
|
|
|
w, err := m.GetSubscribedTo(ctx, e)
|
|
require.NoError(t, err)
|
|
require.Len(t, w, 2)
|
|
assert.Equal(t, "00000000-0000-0000-0000-000000000001", w[0].WebhookID)
|
|
assert.Equal(t, "webhook1", w[0].Name)
|
|
assert.Equal(t, "http://webhook1.url", w[0].URL)
|
|
assert.Equal(t, "00000000-0000-0000-0000-000000000002", w[1].WebhookID)
|
|
assert.Equal(t, "webhook2", w[1].Name)
|
|
assert.Equal(t, "http://webhook2.url", w[1].URL)
|
|
db.AssertExpectations(t)
|
|
})
|
|
}
|
|
|
|
func TestUpdate(t *testing.T) {
|
|
ctx := context.WithValue(context.Background(), hub.UserIDKey, "userID")
|
|
|
|
wh := &hub.Webhook{
|
|
WebhookID: validUUID,
|
|
Name: "webhook1",
|
|
URL: "http://webhook1.url",
|
|
EventKinds: []hub.EventKind{hub.NewRelease},
|
|
Packages: []*hub.Package{
|
|
{PackageID: validUUID},
|
|
},
|
|
}
|
|
|
|
t.Run("user id not found in ctx", func(t *testing.T) {
|
|
t.Parallel()
|
|
m := NewManager(nil)
|
|
assert.Panics(t, func() {
|
|
_ = m.Update(context.Background(), wh)
|
|
})
|
|
})
|
|
|
|
t.Run("invalid input", func(t *testing.T) {
|
|
testCases := []struct {
|
|
errMsg string
|
|
wh *hub.Webhook
|
|
}{
|
|
{
|
|
"invalid webhook id",
|
|
&hub.Webhook{
|
|
WebhookID: "",
|
|
},
|
|
},
|
|
{
|
|
"name not provided",
|
|
&hub.Webhook{
|
|
WebhookID: validUUID,
|
|
Name: "",
|
|
},
|
|
},
|
|
{
|
|
"url not provided",
|
|
&hub.Webhook{
|
|
WebhookID: validUUID,
|
|
Name: "webhook",
|
|
URL: "",
|
|
},
|
|
},
|
|
{
|
|
"invalid url",
|
|
&hub.Webhook{
|
|
WebhookID: validUUID,
|
|
Name: "webhook",
|
|
URL: "invalidurl",
|
|
},
|
|
},
|
|
{
|
|
"invalid template",
|
|
&hub.Webhook{
|
|
WebhookID: validUUID,
|
|
Name: "webhook",
|
|
URL: "http://webhook1.url",
|
|
Template: "{{ .",
|
|
},
|
|
},
|
|
{
|
|
"no event kinds provided",
|
|
&hub.Webhook{
|
|
WebhookID: validUUID,
|
|
Name: "webhook",
|
|
URL: "http://webhook1.url",
|
|
},
|
|
},
|
|
{
|
|
"no packages provided",
|
|
&hub.Webhook{
|
|
WebhookID: validUUID,
|
|
Name: "webhook",
|
|
URL: "http://webhook1.url",
|
|
EventKinds: []hub.EventKind{hub.NewRelease},
|
|
},
|
|
},
|
|
{
|
|
"invalid package id",
|
|
&hub.Webhook{
|
|
WebhookID: validUUID,
|
|
Name: "webhook",
|
|
URL: "http://webhook1.url",
|
|
EventKinds: []hub.EventKind{hub.NewRelease},
|
|
Packages: []*hub.Package{
|
|
{PackageID: ""},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
t.Run(tc.errMsg, func(t *testing.T) {
|
|
t.Parallel()
|
|
m := NewManager(nil)
|
|
|
|
err := m.Update(ctx, tc.wh)
|
|
assert.True(t, errors.Is(err, hub.ErrInvalidInput))
|
|
assert.Contains(t, err.Error(), tc.errMsg)
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("database error", func(t *testing.T) {
|
|
testCases := []struct {
|
|
dbErr error
|
|
expectedError error
|
|
}{
|
|
{
|
|
tests.ErrFakeDB,
|
|
tests.ErrFakeDB,
|
|
},
|
|
{
|
|
util.ErrDBInsufficientPrivilege,
|
|
hub.ErrInsufficientPrivilege,
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
t.Run(tc.dbErr.Error(), func(t *testing.T) {
|
|
t.Parallel()
|
|
db := &tests.DBMock{}
|
|
db.On("Exec", ctx, updateWebhookDBQ, "userID", mock.Anything).Return(tc.dbErr)
|
|
m := NewManager(db)
|
|
|
|
err := m.Update(ctx, wh)
|
|
assert.Equal(t, tc.expectedError, err)
|
|
db.AssertExpectations(t)
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("update webhook succeeded", func(t *testing.T) {
|
|
t.Parallel()
|
|
db := &tests.DBMock{}
|
|
db.On("Exec", ctx, updateWebhookDBQ, "userID", mock.Anything).Return(nil)
|
|
m := NewManager(db)
|
|
|
|
err := m.Update(ctx, wh)
|
|
assert.NoError(t, err)
|
|
db.AssertExpectations(t)
|
|
})
|
|
}
|