Skip to content

Commit

Permalink
Add marketplace listings API endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
greysteil committed Sep 7, 2017
1 parent 1f43830 commit eddf552
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/octokit/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
require 'octokit/client/licenses'
require 'octokit/client/meta'
require 'octokit/client/markdown'
require 'octokit/client/marketplace_listings'
require 'octokit/client/milestones'
require 'octokit/client/notifications'
require 'octokit/client/objects'
Expand Down Expand Up @@ -85,6 +86,7 @@ class Client
include Octokit::Client::Licenses
include Octokit::Client::Meta
include Octokit::Client::Markdown
include Octokit::Client::MarketplaceListings
include Octokit::Client::Milestones
include Octokit::Client::Notifications
include Octokit::Client::Objects
Expand Down
48 changes: 48 additions & 0 deletions lib/octokit/client/marketplace_listings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
module Octokit
class Client

# Methods for the Marketplace Listing API
#
# @see https://developer.github.com/v3/apps/marketplace/
module MarketplaceListings

# List all plans for an app's marketplace listing
#
# @param options [Hash] An customizable set of options
#
# @see https://developer.github.com/v3/apps/marketplace/#list-all-plans-for-your-marketplace-listing
#
# @return [Array<Sawyer::Resource>] A list of plans
def list_plans(options = {})
opts = ensure_api_media_type(:marketplace, options)
paginate "/marketplace_listing/plans", opts
end

# List all GitHub accounts on a specific plan
#
# @param options [Hash] An customizable set of options
#
# @see https://developer.github.com/v3/apps/marketplace/#list-all-github-accounts-user-or-organization-on-a-specific-plan
#
# @return [Array<Sawyer::Resource>] A list of accounts
def list_accounts_for_plan(plan, options = {})
opts = ensure_api_media_type(:marketplace, options)
paginate "/marketplace_listing/plans/#{plan}/accounts", opts
end

