Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Update objectives criteria #94

Merged
merged 4 commits into from
Nov 16, 2023
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
58 changes: 58 additions & 0 deletions __tests__/integration/rubrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,3 +430,61 @@ func TestAddCriteriaToObjective(t *testing.T) {
c.NotEmpty(criteria["uuid"])
c.NotEmpty(criteria["weight"])
}

func TestUpdateCriteria(t *testing.T) {
c := require.New(t)

// Login as a teacher
w, r := PrepareRequest("POST", "/api/v1/session/login", map[string]interface{}{
"email": registeredTeacherEmail,
"password": registeredTeacherPass,
})
router.ServeHTTP(w, r)
firstTeacherCookie := w.Result().Cookies()[0]

// Create a rubric
response, status := CreateRubric(firstTeacherCookie, map[string]interface{}{
"name": "Rubric 1",
})
c.Equal(http.StatusCreated, status)
firstTeacherRubricUUID := response["uuid"].(string)

// Get the criteria UUID
response, status = GetRubricByUUID(firstTeacherCookie, firstTeacherRubricUUID)
c.Equal(http.StatusOK, status)

rubric := response["rubric"].(map[string]interface{})
c.Equal(1, len(rubric["objectives"].([]interface{})))

objective := rubric["objectives"].([]interface{})[0].(map[string]interface{})
c.Equal(1, len(objective["criteria"].([]interface{})))

criteria := objective["criteria"].([]interface{})[0].(map[string]interface{})
criteriaUUID := criteria["uuid"].(string)

// Test cases
newDescription := "New description"
newWeight := 0.125

testCases := []GenericTestCase{
GenericTestCase{
Payload: map[string]interface{}{
"description": "short",
"weight": 0.125,
},
ExpectedStatusCode: http.StatusBadRequest,
},
GenericTestCase{
Payload: map[string]interface{}{
"description": newDescription,
"weight": newWeight,
},
ExpectedStatusCode: http.StatusNoContent,
},
}

for _, testCase := range testCases {
_, status := UpdateCriteria(firstTeacherCookie, criteriaUUID, testCase.Payload)
c.Equal(testCase.ExpectedStatusCode, status)
}
}
8 changes: 8 additions & 0 deletions __tests__/integration/rubrics_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,11 @@ func AddCriteriaToObjective(cookie *http.Cookie, objectiveUUID string, payload m

return ParseJsonResponse(w.Body), w.Code
}

func UpdateCriteria(cookie *http.Cookie, criteriaUUID string, payload map[string]interface{}) (response map[string]interface{}, status int) {
w, r := PrepareRequest("PUT", "/api/v1/rubrics/criteria/"+criteriaUUID, payload)
r.AddCookie(cookie)
router.ServeHTTP(w, r)

return ParseJsonResponse(w.Body), w.Code
}
2 changes: 1 addition & 1 deletion docs/bruno/rubrics/add-criteria-to-rubric-objective.bru
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: add-criteria-to-rubric-objective
type: http
seq: 6
seq: 1
}

post {
Expand Down
2 changes: 1 addition & 1 deletion docs/bruno/rubrics/add-objective-to-rubric.bru
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: add-objective-to-rubric
type: http
seq: 7
seq: 3
}

post {
Expand Down
2 changes: 1 addition & 1 deletion docs/bruno/rubrics/create-rubric.bru
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: create-rubric
type: http
seq: 10
seq: 7
}

post {
Expand Down
2 changes: 1 addition & 1 deletion docs/bruno/rubrics/get-rubric-by-uuid.bru
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: get-rubric-by-uuid
type: http
seq: 8
seq: 5
}

get {
Expand Down
2 changes: 1 addition & 1 deletion docs/bruno/rubrics/get-rubrics-created-by-teacher.bru
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: get-rubrics-created-by-teacher
type: http
seq: 9
seq: 6
}

get {
Expand Down
18 changes: 18 additions & 0 deletions docs/bruno/rubrics/update-criteria.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
meta {
name: update-criteria
type: http
seq: 2
}

put {
url: {{BASE_URL}}/rubrics/criteria/d986f035-4d1b-4498-8ab3-1b9c923dbf9d
body: json
auth: none
}

body:json {
{
"description": "Sin evidencia",
"weight": 0
}
}
2 changes: 1 addition & 1 deletion docs/bruno/rubrics/update-objective.bru
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: update-objective
type: http
seq: 6
seq: 4
}

