Skip to content

Commit

Permalink
refactor: Use more models to represent data
Browse files Browse the repository at this point in the history
  • Loading branch information
mauricioabreu committed Apr 23, 2024
1 parent 86ecc86 commit eed7295
Show file tree
Hide file tree
Showing 17 changed files with 220 additions and 118 deletions.
94 changes: 53 additions & 41 deletions internal/api/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package api
import (
"net/http"

"github.com/dionysia-dev/dionysia/internal/model"
"github.com/dionysia-dev/dionysia/internal/service"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
Expand Down Expand Up @@ -31,14 +30,12 @@ func NewInputController(inputHandler service.InputHandler) *InputController {
// @Failure 500 {object} api.ErrorResponse "Internal server error"
// @Router /inputs [post]
func (c *InputController) CreateInput(ctx *gin.Context) {
var inputData model.Input
var inputData InputData
if err := ctx.BindJSON(&inputData); err != nil {
statusCode, response := handleValidationError(err)
statusCode, response := HandleValidationError(err)
if statusCode == 0 && response == nil {
ctx.JSON(http.StatusInternalServerError, ErrorResponse{
Error: Error{
Message: "InternalServerError: handle validation failed",
},
Error: Error{Message: "InternalServerError: handle validation failed"},
})

return
Expand All @@ -49,20 +46,50 @@ func (c *InputController) CreateInput(ctx *gin.Context) {
return
}

input, err := c.inputHandler.CreateInput(ctx, &inputData)
audioProfiles := make([]service.AudioProfile, 0, len(inputData.AudioProfiles))
for _, audioProfileData := range inputData.AudioProfiles {
audioProfiles = append(audioProfiles, service.AudioProfile{
Codec: audioProfileData.Codec,
Bitrate: audioProfileData.Bitrate,
})
}

videoProfiles := make([]service.VideoProfile, 0, len(inputData.VideoProfiles))
for _, videoProfileData := range inputData.VideoProfiles {
videoProfiles = append(videoProfiles, service.VideoProfile{
Codec: videoProfileData.Codec,
Bitrate: videoProfileData.Bitrate,
MaxKeyInterval: videoProfileData.MaxKeyInterval,
Framerate: videoProfileData.Framerate,
Width: videoProfileData.Width,
Height: videoProfileData.Height,
})
}

input, err := c.inputHandler.CreateInput(ctx, &service.Input{
Name: inputData.Name,
Format: inputData.Format,
AudioProfiles: audioProfiles,
VideoProfiles: videoProfiles,
})
if err != nil {
ctx.JSON(http.StatusInternalServerError, ErrorResponse{
Error: Error{
Message: "InternalServerError: failed creating input",
},
Error: Error{Message: "InternalServerError: failed creating input"},
})

return
}

responseData := InputData{
ID: input.ID,
Name: input.Name,
Format: input.Format,
AudioProfiles: inputData.AudioProfiles,
VideoProfiles: inputData.VideoProfiles,
}
ctx.JSON(http.StatusCreated, SuccessResponse{
Message: "Input created successfully",
Data: input,
Data: responseData,
})
}

Expand All @@ -78,9 +105,7 @@ func (c *InputController) GetInput(ctx *gin.Context) {
id, err := uuid.Parse(ctx.Param("id"))
if err != nil {
ctx.JSON(http.StatusBadRequest, ErrorResponse{
Error: Error{
Message: "BadRequest: invalid UUID format",
},
Error: Error{Message: "BadRequest: invalid UUID format"},
})

return
Expand All @@ -89,9 +114,7 @@ func (c *InputController) GetInput(ctx *gin.Context) {
input, err := c.inputHandler.GetInput(ctx, id)
if err != nil {
ctx.JSON(http.StatusInternalServerError, ErrorResponse{
Error: Error{
Message: "InternalServerError: failed creating input",
},
Error: Error{Message: "InternalServerError: failed creating input"},
})

return
Expand All @@ -114,19 +137,15 @@ func (c *InputController) DeleteInput(ctx *gin.Context) {
id, err := uuid.Parse(ctx.Param("id"))
if err != nil {
ctx.JSON(http.StatusBadRequest, ErrorResponse{
Error: Error{
Message: "BadRequest: invalid UUID format",
},
Error: Error{Message: "BadRequest: invalid UUID format"},
})

return
}

if err := c.inputHandler.DeleteInput(ctx, id); err != nil {
ctx.JSON(http.StatusInternalServerError, ErrorResponse{
Error: Error{
Message: "InternalServerError: failed deleting input",
},
Error: Error{Message: "InternalServerError: failed deleting input"},
})

return
Expand All @@ -138,14 +157,12 @@ func (c *InputController) DeleteInput(ctx *gin.Context) {
}

func (c *InputController) Authenticate(ctx *gin.Context) {
var authData model.IngestAuthData
var authData IngestAuthData
if err := ctx.BindJSON(&authData); err != nil {
statusCode, response := handleValidationError(err)
statusCode, response := HandleValidationError(err)
if statusCode == 0 && response == nil {
ctx.JSON(http.StatusInternalServerError, ErrorResponse{
Error: Error{
Message: "InternalServerError: failed to authenticate",
},
Error: Error{Message: "InternalServerError: failed to authenticate"},
})

return
Expand All @@ -156,22 +173,21 @@ func (c *InputController) Authenticate(ctx *gin.Context) {
return
}

err := c.inputHandler.Authenticate(ctx, authData)
err := c.inputHandler.Authenticate(ctx, service.IngestAuth{
Path: authData.Path,
Action: authData.Action,
})

switch {
case err == service.ErrFailedAuth:
ctx.JSON(http.StatusBadRequest, ErrorResponse{
Error: Error{
Message: "BadRequest: invalid credentials",
},
Error: Error{Message: "BadRequest: invalid credentials"},
})

return
case err != nil:
ctx.JSON(http.StatusInternalServerError, ErrorResponse{
Error: Error{
Message: "InternalServerError: failed to authenticate",
},
Error: Error{Message: "InternalServerError: failed to authenticate"},
})

return
Expand Down Expand Up @@ -200,19 +216,15 @@ func (n *NotificationController) EnqueuePackaging(ctx *gin.Context) {
id, err := uuid.Parse(ctx.Query("id"))
if err != nil {
ctx.JSON(http.StatusBadRequest, ErrorResponse{
Error: Error{
Message: "Invalid UUID format",
},
Error: Error{Message: "Invalid UUID format"},
})

return
}

if err := n.notificationHandler.PackageStream(ctx, id); err != nil {
ctx.JSON(http.StatusInternalServerError, ErrorResponse{
Error: Error{
Message: "InternalServerError: while creating input",
},
Error: Error{Message: "InternalServerError: while creating input"},
})

return
Expand Down
30 changes: 30 additions & 0 deletions internal/api/request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package api

import "github.com/google/uuid"

type InputData struct {
ID uuid.UUID `json:"id" swaggerignore:"true"`
Name string `json:"name" validate:"required"`
Format string `json:"format" validate:"required"`
AudioProfiles []AudioProfileData `json:"audio_profiles"`
VideoProfiles []VideoProfileData `json:"video_profiles"`
}

type AudioProfileData struct {
Codec string `json:"codec"`
Bitrate int `json:"bitrate"`
}

type VideoProfileData struct {
Codec string `json:"codec"`
Bitrate int `json:"bitrate"`
MaxKeyInterval int `json:"max_key_interval"`
Framerate int `json:"framerate"`
Width int `json:"width"`
Height int `json:"height"`
}

type IngestAuthData struct {
Path uuid.UUID `json:"path" validate:"required"`
Action string `json:"action" validate:"required"`
}
4 changes: 2 additions & 2 deletions internal/api/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ type ErrorResponse struct {

type StatusCode int

// handleValidationError validate and handle errors of structs that has `validator/v10` rules
func handleValidationError(err error) (StatusCode, *ErrorResponse) {
// HandleValidationError validate and handle errors of structs that has `validator/v10` rules
func HandleValidationError(err error) (StatusCode, *ErrorResponse) {
validationErrors, ok := err.(validator.ValidationErrors)
if !ok {
return 0, nil
Expand Down
23 changes: 11 additions & 12 deletions internal/api/response_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package api
package api_test

import (
"net/http"
"testing"

"github.com/dionysia-dev/dionysia/internal/model"
"github.com/dionysia-dev/dionysia/internal/api"
"github.com/go-playground/validator/v10"
"github.com/stretchr/testify/assert"
)
Expand All @@ -15,23 +15,22 @@ var validate *validator.Validate
func TestHandleValidationError(t *testing.T) {
validate = validator.New(validator.WithRequiredStructEnabled())

// Test cases
testCases := []struct {
name string
inputError *model.Input
expectedStatusCode StatusCode
expectedErrorResp *ErrorResponse
inputError *api.InputData
expectedStatusCode api.StatusCode
expectedErrorResp *api.ErrorResponse
}{
{
name: "Test with bad request body",
inputError: &model.Input{
inputError: &api.InputData{
Name: "just a name",
},
expectedStatusCode: http.StatusBadRequest,
expectedErrorResp: &ErrorResponse{
Error: Error{
expectedErrorResp: &api.ErrorResponse{
Error: api.Error{
Message: "Invalid request parameters",
Details: []ErrorDetail{
Details: []api.ErrorDetail{
{
Reason: "Format",
Message: "required",
Expand All @@ -42,7 +41,7 @@ func TestHandleValidationError(t *testing.T) {
},
{
name: "Test with valid request body",
inputError: &model.Input{
inputError: &api.InputData{
Name: "beautiful name",
Format: "nice format",
},
Expand All @@ -54,7 +53,7 @@ func TestHandleValidationError(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
err := validate.Struct(tc.inputError)
actualStatusCode, actualErrorResp := handleValidationError(err)
actualStatusCode, actualErrorResp := api.HandleValidationError(err)

assert.Equal(t, tc.expectedStatusCode, actualStatusCode, "Status code mismatch")
assert.Equal(t, tc.expectedErrorResp, actualErrorResp, "Error response mismatch")
Expand Down
2 changes: 1 addition & 1 deletion internal/db/migrate.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package db

import (
"github.com/dionysia-dev/dionysia/internal/model"
"github.com/dionysia-dev/dionysia/internal/db/model"
"gorm.io/gorm"
)

Expand Down
7 changes: 1 addition & 6 deletions internal/model/input.go → internal/db/model/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ type Input struct {

type AudioProfile struct {
InputID uuid.UUID
Bitrate int `json:"bitrate"`
Codec string `json:"codec"`
Bitrate int `json:"bitrate"`
}

type VideoProfile struct {
Expand All @@ -27,8 +27,3 @@ type VideoProfile struct {
Width int `json:"width"`
Height int `json:"height"`
}

type IngestAuthData struct {
Path uuid.UUID `json:"path" validate:"required"`
Action string `json:"action" validate:"required"`
}
2 changes: 1 addition & 1 deletion internal/db/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"
"errors"

"github.com/dionysia-dev/dionysia/internal/model"
"github.com/dionysia-dev/dionysia/internal/db/model"
"github.com/google/uuid"
"gorm.io/gorm"
)
Expand Down
2 changes: 1 addition & 1 deletion internal/mocks/store.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit eed7295

Please sign in to comment.