Skip to content

Commit b6bc86d

Browse files
committed
Scratch projects create action for remixing
This is based on the similar endpoint in Experience CS. Having this will allowed me to test the behaviour of Scratch remixing locally and it will allow us to start work implementing remixing on the frontend before the API is fully implemented. I considered re-using our existing endpoint for remixing, but this is not possible because Scratch does not support updating an unsaved project's id (see [1] for more). [1] - RaspberryPiFoundation/digital-editor-issues#1189 (comment)
1 parent 3c12216 commit b6bc86d

3 files changed

Lines changed: 66 additions & 1 deletion

File tree

app/controllers/api/scratch/projects_controller.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,30 @@ class ProjectsController < ScratchController
77
skip_before_action :check_scratch_feature, only: [:show]
88
before_action :load_project, only: %i[show update]
99

10+
before_action :ensure_create_is_a_remix, only: %i[create]
11+
1012
def show
1113
render json: @project.scratch_component.content
1214
end
1315

16+
def create
17+
render json: { status: 'ok', 'content-name': 'new-project-id' }, status: :ok
18+
end
19+
1420
def update
1521
scratch_content = params.permit!.slice(:meta, :targets, :monitors, :extensions)
1622
@project.scratch_component&.content = scratch_content.to_unsafe_h
1723
@project.save!
1824
render json: { status: 'ok' }, status: :ok
1925
end
26+
27+
private
28+
29+
def ensure_create_is_a_remix
30+
return if params[:is_remix] == '1'
31+
32+
render json: { error: 'Only remixing existing projects is allowed' }, status: :forbidden
33+
end
2034
end
2135
end
2236
end

config/routes.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
namespace :api do
3636
namespace :scratch do
37-
resources :projects, only: %i[show update]
37+
resources :projects, only: %i[show update create]
3838
get '/assets/internalapi/asset/:id(.:format)/get/' => 'assets#show'
3939
post '/assets/:id' => 'assets#create'
4040
end
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
5+
RSpec.describe 'Creating a Scratch project (remixing)', type: :request do
6+
let(:school) { create(:school) }
7+
let(:teacher) { create(:teacher, school:) }
8+
let(:cookie_headers) { { 'Cookie' => "scratch_auth=#{UserProfileMock::TOKEN}" } }
9+
let(:params) { { original_id: 'original-project-id', project: { targets: [] }, is_remix: '1' } }
10+
11+
before do
12+
Flipper.disable :cat_mode
13+
Flipper.disable_actor :cat_mode, school
14+
end
15+
16+
it 'responds 401 Unauthorized when no cookie is provided' do
17+
post '/api/scratch/projects', params: params
18+
19+
expect(response).to have_http_status(:unauthorized)
20+
end
21+
22+
it 'responds 404 Not Found when cat_mode is not enabled' do
23+
authenticated_in_hydra_as(teacher)
24+
25+
post '/api/scratch/projects', params: params, headers: cookie_headers
26+
27+
expect(response).to have_http_status(:not_found)
28+
end
29+
30+
it 'responds 403 Forbidden when not remixing' do
31+
authenticated_in_hydra_as(teacher)
32+
Flipper.enable_actor :cat_mode, school
33+
34+
post '/api/scratch/projects', params: params.merge(is_remix: '0'), headers: cookie_headers
35+
36+
expect(response).to have_http_status(:forbidden)
37+
end
38+
39+
it 'return new project id when cat_mode is enabled and a cookie is provided' do
40+
authenticated_in_hydra_as(teacher)
41+
Flipper.enable_actor :cat_mode, school
42+
43+
post '/api/scratch/projects', params: params, headers: cookie_headers
44+
45+
expect(response).to have_http_status(:ok)
46+
47+
data = JSON.parse(response.body, symbolize_names: true)
48+
expect(data[:status]).to eq('ok')
49+
expect(data[:'content-name']).to eq('new-project-id')
50+
end
51+
end

0 commit comments

Comments
 (0)