# Get the plan associated with a given GitHub account
#
# @param options [Hash] An customizable set of options
#
# @see https://developer.github.com/v3/apps/marketplace/#check-if-a-github-account-is-associated-with-any-marketplace-listing
#
# @return <Sawyer::Resource> Account with plan details, or nil
def plan_for_account(account_id, options = {})
opts = ensure_api_media_type(:marketplace, options)
paginate "/marketplace_listing/accounts/#{account_id}", opts
rescue Octokit::NotFound
nil
end
end
end
end
1 change: 1 addition & 0 deletions lib/octokit/preview.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module Preview
:projects => 'application/vnd.github.inertia-preview+json'.freeze,
:traffic => 'application/vnd.github.spiderman-preview'.freeze,
:integrations => 'application/vnd.github.machine-man-preview+json'.freeze,
:marketplace => 'application/vnd.github.valkyrie-preview+json'.freeze,
:topics => 'application/vnd.github.mercy-preview+json'.freeze
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"http_interactions":[{"request":{"method":"get","uri":"https://api.github.com/marketplace_listing/plans/7/accounts","body":{"encoding":"US-ASCII","base64_string":""},"headers":{"Accept":["Accept: application/vnd.github.valkyrie+json"],"User-Agent":["Octokit Ruby Gem 4.6.2"],"Content-Type":["application/json"],"Authorization":["Bearer <JWT_BEARER_TOKEN>"],"Accept-Encoding":["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"]}},"response":{"status":{"code":200,"message":"OK"},"headers":{"Server":["GitHub.com"],"Date":["Mon, 06 Mar 2017 22:17:47 GMT"],"Content-Type":["application/json; charset=utf-8"],"Transfer-Encoding":["chunked"],"Status":["200 OK"],"Cache-Control":["public, max-age=60, s-maxage=60"],"Vary":["Accept","Accept-Encoding"],"Etag":["W/\"47870164deaaf2f565734db32ec45e97\""],"X-Github-Media-Type":["github.valkyrie; format=json"],"Access-Control-Expose-Headers":["ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval"],"Access-Control-Allow-Origin":["*"],"Content-Security-Policy":["default-src 'none'"],"Strict-Transport-Security":["max-age=31536000; includeSubdomains; preload"],"X-Content-Type-Options":["nosniff"],"X-Frame-Options":["deny"],"X-Xss-Protection":["1; mode=block"],"X-Served-By":["2811da37fbdda4367181b328b22b2499"],"X-Github-Request-Id":["A9F9:6D38:14B3D9B:1A5EEFB:58BDE00B"]},"body":{"encoding":"ASCII-8BIT","base64_string":"W3sidXJsIjoiaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9vcmdzL2dpdGh1YiIs\nInR5cGUiOiJPcmdhbml6YXRpb24iLCJpZCI6NCwibG9naW4iOiJnaXRodWIi\nLCJlbWFpbCI6bnVsbCwib3JnYW5pemF0aW9uX2JpbGxpbmdfZW1haWwiOiJi\naWxsaW5nQGdpdGh1Yi5jb20iLCJtYXJrZXRwbGFjZV9wdXJjaGFzZSI6eyJi\naWxsaW5nX2N5Y2xlIjoibW9udGhseSIsIm5leHRfYmlsbGluZ19kYXRlIjoi\nMjAxNy0xMC0wMVQwMDowMDowMC4wMDBaIiwidW5pdF9jb3VudCI6bnVsbCwi\ncGxhbiI6eyJ1cmwiOiJodHRwczovL2FwaS5naXRodWIuY29tL21hcmtldHBs\nYWNlX2xpc3RpbmcvcGxhbnMvOSIsImFjY291bnRzX3VybCI6Imh0dHBzOi8v\nYXBpLmdpdGh1Yi5jb20vbWFya2V0cGxhY2VfbGlzdGluZy9wbGFucy85L2Fj\nY291bnRzIiwiaWQiOjksIm5hbWUiOiJQcm8iLCJkZXNjcmlwdGlvbiI6IkEg\ncHJvZmVzc2lvbmFsLWdyYWRlIENJIHNvbHV0aW9uIiwibW9udGhseV9wcmlj\nZV9pbl9jZW50cyI6MTA5OSwieWVhcmx5X3ByaWNlX2luX2NlbnRzIjoxMTg3\nMCwicHJpY2VfbW9kZWwiOiJmbGF0LXJhdGUiLCJ1bml0X25hbWUiOm51bGws\nImJ1bGxldHMiOlsiVGhpcyBpcyB0aGUgZmlyc3QgYnVsbGV0IG9mIHRoZSBQ\ncm8gcGxhbiIsIlRoaXMgaXMgdGhlIHNlY29uZCBidWxsZXQgb2YgdGhlIFBy\nbyBwbGFuIl19fX0seyJ1cmwiOiJodHRwczovL2FwaS5naXRodWIuY29tL3Vz\nZXJzL3Rlc3QiLCJ0eXBlIjoiVXNlciIsImlkIjoyLCJsb2dpbiI6InRlc3Qi\nLCJlbWFpbCI6InRlc3RAZXhhbXBsZS5jb20iLCJtYXJrZXRwbGFjZV9wdXJj\naGFzZSI6eyJiaWxsaW5nX2N5Y2xlIjoibW9udGhseSIsIm5leHRfYmlsbGlu\nZ19kYXRlIjoiMjAxNy0xMC0wMVQwMDowMDowMC4wMDBaIiwidW5pdF9jb3Vu\ndCI6bnVsbCwicGxhbiI6eyJ1cmwiOiJodHRwczovL2FwaS5naXRodWIuY29t\nL21hcmtldHBsYWNlX2xpc3RpbmcvcGxhbnMvOCIsImFjY291bnRzX3VybCI6\nImh0dHBzOi8vYXBpLmdpdGh1Yi5jb20vbWFya2V0cGxhY2VfbGlzdGluZy9w\nbGFucy84L2FjY291bnRzIiwiaWQiOjgsIm5hbWUiOiJIb2JieSIsImRlc2Ny\naXB0aW9uIjoiQSBob2JieS1ncmFkZSBDSSBzb2x1dGlvbiIsIm1vbnRobHlf\ncHJpY2VfaW5fY2VudHMiOjEwOTksInllYXJseV9wcmljZV9pbl9jZW50cyI6\nMTE4NzAsInByaWNlX21vZGVsIjoicGVyLXVuaXQiLCJ1bml0X25hbWUiOiJz\nZWF0IiwiYnVsbGV0cyI6WyJUaGlzIGlzIHRoZSBmaXJzdCBidWxsZXQgb2Yg\ndGhlIEhvYmJ5IHBsYW4iLCJUaGlzIGlzIHRoZSBzZWNvbmQgYnVsbGV0IG9m\nIHRoZSBIb2JieSBwbGFuIl19fX1d\n"},"http_version":null},"recorded_at":"Mon, 06 Mar 2017 22:17:47 GMT"}],"recorded_with":"VCR 2.9.3"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"http_interactions":[{"request":{"method":"get","uri":"https://api.github.com/marketplace_listing/plans","body":{"encoding":"US-ASCII","base64_string":""},"headers":{"Accept":["Accept: application/vnd.github.valkyrie+json"],"User-Agent":["Octokit Ruby Gem 4.6.2"],"Content-Type":["application/json"],"Authorization":["Bearer <JWT_BEARER_TOKEN>"],"Accept-Encoding":["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"]}},"response":{"status":{"code":200,"message":"OK"},"headers":{"Server":["GitHub.com"],"Date":["Mon, 06 Mar 2017 22:17:47 GMT"],"Content-Type":["application/json; charset=utf-8"],"Transfer-Encoding":["chunked"],"Status":["200 OK"],"Cache-Control":["public, max-age=60, s-maxage=60"],"Vary":["Accept","Accept-Encoding"],"Etag":["W/\"47870164deaaf2f565734db32ec45e97\""],"X-Github-Media-Type":["github.valkyrie; format=json"],"Access-Control-Expose-Headers":["ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval"],"Access-Control-Allow-Origin":["*"],"Content-Security-Policy":["default-src 'none'"],"Strict-Transport-Security":["max-age=31536000; includeSubdomains; preload"],"X-Content-Type-Options":["nosniff"],"X-Frame-Options":["deny"],"X-Xss-Protection":["1; mode=block"],"X-Served-By":["2811da37fbdda4367181b328b22b2499"],"X-Github-Request-Id":["A9F9:6D38:14B3D9B:1A5EEFB:58BDE00B"]},"body":{"encoding":"ASCII-8BIT","base64_string":"W3sidXJsIjoiaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9tYXJrZXRwbGFjZV9s\naXN0aW5nL3BsYW5zLzciLCJhY2NvdW50c191cmwiOiJodHRwczovL2FwaS5n\naXRodWIuY29tL21hcmtldHBsYWNlX2xpc3RpbmcvcGxhbnMvNy9hY2NvdW50\ncyIsImlkIjo3LCJuYW1lIjoiRnJlZSIsImRlc2NyaXB0aW9uIjoiQSBmcmVl\nIENJIHNvbHV0aW9uIiwibW9udGhseV9wcmljZV9pbl9jZW50cyI6MCwieWVh\ncmx5X3ByaWNlX2luX2NlbnRzIjowLCJwcmljZV9tb2RlbCI6ImZyZWUiLCJ1\nbml0X25hbWUiOm51bGwsImJ1bGxldHMiOlsiVGhpcyBpcyB0aGUgZmlyc3Qg\nYnVsbGV0IG9mIHRoZSBmcmVlIHBsYW4iLCJUaGlzIGlzIHRoZSBzZWNvbmQg\nYnVsbGV0IG9mIHRoZSBmcmVlIHBsYW4iXX0seyJ1cmwiOiJodHRwczovL2Fw\naS5naXRodWIuY29tL21hcmtldHBsYWNlX2xpc3RpbmcvcGxhbnMvOCIsImFj\nY291bnRzX3VybCI6Imh0dHBzOi8vYXBpLmdpdGh1Yi5jb20vbWFya2V0cGxh\nY2VfbGlzdGluZy9wbGFucy84L2FjY291bnRzIiwiaWQiOjgsIm5hbWUiOiJI\nb2JieSIsImRlc2NyaXB0aW9uIjoiQSBob2JieS1ncmFkZSBDSSBzb2x1dGlv\nbiIsIm1vbnRobHlfcHJpY2VfaW5fY2VudHMiOjEwOTksInllYXJseV9wcmlj\nZV9pbl9jZW50cyI6MTE4NzAsInByaWNlX21vZGVsIjoicGVyLXVuaXQiLCJ1\nbml0X25hbWUiOiJzZWF0IiwiYnVsbGV0cyI6WyJUaGlzIGlzIHRoZSBmaXJz\ndCBidWxsZXQgb2YgdGhlIEhvYmJ5IHBsYW4iLCJUaGlzIGlzIHRoZSBzZWNv\nbmQgYnVsbGV0IG9mIHRoZSBIb2JieSBwbGFuIl19LHsidXJsIjoiaHR0cHM6\nLy9hcGkuZ2l0aHViLmNvbS9tYXJrZXRwbGFjZV9saXN0aW5nL3BsYW5zLzki\nLCJhY2NvdW50c191cmwiOiJodHRwczovL2FwaS5naXRodWIuY29tL21hcmtl\ndHBsYWNlX2xpc3RpbmcvcGxhbnMvOS9hY2NvdW50cyIsImlkIjo5LCJuYW1l\nIjoiUHJvIiwiZGVzY3JpcHRpb24iOiJBIHByb2Zlc3Npb25hbC1ncmFkZSBD\nSSBzb2x1dGlvbiIsIm1vbnRobHlfcHJpY2VfaW5fY2VudHMiOjEwOTksInll\nYXJseV9wcmljZV9pbl9jZW50cyI6MTE4NzAsInByaWNlX21vZGVsIjoiZmxh\ndC1yYXRlIiwidW5pdF9uYW1lIjpudWxsLCJidWxsZXRzIjpbIlRoaXMgaXMg\ndGhlIGZpcnN0IGJ1bGxldCBvZiB0aGUgUHJvIHBsYW4iLCJUaGlzIGlzIHRo\nZSBzZWNvbmQgYnVsbGV0IG9mIHRoZSBQcm8gcGxhbiJdfV0=\n"},"http_version":null},"recorded_at":"Mon, 06 Mar 2017 22:17:47 GMT"}],"recorded_with":"VCR 2.9.3"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"http_interactions":[{"request":{"method":"get","uri":"https://api.github.com/marketplace_listing/accounts/1","body":{"encoding":"US-ASCII","base64_string":""},"headers":{"Accept":["Accept: application/vnd.github.valkyrie+json"],"User-Agent":["Octokit Ruby Gem 4.6.2"],"Content-Type":["application/json"],"Authorization":["Bearer <JWT_BEARER_TOKEN>"],"Accept-Encoding":["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"]}},"response":{"status":{"code":200,"message":"OK"},"headers":{"Server":["GitHub.com"],"Date":["Mon, 06 Mar 2017 22:17:47 GMT"],"Content-Type":["application/json; charset=utf-8"],"Transfer-Encoding":["chunked"],"Status":["200 OK"],"Cache-Control":["public, max-age=60, s-maxage=60"],"Vary":["Accept","Accept-Encoding"],"Etag":["W/\"47870164deaaf2f565734db32ec45e97\""],"X-Github-Media-Type":["github.valkyrie; format=json"],"Access-Control-Expose-Headers":["ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval"],"Access-Control-Allow-Origin":["*"],"Content-Security-Policy":["default-src 'none'"],"Strict-Transport-Security":["max-age=31536000; includeSubdomains; preload"],"X-Content-Type-Options":["nosniff"],"X-Frame-Options":["deny"],"X-Xss-Protection":["1; mode=block"],"X-Served-By":["2811da37fbdda4367181b328b22b2499"],"X-Github-Request-Id":["A9F9:6D38:14B3D9B:1A5EEFB:58BDE00B"]},"body":{"encoding":"ASCII-8BIT","base64_string":"eyJ1cmwiOiJodHRwczovL2FwaS5naXRodWIuY29tL29yZ3MvZ2l0aHViIiwi\ndHlwZSI6Ik9yZ2FuaXphdGlvbiIsImlkIjo0LCJsb2dpbiI6ImdpdGh1YiIs\nImVtYWlsIjpudWxsLCJvcmdhbml6YXRpb25fYmlsbGluZ19lbWFpbCI6ImJp\nbGxpbmdAZ2l0aHViLmNvbSIsIm1hcmtldHBsYWNlX3B1cmNoYXNlIjp7ImJp\nbGxpbmdfY3ljbGUiOiJtb250aGx5IiwibmV4dF9iaWxsaW5nX2RhdGUiOiIy\nMDE3LTEwLTAxVDAwOjAwOjAwLjAwMFoiLCJ1bml0X2NvdW50IjpudWxsLCJw\nbGFuIjp7InVybCI6Imh0dHBzOi8vYXBpLmdpdGh1Yi5jb20vbWFya2V0cGxh\nY2VfbGlzdGluZy9wbGFucy85IiwiYWNjb3VudHNfdXJsIjoiaHR0cHM6Ly9h\ncGkuZ2l0aHViLmNvbS9tYXJrZXRwbGFjZV9saXN0aW5nL3BsYW5zLzkvYWNj\nb3VudHMiLCJpZCI6OSwibmFtZSI6IlBybyIsImRlc2NyaXB0aW9uIjoiQSBw\ncm9mZXNzaW9uYWwtZ3JhZGUgQ0kgc29sdXRpb24iLCJtb250aGx5X3ByaWNl\nX2luX2NlbnRzIjoxMDk5LCJ5ZWFybHlfcHJpY2VfaW5fY2VudHMiOjExODcw\nLCJwcmljZV9tb2RlbCI6ImZsYXQtcmF0ZSIsInVuaXRfbmFtZSI6bnVsbCwi\nYnVsbGV0cyI6WyJUaGlzIGlzIHRoZSBmaXJzdCBidWxsZXQgb2YgdGhlIFBy\nbyBwbGFuIiwiVGhpcyBpcyB0aGUgc2Vjb25kIGJ1bGxldCBvZiB0aGUgUHJv\nIHBsYW4iXX19fQ==\n"},"http_version":null},"recorded_at":"Mon, 06 Mar 2017 22:17:47 GMT"}],"recorded_with":"VCR 2.9.3"}
53 changes: 53 additions & 0 deletions spec/octokit/client/marketplace_listings_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
require 'helper'

