connor rigby 2016-12-27 06:26:16 -08:00
commit 1c3657ee5b
13 changed files with 133 additions and 51 deletions

View File

@ -30,11 +30,16 @@ private
# the way we do things right now. We used to just use the params
# object (it was a hash), but now it is a proper object.
def raw_json
@raw_json ||= JSON.parse(request.body.read)
@raw_json ||= JSON.parse(request.body.read).tap{ |x| symbolize(x) }
rescue JSON::ParserError => e
raise OnlyJson
end
# Just a hack to prevent runtime errors when people POST JSON arrays.
def symbolize(x)
x.is_a?(Array) ? x.map(&:deep_symbolize_keys!) : x.deep_symbolize_keys!
end
def set_default_response_format
request.format = "json"
end

View File

@ -14,11 +14,11 @@ module Api
end
def create
mutate Sequences::Create.run(sequence_i_guess, device: current_device)
mutate Sequences::Create.run(sequence_params, device: current_device)
end
def update
mutate Sequences::Update.run(sequence_i_guess, # params[:sequence].as_json,
mutate Sequences::Update.run(sequence_params, # params[:sequence].as_json,
device: current_device,
sequence: sequence)
end
@ -34,15 +34,8 @@ module Api
# TODO: Come back and fix this. Rails 5 has changed the way it handles
# params.
def sequence_i_guess
if @seq_i_guess
return @seq_i_guess
else
js = JSON.parse(request.body.read);
@seq_i_guess ||= js["sequence"] || js || {}
end
rescue JSON::ParserError => e
raise OnlyJson
def sequence_params
@seq_i_guess ||= raw_json[:sequence] || raw_json || {}
end
def sequence

View File

@ -2,17 +2,21 @@ module Api
class ToolSlotsController < Api::AbstractController
def create
mutate ToolSlots::Create.run(tool_slot_params)
if raw_json && raw_json[:tool_slots]
mutate ToolSlots::BatchUpdate.run(raw_json, device: current_device)
else
mutate ToolSlots::Create.run(tool_slot_params)
end
end
def show
render json: tool_slot
end
def index
render json: tool_slots
end
def update
mutate ToolSlots::Update.run(tool_slot_params)
end
@ -21,7 +25,7 @@ module Api
tool_slot.destroy!
render json: ""
end
private
def tool_slots
@ -32,25 +36,11 @@ module Api
@tool_slot ||= tool_slots.find(params[:id])
end
def maybe_add(name)
@tool_slot_params[name] = params[name] if params[name]
end
def tool_slot_params
if @tool_slot_params
@tool_slot_params
else
@tool_slot_params = {device: current_device}
@tool_slot_params[:tool_slot] = tool_slot if params[:id]
maybe_add :name
maybe_add :x
maybe_add :y
maybe_add :z
maybe_add :tool_bay_id
maybe_add :tool_id
@tool_slot_params
end
@tool_slot_params ||= raw_json
.merge({ device: current_device,
tool_slot: (params[:id] ? tool_slot : nil)
}).compact
end
end
end

View File

@ -14,7 +14,11 @@ module Api
end
def create
mutate Tools::Create.run(create_params)
if raw_json[:tools]
mutate Tools::BatchUpdate.run(raw_json, device: current_device)
else
mutate Tools::Create.run(create_params)
end
end
def update

View File

@ -9,8 +9,8 @@ module CeleryScriptSettingsBag
ALLOWED_OPS = %w(< > is not)
STEPS = %w(move_absolute move_relative write_pin read_pin wait
send_message execute if_statement)
ALLOWED_LHS = %w(busy pin0 pin1 pin2 pin3 pin4 pin5 pin6 pin7 pin8
pin9 pin10 pin11 pin12 pin13 x y z)
ALLOWED_LHS = %w(pin0 pin1 pin2 pin3 pin4 pin5 pin6 pin7 pin8 pin9
pin10 pin11 pin12 pin13 x y z)
BAD_ALLOWED_PIN_MODES = 'Can not put "%s" into a left hand side (LHS) '\
'argument. Allowed values: %s'
BAD_LHS = 'Can not put "%s" into a left hand side (LHS) '\

View File

@ -1,4 +1,9 @@
class ToolSlot < ApplicationRecord
belongs_to :tool
belongs_to :tool_bay
validates_uniqueness_of :tool,
allow_blank: true,
allow_nil: true,
scope: :tool_bay_id,
message: "already in use by another tool slot"
end

View File

@ -0,0 +1,37 @@
module ToolSlots
class BatchUpdate < Mutations::Command
class Fail < Exception; end;
required do
model :device, class: Device
array :tool_slots do
hash do
required do
integer :id
end
optional do
string :name
integer :x
integer :y
integer :z
integer :tool_id
end
end
end
end
def execute
ToolSlot.transaction do
tool_slots.map { |p| update_tool_slot(p) }
end
end
private
def update_tool_slot(params)
ts = ToolSlot.find(params.delete(:id))
ts.update_attributes!(params) && ts
end
end
end

View File

@ -0,0 +1,33 @@
module Tools
class BatchUpdate < Mutations::Command
class Fail < Exception; end;
required do
model :device, class: Device
array :tools do
hash do
required do
integer :id
end
optional do
string :name
end
end
end
end
def execute
Tool.transaction do
tools.map { |p| update_tool(p) }
end
end
private
def update_tool(params)
t = Tool.find(params.delete(:id))
t.update_attributes!(params) && t
end
end
end

View File

@ -22,10 +22,6 @@ FarmBot::Application.routes.draw do
:destroy, :update]
resources :tools, only: [:create, :show, :index,
:destroy, :update]
# TODO: Why does Rails hate JWTs as an ID?
# JWTs are supposed to be URL safe, I thought?
# This is a hack to get around 404 errors caused by
# PUTing a JWT to api/password_resets/MY_JWT_HERE
put "/password_resets" => "password_resets#update", as: :whatever
put "/users/verify/:token" => "users#verify", as: :users_verify
end

