Skip to content
Open
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
16 changes: 14 additions & 2 deletions app/jobs/sync_all_course_assignments_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ def sync_assignment(course_to_lms, lms_assignment, results)

# Use shared LmsAssignment to populate Assignment
assignment.name = lms_assignment.name
assignment.due_date = lms_assignment.due_date
assignment.late_due_date = lms_assignment.late_due_date
unless preserve_existing_dates?(assignment, lms_assignment)
assignment.due_date = lms_assignment.due_date
assignment.late_due_date = lms_assignment.late_due_date
end
assignment.external_assignment_id = lms_assignment.id

if assignment.new_record?
Expand All @@ -60,4 +62,14 @@ def sync_assignment(course_to_lms, lms_assignment, results)
end
assignment.save!
end

private

def preserve_existing_dates?(assignment, lms_assignment)
return false if assignment.new_record?
return false unless lms_assignment.is_a?(Lmss::Canvas::Assignment)
return false if lms_assignment.base_date_present?

assignment.due_date.present? || assignment.late_due_date.present?
end
end
1 change: 1 addition & 0 deletions lib/lmss/base_assignment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ def id = raise(NotImplementedError)
def name = raise(NotImplementedError)
def due_date = raise(NotImplementedError)
def late_due_date = raise(NotImplementedError)
def base_date_present? = false
end
end
7 changes: 6 additions & 1 deletion lib/lmss/canvas/assignment.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
module Lmss
module Canvas
class Assignment < BaseAssignment
attr_reader :id, :name, :due_date, :late_due_date
attr_reader :id, :name, :due_date, :late_due_date, :base_date

def initialize(data)
@id = data['id']
@name = data['name']
@base_date = data['base_date']
@due_date = extract_date_field(data, 'due_at')
@late_due_date = extract_date_field(data, 'lock_at')
end

def base_date_present?
@base_date.is_a?(Hash) && @base_date.any?
end

private

def extract_date_field(assignment_data, field_name)
Expand Down
105 changes: 95 additions & 10 deletions spec/jobs/sync_all_course_assignments_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,43 @@
end
end

context 'when Canvas omits base_date metadata' do
let(:canvas_assignments) do
[
Lmss::Canvas::Assignment.new(
'id' => '123',
'name' => 'Assignment 1',
'due_at' => '2025-01-30T23:59:00Z',
'lock_at' => '2025-02-05T23:59:00Z',
'base_date' => nil
)
]
end

it 'preserves existing due dates for Canvas assignments' do
existing_assignment = create(:assignment,
course_to_lms: course_to_lms,
external_assignment_id: '123',
due_date: DateTime.parse('2025-01-15T23:59:00Z'),
late_due_date: DateTime.parse('2025-01-20T23:59:00Z')
)

described_class.perform_now(course_to_lms.id, sync_user.id)

existing_assignment.reload
expect(existing_assignment.due_date).to eq(DateTime.parse('2025-01-15T23:59:00Z'))
expect(existing_assignment.late_due_date).to eq(DateTime.parse('2025-01-20T23:59:00Z'))
end

it 'still sets dates for newly imported assignments' do
described_class.perform_now(course_to_lms.id, sync_user.id)

assignment = Assignment.find_by(external_assignment_id: '123')
expect(assignment.due_date).to eq(DateTime.parse('2025-01-30T23:59:00Z'))
expect(assignment.late_due_date).to eq(DateTime.parse('2025-02-05T23:59:00Z'))
end
end

context 'when sync_user is not staff' do
let(:student_user) { course.students.first }

Expand All @@ -130,20 +167,68 @@
end
end

describe '#sync_assignment' do
let(:job) { described_class.new }
let(:results) do
{
added_assignments: 0,
updated_assignments: 0,
unchanged_assignments: 0,
deleted_assignments: 0
}
end

it 'creates a new assignment and updates results' do
target_course_to_lms = course_to_lms

lms_assignment = build_canvas_assignment(
'id' => 'a123',
'name' => 'HW1',
'due_at' => '2025-01-15T23:59:00Z',
'lock_at' => '2025-01-20T23:59:00Z'
)

# THIS MUST BE REWRITTEN
# This was moved from Course.sync_assignment
# It is now a helper method within the job.
describe '.sync_assignment' do
it 'creates or updates an assignment' do
pending 'moved from course_spec and should be rewritten'
assignment_data = { 'id' => 'a123', 'name' => 'HW1', 'due_at' => 1.day.from_now.to_s }
expect do
described_class.sync_assignment(course_to_lms, assignment_data)
end.to change(Assignment, :count).by(1)
job.send(:sync_assignment, target_course_to_lms, lms_assignment, results)
end.to change { Assignment.where(course_to_lms_id: target_course_to_lms.id).count }.by(1)

assignment = Assignment.last
assignment = Assignment.find_by(course_to_lms_id: target_course_to_lms.id, external_assignment_id: 'a123')
expect(assignment.name).to eq('HW1')
expect(assignment.due_date).to eq(DateTime.parse('2025-01-15T23:59:00Z'))
expect(assignment.late_due_date).to eq(DateTime.parse('2025-01-20T23:59:00Z'))
expect(results[:added_assignments]).to eq(1)
expect(results[:updated_assignments]).to eq(0)
expect(results[:unchanged_assignments]).to eq(0)
end

it 'updates an existing assignment and updates results' do
target_course_to_lms = course_to_lms

existing_assignment = create(:assignment,
course_to_lms: target_course_to_lms,
external_assignment_id: 'a123',
name: 'Old HW Name',
due_date: DateTime.parse('2025-01-10T23:59:00Z')
)

lms_assignment = build_canvas_assignment(
'id' => 'a123',
'name' => 'HW1 Updated',
'due_at' => '2025-01-25T23:59:00Z',
'lock_at' => nil
)

expect do
job.send(:sync_assignment, target_course_to_lms, lms_assignment, results)
end.not_to change { Assignment.where(course_to_lms_id: target_course_to_lms.id).count }

existing_assignment.reload
expect(existing_assignment.name).to eq('HW1 Updated')
expect(existing_assignment.due_date).to eq(DateTime.parse('2025-01-25T23:59:00Z'))
expect(existing_assignment.late_due_date).to be_nil
expect(results[:added_assignments]).to eq(0)
expect(results[:updated_assignments]).to eq(1)
expect(results[:unchanged_assignments]).to eq(0)
end
end

Expand Down
Loading