describe Octokit::Client::MarketplaceListings do
before(:each) do
Octokit.reset!
@client = oauth_client
@jwt_client = Octokit::Client.new(:bearer_token => new_jwt_token)
use_vcr_placeholder_for(@jwt_client.bearer_token, '<JWT_BEARER_TOKEN>')
end

after(:each) do
Octokit.reset!
end

describe ".list_plans", :vcr do
it "returns plans for a marketplace listing" do
plans = @jwt_client.list_plans
expect(plans).to be_kind_of Array
assert_requested :get, github_url("/marketplace_listing/plans")
end
end # .list_plans

describe ".list_accounts_for_plan", :vcr do
it "returns accounts for a given plan" do
plans = @jwt_client.list_accounts_for_plan(7)
expect(plans).to be_kind_of Array
assert_requested :get, github_url("/marketplace_listing/plans/7/accounts")
end
end # .list_accounts_for_plan

describe ".plan_for_account", :vcr do
it "returns the plan for a given account" do
plans = @jwt_client.plan_for_account(1)
expect(plans).to be_kind_of Sawyer::Resource
assert_requested :get, github_url("/marketplace_listing/accounts/1")
end
end # .plan_for_account

private

def new_jwt_token
private_pem = File.read(test_github_integration_pem_key)
private_key = OpenSSL::PKey::RSA.new(private_pem)

payload = {}.tap do |opts|
opts[:iat] = Time.now.to_i # Issued at time.
opts[:exp] = opts[:iat] + 600 # JWT expiration time is 10 minutes from issued time.
opts[:iss] = test_github_integration # Integration's GitHub identifier.
end

JWT.encode(payload, private_key, 'RS256')
end
end

0 comments on commit eddf552

Please sign in to comment.