View File

@ -30,7 +30,6 @@ describe Api::SequencesController do
sequence = FactoryGirl.create(:sequence, device: user.device)
input = { sequence: { name: "Scare Birds" } }
params = { id: sequence.id }
patch :update,
params: params,
body: input.to_json,

View File

@ -0,0 +1,20 @@
require 'spec_helper'
describe Api::ToolSlotsController do
include Devise::Test::ControllerHelpers
describe 'batch updates' do
let(:user) { FactoryGirl.create(:user) }
let!(:tool_slots) { FactoryGirl.create_list(:tool_slot, 3) }
it 'updates a list of tool slots' do
sign_in user
payload = [ {id: tool_slots[0].id, name: "first"},
{id: tool_slots[1].id, name: "second"},
{id: tool_slots[2].id, name: "third"} ]
post :create, body: {tool_slots: payload}.to_json, format: :json
expect(response.status).to eq(200)
expect(json[1][:name]).to eq("second")
expect(ToolSlot.find(json[1][:id]).reload.name).to eq("second")
end
end
end

View File

@ -14,15 +14,15 @@ describe Api::ToolSlotsController do
y: 5,
z: 6 }
before = ToolSlot.count
post :create, params: payload
post :create, body: payload.to_json, format: :json
after = ToolSlot.count
expect(before).to be < after
expect(response.status).to eq(200)
expect(json[:name]).to eq(payload[:name])
expect(json[:x]).to eq(payload[:x])
expect(json[:y]).to eq(payload[:y])
expect(json[:z]).to eq(payload[:z])
expect(json[:tool_bay_id]).to eq(payload[:tool_bay_id])
expect(json[:name]).to eq(payload[:name])
expect(json[:x]).to eq(payload[:x])
expect(json[:y]).to eq(payload[:y])
expect(json[:z]).to eq(payload[:z])
expect(json[:tool_bay_id]).to eq(payload[:tool_bay_id])
end
end
end

View File

@ -9,13 +9,13 @@ describe Api::ToolSlotsController do
it 'updates a tool slot' do
sign_in user
payload = { name: "Fooo", id: tool_slot.id }
payload = { name: "Fooo" }
expect(tool_slot.name).not_to eq(payload[:name])
patch :update, params: payload
patch :update, body: payload.to_json, params: {id: tool_slot.id}
tool_slot.reload
expect(response.status).to eq(200)
expect(tool_slot.name).to eq(payload[:name])
expect(json[:name]).to eq(payload[:name])
expect(json[:name]).to eq(payload[:name])
end
end
end