{"action":"created","comment":{"url":"https://api.github.com/repos/progrium/ruby-jwt/pulls/comments/35671587","id":35671587,"diff_hunk":"@@ -1,434 +1,502 @@\n-require 'helper'\n+require 'spec_helper'\n+require 'jwt'\n \n describe JWT do\n-  before do\n-    @payload = {'foo' => 'bar', 'exp' => Time.now.to_i + 1, 'nbf' => Time.now.to_i - 1 }\n+  let :payload do\n+    {\n+      user_id: 'some@user.tld'\n+    }\n+  end\n+\n+  let :data do\n+    {\n+      :secret => 'My$ecretK3y',\n+      :rsa_private => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'rsa-2048-private.pem'))),\n+      :rsa_public => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'rsa-2048-public.pem'))),\n+      :wrong_rsa_private => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'rsa-2048-wrong-public.pem'))),\n+      :wrong_rsa_public => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'rsa-2048-wrong-public.pem'))),\n+      'ES256_private' => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'ec256-private.pem'))),\n+      'ES256_public' => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'ec256-public.pem'))),\n+      'ES384_private' => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'ec384-private.pem'))),\n+      'ES384_public' => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'ec384-public.pem'))),\n+      'ES512_private' => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'ec512-private.pem'))),\n+      'ES512_public' => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'ec512-public.pem'))),\n+      'NONE' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ1c2VyX2lkIjoic29tZUB1c2VyLnRsZCJ9.',\n+      'HS256' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoic29tZUB1c2VyLnRsZCJ9.tCGvlClld0lbQ3NZaH8y53n5RSBr3zlS4Oy5bXqvzZQ',\n+      'HS384' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJ1c2VyX2lkIjoic29tZUB1c2VyLnRsZCJ9.sj1gc01SawlJSrPZgmveifJ8CzZRYAWjejWm4FRaGaAISESJ9Ncf12fCz2vHrITm',\n+      'HS512' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjoic29tZUB1c2VyLnRsZCJ9.isjhsWMZpRQOWw6LKtlY4L6tMDNkLr0qZ3bQe_xRFXWhzVvJlkclTbLVa1J6Dlj2WyZ_I1jEobTaFMDoXPzwWg',\n+      'RS256' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VyX2lkIjoic29tZUB1c2VyLnRsZCJ9.u82QrhjZTtwve5akvfWS_4LPywbkb1Yp0nUwZJWtTW0ID7dY9rRiQF5KGj2UDLZotqRlUjyNQgE_hB5BBzICDQdCjQHQoYWE5n_D2wV4PMu7Qg3FVKoBFbf8ee6irodu10fgYxpUIZtvbWw52_6k6A9IoSLSzx_lCcxoVGdW90dUuKhBcZkDtY5WNuQg7MiDthupSL1-V4Y1jmT_7o8tLNGFiocyZfGNw4yGpEOGNvD5WePNit0xsnbj6dEquovUvSFKsMaQXp2PVDEkLOiLMcyk0RrHqrHw2eNSCquWTH8PhX5Up-CVmjQM5zF9ibkaiq8NyPtsy-7rgtbyVMqXBQ',\n+      'RS384' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzM4NCJ9.eyJ1c2VyX2lkIjoic29tZUB1c2VyLnRsZCJ9.2_jPwOsUWJ-3r6lXMdJGPdhLNJQSSEmY2mrDXCwNJk-2YhMIqKAzJJCbyso_A1hS7BVkXmHt54RCcNJXroZBOgmGavCcYTPMaT6sCvVVvJJ_wn7jzKHNAJfL5nWeynTQIBWmL-m_v9QpZAgPALdeqjPRv4JHePZm23kvrUgQOxef2ldXv1l6IB3zfF72uEbk9T5pKBvgeeeQ46xm_HtkpXqMdqcTHawUXeXhuiWxuWfy9pAvhm8ivxwJhiQ15-sQNBlS9lG1_gQz1xaZ_Ou_n1nhNfGwpK5HeS0AgmqsqyCOvaGHeAuAOPZ_dSC3cFKu2AP7kc6_AKBgwJzh4agkXg',\n+      'RS512' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzUxMiJ9.eyJ1c2VyX2lkIjoic29tZUB1c2VyLnRsZCJ9.abwof7BqTvuLkN69OhEuFTP7vjGzfvAvooQdwIRne_a88MsjCq31n4UPvyIlY9_8u69rpU79RbMsrq_UZ6L85zP83EcyYI-HOfFZgYDAL3DJ7biBD99JTzyOsH_2i_E6yCkevjEX6uL_Am_C7jpWyePJQkYzTFni6mW4W1T9UobiVGA1tIZ-XOJDPHHxZkGu6W8lKW0UCsr9Ge2SCSlTs_LDSOa34gqMC5GP89unhLqSMqEMJ_Nm6Rj0rnmk87wBZM-b04LLteWuEU59QDNa4nMTjfXW74U4hX9n5EECDPQdQMecgxlUbFunAfZaoNzP4m7H4vux2FzYkjkXhdqnnw',\n+      'ES256' => '',\n+      'ES384' => '',\n+      'ES512' => ''\n+    }\n+  end\n+\n+  after(:each) do\n+    expect(OpenSSL.errors).to be_empty\n   end\n \n-  it 'encodes and decodes JWTs' do\n-    secret = 'secret'\n-    jwt = JWT.encode(@payload, secret)\n-    decoded_payload = JWT.decode(jwt, secret)\n-    expect(decoded_payload).to include(@payload)\n-  end\n+  context 'alg: NONE' do\n+    let :alg do\n+      'none'\n+    end\n \n-  it 'encodes and decodes JWTs for RSA signatures' do\n-    private_key = OpenSSL::PKey::RSA.generate(512)\n-    jwt = JWT.encode(@payload, private_key, 'RS256')\n-    decoded_payload = JWT.decode(jwt, private_key.public_key)\n-    expect(decoded_payload).to include(@payload)\n-  end\n+    it 'should generate a valid token' do\n+      token = JWT.encode payload, nil, alg\n \n-  it 'encodes and decodes JWTs for ECDSA P-256 signatures' do\n-    private_key = OpenSSL::PKey::EC.new('prime256v1')\n-    private_key.generate_key\n-    public_key = OpenSSL::PKey::EC.new(private_key)\n-    public_key.private_key = nil\n-    jwt = JWT.encode(@payload, private_key, 'ES256')\n-    decoded_payload = JWT.decode(jwt, public_key)\n-    expect(decoded_payload).to include(@payload)\n-  end\n+      expect(token).to eq data['NONE']\n+    end\n \n-  it 'encodes and decodes JWTs for ECDSA P-384 signatures' do\n-    private_key = OpenSSL::PKey::EC.new('secp384r1')\n-    private_key.generate_key\n-    public_key = OpenSSL::PKey::EC.new(private_key)\n-    public_key.private_key = nil\n-    jwt = JWT.encode(@payload, private_key, 'ES384')\n-    decoded_payload = JWT.decode(jwt, public_key)\n-    expect(decoded_payload).to include(@payload)\n-  end\n+    it 'should decode a valid token' do\n+      payload, header = JWT.decode data['NONE'], nil, false\n \n-  it 'encodes and decodes JWTs for ECDSA P-521 signatures' do\n-    private_key = OpenSSL::PKey::EC.new('secp521r1')\n-    private_key.generate_key\n-    public_key = OpenSSL::PKey::EC.new(private_key)\n-    public_key.private_key = nil\n-    jwt = JWT.encode(@payload, private_key, 'ES512')\n-    decoded_payload = JWT.decode(jwt, public_key)\n-    expect(decoded_payload).to include(@payload)\n+      expect(header['alg']).to eq alg\n+      expect(payload).to eq payload\n+    end\n   end\n \n-  it 'encodes and decodes JWTs with custom header fields' do\n-    private_key = OpenSSL::PKey::RSA.generate(512)\n-    jwt = JWT.encode(@payload, private_key, 'RS256', {'kid' => 'default'})\n-    decoded_payload = JWT.decode(jwt) do |header|\n-      expect(header['kid']).to eq('default')\n-      private_key.public_key\n+  %w(HS256 HS384 HS512).each do |alg|\n+    context \"alg: #{alg}\" do\n+      it 'should generate a valid token' do\n+        token = JWT.encode payload, data[:secret], alg\n+\n+        expect(token).to eq data[alg]\n+      end\n+\n+      it 'should decode a valid token' do\n+        payload, header = JWT.decode data[alg], data[:secret]\n+\n+        expect(header['alg']).to eq alg\n+        expect(payload).to eq payload\n+      end\n+\n+      it 'wrong secret should raise JWT::DecodeError' do\n+        expect do\n+          JWT.decode data[alg], 'wrong_secret'\n+        end.to raise_error JWT::DecodeError\n+      end\n+\n+      it 'wrong secret and verify = false should not raise JWT::DecodeError' do\n+        expect do\n+          JWT.decode data[alg], 'wrong_secret', false\n+        end.not_to raise_error\n+      end\n     end\n-    expect(decoded_payload).to include(@payload)\n   end\n \n-  it 'raises encode exception when ECDSA algorithm does not match key' do\n-    private_key = OpenSSL::PKey::EC.new('prime256v1')\n-    private_key.generate_key\n-    expect do\n-      JWT.encode(@payload, private_key, 'ES512')\n-    end.to raise_error(JWT::IncorrectAlgorithm, 'payload algorithm is ES512 but ES256 signing key was provided')\n-  end\n+  %w(RS256 RS384 RS512).each do |alg|\n+    context \"alg: #{alg}\" do\n+      it 'should generate a valid token' do\n+        token = JWT.encode payload, data[:rsa_private], alg\n \n-  it 'decodes valid JWTs' do\n-    example_payload = {'hello' => 'world'}\n-    example_secret = 'secret'\n-    example_jwt = 'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJoZWxsbyI6ICJ3b3JsZCJ9.tvagLDLoaiJKxOKqpBXSEGy7SYSifZhjntgm9ctpyj8'\n-    decoded_payload = JWT.decode(example_jwt, example_secret)\n-    expect(decoded_payload).to include(example_payload)\n-  end\n+        expect(token).to eq data[alg]\n+      end\n \n-  it 'decodes valid JWTs with iss' do\n-    example_payload = {'hello' => 'world', 'iss' => 'jwtiss'}\n-    example_secret = 'secret'\n-    example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiaXNzIjoiand0aXNzIn0.nTZkyYfpGUyKULaj45lXw_1gXXjHvGW4h5V7okHdUqQ'\n-    decoded_payload = JWT.decode(example_jwt, example_secret, true, {'iss' => 'jwtiss'})\n-    expect(decoded_payload).to include(example_payload)\n-  end\n+      it 'should decode a valid token' do\n+        payload, header = JWT.decode data[alg], data[:rsa_public]\n \n-  it 'raises invalid issuer' do\n-    # example_payload = {'hello' => 'world', 'iss' => 'jwtiss'}\n-    example_payload2 = {'hello' => 'world'}\n+        expect(header['alg']).to eq alg\n+        expect(payload).to eq payload\n+      end\n \n-    example_secret = 'secret'\n+      it 'wrong key should raise JWT::DecodeError' do\n+        key = OpenSSL::PKey.read File.read(File.join(CERT_PATH, 'rsa-2048-wrong-public.pem'))\n \n-    example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiaXNzIjoiand0aXNzIn0.nTZkyYfpGUyKULaj45lXw_1gXXjHvGW4h5V7okHdUqQ'\n-    expect{ JWT.decode(example_jwt, example_secret, true, {:verify_iss => true, 'iss' => 'jwt_iss'}) }.to raise_error(JWT::InvalidIssuerError)\n+        expect do\n+          JWT.decode data[alg], key\n+        end.to raise_error JWT::DecodeError\n+      end\n \n-    example_jwt2 = 'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJoZWxsbyI6ICJ3b3JsZCJ9.tvagLDLoaiJKxOKqpBXSEGy7SYSifZhjntgm9ctpyj8'\n-    decode_payload2 = JWT.decode(example_jwt2, example_secret, true, {'iss' => 'jwt_iss'})\n-    expect(decode_payload2).to include(example_payload2)\n-  end\n+      it 'wrong key and verify = false should not raise JWT::DecodeError' do\n+        key = OpenSSL::PKey.read File.read(File.join(CERT_PATH, 'rsa-2048-wrong-public.pem'))\n \n-  it 'decodes valid JWTs with iat' do\n-    example_payload = {'hello' => 'world', 'iat' => 1425917209}\n-    example_secret = 'secret'\n-    example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiaWF0IjoxNDI1OTE3MjA5fQ.m4F-Ugo7aLnLunBBO3BeDidyWMx8T9eoJz6FW2rgQhU'\n-    decoded_payload = JWT.decode(example_jwt, example_secret, true, {'iat' => true})\n-    expect(decoded_payload).to include(example_payload)\n+        expect do\n+          JWT.decode data[alg], key, false\n+        end.not_to raise_error\n+      end\n+    end\n   end\n \n-  it 'raises decode exception when iat is invalid' do\n-    # example_payload = {'hello' => 'world', 'iat' => 'abc'}\n-    example_secret = 'secret'\n-    example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiaWF0IjoiMTQyNTkxNzIwOSJ9.Mn_vk61xWjIhbXFqAB0nFmNkDiCmfzUgl_LaCKRT6S8'\n-    expect{ JWT.decode(example_jwt, example_secret, true, {:verify_iat => true, 'iat' => 1425917209}) }.to raise_error(JWT::InvalidIatError)\n-  end\n+  %w(ES256 ES384 ES512).each do |alg|\n+    context \"alg: #{alg}\" do\n+      before(:each) do\n+        data[alg] = JWT.encode payload, data[\"#{alg}_private\"], alg\n+      end\n \n-  it 'decodes valid JWTs with jti' do\n-    example_payload = {'hello' => 'world', 'iat' => 1425917209, 'jti' => Digest::MD5.hexdigest('secret:1425917209')}\n-    example_secret = 'secret'\n-    example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiaWF0IjoxNDI1OTE3MjA5LCJqdGkiOiI1NWM3NzZlMjFmN2NiZDg3OWMwNmZhYzAxOGRhYzQwMiJ9.ET0hb-VTUOL3M22oG13ofzvGPLMAncbF8rdNDIqo8tg'\n-    decoded_payload = JWT.decode(example_jwt, example_secret, true, {'jti' => Digest::MD5.hexdigest('secret:1425917209')})\n-    expect(decoded_payload).to include(example_payload)\n-  end\n+      let :wrong_key do\n+        OpenSSL::PKey.read File.read(File.join(CERT_PATH, 'ec256-wrong-public.pem'))\n+      end\n \n-  it 'raises decode exception when jti is invalid' do\n-    # example_payload = {'hello' => 'world', 'iat' => 1425917209, 'jti' => Digest::MD5.hexdigest('secret:1425917209')}\n-    example_secret = 'secret'\n-    example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiaWF0IjoxNDI1OTE3MjA5LCJqdGkiOiI1NWM3NzZlMjFmN2NiZDg3OWMwNmZhYzAxOGRhYzQwMiJ9.ET0hb-VTUOL3M22oG13ofzvGPLMAncbF8rdNDIqo8tg'\n-    expect{ JWT.decode(example_jwt, example_secret, true, {:verify_jti => true, 'jti' => Digest::MD5.hexdigest('secret:1425922032')}) }.to raise_error(JWT::InvalidJtiError)\n-    # expect{ JWT.decode(example_jwt, example_secret) }.to raise_error(JWT::InvalidJtiError)\n-  end\n+      it 'should generate a valid token' do\n+        payload, header = JWT.decode data[alg], data[\"#{alg}_public\"]\n \n-  it 'raises decode exception when jti without iat' do\n-    # example_payload = {'hello' => 'world', 'jti' => Digest::MD5.hexdigest('secret:1425917209')}\n-    example_secret = 'secret'\n-    example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwianRpIjoiNTVjNzc2ZTIxZjdjYmQ4NzljMDZmYWMwMThkYWM0MDIifQ.n0foJCnCM_-_xUvG_TOmR9mYpL2y0UqZOD_gv33djeE'\n-    expect{ JWT.decode(example_jwt, example_secret, true, {:verify_jti => true, 'jti' => Digest::MD5.hexdigest('secret:1425922032')}) }.to raise_error(JWT::InvalidJtiError)\n-  end\n+        expect(header['alg']).to eq alg\n+        expect(payload).to eq payload\n+      end\n \n-  it 'decodes valid JWTs with aud' do\n-    example_payload = {'hello' => 'world', 'aud' => 'url:pnd'}\n-    example_payload2 = {'hello' => 'world', 'aud' => ['url:pnd', 'aud:yes']}\n-    example_secret = 'secret'\n-    example_jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiYXVkIjoidXJsOnBuZCJ9._gT5veUtNiZD7wLEC6Gd0-nkQV3cl1z8G0zXq8qcd-8'\n-    example_jwt2 = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiYXVkIjpbInVybDpwbmQiLCJhdWQ6eWVzIl19.qNPNcT4X9B5uI91rIwbW2bIPTsp8wbRYW3jkZkrmqbQ'\n-    decoded_payload = JWT.decode(example_jwt, example_secret, true, {'aud' => 'url:pnd'})\n-    decoded_payload2 = JWT.decode(example_jwt2, example_secret, true, {'aud' => 'url:pnd'})\n-    expect(decoded_payload).to include(example_payload)\n-    expect(decoded_payload2).to include(example_payload2)\n-  end\n+      it 'should decode a valid token' do","path":"spec/jwt_spec.rb","position":261,"original_position":261,"commit_id":"f515f6e93ad77ae0530c4ba85d379125be253dad","original_commit_id":"0bc45b7343278a86a02ce96e206468719a2ae8ed","user":{"login":"aj-michael","id":7756476,"avatar_url":"https://avatars.githubusercontent.com/u/7756476?v=3","gravatar_id":"","url":"https://api.github.com/users/aj-michael","html_url":"https://github.com/aj-michael","followers_url":"https://api.github.com/users/aj-michael/followers","following_url":"https://api.github.com/users/aj-michael/following{/other_user}","gists_url":"https://api.github.com/users/aj-michael/gists{/gist_id}","starred_url":"https://api.github.com/users/aj-michael/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aj-michael/subscriptions","organizations_url":"https://api.github.com/users/aj-michael/orgs","repos_url":"https://api.github.com/users/aj-michael/repos","events_url":"https://api.github.com/users/aj-michael/events{/privacy}","received_events_url":"https://api.github.com/users/aj-michael/received_events","type":"User","site_admin":false},"body":"My apologies, I'm not saying they should be identical tests. I'm saying that at the moment, they are identical, as in they contain the same expressions. I don't believe they should be.","created_at":"2015-07-28T16:59:36Z","updated_at":"2015-07-28T16:59:36Z","html_url":"https://github.com/progrium/ruby-jwt/pull/85#discussion_r35671587","pull_request_url":"https://api.github.com/repos/progrium/ruby-jwt/pulls/85","_links":{"self":{"href":"https://api.github.com/repos/progrium/ruby-jwt/pulls/comments/35671587"},"html":{"href":"https://github.com/progrium/ruby-jwt/pull/85#discussion_r35671587"},"pull_request":{"href":"https://api.github.com/repos/progrium/ruby-jwt/pulls/85"}}},"pull_request":{"url":"https://api.github.com/repos/progrium/ruby-jwt/pulls/85","id":37411398,"html_url":"https://github.com/progrium/ruby-jwt/pull/85","diff_url":"https://github.com/progrium/ruby-jwt/pull/85.diff","patch_url":"https://github.com/progrium/ruby-jwt/pull/85.patch","issue_url":"https://api.github.com/repos/progrium/ruby-jwt/issues/85","number":85,"state":"open","locked":false,"title":"Code review: Rspec test refactoring","user":{"login":"excpt","id":229786,"avatar_url":"https://avatars.githubusercontent.com/u/229786?v=3","gravatar_id":"","url":"https://api.github.com/users/excpt","html_url":"https://github.com/excpt","followers_url":"https://api.github.com/users/excpt/followers","following_url":"https://api.github.com/users/excpt/following{/other_user}","gists_url":"https://api.github.com/users/excpt/gists{/gist_id}","starred_url":"https://api.github.com/users/excpt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/excpt/subscriptions","organizations_url":"https://api.github.com/users/excpt/orgs","repos_url":"https://api.github.com/users/excpt/repos","events_url":"https://api.github.com/users/excpt/events{/privacy}","received_events_url":"https://api.github.com/users/excpt/received_events","type":"User","site_admin":false},"body":"Code review request. Please comment! :)","created_at":"2015-06-10T22:24:08Z","updated_at":"2015-07-28T16:59:36Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"milestone":{"url":"https://api.github.com/repos/progrium/ruby-jwt/milestones/7","html_url":"https://github.com/progrium/ruby-jwt/milestones/Version%201.5.2","labels_url":"https://api.github.com/repos/progrium/ruby-jwt/milestones/7/labels","id":1176088,"number":7,"title":"Version 1.5.2","description":"","creator":{"login":"excpt","id":229786,"avatar_url":"https://avatars.githubusercontent.com/u/229786?v=3","gravatar_id":"","url":"https://api.github.com/users/excpt","html_url":"https://github.com/excpt","followers_url":"https://api.github.com/users/excpt/followers","following_url":"https://api.github.com/users/excpt/following{/other_user}","gists_url":"https://api.github.com/users/excpt/gists{/gist_id}","starred_url":"https://api.github.com/users/excpt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/excpt/subscriptions","organizations_url":"https://api.github.com/users/excpt/orgs","repos_url":"https://api.github.com/users/excpt/repos","events_url":"https://api.github.com/users/excpt/events{/privacy}","received_events_url":"https://api.github.com/users/excpt/received_events","type":"User","site_admin":false},"open_issues":1,"closed_issues":1,"state":"open","created_at":"2015-06-22T20:45:50Z","updated_at":"2015-07-20T19:46:40Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/progrium/ruby-jwt/pulls/85/commits","review_comments_url":"https://api.github.com/repos/progrium/ruby-jwt/pulls/85/comments","review_comment_url":"https://api.github.com/repos/progrium/ruby-jwt/pulls/comments{/number}","comments_url":"https://api.github.com/repos/progrium/ruby-jwt/issues/85/comments","statuses_url":"https://api.github.com/repos/progrium/ruby-jwt/statuses/f515f6e93ad77ae0530c4ba85d379125be253dad","head":{"label":"progrium:rspec-test-refactoring","ref":"rspec-test-refactoring","sha":"f515f6e93ad77ae0530c4ba85d379125be253dad","user":{"login":"progrium","id":647,"avatar_url":"https://avatars.githubusercontent.com/u/647?v=3","gravatar_id":"","url":"https://api.github.com/users/progrium","html_url":"https://github.com/progrium","followers_url":"https://api.github.com/users/progrium/followers","following_url":"https://api.github.com/users/progrium/following{/other_user}","gists_url":"https://api.github.com/users/progrium/gists{/gist_id}","starred_url":"https://api.github.com/users/progrium/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/progrium/subscriptions","organizations_url":"https://api.github.com/users/progrium/orgs","repos_url":"https://api.github.com/users/progrium/repos","events_url":"https://api.github.com/users/progrium/events{/privacy}","received_events_url":"https://api.github.com/users/progrium/received_events","type":"User","site_admin":false},"repo":{"id":1404127,"name":"ruby-jwt","full_name":"progrium/ruby-jwt","owner":{"login":"progrium","id":647,"avatar_url":"https://avatars.githubusercontent.com/u/647?v=3","gravatar_id":"","url":"https://api.github.com/users/progrium","html_url":"https://github.com/progrium","followers_url":"https://api.github.com/users/progrium/followers","following_url":"https://api.github.com/users/progrium/following{/other_user}","gists_url":"https://api.github.com/users/progrium/gists{/gist_id}","starred_url":"https://api.github.com/users/progrium/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/progrium/subscriptions","organizations_url":"https://api.github.com/users/progrium/orgs","repos_url":"https://api.github.com/users/progrium/repos","events_url":"https://api.github.com/users/progrium/events{/privacy}","received_events_url":"https://api.github.com/users/progrium/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/progrium/ruby-jwt","description":"JSON Web Token implementation in Ruby","fork":false,"url":"https://api.github.com/repos/progrium/ruby-jwt","forks_url":"https://api.github.com/repos/progrium/ruby-jwt/forks","keys_url":"https://api.github.com/repos/progrium/ruby-jwt/keys{/key_id}","collaborators_url":"https://api.github.com/repos/progrium/ruby-jwt/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/progrium/ruby-jwt/teams","hooks_url":"https://api.github.com/repos/progrium/ruby-jwt/hooks","issue_events_url":"https://api.github.com/repos/progrium/ruby-jwt/issues/events{/number}","events_url":"https://api.github.com/repos/progrium/ruby-jwt/events","assignees_url":"https://api.github.com/repos/progrium/ruby-jwt/assignees{/user}","branches_url":"https://api.github.com/repos/progrium/ruby-jwt/branches{/branch}","tags_url":"https://api.github.com/repos/progrium/ruby-jwt/tags","blobs_url":"https://api.github.com/repos/progrium/ruby-jwt/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/progrium/ruby-jwt/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/progrium/ruby-jwt/git/refs{/sha}","trees_url":"https://api.github.com/repos/progrium/ruby-jwt/git/trees{/sha}","statuses_url":"https://api.github.com/repos/progrium/ruby-jwt/statuses/{sha}","languages_url":"https://api.github.com/repos/progrium/ruby-jwt/languages","stargazers_url":"https://api.github.com/repos/progrium/ruby-jwt/stargazers","contributors_url":"https://api.github.com/repos/progrium/ruby-jwt/contributors","subscribers_url":"https://api.github.com/repos/progrium/ruby-jwt/subscribers","subscription_url":"https://api.github.com/repos/progrium/ruby-jwt/subscription","commits_url":"https://api.github.com/repos/progrium/ruby-jwt/commits{/sha}","git_commits_url":"https://api.github.com/repos/progrium/ruby-jwt/git/commits{/sha}","comments_url":"https://api.github.com/repos/progrium/ruby-jwt/comments{/number}","issue_comment_url":"https://api.github.com/repos/progrium/ruby-jwt/issues/comments{/number}","contents_url":"https://api.github.com/repos/progrium/ruby-jwt/contents/{+path}","compare_url":"https://api.github.com/repos/progrium/ruby-jwt/compare/{base}...{head}","merges_url":"https://api.github.com/repos/progrium/ruby-jwt/merges","archive_url":"https://api.github.com/repos/progrium/ruby-jwt/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/progrium/ruby-jwt/downloads","issues_url":"https://api.github.com/repos/progrium/ruby-jwt/issues{/number}","pulls_url":"https://api.github.com/repos/progrium/ruby-jwt/pulls{/number}","milestones_url":"https://api.github.com/repos/progrium/ruby-jwt/milestones{/number}","notifications_url":"https://api.github.com/repos/progrium/ruby-jwt/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/progrium/ruby-jwt/labels{/name}","releases_url":"https://api.github.com/repos/progrium/ruby-jwt/releases{/id}","created_at":"2011-02-23T21:45:17Z","updated_at":"2015-07-27T18:46:00Z","pushed_at":"2015-07-28T16:49:23Z","git_url":"git://github.com/progrium/ruby-jwt.git","ssh_url":"git@github.com:progrium/ruby-jwt.git","clone_url":"https://github.com/progrium/ruby-jwt.git","svn_url":"https://github.com/progrium/ruby-jwt","homepage":"","size":746,"stargazers_count":670,"watchers_count":670,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":70,"mirror_url":null,"open_issues_count":3,"forks":70,"open_issues":3,"watchers":670,"default_branch":"master"}},"base":{"label":"progrium:master","ref":"master","sha":"fbda12b2f9ce8d53cb4af7161f5d5f3b504a07a3","user":{"login":"progrium","id":647,"avatar_url":"https://avatars.githubusercontent.com/u/647?v=3","gravatar_id":"","url":"https://api.github.com/users/progrium","html_url":"https://github.com/progrium","followers_url":"https://api.github.com/users/progrium/followers","following_url":"https://api.github.com/users/progrium/following{/other_user}","gists_url":"https://api.github.com/users/progrium/gists{/gist_id}","starred_url":"https://api.github.com/users/progrium/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/progrium/subscriptions","organizations_url":"https://api.github.com/users/progrium/orgs","repos_url":"https://api.github.com/users/progrium/repos","events_url":"https://api.github.com/users/progrium/events{/privacy}","received_events_url":"https://api.github.com/users/progrium/received_events","type":"User","site_admin":false},"repo":{"id":1404127,"name":"ruby-jwt","full_name":"progrium/ruby-jwt","owner":{"login":"progrium","id":647,"avatar_url":"https://avatars.githubusercontent.com/u/647?v=3","gravatar_id":"","url":"https://api.github.com/users/progrium","html_url":"https://github.com/progrium","followers_url":"https://api.github.com/users/progrium/followers","following_url":"https://api.github.com/users/progrium/following{/other_user}","gists_url":"https://api.github.com/users/progrium/gists{/gist_id}","starred_url":"https://api.github.com/users/progrium/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/progrium/subscriptions","organizations_url":"https://api.github.com/users/progrium/orgs","repos_url":"https://api.github.com/users/progrium/repos","events_url":"https://api.github.com/users/progrium/events{/privacy}","received_events_url":"https://api.github.com/users/progrium/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/progrium/ruby-jwt","description":"JSON Web Token implementation in Ruby","fork":false,"url":"https://api.github.com/repos/progrium/ruby-jwt","forks_url":"https://api.github.com/repos/progrium/ruby-jwt/forks","keys_url":"https://api.github.com/repos/progrium/ruby-jwt/keys{/key_id}","collaborators_url":"https://api.github.com/repos/progrium/ruby-jwt/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/progrium/ruby-jwt/teams","hooks_url":"https://api.github.com/repos/progrium/ruby-jwt/hooks","issue_events_url":"https://api.github.com/repos/progrium/ruby-jwt/issues/events{/number}","events_url":"https://api.github.com/repos/progrium/ruby-jwt/events","assignees_url":"https://api.github.com/repos/progrium/ruby-jwt/assignees{/user}","branches_url":"https://api.github.com/repos/progrium/ruby-jwt/branches{/branch}","tags_url":"https://api.github.com/repos/progrium/ruby-jwt/tags","blobs_url":"https://api.github.com/repos/progrium/ruby-jwt/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/progrium/ruby-jwt/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/progrium/ruby-jwt/git/refs{/sha}","trees_url":"https://api.github.com/repos/progrium/ruby-jwt/git/trees{/sha}","statuses_url":"https://api.github.com/repos/progrium/ruby-jwt/statuses/{sha}","languages_url":"https://api.github.com/repos/progrium/ruby-jwt/languages","stargazers_url":"https://api.github.com/repos/progrium/ruby-jwt/stargazers","contributors_url":"https://api.github.com/repos/progrium/ruby-jwt/contributors","subscribers_url":"https://api.github.com/repos/progrium/ruby-jwt/subscribers","subscription_url":"https://api.github.com/repos/progrium/ruby-jwt/subscription","commits_url":"https://api.github.com/repos/progrium/ruby-jwt/commits{/sha}","git_commits_url":"https://api.github.com/repos/progrium/ruby-jwt/git/commits{/sha}","comments_url":"https://api.github.com/repos/progrium/ruby-jwt/comments{/number}","issue_comment_url":"https://api.github.com/repos/progrium/ruby-jwt/issues/comments{/number}","contents_url":"https://api.github.com/repos/progrium/ruby-jwt/contents/{+path}","compare_url":"https://api.github.com/repos/progrium/ruby-jwt/compare/{base}...{head}","merges_url":"https://api.github.com/repos/progrium/ruby-jwt/merges","archive_url":"https://api.github.com/repos/progrium/ruby-jwt/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/progrium/ruby-jwt/downloads","issues_url":"https://api.github.com/repos/progrium/ruby-jwt/issues{/number}","pulls_url":"https://api.github.com/repos/progrium/ruby-jwt/pulls{/number}","milestones_url":"https://api.github.com/repos/progrium/ruby-jwt/milestones{/number}","notifications_url":"https://api.github.com/repos/progrium/ruby-jwt/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/progrium/ruby-jwt/labels{/name}","releases_url":"https://api.github.com/repos/progrium/ruby-jwt/releases{/id}","created_at":"2011-02-23T21:45:17Z","updated_at":"2015-07-27T18:46:00Z","pushed_at":"2015-07-28T16:49:23Z","git_url":"git://github.com/progrium/ruby-jwt.git","ssh_url":"git@github.com:progrium/ruby-jwt.git","clone_url":"https://github.com/progrium/ruby-jwt.git","svn_url":"https://github.com/progrium/ruby-jwt","homepage":"","size":746,"stargazers_count":670,"watchers_count":670,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":70,"mirror_url":null,"open_issues_count":3,"forks":70,"open_issues":3,"watchers":670,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/progrium/ruby-jwt/pulls/85"},"html":{"href":"https://github.com/progrium/ruby-jwt/pull/85"},"issue":{"href":"https://api.github.com/repos/progrium/ruby-jwt/issues/85"},"comments":{"href":"https://api.github.com/repos/progrium/ruby-jwt/issues/85/comments"},"review_comments":{"href":"https://api.github.com/repos/progrium/ruby-jwt/pulls/85/comments"},"review_comment":{"href":"https://api.github.com/repos/progrium/ruby-jwt/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/progrium/ruby-jwt/pulls/85/commits"},"statuses":{"href":"https://api.github.com/repos/progrium/ruby-jwt/statuses/f515f6e93ad77ae0530c4ba85d379125be253dad"}}}}