Comparing changes

v0.1.6 v0.1.7
10 commits 16 files changed

Commits

08a3beb add shipit script. mo 2018-05-18 19:44:43
9943099 bump version. mo 2018-05-18 19:42:35
a24b69e fix rubocop error. mo 2018-05-18 19:40:00
2b1001e add client.delete mokha 2018-05-15 01:05:14
8f0afaf fix rubocop errors. mokha 2018-05-15 00:56:06
dbe6f55 rubocop -a mokha 2018-05-15 00:46:21
dd2d2d9 inline conditional. mokha 2018-05-15 00:43:54
d5299cb test mutual tls connection. mokha 2018-05-15 00:38:39
bin/shipit
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+set -e
+
+cd "$(dirname "$0")/.."
+
+[ -z "$DEBUG" ] || set -x
+
+bin/cibuild
+bundle exec rake release
exe/net-hippie
@@ -1,4 +1,5 @@
 #!/usr/bin/env ruby
+# frozen_string_literal: true
 
 require 'net/hippie'
 
lib/net/hippie/api.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module Net
   module Hippie
     # A no nonsense class to perform HTTP requests.
lib/net/hippie/client.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module Net
   module Hippie
     # A simple client for connecting with http resources.
@@ -20,7 +22,7 @@ module Net
         @certificate = certificate
         @default_headers = headers
         @key = key
-        @mapper = JsonMapper.new
+        @mapper = ContentTypeMapper.new
         @passphrase = passphrase
         @verify_mode = verify_mode
       end
@@ -50,6 +52,12 @@ module Net
         execute(uri, request, &block)
       end
 
+      def delete(uri, headers: {}, body: {}, &block)
+        type = Net::HTTP::Delete
+        request = request_for(type, uri, headers: headers, body: body)
+        execute(uri, request, &block)
+      end
+
       private
 
       attr_reader :default_headers
@@ -62,16 +70,14 @@ module Net
         http.use_ssl = uri.is_a?(URI::HTTPS)
         http.verify_mode = verify_mode
         http.set_debug_output(Net::Hippie.logger)
-        if certificate && key
-          http.cert = OpenSSL::X509::Certificate.new(certificate) if certificate
-          http.key = private_key
-        end
+        apply_client_tls_to(http)
         http
       end
 
       def request_for(type, uri, headers: {}, body: {})
-        type.new(uri, default_headers.merge(headers)).tap do |x|
-          x.body = mapper.map_from(body) unless body.empty?
+        final_headers = default_headers.merge(headers)
+        type.new(uri, final_headers).tap do |x|
+          x.body = mapper.map_from(final_headers, body) unless body.empty?
         end
       end
 
@@ -79,12 +85,15 @@ module Net
         uri.is_a?(URI) ? uri : URI.parse(uri)
       end
 
-      def private_key
-        if passphrase
-          OpenSSL::PKey::RSA.new(key, passphrase)
-        else
-          OpenSSL::PKey::RSA.new(key)
-        end
+      def private_key(type = OpenSSL::PKey::RSA)
+        passphrase ? type.new(key, passphrase) : type.new(key)
+      end
+
+      def apply_client_tls_to(http)
+        return if certificate.nil? || key.nil?
+
+        http.cert = OpenSSL::X509::Certificate.new(certificate)
+        http.key = private_key
       end
     end
   end
lib/net/hippie/content_type_mapper.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Net
+  module Hippie
+    # Converts a ruby hash into a JSON string
+    class ContentTypeMapper
+      def map_from(headers, body)
+        content_type = headers['Content-Type'] || ''
+        return JSON.generate(body) if content_type.include?('json')
+        body
+      end
+    end
+  end
+end
lib/net/hippie/json_mapper.rb
@@ -1,10 +0,0 @@
-module Net
-  module Hippie
-    # Converts a ruby hash into a JSON string
-    class JsonMapper
-      def map_from(hash)
-        JSON.generate(hash)
-      end
-    end
-  end
-end
lib/net/hippie/version.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
 module Net
   module Hippie
-    VERSION = '0.1.6'.freeze
+    VERSION = '0.1.7'
   end
 end
lib/net/hippie.rb
@@ -1,10 +1,12 @@
+# frozen_string_literal: true
+
 require 'json'
 require 'logger'
 require 'net/http'
 require 'openssl'
 
 require 'net/hippie/version'
-require 'net/hippie/json_mapper'
+require 'net/hippie/content_type_mapper'
 require 'net/hippie/client'
 require 'net/hippie/api'
 
