From 16902fe6e9074c676a4d9a5781699579c6e2be3b Mon Sep 17 00:00:00 2001 From: Martin Dolores Date: Mon, 25 Aug 2025 18:05:13 +1000 Subject: [PATCH 1/3] feature/session-tracker-service - implement session tracker service with integration test - amend marking session update_session_details method to initalize date time before assigning --- app/models/marking_session.rb | 10 +++++++++- app/services/session_tracker.rb | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/models/marking_session.rb b/app/models/marking_session.rb index 9ba79540d..e26c4083e 100644 --- a/app/models/marking_session.rb +++ b/app/models/marking_session.rb @@ -15,6 +15,14 @@ def duration_minutes def update_session_details now = DateTime.now - update(end_time: now) + if start_time.present? + duration = ((now.to_f - start_time.to_f) / 60).to_i + update( + end_time: now, + duration_minutes: duration + ) + else + update(end_time: now, duration_minutes: 0) + end end end diff --git a/app/services/session_tracker.rb b/app/services/session_tracker.rb index 441d1e5d7..79eb5b531 100644 --- a/app/services/session_tracker.rb +++ b/app/services/session_tracker.rb @@ -18,10 +18,10 @@ def self.record_assessment_activity(action:, user:, project:, ip_address:, task: project_id: project.id, task_id: task&.id, task_definition_id: task&.task_definition_id, - created_at: Time.zone.now + created_at: DateTime.now ) - session.update_session_details + session.update_session_details if action == 'assessing' activity end From 2500b0adb457012eee5ba9c84ae4e35114436a39 Mon Sep 17 00:00:00 2001 From: rammakablecode Date: Tue, 27 Jan 2026 00:18:28 +1100 Subject: [PATCH 2/3] Implement session tracking with duration_minutes and activity logging --- db/migrate/20250922103033_create_marking_sessions.rb | 1 + db/schema.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/db/migrate/20250922103033_create_marking_sessions.rb b/db/migrate/20250922103033_create_marking_sessions.rb index c30f18fbd..4f0af0815 100644 --- a/db/migrate/20250922103033_create_marking_sessions.rb +++ b/db/migrate/20250922103033_create_marking_sessions.rb @@ -6,6 +6,7 @@ def change t.string :ip_address t.datetime :start_time t.datetime :end_time + t.integer :duration_minutes, default: 0 t.boolean :during_tutorial t.timestamps diff --git a/db/schema.rb b/db/schema.rb index 0e65657d5..24ac67dc7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -191,6 +191,7 @@ t.string "ip_address" t.datetime "start_time" t.datetime "end_time" + t.integer "duration_minutes", default: 0 t.boolean "during_tutorial" t.datetime "created_at", null: false t.datetime "updated_at", null: false From 6cce7dea8f1b957c7408565d84e60b7887e48fe7 Mon Sep 17 00:00:00 2001 From: rammakablecode Date: Thu, 29 Jan 2026 16:24:00 +1100 Subject: [PATCH 3/3] Update marking session tests to align with session tracking logic --- test/api/marking_sessions_api_test.rb | 112 +++++++++++++------------- 1 file changed, 58 insertions(+), 54 deletions(-) diff --git a/test/api/marking_sessions_api_test.rb b/test/api/marking_sessions_api_test.rb index 7a0615f7d..75f2d1d02 100644 --- a/test/api/marking_sessions_api_test.rb +++ b/test/api/marking_sessions_api_test.rb @@ -150,16 +150,15 @@ def test_marking_sessions assert_not last_activity.nil? # > Force the session to be 10 minutes in the past - travel 10.minutes - travel 5.seconds # Ensure we're past the 10 minute mark + travel 10.minutes + 5.seconds # Ensure we're past the 10 minute mark - # Create a comment as the tutor, ensure activity was created - get "/api/projects/#{project.id}/task_def_id/#{td.id}/submission_details" + # Use 'put' (assessing) because SessionTracker only updates end_time if action == 'assessing' + put "/api/projects/#{project.id}/task_def_id/#{td.id}", { trigger: 'discuss' } assert_equal 200, last_response.status - last_session = MarkingSession.last - last_activity = SessionActivity.last + last_session.reload + # Now it should be 10 because the end_time was pushed forward assert_equal 10, last_session.duration_minutes # Ensure activity points to the same session @@ -263,8 +262,8 @@ def test_get_marking_sessions create(:marking_session, user: convenor, unit: unit, - start_time: date.to_time + rand(0..12).hours, - end_time: date.to_time + rand(13..23).hours, + start_time: date.in_time_zone.change(hour: rand(0..12)), + end_time: date.in_time_zone.change(hour: rand(13..23)), ip_address: '127.0.0.1') end end @@ -305,49 +304,49 @@ def test_marking_sessions_tutorial_split activity_type_id: activity_type.id, activity_type: activity_type }) - tutorial1 = Tutorial.create!({ - unit: unit, - meeting_day: "Wednesday", - meeting_time: "8:00", - meeting_location: "-", - code: "Tutorial1", - unit_role: unit_role, - abbreviation: "Tutorial1", - tutorial_stream: tutorial_stream - }) - - tutorial2 = Tutorial.create!({ - unit: unit, - meeting_day: "Wednesday", - meeting_time: "11:00", - meeting_location: "-", - code: "Tutorial2", - unit_role: unit_role, - abbreviation: "Tutorial2", - tutorial_stream: tutorial_stream - }) - - tutorial3 = Tutorial.create!({ - unit: unit, - meeting_day: "Wednesday", - meeting_time: "13:00", - meeting_location: "-", - code: "Tutorial3", - unit_role: unit_role, - abbreviation: "Tutorial3", - tutorial_stream: tutorial_stream - }) - - tutorial4 = Tutorial.create!({ - unit: unit, - meeting_day: "Thursday", - meeting_time: "12:00", - meeting_location: "-", - code: "Tutorial4", - unit_role: unit_role, - abbreviation: "Tutorial4", - tutorial_stream: tutorial_stream - }) + Tutorial.create!({ + unit: unit, + meeting_day: "Wednesday", + meeting_time: "8:00", + meeting_location: "-", + code: "Tutorial1", + unit_role: unit_role, + abbreviation: "Tutorial1", + tutorial_stream: tutorial_stream + }) + + Tutorial.create!({ + unit: unit, + meeting_day: "Wednesday", + meeting_time: "11:00", + meeting_location: "-", + code: "Tutorial2", + unit_role: unit_role, + abbreviation: "Tutorial2", + tutorial_stream: tutorial_stream + }) + + Tutorial.create!({ + unit: unit, + meeting_day: "Wednesday", + meeting_time: "13:00", + meeting_location: "-", + code: "Tutorial3", + unit_role: unit_role, + abbreviation: "Tutorial3", + tutorial_stream: tutorial_stream + }) + + Tutorial.create!({ + unit: unit, + meeting_day: "Thursday", + meeting_time: "12:00", + meeting_location: "-", + code: "Tutorial4", + unit_role: unit_role, + abbreviation: "Tutorial4", + tutorial_stream: tutorial_stream + }) MarkingSession.delete_all @@ -360,7 +359,7 @@ def test_marking_sessions_tutorial_split start_time = wednesday.in_time_zone.change(hour: 5, min: 4) # 11:05am end_time = wednesday.in_time_zone.change(hour: 18, min: 0) # 3:00pm - current_time = start_time + current_time = start_time + 0.seconds # unit = Unit.first project = unit.projects.first @@ -409,8 +408,13 @@ def test_marking_sessions_tutorial_split current_time += 5.minutes end - start_time = thursday.to_time.change(hour: 17, min: 0) # 12:05pm - end_time = thursday.to_time.change(hour: 18, min: 0) # 3:00pm + # Ensure the next activity MUST create a new one, closing previous one. + MarkingSession.last.update(end_time: thursday.in_time_zone.change(hour: 15, min: 1)) + + travel 2.hours # ensure testing on a new session + + start_time = thursday.in_time_zone.change(hour: 17, min: 0) + end_time = thursday.in_time_zone.change(hour: 18, min: 0) current_time = start_time