From 5d912f55e79ec0a81b683736fb3e745fc531d7be Mon Sep 17 00:00:00 2001 From: Rick Carlino Date: Thu, 8 Jan 2015 07:08:54 -0600 Subject: [PATCH 1/4] Working on steps builder --- app/controllers/api/abstract_controller.rb | 2 +- app/mutations/sequences/create.rb | 8 +++++--- app/mutations/steps/create.rb | 3 +++ .../api/sequences/sequences_create_spec.rb | 15 +++++++++++---- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/app/controllers/api/abstract_controller.rb b/app/controllers/api/abstract_controller.rb index 7792a341f..268106c04 100644 --- a/app/controllers/api/abstract_controller.rb +++ b/app/controllers/api/abstract_controller.rb @@ -9,7 +9,7 @@ private if outcome.success? render options.merge(json: outcome) else - render options.merge(json: outcome.errors.message_list, status: 422) + render options.merge(json: outcome.errors.message, status: 422) end end diff --git a/app/mutations/sequences/create.rb b/app/mutations/sequences/create.rb index a14a9cb92..5245bd345 100644 --- a/app/mutations/sequences/create.rb +++ b/app/mutations/sequences/create.rb @@ -2,9 +2,11 @@ module Sequences class Create < Mutations::Command required do - model :user - string :name - array(:steps) { model :step, builder: Steps::Create, class: Object } + model :user + string :time_stamp + array(:steps) do + model :step, builder: Steps::Create + end end def validate diff --git a/app/mutations/steps/create.rb b/app/mutations/steps/create.rb index 50eefcef2..6c006ba29 100644 --- a/app/mutations/steps/create.rb +++ b/app/mutations/steps/create.rb @@ -3,6 +3,9 @@ module Steps required do string :message_type, in: Step::MESSAGE_TYPES + date :time_stamp + hash(:command) { :* } + model :sequence end def validate diff --git a/spec/controllers/api/sequences/sequences_create_spec.rb b/spec/controllers/api/sequences/sequences_create_spec.rb index 286ce16b5..cbb4cecdd 100644 --- a/spec/controllers/api/sequences/sequences_create_spec.rb +++ b/spec/controllers/api/sequences/sequences_create_spec.rb @@ -10,11 +10,18 @@ describe Api::SequencesController do it 'creates a new sequences for a user' do sign_in user - inputs = {name: "Scare Birds", + input = {name: "Scare Birds", steps: [{ - message_type: 'move_rel' - }]} - post :create, inputs + message_type: 'move_rel', + time_stamp: Time.now, + command: {action: 'MOVE RELATIVE', + x: 1, + y: 2, + z: 3, + speed: 100, + delay: 0}}]} + post :create, input + binding.pry expect(response.status).to eq(200) end end From 43ee0daeda110f2eaebb9acb28275ddc4602aaa3 Mon Sep 17 00:00:00 2001 From: Rick Carlino Date: Sun, 11 Jan 2015 08:47:35 -0600 Subject: [PATCH 2/4] Fixed / tested Steps::Create --- app/models/step.rb | 5 +++- app/mutations/steps/create.rb | 30 ++++++++++++++----- .../api/sequences/sequences_create_spec.rb | 2 +- spec/factories/sequences.rb | 5 ++-- spec/mutations/steps/create_spec.rb | 23 ++++++++++++++ 5 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 spec/mutations/steps/create_spec.rb diff --git a/app/models/step.rb b/app/models/step.rb index 0f096e1bb..14a34ff1d 100644 --- a/app/models/step.rb +++ b/app/models/step.rb @@ -7,6 +7,9 @@ class Step embedded_in :sequence field :message_type - field :time_stamp, type: Time + validates :message_type, presence: true + field :command, type: Hash + validates :command, presence: true + end diff --git a/app/mutations/steps/create.rb b/app/mutations/steps/create.rb index 6c006ba29..99b12b978 100644 --- a/app/mutations/steps/create.rb +++ b/app/mutations/steps/create.rb @@ -3,19 +3,35 @@ module Steps required do string :message_type, in: Step::MESSAGE_TYPES - date :time_stamp - hash(:command) { :* } + hash(:command) { model :*, class: Object } model :sequence end - def validate + def execute + create(Step, inputs) end - def execute - # STILL NEED TO: - # * Make the steps mutation create a step - # * Make the sequence mutation create one, too. + # TODO: Move this into a refinement + # This method provides a uniform way of + # 1. Creating models inside of Mutations + # 2. presenting API model validation errors unifromly. + # This is important for keeping API msgs sane. + # Returns an instance of Klass -OR- a hash of model validation err. messages + # You may optionally pass in a block to transform the model / input + # before it gets saved. + # Ex: create(User, name: 'Rick', email: "r@mailinator.com") do |user, inputs| + # inputs.email.downcase! + # user.password = "SomethingThatYouPassIn" + # end + def create(klass, inputs = {}) binding.pry + model = klass.new(inputs) + yield(model, inputs) if block_given? + if (model.valid? && model.save) + model + else + model.errors.messages + end end end end diff --git a/spec/controllers/api/sequences/sequences_create_spec.rb b/spec/controllers/api/sequences/sequences_create_spec.rb index cbb4cecdd..af59d3cde 100644 --- a/spec/controllers/api/sequences/sequences_create_spec.rb +++ b/spec/controllers/api/sequences/sequences_create_spec.rb @@ -9,6 +9,7 @@ describe Api::SequencesController do let(:user) { FactoryGirl.create(:user) } it 'creates a new sequences for a user' do + pending "Going to create mutation level tests first." sign_in user input = {name: "Scare Birds", steps: [{ @@ -21,7 +22,6 @@ describe Api::SequencesController do speed: 100, delay: 0}}]} post :create, input - binding.pry expect(response.status).to eq(200) end end diff --git a/spec/factories/sequences.rb b/spec/factories/sequences.rb index da8c5b1ab..ab3abaa4b 100644 --- a/spec/factories/sequences.rb +++ b/spec/factories/sequences.rb @@ -2,7 +2,8 @@ FactoryGirl.define do factory :sequence do - name - color + name { Faker::Company.catch_phrase } + color { Step::MESSAGE_TYPES.sample } + user end end diff --git a/spec/mutations/steps/create_spec.rb b/spec/mutations/steps/create_spec.rb new file mode 100644 index 000000000..ed84c36e4 --- /dev/null +++ b/spec/mutations/steps/create_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe Steps::Create do + let(:user) { FactoryGirl.create(:user) } + let(:mutation) { Steps::Create } + let(:valid_params) { {message_type: 'move_rel', + sequence: FactoryGirl.create(:sequence), + command: {action: 'MOVE RELATIVE', + x: 1, + y: 2, + z: 3, + speed: 100, + delay: 0}} } + + it 'Builds an instance of `step`' do + outcome = mutation.run(valid_params) + expect(outcome.success?).to be_truthy + expect(outcome.result.message_type).to eq(valid_params[:message_type]) + expect(outcome.result.sequence).to eq(valid_params[:sequence]) + cmd = outcome.result.command.deep_symbolize_keys + expect(cmd).to eq(valid_params[:command]) + end +end From 58bbb3e21e778f373d039a405434b77bb13ff409 Mon Sep 17 00:00:00 2001 From: Rick Carlino Date: Mon, 12 Jan 2015 07:14:18 -0600 Subject: [PATCH 3/4] Done with controller for sequence creation - now to make fixes for hound --- .DS_Store | Bin 15364 -> 10244 bytes app/controllers/api/sequences_controller.rb | 1 - app/mutations/sequences/create.rb | 14 ++++++---- app/mutations/steps/create.rb | 24 +--------------- app/mutations/steps/initialize.rb | 14 ++++++++++ config/application.rb | 3 +- lib/mongoid_refinements.rb | 25 +++++++++++++++++ .../api/sequences/sequences_create_spec.rb | 2 -- spec/mutations/sequences/create_spec.rb | 26 ++++++++++++++++++ 9 files changed, 76 insertions(+), 33 deletions(-) create mode 100644 app/mutations/steps/initialize.rb create mode 100644 lib/mongoid_refinements.rb create mode 100644 spec/mutations/sequences/create_spec.rb diff --git a/.DS_Store b/.DS_Store index db04a384c7c4094b429d108d2e8730771906d7d8..0d8b3ad5237225c6d37a558f7a4d8b84fc2f4a0f 100755 GIT binary patch delta 49 zcmZpvXbG6$<EdU^hQw;AS3yVoqUZh8%`WhNQCKqP(2^ymSTz2FA@blBH~$*%kh> F0|0zd6M delta 44 zcmZn(XsMXs&ls>VU^hQwz-AtSV$RJ|C5zZ57Km+TSNO}mF>x9D#)9cUe3%6QYpD>N diff --git a/app/controllers/api/sequences_controller.rb b/app/controllers/api/sequences_controller.rb index 9ed2520eb..290dd1765 100644 --- a/app/controllers/api/sequences_controller.rb +++ b/app/controllers/api/sequences_controller.rb @@ -1,4 +1,3 @@ -# Api::SequencesController performs CRUD on stored sequences module Api class SequencesController < Api::AbstractController def create diff --git a/app/mutations/sequences/create.rb b/app/mutations/sequences/create.rb index 5245bd345..c78667f0d 100644 --- a/app/mutations/sequences/create.rb +++ b/app/mutations/sequences/create.rb @@ -1,19 +1,21 @@ module Sequences class Create < Mutations::Command + using MongoidRefinements required do - model :user - string :time_stamp - array(:steps) do - model :step, builder: Steps::Create + model :user, class: User + string :name + array :steps do + model :step, builder: Steps::Initialize, new_records: true end end - def validate + optional do + string :color, in: Sequence::COLORS end def execute - {} + create(Sequence, inputs) end end end diff --git a/app/mutations/steps/create.rb b/app/mutations/steps/create.rb index 99b12b978..112d3d545 100644 --- a/app/mutations/steps/create.rb +++ b/app/mutations/steps/create.rb @@ -1,5 +1,6 @@ module Steps class Create < Mutations::Command + using MongoidRefinements required do string :message_type, in: Step::MESSAGE_TYPES @@ -10,28 +11,5 @@ module Steps def execute create(Step, inputs) end - - # TODO: Move this into a refinement - # This method provides a uniform way of - # 1. Creating models inside of Mutations - # 2. presenting API model validation errors unifromly. - # This is important for keeping API msgs sane. - # Returns an instance of Klass -OR- a hash of model validation err. messages - # You may optionally pass in a block to transform the model / input - # before it gets saved. - # Ex: create(User, name: 'Rick', email: "r@mailinator.com") do |user, inputs| - # inputs.email.downcase! - # user.password = "SomethingThatYouPassIn" - # end - def create(klass, inputs = {}) - binding.pry - model = klass.new(inputs) - yield(model, inputs) if block_given? - if (model.valid? && model.save) - model - else - model.errors.messages - end - end end end diff --git a/app/mutations/steps/initialize.rb b/app/mutations/steps/initialize.rb new file mode 100644 index 000000000..f6608fd92 --- /dev/null +++ b/app/mutations/steps/initialize.rb @@ -0,0 +1,14 @@ +module Steps + # Initializes a Step _BUT DOES NOT PERSIST TO THE DATABASE_. This is useful + # When you are creating a yet-to-be-saved Sequence and need to embed Steps. + class Initialize < Mutations::Command + required do + string :message_type, in: Step::MESSAGE_TYPES + hash(:command) { model :*, class: Object } + end + + def execute + Step.new inputs + end + end +end diff --git a/config/application.rb b/config/application.rb index 664b12e5c..df2d500aa 100755 --- a/config/application.rb +++ b/config/application.rb @@ -11,6 +11,7 @@ require "sprockets/railtie" # you've limited to :test, :development, or :production. Bundler.require(:default, Rails.env) +# TODO: Rename this from DSS to Farmbot or something like that. module Dss class Application < Rails::Application # Settings in config/environments/* take precedence over those specified @@ -33,6 +34,6 @@ module Dss g.helper_specs false g.fixture_replacement :factory_girl, :dir => 'spec/factories' end - + config.autoload_paths << Rails.root.join('lib') end end diff --git a/lib/mongoid_refinements.rb b/lib/mongoid_refinements.rb new file mode 100644 index 000000000..e1bb8d71a --- /dev/null +++ b/lib/mongoid_refinements.rb @@ -0,0 +1,25 @@ +# A set of refinements that help the mutations gem deal with Mongoid +module MongoidRefinements + refine Mutations::Command do + # This method provides a uniform way of ================================== + # 1. Creating models inside of Mutations + # 2. presenting API model validation errors unifromly. + # This is important for keeping API msgs sane. + # Returns an instance of Klass -OR- a hash of model validation err. + # messages You may optionally pass in a block to transform the model/input + # before it gets saved. + # Ex: create(User, name: 'Rick', email: "r@m.com") do |user, inputs| + # inputs.email.downcase! + # user.password = "SomethingThatYouPassIn" + # end # ============================================================== + def create(klass, inputs = {}) + model = klass.new(inputs) + yield(model, inputs) if block_given? + if (model.valid? && model.save) + model + else + model.errors.messages + end + end + end +end diff --git a/spec/controllers/api/sequences/sequences_create_spec.rb b/spec/controllers/api/sequences/sequences_create_spec.rb index af59d3cde..fc99d937f 100644 --- a/spec/controllers/api/sequences/sequences_create_spec.rb +++ b/spec/controllers/api/sequences/sequences_create_spec.rb @@ -9,12 +9,10 @@ describe Api::SequencesController do let(:user) { FactoryGirl.create(:user) } it 'creates a new sequences for a user' do - pending "Going to create mutation level tests first." sign_in user input = {name: "Scare Birds", steps: [{ message_type: 'move_rel', - time_stamp: Time.now, command: {action: 'MOVE RELATIVE', x: 1, y: 2, diff --git a/spec/mutations/sequences/create_spec.rb b/spec/mutations/sequences/create_spec.rb new file mode 100644 index 000000000..09f36bfe8 --- /dev/null +++ b/spec/mutations/sequences/create_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe Steps::Create do + let(:user) { FactoryGirl.create(:user) } + let(:mutation) { Sequences::Create } + let(:step) { {message_type: 'move_rel', + command: {action: 'MOVE RELATIVE', + x: 1, + y: 2, + z: 3, + speed: 100, + delay: 0}} } + let(:valid_params) { {user: user, + name: 'Hi.', + steps: [step]} } + + it 'Builds a `sequence`' do + outcome = mutation.run(valid_params) + expect(outcome.success?).to be_truthy + seq = outcome.result + + expect(seq.steps.count).to eq(1) + expect(seq.name).to eq('Hi.') + expect(seq.user).to eq(user) + end +end From edfcad11fa7be483598ac7af62346496439123f8 Mon Sep 17 00:00:00 2001 From: Rick Carlino Date: Mon, 12 Jan 2015 07:23:41 -0600 Subject: [PATCH 4/4] Changes for hound --- app/models/step.rb | 1 - lib/mongoid_refinements.rb | 2 +- .../api/sequences/sequences_create_spec.rb | 17 ++++++------- spec/mutations/sequences/create_spec.rb | 25 +++++++++++-------- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/app/models/step.rb b/app/models/step.rb index 14a34ff1d..bae4aceb8 100644 --- a/app/models/step.rb +++ b/app/models/step.rb @@ -11,5 +11,4 @@ class Step field :command, type: Hash validates :command, presence: true - end diff --git a/lib/mongoid_refinements.rb b/lib/mongoid_refinements.rb index e1bb8d71a..6cd227163 100644 --- a/lib/mongoid_refinements.rb +++ b/lib/mongoid_refinements.rb @@ -15,7 +15,7 @@ module MongoidRefinements def create(klass, inputs = {}) model = klass.new(inputs) yield(model, inputs) if block_given? - if (model.valid? && model.save) + if model.valid? && model.save model else model.errors.messages diff --git a/spec/controllers/api/sequences/sequences_create_spec.rb b/spec/controllers/api/sequences/sequences_create_spec.rb index fc99d937f..08c7af7fc 100644 --- a/spec/controllers/api/sequences/sequences_create_spec.rb +++ b/spec/controllers/api/sequences/sequences_create_spec.rb @@ -10,15 +10,14 @@ describe Api::SequencesController do it 'creates a new sequences for a user' do sign_in user - input = {name: "Scare Birds", - steps: [{ - message_type: 'move_rel', - command: {action: 'MOVE RELATIVE', - x: 1, - y: 2, - z: 3, - speed: 100, - delay: 0}}]} + input = { name: "Scare Birds", + steps: [{ message_type: 'move_rel', + command: { action: 'MOVE RELATIVE', + x: 1, + y: 2, + z: 3, + speed: 100, + delay: 0} }] } post :create, input expect(response.status).to eq(200) end diff --git a/spec/mutations/sequences/create_spec.rb b/spec/mutations/sequences/create_spec.rb index 09f36bfe8..689831d4c 100644 --- a/spec/mutations/sequences/create_spec.rb +++ b/spec/mutations/sequences/create_spec.rb @@ -3,16 +3,21 @@ require 'spec_helper' describe Steps::Create do let(:user) { FactoryGirl.create(:user) } let(:mutation) { Sequences::Create } - let(:step) { {message_type: 'move_rel', - command: {action: 'MOVE RELATIVE', - x: 1, - y: 2, - z: 3, - speed: 100, - delay: 0}} } - let(:valid_params) { {user: user, - name: 'Hi.', - steps: [step]} } + let(:step) do + { message_type: 'move_rel', + command: { action: 'MOVE RELATIVE', + x: 1, + y: 2, + z: 3, + speed: 100, + delay: 0 } } + end + + let(:valid_params) do + { user: user, + name: 'Hi.', + steps: [step] } + end it 'Builds a `sequence`' do outcome = mutation.run(valid_params)