require 'spec_helper' require 'pact_broker/api/resources/pact' require 'rack/test' require 'pact_broker/pacts/service' require 'pact_broker/pacticipants/service' module PactBroker::Api module Resources describe Pact do include Rack::Test::Methods let(:app) { PactBroker::API } let(:json) { {some: 'json'}.to_json } describe "GET" do context "Accept: text/html" do let(:json_content) { 'json_content' } let(:pact) { double("pact", json_content: json_content)} let(:html) { 'html' } let(:pact_id_params) { {provider_name: "provider_name", consumer_name: "consumer_name", consumer_version_number: "1.2.3"} } before do allow(PactBroker::Pacts::Service).to receive(:find_pact).and_return(pact) allow(PactBroker.configuration.html_pact_renderer).to receive(:call).and_return(html) end subject { get "/pacts/provider/provider_name/consumer/consumer_name/versions/1.2.3",{}, {'HTTP_ACCEPT' => "text/html"} } it "find the pact" do expect(PactBroker::Pacts::Service).to receive(:find_pact).with(hash_including(pact_id_params)) subject end it "uses the configured HTML renderer" do expect(PactBroker.configuration.html_pact_renderer).to receive(:call).with(pact) subject end it "returns a HTML body" do subject expect(last_response.body).to eq html end it "returns a content type of HTML" do subject expect(last_response.headers['Content-Type']).to eq 'text/html;charset=utf-8' end end end shared_examples "an update endpoint" do |http_method| subject { self.send http_method, "/pacts/provider/Provider/consumer/Consumer/version/1.2.3", json, {'CONTENT_TYPE' => "application/json"} ; last_response } let(:response) { subject; last_response } context "with invalid JSON" do let(:json) { '{' } it "returns a 400 response" do expect(response.status).to eq 400 end it "returns a JSON content type" do expect(response.headers['Content-Type']).to eq "application/json;charset=utf-8" end it "returns an error message" do expect(JSON.parse(response.body)["error"]).to match(/Error parsing JSON/) end end context "with validation errors" do let(:errors) { double(:errors, messages: ['messages']) } before do allow_any_instance_of(Contracts::PutPactParamsContract).to receive(:validate).and_return(false) allow_any_instance_of(Contracts::PutPactParamsContract).to receive(:errors).and_return(errors) end it "returns a 400 error" do expect(subject).to be_a_json_error_response 'messages' end end context "with a potential duplicate pacticipant" do let(:pacticipant_service) { PactBroker::Pacticipants::Service } let(:messages) { ["message1", "message2"] } before do allow(pacticipant_service).to receive(:messages_for_potential_duplicate_pacticipants).and_return(messages) end it "checks for duplicates" do expect(pacticipant_service).to receive(:messages_for_potential_duplicate_pacticipants).with(['Consumer', 'Provider'], 'http://example.org') response end it "returns a 409 response" do expect(response.status).to eq 409 end it "returns a text response" do expect(response.headers['Content-Type']).to eq 'text/plain' end it "returns the messages in the response body" do expect(response.body).to eq "message1\nmessage2" end end end describe "PUT" do it_behaves_like "an update endpoint", :put end describe "PATCH" do it_behaves_like "an update endpoint", :patch end describe "DELETE" do subject { delete "/pacts/provider/Provider/consumer/Consumer/version/1.2", json, {'CONTENT_TYPE' => "application/json"} ; last_response } let(:pact) { double('pact') } let(:pact_service) { PactBroker::Pacts::Service } let(:response) { subject; last_response } before do allow(pact_service).to receive(:find_pact).and_return(pact) allow(pact_service).to receive(:delete) end context "when the pact exists" do it "deletes the pact using the pact service" do expect(pact_service).to receive(:delete).with(instance_of(PactBroker::Pacts::PactParams)) subject end it "returns a 204" do expect(subject.status).to eq 204 end end context "when the pact does not exist" do let(:pact) { nil } it "returns a 404" do expect(subject.status).to eq 404 end end end end end end