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
21 changes: 20 additions & 1 deletion app/controllers/api/lessons_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ def index
archive_scope = params[:include_archived] == 'true' ? Lesson : Lesson.unarchived
scope = params[:school_class_id] ? archive_scope.where(school_class_id: params[:school_class_id]) : archive_scope
ordered_scope = scope.order(created_at: :asc)
@lessons_with_users = ordered_scope.accessible_by(current_ability).with_users
accessible_lessons = ordered_scope.accessible_by(current_ability)
lessons_with_users = accessible_lessons.with_users
remixes = user_remixes(accessible_lessons)
@lessons_with_users_and_remixes = lessons_with_users.zip(remixes)
render :index, formats: [:json], status: :ok
end

Expand Down Expand Up @@ -74,6 +77,22 @@ def verify_school_class_belongs_to_school
raise ParameterError, 'school_class_id does not correspond to school_id'
end

def user_remixes(lessons)
lessons.map do |lesson|
next nil unless lesson&.project&.remixes&.any?

user_remix(lesson)
end
end

def user_remix(lesson)
lesson.project&.remixes
&.where(user_id: current_user.id)
&.accessible_by(current_ability)
&.order(created_at: :asc)
&.first
end

def lesson_params
base_params.merge(user_id: current_user.id)
end
Expand Down
6 changes: 5 additions & 1 deletion app/controllers/api/projects/remixes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Projects
class RemixesController < ApiController
before_action :authorize_user
load_and_authorize_resource :school, only: :index
before_action :load_and_authorize_remix, only: %i[show]
before_action :load_and_authorize_remix, only: %i[show show_identifier]

def index
projects = Project.where(remixed_from_id: project.id).accessible_by(current_ability)
Expand All @@ -17,6 +17,10 @@ def show
render '/api/projects/show', formats: [:json]
end

def show_identifier
render json: { identifier: @project.identifier }, status: :ok
end

def create
# Ensure we have a fallback value to prevent bad requests
remix_origin = request.origin || request.referer
Expand Down
5 changes: 4 additions & 1 deletion app/views/api/lessons/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

json.array!(@lessons_with_users) do |lesson, user|
json.array!(@lessons_with_users_and_remixes) do |lesson_with_user, remix|
lesson, user = lesson_with_user # Destructure the pair
json.call(
lesson,
:id,
Expand All @@ -26,4 +27,6 @@ json.array!(@lessons_with_users) do |lesson, user|
end

json.user_name(user&.name)

json.remix_identifier(remix.identifier) if remix.present?
end
4 changes: 3 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
post :submit, on: :member, to: 'school_projects#submit'
post :return, on: :member, to: 'school_projects#return'
post :complete, on: :member, to: 'school_projects#complete'
resource :remix, only: %i[show create], controller: 'projects/remixes'
resource :remix, only: %i[show create], controller: 'projects/remixes' do
get :identifier, on: :member, to: 'projects/remixes#show_identifier'
end
resources :remixes, only: %i[index], controller: 'projects/remixes'
resource :images, only: %i[show create], controller: 'projects/images'
resources :feedback, only: %i[index create], controller: 'feedback' do
Expand Down
11 changes: 11 additions & 0 deletions spec/features/lesson/listing_lessons_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,17 @@
expect(data.size).to eq(1)
end

it "includes the remix identifier when the user has remixed the lesson's project" do
student = create(:student, school:)
authenticated_in_hydra_as(student)
create(:class_student, school_class:, student_id: student.id)
student_project = create(:project, school:, lesson:, parent: lesson.project, user_id: student.id)

get('/api/lessons', headers:)
data = JSON.parse(response.body, symbolize_names: true)
expect(data.first[:remix_identifier]).to eq(student_project.identifier)
end

it "does not include the lesson when the user is not a school-student within the lesson's class" do
student = create(:student, school:)
authenticated_in_hydra_as(student)
Expand Down
36 changes: 36 additions & 0 deletions spec/requests/projects/remix_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,35 @@
end
end

describe('#show_identifier') do
let!(:remixed_project) do
create(:project, remixed_from_id: original_project.id, user_id: authenticated_user.id)
end

it 'returns success response' do
get("/api/projects/#{original_project.identifier}/remix/identifier", headers:)
expect(response).to have_http_status(:ok)
end

it 'returns the project identifier' do
get("/api/projects/#{original_project.identifier}/remix/identifier", headers:)
expect(response.parsed_body['identifier']).to eq(remixed_project.identifier)
end

it 'returns 404 response if invalid project' do
get('/api/projects/no-such-project/remix/identifier', headers:)
expect(response).to have_http_status(:not_found)
end

it 'returns 404 if no remixed project for user' do
another_user = create(:owner, school:)
authenticated_in_hydra_as(another_user)

get("/api/projects/#{original_project.identifier}/remix/identifier", headers:)
expect(response).to have_http_status(:not_found)
end
end

describe '#create' do
it 'returns success response' do
post("/api/projects/#{original_project.identifier}/remix", params: { project: project_params }, headers:)
Expand Down Expand Up @@ -116,6 +145,13 @@
end
end

describe '#show_identifier' do
it 'returns unauthorized' do
get "/api/projects/#{original_project.identifier}/remix/identifier"
expect(response).to have_http_status(:unauthorized)
end
end

describe '#create' do
it 'returns unauthorized' do
post "/api/projects/#{original_project.identifier}/remix"
Expand Down
Loading