|
5 | 5 | RSpec.describe 'Creating a Scratch project (remixing)', type: :request do |
6 | 6 | let(:school) { create(:school) } |
7 | 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' } } |
| 8 | + let(:headers) do |
| 9 | + { |
| 10 | + 'Cookie' => "scratch_auth=#{UserProfileMock::TOKEN}", |
| 11 | + 'Origin' => 'editor.com' |
| 12 | + } |
| 13 | + end |
| 14 | + let(:request_query) { { original_id: original_project.identifier, is_remix: '1' } } |
| 15 | + let(:scratch_project) do |
| 16 | + { |
| 17 | + meta: { semver: '3.0.0' }, |
| 18 | + targets: ['updated target'], |
| 19 | + monitors: [], |
| 20 | + extensions: ['pen'] |
| 21 | + } |
| 22 | + end |
| 23 | + let(:lesson) { create(:lesson, school:, user_id: teacher.id) } |
| 24 | + let(:original_project) do |
| 25 | + create( |
| 26 | + :project, |
| 27 | + school:, |
| 28 | + lesson:, |
| 29 | + user_id: teacher.id, |
| 30 | + project_type: Project::Types::CODE_EDITOR_SCRATCH, |
| 31 | + locale: nil |
| 32 | + ) |
| 33 | + end |
10 | 34 |
|
11 | 35 | before do |
| 36 | + mock_phrase_generation('new-project-id') |
| 37 | + create(:scratch_component, project: original_project) |
| 38 | + |
12 | 39 | Flipper.disable :cat_mode |
13 | 40 | Flipper.disable_actor :cat_mode, school |
14 | 41 | end |
15 | 42 |
|
| 43 | + def make_request(query: request_query, request_headers: headers, request_params: scratch_project) |
| 44 | + post( |
| 45 | + "/api/scratch/projects?#{Rack::Utils.build_query(query)}", |
| 46 | + params: request_params, |
| 47 | + headers: request_headers, |
| 48 | + as: :json |
| 49 | + ) |
| 50 | + end |
| 51 | + |
16 | 52 | it 'responds 401 Unauthorized when no cookie is provided' do |
17 | | - post '/api/scratch/projects', params: params |
| 53 | + make_request(request_headers: {}) |
18 | 54 |
|
19 | 55 | expect(response).to have_http_status(:unauthorized) |
20 | 56 | end |
21 | 57 |
|
22 | 58 | it 'responds 404 Not Found when cat_mode is not enabled' do |
23 | 59 | authenticated_in_hydra_as(teacher) |
24 | 60 |
|
25 | | - post '/api/scratch/projects', params: params, headers: cookie_headers |
| 61 | + make_request |
26 | 62 |
|
27 | 63 | expect(response).to have_http_status(:not_found) |
28 | 64 | end |
29 | 65 |
|
30 | | - it 'responds 403 Forbidden when not remixing' do |
31 | | - authenticated_in_hydra_as(teacher) |
32 | | - Flipper.enable_actor :cat_mode, school |
| 66 | + context 'when authenticated and cat_mode is enabled' do |
| 67 | + before do |
| 68 | + authenticated_in_hydra_as(teacher) |
| 69 | + Flipper.enable_actor :cat_mode, school |
| 70 | + end |
33 | 71 |
|
34 | | - post '/api/scratch/projects', params: params.merge(is_remix: '0'), headers: cookie_headers |
| 72 | + it 'responds 403 Forbidden when not remixing' do |
| 73 | + make_request(query: request_query.merge(is_remix: '0')) |
35 | 74 |
|
36 | | - expect(response).to have_http_status(:forbidden) |
37 | | - end |
| 75 | + expect(response).to have_http_status(:forbidden) |
| 76 | + end |
38 | 77 |
|
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 |
| 78 | + it 'responds 403 Forbidden when original_id is missing' do |
| 79 | + make_request(query: { is_remix: '1' }) |
| 80 | + |
| 81 | + expect(response).to have_http_status(:forbidden) |
| 82 | + end |
| 83 | + |
| 84 | + it 'responds 404 Not Found when original project does not exist' do |
| 85 | + make_request(query: { original_id: 'no-such-project', is_remix: '1' }) |
| 86 | + |
| 87 | + expect(response).to have_http_status(:not_found) |
| 88 | + end |
| 89 | + |
| 90 | + it 'responds 404 Not Found when the original project is not a Scratch project' do |
| 91 | + non_scratch_project = create(:project, school:, lesson:, user_id: teacher.id, locale: nil) |
| 92 | + |
| 93 | + make_request(query: { original_id: non_scratch_project.identifier, is_remix: '1' }) |
| 94 | + |
| 95 | + expect(response).to have_http_status(:not_found) |
| 96 | + end |
| 97 | + |
| 98 | + it 'responds 401 Unauthorized when the user cannot access the original project' do |
| 99 | + inaccessible_project = create(:project, project_type: Project::Types::CODE_EDITOR_SCRATCH, locale: nil) |
| 100 | + create(:scratch_component, project: inaccessible_project) |
| 101 | + |
| 102 | + make_request(query: { original_id: inaccessible_project.identifier, is_remix: '1' }) |
| 103 | + |
| 104 | + expect(response).to have_http_status(:unauthorized) |
| 105 | + end |
| 106 | + |
| 107 | + it 'responds 400 Bad Request when no Scratch content is submitted' do |
| 108 | + make_request(request_params: {}) |
| 109 | + |
| 110 | + expect(response).to have_http_status(:bad_request) |
| 111 | + end |
42 | 112 |
|
43 | | - post '/api/scratch/projects', params: params, headers: cookie_headers |
| 113 | + it 'creates a remix, associates it to the current user, and returns the new identifier' do |
| 114 | + expect { make_request }.to change(Project, :count).by(1) |
44 | 115 |
|
45 | | - expect(response).to have_http_status(:ok) |
| 116 | + expect(response).to have_http_status(:ok) |
| 117 | + expect(response.parsed_body).to eq( |
| 118 | + 'status' => 'ok', |
| 119 | + 'content-name' => 'new-project-id' |
| 120 | + ) |
46 | 121 |
|
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') |
| 122 | + remixed_project = Project.find_by!(identifier: 'new-project-id') |
| 123 | + expect(remixed_project.user_id).to eq(teacher.id) |
| 124 | + expect(remixed_project.remixed_from_id).to eq(original_project.id) |
| 125 | + expect(remixed_project.lesson_id).to be_nil |
| 126 | + expect(remixed_project.scratch_component.content.to_h).to eq(scratch_project.deep_stringify_keys) |
| 127 | + end |
50 | 128 | end |
51 | 129 | end |
0 commit comments