Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Pact::Jwt object, to handle json web tokens in the pact definintion #32

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions lib/pact/jwt.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
require 'pact/symbolize_keys'
module Pact

# Specifies that the actual object should be considered a match if
# it includes the same keys, and the values of the keys are of the same class.

class Jwt
Copy link
Member

@bethesque bethesque May 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about calling this JWT? It looks funny to my eye, but I know it's completely subjective.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like Jwt very much, to be honest. I started with JWT, and changed it, to avoid confusion with JWT the gem itself.

include SymbolizeKeys

attr_reader :contents, :key, :algo

def initialize contents, key, algo
@contents = contents
@key = key
@algo = algo
end

def to_hash
{
:json_class => self.class.name,
:contents => contents,
:algo => algo,
:key => key
}
end

def as_json opts = {}
to_hash
end

def to_json opts = {}
as_json.to_json opts
end

def self.json_create hash
h = symbolize_keys(hash)
new(h[:contents],h[:key],h[:algo])
end

def eq other
self == other
end

def == other
other.is_a?(Jwt) && other.contents == self.contents
end

def generate
contents
end
end
end


10 changes: 10 additions & 0 deletions lib/pact/matchers/matchers.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'pact/term'
require 'pact/something_like'
require 'pact/jwt'
require 'pact/shared/null_expectation'
require 'pact/shared/key_not_found'
require 'pact/matchers/unexpected_key'
Expand Down Expand Up @@ -39,6 +40,7 @@ def calculate_diff expected, actual, opts = {}
when Regexp then regexp_diff(expected, actual, options)
when Pact::SomethingLike then calculate_diff(expected.contents, actual, options.merge(:type => true))
when Pact::ArrayLike then array_like_diff(expected, actual, options)
when Pact::Jwt then jwt_diff(expected,actual,options)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dude, spacing! Gotta respect the formatting contentions of the codebase, otherwise your PRs will never get merged!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I know it's just a conversation stater, but it's nice to make a good first impression ;)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh oops, completely overlooked that.

else object_diff(expected, actual, options)
end
end
Expand All @@ -61,6 +63,14 @@ def array_diff expected, actual, options
end
end

def jwt_diff expected, actual, options
if actual.is_a? String
diff(expected.contents, JWT.decode(actual,nil,nil)[0], options)
else
Difference.new expected, actual
end
end

def actual_array_diff expected, actual, options
difference = []
diff_found = false
Expand Down
2 changes: 2 additions & 0 deletions lib/pact/reification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ def self.from_term(term)
case term
when Pact::Term, Regexp, Pact::SomethingLike, Pact::ArrayLike
from_term(term.generate)
when Pact::Jwt
JWT.encode(from_term(term.generate),term.key,term.algo)
when Hash
term.inject({}) do |mem, (key,term)|
mem[key] = from_term(term)
Expand Down
1 change: 1 addition & 0 deletions lib/pact/support.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require 'pact/helpers'
require 'pact/configuration'
require 'pact/reification'
require 'jwt'

module Pact
include Pact::Helpers
Expand Down
1 change: 1 addition & 0 deletions pact-support.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Gem::Specification.new do |gem|
gem.add_runtime_dependency 'find_a_port', '~> 1.0.1'
gem.add_runtime_dependency 'thor'
gem.add_runtime_dependency 'awesome_print', '~> 1.1'
gem.add_runtime_dependency 'jwt'

gem.add_development_dependency 'rake', '~> 10.0.3'
gem.add_development_dependency 'webmock', '~> 2.0.0'
Expand Down
25 changes: 25 additions & 0 deletions spec/lib/pact/matchers/matchers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,31 @@ module Pact::Matchers

end

describe 'matching with jwt' do

context 'when the actual is a simple hash like the expected' do
let(:expected) { Pact::Jwt.new( { "a" => 1 },'JWT_KEY','HS256' ) }
let(:actual) { JWT.encode({ a: 1},'JWT_KEY', 'HS256') }

it 'returns an empty diff' do
expect(diff(expected, actual)).to eq({})
end

end

context 'when the actual is a Pact term like the expected' do
let(:expected) { Pact::Jwt.new( { "key" => Pact::Term.new(:matcher => /.*llo/, :generate => 'hello') }, 'JWT_KEY','HS256' ) }
let(:actual) { JWT.encode({ key: 'allo'},'JWT_KEY', 'HS256') }

it 'returns an empty diff' do
expect(diff(expected, actual)).to eq({})
end

end

end


describe 'option {allow_unexpected_keys: false}' do
context "when an unexpected key is found" do
let(:expected) { {:a => 1} }
Expand Down
9 changes: 9 additions & 0 deletions spec/lib/pact/reification_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ module Pact
britney: 'britney',
nested: { foo: /bar/, baz: 'qux' },
my_term: Term.new(generate: 'wiffle', matcher: /^wif/),
jwt: Jwt.new({foo: 'john'}, 'JWT_KEY','HS256'),
nested_jwt: Jwt.new({foo: Term.new(generate: 'wiffle', matcher: /^wif/)}, 'JWT_KEY','HS256'),
array: ['first', /second/]
}
end
Expand Down Expand Up @@ -37,6 +39,13 @@ module Pact
expect(subject[:array]).to eql ['first', 'second']
end

it "handles jwt" do
expect(subject[:jwt]).to eql 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJqb2huIn0.HWnd4KMrX6QyzQ78P93t-avWabIrURe6aX1M6Nh1Jn4'
end

it "handles nested jwt" do
expect(subject[:nested_jwt]).to eql 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJ3aWZmbGUifQ.FFQQzR6BEuNWZnTlVYjo3zR-rs6Sl_p3lU2EDdTkpE8'
end
end

context "when reifying a Request" do
Expand Down