Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions applications/handler/handler.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package handler

import (
"strconv"
"strings"

"github.com/zopdev/zop-api/applications/service"
Expand Down Expand Up @@ -49,6 +50,23 @@ func (h *Handler) ListApplications(ctx *gofr.Context) (interface{}, error) {
return applications, nil
}

func (h *Handler) GetApplication(ctx *gofr.Context) (interface{}, error) {
id := ctx.PathParam("id")
id = strings.TrimSpace(id)

applicationID, err := strconv.Atoi(id)
if err != nil {
return nil, http.ErrorInvalidParam{Params: []string{"id"}}
}

res, err := h.service.GetApplication(ctx, applicationID)
if err != nil {
return nil, err
}

return res, nil
}

func validateApplication(application *store.Application) error {
application.Name = strings.TrimSpace(application.Name)

Expand Down
1 change: 1 addition & 0 deletions applications/service/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ import (
type ApplicationService interface {
AddApplication(ctx *gofr.Context, application *store.Application) (*store.Application, error)
FetchAllApplications(ctx *gofr.Context) ([]store.Application, error)
GetApplication(ctx *gofr.Context, id int) (*store.Application, error)
}
15 changes: 15 additions & 0 deletions applications/service/mock_interface.go

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

79 changes: 74 additions & 5 deletions applications/service/service.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
package service

import (
"database/sql"
"encoding/json"
"errors"

"database/sql"
"github.com/zopdev/zop-api/environments/service"

"github.com/zopdev/zop-api/applications/store"
"gofr.dev/pkg/gofr"
"gofr.dev/pkg/gofr/http"
)

type Service struct {
store store.ApplicationStore
store store.ApplicationStore
environmentService service.EnvironmentService
}

func New(str store.ApplicationStore) ApplicationService {
return &Service{store: str}
func New(str store.ApplicationStore, envSvc service.EnvironmentService) ApplicationService {
return &Service{store: str, environmentService: envSvc}
}

func (s *Service) AddApplication(ctx *gofr.Context, application *store.Application) (*store.Application, error) {
Expand All @@ -30,14 +33,80 @@ func (s *Service) AddApplication(ctx *gofr.Context, application *store.Applicati
return nil, http.ErrorEntityAlreadyExist{}
}

environments := application.Environments

application, err = s.store.InsertApplication(ctx, application)
if err != nil {
return nil, err
}

if len(environments) == 0 {
environments = append(environments, store.Environment{
Name: "default",
Level: 1,
})
}

for i := range environments {
environments[i].ApplicationID = application.ID

environment, err := s.store.InsertEnvironment(ctx, &environments[i])
if err != nil {
return nil, err
}

environments[i] = *environment
}

return application, nil
}

func (s *Service) FetchAllApplications(ctx *gofr.Context) ([]store.Application, error) {
return s.store.GetALLApplications(ctx)
applications, err := s.store.GetALLApplications(ctx)
if err != nil {
return nil, err
}

for i := range applications {
environments, err := s.environmentService.FetchAll(ctx, int(applications[i].ID))
if err != nil {
return nil, err
}

bytes, err := json.Marshal(environments)
if err != nil {
return nil, err
}

err = json.Unmarshal(bytes, &applications[i].Environments)
if err != nil {
return nil, err
}
}

return applications, nil
}

func (s *Service) GetApplication(ctx *gofr.Context, id int) (*store.Application, error) {
application, err := s.store.GetApplicationByID(ctx, id)
if err != nil {
return nil, err
}

environments, err := s.environmentService.FetchAll(ctx, id)
if err != nil {
return nil, err
}

bytes, err := json.Marshal(environments)
if err != nil {
return nil, err
}

err = json.Unmarshal(bytes, &application.Environments)
if err != nil {
return nil, err
}

return application, nil
}
125 changes: 121 additions & 4 deletions applications/service/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import (
"go.uber.org/mock/gomock"
"gofr.dev/pkg/gofr"

envStore "github.com/zopdev/zop-api/environments/store"

"github.com/zopdev/zop-api/applications/store"
"github.com/zopdev/zop-api/environments/service"
"gofr.dev/pkg/gofr/http"
)

Expand All @@ -23,6 +26,7 @@ func TestService_AddApplication(t *testing.T) {
defer ctrl.Finish()

mockStore := store.NewMockApplicationStore(ctrl)
mockEvironmentService := service.NewMockEnvironmentService(ctrl)
ctx := &gofr.Context{}

application := &store.Application{
Expand All @@ -44,6 +48,9 @@ func TestService_AddApplication(t *testing.T) {
mockStore.EXPECT().
InsertApplication(ctx, application).
Return(application, nil)
mockStore.EXPECT().
InsertEnvironment(ctx, gomock.Any()).
Return(&store.Environment{ID: 1}, nil).Times(1)
},
input: application,
expectedError: nil,
Expand Down Expand Up @@ -81,14 +88,30 @@ func TestService_AddApplication(t *testing.T) {
input: application,
expectedError: errTest,
},
{
name: "error inserting environment",
mockBehavior: func() {
mockStore.EXPECT().
GetApplicationByName(ctx, "Test Application").
Return(nil, sql.ErrNoRows)
mockStore.EXPECT().
InsertApplication(ctx, application).
Return(application, nil)
mockStore.EXPECT().
InsertEnvironment(ctx, gomock.Any()).
Return(nil, errTest).Times(1)
},
input: application,
expectedError: errTest,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tc.mockBehavior()

service := New(mockStore)
_, err := service.AddApplication(ctx, tc.input)
appService := New(mockStore, mockEvironmentService)
_, err := appService.AddApplication(ctx, tc.input)

if tc.expectedError != nil {
require.Error(t, err)
Expand All @@ -105,6 +128,8 @@ func TestService_FetchAllApplications(t *testing.T) {
defer ctrl.Finish()

mockStore := store.NewMockApplicationStore(ctrl)
mockEvironmentService := service.NewMockEnvironmentService(ctrl)

ctx := &gofr.Context{}

expectedApplications := []store.Application{
Expand All @@ -126,6 +151,9 @@ func TestService_FetchAllApplications(t *testing.T) {
mockStore.EXPECT().
GetALLApplications(ctx).
Return(expectedApplications, nil)
mockEvironmentService.EXPECT().
FetchAll(ctx, 1).
Return([]envStore.Environment{{ID: 1, Name: "default", Level: 1}}, nil)
},
expectedError: nil,
},
Expand All @@ -138,14 +166,26 @@ func TestService_FetchAllApplications(t *testing.T) {
},
expectedError: errTest,
},
{
name: "error fetching environments for application",
mockBehavior: func() {
mockStore.EXPECT().
GetALLApplications(ctx).
Return(expectedApplications, nil)
mockEvironmentService.EXPECT().
FetchAll(ctx, 1).
Return(nil, errTest)
},
expectedError: errTest,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tc.mockBehavior()

service := New(mockStore)
applications, err := service.FetchAllApplications(ctx)
appService := New(mockStore, mockEvironmentService)
applications, err := appService.FetchAllApplications(ctx)

if tc.expectedError != nil {
require.Error(t, err)
Expand All @@ -157,3 +197,80 @@ func TestService_FetchAllApplications(t *testing.T) {
})
}
}

func TestService_GetApplication(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockStore := store.NewMockApplicationStore(ctrl)
mockEvironmentService := service.NewMockEnvironmentService(ctrl)

ctx := &gofr.Context{}

expectedApplication := store.Application{
ID: 1,
Name: "Test Application",
CreatedAt: "2023-12-11T00:00:00Z",
}

testCases := []struct {
name string
mockBehavior func()
expectedError error
expectedApp *store.Application
}{
{
name: "success",
mockBehavior: func() {
mockStore.EXPECT().
GetApplicationByID(ctx, 1).
Return(&expectedApplication, nil)
mockEvironmentService.EXPECT().
FetchAll(ctx, 1).
Return([]envStore.Environment{{ID: 1, Name: "default", Level: 1}}, nil)
},
expectedError: nil,
expectedApp: &expectedApplication,
},
{
name: "error fetching application by ID",
mockBehavior: func() {
mockStore.EXPECT().
GetApplicationByID(ctx, 1).
Return(nil, errTest)
},
expectedError: errTest,
expectedApp: nil,
},
{
name: "error fetching environments for application",
mockBehavior: func() {
mockStore.EXPECT().
GetApplicationByID(ctx, 1).
Return(&expectedApplication, nil)
mockEvironmentService.EXPECT().
FetchAll(ctx, 1).
Return(nil, errTest)
},
expectedError: errTest,
expectedApp: nil,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tc.mockBehavior()

appService := New(mockStore, mockEvironmentService)
application, err := appService.GetApplication(ctx, 1)

if tc.expectedError != nil {
require.Error(t, err)
require.Equal(t, tc.expectedError, err)
} else {
require.NoError(t, err)
require.Equal(t, tc.expectedApp, application)
}
})
}
}
2 changes: 2 additions & 0 deletions applications/store/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ type ApplicationStore interface {
InsertApplication(ctx *gofr.Context, application *Application) (*Application, error)
GetALLApplications(ctx *gofr.Context) ([]Application, error)
GetApplicationByName(ctx *gofr.Context, name string) (*Application, error)
GetApplicationByID(ctx *gofr.Context, id int) (*Application, error)
InsertEnvironment(ctx *gofr.Context, environment *Environment) (*Environment, error)
}
Loading
Loading