test/fixtures/delete_breaches.yml
@@ -0,0 +1,24 @@
+---
+http_interactions:
+- request:
+    method: delete
+    uri: https://haveibeenpwned.com/api/breaches
+    body:
+      encoding: UTF-8
+      string: ""
+    headers:
+      Accept:
+      - application/vnd.haveibeenpwned.v2+json
+  response:
+    status:
+      code: 200
+      message: OK
+    headers:
+      Content-Type:
+      - application/json; charset=utf-8
+    body:
+      encoding: UTF-8
+      string: '{"Message":"Congratulations!"}'
+    http_version:
+  recorded_at: Mon, 07 May 2018 20:21:13 GMT
+recorded_with: VCR 4.0.0
test/net/client_test.rb
@@ -103,4 +103,60 @@ class ClientTest < Minitest::Test
       assert_equal 'Congratulations!', JSON.parse(@response.body)['Message']
     end
   end
+
+  def test_delete
+    uri = URI.parse('https://haveibeenpwned.com/api/breaches')
+    VCR.use_cassette('delete_breaches') do
+      response = subject.delete(uri)
+      refute_nil response
+      assert_equal 'Congratulations!', JSON.parse(response.body)['Message']
+    end
+  end
+
+  def test_client_tls
+    private_key = OpenSSL::PKey::RSA.new(2048)
+    certificate = OpenSSL::X509::Certificate.new
+    certificate.not_after = certificate.not_before = Time.now
+    certificate.public_key = private_key.public_key
+    certificate.sign(private_key, OpenSSL::Digest::SHA256.new)
+
+    subject = Net::Hippie::Client.new(certificate: certificate.to_pem, key: private_key.export)
+    uri = URI.parse('https://haveibeenpwned.com/api/breaches')
+
+    @called = false
+    VCR.use_cassette('get_breaches') do
+      subject.get(uri) do |_request, response|
+        @called = true
+        refute_nil response
+        assert_equal '000webhost', JSON.parse(response.body)[0]['Title']
+      end
+    end
+    assert(@called)
+  end
+
+  def test_client_tls_with_passphrase
+    private_key = OpenSSL::PKey::RSA.new(2048)
+    passphrase = SecureRandom.hex(16)
+    certificate = OpenSSL::X509::Certificate.new
+    certificate.not_after = certificate.not_before = Time.now
+    certificate.public_key = private_key.public_key
+    certificate.sign(private_key, OpenSSL::Digest::SHA256.new)
+
+    subject = Net::Hippie::Client.new(
+      certificate: certificate.to_pem,
+      key: private_key.export(OpenSSL::Cipher.new('AES-256-CBC'), passphrase),
+      passphrase: passphrase
+    )
+    uri = URI.parse('https://haveibeenpwned.com/api/breaches')
+
+    @called = false
+    VCR.use_cassette('get_breaches') do
+      subject.get(uri) do |_request, response|
+        @called = true
+        refute_nil response
+        assert_equal '000webhost', JSON.parse(response.body)[0]['Title']
+      end
+    end
+    assert(@called)
+  end
 end
test/net/content_type_mapper_test.rb
@@ -0,0 +1,27 @@
+require 'test_helper'
+
+class ContentTypeMapperTest < Minitest::Test
+  def test_returns_json
+    subject = Net::Hippie::ContentTypeMapper.new
+    headers = { 'Content-Type' => 'application/json' }
+    body = { message: 'something witty' }
+    result = subject.map_from(headers, body)
+    assert_equal JSON.generate(body), result
+  end
+
+  def test_returns_json_with_charset
+    subject = Net::Hippie::ContentTypeMapper.new
+    headers = { 'Content-Type' => 'application/json; charset=utf-8' }
+    body = { message: 'something witty' }
+    result = subject.map_from(headers, body)
+    assert_equal JSON.generate(body), result
+  end
+
+  def test_return_html
+    subject = Net::Hippie::ContentTypeMapper.new
+    headers = { 'Content-Type' => 'text/html' }
+    body = '<html></html>'
+    result = subject.map_from(headers, body)
+    assert_equal body, result
+  end
+end
test/test_helper.rb
@@ -1,5 +1,6 @@
 $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
 require 'net/hippie'
+require 'securerandom'
 require 'vcr'
 require 'webmock'
 
.rubocop.yml
@@ -0,0 +1,8 @@
+AllCops:
+  Exclude:
+    - 'coverage/**/*'
+    - 'pkg/**/*'
+    - 'test/**/*'
+    - 'tmp/**/*'
+    - 'vendor/**/*'
+  TargetRubyVersion: 2.5
Gemfile
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 source 'https://rubygems.org'
 
 git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
net-hippie.gemspec
@@ -1,4 +1,6 @@
 
+# frozen_string_literal: true
+
 lib = File.expand_path('lib', __dir__)
 $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
 require 'net/hippie/version'
Rakefile
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'bundler/gem_tasks'
 require 'rake/testtask'
 require 'rubocop/rake_task'