put {
Expand Down
49 changes: 39 additions & 10 deletions docs/insomnia/collection.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"_type": "export",
"__export_format": 4,
"__export_date": "2023-11-16T00:00:17.420Z",
"__export_source": "insomnia.desktop.app:v8.4.1",
"__export_date": "2023-11-16T12:35:55.652Z",
"__export_source": "insomnia.desktop.app:v8.4.2",
"resources": [
{
"_id": "req_c2f0c73479b541a49dbada7341b1c575",
"parentId": "fld_471e0003712e4ff0a2978078fa774ef7",
"modified": 1699472729783,
"modified": 1700137908954,
"created": 1699472694976,
"url": "{{BASE_URL}}/accounts/admins",
"name": "register-admin",
Expand Down Expand Up @@ -660,7 +660,7 @@
{
"_id": "req_00f7ec30e93c4a3bb7ec90e2b80407b6",
"parentId": "fld_4915fda7f3a64b3ba16e401d430745a1",
"modified": 1700090526394,
"modified": 1700092857989,
"created": 1700090427249,
"url": "{{ _.BASE_URL }}/rubrics/objectives/1fc6b653-6977-4025-981e-6c937a10a251",
"name": "update-objective",
Expand Down Expand Up @@ -689,15 +689,15 @@
{
"_id": "req_dc979436daa84e19bfc983515f7f0f9b",
"parentId": "fld_4915fda7f3a64b3ba16e401d430745a1",
"modified": 1700060008053,
"modified": 1700137892992,
"created": 1699473189242,
"url": "{{ _.BASE_URL }}/rubrics/objectives/e81fecb0-620c-4af5-80d9-5e9a6af88b68/criteria",
"name": "add-criteria-to-objective",
"description": "",
"method": "POST",
"body": {
"mimeType": "application/json",
"text": "{\n\t\"description\": \"It does not present a list of functional requirements\",\n\t\"weight\": -1\n}"
"text": "{\n\t\"description\": \"It does not present a list of functional requirements\",\n\t\"weight\": 0\n}"
},
"parameters": [],
"headers": [
Expand All @@ -715,6 +715,35 @@
"settingFollowRedirects": "global",
"_type": "request"
},
{
"_id": "req_73cce43293304b7cb3b760903512af7a",
"parentId": "fld_4915fda7f3a64b3ba16e401d430745a1",
"modified": 1700137970119,
"created": 1700137853193,
"url": "{{ _.BASE_URL }}/rubrics/criteria/d986f035-4d1b-4498-8ab3-1b9c923dbf9d",
"name": "update-criteria",
"description": "",
"method": "PUT",
"body": {
"mimeType": "application/json",
"text": "{\n\t\"description\": \"Sin evidencia\",\n\t\"weight\": 0\n}"
},
"parameters": [],
"headers": [
{ "name": "Content-Type", "value": "application/json" },
{ "name": "User-Agent", "value": "insomnia/8.4.2" }
],
"authentication": {},
"metaSortKey": -1699473189142,
"isPrivate": false,
"settingStoreCookies": true,
"settingSendCookies": true,
"settingDisableRenderRequestBody": false,
"settingEncodeUrl": true,
"settingRebuildPath": true,
"settingFollowRedirects": "global",
"_type": "request"
},
{
"_id": "env_c0a0aa13c1388a57edad6b5876667ffb89c3f19d",
"parentId": "wrk_d434a8527f444bf9a18c549e59efeee5",
Expand All @@ -731,21 +760,21 @@
{
"_id": "jar_c0a0aa13c1388a57edad6b5876667ffb89c3f19d",
"parentId": "wrk_d434a8527f444bf9a18c549e59efeee5",
"modified": 1700090481591,
"modified": 1700137934108,
"created": 1699472219279,
"name": "Default Jar",
"cookies": [
{
"key": "session",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1dWlkIjoiMmI3OTAxOTUtNzkxZC00ODFiLTk0NjMtZjg3ZTIxNjYzZDk2Iiwicm9sZSI6InRlYWNoZXIiLCJpc3MiOiJjb2RlbGFicyIsImV4cCI6MTcwMDExMjA4MSwibmJmIjoxNzAwMDkwNDgxLCJpYXQiOjE3MDAwOTA0ODF9.2Zo3CV7Qf1H7q9fbeqrhyrqTYn-UGiJnelDsAvMm92A",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1dWlkIjoiMmI3OTAxOTUtNzkxZC00ODFiLTk0NjMtZjg3ZTIxNjYzZDk2Iiwicm9sZSI6InRlYWNoZXIiLCJpc3MiOiJjb2RlbGFicyIsImV4cCI6MTcwMDE1OTUzNCwibmJmIjoxNzAwMTM3OTM0LCJpYXQiOjE3MDAxMzc5MzR9.49rizwDc8xUg5k6-auur9tdCvokp-8FWSEW3l2aRqxc",
"maxAge": 21600,
"domain": "localhost",
"path": "/",
"httpOnly": true,
"hostOnly": true,
"creation": "2023-11-08T19:42:29.254Z",
"lastAccessed": "2023-11-15T23:21:21.590Z",
"id": "91936dac-fbdd-49bc-96e2-50326472280f"
"lastAccessed": "2023-11-16T12:32:14.108Z",
"id": "ac7429d7-8082-4484-a6b1-6b2bcb838153"
}
],
"_type": "cookie_jar"
Expand Down
19 changes: 19 additions & 0 deletions src/rubrics/application/use_cases.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,22 @@ func (useCases *RubricsUseCases) AddCriteriaToObjective(dto *dtos.AddCriteriaToO

return criteriaUUID, nil
}

func (useCases *RubricsUseCases) UpdateCriteria(dto *dtos.UpdateCriteriaDTO) (err error) {
// Check if the criteria belongs to a rubric that belongs to the teacher
teacherOwnsCriteria, err := useCases.RubricsRepository.DoesTeacherOwnCriteria(dto.TeacherUUID, dto.CriteriaUUID)
if err != nil {
return err
}
if !teacherOwnsCriteria {
return &errors.TeacherDoesNotOwnsRubric{}
}

// Update the criteria
err = useCases.RubricsRepository.UpdateCriteria(dto)
if err != nil {
return err
}

return nil
}
2 changes: 2 additions & 0 deletions src/rubrics/domain/definitions/rubrics_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ type RubricsRepository interface {

AddObjectiveToRubric(rubricUUID string, objectiveDescription string) (objectiveUUID string, err error)
UpdateObjective(dto *dtos.UpdateObjectiveDTO) (err error)

AddCriteriaToObjective(dto *dtos.AddCriteriaToObjectiveDTO) (criteriaUUID string, err error)
UpdateCriteria(dto *dtos.UpdateCriteriaDTO) (err error)
}
8 changes: 8 additions & 0 deletions src/rubrics/domain/dtos/update_criteria_dto.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package dtos

type UpdateCriteriaDTO struct {
TeacherUUID string
CriteriaUUID string
CriteriaDescription string
CriteriaWeight float64
}
48 changes: 48 additions & 0 deletions src/rubrics/infrastructure/http/http_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,51 @@ func (controller *RubricsController) HandleUpdateObjective(c *gin.Context) {

c.Status(http.StatusNoContent)
}

func (controller *RubricsController) HandleUpdateCriteria(c *gin.Context) {
teacher_uuid := c.GetString("session_uuid")

// Validate criteria UUID
criteria_uuid := c.Param("criteriaUUID")
if err := shared_infrastructure.GetValidator().Var(criteria_uuid, "uuid4"); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"message": "Invalid criteria uuid",
})
return
}

// Parse request body
var request requests.UpdateCriteriaRequest
if err := c.ShouldBindJSON(&request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"message": "Invalid request body",
})
return
}

// Validate request body
if err := shared_infrastructure.GetValidator().Struct(request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"message": "Validation error",
"errors": err.Error(),
})
return
}

// Create DTO
dto := dtos.UpdateCriteriaDTO{
TeacherUUID: teacher_uuid,
CriteriaUUID: criteria_uuid,
CriteriaDescription: request.Description,
CriteriaWeight: request.Weight,
}

// Update the criteria
err := controller.UseCases.UpdateCriteria(&dto)
if err != nil {
c.Error(err)
return
}

c.Status(http.StatusNoContent)
}
7 changes: 7 additions & 0 deletions src/rubrics/infrastructure/http/http_routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,11 @@ func StartRubricsRoutes(g *gin.RouterGroup) {
shared_infrastructure.WithAuthorizationMiddleware([]string{"teacher"}),
controller.HandleUpdateObjective,
)

rubricsGroup.PUT(
"/criteria/:criteriaUUID",
shared_infrastructure.WithAuthenticationMiddleware(),
shared_infrastructure.WithAuthorizationMiddleware([]string{"teacher"}),
controller.HandleUpdateCriteria,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,22 @@ func (repository *RubricsPostgresRepository) AddCriteriaToObjective(dto *dtos.Ad

return criteriaUUID, nil
}

func (repository *RubricsPostgresRepository) UpdateCriteria(dto *dtos.UpdateCriteriaDTO) (err error) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()

// Update the criteria
query := `
UPDATE criteria
SET description = $1, weight = $2
WHERE id = $3
`

_, err = repository.Connection.ExecContext(ctx, query, dto.CriteriaDescription, dto.CriteriaWeight, dto.CriteriaUUID)
if err != nil {
return err
}

return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package requests

type UpdateCriteriaRequest struct {
Description string `json:"description" validate:"required,min=8,max=510"`
Weight float64 `json:"weight" default:"0" validate:"numeric,min=0,max=100"`
}