require 'spec_helper' require 'puppet_spec/files' require 'puppet_spec/handler' require 'puppet/network/http' describe Puppet::Network::HTTP::Response do include PuppetSpec::Files let(:handler) { PuppetSpec::Handler.new } let(:response) { {} } let(:subject) { described_class.new(handler, response) } let(:body_utf8) { JSON.dump({ "foo" => "bar"}).encode('UTF-8') } let(:body_shift_jis) { [130, 174].pack('C*').force_encoding(Encoding::Shift_JIS) } let(:invalid_shift_jis) { "\xC0\xFF".force_encoding(Encoding::Shift_JIS) } context "when passed a response body" do it "passes the status code and body to the handler" do expect(handler).to receive(:set_response).with(response, body_utf8, 200) subject.respond_with(200, 'application/json', body_utf8) end it "accepts a File body" do file = tmpfile('response_spec') expect(handler).to receive(:set_response).with(response, file, 200) subject.respond_with(200, 'application/octet-stream', file) end end context "when passed a content type" do it "accepts a mime string" do expect(handler).to receive(:set_content_type).with(response, 'application/json; charset=utf-8') subject.respond_with(200, 'application/json', body_utf8) end it "accepts a format object" do formatter = Puppet::Network::FormatHandler.format(:json) expect(handler).to receive(:set_content_type).with(response, 'application/json; charset=utf-8') subject.respond_with(200, formatter, body_utf8) end end context "when resolving charset" do context "with binary content" do it "omits the charset" do body_binary = [0xDEADCAFE].pack('L') formatter = Puppet::Network::FormatHandler.format(:binary) expect(handler).to receive(:set_content_type).with(response, 'application/octet-stream') subject.respond_with(200, formatter, body_binary) end end context "with text/plain content" do let(:formatter) { Puppet::Network::FormatHandler.format(:s) } it "sets the charset to UTF-8 for content already in that format" do body_pem = "BEGIN CERTIFICATE".encode('UTF-8') expect(handler).to receive(:set_content_type).with(response, 'text/plain; charset=utf-8') subject.respond_with(200, formatter, body_pem) end it "encodes the content to UTF-8 for content not already in UTF-8" do expect(handler).to receive(:set_content_type).with(response, 'text/plain; charset=utf-8') expect(handler).to receive(:set_response).with(response, body_shift_jis.encode('utf-8'), 200) subject.respond_with(200, formatter, body_shift_jis) end it "raises an exception if transcoding fails" do expect { subject.respond_with(200, formatter, invalid_shift_jis) }.to raise_error(EncodingError, /"\\xFF" on Shift_JIS/) end end context "with application/json content" do let(:formatter) { Puppet::Network::FormatHandler.format(:json) } it "sets the charset to UTF-8 for content already in that format" do expect(handler).to receive(:set_content_type).with(response, 'application/json; charset=utf-8') subject.respond_with(200, formatter, body_utf8) end it "encodes the content to UTF-8 for content not already in UTF-8" do expect(handler).to receive(:set_content_type).with(response, 'application/json; charset=utf-8') expect(handler).to receive(:set_response).with(response, body_shift_jis.encode('utf-8'), 200) subject.respond_with(200, formatter, body_shift_jis) end it "raises an exception if transcoding fails" do expect { subject.respond_with(200, formatter, invalid_shift_jis) }.to raise_error(EncodingError, /"\\xFF" on Shift_JIS/) end end end end