From 1632bf143dda6569871624350252568f77e229f3 Mon Sep 17 00:00:00 2001 From: Allen Annom Date: Thu, 16 Jan 2025 16:06:48 +0000 Subject: [PATCH] UML-3724 consuming event and added tests --- lambda-functions/event-receiver/app/config.go | 10 --- .../event-receiver/app/factory.go | 13 +--- .../event-receiver/app/factory_test.go | 27 ++++++++ .../event-receiver/app/handler.go | 23 ++++--- .../event-receiver/app/handler_test.go | 12 ++++ lambda-functions/event-receiver/app/logger.go | 6 +- .../event-receiver/app/logger_test.go | 38 +++++++++++ lambda-functions/event-receiver/app/main.go | 13 ++-- .../app/mocks/CloudWatchHandler.go | 47 ++++++++++++++ .../event-receiver/app/mocks/Factory.go | 65 +++++++++++++++++++ .../event-receiver/app/mocks/Logger.go | 45 +++++++++++++ lambda-functions/event-receiver/go.mod | 25 ++++++- lambda-functions/event-receiver/go.sum | 38 +++++++++++ 13 files changed, 324 insertions(+), 38 deletions(-) create mode 100644 lambda-functions/event-receiver/app/factory_test.go create mode 100644 lambda-functions/event-receiver/app/handler_test.go create mode 100644 lambda-functions/event-receiver/app/logger_test.go create mode 100644 lambda-functions/event-receiver/app/mocks/CloudWatchHandler.go create mode 100644 lambda-functions/event-receiver/app/mocks/Factory.go create mode 100644 lambda-functions/event-receiver/app/mocks/Logger.go diff --git a/lambda-functions/event-receiver/app/config.go b/lambda-functions/event-receiver/app/config.go index 6aa6fab803..a94f79357c 100644 --- a/lambda-functions/event-receiver/app/config.go +++ b/lambda-functions/event-receiver/app/config.go @@ -4,16 +4,6 @@ import ( "os" ) -type AppConfig struct { - EventBusName string -} - -func LoadConfig() AppConfig { - return AppConfig{ - EventBusName: getEnv("EVENT_BUS_NAME", "default") - } -} - func getEnv(key, fallback string) string { if value, exists := os.LookupEnv(key); exists { return value diff --git a/lambda-functions/event-receiver/app/factory.go b/lambda-functions/event-receiver/app/factory.go index 89e562d56d..b2188c306a 100644 --- a/lambda-functions/event-receiver/app/factory.go +++ b/lambda-functions/event-receiver/app/factory.go @@ -5,22 +5,19 @@ import ( ) type Factory interface { - GetAWSConfig() aws.GetAWSConfig + GetAWSConfig() aws.Config GetLogger() Logger - GetConfig() AppConfig } type factory struct { - awsConfig aws.GetAWSConfig + awsConfig aws.Config logger Logger - config AppConfig } -func NewFactory(cfg aws.Config, logger Logger, config AppConfig) Factory { +func NewFactory(cfg aws.Config, logger Logger) Factory { return &factory{ awsConfig: cfg, logger: logger, - config: config, } } @@ -31,7 +28,3 @@ func (f *factory) GetAWSConfig() aws.Config { func (f *factory) GetLogger() Logger { return f.logger } - -func (f *factory) GetConfig() AppConfig { - return f.config -} \ No newline at end of file diff --git a/lambda-functions/event-receiver/app/factory_test.go b/lambda-functions/event-receiver/app/factory_test.go new file mode 100644 index 0000000000..e4efa596fa --- /dev/null +++ b/lambda-functions/event-receiver/app/factory_test.go @@ -0,0 +1,27 @@ +package main + +import ( + "testing" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/stretchr/testify/assert" + "github.com/ministryofjustice/opg-use-an-lpa/app/mocks" +) + +func TestFactory_GetLogger(t *testing.T) { + mockLogger := new(mocks.Logger) + mockAWSConfig := aws.Config{} + + factory := NewFactory(mockAWSConfig, mockLogger) + + assert.Equal(t, mockLogger, factory.GetLogger()) +} + +func TestFactory_GetAWSConfig(t *testing.T) { + mockLogger := new(mocks.Logger) + mockAWSConfig := aws.Config{} + + factory := NewFactory(mockAWSConfig, mockLogger) + + assert.Equal(t, mockAWSConfig, factory.GetAWSConfig()) +} diff --git a/lambda-functions/event-receiver/app/handler.go b/lambda-functions/event-receiver/app/handler.go index a924bede86..a2a3439e64 100644 --- a/lambda-functions/event-receiver/app/handler.go +++ b/lambda-functions/event-receiver/app/handler.go @@ -8,8 +8,8 @@ import ( "github.com/aws/aws-lambda-go/events" ) -type CloudWatchHandler interfact { - Handle(ctx context.Context, event events.CloudWatchHandler) error +type CloudWatchHandler interface { + Handle(ctx context.Context, event events.CloudWatchEvent) error } type cloudWatchHandler struct { @@ -24,17 +24,22 @@ func NewCloudWatchHandler(factory Factory, logger Logger) CloudWatchHandler { } } -func (h *cloudWatchHandler) Handle(ctx context.Context, event events.CloudWatchHandler) error { +func (h *cloudWatchHandler) Handle(ctx context.Context, event events.CloudWatchEvent) error { + var parsedEvent events.CloudWatchEvent + h.logger.Info("Received CloudWatch event", "source", event.Source) - switch event.Source { - case "opg.poas.makeregister": - h.logger.Info("Handling 'makeregister' event", "detailType", event.DetailType) + err := json.Unmarshal(event.Detail, &parsedEvent) + if err != nil { + h.logger.Error("Failed to unmarshal event detail", err) + return fmt.Errorf("failed to unmarshal event: %w", err) + } + switch parsedEvent.Source { + case "opg.poas.makeregister": + h.logger.Info("Handling 'makeregister' event", "detailType", parsedEvent.DetailType) default: - eventData, _ := json.Marshal(event) - h.logger.Warn("Unhandled event source", fmt.Errorf("unknown source: %s", event.Source), "event", string(eventData)) - return fmt.Errorf("unknown event source: %s", event.Source) + h.logger.Warn("Unhandled event source: " + parsedEvent.Source, err) } return nil diff --git a/lambda-functions/event-receiver/app/handler_test.go b/lambda-functions/event-receiver/app/handler_test.go new file mode 100644 index 0000000000..e627d21ff3 --- /dev/null +++ b/lambda-functions/event-receiver/app/handler_test.go @@ -0,0 +1,12 @@ +package main + +import ( + "testing" + "context" + "encoding/json" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/assert" + "github.com/ministryofjustice/opg-use-an-lpa/app/mocks" + "github.com/aws/aws-lambda-go/events" +) diff --git a/lambda-functions/event-receiver/app/logger.go b/lambda-functions/event-receiver/app/logger.go index 504048f680..5b50e54ac9 100644 --- a/lambda-functions/event-receiver/app/logger.go +++ b/lambda-functions/event-receiver/app/logger.go @@ -5,9 +5,9 @@ import ( ) type Logger interface { - Info(message String, args ...interface{}) - Warn(message String, err error, args ...interface{}) - Error(message String, err error) + Info(message string, args ...interface{}) + Warn(message string, err error, args ...interface{}) + Error(message string, err error) } type defaultLogger struct{} diff --git a/lambda-functions/event-receiver/app/logger_test.go b/lambda-functions/event-receiver/app/logger_test.go new file mode 100644 index 0000000000..0a4d85005e --- /dev/null +++ b/lambda-functions/event-receiver/app/logger_test.go @@ -0,0 +1,38 @@ +package main + +import ( + "testing" + + "github.com/stretchr/testify/mock" + "github.com/ministryofjustice/opg-use-an-lpa/app/mocks" +) + +func TestLogger_Info(t *testing.T) { + mockLogger := new(mocks.Logger) + + mockLogger.On("Info", "Test info log").Return() + + mockLogger.Info("Test info log") + + mockLogger.AssertExpectations(t) +} + +func TestLogger_Warn(t *testing.T) { + mockLogger := new(mocks.Logger) + + mockLogger.On("Warn", "Test warn log", mock.Anything).Return() + + mockLogger.Warn("Test warn log", nil) + + mockLogger.AssertExpectations(t) +} + +func TestLogger_Error(t *testing.T) { + mockLogger := new(mocks.Logger) + + mockLogger.On("Error", "Test error log", mock.Anything).Return() + + mockLogger.Error("Test error log", nil) + + mockLogger.AssertExpectations(t) +} diff --git a/lambda-functions/event-receiver/app/main.go b/lambda-functions/event-receiver/app/main.go index 7a1080cc88..3d798379c3 100755 --- a/lambda-functions/event-receiver/app/main.go +++ b/lambda-functions/event-receiver/app/main.go @@ -3,8 +3,13 @@ package main import ( "context" - "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/aws" +) + +var ( + cfg aws.Config ) func main() { @@ -16,13 +21,11 @@ func main() { cfg, err = config.LoadDefaultConfig(ctx) if err != nil { - logger.ErrorContext(ctx, "failed to load default config", slog.Any("err", err)) + logger.Error("failed to load default config", err) return } - appConfig := LoadConfig() - - appFactory := NewFactory(cfg, logger, appConfig) + appFactory := NewFactory(cfg, logger) handler := NewCloudWatchHandler(appFactory, logger) diff --git a/lambda-functions/event-receiver/app/mocks/CloudWatchHandler.go b/lambda-functions/event-receiver/app/mocks/CloudWatchHandler.go new file mode 100644 index 0000000000..d148cd6d1e --- /dev/null +++ b/lambda-functions/event-receiver/app/mocks/CloudWatchHandler.go @@ -0,0 +1,47 @@ +// Code generated by mockery v2.51.0. DO NOT EDIT. + +package mocks + +import ( + context "context" + + events "github.com/aws/aws-lambda-go/events" + mock "github.com/stretchr/testify/mock" +) + +// CloudWatchHandler is an autogenerated mock type for the CloudWatchHandler type +type CloudWatchHandler struct { + mock.Mock +} + +// Handle provides a mock function with given fields: ctx, event +func (_m *CloudWatchHandler) Handle(ctx context.Context, event events.CloudWatchEvent) error { + ret := _m.Called(ctx, event) + + if len(ret) == 0 { + panic("no return value specified for Handle") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, events.CloudWatchEvent) error); ok { + r0 = rf(ctx, event) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// NewCloudWatchHandler creates a new instance of CloudWatchHandler. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewCloudWatchHandler(t interface { + mock.TestingT + Cleanup(func()) +}) *CloudWatchHandler { + mock := &CloudWatchHandler{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/lambda-functions/event-receiver/app/mocks/Factory.go b/lambda-functions/event-receiver/app/mocks/Factory.go new file mode 100644 index 0000000000..a6a2084917 --- /dev/null +++ b/lambda-functions/event-receiver/app/mocks/Factory.go @@ -0,0 +1,65 @@ +// Code generated by mockery v2.51.0. DO NOT EDIT. + +package mocks + +import ( + aws "github.com/aws/aws-sdk-go-v2/aws" + mock "github.com/stretchr/testify/mock" +) + +// Factory is an autogenerated mock type for the Factory type +type Factory struct { + mock.Mock +} + +// GetAWSConfig provides a mock function with no fields +func (_m *Factory) GetAWSConfig() aws.Config { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetAWSConfig") + } + + var r0 aws.Config + if rf, ok := ret.Get(0).(func() aws.Config); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(aws.Config) + } + + return r0 +} + +// GetLogger provides a mock function with no fields +func (_m *Factory) GetLogger() Logger { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetLogger") + } + + var r0 Logger + if rf, ok := ret.Get(0).(func() Logger); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(Logger) + } + } + + return r0 +} + +// NewFactory creates a new instance of Factory. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewFactory(t interface { + mock.TestingT + Cleanup(func()) +}) *Factory { + mock := &Factory{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/lambda-functions/event-receiver/app/mocks/Logger.go b/lambda-functions/event-receiver/app/mocks/Logger.go new file mode 100644 index 0000000000..1823adc9f5 --- /dev/null +++ b/lambda-functions/event-receiver/app/mocks/Logger.go @@ -0,0 +1,45 @@ +// Code generated by mockery v2.51.0. DO NOT EDIT. + +package mocks + +import mock "github.com/stretchr/testify/mock" + +// Logger is an autogenerated mock type for the Logger type +type Logger struct { + mock.Mock +} + +// Error provides a mock function with given fields: message, err +func (_m *Logger) Error(message string, err error) { + _m.Called(message, err) +} + +// Info provides a mock function with given fields: message, args +func (_m *Logger) Info(message string, args ...interface{}) { + var _ca []interface{} + _ca = append(_ca, message) + _ca = append(_ca, args...) + _m.Called(_ca...) +} + +// Warn provides a mock function with given fields: message, err, args +func (_m *Logger) Warn(message string, err error, args ...interface{}) { + var _ca []interface{} + _ca = append(_ca, message, err) + _ca = append(_ca, args...) + _m.Called(_ca...) +} + +// NewLogger creates a new instance of Logger. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewLogger(t interface { + mock.TestingT + Cleanup(func()) +}) *Logger { + mock := &Logger{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/lambda-functions/event-receiver/go.mod b/lambda-functions/event-receiver/go.mod index f44c3becbb..0b472c16bb 100644 --- a/lambda-functions/event-receiver/go.mod +++ b/lambda-functions/event-receiver/go.mod @@ -2,4 +2,27 @@ module github.com/ministryofjustice/opg-use-an-lpa go 1.23.1 -require github.com/aws/aws-lambda-go v1.47.0 // indirect +require ( + github.com/aws/aws-lambda-go v1.47.0 + github.com/aws/aws-sdk-go-v2 v1.33.0 + github.com/aws/aws-sdk-go-v2/config v1.29.0 + github.com/stretchr/testify v1.10.0 +) + +require ( + github.com/aws/aws-sdk-go-v2/credentials v1.17.53 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.24 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.28 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.28 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.9 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.24.10 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.9 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.33.8 // indirect + github.com/aws/smithy-go v1.22.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/lambda-functions/event-receiver/go.sum b/lambda-functions/event-receiver/go.sum index 23a2b4057f..02684e7b7a 100644 --- a/lambda-functions/event-receiver/go.sum +++ b/lambda-functions/event-receiver/go.sum @@ -1,2 +1,40 @@ github.com/aws/aws-lambda-go v1.47.0 h1:0H8s0vumYx/YKs4sE7YM0ktwL2eWse+kfopsRI1sXVI= github.com/aws/aws-lambda-go v1.47.0/go.mod h1:dpMpZgvWx5vuQJfBt0zqBha60q7Dd7RfgJv23DymV8A= +github.com/aws/aws-sdk-go-v2 v1.33.0 h1:Evgm4DI9imD81V0WwD+TN4DCwjUMdc94TrduMLbgZJs= +github.com/aws/aws-sdk-go-v2 v1.33.0/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= +github.com/aws/aws-sdk-go-v2/config v1.29.0 h1:Vk/u4jof33or1qAQLdofpjKV7mQQT7DcUpnYx8kdmxY= +github.com/aws/aws-sdk-go-v2/config v1.29.0/go.mod h1:iXAZK3Gxvpq3tA+B9WaDYpZis7M8KFgdrDPMmHrgbJM= +github.com/aws/aws-sdk-go-v2/credentials v1.17.53 h1:lwrVhiEDW5yXsuVKlFVUnR2R50zt2DklhOyeLETqDuE= +github.com/aws/aws-sdk-go-v2/credentials v1.17.53/go.mod h1:CkqM1bIw/xjEpBMhBnvqUXYZbpCFuj6dnCAyDk2AtAY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.24 h1:5grmdTdMsovn9kPZPI23Hhvp0ZyNm5cRO+IZFIYiAfw= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.24/go.mod h1:zqi7TVKTswH3Ozq28PkmBmgzG1tona7mo9G2IJg4Cis= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.28 h1:igORFSiH3bfq4lxKFkTSYDhJEUCYo6C8VKiWJjYwQuQ= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.28/go.mod h1:3So8EA/aAYm36L7XIvCVwLa0s5N0P7o2b1oqnx/2R4g= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.28 h1:1mOW9zAUMhTSrMDssEHS/ajx8JcAj/IcftzcmNlmVLI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.28/go.mod h1:kGlXVIWDfvt2Ox5zEaNglmq0hXPHgQFNMix33Tw22jA= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.9 h1:TQmKDyETFGiXVhZfQ/I0cCFziqqX58pi4tKJGYGFSz0= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.9/go.mod h1:HVLPK2iHQBUx7HfZeOQSEu3v2ubZaAY2YPbAm5/WUyY= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.10 h1:DyZUj3xSw3FR3TXSwDhPhuZkkT14QHBiacdbUVcD0Dg= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.10/go.mod h1:Ro744S4fKiCCuZECXgOi760TiYylUM8ZBf6OGiZzJtY= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.9 h1:I1TsPEs34vbpOnR81GIcAq4/3Ud+jRHVGwx6qLQUHLs= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.9/go.mod h1:Fzsj6lZEb8AkTE5S68OhcbBqeWPsR8RnGuKPr8Todl8= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.8 h1:pqEJQtlKWvnv3B6VRt60ZmsHy3SotlEBvfUBPB1KVcM= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.8/go.mod h1:f6vjfZER1M17Fokn0IzssOTMT2N8ZSq+7jnNF0tArvw= +github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= +github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=