Skip to content

Commit

Permalink
Add a new endpoint to unreserve a path
Browse files Browse the repository at this point in the history
This adds a new command to unreserve (destroy) a PathReservation,
provided the reservation exists and matches the given publishing app.
  • Loading branch information
Ben Thorner committed Mar 15, 2019
1 parent 0b1cdab commit f0f7207
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 0 deletions.
30 changes: 30 additions & 0 deletions app/commands/unreserve_path.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module Commands
class UnreservePath < BaseCommand
def call
reservation = lookup_reservation
check_is_owned_by_app(reservation)
reservation.destroy
Success.new(payload)
end

private

def lookup_reservation
PathReservation.find_by!(
base_path: payload[:base_path]
)
rescue ActiveRecord::RecordNotFound
msg = "#{payload[:base_path]} is not reserved"
raise CommandError.new(code: 404, message: msg)
end

def check_is_owned_by_app(reservation)
publishing_app = payload[:publishing_app]
base_path = payload[:base_path]
return if reservation.publishing_app == publishing_app

msg = "#{base_path} is reserved by #{reservation.publishing_app}"
raise CommandError.new(code: 422, message: msg)
end
end
end
5 changes: 5 additions & 0 deletions app/controllers/path_reservations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ def reserve_path
render status: response.code, json: response
end

def unreserve_path
response = Commands::UnreservePath.call(path_item)
render status: response.code, json: response
end

private

def path_item
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def content_id_constraint(request)
delete "/publish-intent(/*base_path)", to: "publish_intents#destroy"

put "/paths(/*base_path)", to: "path_reservations#reserve_path"
delete "/paths(/*base_path)", to: "path_reservations#unreserve_path"

post '/lookup-by-base-path', to: 'lookups#by_base_path'

Expand Down
24 changes: 24 additions & 0 deletions doc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ message queue for other apps (e.g. `email-alert-service`) to consume.
- [`POST /v2/links/by-content-id`](#post-v2linksby-content-id)
- [`POST /lookup-by-base-path`](#post-lookup-by-base-path)
- [`PUT /paths/:base_path`](#put-pathsbase_path)
- [`DELETE /paths/:base_path`](#delete-pathsbase_path)
- [`GET /debug/:content_id`](#get-debugcontent_id)

### Optimistic locking (`previous_version`)
Expand Down Expand Up @@ -718,6 +719,29 @@ Reserves a path for a publishing application. Returns success or failure only.
publishing_app, and `override_existing` is true, the existing reservation will
be updated to the supplied publishing_app.

## `DELETE /paths/:base_path`

[Request/response detail][unreserve-path-pact]

Unreserves a path for a publishing application. Returns success or failure only.

### Path parameters

- `base_path`
- Identifies the path that will be unreserved

### JSON parameters:

- `publishing_app` *(required)*
- The name of the application making this request, words separated with hyphens.

### State changes

- If no path reservation for the supplied base_path is present, the command will
fail.
- If a path reservation exists for the supplied base_path but a different
publishing_app, the command will fail.

## `GET /debug/:content_id`

Displays debug information for `content_id`.
Expand Down
40 changes: 40 additions & 0 deletions spec/commands/unreserve_path_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require "rails_helper"

RSpec.describe Commands::UnreservePath do
describe "#call" do
context "when the path is owned by the app" do
it "successfully removes the reservation" do
payload = { publishing_app: "foo", base_path: "/bar" }
create(:path_reservation, payload)
described_class.call(payload)
expect(PathReservation.count).to be_zero
end
end

context "when the path is not owned by the app" do
it "returns an error" do
payload = { base_path: "/bar", publishing_app: "foo" }

create(:path_reservation,
base_path: "/bar",
publishing_app: "bar")

expect { described_class.call(payload) }
.to raise_error(
CommandError, /is reserved/
)
end
end

context "when the path has not been reserved" do
it "returns an error" do
payload = { base_path: "/bar" }

expect { described_class.call(payload) }
.to raise_error(
CommandError, /is not reserved/
)
end
end
end
end
27 changes: 27 additions & 0 deletions spec/controllers/path_reservations_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,31 @@
end
end
end

describe "unreserve_path" do
let(:payload) { { publishing_app: "foo" } }

context "with a valid path unreservation request" do
it "responds successfuly" do
create(:path_reservation, base_path: "/bar", publishing_app: "foo")
delete :unreserve_path, params: { base_path: "bar" }, body: payload.to_json
expect(response.status).to eq(200)
end
end

context "with an invalid path unreservation request" do
it "responds with status 422" do
create(:path_reservation, base_path: "/bar")
delete :unreserve_path, params: { base_path: "bar" }, body: payload.to_json
expect(response.status).to eq(422)
end
end

context "with a non-existant path unreservation request" do
it "responds with status 404" do
delete :unreserve_path, params: { base_path: "bar" }, body: payload.to_json
expect(response.status).to eq(404)
end
end
end
end
32 changes: 32 additions & 0 deletions spec/requests/unreserve_path_requests_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require "rails_helper"

RSpec.describe "DELETE /paths", type: :request do
let(:request_body) { payload.to_json }

def do_request(body: request_body, headers: {})
delete request_path, params: body, headers: headers
end

context "with path /vat-rates" do
let(:request_path) { "/paths#{base_path}" }
let(:payload) { { publishing_app: "publisher" } }

before do
create(:path_reservation,
base_path: base_path,
publishing_app: "publisher")
end

it "responds successfully" do
do_request

expect(response.status).to eq(200)
end

it "unreserves the path" do
expect {
do_request
}.to change(PathReservation, :count).by(-1)
end
end
end

0 comments on commit f0f7207

Please sign in to comment.