Skip to content

Commit a07678b

Browse files
authored
Merge pull request code-dot-org#10162 from code-dot-org/lastAttempt
Changes User.last_attempt to return a UserLevel rather than an Activity.
2 parents 1ff1a20 + 40b5ada commit a07678b

File tree

7 files changed

+64
-68
lines changed

7 files changed

+64
-68
lines changed

dashboard/app/controllers/api_controller.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,13 +167,13 @@ def user_progress_for_stage
167167
level = params[:level] ? Script.cache_find_level(params[:level].to_i) : script_level.oldest_active_level
168168

169169
if current_user
170-
last_activity = current_user.last_attempt(level)
171-
level_source = last_activity.try(:level_source).try(:data)
170+
user_level = current_user.last_attempt(level)
171+
level_source = user_level.try(:level_source).try(:data)
172172

173173
response[:progress] = current_user.user_progress_by_stage(stage)
174-
if last_activity
174+
if user_level
175175
response[:lastAttempt] = {
176-
timestamp: last_activity.updated_at.to_datetime.to_milliseconds,
176+
timestamp: user_level.updated_at.to_datetime.to_milliseconds,
177177
source: level_source
178178
}
179179
end

dashboard/app/controllers/script_levels_controller.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ def load_level_source
152152
readonly_view_options
153153
elsif @user && current_user && @user != current_user
154154
# load other user's solution for teachers viewing their students' solution
155+
# TODO(asher): Determine if the ordering of level_source and @user_level
156+
# assignment can be reversed to make level_source rely on @user_level.
155157
level_source = @user.last_attempt(@level).try(:level_source)
156158
@user_level = @user.user_level_for(@script_level, @level)
157159
readonly_view_options

dashboard/app/models/user.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -518,14 +518,16 @@ def unpassed_progression_level?(script_level, user_levels)
518518
end
519519
end
520520

521-
# Returns the most recent (via created_at) activity for the specified level.
522-
# TODO(asher): Change this to use UserLevel rather than Activity.
521+
# Returns the most recent (via updated_at) user_level for the specified
522+
# level.
523523
def last_attempt(level)
524-
Activity.where(user_id: self.id, level_id: level.id).order('id desc').first
524+
UserLevel.where(user_id: self.id, level_id: level.id).
525+
order('updated_at DESC').
526+
first
525527
end
526528

527-
# Returns the most recent (via updated_at) user_level for the specified
528-
# level.
529+
# Returns the most recent (via updated_at) user_level for any of the specified
530+
# levels.
529531
def last_attempt_for_any(levels)
530532
level_ids = levels.map(&:id)
531533
UserLevel.where(user_id: self.id, level_id: level_ids).

dashboard/test/controllers/api_controller_test.rb

Lines changed: 46 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ def make_progress_in_section(script)
233233
end
234234

235235
test "should get surveys for section with script with anonymous level_group assessment" do
236+
# Seed the RNG deterministically so we get the same "random" shuffling of results.
237+
srand 1
238+
236239
script = create :script
237240

238241
sub_level1 = create :text_match, name: 'level_free_response', type: 'TextMatch'
@@ -252,52 +255,47 @@ def make_progress_in_section(script)
252255
level1.save!
253256
create :script_level, script: script, levels: [level1], assessment: true
254257

255-
# student_1 did the survey
256-
create(:activity, user: @student_1, level: level1, level_source: create(:level_source, level: level1))
257-
258-
create(:activity, user: @student_1, level: sub_level1,
259-
level_source: create(:level_source, level: sub_level1, data: "This is a free response"))
260-
create(:activity, user: @student_1, level: sub_level2,
261-
level_source: create(:level_source, level: sub_level2, data: "0"))
262-
create(:activity, user: @student_1, level: sub_level3,
263-
level_source: create(:level_source, level: sub_level3, data: "1"))
264-
create(:activity, user: @student_1, level: sub_level4,
265-
level_source: create(:level_source, level: sub_level4, data: "-1"))
266-
267-
# student_2 also did the survey
268-
create(:activity, user: @student_2, level: level1, level_source: create(:level_source, level: level1))
269-
270-
create(:activity, user: @student_2, level: sub_level1,
271-
level_source: create(:level_source, level: sub_level1, data: "This is a different free response"))
272-
create(:activity, user: @student_2, level: sub_level2,
273-
level_source: create(:level_source, level: sub_level2, data: "-1"))
274-
create(:activity, user: @student_2, level: sub_level3,
275-
level_source: create(:level_source, level: sub_level3, data: "2"))
276-
create(:activity, user: @student_2, level: sub_level4,
277-
level_source: create(:level_source, level: sub_level4, data: "3"))
278-
279-
# student_3 through student_5 also did the survey, just submitting a free response.
280-
[@student_3, @student_4, @student_5].each_with_index do |student, student_index|
281-
create(:activity, user: student, level: level1, level_source: create(:level_source, level: level1))
282-
283-
create(:activity, user: student, level: sub_level1,
284-
level_source: create(:level_source, level: sub_level1, data: "Free response from student #{student_index + 3}"))
285-
create(:activity, user: student, level: sub_level2,
286-
level_source: create(:level_source, level: sub_level2, data: "-1"))
287-
create(:activity, user: student, level: sub_level3,
288-
level_source: create(:level_source, level: sub_level3, data: "-1"))
289-
create(:activity, user: student, level: sub_level4,
290-
level_source: create(:level_source, level: sub_level4, data: "-1"))
291-
end
292-
293258
updated_at = Time.now
294259

