diff --git a/app/concepts/project/operation/create.rb b/app/concepts/project/operation/create.rb index 7fd25a6a..2fa9da92 100644 --- a/app/concepts/project/operation/create.rb +++ b/app/concepts/project/operation/create.rb @@ -5,16 +5,32 @@ module Operation class Create require 'operation_response' - def self.call(user_id:) - response = OperationResponse.new - response[:project] = Project.new(user_id: user_id, project_type: 'python') - response[:project].components.build(name: 'main', extension: 'py', default: true, index: 0) - response[:project].save! - response - rescue StandardError - # TODO: log error - response[:error] = 'Error creating project' - response + DEFAULT_COMPONENT = { name: 'main', extension: 'py', default: true, index: 0 }.freeze + DEFAULT_PROJECT = { type: 'python', name: 'Untitled project', components: [DEFAULT_COMPONENT], + image_list: [] }.freeze + + class << self + def call(user_id:, params:) + response = OperationResponse.new + + project = DEFAULT_PROJECT.merge( + params.deep_transform_keys do |key| + key.to_sym + rescue StandardError + key + end + ) + new_project = Project.new(project_type: project[:type], user_id: user_id, name: project[:name]) + new_project.components.build(project[:components]) + + response[:project] = new_project + response[:project].save! + response + rescue StandardError + # TODO: log error + response[:error] = 'Error creating project' + response + end end end end diff --git a/app/controllers/api/projects_controller.rb b/app/controllers/api/projects_controller.rb index 16ff795a..76799e48 100644 --- a/app/controllers/api/projects_controller.rb +++ b/app/controllers/api/projects_controller.rb @@ -17,7 +17,7 @@ def show end def create - result = Project::Operation::Create.call(user_id: current_user) + result = Project::Operation::Create.call(params: project_params, user_id: current_user) if result.success? @project = result[:project] @@ -53,9 +53,8 @@ def load_projects end def project_params - params.require(:project) - .permit(:name, - components: %i[id name extension content index]) + params.permit(project: [:name, :type, :image_list, + { components: %i[id name extension content index default] }]).fetch(:project, {}) end end end diff --git a/db/schema.rb b/db/schema.rb index bfbd2fb2..468f8e24 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,8 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_03_11_121518) do - +ActiveRecord::Schema[7.0].define(version: 2022_03_11_121518) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -21,7 +20,7 @@ t.string "record_type", null: false t.uuid "record_id", null: false t.uuid "blob_id", null: false - t.datetime "created_at", precision: 6, null: false + t.datetime "created_at", null: false t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true end @@ -34,7 +33,7 @@ t.string "service_name", null: false t.bigint "byte_size", null: false t.string "checksum" - t.datetime "created_at", precision: 6, null: false + t.datetime "created_at", null: false t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true end @@ -49,8 +48,8 @@ t.string "name", null: false t.string "extension", null: false t.string "content" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "index" t.boolean "default", default: false, null: false t.index ["index", "project_id"], name: "index_components_on_index_and_project_id", unique: true @@ -62,8 +61,8 @@ t.string "name" t.string "identifier", null: false t.string "project_type", default: "python", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.uuid "remixed_from_id" t.index ["identifier"], name: "index_projects_on_identifier", unique: true t.index ["remixed_from_id"], name: "index_projects_on_remixed_from_id" diff --git a/spec/concepts/project/operation/create_spec.rb b/spec/concepts/project/operation/create_spec.rb index d6823c95..afd19fa0 100644 --- a/spec/concepts/project/operation/create_spec.rb +++ b/spec/concepts/project/operation/create_spec.rb @@ -3,9 +3,10 @@ require 'rails_helper' RSpec.describe Project::Operation::Create, type: :unit do - subject(:create_project) { described_class.call(user_id: user_id) } + subject(:create_project) { described_class.call(user_id: user_id, params: project_params) } let(:user_id) { 'e0675b6c-dc48-4cd6-8c04-0f7ac05af51a' } + let(:project_params) { {} } before do mock_phrase_generation @@ -37,6 +38,34 @@ expect(attrs).to eq(expected) end + context 'when initial project present' do + subject(:create_project_with_content) { described_class.call(user_id: user_id, params: project_params) } + + let(:project_params) do + { + type: 'python', + components: [ + { + name: 'main', + extension: 'py', + content: 'print("hello world")', + index: 0, + default: true + } + ] + } + end + + it 'returns success' do + expect(create_project_with_content.success?).to eq(true) + end + + it 'returns project with correct component content' do + new_project = create_project_with_content[:project] + expect(new_project.components.first.content).to eq('print("hello world")') + end + end + context 'when creation fails' do before do mock_project = instance_double(Project)