Skip to content

Commit

Permalink
Merge pull request #691 from djberg96/zones_post_actions
Browse files Browse the repository at this point in the history
Allow Zones to be edited, deleted
  • Loading branch information
lpichler authored Oct 24, 2019
2 parents 7f3257d + 110b267 commit e9b1b2c
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 8 deletions.
28 changes: 28 additions & 0 deletions app/controllers/api/zones_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,32 @@
module Api
class ZonesController < BaseController
INVALID_ZONES_ATTRS = ID_ATTRS + %w[created_on updated_on].freeze

# Edit an existing zone. Certain fields are meant for internal use only
# and may not be edited. Attempting to edit one of the forbidden fields
# will result in a bad request error.
#
def edit_resource(type, id, data)
bad_attrs = data_includes_invalid_attrs(data)

if bad_attrs.present?
msg = "Attribute(s) '#{bad_attrs}' should not be specified for updating a zone resource"
raise BadRequestError, msg
end

super
end

private

# Check to see if any of the data attributes contain an invalid field.
# Returns a list of invalid fields as a comma separated string that you
# can use for error messages, or nil if the data argument is blank.
#
def data_includes_invalid_attrs(data)
return nil unless data

data.keys.select { |key| INVALID_ZONES_ATTRS.include?(key) }.compact.join(", ")
end
end
end
11 changes: 4 additions & 7 deletions config/api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4196,7 +4196,7 @@
- :collection
:subcollections:
- :settings
:verbs: *gp
:verbs: *gpd
:klass: Zone
:collection_actions:
:get:
Expand All @@ -4205,24 +4205,21 @@
:post:
- :name: query
:identifier: zone
- :name: add
- :name: create
:identifier: zone_new
:disabled: true
- :name: edit
:identifier: zone_edit
:disabled: true
- :name: delete
:identifier: zone_delete
:disabled: true
:resource_actions:
:get:
- :name: read
:identifier: zone
:post:
- :name: edit
:identifier: zone_edit
:disabled: true
- :name: delete
:identifier: zone_delete
:delete:
- :name: delete
:identifier: zone_delete
:disabled: true
140 changes: 139 additions & 1 deletion spec/requests/zones_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,145 @@
RSpec.describe "Zones" do
let(:zone) { FactoryBot.create(:zone) }

describe "/api/zones/:id?expand=settings" do
context "authorization", :authorization do
it "forbids access to zones without an appropriate role" do
api_basic_authorize

get(api_zones_url)

expect(response).to have_http_status(:forbidden)
end

it "forbids access to a zone resource without an appropriate role" do
api_basic_authorize

get(api_zone_url(nil, zone))

expect(response).to have_http_status(:forbidden)
end
end

context "get", :get do
it "allows GETs of a zone" do
api_basic_authorize action_identifier(:zones, :read, :resource_actions, :get)

get(api_zone_url(nil, zone))

expect_single_resource_query(
"href" => api_zone_url(nil, zone),
"id" => zone.id.to_s
)
end
end

context "edit", :edit do
it "will fail if you try to edit forbidden fields" do
api_basic_authorize action_identifier(:zones, :edit)

zone = FactoryBot.create(:zone, :description => "Current Zone description")

post api_zone_url(nil, zone), :params => gen_request(:edit, :created_on => Time.now.utc)
expect_bad_request("Attribute(s) 'created_on' should not be specified for updating a zone resource")

post api_zone_url(nil, zone), :params => gen_request(:edit, :updated_on => Time.now.utc)
expect_bad_request("Attribute(s) 'updated_on' should not be specified for updating a zone resource")
end

it "can update multiple zones with POST" do
api_basic_authorize action_identifier(:zones, :edit)

zone1 = FactoryBot.create(:zone, :description => "Test Zone 1")
zone2 = FactoryBot.create(:zone, :description => "Test Zone 2")

options = [
{"href" => api_zone_url(nil, zone1), "description" => "Updated Test Zone 1"},
{"href" => api_zone_url(nil, zone2), "description" => "Updated Test Zone 2"}
]

post api_zones_url, :params => gen_request(:edit, options)

expect(response).to have_http_status(:ok)

expect_results_to_match_hash(
"results",
[
{"id" => zone1.id.to_s, "description" => "Updated Test Zone 1"},
{"id" => zone2.id.to_s, "description" => "Updated Test Zone 2"}
]
)

expect(zone1.reload.description).to eq("Updated Test Zone 1")
expect(zone2.reload.description).to eq("Updated Test Zone 2")
end

it "will fail to update multiple zones if any forbidden fields are edited" do
api_basic_authorize action_identifier(:zones, :edit)

zone1 = FactoryBot.create(:zone, :description => "Test Zone 1")
zone2 = FactoryBot.create(:zone, :description => "Test Zone 2")

options = [
{"href" => api_zone_url(nil, zone1), "description" => "New description"},
{"href" => api_zone_url(nil, zone2), "created_on" => Time.now.utc}
]

post api_zones_url, :params => gen_request(:edit, options)

expect_bad_request("Attribute(s) 'created_on' should not be specified for updating a zone resource")
end

it "forbids edit of a zone without an appropriate role" do
api_basic_authorize

zone = FactoryBot.create(:zone, :description => "Current Zone description")

post api_zone_url(nil, zone), :params => gen_request(:edit, :description => "New Zone description")

expect(response).to have_http_status(:forbidden)
end
end

context "delete", :delete do
it "can delete a zone with POST" do
api_basic_authorize action_identifier(:zones, :delete)
zone = FactoryBot.create(:zone)

expect { post api_zone_url(nil, zone), :params => gen_request(:delete) }.to change(Zone, :count).by(-1)
expect(response).to have_http_status(:ok)
end

it "can delete a zone with DELETE" do
api_basic_authorize action_identifier(:zones, :delete)
zone = FactoryBot.create(:zone)

expect { delete api_zone_url(nil, zone) }.to change(Zone, :count).by(-1)
expect(response).to have_http_status(:no_content)
end

it "can delete multiple zones with POST" do
api_basic_authorize action_identifier(:zones, :delete)
zones = FactoryBot.create_list(:zone, 2)

options = [
{"href" => api_zone_url(nil, zones.first)},
{"href" => api_zone_url(nil, zones.last)}
]

expect { post api_zones_url, :params => gen_request(:delete, options) }.to change(Zone, :count).by(-2)
expect(response).to have_http_status(:ok)
end

it "forbids deletion of a zone without an appropriate role" do
api_basic_authorize
zone = FactoryBot.create(:zone, :description => "Current Region description")

delete api_zone_url(nil, zone)

expect(response).to have_http_status(:forbidden)
end
end

describe "/api/zones/:id?expand=settings", :settings do
it "expands the settings subcollection" do
api_basic_authorize(action_identifier(:zones, :read, :resource_actions, :get), :ops_settings)

Expand Down

0 comments on commit e9b1b2c

Please sign in to comment.