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

ticket/200: sign out unsigned out members in last place #155

Merged
merged 1 commit into from
Feb 11, 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
29 changes: 15 additions & 14 deletions internal/services/events_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,26 +107,19 @@ func (es *eventService) EndEvent(eventId uint64) error {
return e.Forbidden("This event has already ended, it cannot be ended again.")
}

// Retrieve list of entries for the event
// Reject request with 403 if all entries are not signed out
entries := []models.Participant{}
res = es.db.Where("event_id = ?", eventId).Order("signed_out_at DESC").Find(&entries)
if err := res.Error; err != nil {
return e.InternalServerError(err.Error())
}

for _, entry := range entries {
if entry.SignedOutAt == nil {
return e.Forbidden("Event cannot be ended while there are still unsigned out entries.")
}
}

// Start transaction for the event update and ranking update process
tx := es.db.Begin()
if err := tx.Error; err != nil {
return e.InternalServerError(err.Error())
}

// Update all entries who are not signed out to sign them out in last place
res = tx.Model(&models.Participant{}).Where("event_id = ? AND signed_out_at IS NULL", event.ID).Update("signed_out_at", event.StartDate)
if err := res.Error; err != nil {
tx.Rollback()
return e.InternalServerError(err.Error())
}

// Update events state
event.State = models.EventStateEnded
tx.Save(&event)
Expand All @@ -135,6 +128,14 @@ func (es *eventService) EndEvent(eventId uint64) error {
return e.InternalServerError(err.Error())
}

// Retrieve list of entries for the event
entries := []models.Participant{}
res = tx.Where("event_id = ?", eventId).Order("signed_out_at DESC").Find(&entries)
if err := res.Error; err != nil {
tx.Rollback()
return e.InternalServerError(err.Error())
}

// Calculate points for each entry in the event and update placements
rankingService := NewRankingService(tx)
eventSize := len(entries)
Expand Down
67 changes: 67 additions & 0 deletions internal/services/events_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,73 @@ func EndEventTest() func(*testing.T) {
}
}

func TestEventService_EndEvent_UnsignedOutEntries(t *testing.T) {
t.Setenv("ENVIRONMENT", "TEST")

db, err := database.OpenTestConnection()
if err != nil {
t.Fatal(err.Error())
}
defer database.WipeDB(db)

set, err := testhelpers.SetupSemester(db, "Fall 2022")
if err != nil {
t.Fatalf("Failed to setup test environment: %v", err)
}

event, err := testhelpers.CreateEvent(db, "Event 1", set.Semester.ID, time.Now().UTC())
if err != nil {
t.Fatalf("Failed to setup event: %v", err)
}

now := time.Now().UTC()
_, err = testhelpers.CreateParticipant(db, set.Memberships[0].ID, event.ID, 0, &now, 2)
if err != nil {
t.Fatalf("Failed to add entry: %v", err)
}

next := now.Add(time.Minute * 30)
_, err = testhelpers.CreateParticipant(db, set.Memberships[1].ID, event.ID, 0, &next, 0)
if err != nil {
t.Fatalf("Failed to add entry: %v", err)
}

entry3, err := testhelpers.CreateParticipant(db, set.Memberships[2].ID, event.ID, 0, nil, 4)
if err != nil {
t.Fatalf("Failed to add entry: %v", err)
}

svc := NewEventService(db)
err = svc.EndEvent(event.ID)
if err != nil {
t.Errorf("EndEvent() error = %v", err)
return
}

// Check that entry3's signed_out_at field is set to the start time of the event
foundEntry := models.Participant{ID: entry3.ID}
res := db.First(&foundEntry)
if res.Error != nil {
t.Fatal(res.Error.Error())
}

// Check that the date is the same
sYear, sMonth, sDay := foundEntry.SignedOutAt.Date()
eYear, eMonth, eDay := event.StartDate.Date()
if sYear != eYear || sMonth != eMonth || sDay != eDay {
t.Errorf("SignedOutAt not equal to StartDate of event (user not signed out in last place): SignedOutAt: %v, StartDate: %v", foundEntry.SignedOutAt, event.StartDate)
return
}

// Check that hour, min, and second are equal (milliseconds don't matter)
sHour, sMin, sSec := foundEntry.SignedOutAt.Clock()
eHour, eMin, eSec := event.StartDate.Clock()
if sHour != eHour || sMin != eMin || sSec != eSec {
t.Errorf("SignedOutAt not equal to StartDate of event (user not signed out in last place): SignedOutAt: %v, StartDate: %v", foundEntry.SignedOutAt, event.StartDate)
return
}
}

func TestEventService_EndEvent_PlacementAndRankingsUpdated(t *testing.T) {
t.Setenv("ENVIRONMENT", "TEST")

Expand Down