Tests for PointGroup#create

pull/1351/head
Rick Carlino 2019-08-05 13:27:16 -05:00
parent 99e192c8df
commit 9676a32459
7 changed files with 77 additions and 15 deletions

View File

@ -6,10 +6,6 @@ module Api
render json: your_point_groups
end
def show
render json: the_point_group
end
def create
mutate PointGroups::Create.run(raw_json, point_group_params)
end
@ -29,7 +25,7 @@ module Api
end
def your_point_groups
PointGroup.where(point_group_params)
PointGroup.preload(:point_group_items).where(point_group_params)
end
def point_group_params

View File

@ -9,7 +9,6 @@ module PointGroups
end
def validate
point_ids.sort!
validate_point_ids
end

View File

@ -7,7 +7,7 @@ module PointGroups
end
def validate_point_ids
unless point_ids == points.pluck(:id).sort
unless point_ids.sort! == points.pluck(:id).sort
add_error :points, :points_bad, BAD_POINT_IDS
end
end

View File

@ -1,11 +1,51 @@
module PointGroups
class Update < Mutations::Command
include PointGroups::Helpers
required do
model :device, class: Device
model :point_group, class: PointGroup
end
optional do
string :name
array :point_ids, class: Integer
end
def validate
validate_point_ids if point_ids.any?
end
def execute
raise "Not yet implemented"
PointGroup.transaction do
PointGroup.transaction do
maybe_reconcile_points
point_group.update_attributes!(update_attributes)
point_group.reload
end
end
end
private
def update_attributes
@update_attributes ||= inputs.slice(:name).merge(updated_at: Time.now)
end
def maybe_reconcile_points
# STEP 0: Setup
old_point_ids = Set.new(point_group.point_group_items.pluck(:point_id))
new_point_ids = Set.new(point_ids)
dont_delete = new_point_ids & old_point_ids
do_delete = (old_point_ids - dont_delete).to_a
# STEP 1: "Garbage Collection" of PGIs that are no longer used.
PointGroupItem.find_by!(id: do_delete).destroy!
# STEP 2: Create missing PGIs
PointGroupItem.create!((new_point_ids - dont_delete).to_a.map do |id|
{ point_id: id, point_group_id: point_group.id }
end)
end
end
end

View File

@ -2,10 +2,6 @@ class PointGroupSerializer < ApplicationSerializer
attributes :name, :point_ids
def point_ids
if object.association_cached?(:point_group_items)
object.point_group_items.pluck(:point_id)
else
raise "N+1 Detected in PointGroupSerializer"
end
object.point_group_items.pluck(:point_id)
end
end

View File

@ -17,7 +17,7 @@ FarmBot::Application.routes.draw do
peripherals: [:create, :destroy, :index, :show, :update],
pin_bindings: [:create, :destroy, :index, :show, :update],
plant_templates: [:create, :destroy, :index, :update],
point_groups: [:create, :destroy, :index, :update],
point_groups: [:index, :create, :update, :destroy],
regimens: [:create, :destroy, :index, :show, :update],
sensor_readings: [:create, :destroy, :index, :show],
sensors: [:create, :destroy, :index, :show, :update],

View File

@ -2,8 +2,39 @@ require "spec_helper"
describe Api::PointGroupsController do
include Devise::Test::ControllerHelpers
def rando_points
[
:tool_slot,
:generic_pointer,
:plant,
].map { |x| FactoryBot.create(x, device: device).id }.sort
end
let(:user) { FactoryBot.create(:user) }
let(:device) { user.device }
it "updates point groups"
let(:old_point_ids) do rando_points end
let(:pg) do
PointGroups::Create.run!(device: device,
point_ids: old_point_ids,
name: "PointGroups::Update test")
end
it "updates point groups" do
sign_in user
do_delete = old_point_ids[0]
dont_delete = [old_point_ids[1], old_point_ids[2]]
new_point_ids = rando_points + dont_delete
payload = { name: "new name",
point_ids: new_point_ids }
put :update, body: payload.to_json, format: :json, params: { id: pg.id }
expect(response.status).to eq(200)
expect(PointGroupItem.exists?(do_delete)).to be false
dont_delete.map { |id| expect(PointGroupItem.exists?(id)).to be(true) }
expect(json[:point_ids].count).to eq(new_point_ids.count)
expect(json.fetch(:name)).to eq "new name"
expect(new_point_ids.to_set).to eq(json.fetch(:point_ids).to_set)
end
end