diff --git a/go.mod b/go.mod index dc74b5a..10acf90 100644 --- a/go.mod +++ b/go.mod @@ -3,23 +3,13 @@ module github.com/firmino/webhook go 1.21.0 require ( - github.com/gofiber/fiber/v2 v2.49.0 github.com/google/uuid v1.3.1 + github.com/rabbitmq/amqp091-go v1.8.1 github.com/stretchr/testify v1.8.4 ) require ( - github.com/andybalholm/brotli v1.0.5 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/klauspost/compress v1.16.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rivo/uniseg v0.2.0 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.48.0 // indirect - github.com/valyala/tcplisten v1.0.0 // indirect - golang.org/x/sys v0.11.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index d1ade07..a9d1f5e 100644 --- a/go.sum +++ b/go.sum @@ -1,37 +1,28 @@ -github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= -github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/gofiber/fiber/v2 v2.49.0 h1:xBVG2c66GDcWfww56xHvMn52Q0XX7UrSvjj6MD8/5EE= -github.com/gofiber/fiber/v2 v2.49.0/go.mod h1:oxpt7wQaEYgdDmq7nMxCGhilYicBLFnZ+jQSJcQDlSE= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 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/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rabbitmq/amqp091-go v1.8.1 h1:RejT1SBUim5doqcL6s7iN6SBmsQqyTgXb1xMlH0h1hA= +github.com/rabbitmq/amqp091-go v1.8.1/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.48.0 h1:oJWvHb9BIZToTQS3MuQ2R3bJZiNSa2KiNdeI8A+79Tc= -github.com/valyala/fasthttp v1.48.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= -github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= -github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/domain/event.go b/internal/domain/event.go index 44532b3..51f67d1 100644 --- a/internal/domain/event.go +++ b/internal/domain/event.go @@ -5,8 +5,19 @@ import ( "github.com/google/uuid" ) -const ErrorEventNameIsRequired = "Field Name is required" -const ErrorEventDescriptionIsRequired = "Field Description is required" +var ( + ErrorEventNameIsRequired = pkg.WebhookError{ + Reason: "Field Name is required", + StatusCode: 412, + Status: "Precondition Failed", + } + + ErrorEventDescriptionIsRequired = pkg.WebhookError{ + Reason: "Field Description is required", + StatusCode: 412, + Status: "Field Name is required", + } +) type Event struct { Id uuid.UUID `json:"id"` @@ -22,10 +33,10 @@ func NewEvent(name string, description string) (Event, error) { func (e *Event) validate() error { if e.Name == "" { - return pkg.NewCustomError(pkg.PreconditionFailed, ErrorEventNameIsRequired) + return ErrorEventNameIsRequired } if e.Description == "" { - return pkg.NewCustomError(pkg.PreconditionFailed, ErrorEventDescriptionIsRequired) + return ErrorEventDescriptionIsRequired } return nil } diff --git a/internal/domain/event_test.go b/internal/domain/event_test.go index b9713f0..018a70b 100644 --- a/internal/domain/event_test.go +++ b/internal/domain/event_test.go @@ -3,7 +3,6 @@ package domain import ( "testing" - "github.com/firmino/webhook/pkg" "github.com/stretchr/testify/assert" ) @@ -18,13 +17,13 @@ func TestNewEvent(t *testing.T) { name: "Invalid Name", input: Event{Name: "", Description: "Teste"}, expected: Event{Name: "", Description: "Teste"}, - expectedError: pkg.NewCustomError(pkg.PreconditionFailed, ErrorEventNameIsRequired), + expectedError: ErrorEventNameIsRequired, }, { name: "Invalid Description", input: Event{Name: "Teste", Description: ""}, expected: Event{Name: "Teste", Description: ""}, - expectedError: pkg.NewCustomError(pkg.PreconditionFailed, ErrorEventDescriptionIsRequired), + expectedError: ErrorEventDescriptionIsRequired, }, { name: "Valid Event", diff --git a/internal/domain/webhook.go b/internal/domain/webhook.go new file mode 100644 index 0000000..fe45fef --- /dev/null +++ b/internal/domain/webhook.go @@ -0,0 +1,67 @@ +package domain + +import ( + "context" + "net/url" + + "github.com/firmino/webhook/pkg" + "github.com/google/uuid" +) + +type Webhook struct { + Id uuid.UUID + Authorization string + Url string + Description string + IsEnabled bool + TenantId uuid.UUID +} + +var ( + InvalidWebhookUrl = pkg.WebhookError{ + Reason: "Url is not valid", + StatusCode: 412, + Status: "webhook-url", + } + + InvalidAuthorization = pkg.WebhookError{ + Reason: "Authorization is not valid", + StatusCode: 412, + Status: "webhook-authorization", + } +) + +func NewWebhook(url, authorization string, tenantId uuid.UUID) (Webhook, error) { + w := Webhook{ + Id: uuid.New(), + Url: url, + Authorization: authorization, + IsEnabled: true, + TenantId: tenantId, + } + err := w.validate() + return w, err +} + +func (w *Webhook) validate() error { + _, err := url.ParseRequestURI(w.Url) + if err != nil { + return InvalidWebhookUrl + } + if w.Authorization == "" { + return InvalidAuthorization + } + return nil +} + +type WebhookRepository interface { + Insert(ctx context.Context, webhook Webhook) (*Webhook, error) + FindById(ctx context.Context, id uuid.UUID) (*Webhook, error) + FindAll(ctx context.Context, pagination *pkg.Pagination) (*pkg.Pagination, error) +} + +type WebhookUseCase interface { + Save(ctx context.Context, webhook Webhook) (*Webhook, error) + GetById(ctx context.Context, id uuid.UUID) (*Webhook, error) + GetAll(ctx context.Context, pagination *pkg.Pagination) (*pkg.Pagination, error) +} diff --git a/internal/domain/webhook_test.go b/internal/domain/webhook_test.go new file mode 100644 index 0000000..7636686 --- /dev/null +++ b/internal/domain/webhook_test.go @@ -0,0 +1,53 @@ +package domain + +import ( + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/assert" +) + +func TestNewWebhook(t *testing.T) { + id := uuid.New() + tests := []struct { + name string + input Webhook + expected Webhook + expectedError error + }{ + { + name: "Invalid Url", + input: Webhook{Url: "1", Authorization: "", Id: id}, + expected: Webhook{TenantId: id, Url: "1", Authorization: "", IsEnabled: true}, + expectedError: InvalidWebhookUrl, + }, + { + name: "Invalid AuthorizationIsRequired", + input: Webhook{Url: "http://teste.com.br", Authorization: "", Id: id}, + expected: Webhook{TenantId: id, Url: "http://teste.com.br", Authorization: "", IsEnabled: true}, + expectedError: InvalidAuthorization, + }, + { + name: "Invalid webhook registry", + input: Webhook{Url: "", Authorization: "", Id: id}, + expected: Webhook{TenantId: id, Url: "", Authorization: "", IsEnabled: true}, + expectedError: InvalidWebhookUrl, + }, + { + name: "Valid Webhook", + input: Webhook{Url: "http://teste.ccom.br", Authorization: "123"}, + expected: Webhook{Url: "http://teste.ccom.br", Authorization: "123", TenantId: id, IsEnabled: true, Id: id}, + expectedError: nil, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + webhook, err := NewWebhook(test.input.Url, test.input.Authorization, id) + test.expected.Id = webhook.Id + assert.Equal(t, test.expected, webhook) + if test.expectedError != nil { + assert.Equal(t, err, test.expectedError) + } + }) + } +} diff --git a/pkg/errors.go b/pkg/errors.go index 3c52088..304b212 100644 --- a/pkg/errors.go +++ b/pkg/errors.go @@ -1,27 +1,15 @@ package pkg -type GenericError struct { - Code ErrorCode - Message string +type WebhookError struct { + StatusCode int + Status string + Reason string } -type CustomError struct { - GenericError +// Error returns the error message. +func (e WebhookError) Error() string { + if e.Reason != "" { + return e.Reason + } + return "Webhooks Error" } - -func NewCustomError(code ErrorCode, msg string) *CustomError { - return &CustomError{GenericError{ - Code: code, - Message: msg, - }} -} - -func (e *CustomError) Error() string { - return e.Message -} - -type ErrorCode uint8 - -const ( - PreconditionFailed ErrorCode = iota -)