260+
# All students did the LevelGroup.
295261
[@student_1, @student_2, @student_3, @student_4, @student_5].each do |student|
296-
create :user_level, user: student, best_result: 100, script: script, level: level1, submitted: true, updated_at: updated_at
262+
create :user_level, user: student, script: script, level: level1,
263+
level_source: create(:level_source, level: level1), best_result: 100,
264+
submitted: true, updated_at: updated_at
297265
end
298266

299-
# Seed the RNG with the same thing so we get the same "random" shuffling of results.
300-
srand 1
267+
# student_1 did the survey.
268+
create :user_level, user: @student_1, script: script, level: sub_level1,
269+
level_source: create(:level_source, level: sub_level1, data: "This is a free response")
270+
create :user_level, user: @student_1, script: script, level: sub_level2,
271+
level_source: create(:level_source, level: sub_level2, data: "0")
272+
create :user_level, user: @student_1, script: script, level: sub_level3,
273+
level_source: create(:level_source, level: sub_level3, data: "1")
274+
create :user_level, user: @student_1, script: script, level: sub_level4,
275+
level_source: create(:level_source, level: sub_level4, data: "-1")
276+
277+
# student_2 did the survey.
278+
create :user_level, user: @student_2, script: script, level: sub_level1,
279+
level_source: create(:level_source, level: sub_level1, data: "This is a different free response")
280+
create :user_level, user: @student_2, script: script, level: sub_level2,
281+
level_source: create(:level_source, level: sub_level2, data: "-1")
282+
create :user_level, user: @student_2, script: script, level: sub_level3,
283+
level_source: create(:level_source, level: sub_level3, data: "2")
284+
create :user_level, user: @student_2, script: script, level: sub_level4,
285+
level_source: create(:level_source, level: sub_level4, data: "3")
286+
287+
# student_3, student_4, and student_5 did only the free response part of the
288+
# survey....
289+
[@student_3, @student_4, @student_5].each_with_index do |student, student_index|
290+
create :user_level, user: student, script: script, level: sub_level1,
291+
level_source: create(:level_source, level: sub_level1, data: "Free response from student #{student_index + 3}")
292+
create :user_level, user: student, script: script, level: sub_level2,
293+
level_source: create(:level_source, level: sub_level2, data: "-1")
294+
create :user_level, user: student, script: script, level: sub_level3,
295+
level_source: create(:level_source, level: sub_level3, data: "-1")
296+
create :user_level, user: student, script: script, level: sub_level4,
297+
level_source: create(:level_source, level: sub_level4, data: "-1")
298+
end
301299

302300
get :section_surveys, section_id: @section.id, script_id: script.id
303301
assert_response :success
@@ -811,10 +809,11 @@ def make_progress_in_section(script)
811809

812810
script_level = script.script_levels[0]
813811
level = script_level.level
814-
create :user_level, user: user, best_result: 100, script: script, level: level
812+
level_source = create :level_source, level: level, data: 'level source'
815813

816-
create(:activity, user: user, level: level,
817-
level_source: create(:level_source, level: level, data: 'level source'))
814+
create :user_level, user: user, best_result: 100, script: script,
815+
level: level, level_source: level_source
816+
create :activity, user: user, level: level, level_source: level_source
818817

