Skip to content

Commit 0e0beb6

Browse files
authored
Return submitted count with lessons list if user is teacher or owner (#624)
## Status - Closes _add issue numbers or delete_ - Related to _add issue numbers or delete_ ## Points for consideration: - Security - Performance ## What's changed? _Description of what's been done - bullets are often best_ ## Steps to perform after deploying to production _If the production environment requires any extra work after this PR has been deployed detail it here. This could be running a Rake task, a migration, or upgrading a Gem. That kind of thing._
1 parent a44daab commit 0e0beb6

10 files changed

Lines changed: 103 additions & 68 deletions

File tree

app/controllers/api/lessons_controller.rb

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,16 @@ def index
1010
archive_scope = params[:include_archived] == 'true' ? Lesson : Lesson.unarchived
1111
scope = params[:school_class_id] ? archive_scope.where(school_class_id: params[:school_class_id]) : archive_scope
1212
ordered_scope = scope.order(created_at: :asc)
13+
1314
accessible_lessons = ordered_scope.accessible_by(current_ability)
14-
lessons_with_users = accessible_lessons.with_users
15-
remixes = user_remixes(accessible_lessons)
16-
@lessons_with_users_and_remixes = lessons_with_users.zip(remixes)
17-
render :index, formats: [:json], status: :ok
15+
@lessons_with_users = accessible_lessons.with_users
16+
if current_user&.school_teacher?(school) || current_user&.school_owner?(school)
17+
render :teacher_index, formats: [:json], status: :ok
18+
else
19+
remixes = user_remixes(accessible_lessons)
20+
@lessons_with_users_and_remixes = @lessons_with_users.zip(remixes)
21+
render :student_index, formats: [:json], status: :ok
22+
end
1823
end
1924

2025
def show
@@ -121,7 +126,7 @@ def school_owner?
121126
end
122127

123128
def school
124-
@school ||= @lesson&.school || School.find_by(id: base_params[:school_id])
129+
@school ||= @lesson&.school || School.find_by(id: base_params[:school_id]) || SchoolClass.find_by(id: params[:school_class_id])&.school
125130
end
126131
end
127132
end

app/models/lesson.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ def unarchive!
5252
save!(validate: false)
5353
end
5454

55+
def submitted_count
56+
return 0 unless project
57+
58+
project.remixes.count { |remix| remix.school_project&.submitted? }
59+
end
60+
5561
private
5662

5763
def assign_school_from_school_class
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# frozen_string_literal: true
2+
3+
json.call(
4+
lesson,
5+
:id,
6+
:school_id,
7+
:school_class_id,
8+
:copied_from_id,
9+
:user_id,
10+
:name,
11+
:description,
12+
:visibility,
13+
:due_date,
14+
:archived_at,
15+
:created_at,
16+
:updated_at
17+
)
18+
19+
if lesson.project
20+
json.project(
21+
lesson.project,
22+
:identifier,
23+
:project_type
24+
)
25+
end
26+
27+
json.user_name(user&.name)

app/views/api/lessons/index.json.jbuilder

Lines changed: 0 additions & 32 deletions
This file was deleted.

app/views/api/lessons/show.json.jbuilder

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,4 @@
22

33
lesson, user = @lesson_with_user
44

5-
json.call(
6-
lesson,
7-
:id,
8-
:school_id,
9-
:school_class_id,
10-
:copied_from_id,
11-
:user_id,
12-
:name,
13-
:description,
14-
:visibility,
15-
:due_date,
16-
:archived_at,
17-
:created_at,
18-
:updated_at
19-
)
20-
21-
if lesson.project
22-
json.project(
23-
lesson.project,
24-
:identifier,
25-
:project_type
26-
)
27-
end
28-
29-
json.user_name(user&.name)
5+
json.partial! 'lesson', lesson:, user:
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# frozen_string_literal: true
2+
3+
json.array!(@lessons_with_users_and_remixes) do |lesson_with_user, remix|
4+
lesson, user = lesson_with_user
5+
json.partial! 'lesson', lesson: lesson, user: user
6+
json.remix_identifier(remix.identifier) if remix.present?
7+
end
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# frozen_string_literal: true
2+
3+
json.array!(@lessons_with_users) do |lesson, user|
4+
json.partial! 'lesson', lesson: lesson, user: user
5+
json.submitted_count(lesson.submitted_count)
6+
end

spec/factories/lesson.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
project factory: %i[project]
1414

1515
after(:build) do |lesson, evaluator|
16-
lesson.project.user_id = lesson.user_id
17-
lesson.project.name = evaluator.project_name
18-
lesson.project.identifier = "#{lesson.name.parameterize}-#{lesson.user_id}"
16+
lesson.project&.user_id = lesson.user_id
17+
lesson.project&.name = evaluator.project_name
18+
lesson.project&.identifier = "#{lesson.name.parameterize}-#{lesson.user_id}"
1919
end
2020

2121
trait :with_project_components do

spec/features/lesson/listing_lessons_spec.rb

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
let!(:lesson) { create(:lesson, name: 'Test Lesson', visibility: 'public', user_id: teacher.id) }
1313
let(:teacher) { create(:teacher, school:, name: 'School Teacher') }
1414
let(:owner) { create(:owner, school:) }
15+
let(:student) { create(:student, school:) }
1516
let(:school) { create(:school) }
1617
let(:school_class) { create(:school_class, teacher_ids: [teacher.id], school:) }
1718
let(:another_school_class) { create(:school_class, teacher_ids: [teacher.id], school:) }
@@ -119,6 +120,17 @@
119120
expect(data.size).to eq(1)
120121
end
121122

123+
it 'includes the submitted_count for each lesson' do
124+
lesson.update!(school_class_id: school_class.id)
125+
remix = create(:project, school:, remixed_from_id: lesson.project.id, user_id: student.id)
126+
remix.school_project.transition_status_to!(:submitted, student.id)
127+
128+
get("/api/lessons?school_class_id=#{school_class.id}", headers:)
129+
data = JSON.parse(response.body, symbolize_names: true)
130+
131+
expect(data.first[:submitted_count]).to eq(1)
132+
end
133+
122134
context "when the lesson's visibility is 'private'" do
123135
let!(:lesson) { create(:lesson, name: 'Test Lesson', visibility: 'private') }
124136
let(:owner) { create(:owner, school:) }
@@ -172,7 +184,6 @@
172184
end
173185

174186
it 'does not include the lesson when the user is a school-student' do
175-
student = create(:student, school:)
176187
authenticated_in_hydra_as(student)
177188

178189
get('/api/lessons', headers:)
@@ -200,7 +211,6 @@
200211
end
201212

202213
it "includes the lesson when the user is a school-student within the lesson's class" do
203-
student = create(:student, school:)
204214
authenticated_in_hydra_as(student)
205215
create(:class_student, school_class:, student_id: student.id)
206216

@@ -210,6 +220,15 @@
210220
expect(data.size).to eq(1)
211221
end
212222

223+
it 'does not include the submitted_count when the user is a school-student within the lesson\'s class' do
224+
authenticated_in_hydra_as(student)
225+
create(:class_student, school_class:, student_id: student.id)
226+
227+
get('/api/lessons', headers:)
228+
data = JSON.parse(response.body, symbolize_names: true)
229+
expect(data.first).not_to have_key(:submitted_count)
230+
end
231+
213232
it "includes the remix identifier when the user has remixed the lesson's project" do
214233
student = create(:student, school:)
215234
authenticated_in_hydra_as(student)
@@ -222,7 +241,6 @@
222241
end
223242

224243
it "does not include the lesson when the user is not a school-student within the lesson's class" do
225-
student = create(:student, school:)
226244
authenticated_in_hydra_as(student)
227245

228246
get('/api/lessons', headers:)

spec/models/lesson_spec.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,4 +287,26 @@
287287
expect(lesson.archived?).to be(false)
288288
end
289289
end
290+
291+
describe '#submitted_count' do
292+
it 'returns 0 if there is no project' do
293+
lesson = create(:lesson, project: nil)
294+
expect(lesson.submitted_count).to eq(0)
295+
end
296+
297+
it 'returns the count of submitted remixes of the lesson project' do
298+
student = create(:student, school:)
299+
lesson = create(:lesson, school:, user_id: teacher.id)
300+
301+
remix_1 = create(:project, school:, remixed_from_id: lesson.project.id, user_id: student.id)
302+
remix_1.school_project.transition_status_to!(:submitted, remix_1.user_id)
303+
304+
remix_2 = create(:project, school:, remixed_from_id: lesson.project.id, user_id: student.id)
305+
remix_2.school_project.transition_status_to!(:submitted, remix_2.user_id)
306+
307+
create(:project, school:, remixed_from_id: lesson.project.id, user_id: student.id) # Not submitted
308+
309+
expect(lesson.submitted_count).to eq(2)
310+
end
311+
end
290312
end

0 commit comments

Comments
 (0)