Skip to content

Commit

Permalink
Refactored account controller handler to support environment (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
petruki authored Sep 14, 2024
1 parent 90857fd commit 0133ccf
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 54 deletions.
21 changes: 11 additions & 10 deletions src/controller/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,10 @@ func NewAccountController(repo repository.AccountRepository, coreHandler *core.C
}

func (controller *AccountController) RegisterRoutes(r *mux.Router) http.Handler {
const routesDomainVar = "/{domainId}"

r.NewRoute().Path(controller.RouteAccountPath + routesDomainVar).Name("GetAccount").HandlerFunc(controller.FetchAccountHandler).Methods(http.MethodGet)
r.NewRoute().Path(controller.RouteAccountPath).Name("CreateAccount").HandlerFunc(controller.CreateAccountHandler).Methods(http.MethodPost)
r.NewRoute().Path(controller.RouteAccountPath + routesDomainVar).Name("UpdateAccount").HandlerFunc(controller.UpdateAccountHandler).Methods(http.MethodPut)
r.NewRoute().Path(controller.RouteAccountPath + routesDomainVar).Name("DeleteAccount").HandlerFunc(controller.DeleteAccountHandler).Methods(http.MethodDelete)
r.NewRoute().Path(controller.RouteAccountPath).Name("UpdateAccount").HandlerFunc(controller.UpdateAccountHandler).Methods(http.MethodPut)
r.NewRoute().Path(controller.RouteAccountPath + "/{domainId}/{enviroment}").Name("GetAccount").HandlerFunc(controller.FetchAccountHandler).Methods(http.MethodGet)
r.NewRoute().Path(controller.RouteAccountPath + "/{domainId}/{enviroment}").Name("DeleteAccount").HandlerFunc(controller.DeleteAccountHandler).Methods(http.MethodDelete)

return r
}
Expand All @@ -51,7 +49,6 @@ func (controller *AccountController) CreateAccountHandler(w http.ResponseWriter,

// Encrypt token before saving
if accountRequest.Token != "" {
println("Encrypting token", accountRequest.Token)
accountRequest.Token = utils.Encrypt(accountRequest.Token, config.GetEnv("GIT_TOKEN_PRIVATE_KEY"))
}

Expand All @@ -70,8 +67,10 @@ func (controller *AccountController) CreateAccountHandler(w http.ResponseWriter,
}

func (controller *AccountController) FetchAccountHandler(w http.ResponseWriter, r *http.Request) {
domainId := r.URL.Path[len(controller.RouteAccountPath+"/"):]
account, err := controller.AccountRepository.FetchByDomainId(domainId)
domainId := mux.Vars(r)["domainId"]
enviroment := mux.Vars(r)["enviroment"]

account, err := controller.AccountRepository.FetchByDomainIdEnvironment(domainId, enviroment)
if err != nil {
utils.Log(utils.LogLevelError, "Error fetching account: %s", err.Error())
utils.ResponseJSON(w, ErrorResponse{Error: "Account not found"}, http.StatusNotFound)
Expand Down Expand Up @@ -106,8 +105,10 @@ func (controller *AccountController) UpdateAccountHandler(w http.ResponseWriter,
}

func (controller *AccountController) DeleteAccountHandler(w http.ResponseWriter, r *http.Request) {
domainId := r.URL.Path[len(controller.RouteAccountPath+"/"):]
err := controller.AccountRepository.DeleteByDomainId(domainId)
domainId := mux.Vars(r)["domainId"]
enviroment := mux.Vars(r)["enviroment"]

err := controller.AccountRepository.DeleteByDomainIdEnvironment(domainId, enviroment)
if err != nil {
utils.Log(utils.LogLevelError, "Error deleting account: %s", err.Error())
utils.ResponseJSON(w, ErrorResponse{Error: "Error deleting account: " + err.Error()}, http.StatusInternalServerError)
Expand Down
26 changes: 12 additions & 14 deletions src/controller/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import (
"github.com/switcherapi/switcher-gitops/src/utils"
)

const NOT_FOUND = "/not-found"

func TestCreateAccountHandler(t *testing.T) {
t.Run("Should create an account", func(t *testing.T) {
// Test
Expand Down Expand Up @@ -63,14 +61,14 @@ func TestCreateAccountHandler(t *testing.T) {
}

func TestFetchAccountHandler(t *testing.T) {
t.Run("Should fetch an account by domain ID", func(t *testing.T) {
t.Run("Should fetch an account by domain ID / environment", func(t *testing.T) {
// Create an account
accountV1.Domain.ID = "123-controller-fetch-account"
accountController.CreateAccountHandler(givenAccountRequest(accountV1))

// Test
payload := []byte("")
req, _ := http.NewRequest(http.MethodGet, accountController.RouteAccountPath+"/"+accountV1.Domain.ID, bytes.NewBuffer(payload))
req, _ := http.NewRequest(http.MethodGet, accountController.RouteAccountPath+"/"+accountV1.Domain.ID+"/"+accountV1.Environment, bytes.NewBuffer(payload))
response := executeRequest(req)

// Assert
Expand All @@ -82,10 +80,10 @@ func TestFetchAccountHandler(t *testing.T) {
assert.Equal(t, accountV1.Repository, accountResponse.Repository)
})

t.Run("Should not fetch an account by domain ID - not found", func(t *testing.T) {
t.Run("Should not fetch an account by domain ID / environment - not found", func(t *testing.T) {
// Test
payload := []byte("")
req, _ := http.NewRequest(http.MethodGet, accountController.RouteAccountPath+NOT_FOUND, bytes.NewBuffer(payload))
req, _ := http.NewRequest(http.MethodGet, accountController.RouteAccountPath+"/not-found/default", bytes.NewBuffer(payload))
response := executeRequest(req)

// Assert
Expand All @@ -104,7 +102,7 @@ func TestUpdateAccountHandler(t *testing.T) {
accountV2.Domain.ID = accountV1.Domain.ID
accountV2.Domain.Message = "Updated successfully"
payload, _ := json.Marshal(accountV2)
req, _ := http.NewRequest(http.MethodPut, accountController.RouteAccountPath+"/"+accountV2.Domain.ID, bytes.NewBuffer(payload))
req, _ := http.NewRequest(http.MethodPut, accountController.RouteAccountPath, bytes.NewBuffer(payload))
response := executeRequest(req)

// Assert
Expand All @@ -130,7 +128,7 @@ func TestUpdateAccountHandler(t *testing.T) {
accountRequest.Token = "new-token"

payload, _ := json.Marshal(accountRequest)
req, _ := http.NewRequest(http.MethodPut, accountController.RouteAccountPath+"/"+accountV1.Domain.ID, bytes.NewBuffer(payload))
req, _ := http.NewRequest(http.MethodPut, accountController.RouteAccountPath, bytes.NewBuffer(payload))
response := executeRequest(req)

// Assert
Expand All @@ -151,7 +149,7 @@ func TestUpdateAccountHandler(t *testing.T) {
t.Run("Should not update an account - invalid request", func(t *testing.T) {
// Test
payload := []byte("")
req, _ := http.NewRequest(http.MethodPut, accountController.RouteAccountPath+"/invalid-request", bytes.NewBuffer(payload))
req, _ := http.NewRequest(http.MethodPut, accountController.RouteAccountPath, bytes.NewBuffer(payload))
response := executeRequest(req)

// Assert
Expand All @@ -169,7 +167,7 @@ func TestUpdateAccountHandler(t *testing.T) {

// Test
payload, _ := json.Marshal(accountV1)
req, _ := http.NewRequest(http.MethodPut, accountController.RouteAccountPath+NOT_FOUND, bytes.NewBuffer(payload))
req, _ := http.NewRequest(http.MethodPut, accountController.RouteAccountPath, bytes.NewBuffer(payload))
response := executeRequest(req)

// Assert
Expand All @@ -179,22 +177,22 @@ func TestUpdateAccountHandler(t *testing.T) {
}

func TestDeleteAccountHandler(t *testing.T) {
t.Run("Should delete an account", func(t *testing.T) {
t.Run("Should delete an account by domain ID / environment", func(t *testing.T) {
// Create an account
accountV1.Domain.ID = "123-controller-delete-account"
accountController.CreateAccountHandler(givenAccountRequest(accountV1))

// Test
req, _ := http.NewRequest(http.MethodDelete, accountController.RouteAccountPath+"/"+accountV1.Domain.ID, nil)
req, _ := http.NewRequest(http.MethodDelete, accountController.RouteAccountPath+"/"+accountV1.Domain.ID+"/"+accountV1.Environment, nil)
response := executeRequest(req)

// Assert
assert.Equal(t, http.StatusNoContent, response.Code)
})

t.Run("Should not delete an account - not found", func(t *testing.T) {
t.Run("Should not delete an account by domain ID / environment - not found", func(t *testing.T) {
// Test
req, _ := http.NewRequest(http.MethodDelete, accountController.RouteAccountPath+NOT_FOUND, nil)
req, _ := http.NewRequest(http.MethodDelete, accountController.RouteAccountPath+"/not-found/default", nil)
response := executeRequest(req)

// Assert
Expand Down
5 changes: 3 additions & 2 deletions src/controller/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,9 @@ var accountV1 = model.Account{
}

var accountV2 = model.Account{
Repository: "switcherapi/switcher-gitops",
Branch: "main",
Repository: "switcherapi/switcher-gitops",
Branch: "main",
Environment: "default",
Domain: model.DomainDetails{
ID: "123-controller-test",
Name: "Switcher GitOps",
Expand Down
26 changes: 13 additions & 13 deletions src/core/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestInitCoreHandlerCoroutine(t *testing.T) {
status, err := coreHandler.InitCoreHandlerCoroutine()

// Terminate the goroutine
coreHandler.AccountRepository.DeleteByDomainId(accountCreated.Domain.ID)
coreHandler.AccountRepository.DeleteByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
time.Sleep(1 * time.Second)

// Assert
Expand All @@ -50,7 +50,7 @@ func TestInitCoreHandlerCoroutine(t *testing.T) {
status, _ := coreHandler.InitCoreHandlerCoroutine()

// Terminate the goroutine
coreHandler.AccountRepository.DeleteByDomainId(accountCreated.Domain.ID)
coreHandler.AccountRepository.DeleteByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
time.Sleep(1 * time.Second)

// Assert
Expand All @@ -76,7 +76,7 @@ func TestStartAccountHandler(t *testing.T) {
time.Sleep(1 * time.Second)

// Assert
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainId(accountCreated.Domain.ID)
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
assert.Equal(t, model.StatusPending, accountFromDb.Domain.Status)
assert.Equal(t, "Account was deactivated", accountFromDb.Domain.Message)
assert.Equal(t, "", accountFromDb.Domain.LastCommit)
Expand All @@ -99,7 +99,7 @@ func TestStartAccountHandler(t *testing.T) {
time.Sleep(1 * time.Second)

// Assert
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainId(accountCreated.Domain.ID)
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
assert.Equal(t, model.StatusError, accountFromDb.Domain.Status)
assert.Contains(t, accountFromDb.Domain.Message, "Failed to fetch repository data")
assert.Equal(t, "", accountFromDb.Domain.LastCommit)
Expand All @@ -125,7 +125,7 @@ func TestStartAccountHandler(t *testing.T) {
time.Sleep(1 * time.Second)

// Assert
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainId(accountCreated.Domain.ID)
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
assert.Equal(t, model.StatusError, accountFromDb.Domain.Status)
assert.Contains(t, accountFromDb.Domain.Message, "Failed to fetch snapshot version")
assert.Equal(t, "", accountFromDb.Domain.LastCommit)
Expand All @@ -146,12 +146,12 @@ func TestStartAccountHandler(t *testing.T) {
numGoroutinesBefore := runtime.NumGoroutine()

// Terminate the goroutine
coreHandler.AccountRepository.DeleteByDomainId(accountCreated.Domain.ID)
coreHandler.AccountRepository.DeleteByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
time.Sleep(1 * time.Second)
numGoroutinesAfter := runtime.NumGoroutine()

// Assert
_, err := coreHandler.AccountRepository.FetchByDomainId(accountCreated.Domain.ID)
_, err := coreHandler.AccountRepository.FetchByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
assert.LessOrEqual(t, numGoroutinesAfter, numGoroutinesBefore)
assert.NotNil(t, err)

Expand All @@ -175,7 +175,7 @@ func TestStartAccountHandler(t *testing.T) {
time.Sleep(1 * time.Second)

// Assert
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainId(accountCreated.Domain.ID)
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
assert.Equal(t, model.StatusSynced, accountFromDb.Domain.Status)
assert.Contains(t, accountFromDb.Domain.Message, model.MessageSynced)
assert.Equal(t, "123", accountFromDb.Domain.LastCommit)
Expand Down Expand Up @@ -221,7 +221,7 @@ func TestStartAccountHandler(t *testing.T) {
time.Sleep(1 * time.Second)

// Assert
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainId(accountCreated.Domain.ID)
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
assert.Equal(t, model.StatusSynced, accountFromDb.Domain.Status)
assert.Contains(t, accountFromDb.Domain.Message, model.MessageSynced)
assert.Equal(t, "123", accountFromDb.Domain.LastCommit)
Expand Down Expand Up @@ -255,7 +255,7 @@ func TestStartAccountHandler(t *testing.T) {
time.Sleep(1 * time.Second)

// Assert
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainId(accountCreated.Domain.ID)
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
assert.Equal(t, model.StatusSynced, accountFromDb.Domain.Status)
assert.Contains(t, accountFromDb.Domain.Message, model.MessageSynced)
assert.Equal(t, "123", accountFromDb.Domain.LastCommit)
Expand Down Expand Up @@ -289,7 +289,7 @@ func TestStartAccountHandler(t *testing.T) {
time.Sleep(1 * time.Second)

// Assert
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainId(accountCreated.Domain.ID)
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
assert.Equal(t, model.StatusSynced, accountFromDb.Domain.Status)
assert.Contains(t, accountFromDb.Domain.Message, model.MessageSynced)
assert.Equal(t, "123", accountFromDb.Domain.LastCommit)
Expand Down Expand Up @@ -347,7 +347,7 @@ func TestStartAccountHandler(t *testing.T) {
time.Sleep(1 * time.Second)

// Assert
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainId(accountCreated.Domain.ID)
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
assert.Equal(t, model.StatusError, accountFromDb.Domain.Status)
assert.Contains(t, accountFromDb.Domain.Message, "Failed to check for changes")
assert.Equal(t, "", accountFromDb.Domain.LastCommit)
Expand Down Expand Up @@ -375,7 +375,7 @@ func TestStartAccountHandler(t *testing.T) {
time.Sleep(1 * time.Second)

// Assert
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainId(accountCreated.Domain.ID)
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
assert.Equal(t, model.StatusError, accountFromDb.Domain.Status)
assert.Contains(t, accountFromDb.Domain.Message, "authorization failed")
assert.Contains(t, accountFromDb.Domain.Message, "Failed to apply changes [Repository]")
Expand Down
12 changes: 6 additions & 6 deletions src/repository/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import (
type AccountRepository interface {
Create(account *model.Account) (*model.Account, error)
FetchByAccountId(accountId string) (*model.Account, error)
FetchByDomainId(domainId string) (*model.Account, error)
FetchByDomainIdEnvironment(domainId string, environment string) (*model.Account, error)
FetchAllActiveAccounts() ([]model.Account, error)
Update(account *model.Account) (*model.Account, error)
DeleteByAccountId(accountId string) error
DeleteByDomainId(domainId string) error
DeleteByDomainIdEnvironment(domainId string, environment string) error
}

type AccountRepositoryMongo struct {
Expand Down Expand Up @@ -64,7 +64,7 @@ func (repo *AccountRepositoryMongo) FetchByAccountId(accountId string) (*model.A
return &account, nil
}

func (repo *AccountRepositoryMongo) FetchByDomainId(domainId string) (*model.Account, error) {
func (repo *AccountRepositoryMongo) FetchByDomainIdEnvironment(domainId string, environment string) (*model.Account, error) {
collection, ctx, cancel := getDbContext(repo)
defer cancel()

Expand Down Expand Up @@ -101,7 +101,7 @@ func (repo *AccountRepositoryMongo) Update(account *model.Account) (*model.Accou
collection, ctx, cancel := getDbContext(repo)
defer cancel()

filter := primitive.M{domainIdFilter: account.Domain.ID}
filter := primitive.M{domainIdFilter: account.Domain.ID, environmentFilter: account.Environment}
update := getUpdateFields(account)

var updatedAccount model.Account
Expand Down Expand Up @@ -131,11 +131,11 @@ func (repo *AccountRepositoryMongo) DeleteByAccountId(accountId string) error {
return err
}

func (repo *AccountRepositoryMongo) DeleteByDomainId(domainId string) error {
func (repo *AccountRepositoryMongo) DeleteByDomainIdEnvironment(domainId string, environment string) error {
collection, ctx, cancel := getDbContext(repo)
defer cancel()

filter := primitive.M{domainIdFilter: domainId}
filter := primitive.M{domainIdFilter: domainId, environmentFilter: environment}
result, err := collection.DeleteOne(ctx, filter)

if result.DeletedCount == 0 {
Expand Down
18 changes: 9 additions & 9 deletions src/repository/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestCreateAccount(t *testing.T) {
assert.NotNil(t, createdAccount.ID)
})

t.Run("Should create 2 accounts for each environment", func(t *testing.T) {
t.Run("Should create accounts for each environment", func(t *testing.T) {
// Given
account1 := givenAccount(true)
account2 := givenAccount(true)
Expand Down Expand Up @@ -79,23 +79,23 @@ func TestFetchAccount(t *testing.T) {
assert.NotNil(t, err)
})

t.Run("Should fetch an account by domain ID", func(t *testing.T) {
t.Run("Should fetch an account by domain ID and environment", func(t *testing.T) {
// Given
account := givenAccount(true)
account.Domain.ID = "123-fetch-account-by-domain-id"
accountCreated, _ := accountRepository.Create(&account)

// Test
fetchedAccount, err := accountRepository.FetchByDomainId(accountCreated.Domain.ID)
fetchedAccount, err := accountRepository.FetchByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)

// Assert
assert.Nil(t, err)
assert.NotNil(t, fetchedAccount.ID)
})

t.Run("Should not fetch an account by domain ID - not found", func(t *testing.T) {
t.Run("Should not fetch an account by domain ID and environment - not found", func(t *testing.T) {
// Test
_, err := accountRepository.FetchByDomainId("non_existent_domain_id")
_, err := accountRepository.FetchByDomainIdEnvironment("non_existent_domain_id", "default")

// Assert
assert.NotNil(t, err)
Expand Down Expand Up @@ -175,22 +175,22 @@ func TestDeleteAccount(t *testing.T) {
assert.Equal(t, "Account not found for id: non_existent_id", err.Error())
})

t.Run("Should delete an account by domain ID", func(t *testing.T) {
t.Run("Should delete an account by domain ID and environment", func(t *testing.T) {
// Given
account := givenAccount(true)
account.Domain.ID = "123-delete-account-by-domain-id"
accountCreated, _ := accountRepository.Create(&account)

// Test
err := accountRepository.DeleteByDomainId(accountCreated.Domain.ID)
err := accountRepository.DeleteByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)

// Assert
assert.Nil(t, err)
})

t.Run("Should not delete an account by domain ID - not found", func(t *testing.T) {
t.Run("Should not delete an account by domain ID and environment - not found", func(t *testing.T) {
// Test
err := accountRepository.DeleteByDomainId("non_existent_domain_id")
err := accountRepository.DeleteByDomainIdEnvironment("non_existent_domain_id", "default")

// Assert
assert.NotNil(t, err)
Expand Down

0 comments on commit 0133ccf

Please sign in to comment.