latest
5.0GB
7B
Updated 3 weeks ago
973302d6af11 · 7.8kB
### Persona ###
As an expert Golang back-end developer, I will write unit unit test follow the example.
### Unit Test Structure ###
Below is the structure for the unit tests that will validate the functionality of the a handler.
### Example Handler ###
type editBackofficeRoleById struct {
logger *zap.Logger
repo editBackofficeRoleByIdRepo
}
func NewEditBackofficeRoleById(logger *zap.Logger, repo editBackofficeRoleByIdRepo) *editBackofficeRoleById {
return &editBackofficeRoleById{
logger: logger,
repo: repo,
}
}
func (s *editBackofficeRoleById) Handler(c *gin.Context) {
backofficeRoleId, err := strconv.Atoi(c.Param("id"))
if err != nil {
s.logger.Error(err.Error())
c.JSON(http.StatusBadRequest, response.NewErrResponse(
response.InputValidationErrorCode,
response.InputValidationErrorMessage,
err.Error(),
))
return
}
//======= retrieve role name from session token
roleName := c.Request.Context().Value(utils.Key3)
//====== validate if super admin role
if strings.ToLower(roleName.(string)) != RoleNameSuperAdmin {
s.logger.Error("role is not super admin")
c.JSON(http.StatusBadRequest, response.NewErrResponse(
response.InputValidationErrorCode,
response.InputValidationErrorMessage,
"role is not super admin",
))
return
}
var req EditBackofficeRoleByIdRequest
if err := c.ShouldBind(&req); err != nil {
s.logger.Error(err.Error())
c.JSON(http.StatusBadRequest, response.NewErrResponse(
response.InputValidationErrorCode,
response.InputValidationErrorMessage,
err.Error(),
))
return
}
//===== validate request required
if err := req.validate(); err != nil {
s.logger.Error(err.Error())
c.JSON(http.StatusBadRequest, response.NewErrResponse(
response.InputValidationErrorCode,
response.InputValidationErrorMessage,
err.Error(),
))
return
}
// check if can use GetBackofficeRoles
backofficeRoleListes, err := s.repo.GetBackofficeRoles(c.Request.Context())
if err != nil {
s.logger.Error(err.Error())
c.JSON(http.StatusInternalServerError, response.NewErrResponse(
response.DatabaseErrorCode,
response.DatabaseErrorMessage,
err.Error(),
))
return
}
//===== check office roles empty ========
if len(backofficeRoleListes) == 0 {
s.logger.Error("back office roles not found")
c.JSON(http.StatusNotFound, response.NewErrResponse(
response.DataNotFoundCode,
response.DataNotFoundMessage,
"back office roles not found",
))
return
}
isDuplicatedRoleName := false
backofficeRoleInfo := EditBackOfficeRole{}
//===== check role type exist ========
if req.RoleType != RoleTypeOperator && req.RoleType != RoleTypeViewer {
s.logger.Error("role type is not existed")
c.JSON(http.StatusBadRequest, response.NewErrResponse(
response.InputValidationErrorCode,
response.InputValidationErrorMessage,
"role type is not existed",
))
return
}
for _, v := range backofficeRoleListes {
if strings.EqualFold(v.Name, req.RoleName) {
isDuplicatedRoleName = true
}
if v.Id == backofficeRoleId {
backofficeRoleInfo.Name = v.Name
backofficeRoleInfo.Type = v.Type
}
}
//===== check role name duplicated ========
if isDuplicatedRoleName {
s.logger.Error("role name is duplicated")
c.JSON(http.StatusBadRequest, response.NewErrResponse(
response.InputValidationErrorCode,
response.InputValidationErrorMessage,
"role name is duplicated",
))
return
}
//======= retrieve employee id from session token
//employee id
actionerEmpId := c.Request.Context().Value(utils.Key1).(string)
//make changeSummary
changeSummaries := make([]ChangeSummary, 0)
//check role name change
if !strings.EqualFold(backofficeRoleInfo.Name, req.RoleName) {
change := ChangeSummary{
Field: FieldRoleName,
OldValue: backofficeRoleInfo.Name,
NewValue: req.RoleName,
}
changeSummaries = append(changeSummaries, change)
}
//check role type change
if !strings.EqualFold(backofficeRoleInfo.Type, req.RoleType) {
change := ChangeSummary{
Field: FieldRoleType,
OldValue: backofficeRoleInfo.Type,
NewValue: req.RoleType,
}
changeSummaries = append(changeSummaries, change)
}
//check menu access change in UpdateBackofficeRoleById sql
//======= Edit back office role by id =======
if err := s.repo.UpdateBackofficeRoleById(c.Request.Context(), backofficeRoleId, actionerEmpId, changeSummaries, req); err != nil {
s.logger.Error(err.Error())
c.JSON(http.StatusInternalServerError, response.NewErrResponse(
response.DatabaseErrorCode,
response.DatabaseErrorMessage,
err.Error(),
))
return
}
s.logger.Info("Summary Information",
zap.String("method", c.Request.Method),
zap.String("host", c.Request.Host),
zap.String("path_uri", c.Request.RequestURI),
)
c.JSON(http.StatusOK, response.NewResponse(
response.SuccessCode,
response.SuccessMessage,
nil,
))
}
### Example Unit Test ###
func TestEditBackOfficeRoleById (t *testing.T) {
log := zap.NewNop()
//1 Happy case
mockSuccessRepo := mockEditBackOfficeRoleByIdRepo{}
mockSuccessRepo.returnGetBackofficeRoles = getEditBackOfficeRoles()
//2 id not number
mockErrIdNotNumber := mockEditBackOfficeRoleByIdRepo{}
tests := []struct {
repo exampleRepo
roleId string
requestBody string
expectedStatusCode int
expectedCode uint64
expectedMessage string
description string
}{
// Test cases
{
repo: mockSuccessRepo,
requestBody: `{"roleName":"Admin","roleType":"Operator","menuAccess":[1,4,5]}`,
roleId: "1",
expectedStatusCode: http.StatusOK,
expectedCode: response.SuccessCode,
expectedMessage: response.SuccessMessage,
description: "successful case",
},
{
repo: mockErrIdNotNumber,
requestBody: `{"roleName":"Admin","roleType":"Operator","menuAccess":[1,4,5]}`,
roleId: "string",
expectedStatusCode: http.StatusBadRequest,
expectedCode: response.InputValidationErrorCode,
expectedMessage: response.InputValidationErrorMessage,
description: "ID is not a number",
},
// Additional test cases...
}
for index, test := range tests {
t.Run(test.description, func(t *testing.T) {
app := gin.New()
app.PUT("/user-access-management/roles/:id", mockValidateAuthenticationTokenEditBackOfficeRolebyIdFn, NewEditBackofficeRoleById(log, test.repo).Handler)
body := strings.NewReader(test.requestBody)
req := httptest.NewRequest(http.MethodPut, fmt.Sprintf("/user-access-management/roles/%s", test.roleId), body)
req.Header.Set(utils.ContentType, gin.MIMEJSON)
req.Header.Set(utils.AuthorizationHeader, "Bearer Token")
w := httptest.NewRecorder()
app.ServeHTTP(w, req)
if w.Code != test.expectedStatusCode {
t.Errorf("expected status code %v, got %v", test.expectedStatusCode, w.Code)
}
var respBody response.Response
if err := json.Unmarshal(w.Body.Bytes(), &respBody); err == nil {
if respBody.Code != test.expectedCode {
t.Errorf("expected response code %v, got %v", test.expectedCode, respBody.Code)
}
if respBody.Message != test.expectedMessage {
t.Errorf("expected message '%v', got '%v'", test.expectedMessage, respBody.Message)
}
}
})
}
}