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
2 changes: 1 addition & 1 deletion internal/database/class_enrollments_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ func (db *DB) EndEnrollmentsForTransfer(ctx context.Context, userID, fromFacilit
AND pce.user_id = ?
AND pc.facility_id = ?
AND pce.enrollment_status = 'Enrolled'`,
models.EnrollmentIncompleteTransfered, userID, fromFacilityID).Error; err != nil {
models.EnrollmentIncompleteTransferred, userID, fromFacilityID).Error; err != nil {
return newUpdateDBError(err, "program_class_enrollments")
}
return nil
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-- +goose Up
-- 00003 settled on the misspelt 'Incomplete: Transfered'. The status is now
-- spelt 'Incomplete: Transferred' everywhere, so this renames the stored rows.
UPDATE programs.program_class_enrollments
SET enrollment_status = 'Incomplete: Transferred'
WHERE enrollment_status = 'Incomplete: Transfered';

-- +goose Down
-- Nothing to undo: the rows it changed can't be told apart from the ones that
-- were already 'Incomplete: Transferred'.
2 changes: 1 addition & 1 deletion internal/database/program_classes_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ func (db *DB) GetProgramClassOutcomes(id int, args *models.QueryContext) ([]Prog
incompleteStatuses := []models.ProgramEnrollmentStatus{
models.EnrollmentIncompleteDropped,
models.EnrollmentIncompleteFailedToComplete,
models.EnrollmentIncompleteTransfered,
models.EnrollmentIncompleteTransferred,
models.EnrollmentIncompleteSegregated}

// Create a set that includes the last 6 months, excluding the current month, of program outcomes
Expand Down
2 changes: 1 addition & 1 deletion internal/database/reports_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var rosterStatusFilterMap = map[string]string{
"Dropped": "Incomplete: Dropped",
"Segregated": "Incomplete: Segregated",
"Failed to Complete": "Incomplete: Failed to Complete",
"Transfered": "Incomplete: Transfered",
"Transferred": "Incomplete: Transferred",
}

const sessionsAttendedSubquery = `(SELECT COUNT(*) FROM program_class_event_attendance pcea
Expand Down
11 changes: 11 additions & 0 deletions internal/database/reports_store_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package database

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestMapRosterStatusesTransferred(t *testing.T) {
assert.Equal(t, []string{"Incomplete: Transferred"}, mapRosterStatuses([]string{"Transferred"}))
}
2 changes: 1 addition & 1 deletion internal/database/seed_dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ var (
models.EnrollmentIncompleteWithdrawn,
models.EnrollmentIncompleteDropped,
models.EnrollmentIncompleteFailedToComplete,
models.EnrollmentIncompleteTransfered,
models.EnrollmentIncompleteTransferred,
}
sampleAttendance = []models.Attendance{models.Present, models.Absent_Excused, models.Absent_Unexcused}
)
Expand Down
4 changes: 4 additions & 0 deletions internal/handlers/class_enrollments.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net/http"
"slices"
"strconv"
"time"

Expand Down Expand Up @@ -137,6 +138,9 @@ func (srv *server) handleUpdateProgramClassEnrollments(w http.ResponseWriter, r
if enrollment.EnrollmentStatus == "" {
return newInvalidIdServiceError(errors.New("enrollment status is required"), "enrollment status")
}
if !slices.Contains(models.AllEnrollmentStatuses, enrollment.EnrollmentStatus) {
return newBadRequestServiceError(errors.New("unknown enrollment status"), "enrollment status")
}
class, err := srv.store.GetCohortByID(classId)
if err != nil {
return newDatabaseServiceError(err)
Expand Down
34 changes: 34 additions & 0 deletions internal/handlers/class_enrollments_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,3 +210,37 @@ func TestGraduationRecordsAdminEmail(t *testing.T) {
require.NoError(t, srv.store.Where("user_id = ?", resident.ID).First(&completion).Error)
assert.Equal(t, "facadmin@example.com", completion.AdminEmail)
}

func TestUpdateEnrollmentsRejectsUnknownStatus(t *testing.T) {
srv := newTestServer(t)
facility := models.Facility{Name: "North", Timezone: "America/Chicago"}
require.NoError(t, srv.store.Create(&facility).Error)
admin := models.User{Username: "facadmin", Email: "facadmin@example.com", Role: users.FacilityAdmin, FacilityID: facility.ID}
require.NoError(t, srv.store.Create(&admin).Error)
resident := models.User{Username: "resident", Email: "resident@example.com", Role: users.Student, FacilityID: facility.ID}
require.NoError(t, srv.store.Create(&resident).Error)
program := models.Program{Name: "GED"}
require.NoError(t, srv.store.Create(&program).Error)
class := models.ProgramClassCohort{ProgramID: program.ID, FacilityID: facility.ID, Status: models.Active, Description: "Description", Capacity: 10, StartDt: time.Now()}
require.NoError(t, srv.store.Create(&class).Error)
require.NoError(t, srv.store.Create(&models.ProgramClassEnrollment{CohortID: class.ID, UserID: resident.ID, EnrollmentStatus: models.Enrolled}).Error)
cohortID := strconv.Itoa(int(class.ID))

for _, status := range []string{"Incomplete: Transfered", "Bogus"} {
t.Run(status, func(t *testing.T) {
body, err := json.Marshal(map[string]any{"enrollment_status": status, "user_ids": []uint{resident.ID}})
require.NoError(t, err)
req := httptest.NewRequest(http.MethodPatch, "/api/program-classes/"+cohortID+"/enrollments", bytes.NewReader(body))
req.SetPathValue("cohort_id", cohortID)
req = req.WithContext(identity.NewContext(req.Context(), &identity.Claims{UserID: admin.ID, Role: admin.Role, FacilityID: facility.ID}))
err = srv.handleUpdateProgramClassEnrollments(httptest.NewRecorder(), req, sLog{f: map[string]any{}})
svcErr, ok := err.(serviceError)
require.True(t, ok, "expected a serviceError, got %v", err)
assert.Equal(t, http.StatusBadRequest, svcErr.Status)

var stored models.ProgramClassEnrollment
require.NoError(t, srv.store.Where("user_id = ?", resident.ID).First(&stored).Error)
assert.Equal(t, models.Enrolled, stored.EnrollmentStatus)
})
}
}
4 changes: 2 additions & 2 deletions internal/handlers/internal_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ func TestInternalAPI(t *testing.T) {
for range 2 {
require.NoError(t, core.EndEnrollmentsForTransfer(ctx, resident.ID, facility.ID))
}
assert.Equal(t, []models.ProgramEnrollmentStatus{models.EnrollmentIncompleteTransfered}, status())
assert.Equal(t, []models.ProgramEnrollmentStatus{models.EnrollmentIncompleteTransferred}, status())

enroll()
for range 2 {
require.NoError(t, core.WithdrawEnrollments(ctx, resident.ID))
}
assert.Equal(t, []models.ProgramEnrollmentStatus{models.EnrollmentIncompleteTransfered, models.EnrollmentIncompleteWithdrawn}, status())
assert.Equal(t, []models.ProgramEnrollmentStatus{models.EnrollmentIncompleteTransferred, models.EnrollmentIncompleteWithdrawn}, status())

// A wrong token gets nothing.
_, err = programs.NewClient(ts.URL, "guess", nil).EnrolledUserIDs(ctx, class.ID)
Expand Down
2 changes: 1 addition & 1 deletion internal/integration/class_enrollments_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func runUpdateToTerminalStatusTest(t *testing.T, env *TestEnv, facility *models.
models.EnrollmentIncompleteWithdrawn,
models.EnrollmentIncompleteDropped,
models.EnrollmentIncompleteFailedToComplete,
models.EnrollmentIncompleteTransfered,
models.EnrollmentIncompleteTransferred,
models.EnrollmentIncompleteSegregated,
}

Expand Down
4 changes: 2 additions & 2 deletions internal/models/program_classes.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ const (
EnrollmentIncompleteWithdrawn ProgramEnrollmentStatus = "Incomplete: Withdrawn"
EnrollmentIncompleteDropped ProgramEnrollmentStatus = "Incomplete: Dropped"
EnrollmentIncompleteFailedToComplete ProgramEnrollmentStatus = "Incomplete: Failed to Complete"
EnrollmentIncompleteTransfered ProgramEnrollmentStatus = "Incomplete: Transfered"
EnrollmentIncompleteTransferred ProgramEnrollmentStatus = "Incomplete: Transferred"
EnrollmentIncompleteSegregated ProgramEnrollmentStatus = "Incomplete: Segregated"
)

Expand All @@ -353,7 +353,7 @@ var AllEnrollmentStatuses = []ProgramEnrollmentStatus{
EnrollmentIncompleteWithdrawn,
EnrollmentIncompleteDropped,
EnrollmentIncompleteFailedToComplete,
EnrollmentIncompleteTransfered,
EnrollmentIncompleteTransferred,
EnrollmentIncompleteSegregated,
}

Expand Down
8 changes: 7 additions & 1 deletion internal/models/program_classes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func TestAllEnrollmentStatusesCoversIncompletePrefix(t *testing.T) {
EnrollmentIncompleteWithdrawn,
EnrollmentIncompleteDropped,
EnrollmentIncompleteFailedToComplete,
EnrollmentIncompleteTransfered,
EnrollmentIncompleteTransferred,
EnrollmentIncompleteSegregated,
}
for _, s := range declared {
Expand All @@ -61,3 +61,9 @@ func TestAllEnrollmentStatusesCoversIncompletePrefix(t *testing.T) {
}
}
}

func TestTransferredStatusSpelling(t *testing.T) {
if string(EnrollmentIncompleteTransferred) != "Incomplete: Transferred" {
t.Errorf("got %q", EnrollmentIncompleteTransferred)
}
}
Loading