819818
get :user_progress_for_stage, script_name: script.name, stage_position: 1, level_position: 1
820819
assert_response :success
@@ -895,17 +894,10 @@ def make_progress_in_section(script)
895894
stage = create :stage, script: script
896895
level1a = create :maze, name: 'maze 1'
897896
level1b = create :maze, name: 'maze 1 new'
897+
level_source = create :level_source, level: level1a, data: 'level source'
898898
create :script_level, script: script, stage: stage, levels: [level1a, level1b], properties: "{'maze 1': {active: false}}"
899-
create(
900-
:activity,
901-
user: @student_1,
902-
level: level1a,
903-
level_source: create(
904-
:level_source,
905-
level: level1a,
906-
data: 'level source'
907-
)
908-
)
899+
create :user_level, user: @student_1, script: script, level: level1a, level_source: level_source
900+
create :activity, user: @student_1, level: level1a, level_source: level_source
909901

910902
get :user_progress_for_stage, script_name: script.name, stage_position: 1, level_position: 1, level: level1a.id
911903
body = JSON.parse(response.body)

dashboard/test/controllers/script_levels_controller_test.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,6 @@ def assert_caching_enabled(cache_control_header, max_age, proxy_max_age)
751751
last_attempt_data = 'test'
752752
level = @custom_s1_l1.level
753753
level_source = LevelSource.find_identical_or_create(level, last_attempt_data)
754-
Activity.create!(level: level, user: @student, level_source: level_source)
755754
UserLevel.create!(level: level, user: @student, level_source: level_source)
756755

757756
get :show, script_id: @custom_script, stage_position: @custom_stage_1.absolute_position, id: @custom_s1_l1.position
@@ -766,7 +765,6 @@ def assert_caching_enabled(cache_control_header, max_age, proxy_max_age)
766765
last_attempt_data = 'test'
767766
level = @custom_s1_l1.level
768767
level_source = LevelSource.find_identical_or_create(level, last_attempt_data)
769-
Activity.create!(level: level, user: @student, level_source: level_source)
770768
UserLevel.create!(script: @custom_script, level: level, user: @student, level_source: level_source)
771769

772770
get :show, script_id: @custom_script, stage_position: @custom_stage_1.absolute_position, id: @custom_s1_l1.position, user_id: @student.id, section_id: @section.id

dashboard/test/helpers/users_helper_test.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,14 @@ def test_summarize_user_progress_with_pages
104104
# Create a ScriptLevel joining this level to the script.
105105
create :script_level, script: script, levels: [level], assessment: true
106106

107-
# Create a UserLevel joining this level to the user.
108-
ul = create :user_level, user: user, best_result: ActivityConstants::BEST_PASS_RESULT, level: level, script: script
109-
110107
# The Activity record will point at a LevelSource with JSON data in which
111108
# page one has all valid answers and page two has no valid answers.
112109
level_source = create :level_source,
113110
data: "{\"#{sub_level1.id}\":{\"valid\":true},\"#{sub_level2.id}\":{\"valid\":true},\"#{sub_level3.id}\":{\"valid\":false},\"#{sub_level4.id}\":{\"valid\":false}}"
114111

112+
# Create a UserLevel joining this level to the user.
113+
ul = create :user_level, user: user, best_result: ActivityConstants::BEST_PASS_RESULT, level: level, script: script, level_source: level_source
114+
115115
# And now create the Activity record.
116116
create :activity, level_id: level.id,
117117
user_id: user.id,

dashboard/test/models/plc/course_unit_module_selection_test.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class CourseUnitModuleSelectionTest < ActionView::TestCase
8484

8585
@evaluation = LevelGroup.create_from_level_builder({name: 'evaluation'}, {dsl_text: levelgroup_dsl})
8686
create(:script_level, script: @course_unit.script, levels: [@evaluation])
87+
@user_level = create(:user_level, user: @user, script: @course_unit.script, level: @evaluation)
8788
@activity = create(:activity, user: @user, level: @evaluation)
8889
@user_level = create(:user_level, user: @user, level: @evaluation)
8990
end
@@ -128,6 +129,7 @@ def get_preferred_modules_for_answers(answers_map)
128129
end
129130

130131
level_source = create(:level_source, level: @evaluation, data: answers_data.to_json)
132+
@user_level.update(level_source: level_source)
131133
@activity.update(level_source: level_source)
132134
@user_level.update(level_source: level_source)
133135
@course_unit.determine_preferred_learning_modules @user

0 commit comments

Comments
 (0)