From 6be5b6ef33b7fae618101dcddb363dbe71fda752 Mon Sep 17 00:00:00 2001 From: Henrik Nygren Date: Tue, 27 Oct 2026 14:07:27 +0200 Subject: [PATCH] Keep explicit unlocks' dates when unlock conditions change --- app/models/exercise_group.rb | 5 ++++- spec/models/exercise_group_spec.rb | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/models/exercise_group.rb b/app/models/exercise_group.rb index f7f533357..57422c55b 100644 --- a/app/models/exercise_group.rb +++ b/app/models/exercise_group.rb @@ -90,8 +90,11 @@ def exercises_by_unlock_spec def group_unlock_conditions=(unlock_conditions) group_exercises = exercises(false) # Rows granted under other conditions keep their date: fast refresh never revokes them, so moving it would open them early. + # Explicit unlocks keep theirs too: the row already started the deadline timer, so a later date would lock it while the timer runs. conditions = UnlockSpec.non_date_conditions(unlock_conditions).sort - rows_to_move = group_exercises.select { |e| UnlockSpec.non_date_conditions(e.unlock_spec).sort == conditions }.map(&:name) + rows_to_move = group_exercises.select do |e| + !e.requires_explicit_unlock? && UnlockSpec.non_date_conditions(e.unlock_spec).sort == conditions + end.map(&:name) group_exercises.each do |e| e.unlock_spec = unlock_conditions e.save! diff --git a/spec/models/exercise_group_spec.rb b/spec/models/exercise_group_spec.rb index 4fda95f4f..f0ce83639 100644 --- a/spec/models/exercise_group_spec.rb +++ b/spec/models/exercise_group_spec.rb @@ -61,6 +61,13 @@ expect(Unlock.where(exercise_name: %w[week1-01 week1-02]).pluck(:valid_after)).to all(eq(Time.zone.parse('2012-05-05'))) end + it 'keeps the date of explicit unlocks, whose deadline timer has already started' do + [ex1, ex2].each { |ex| ex.update!(deadline_spec: ['unlock + 7 days'].to_json) } + group.group_unlock_conditions = ['5.5.2012'].to_json + + expect(Unlock.where(exercise_name: %w[week1-01 week1-02]).pluck(:valid_after)).to all(eq(Time.zone.parse('2011-01-01'))) + end + it 'leaves unlock rows alone when the conditions are cleared' do group.group_unlock_conditions = [].to_json