Skip to content

Commit da7f717

Browse files
fix: assessment updates, flakey review test (#2387)
Signed-off-by: Sarah Funkhouser <147884153+golanglemonade@users.noreply.github.com>
1 parent a78f621 commit da7f717

8 files changed

Lines changed: 42 additions & 26 deletions

File tree

internal/ent/hooks/assessment.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@ func HookQuestionnaireAssessment() ent.Hook {
2121

2222
id, ok := m.TemplateID()
2323
if !ok {
24-
// user provided jsonconfig and uischema directly then
25-
// and not trying to be created/cloned from a template
26-
//
27-
// but at least the jsonconfig needs to be provided
28-
_, ok := m.Jsonconfig()
29-
if !ok {
30-
return nil, fmt.Errorf("jsonconfig is required if you do not create an assessment from a template") //nolint:err113
24+
if m.Op().Is(ent.OpCreate) {
25+
// user provided jsonconfig and uischema directly then
26+
// and not trying to be created/cloned from a template
27+
//
28+
// but at least the jsonconfig needs to be provided
29+
_, ok := m.Jsonconfig()
30+
if !ok {
31+
return nil, fmt.Errorf("jsonconfig is required if you do not create an assessment from a template") //nolint:err113
32+
}
3133
}
3234
return next.Mutate(ctx, m)
3335
}

internal/ent/hooks/assessment_response.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,21 +93,20 @@ func findExistingAssessmentResponse(ctx context.Context, client *generated.Clien
9393
// assessment response. For drafts it updates due date only. For non-drafts it increments send
9494
// attempts, resets overdue status, and sends a new email invitation.
9595
func handleExistingAssessmentResponse(ctx context.Context, m *generated.AssessmentResponseMutation, existingResponse *generated.AssessmentResponse, isTest bool) (*generated.AssessmentResponse, error) {
96-
isDraft, _ := m.IsDraft()
97-
98-
if existingResponse.Status != enums.AssessmentResponseStatusDraft &&
99-
existingResponse.Status != enums.AssessmentResponseStatusSent &&
100-
existingResponse.Status != enums.AssessmentResponseStatusOverdue &&
96+
if existingResponse.Status == enums.AssessmentResponseStatusCompleted &&
10197
!isTest {
102-
return nil, ErrAssessmentInProgress
98+
return nil, ErrAssessmentInCompleted
10399
}
104100

105101
update := m.Client().AssessmentResponse.UpdateOneID(existingResponse.ID)
106102

107103
if dueDate, ok := m.DueDate(); ok {
108104
update = update.SetDueDate(dueDate)
105+
// ensure if due date changes status is not marked as overdue
106+
update = update.SetStatus(enums.AssessmentResponseStatusSent)
109107
}
110108

109+
isDraft, _ := m.IsDraft()
111110
if isDraft {
112111
update = update.SetStatus(enums.AssessmentResponseStatusDraft)
113112

@@ -220,12 +219,8 @@ func HookUpdateAssessmentResponse() ent.Hook {
220219

221220
newStatus, statusExists := m.Status()
222221

223-
if statusExists {
224-
switch assessmentResp.Status {
225-
case enums.AssessmentResponseStatusCompleted,
226-
enums.AssessmentResponseStatusOverdue:
227-
return nil, ErrAssessmentInProgress
228-
}
222+
if statusExists && assessmentResp.Status == enums.AssessmentResponseStatusCompleted {
223+
return nil, ErrAssessmentInCompleted
229224
}
230225

231226
isPastDue := !assessmentResp.DueDate.IsZero() && time.Now().After(assessmentResp.DueDate)

internal/ent/hooks/errors.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ var (
3636
ErrMaxAttemptsAssessments = errors.New("too many attempts to resend assessment invitation")
3737
// ErrMaxSubscriptionAttempts is returned when a user has reached the max attempts to subscribe to an org
3838
ErrMaxSubscriptionAttempts = errors.New("too many attempts to resend org subscription email")
39-
// ErrAssessmentInProgress is returned when attempting to resend an email for an assessment that is already in progress
40-
ErrAssessmentInProgress = errors.New("assessment is already in progress or completed")
39+
// ErrAssessmentInCompleted is returned when attempting to resend an email for an assessment that is already completed
40+
ErrAssessmentInCompleted = errors.New("assessment is already completed")
4141
// ErrMissingRecipientEmail is returned when an email is required but not provided
4242
ErrMissingRecipientEmail = errors.New("recipient email is required but not provided")
4343
// ErrMissingRequiredName is returned when a name is required but not provided

internal/ent/hooks/review.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
)
1919

2020
func getNextReviewDate(frequency enums.Frequency, lastReviewedAt models.DateTime) models.DateTime {
21-
lastReviewDate := time.Time(lastReviewedAt)
21+
lastReviewDate := time.Time(lastReviewedAt).UTC()
2222

2323
switch frequency {
2424
case enums.FrequencyYearly:

internal/graphapi/assessment_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,15 @@ func TestMutationUpdateAssessment(t *testing.T) {
302302
client: suite.client.api,
303303
ctx: testUser1.UserCtx,
304304
},
305+
{
306+
name: "happy path, update due date",
307+
id: assessment.ID,
308+
request: testclient.UpdateAssessmentInput{
309+
ResponseDueDuration: lo.ToPtr(int64(86400)), // 1 day,
310+
},
311+
client: suite.client.api,
312+
ctx: adminUser.UserCtx,
313+
},
305314
{
306315
name: "happy path, update tags",
307316
id: assessment.ID,
@@ -386,6 +395,10 @@ func TestMutationUpdateAssessment(t *testing.T) {
386395
if len(tc.request.AppendTags) > 0 {
387396
assert.Check(t, len(resp.UpdateAssessment.Assessment.Tags) >= len(tc.request.AppendTags))
388397
}
398+
399+
if tc.request.ResponseDueDuration != nil {
400+
assert.Check(t, is.Equal(*resp.UpdateAssessment.Assessment.ResponseDueDuration, *tc.request.ResponseDueDuration))
401+
}
389402
})
390403
}
391404

internal/graphapi/assessmentresponse_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ func TestMutationCreateAssessmentResponse(t *testing.T) {
422422
assert.NilError(t, err)
423423

424424
_, err = suite.client.api.CreateAssessmentResponse(testUser1.UserCtx, req)
425-
assert.ErrorContains(t, err, "assessment is already in progress or completed")
425+
assert.ErrorContains(t, err, "assessment is already completed")
426426
})
427427

428428
(&Cleanup[*generated.AssessmentResponseDeleteOne]{client: suite.client.db.AssessmentResponse, IDs: responseIDsOrg1}).MustDelete(testUser1.UserCtx, t)

internal/graphapi/review_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ func TestReviewWithReviewFrequencyCalculation(t *testing.T) {
485485
expectedReviewDate = lastReviewTime.AddDate(0, freq.addMonths, 0)
486486
}
487487

488-
nextReviewTime := time.Time(*updatedEntity.NextReviewAt)
488+
nextReviewTime := time.Time(*updatedEntity.NextReviewAt).UTC()
489489

490490
assert.Check(t, is.DeepEqual(expectedReviewDate.Year(), nextReviewTime.Year()),
491491
"next_review_at year should match expected")
@@ -526,8 +526,8 @@ func TestReviewWithMultipleConnectedEntities(t *testing.T) {
526526
assert.Check(t, newEntity.LastReviewedAt != nil, "last_reviewed_at should be set")
527527
assert.Check(t, newEntity.NextReviewAt != nil, "next_review_at should be set")
528528

529-
lastReviewedTime := time.Time(*newEntity.LastReviewedAt)
530-
nextReviewTime := time.Time(*newEntity.NextReviewAt)
529+
lastReviewedTime := time.Time(*newEntity.LastReviewedAt).UTC()
530+
nextReviewTime := time.Time(*newEntity.NextReviewAt).UTC()
531531

532532
expectedReviewDate := lastReviewedTime.AddDate(0, 1, 0)
533533

internal/httpserve/handlers/questionnaire.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package handlers
22

33
import (
44
"context"
5+
"errors"
56
"time"
67

78
echo "github.com/theopenlane/echox"
@@ -13,6 +14,7 @@ import (
1314
"github.com/theopenlane/core/internal/ent/generated/assessment"
1415
"github.com/theopenlane/core/internal/ent/generated/assessmentresponse"
1516
"github.com/theopenlane/core/internal/ent/generated/privacy"
17+
"github.com/theopenlane/core/internal/ent/hooks"
1618
"github.com/theopenlane/core/pkg/logx"
1719
)
1820

@@ -257,6 +259,10 @@ func (h *Handler) SubmitQuestionnaire(ctx echo.Context, openapi *OpenAPIContext)
257259

258260
freshResponse, err := responseUpdate.Save(allowCtx)
259261
if err != nil {
262+
if errors.Is(err, hooks.ErrAssessmentInCompleted) {
263+
return h.BadRequest(ctx, err, openapi)
264+
}
265+
260266
logx.FromContext(reqCtx).Err(err).Msg("could not update assessment response")
261267
return h.InternalServerError(ctx, ErrProcessingRequest, openapi)
262268
}

0 commit comments

Comments
 (0)