mirror of
https://github.com/absmach/magistrala.git
synced 2026-06-23 04:10:28 +00:00
NOISSUE - Configure RE and reports billing callout (#3478)
Continuous Delivery / lint-and-build (push) Has been cancelled
Continuous Delivery / Build and Push Docker Images (push) Has been cancelled
Deploy GitHub Pages / swagger-ui (push) Has been cancelled
CI Pipeline / Lint Proto (push) Has been cancelled
CI Pipeline / lint-and-build (push) Has been cancelled
CI Pipeline / Detect Changes (push) Has been cancelled
CI Pipeline / Test ${{ matrix.module }} (push) Has been cancelled
CI Pipeline / Upload Coverage (push) Has been cancelled
Continuous Delivery / lint-and-build (push) Has been cancelled
Continuous Delivery / Build and Push Docker Images (push) Has been cancelled
Deploy GitHub Pages / swagger-ui (push) Has been cancelled
CI Pipeline / Lint Proto (push) Has been cancelled
CI Pipeline / lint-and-build (push) Has been cancelled
CI Pipeline / Detect Changes (push) Has been cancelled
CI Pipeline / Test ${{ matrix.module }} (push) Has been cancelled
CI Pipeline / Upload Coverage (push) Has been cancelled
Signed-off-by: JeffMboya <jangina.mboya@gmail.com> Signed-off-by: nyagamunene <stevenyaga2014@gmail.com> Co-authored-by: nyagamunene <stevenyaga2014@gmail.com>
This commit is contained in:
+8
-2
@@ -45,6 +45,7 @@ import (
|
||||
grpcClient "github.com/absmach/magistrala/readers/api/grpc"
|
||||
"github.com/absmach/magistrala/reports"
|
||||
httpapi "github.com/absmach/magistrala/reports/api"
|
||||
reportsevents "github.com/absmach/magistrala/reports/events"
|
||||
"github.com/absmach/magistrala/reports/middleware"
|
||||
"github.com/absmach/magistrala/reports/operations"
|
||||
repg "github.com/absmach/magistrala/reports/postgres"
|
||||
@@ -285,7 +286,7 @@ func main() {
|
||||
|
||||
runInfo := make(chan pkglog.RunInfo, channBuffer)
|
||||
|
||||
svc, err := newService(cfg, database, runInfo, authz, ec, logger, readersClient, template, callout, tracer)
|
||||
svc, err := newService(ctx, cfg, database, runInfo, authz, ec, logger, readersClient, template, callout, tracer)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("failed to create services: %s", err))
|
||||
exitCode = 1
|
||||
@@ -325,7 +326,7 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func newService(cfg config, db pgclient.Database, runInfo chan pkglog.RunInfo, authz mgauthz.Authorization, ec email.Config, logger *slog.Logger, readersClient grpcReadersV1.ReadersServiceClient, template reports.ReportTemplate, callout callout.Callout, tracer trace.Tracer) (reports.Service, error) {
|
||||
func newService(ctx context.Context, cfg config, db pgclient.Database, runInfo chan pkglog.RunInfo, authz mgauthz.Authorization, ec email.Config, logger *slog.Logger, readersClient grpcReadersV1.ReadersServiceClient, template reports.ReportTemplate, callout callout.Callout, tracer trace.Tracer) (reports.Service, error) {
|
||||
repo := repg.NewRepository(db)
|
||||
idp := uuid.New()
|
||||
|
||||
@@ -350,6 +351,11 @@ func newService(cfg config, db pgclient.Database, runInfo chan pkglog.RunInfo, a
|
||||
return nil, fmt.Errorf("failed to create reports service: %w", err)
|
||||
}
|
||||
|
||||
csvc, err = reportsevents.NewEventStoreMiddleware(ctx, csvc, cfg.ESURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to init reports event store middleware: %w", err)
|
||||
}
|
||||
|
||||
permConfig, err := permissions.ParsePermissionsFile(cfg.PermissionsFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse permissions file: %w", err)
|
||||
|
||||
+16
@@ -578,6 +578,14 @@ MG_REPORTS_EMAIL_TEMPLATE=reports.tmpl
|
||||
MG_REPORTS_DEFAULT_TEMPLATE=
|
||||
MG_PDF_CONVERTER_URL=http://pdf-generator:3000/forms/chromium/convert/html
|
||||
MG_REPORTS_URL=http://reports:9017
|
||||
MG_REPORTS_CALLOUT_URLS=""
|
||||
MG_REPORTS_CALLOUT_METHOD="POST"
|
||||
MG_REPORTS_CALLOUT_TLS_VERIFICATION="false"
|
||||
MG_REPORTS_CALLOUT_TIMEOUT="10s"
|
||||
MG_REPORTS_CALLOUT_CA_CERT=""
|
||||
MG_REPORTS_CALLOUT_CERT=""
|
||||
MG_REPORTS_CALLOUT_KEY=""
|
||||
MG_REPORTS_CALLOUT_OPERATIONS=""
|
||||
|
||||
## Addon Services
|
||||
|
||||
@@ -758,6 +766,14 @@ MG_REPORTS_EMAIL_TEMPLATE=reports.tmpl
|
||||
MG_REPORTS_DEFAULT_TEMPLATE=
|
||||
MG_REPORTS_URL=http://reports:9017
|
||||
MG_PDF_CONVERTER_URL=http://pdf-generator:3000/forms/chromium/convert/html
|
||||
MG_REPORTS_CALLOUT_URLS=""
|
||||
MG_REPORTS_CALLOUT_METHOD="POST"
|
||||
MG_REPORTS_CALLOUT_TLS_VERIFICATION="false"
|
||||
MG_REPORTS_CALLOUT_TIMEOUT="10s"
|
||||
MG_REPORTS_CALLOUT_CA_CERT=""
|
||||
MG_REPORTS_CALLOUT_CERT=""
|
||||
MG_REPORTS_CALLOUT_KEY=""
|
||||
MG_REPORTS_CALLOUT_OPERATIONS=""
|
||||
|
||||
### Timescale Reader gRPC Client Config (Magistrala)
|
||||
MG_TIMESCALE_READER_GRPC_URL=timescale-reader:7011
|
||||
|
||||
@@ -2139,6 +2139,14 @@ services:
|
||||
MG_REPORTS_DB_SSL_ROOT_CERT: ${MG_REPORTS_DB_SSL_ROOT_CERT}
|
||||
MG_REPORTS_DEFAULT_TEMPLATE: ${MG_REPORTS_DEFAULT_TEMPLATE}
|
||||
MG_PDF_CONVERTER_URL: ${MG_PDF_CONVERTER_URL}
|
||||
MG_REPORTS_CALLOUT_URLS: ${MG_REPORTS_CALLOUT_URLS}
|
||||
MG_REPORTS_CALLOUT_METHOD: ${MG_REPORTS_CALLOUT_METHOD}
|
||||
MG_REPORTS_CALLOUT_TLS_VERIFICATION: ${MG_REPORTS_CALLOUT_TLS_VERIFICATION}
|
||||
MG_REPORTS_CALLOUT_TIMEOUT: ${MG_REPORTS_CALLOUT_TIMEOUT}
|
||||
MG_REPORTS_CALLOUT_CA_CERT: ${MG_REPORTS_CALLOUT_CA_CERT}
|
||||
MG_REPORTS_CALLOUT_CERT: ${MG_REPORTS_CALLOUT_CERT}
|
||||
MG_REPORTS_CALLOUT_KEY: ${MG_REPORTS_CALLOUT_KEY}
|
||||
MG_REPORTS_CALLOUT_OPERATIONS: ${MG_REPORTS_CALLOUT_OPERATIONS}
|
||||
MG_MESSAGE_BROKER_URL: ${MG_MESSAGE_BROKER_URL}
|
||||
MG_ES_URL: ${MG_ES_URL}
|
||||
MG_JAEGER_URL: ${MG_JAEGER_URL}
|
||||
|
||||
+1
-1
@@ -83,7 +83,7 @@ type listRuleEvent struct {
|
||||
|
||||
// Encode implements the events.Event interface for listRuleEvent.
|
||||
func (lre listRuleEvent) Encode() (map[string]any, error) {
|
||||
val := lre.PageMeta.EventEncode()
|
||||
val := lre.EventEncode()
|
||||
maps.Copy(val, lre.baseRuleEvent.Encode())
|
||||
val["operation"] = ruleList
|
||||
return val, nil
|
||||
|
||||
@@ -0,0 +1,580 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package events_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala/internal/testsutil"
|
||||
"github.com/absmach/magistrala/pkg/authn"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
svcerr "github.com/absmach/magistrala/pkg/errors/service"
|
||||
"github.com/absmach/magistrala/pkg/messaging"
|
||||
"github.com/absmach/magistrala/pkg/roles"
|
||||
"github.com/absmach/magistrala/re"
|
||||
"github.com/absmach/magistrala/re/events"
|
||||
"github.com/absmach/magistrala/re/mocks"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
storeClient *redis.Client
|
||||
storeURL string
|
||||
validSession = authn.Session{
|
||||
DomainID: testsutil.GenerateUUID(&testing.T{}),
|
||||
UserID: testsutil.GenerateUUID(&testing.T{}),
|
||||
}
|
||||
validRule = generateTestRule(&testing.T{})
|
||||
validPage = re.Page{
|
||||
Offset: 0,
|
||||
Limit: 10,
|
||||
Total: 1,
|
||||
Rules: []re.Rule{validRule},
|
||||
}
|
||||
)
|
||||
|
||||
func newEventStoreMiddleware(t *testing.T) (*mocks.Service, re.Service) {
|
||||
svc := new(mocks.Service)
|
||||
nsvc, err := events.NewEventStoreMiddleware(context.Background(), svc, storeURL)
|
||||
require.Nil(t, err, fmt.Sprintf("create events store middleware failed with unexpected error: %s", err))
|
||||
|
||||
return svc, nsvc
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
code := testsutil.RunRedisTest(m, &storeClient, &storeURL)
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
func TestAddRule(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
rule re.Rule
|
||||
svcRes re.Rule
|
||||
svcRoleRes []roles.RoleProvision
|
||||
svcErr error
|
||||
resp re.Rule
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "publish successfully",
|
||||
session: validSession,
|
||||
rule: validRule,
|
||||
svcRes: validRule,
|
||||
svcRoleRes: []roles.RoleProvision{},
|
||||
svcErr: nil,
|
||||
resp: validRule,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed to publish with service error",
|
||||
session: validSession,
|
||||
rule: validRule,
|
||||
svcRes: re.Rule{},
|
||||
svcRoleRes: []roles.RoleProvision{},
|
||||
svcErr: svcerr.ErrCreateEntity,
|
||||
resp: re.Rule{},
|
||||
err: svcerr.ErrCreateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("AddRule", validCtx, tc.session, tc.rule).Return(tc.svcRes, tc.svcRoleRes, tc.svcErr)
|
||||
resp, _, err := nsvc.AddRule(validCtx, tc.session, tc.rule)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestViewRule(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
ruleID string
|
||||
withRoles bool
|
||||
svcRes re.Rule
|
||||
svcErr error
|
||||
resp re.Rule
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "publish successfully",
|
||||
session: validSession,
|
||||
ruleID: validRule.ID,
|
||||
withRoles: false,
|
||||
svcRes: validRule,
|
||||
svcErr: nil,
|
||||
resp: validRule,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed to publish with service error",
|
||||
session: validSession,
|
||||
ruleID: validRule.ID,
|
||||
withRoles: false,
|
||||
svcRes: re.Rule{},
|
||||
svcErr: svcerr.ErrViewEntity,
|
||||
resp: re.Rule{},
|
||||
err: svcerr.ErrViewEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("ViewRule", validCtx, tc.session, tc.ruleID, tc.withRoles).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.ViewRule(validCtx, tc.session, tc.ruleID, tc.withRoles)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateRule(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
updatedRule := validRule
|
||||
updatedRule.Name = "updatedName"
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
rule re.Rule
|
||||
svcRes re.Rule
|
||||
svcErr error
|
||||
resp re.Rule
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "publish successfully",
|
||||
session: validSession,
|
||||
rule: updatedRule,
|
||||
svcRes: updatedRule,
|
||||
svcErr: nil,
|
||||
resp: updatedRule,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed to publish with service error",
|
||||
session: validSession,
|
||||
rule: updatedRule,
|
||||
svcRes: re.Rule{},
|
||||
svcErr: svcerr.ErrUpdateEntity,
|
||||
resp: re.Rule{},
|
||||
err: svcerr.ErrUpdateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("UpdateRule", validCtx, tc.session, tc.rule).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.UpdateRule(validCtx, tc.session, tc.rule)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateRuleTags(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
taggedRule := validRule
|
||||
taggedRule.Tags = []string{"newtag1", "newtag2"}
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
rule re.Rule
|
||||
svcRes re.Rule
|
||||
svcErr error
|
||||
resp re.Rule
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "publish successfully",
|
||||
session: validSession,
|
||||
rule: taggedRule,
|
||||
svcRes: taggedRule,
|
||||
svcErr: nil,
|
||||
resp: taggedRule,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed to publish with service error",
|
||||
session: validSession,
|
||||
rule: taggedRule,
|
||||
svcRes: re.Rule{},
|
||||
svcErr: svcerr.ErrUpdateEntity,
|
||||
resp: re.Rule{},
|
||||
err: svcerr.ErrUpdateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("UpdateRuleTags", validCtx, tc.session, tc.rule).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.UpdateRuleTags(validCtx, tc.session, tc.rule)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateRuleSchedule(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
rule re.Rule
|
||||
svcRes re.Rule
|
||||
svcErr error
|
||||
resp re.Rule
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "publish successfully",
|
||||
session: validSession,
|
||||
rule: validRule,
|
||||
svcRes: validRule,
|
||||
svcErr: nil,
|
||||
resp: validRule,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed to publish with service error",
|
||||
session: validSession,
|
||||
rule: validRule,
|
||||
svcRes: re.Rule{},
|
||||
svcErr: svcerr.ErrUpdateEntity,
|
||||
resp: re.Rule{},
|
||||
err: svcerr.ErrUpdateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("UpdateRuleSchedule", validCtx, tc.session, tc.rule).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.UpdateRuleSchedule(validCtx, tc.session, tc.rule)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListRules(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
pageMeta re.PageMeta
|
||||
svcRes re.Page
|
||||
svcErr error
|
||||
resp re.Page
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "publish successfully",
|
||||
session: validSession,
|
||||
pageMeta: re.PageMeta{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
svcRes: validPage,
|
||||
svcErr: nil,
|
||||
resp: validPage,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed to publish with service error",
|
||||
session: validSession,
|
||||
pageMeta: re.PageMeta{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
svcRes: re.Page{},
|
||||
svcErr: svcerr.ErrViewEntity,
|
||||
resp: re.Page{},
|
||||
err: svcerr.ErrViewEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("ListRules", validCtx, tc.session, tc.pageMeta).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.ListRules(validCtx, tc.session, tc.pageMeta)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveRule(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
ruleID string
|
||||
svcErr error
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "publish successfully",
|
||||
session: validSession,
|
||||
ruleID: validRule.ID,
|
||||
svcErr: nil,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed to publish with service error",
|
||||
session: validSession,
|
||||
ruleID: validRule.ID,
|
||||
svcErr: svcerr.ErrRemoveEntity,
|
||||
err: svcerr.ErrRemoveEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("RemoveRule", validCtx, tc.session, tc.ruleID).Return(tc.svcErr)
|
||||
err := nsvc.RemoveRule(validCtx, tc.session, tc.ruleID)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnableRule(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
ruleID string
|
||||
svcRes re.Rule
|
||||
svcErr error
|
||||
resp re.Rule
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "publish successfully",
|
||||
session: validSession,
|
||||
ruleID: validRule.ID,
|
||||
svcRes: validRule,
|
||||
svcErr: nil,
|
||||
resp: validRule,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed to publish with service error",
|
||||
session: validSession,
|
||||
ruleID: validRule.ID,
|
||||
svcRes: re.Rule{},
|
||||
svcErr: svcerr.ErrUpdateEntity,
|
||||
resp: re.Rule{},
|
||||
err: svcerr.ErrUpdateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("EnableRule", validCtx, tc.session, tc.ruleID).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.EnableRule(validCtx, tc.session, tc.ruleID)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDisableRule(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
ruleID string
|
||||
svcRes re.Rule
|
||||
svcErr error
|
||||
resp re.Rule
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "publish successfully",
|
||||
session: validSession,
|
||||
ruleID: validRule.ID,
|
||||
svcRes: validRule,
|
||||
svcErr: nil,
|
||||
resp: validRule,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed to publish with service error",
|
||||
session: validSession,
|
||||
ruleID: validRule.ID,
|
||||
svcRes: re.Rule{},
|
||||
svcErr: svcerr.ErrUpdateEntity,
|
||||
resp: re.Rule{},
|
||||
err: svcerr.ErrUpdateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("DisableRule", validCtx, tc.session, tc.ruleID).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.DisableRule(validCtx, tc.session, tc.ruleID)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStartScheduler(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
svcErr error
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "start scheduler successfully",
|
||||
svcErr: nil,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed with service error",
|
||||
svcErr: svcerr.ErrCreateEntity,
|
||||
err: svcerr.ErrCreateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("StartScheduler", context.Background()).Return(tc.svcErr)
|
||||
err := nsvc.StartScheduler(context.Background())
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandle(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
msg := &messaging.Message{Channel: "test.channel"}
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
msg *messaging.Message
|
||||
svcErr error
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "handle successfully",
|
||||
msg: msg,
|
||||
svcErr: nil,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed with service error",
|
||||
msg: msg,
|
||||
svcErr: svcerr.ErrCreateEntity,
|
||||
err: svcerr.ErrCreateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("Handle", tc.msg).Return(tc.svcErr)
|
||||
err := nsvc.Handle(tc.msg)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancel(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
svcErr error
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "cancel successfully",
|
||||
svcErr: nil,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed with service error",
|
||||
svcErr: svcerr.ErrCreateEntity,
|
||||
err: svcerr.ErrCreateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("Cancel").Return(tc.svcErr)
|
||||
err := nsvc.Cancel()
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func generateTestRule(t *testing.T) re.Rule {
|
||||
createdAt, err := time.Parse(time.RFC3339, "2024-01-01T00:00:00Z")
|
||||
assert.Nil(t, err, fmt.Sprintf("Unexpected error parsing time: %v", err))
|
||||
return re.Rule{
|
||||
ID: testsutil.GenerateUUID(t),
|
||||
Name: "testrule",
|
||||
DomainID: testsutil.GenerateUUID(t),
|
||||
InputChannel: "test.channel",
|
||||
Status: re.EnabledStatus,
|
||||
CreatedAt: createdAt,
|
||||
UpdatedAt: createdAt,
|
||||
}
|
||||
}
|
||||
@@ -85,6 +85,19 @@ The service is configured using the following environment variables (values show
|
||||
| `MG_REPORTS_DEFAULT_TEMPLATE` | Use on-disk HTML template when non-empty | "" |
|
||||
| `MG_PDF_CONVERTER_URL` | HTML-to-PDF conversion endpoint | `http://pdf-generator:3000/forms/chromium/convert/html` |
|
||||
|
||||
### Callout
|
||||
|
||||
| Variable | Description | Default |
|
||||
| --- | --- | --- |
|
||||
| `MG_REPORTS_CALLOUT_URLS` | Callout target URLs | "" |
|
||||
| `MG_REPORTS_CALLOUT_METHOD` | Callout HTTP method | `POST` |
|
||||
| `MG_REPORTS_CALLOUT_TLS_VERIFICATION` | TLS verification for callout | `false` |
|
||||
| `MG_REPORTS_CALLOUT_TIMEOUT` | Callout timeout | `10s` |
|
||||
| `MG_REPORTS_CALLOUT_CA_CERT` | Callout CA cert path | "" |
|
||||
| `MG_REPORTS_CALLOUT_CERT` | Callout client cert path | "" |
|
||||
| `MG_REPORTS_CALLOUT_KEY` | Callout client key path | "" |
|
||||
| `MG_REPORTS_CALLOUT_OPERATIONS` | Callout operations filter | "" |
|
||||
|
||||
## Features
|
||||
|
||||
- **Report generation**: Build report data from time-series messages.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package events provides the domain concept definitions needed to support
|
||||
// reports events functionality.
|
||||
package events
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package events
|
||||
|
||||
import (
|
||||
"github.com/absmach/magistrala/pkg/authn"
|
||||
"github.com/absmach/magistrala/pkg/events"
|
||||
"github.com/absmach/magistrala/reports"
|
||||
)
|
||||
|
||||
const (
|
||||
reportPrefix = "report."
|
||||
reportCreate = reportPrefix + "create"
|
||||
reportRemove = reportPrefix + "remove"
|
||||
)
|
||||
|
||||
var (
|
||||
_ events.Event = (*createReportConfigEvent)(nil)
|
||||
_ events.Event = (*removeReportConfigEvent)(nil)
|
||||
)
|
||||
|
||||
type baseReportEvent struct {
|
||||
session authn.Session
|
||||
requestID string
|
||||
}
|
||||
|
||||
func newBaseReportEvent(session authn.Session, requestID string) baseReportEvent {
|
||||
return baseReportEvent{
|
||||
session: session,
|
||||
requestID: requestID,
|
||||
}
|
||||
}
|
||||
|
||||
func (bre baseReportEvent) Encode() map[string]any {
|
||||
return map[string]any{
|
||||
"domain": bre.session.DomainID,
|
||||
"user_id": bre.session.UserID,
|
||||
"token_type": bre.session.Type.String(),
|
||||
"super_admin": bre.session.SuperAdmin,
|
||||
"request_id": bre.requestID,
|
||||
}
|
||||
}
|
||||
|
||||
type createReportConfigEvent struct {
|
||||
cfg reports.ReportConfig
|
||||
baseReportEvent
|
||||
}
|
||||
|
||||
func (e createReportConfigEvent) Encode() (map[string]any, error) {
|
||||
val := e.baseReportEvent.Encode()
|
||||
val["id"] = e.cfg.ID
|
||||
val["name"] = e.cfg.Name
|
||||
val["operation"] = reportCreate
|
||||
return val, nil
|
||||
}
|
||||
|
||||
type removeReportConfigEvent struct {
|
||||
id string
|
||||
baseReportEvent
|
||||
}
|
||||
|
||||
func (e removeReportConfigEvent) Encode() (map[string]any, error) {
|
||||
val := e.baseReportEvent.Encode()
|
||||
val["id"] = e.id
|
||||
val["operation"] = reportRemove
|
||||
return val, nil
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package events
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/absmach/magistrala/pkg/authn"
|
||||
"github.com/absmach/magistrala/pkg/events"
|
||||
"github.com/absmach/magistrala/pkg/events/store"
|
||||
rmEvents "github.com/absmach/magistrala/pkg/roles/rolemanager/events"
|
||||
"github.com/absmach/magistrala/reports"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
)
|
||||
|
||||
const (
|
||||
magistralaPrefix = "magistrala."
|
||||
CreateStream = magistralaPrefix + reportCreate
|
||||
RemoveStream = magistralaPrefix + reportRemove
|
||||
)
|
||||
|
||||
var _ reports.Service = (*eventStore)(nil)
|
||||
|
||||
type eventStore struct {
|
||||
events.Publisher
|
||||
svc reports.Service
|
||||
rmEvents.RoleManagerEventStore
|
||||
}
|
||||
|
||||
func NewEventStoreMiddleware(ctx context.Context, svc reports.Service, url string) (reports.Service, error) {
|
||||
publisher, err := store.NewPublisher(ctx, url, "reports-es-pub")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := rmEvents.NewRoleManagerEventStore("reports", reportPrefix, svc, publisher)
|
||||
|
||||
return &eventStore{
|
||||
svc: svc,
|
||||
Publisher: publisher,
|
||||
RoleManagerEventStore: res,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (es *eventStore) AddReportConfig(ctx context.Context, session authn.Session, cfg reports.ReportConfig) (reports.ReportConfig, error) {
|
||||
reportCfg, err := es.svc.AddReportConfig(ctx, session, cfg)
|
||||
if err != nil {
|
||||
return reportCfg, err
|
||||
}
|
||||
event := createReportConfigEvent{
|
||||
cfg: reportCfg,
|
||||
baseReportEvent: newBaseReportEvent(session, middleware.GetReqID(ctx)),
|
||||
}
|
||||
if err := es.Publish(ctx, CreateStream, event); err != nil {
|
||||
return reportCfg, err
|
||||
}
|
||||
return reportCfg, nil
|
||||
}
|
||||
|
||||
func (es *eventStore) RemoveReportConfig(ctx context.Context, session authn.Session, id string) error {
|
||||
if err := es.svc.RemoveReportConfig(ctx, session, id); err != nil {
|
||||
return err
|
||||
}
|
||||
event := removeReportConfigEvent{
|
||||
id: id,
|
||||
baseReportEvent: newBaseReportEvent(session, middleware.GetReqID(ctx)),
|
||||
}
|
||||
return es.Publish(ctx, RemoveStream, event)
|
||||
}
|
||||
|
||||
func (es *eventStore) ViewReportConfig(ctx context.Context, session authn.Session, id string, withRoles bool) (reports.ReportConfig, error) {
|
||||
return es.svc.ViewReportConfig(ctx, session, id, withRoles)
|
||||
}
|
||||
|
||||
func (es *eventStore) UpdateReportConfig(ctx context.Context, session authn.Session, cfg reports.ReportConfig) (reports.ReportConfig, error) {
|
||||
return es.svc.UpdateReportConfig(ctx, session, cfg)
|
||||
}
|
||||
|
||||
func (es *eventStore) UpdateReportSchedule(ctx context.Context, session authn.Session, cfg reports.ReportConfig) (reports.ReportConfig, error) {
|
||||
return es.svc.UpdateReportSchedule(ctx, session, cfg)
|
||||
}
|
||||
|
||||
func (es *eventStore) ListReportsConfig(ctx context.Context, session authn.Session, pm reports.PageMeta) (reports.ReportConfigPage, error) {
|
||||
return es.svc.ListReportsConfig(ctx, session, pm)
|
||||
}
|
||||
|
||||
func (es *eventStore) EnableReportConfig(ctx context.Context, session authn.Session, id string) (reports.ReportConfig, error) {
|
||||
return es.svc.EnableReportConfig(ctx, session, id)
|
||||
}
|
||||
|
||||
func (es *eventStore) DisableReportConfig(ctx context.Context, session authn.Session, id string) (reports.ReportConfig, error) {
|
||||
return es.svc.DisableReportConfig(ctx, session, id)
|
||||
}
|
||||
|
||||
func (es *eventStore) UpdateReportTemplate(ctx context.Context, session authn.Session, cfg reports.ReportConfig) error {
|
||||
return es.svc.UpdateReportTemplate(ctx, session, cfg)
|
||||
}
|
||||
|
||||
func (es *eventStore) ViewReportTemplate(ctx context.Context, session authn.Session, id string) (reports.ReportTemplate, error) {
|
||||
return es.svc.ViewReportTemplate(ctx, session, id)
|
||||
}
|
||||
|
||||
func (es *eventStore) DeleteReportTemplate(ctx context.Context, session authn.Session, id string) error {
|
||||
return es.svc.DeleteReportTemplate(ctx, session, id)
|
||||
}
|
||||
|
||||
func (es *eventStore) GenerateReport(ctx context.Context, session authn.Session, config reports.ReportConfig, action reports.ReportAction) (reports.ReportPage, error) {
|
||||
return es.svc.GenerateReport(ctx, session, config, action)
|
||||
}
|
||||
|
||||
func (es *eventStore) StartScheduler(ctx context.Context) error {
|
||||
return es.svc.StartScheduler(ctx)
|
||||
}
|
||||
@@ -0,0 +1,632 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package events_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala/internal/testsutil"
|
||||
"github.com/absmach/magistrala/pkg/authn"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
svcerr "github.com/absmach/magistrala/pkg/errors/service"
|
||||
"github.com/absmach/magistrala/reports"
|
||||
"github.com/absmach/magistrala/reports/events"
|
||||
"github.com/absmach/magistrala/reports/mocks"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
storeClient *redis.Client
|
||||
storeURL string
|
||||
validSession = authn.Session{
|
||||
DomainID: testsutil.GenerateUUID(&testing.T{}),
|
||||
UserID: testsutil.GenerateUUID(&testing.T{}),
|
||||
}
|
||||
validReportConfig = generateTestReportConfig(&testing.T{})
|
||||
validReportConfigPage = reports.ReportConfigPage{
|
||||
PageMeta: reports.PageMeta{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
Total: 1,
|
||||
},
|
||||
ReportConfigs: []reports.ReportConfig{validReportConfig},
|
||||
}
|
||||
)
|
||||
|
||||
func newEventStoreMiddleware(t *testing.T) (*mocks.Service, reports.Service) {
|
||||
svc := new(mocks.Service)
|
||||
nsvc, err := events.NewEventStoreMiddleware(context.Background(), svc, storeURL)
|
||||
require.Nil(t, err, fmt.Sprintf("create events store middleware failed with unexpected error: %s", err))
|
||||
|
||||
return svc, nsvc
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
code := testsutil.RunRedisTest(m, &storeClient, &storeURL)
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
func TestAddReportConfig(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
cfg reports.ReportConfig
|
||||
svcRes reports.ReportConfig
|
||||
svcErr error
|
||||
resp reports.ReportConfig
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "publish successfully",
|
||||
session: validSession,
|
||||
cfg: validReportConfig,
|
||||
svcRes: validReportConfig,
|
||||
svcErr: nil,
|
||||
resp: validReportConfig,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed to publish with service error",
|
||||
session: validSession,
|
||||
cfg: validReportConfig,
|
||||
svcRes: reports.ReportConfig{},
|
||||
svcErr: svcerr.ErrCreateEntity,
|
||||
resp: reports.ReportConfig{},
|
||||
err: svcerr.ErrCreateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("AddReportConfig", validCtx, tc.session, tc.cfg).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.AddReportConfig(validCtx, tc.session, tc.cfg)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveReportConfig(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
reportID string
|
||||
svcErr error
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "publish successfully",
|
||||
session: validSession,
|
||||
reportID: validReportConfig.ID,
|
||||
svcErr: nil,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed to publish with service error",
|
||||
session: validSession,
|
||||
reportID: validReportConfig.ID,
|
||||
svcErr: svcerr.ErrRemoveEntity,
|
||||
err: svcerr.ErrRemoveEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("RemoveReportConfig", validCtx, tc.session, tc.reportID).Return(tc.svcErr)
|
||||
err := nsvc.RemoveReportConfig(validCtx, tc.session, tc.reportID)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestViewReportConfig(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
reportID string
|
||||
withRoles bool
|
||||
svcRes reports.ReportConfig
|
||||
svcErr error
|
||||
resp reports.ReportConfig
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "view successfully",
|
||||
session: validSession,
|
||||
reportID: validReportConfig.ID,
|
||||
withRoles: false,
|
||||
svcRes: validReportConfig,
|
||||
svcErr: nil,
|
||||
resp: validReportConfig,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed with service error",
|
||||
session: validSession,
|
||||
reportID: validReportConfig.ID,
|
||||
withRoles: false,
|
||||
svcRes: reports.ReportConfig{},
|
||||
svcErr: svcerr.ErrViewEntity,
|
||||
resp: reports.ReportConfig{},
|
||||
err: svcerr.ErrViewEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("ViewReportConfig", validCtx, tc.session, tc.reportID, tc.withRoles).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.ViewReportConfig(validCtx, tc.session, tc.reportID, tc.withRoles)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateReportConfig(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
updatedCfg := validReportConfig
|
||||
updatedCfg.Name = "updatedName"
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
cfg reports.ReportConfig
|
||||
svcRes reports.ReportConfig
|
||||
svcErr error
|
||||
resp reports.ReportConfig
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "update successfully",
|
||||
session: validSession,
|
||||
cfg: updatedCfg,
|
||||
svcRes: updatedCfg,
|
||||
svcErr: nil,
|
||||
resp: updatedCfg,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed with service error",
|
||||
session: validSession,
|
||||
cfg: updatedCfg,
|
||||
svcRes: reports.ReportConfig{},
|
||||
svcErr: svcerr.ErrUpdateEntity,
|
||||
resp: reports.ReportConfig{},
|
||||
err: svcerr.ErrUpdateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("UpdateReportConfig", validCtx, tc.session, tc.cfg).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.UpdateReportConfig(validCtx, tc.session, tc.cfg)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateReportSchedule(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
cfg reports.ReportConfig
|
||||
svcRes reports.ReportConfig
|
||||
svcErr error
|
||||
resp reports.ReportConfig
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "update schedule successfully",
|
||||
session: validSession,
|
||||
cfg: validReportConfig,
|
||||
svcRes: validReportConfig,
|
||||
svcErr: nil,
|
||||
resp: validReportConfig,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed with service error",
|
||||
session: validSession,
|
||||
cfg: validReportConfig,
|
||||
svcRes: reports.ReportConfig{},
|
||||
svcErr: svcerr.ErrUpdateEntity,
|
||||
resp: reports.ReportConfig{},
|
||||
err: svcerr.ErrUpdateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("UpdateReportSchedule", validCtx, tc.session, tc.cfg).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.UpdateReportSchedule(validCtx, tc.session, tc.cfg)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListReportsConfig(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
pageMeta reports.PageMeta
|
||||
svcRes reports.ReportConfigPage
|
||||
svcErr error
|
||||
resp reports.ReportConfigPage
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "list successfully",
|
||||
session: validSession,
|
||||
pageMeta: reports.PageMeta{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
svcRes: validReportConfigPage,
|
||||
svcErr: nil,
|
||||
resp: validReportConfigPage,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed with service error",
|
||||
session: validSession,
|
||||
pageMeta: reports.PageMeta{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
svcRes: reports.ReportConfigPage{},
|
||||
svcErr: svcerr.ErrViewEntity,
|
||||
resp: reports.ReportConfigPage{},
|
||||
err: svcerr.ErrViewEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("ListReportsConfig", validCtx, tc.session, tc.pageMeta).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.ListReportsConfig(validCtx, tc.session, tc.pageMeta)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnableReportConfig(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
reportID string
|
||||
svcRes reports.ReportConfig
|
||||
svcErr error
|
||||
resp reports.ReportConfig
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "enable successfully",
|
||||
session: validSession,
|
||||
reportID: validReportConfig.ID,
|
||||
svcRes: validReportConfig,
|
||||
svcErr: nil,
|
||||
resp: validReportConfig,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed with service error",
|
||||
session: validSession,
|
||||
reportID: validReportConfig.ID,
|
||||
svcRes: reports.ReportConfig{},
|
||||
svcErr: svcerr.ErrUpdateEntity,
|
||||
resp: reports.ReportConfig{},
|
||||
err: svcerr.ErrUpdateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("EnableReportConfig", validCtx, tc.session, tc.reportID).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.EnableReportConfig(validCtx, tc.session, tc.reportID)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDisableReportConfig(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
reportID string
|
||||
svcRes reports.ReportConfig
|
||||
svcErr error
|
||||
resp reports.ReportConfig
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "disable successfully",
|
||||
session: validSession,
|
||||
reportID: validReportConfig.ID,
|
||||
svcRes: validReportConfig,
|
||||
svcErr: nil,
|
||||
resp: validReportConfig,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed with service error",
|
||||
session: validSession,
|
||||
reportID: validReportConfig.ID,
|
||||
svcRes: reports.ReportConfig{},
|
||||
svcErr: svcerr.ErrUpdateEntity,
|
||||
resp: reports.ReportConfig{},
|
||||
err: svcerr.ErrUpdateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("DisableReportConfig", validCtx, tc.session, tc.reportID).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.DisableReportConfig(validCtx, tc.session, tc.reportID)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateReportTemplate(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
cfg reports.ReportConfig
|
||||
svcErr error
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "update template successfully",
|
||||
session: validSession,
|
||||
cfg: validReportConfig,
|
||||
svcErr: nil,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed with service error",
|
||||
session: validSession,
|
||||
cfg: validReportConfig,
|
||||
svcErr: svcerr.ErrUpdateEntity,
|
||||
err: svcerr.ErrUpdateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("UpdateReportTemplate", validCtx, tc.session, tc.cfg).Return(tc.svcErr)
|
||||
err := nsvc.UpdateReportTemplate(validCtx, tc.session, tc.cfg)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestViewReportTemplate(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
reportID string
|
||||
svcRes reports.ReportTemplate
|
||||
svcErr error
|
||||
resp reports.ReportTemplate
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "view template successfully",
|
||||
session: validSession,
|
||||
reportID: validReportConfig.ID,
|
||||
svcRes: reports.ReportTemplate("template content"),
|
||||
svcErr: nil,
|
||||
resp: reports.ReportTemplate("template content"),
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed with service error",
|
||||
session: validSession,
|
||||
reportID: validReportConfig.ID,
|
||||
svcRes: reports.ReportTemplate(""),
|
||||
svcErr: svcerr.ErrViewEntity,
|
||||
resp: reports.ReportTemplate(""),
|
||||
err: svcerr.ErrViewEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("ViewReportTemplate", validCtx, tc.session, tc.reportID).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.ViewReportTemplate(validCtx, tc.session, tc.reportID)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteReportTemplate(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
reportID string
|
||||
svcErr error
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "delete template successfully",
|
||||
session: validSession,
|
||||
reportID: validReportConfig.ID,
|
||||
svcErr: nil,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed with service error",
|
||||
session: validSession,
|
||||
reportID: validReportConfig.ID,
|
||||
svcErr: svcerr.ErrRemoveEntity,
|
||||
err: svcerr.ErrRemoveEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("DeleteReportTemplate", validCtx, tc.session, tc.reportID).Return(tc.svcErr)
|
||||
err := nsvc.DeleteReportTemplate(validCtx, tc.session, tc.reportID)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateReport(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
validCtx := context.WithValue(context.Background(), middleware.RequestIDKey, testsutil.GenerateUUID(t))
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
config reports.ReportConfig
|
||||
action reports.ReportAction
|
||||
svcRes reports.ReportPage
|
||||
svcErr error
|
||||
resp reports.ReportPage
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "generate report successfully",
|
||||
session: validSession,
|
||||
config: validReportConfig,
|
||||
action: reports.ViewReport,
|
||||
svcRes: reports.ReportPage{},
|
||||
svcErr: nil,
|
||||
resp: reports.ReportPage{},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed with service error",
|
||||
session: validSession,
|
||||
config: validReportConfig,
|
||||
action: reports.ViewReport,
|
||||
svcRes: reports.ReportPage{},
|
||||
svcErr: svcerr.ErrViewEntity,
|
||||
resp: reports.ReportPage{},
|
||||
err: svcerr.ErrViewEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("GenerateReport", validCtx, tc.session, tc.config, tc.action).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := nsvc.GenerateReport(validCtx, tc.session, tc.config, tc.action)
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
assert.Equal(t, tc.resp, resp, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.resp, resp))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStartScheduler(t *testing.T) {
|
||||
svc, nsvc := newEventStoreMiddleware(t)
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
svcErr error
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "start scheduler successfully",
|
||||
svcErr: nil,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "failed with service error",
|
||||
svcErr: svcerr.ErrCreateEntity,
|
||||
err: svcerr.ErrCreateEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("StartScheduler", context.Background()).Return(tc.svcErr)
|
||||
err := nsvc.StartScheduler(context.Background())
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func generateTestReportConfig(t *testing.T) reports.ReportConfig {
|
||||
createdAt, err := time.Parse(time.RFC3339, "2024-01-01T00:00:00Z")
|
||||
assert.Nil(t, err, fmt.Sprintf("Unexpected error parsing time: %v", err))
|
||||
return reports.ReportConfig{
|
||||
ID: testsutil.GenerateUUID(t),
|
||||
Name: "testreport",
|
||||
DomainID: testsutil.GenerateUUID(t),
|
||||
Status: reports.EnabledStatus,
|
||||
CreatedAt: createdAt,
|
||||
UpdatedAt: createdAt,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user