influxdb/testing/notification_rule.go

2708 lines
72 KiB
Go

package testing
import (
"context"
"sort"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/influxdata/influxdb/v2"
"github.com/influxdata/influxdb/v2/mock"
"github.com/influxdata/influxdb/v2/notification"
"github.com/influxdata/influxdb/v2/notification/endpoint"
"github.com/influxdata/influxdb/v2/notification/rule"
)
// NotificationRuleFields includes prepopulated data for mapping tests.
type NotificationRuleFields struct {
IDGenerator influxdb.IDGenerator
TimeGenerator influxdb.TimeGenerator
NotificationRules []influxdb.NotificationRule
Orgs []*influxdb.Organization
UserResourceMappings []*influxdb.UserResourceMapping
Tasks []influxdb.TaskCreate
Endpoints []influxdb.NotificationEndpoint
}
var notificationRuleCmpOptions = cmp.Options{
cmpopts.IgnoreFields(rule.Base{}, "TaskID"),
cmp.Transformer("Sort", func(in []influxdb.NotificationRule) []influxdb.NotificationRule {
out := append([]influxdb.NotificationRule(nil), in...)
sort.Slice(out, func(i, j int) bool {
return out[i].GetID() > out[j].GetID()
})
return out
}),
}
// NotificationRuleStore tests all the service functions.
func NotificationRuleStore(
init func(NotificationRuleFields, *testing.T) (influxdb.NotificationRuleStore, func()), t *testing.T,
) {
tests := []struct {
name string
fn func(init func(NotificationRuleFields, *testing.T) (influxdb.NotificationRuleStore, func()),
t *testing.T)
}{
{
name: "CreateNotificationRule",
fn: CreateNotificationRule,
},
{
name: "FindNotificationRuleByID",
fn: FindNotificationRuleByID,
},
{
name: "FindNotificationRules",
fn: FindNotificationRules,
},
{
name: "UpdateNotificationRule",
fn: UpdateNotificationRule,
},
{
name: "PatchNotificationRule",
fn: PatchNotificationRule,
},
{
name: "DeleteNotificationRule",
fn: DeleteNotificationRule,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.fn(init, t)
})
}
}
// CreateNotificationRule testing.
func CreateNotificationRule(
init func(NotificationRuleFields, *testing.T) (influxdb.NotificationRuleStore, func()),
t *testing.T,
) {
type args struct {
notificationRule influxdb.NotificationRule
userID influxdb.ID
}
type wants struct {
err error
notificationRules []influxdb.NotificationRule
userResourceMapping []*influxdb.UserResourceMapping
}
tests := []struct {
name string
fields NotificationRuleFields
args args
wants wants
}{
{
name: "basic create notification rule",
fields: NotificationRuleFields{
IDGenerator: mock.NewIDGenerator(twoID, t),
TimeGenerator: fakeGenerator,
Orgs: []*influxdb.Organization{
{
Name: "org",
ID: MustIDBase16(fourID),
},
},
Endpoints: []influxdb.NotificationEndpoint{
&endpoint.Slack{
URL: "http://localhost:7777",
Token: influxdb.SecretField{
// TODO(desa): not sure why this has to end in token, but it does
Key: "020f755c3c082001-token",
Value: strPtr("abc123"),
},
Base: endpoint.Base{
OrgID: MustIDBase16Ptr(fourID),
Name: "foo",
Status: influxdb.Active,
},
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Critical,
},
},
TagRules: []notification.TagRule{
{
Tag: influxdb.Tag{
Key: "k1",
Value: "v1",
},
Operator: influxdb.NotEqual,
},
{
Tag: influxdb.Tag{
Key: "k2",
Value: "v2",
},
Operator: influxdb.RegexEqual,
},
},
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
},
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
},
},
},
args: args{
userID: MustIDBase16(sixID),
notificationRule: &rule.Slack{
Base: rule.Base{
OwnerID: MustIDBase16(sixID),
Name: "name2",
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Critical,
},
},
TagRules: []notification.TagRule{
{
Tag: influxdb.Tag{
Key: "k1",
Value: "v1",
},
Operator: influxdb.NotEqual,
},
{
Tag: influxdb.Tag{
Key: "k2",
Value: "v2",
},
Operator: influxdb.RegexEqual,
},
},
},
MessageTemplate: "msg1",
},
},
wants: wants{
notificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Critical,
},
},
TagRules: []notification.TagRule{
{
Tag: influxdb.Tag{
Key: "k1",
Value: "v1",
},
Operator: influxdb.NotEqual,
},
{
Tag: influxdb.Tag{
Key: "k2",
Value: "v2",
},
Operator: influxdb.RegexEqual,
},
},
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Critical,
},
},
TagRules: []notification.TagRule{
{
Tag: influxdb.Tag{
Key: "k1",
Value: "v1",
},
Operator: influxdb.NotEqual,
},
{
Tag: influxdb.Tag{
Key: "k2",
Value: "v2",
},
Operator: influxdb.RegexEqual,
},
},
CRUDLog: influxdb.CRUDLog{
CreatedAt: fakeDate,
UpdatedAt: fakeDate,
},
},
MessageTemplate: "msg1",
},
},
userResourceMapping: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
},
{
ResourceID: MustIDBase16(twoID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, done := init(tt.fields, t)
defer done()
ctx := context.Background()
nrc := influxdb.NotificationRuleCreate{
NotificationRule: tt.args.notificationRule,
Status: influxdb.Active,
}
err := s.CreateNotificationRule(ctx, nrc, tt.args.userID)
if (err != nil) != (tt.wants.err != nil) {
t.Fatalf("expected error '%v' got '%v'", tt.wants.err, err)
}
if tt.wants.err == nil && !tt.args.notificationRule.GetID().Valid() {
t.Fatalf("notification rule ID not set from CreateNotificationRule")
}
if err != nil && tt.wants.err != nil {
if influxdb.ErrorCode(err) != influxdb.ErrorCode(tt.wants.err) {
t.Fatalf("expected error messages to match '%v' got '%v'", influxdb.ErrorCode(tt.wants.err), influxdb.ErrorCode(err))
}
}
urmFilter := influxdb.UserResourceMappingFilter{
UserID: tt.args.userID,
ResourceType: influxdb.NotificationRuleResourceType,
}
filter := influxdb.NotificationRuleFilter{
UserResourceMappingFilter: urmFilter,
}
nrs, _, err := s.FindNotificationRules(ctx, filter)
if err != nil {
t.Fatalf("failed to retrieve notification rules: %v", err)
}
if diff := cmp.Diff(nrs, tt.wants.notificationRules, notificationRuleCmpOptions...); diff != "" {
t.Errorf("notificationRules are different -got/+want\ndiff %s", diff)
}
})
}
}
// FindNotificationRuleByID testing.
func FindNotificationRuleByID(
init func(NotificationRuleFields, *testing.T) (influxdb.NotificationRuleStore, func()),
t *testing.T,
) {
type args struct {
id influxdb.ID
}
type wants struct {
err error
notificationRule influxdb.NotificationRule
}
tests := []struct {
name string
fields NotificationRuleFields
args args
wants wants
}{
{
name: "bad id",
fields: NotificationRuleFields{
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
args: args{
id: influxdb.ID(0),
},
wants: wants{
err: &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "provided notification rule ID has invalid format",
},
},
},
{
name: "not found",
fields: NotificationRuleFields{
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
args: args{
id: MustIDBase16(threeID),
},
wants: wants{
err: &influxdb.Error{
Code: influxdb.ENotFound,
Msg: "notification rule not found",
},
},
},
{
name: "basic find telegraf config by id",
fields: NotificationRuleFields{
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
args: args{
id: MustIDBase16(twoID),
},
wants: wants{
notificationRule: &rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, done := init(tt.fields, t)
defer done()
ctx := context.Background()
nr, err := s.FindNotificationRuleByID(ctx, tt.args.id)
ErrorsEqual(t, err, tt.wants.err)
if diff := cmp.Diff(nr, tt.wants.notificationRule, notificationRuleCmpOptions...); diff != "" {
t.Errorf("notification rule is different -got/+want\ndiff %s", diff)
}
})
}
}
// FindNotificationRules testing
func FindNotificationRules(
init func(NotificationRuleFields, *testing.T) (influxdb.NotificationRuleStore, func()),
t *testing.T,
) {
type args struct {
filter influxdb.NotificationRuleFilter
opts influxdb.FindOptions
}
type wants struct {
notificationRules []influxdb.NotificationRule
err error
}
tests := []struct {
name string
fields NotificationRuleFields
args args
wants wants
}{
{
name: "find nothing (empty set)",
fields: NotificationRuleFields{
UserResourceMappings: []*influxdb.UserResourceMapping{},
NotificationRules: []influxdb.NotificationRule{},
},
args: args{
filter: influxdb.NotificationRuleFilter{
UserResourceMappingFilter: influxdb.UserResourceMappingFilter{
ResourceType: influxdb.NotificationRuleResourceType,
},
},
},
wants: wants{
notificationRules: []influxdb.NotificationRule{},
},
},
{
name: "find all notification rules",
fields: NotificationRuleFields{
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
args: args{
filter: influxdb.NotificationRuleFilter{
UserResourceMappingFilter: influxdb.UserResourceMappingFilter{
UserID: MustIDBase16(sixID),
ResourceType: influxdb.NotificationRuleResourceType,
},
},
},
wants: wants{
notificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
},
{
name: "find owners only",
fields: NotificationRuleFields{
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
args: args{
filter: influxdb.NotificationRuleFilter{
UserResourceMappingFilter: influxdb.UserResourceMappingFilter{
UserID: MustIDBase16(sixID),
ResourceType: influxdb.NotificationRuleResourceType,
UserType: influxdb.Owner,
},
},
},
wants: wants{
notificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
},
},
},
{
name: "filter by organization id only",
fields: NotificationRuleFields{
Orgs: []*influxdb.Organization{
{
ID: MustIDBase16(oneID),
Name: "org1",
},
{
ID: MustIDBase16(fourID),
Name: "org4",
},
},
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
{
ResourceID: MustIDBase16(twoID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
},
{
ResourceID: MustIDBase16(fourID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
OrgID: MustIDBase16(fourID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr1",
},
Channel: "ch1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
OrgID: MustIDBase16(fourID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr2",
},
MessageTemplate: "body2",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(fourID),
OrgID: MustIDBase16(oneID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr3",
},
MessageTemplate: "msg",
},
},
},
args: args{
filter: influxdb.NotificationRuleFilter{
OrgID: idPtr(MustIDBase16(oneID)),
},
},
wants: wants{
notificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(fourID),
OrgID: MustIDBase16(oneID),
OwnerID: MustIDBase16(sixID),
EndpointID: 1,
Name: "nr3",
},
MessageTemplate: "msg",
},
},
},
},
{
name: "filter by organization name only",
fields: NotificationRuleFields{
Orgs: []*influxdb.Organization{
{
ID: MustIDBase16(oneID),
Name: "org1",
},
{
ID: MustIDBase16(fourID),
Name: "org4",
},
},
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
{
ResourceID: MustIDBase16(twoID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
},
{
ResourceID: MustIDBase16(fourID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
OrgID: MustIDBase16(fourID),
OwnerID: MustIDBase16(sixID),
EndpointID: 1,
Name: "nr1",
},
Channel: "ch1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
OrgID: MustIDBase16(fourID),
OwnerID: MustIDBase16(sixID),
EndpointID: 1,
Name: "nr2",
},
MessageTemplate: "body2",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(fourID),
OrgID: MustIDBase16(oneID),
OwnerID: MustIDBase16(sixID),
EndpointID: 1,
Name: "nr3",
},
MessageTemplate: "msg",
},
},
},
args: args{
filter: influxdb.NotificationRuleFilter{
Organization: strPtr("org4"),
},
},
wants: wants{
notificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
OrgID: MustIDBase16(fourID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr1",
},
Channel: "ch1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
OrgID: MustIDBase16(fourID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr2",
},
MessageTemplate: "body2",
},
},
},
},
// {
// name: "filter by tags",
// fields: NotificationRuleFields{
// Orgs: []*influxdb.Organization{
// {
// ID: MustIDBase16(oneID),
// Name: "org1",
// },
// {
// ID: MustIDBase16(fourID),
// Name: "org4",
// },
// },
// UserResourceMappings: []*influxdb.UserResourceMapping{
// {
// ResourceID: MustIDBase16(oneID),
// ResourceType: influxdb.NotificationRuleResourceType,
// UserID: MustIDBase16(sixID),
// UserType: influxdb.Owner,
// },
// {
// ResourceID: MustIDBase16(twoID),
// ResourceType: influxdb.NotificationRuleResourceType,
// UserID: MustIDBase16(sixID),
// UserType: influxdb.Member,
// },
// {
// ResourceID: MustIDBase16(fourID),
// ResourceType: influxdb.NotificationRuleResourceType,
// UserID: MustIDBase16(sixID),
// UserType: influxdb.Owner,
// },
// },
// NotificationRules: []influxdb.NotificationRule{
// &rule.Slack{
// Base: rule.Base{
// ID: MustIDBase16(oneID),
// OrgID: MustIDBase16(fourID),
// OwnerID: MustIDBase16(sixID),
// EndpointID: 1,
// Status: influxdb.Active,
// Name: "nr1",
// TagRules: []influxdb.TagRule{
// {
// Tag: influxdb.Tag{
// Key: "environment",
// Value: "production",
// },
// Operator: notification.Equal,
// },
// },
// },
// Channel: "ch1",
// MessageTemplate: "msg1",
// },
// &rule.Slack{
// Base: rule.Base{
// ID: MustIDBase16(twoID),
// OrgID: MustIDBase16(fourID),
// OwnerID: MustIDBase16(sixID),
// EndpointID: 1,
// Status: influxdb.Active,
// Name: "nr2",
// TagRules: []influxdb.TagRule{
// {
// Tag: influxdb.Tag{
// Key: "environment",
// Value: "production",
// },
// Operator: notification.Equal,
// },
// {
// Tag: influxdb.Tag{
// Key: "location",
// Value: "paris",
// },
// Operator: notification.Equal,
// },
// },
// },
// MessageTemplate: "body2",
// },
// &rule.Slack{
// Base: rule.Base{
// ID: MustIDBase16(fourID),
// OrgID: MustIDBase16(oneID),
// OwnerID: MustIDBase16(sixID),
// EndpointID: 1,
// Status: influxdb.Active,
// Name: "nr3",
// TagRules: []influxdb.TagRule{
// {
// Tag: influxdb.Tag{
// Key: "environment",
// Value: "production",
// },
// Operator: notification.Equal,
// },
// {
// Tag: influxdb.Tag{
// Key: "location",
// Value: "paris",
// },
// Operator: notification.Equal,
// },
// },
// },
// MessageTemplate: "msg",
// },
// },
// },
// args: args{
// filter: influxdb.NotificationRuleFilter{
// Organization: strPtr("org4"),
// Tags: []influxdb.Tag{
// {
// Key: "environment",
// Value: "production",
// },
// {
// Key: "location",
// Value: "paris",
// },
// },
// },
// },
// wants: wants{
// notificationRules: []influxdb.NotificationRule{
// &rule.Slack{
// Base: rule.Base{
// ID: MustIDBase16(fourID),
// OrgID: MustIDBase16(oneID),
// OwnerID: MustIDBase16(sixID),
// EndpointID: 1,
// Status: influxdb.Active,
// Name: "nr3",
// TagRules: []influxdb.TagRule{
// {
// Tag: influxdb.Tag{
// Key: "environment",
// Value: "production",
// },
// Operator: notification.Equal,
// },
// {
// Tag: influxdb.Tag{
// Key: "location",
// Value: "paris",
// },
// Operator: notification.Equal,
// },
// },
// },
// MessageTemplate: "msg",
// },
// },
// },
// },
{
name: "find owners and restrict by organization",
fields: NotificationRuleFields{
Orgs: []*influxdb.Organization{
{
ID: MustIDBase16(oneID),
Name: "org1",
},
{
ID: MustIDBase16(fourID),
Name: "org4",
},
},
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
{
ResourceID: MustIDBase16(twoID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
},
{
ResourceID: MustIDBase16(fourID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
OrgID: MustIDBase16(fourID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr1",
},
Channel: "ch1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
OrgID: MustIDBase16(fourID),
OwnerID: MustIDBase16(sixID),
EndpointID: 1,
Name: "nr2",
},
MessageTemplate: "body2",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(fourID),
OrgID: MustIDBase16(oneID),
OwnerID: MustIDBase16(sixID),
EndpointID: 1,
Name: "nr3",
},
MessageTemplate: "msg",
},
},
},
args: args{
filter: influxdb.NotificationRuleFilter{
OrgID: idPtr(MustIDBase16(oneID)),
UserResourceMappingFilter: influxdb.UserResourceMappingFilter{
UserID: MustIDBase16(sixID),
ResourceType: influxdb.NotificationRuleResourceType,
UserType: influxdb.Owner,
},
},
},
wants: wants{
notificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(fourID),
OrgID: MustIDBase16(oneID),
OwnerID: MustIDBase16(sixID),
EndpointID: 1,
Name: "nr3",
},
MessageTemplate: "msg",
},
},
},
},
{
name: "look for organization not bound to any notification rule",
fields: NotificationRuleFields{
Orgs: []*influxdb.Organization{
{
ID: MustIDBase16(oneID),
Name: "org1",
},
{
ID: MustIDBase16(fourID),
Name: "org4",
},
},
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
{
ResourceID: MustIDBase16(twoID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
},
{
ResourceID: MustIDBase16(fourID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
OrgID: MustIDBase16(fourID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr1",
},
Channel: "ch1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
OrgID: MustIDBase16(fourID),
OwnerID: MustIDBase16(sixID),
EndpointID: 1,
Name: "nr2",
},
MessageTemplate: "body2",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(fourID),
OrgID: MustIDBase16(fourID),
OwnerID: MustIDBase16(sixID),
EndpointID: 1,
Name: "nr3",
},
MessageTemplate: "msg",
},
},
},
args: args{
filter: influxdb.NotificationRuleFilter{
OrgID: idPtr(MustIDBase16(oneID)),
},
},
wants: wants{
notificationRules: []influxdb.NotificationRule{},
},
},
{
name: "find options limit",
fields: NotificationRuleFields{
Orgs: []*influxdb.Organization{
{
ID: MustIDBase16(oneID),
Name: "org1",
},
{
ID: MustIDBase16(fourID),
Name: "org4",
},
},
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
{
ResourceID: MustIDBase16(twoID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
},
{
ResourceID: MustIDBase16(fourID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
OrgID: MustIDBase16(oneID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr1",
},
Channel: "ch1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
OrgID: MustIDBase16(oneID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr2",
},
MessageTemplate: "body2",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(fourID),
OrgID: MustIDBase16(oneID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr3",
},
MessageTemplate: "msg",
},
},
},
args: args{
filter: influxdb.NotificationRuleFilter{
OrgID: idPtr(MustIDBase16(oneID)),
},
opts: influxdb.FindOptions{
Limit: 2,
},
},
wants: wants{
notificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
OrgID: MustIDBase16(oneID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr1",
},
Channel: "ch1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
OrgID: MustIDBase16(oneID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr2",
},
MessageTemplate: "body2",
},
},
},
},
{
name: "find options offset",
fields: NotificationRuleFields{
Orgs: []*influxdb.Organization{
{
ID: MustIDBase16(oneID),
Name: "org1",
},
{
ID: MustIDBase16(fourID),
Name: "org4",
},
},
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
{
ResourceID: MustIDBase16(twoID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
},
{
ResourceID: MustIDBase16(fourID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
OrgID: MustIDBase16(oneID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr1",
},
Channel: "ch1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
OrgID: MustIDBase16(oneID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr2",
},
MessageTemplate: "body2",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(fourID),
OrgID: MustIDBase16(oneID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr3",
},
MessageTemplate: "msg",
},
},
},
args: args{
filter: influxdb.NotificationRuleFilter{
OrgID: idPtr(MustIDBase16(oneID)),
},
opts: influxdb.FindOptions{
Offset: 1,
},
},
wants: wants{
notificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
OrgID: MustIDBase16(oneID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr2",
},
MessageTemplate: "body2",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(fourID),
OrgID: MustIDBase16(oneID),
EndpointID: 1,
OwnerID: MustIDBase16(sixID),
Name: "nr3",
},
MessageTemplate: "msg",
},
},
},
},
{
name: "find nothing",
fields: NotificationRuleFields{
Orgs: []*influxdb.Organization{
{
ID: MustIDBase16(oneID),
Name: "org1",
},
{
ID: MustIDBase16(fourID),
Name: "org4",
},
},
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
{
ResourceID: MustIDBase16(twoID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
},
{
ResourceID: MustIDBase16(fourID),
ResourceType: influxdb.NotificationRuleResourceType,
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
OrgID: MustIDBase16(fourID),
OwnerID: MustIDBase16(sixID),
EndpointID: 1,
Name: "nr1",
},
Channel: "ch1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
OrgID: MustIDBase16(fourID),
OwnerID: MustIDBase16(sixID),
EndpointID: 1,
Name: "nr2",
},
MessageTemplate: "body2",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(fourID),
OrgID: MustIDBase16(fourID),
OwnerID: MustIDBase16(sixID),
EndpointID: 1,
Name: "nr3",
},
MessageTemplate: "msg",
},
},
},
args: args{
filter: influxdb.NotificationRuleFilter{
UserResourceMappingFilter: influxdb.UserResourceMappingFilter{
UserID: MustIDBase16(fourID),
ResourceType: influxdb.NotificationRuleResourceType,
},
},
},
wants: wants{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, done := init(tt.fields, t)
defer done()
ctx := context.Background()
nrs, n, err := s.FindNotificationRules(ctx, tt.args.filter, tt.args.opts)
ErrorsEqual(t, err, tt.wants.err)
if n != len(tt.wants.notificationRules) {
t.Fatalf("notification rules length is different got %d, want %d", n, len(tt.wants.notificationRules))
}
if diff := cmp.Diff(nrs, tt.wants.notificationRules, notificationRuleCmpOptions...); diff != "" {
t.Errorf("notification rules are different -got/+want\ndiff %s", diff)
}
})
}
}
// UpdateNotificationRule testing.
func UpdateNotificationRule(
init func(NotificationRuleFields, *testing.T) (influxdb.NotificationRuleStore, func()),
t *testing.T,
) {
type args struct {
userID influxdb.ID
id influxdb.ID
notificationRule influxdb.NotificationRule
}
type wants struct {
notificationRule influxdb.NotificationRule
err error
}
tests := []struct {
name string
fields NotificationRuleFields
args args
wants wants
}{
{
name: "can't find the id",
fields: NotificationRuleFields{
TimeGenerator: fakeGenerator,
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
args: args{
userID: MustIDBase16(sixID),
id: MustIDBase16(fourID),
notificationRule: &rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink3",
SleepUntil: &time3,
Every: mustDuration("2h"),
},
MessageTemplate: "msg2",
},
},
wants: wants{
err: &influxdb.Error{
Code: influxdb.ENotFound,
Msg: "notification rule not found",
},
},
},
{
name: "regular update",
fields: NotificationRuleFields{
TimeGenerator: fakeGenerator,
IDGenerator: mock.NewIDGenerator(twoID, t),
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
Tasks: []influxdb.TaskCreate{
{
OwnerID: MustIDBase16(sixID),
OrganizationID: MustIDBase16(fourID),
Flux: `from(bucket: "foo") |> range(start: -1m)
option task = {name: "bar", every: 1m}
`,
},
},
Endpoints: []influxdb.NotificationEndpoint{
&endpoint.Slack{
URL: "http://localhost:7777",
Token: influxdb.SecretField{
// TODO(desa): not sure why this has to end in token, but it does
Key: "020f755c3c082001-token",
Value: strPtr("abc123"),
},
Base: endpoint.Base{
OrgID: MustIDBase16Ptr(fourID),
Name: "foo",
Status: influxdb.Active,
},
},
},
Orgs: []*influxdb.Organization{
{
ID: MustIDBase16(fourID),
Name: "foo",
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Info,
},
},
EndpointID: MustIDBase16(twoID),
TaskID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Info,
},
},
TaskID: MustIDBase16(twoID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
args: args{
userID: MustIDBase16(sixID),
id: MustIDBase16(twoID),
notificationRule: &rule.Slack{
Base: rule.Base{
OwnerID: MustIDBase16(sixID),
Name: "name3",
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Info,
},
},
RunbookLink: "runbooklink3",
SleepUntil: &time3,
Every: mustDuration("2h"),
},
MessageTemplate: "msg2",
},
},
wants: wants{
notificationRule: &rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name3",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
TaskID: MustIDBase16(twoID),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Info,
},
},
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink3",
SleepUntil: &time3,
Every: mustDuration("2h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: fakeDate,
},
},
MessageTemplate: "msg2",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, done := init(tt.fields, t)
defer done()
ctx := context.Background()
nrc := influxdb.NotificationRuleCreate{
NotificationRule: tt.args.notificationRule,
Status: influxdb.Active,
}
tc, err := s.UpdateNotificationRule(ctx, tt.args.id,
nrc, tt.args.userID)
ErrorsEqual(t, err, tt.wants.err)
if diff := cmp.Diff(tc, tt.wants.notificationRule, notificationRuleCmpOptions...); tt.wants.err == nil && diff != "" {
t.Errorf("notificationRules are different -got/+want\ndiff %s", diff)
}
})
}
}
// PatchNotificationRule testing.
func PatchNotificationRule(
init func(NotificationRuleFields, *testing.T) (influxdb.NotificationRuleStore, func()),
t *testing.T,
) {
name3 := "name2"
status3 := influxdb.Inactive
type args struct {
//userID influxdb.ID
id influxdb.ID
upd influxdb.NotificationRuleUpdate
}
type wants struct {
notificationRule influxdb.NotificationRule
err error
}
tests := []struct {
name string
fields NotificationRuleFields
args args
wants wants
}{
{
name: "can't find the id",
fields: NotificationRuleFields{
TimeGenerator: fakeGenerator,
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
args: args{
id: MustIDBase16(fourID),
upd: influxdb.NotificationRuleUpdate{
Name: &name3,
Status: &status3,
},
},
wants: wants{
err: &influxdb.Error{
Code: influxdb.ENotFound,
Msg: "notification rule not found",
},
},
},
{
name: "patch without status",
fields: NotificationRuleFields{
TimeGenerator: fakeGenerator,
IDGenerator: mock.NewIDGenerator(twoID, t),
Tasks: []influxdb.TaskCreate{
{
OwnerID: MustIDBase16(sixID),
OrganizationID: MustIDBase16(fourID),
Flux: `from(bucket: "foo") |> range(start: -1m)
option task = {name: "bar", every: 1m}
`,
},
},
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
Endpoints: []influxdb.NotificationEndpoint{
&endpoint.Slack{
URL: "http://localhost:7777",
Token: influxdb.SecretField{
// TODO(desa): not sure why this has to end in token, but it does
Key: "020f755c3c082001-token",
Value: strPtr("abc123"),
},
Base: endpoint.Base{
OrgID: MustIDBase16Ptr(fourID),
Name: "foo",
Status: influxdb.Active,
},
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Critical,
},
{
CurrentLevel: notification.Info,
},
},
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
EndpointID: MustIDBase16(twoID),
TaskID: MustIDBase16(twoID),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Critical,
},
{
CurrentLevel: notification.Info,
},
},
OrgID: MustIDBase16(fourID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
Orgs: []*influxdb.Organization{
{
ID: MustIDBase16(fourID),
Name: "foo",
},
},
},
args: args{
id: MustIDBase16(twoID),
upd: influxdb.NotificationRuleUpdate{
Name: &name3,
},
},
wants: wants{
notificationRule: &rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: name3,
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
TaskID: MustIDBase16(twoID),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Critical,
},
{
CurrentLevel: notification.Info,
},
},
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: fakeDate,
},
},
MessageTemplate: "msg",
},
},
},
{
name: "regular patch",
fields: NotificationRuleFields{
TimeGenerator: fakeGenerator,
IDGenerator: mock.NewIDGenerator(twoID, t),
Tasks: []influxdb.TaskCreate{
{
OwnerID: MustIDBase16(sixID),
OrganizationID: MustIDBase16(fourID),
Flux: `from(bucket: "foo") |> range(start: -1m)
option task = {name: "bar", every: 1m}
`,
},
},
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
Endpoints: []influxdb.NotificationEndpoint{
&endpoint.Slack{
URL: "http://localhost:7777",
Token: influxdb.SecretField{
// TODO(desa): not sure why this has to end in token, but it does
Key: "020f755c3c082001-token",
Value: strPtr("abc123"),
},
Base: endpoint.Base{
OrgID: MustIDBase16Ptr(fourID),
Name: "foo",
Status: influxdb.Active,
},
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Critical,
},
{
CurrentLevel: notification.Info,
},
},
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
EndpointID: MustIDBase16(twoID),
TaskID: MustIDBase16(twoID),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Critical,
},
{
CurrentLevel: notification.Info,
},
},
OrgID: MustIDBase16(fourID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
Orgs: []*influxdb.Organization{
{
ID: MustIDBase16(fourID),
Name: "foo",
},
},
},
args: args{
id: MustIDBase16(twoID),
upd: influxdb.NotificationRuleUpdate{
Name: &name3,
Status: &status3,
},
},
wants: wants{
notificationRule: &rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: name3,
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
TaskID: MustIDBase16(twoID),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Critical,
},
{
CurrentLevel: notification.Info,
},
},
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: fakeDate,
},
},
MessageTemplate: "msg",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, done := init(tt.fields, t)
defer done()
ctx := context.Background()
tc, err := s.PatchNotificationRule(ctx, tt.args.id, tt.args.upd)
ErrorsEqual(t, err, tt.wants.err)
if diff := cmp.Diff(tc, tt.wants.notificationRule, notificationRuleCmpOptions...); tt.wants.err == nil && diff != "" {
t.Errorf("notificationRules are different -got/+want\ndiff %s", diff)
}
})
}
}
// DeleteNotificationRule testing.
func DeleteNotificationRule(
init func(NotificationRuleFields, *testing.T) (influxdb.NotificationRuleStore, func()),
t *testing.T,
) {
type args struct {
id influxdb.ID
userID influxdb.ID
}
type wants struct {
notificationRules []influxdb.NotificationRule
userResourceMappings []*influxdb.UserResourceMapping
err error
}
tests := []struct {
name string
fields NotificationRuleFields
args args
wants wants
}{
{
name: "bad id",
fields: NotificationRuleFields{
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
args: args{
id: influxdb.ID(0),
userID: MustIDBase16(sixID),
},
wants: wants{
err: &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "provided notification rule ID has invalid format",
},
userResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
notificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
EndpointID: MustIDBase16(twoID),
OrgID: MustIDBase16(fourID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
},
{
name: "none existing config",
fields: NotificationRuleFields{
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
IDGenerator: mock.NewIDGenerator(twoID, t),
Tasks: []influxdb.TaskCreate{
{
OwnerID: MustIDBase16(sixID),
OrganizationID: MustIDBase16(fourID),
Flux: `from(bucket: "foo") |> range(start: -1m)
option task = {name: "bar", every: 1m}
`,
},
},
Orgs: []*influxdb.Organization{
{
ID: MustIDBase16(fourID),
Name: "foo",
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
TaskID: MustIDBase16(twoID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
args: args{
id: MustIDBase16(fourID),
userID: MustIDBase16(sixID),
},
wants: wants{
err: &influxdb.Error{
Code: influxdb.ENotFound,
Msg: "notification rule not found",
},
userResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
notificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink2",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
},
{
name: "regular delete",
fields: NotificationRuleFields{
UserResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
{
ResourceID: MustIDBase16(twoID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Member,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
Tasks: []influxdb.TaskCreate{
{
OwnerID: MustIDBase16(sixID),
OrganizationID: MustIDBase16(fourID),
Flux: `from(bucket: "foo") |> range(start: -1m)
option task = {name: "bar", every: 1m}
`,
},
},
IDGenerator: mock.NewIDGenerator(twoID, t),
Orgs: []*influxdb.Organization{
{
ID: MustIDBase16(fourID),
Name: "foo",
},
},
NotificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
EndpointID: MustIDBase16(twoID),
TaskID: MustIDBase16(twoID),
OrgID: MustIDBase16(fourID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(twoID),
Name: "name2",
OwnerID: MustIDBase16(sixID),
TaskID: MustIDBase16(twoID),
OrgID: MustIDBase16(fourID),
RunbookLink: "runbooklink2",
EndpointID: MustIDBase16(twoID),
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
MessageTemplate: "msg",
},
},
},
args: args{
id: MustIDBase16(twoID),
userID: MustIDBase16(sixID),
},
wants: wants{
userResourceMappings: []*influxdb.UserResourceMapping{
{
ResourceID: MustIDBase16(oneID),
UserID: MustIDBase16(sixID),
UserType: influxdb.Owner,
ResourceType: influxdb.NotificationRuleResourceType,
},
},
notificationRules: []influxdb.NotificationRule{
&rule.Slack{
Base: rule.Base{
ID: MustIDBase16(oneID),
Name: "name1",
OwnerID: MustIDBase16(sixID),
OrgID: MustIDBase16(fourID),
TaskID: MustIDBase16(twoID),
EndpointID: MustIDBase16(twoID),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Channel: "channel1",
MessageTemplate: "msg1",
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, done := init(tt.fields, t)
defer done()
ctx := context.Background()
err := s.DeleteNotificationRule(ctx, tt.args.id)
ErrorsEqual(t, err, tt.wants.err)
filter := influxdb.NotificationRuleFilter{
UserResourceMappingFilter: influxdb.UserResourceMappingFilter{
UserID: tt.args.userID,
ResourceType: influxdb.NotificationRuleResourceType,
},
}
nrs, n, err := s.FindNotificationRules(ctx, filter)
if err != nil && tt.wants.err == nil {
t.Fatalf("expected errors to be nil got '%v'", err)
}
if err != nil && tt.wants.err != nil {
if want, got := tt.wants.err.Error(), err.Error(); want != got {
t.Fatalf("expected error '%v' got '%v'", tt.wants.err, err)
}
}
if n != len(tt.wants.notificationRules) {
t.Fatalf("notification rules length is different got %d, want %d", n, len(tt.wants.notificationRules))
}
if diff := cmp.Diff(nrs, tt.wants.notificationRules, notificationRuleCmpOptions...); diff != "" {
t.Errorf("notification rules are different -got/+want\ndiff %s", diff)
}
})
}
}