heroku-client 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/lib/heroku-client.rb +1 -0
- data/lib/heroku-client/api.rb +31 -0
- data/lib/heroku-client/http.rb +45 -10
- data/lib/heroku-client/json_util.rb +26 -0
- data/lib/heroku-client/version.rb +1 -1
- data/spec/heroku-client/api_spec.rb +44 -0
- data/spec/heroku-client/http_spec.rb +18 -8
- data/spec/heroku-client/json_util_spec.rb +29 -0
- data/spec/responses/api.rb +42 -0
- data/spec/spec_helper.rb +5 -0
- metadata +6 -2
data/.gitignore
CHANGED
data/lib/heroku-client.rb
CHANGED
data/lib/heroku-client/api.rb
CHANGED
@@ -13,6 +13,37 @@ module Heroku
|
|
13
13
|
raise "Invalid number of parameters"
|
14
14
|
end
|
15
15
|
|
16
|
+
def create_app(params = {})
|
17
|
+
post_params = {}
|
18
|
+
|
19
|
+
[:name, :stack].each do |k|
|
20
|
+
post_params["app[#{k}]"] = params[k] if params.has_key? k
|
21
|
+
end
|
22
|
+
|
23
|
+
post "apps", post_params
|
24
|
+
end
|
25
|
+
|
26
|
+
def rename_app(old_app_name, new_app_name)
|
27
|
+
put_params = {}
|
28
|
+
|
29
|
+
put_params["name"] = old_app_name
|
30
|
+
put_params["app[name]"] = new_app_name
|
31
|
+
|
32
|
+
put "apps/#{old_app_name}", put_params
|
33
|
+
end
|
34
|
+
|
35
|
+
def transfer_app(app_name, new_owner)
|
36
|
+
put_params = {}
|
37
|
+
|
38
|
+
put_params["app[transfer_owner]"] = new_owner
|
39
|
+
|
40
|
+
put "apps/#{app_name}", put_params
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete_app(app_name)
|
44
|
+
delete "apps/#{app_name}"
|
45
|
+
end
|
46
|
+
|
16
47
|
def collaborators(app_name)
|
17
48
|
return get("apps/#{app_name}/collaborators")
|
18
49
|
end
|
data/lib/heroku-client/http.rb
CHANGED
@@ -2,27 +2,62 @@ module Heroku
|
|
2
2
|
module Client
|
3
3
|
module Http
|
4
4
|
def get(uri)
|
5
|
+
request :get, uri
|
6
|
+
end
|
7
|
+
|
8
|
+
def post(uri, body)
|
9
|
+
request :post, uri, body
|
10
|
+
end
|
11
|
+
|
12
|
+
def put(uri, body)
|
13
|
+
request :put, uri, body
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete(uri)
|
17
|
+
request :delete, uri
|
18
|
+
end
|
19
|
+
|
20
|
+
def request(method, uri, body = {})
|
5
21
|
headers = { "Accept" => "application/json"}
|
6
|
-
|
22
|
+
basic_auth = { password: apikey }
|
7
23
|
|
8
|
-
|
9
|
-
raise PaymentRequiredError if resp.code == 402
|
10
|
-
raise ForbiddenError if resp.code == 403
|
11
|
-
raise NotFoundError if resp.code == 404
|
12
|
-
raise PreConditionFailedError if resp.code == 412
|
13
|
-
raise UnprocessableEntityError if resp.code == 422
|
14
|
-
raise LockedError if resp.code == 423
|
24
|
+
options = { basic_auth: basic_auth, headers: headers }
|
15
25
|
|
16
|
-
|
26
|
+
options[:body] = body unless body.empty?
|
17
27
|
|
18
|
-
|
28
|
+
url = "https://api.heroku.com/#{uri}"
|
29
|
+
|
30
|
+
resp = HTTParty.get url, options if method == :get
|
31
|
+
resp = HTTParty.post url, options if method == :post
|
32
|
+
resp = HTTParty.put url, options if method == :put
|
33
|
+
resp = HTTParty.delete url, options if method == :delete
|
34
|
+
|
35
|
+
unless resp.success?
|
36
|
+
error_message = json_util.parse_error(resp.body)
|
37
|
+
|
38
|
+
raise UnauthorizedError, error_message if resp.code == 401
|
39
|
+
raise PaymentRequiredError, error_message if resp.code == 402
|
40
|
+
raise ForbiddenError, error_message if resp.code == 403
|
41
|
+
raise NotFoundError, error_message if resp.code == 404
|
42
|
+
raise PreConditionFailedError, error_message if resp.code == 412
|
43
|
+
raise UnprocessableEntityError, error_message if resp.code == 422
|
44
|
+
raise LockedError, error_message if resp.code == 423
|
19
45
|
|
46
|
+
raise UnknownError
|
47
|
+
end
|
48
|
+
|
49
|
+
parsed = JSON.parse(resp.body)
|
20
50
|
parsed = parsed.map { |o| HerokuObj.new(o) } if parsed.is_a? Array
|
21
51
|
|
22
52
|
parsed = HerokuObj.new parsed if parsed.is_a? Hash
|
23
53
|
|
24
54
|
parsed
|
25
55
|
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def json_util
|
59
|
+
@json_util ||= JSONUtil.new
|
60
|
+
end
|
26
61
|
end
|
27
62
|
|
28
63
|
class UnauthorizedError < Exception
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Heroku
|
2
|
+
module Client
|
3
|
+
class JSONUtil
|
4
|
+
|
5
|
+
def parse_error(body)
|
6
|
+
parse_json_error(body) || parse_plain_text_error(body)
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse_json_error(body)
|
10
|
+
json = JSON.parse body rescue false
|
11
|
+
|
12
|
+
case json
|
13
|
+
when Array
|
14
|
+
json.first.join ' ' # message like [["name", "is already taken"]]
|
15
|
+
when Hash
|
16
|
+
json['error'] # message like {"error": "The error message"}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def parse_plain_text_error(body)
|
21
|
+
body
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -14,6 +14,14 @@ describe Heroku::Client::Api do
|
|
14
14
|
FakeWeb.register_uri :get, Responses::Api.processes_url(api.apikey, app_name), body: Responses::Api.processes
|
15
15
|
FakeWeb.register_uri :get, Responses::Api.releases_url(api.apikey, app_name), body: Responses::Api.releases
|
16
16
|
FakeWeb.register_uri :get, Responses::Api.stacks_url(api.apikey, app_name), body: Responses::Api.stacks
|
17
|
+
|
18
|
+
FakeWeb.register_uri :post, Responses::Api.apps_url(api.apikey), body: Responses::Api.create_app
|
19
|
+
#FakeWeb.register_uri :post, Responses::Api.apps_url(api.apikey), request_body: "app[name]=test_app&app[stack]=bamboo", body: Responses::Api.create_app("test_app", "bamboo")
|
20
|
+
|
21
|
+
FakeWeb.register_uri :put, Responses::Api.rename_app_url(api.apikey), body: Responses::Api.rename_app
|
22
|
+
FakeWeb.register_uri :put, Responses::Api.transfer_app_url(api.apikey), body: Responses::Api.transfer_app
|
23
|
+
|
24
|
+
FakeWeb.register_uri :delete, Responses::Api.apps_by_name_url(api.apikey), body: "{}"
|
17
25
|
end
|
18
26
|
|
19
27
|
let(:api) { Heroku::Client::Api.new "apikey" }
|
@@ -36,6 +44,42 @@ describe Heroku::Client::Api do
|
|
36
44
|
end
|
37
45
|
end
|
38
46
|
|
47
|
+
describe "#create_app" do
|
48
|
+
it "returns created app" do
|
49
|
+
api.create_app.stack.should eq("cedar")
|
50
|
+
end
|
51
|
+
|
52
|
+
=begin
|
53
|
+
context "when parameters are passed" do
|
54
|
+
let(:created_app) { api.create_app name: "test_app", stack: "bamboo" }
|
55
|
+
|
56
|
+
it "returns created app with given name" do
|
57
|
+
created_app.name.should eq("test_app")
|
58
|
+
end
|
59
|
+
|
60
|
+
it "returns create app with given stack"
|
61
|
+
end
|
62
|
+
=end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#rename_app" do
|
66
|
+
it "returns the new name for app" do
|
67
|
+
api.rename_app("example_old", "example_new").name.should eq("example_new")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#transfer_app" do
|
72
|
+
it "is success" do
|
73
|
+
api.transfer_app "example", "new_owner@email.com"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#delete_app" do
|
78
|
+
it "is success" do
|
79
|
+
api.delete_app "example"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
39
83
|
describe "#collaborators" do
|
40
84
|
let(:collaborators) { api.collaborators(app_name) }
|
41
85
|
|
@@ -14,35 +14,37 @@ describe Heroku::Client::Http do
|
|
14
14
|
Http.new
|
15
15
|
end
|
16
16
|
|
17
|
-
describe "
|
17
|
+
describe "#request" do
|
18
18
|
context "success" do
|
19
19
|
before do
|
20
20
|
FakeWeb.register_uri :get, Responses::Api.apps_url(http.apikey), body: Responses::Api.apps
|
21
21
|
FakeWeb.register_uri :get, Responses::Api.apps_by_name_url(http.apikey), body: Responses::Api.apps_by_name
|
22
22
|
end
|
23
23
|
|
24
|
+
let(:result) { http.request(:get, "apps") }
|
25
|
+
|
24
26
|
it "parses the response body" do
|
25
|
-
|
27
|
+
result.should be_a(Array)
|
26
28
|
end
|
27
29
|
|
28
30
|
it "parses the json hash to HerokuObj" do
|
29
|
-
|
31
|
+
result.first.should be_a(Heroku::Client::HerokuObj)
|
30
32
|
end
|
31
33
|
|
32
34
|
it "parses the json hash to HerokuObj" do
|
33
|
-
http.get
|
35
|
+
http.request(:get, "apps/example").should be_a(Heroku::Client::HerokuObj)
|
34
36
|
end
|
35
37
|
end
|
36
38
|
|
37
39
|
shared_examples "http request error" do |http_code, http_msg, error_class|
|
38
40
|
before do
|
39
|
-
FakeWeb.register_uri :get, "https://:apikey@api.heroku.com/apps", status: [http_code, http_msg]
|
41
|
+
FakeWeb.register_uri :get, "https://:apikey@api.heroku.com/apps", status: [http_code, http_msg], body: '{ "error": "The error message" }'
|
40
42
|
end
|
41
43
|
|
42
44
|
it "raises #{error_class}" do
|
43
45
|
expect {
|
44
|
-
http.get
|
45
|
-
}.to raise_error(error_class)
|
46
|
+
http.request(:get, "apps")
|
47
|
+
}.to raise_error(error_class, 'The error message')
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
@@ -75,7 +77,15 @@ describe Heroku::Client::Http do
|
|
75
77
|
end
|
76
78
|
|
77
79
|
context "unknown error" do
|
78
|
-
|
80
|
+
before do
|
81
|
+
FakeWeb.register_uri :get, "https://:apikey@api.heroku.com/apps", status: ["500", "Internal Server Error"], body: '{ "error": "The error message" }'
|
82
|
+
end
|
83
|
+
|
84
|
+
it "raises UnkownError" do
|
85
|
+
expect {
|
86
|
+
http.request :get, "apps"
|
87
|
+
}.to raise_error(Heroku::Client::UnknownError)
|
88
|
+
end
|
79
89
|
end
|
80
90
|
end
|
81
91
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Heroku::Client::JSONUtil do
|
4
|
+
|
5
|
+
describe "#parse_error" do
|
6
|
+
let(:json) { Heroku::Client::JSONUtil.new }
|
7
|
+
|
8
|
+
shared_examples "error parser" do |body, expected|
|
9
|
+
it "should parse error" do
|
10
|
+
json.parse_error(body).should eq(expected)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when error is json" do
|
15
|
+
context "and error is object" do
|
16
|
+
it_behaves_like "error parser", '{ "error": "The error message" }', "The error message"
|
17
|
+
end
|
18
|
+
|
19
|
+
context "and error is array" do
|
20
|
+
it_behaves_like "error parser", '[["name","is already taken"]]', 'name is already taken'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when error is plain text" do
|
25
|
+
it_behaves_like "error parser", 'Some plain text error message', 'Some plain text error message'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/spec/responses/api.rb
CHANGED
@@ -24,6 +24,48 @@ module Responses
|
|
24
24
|
EJSON
|
25
25
|
end
|
26
26
|
|
27
|
+
def self.create_app(app_name = "example", stack = "cedar")
|
28
|
+
<<-EJSON
|
29
|
+
{
|
30
|
+
"id": 1000000,
|
31
|
+
"name": "#{app_name}",
|
32
|
+
"create_status": "complete",
|
33
|
+
"created_at": "2011/01/01 00:00:00 -0700",
|
34
|
+
"stack": "#{stack}",
|
35
|
+
"requested_stack": null,
|
36
|
+
"repo_migrate_status": "complete",
|
37
|
+
"slug_size": 1000000,
|
38
|
+
"repo_size": 1000000,
|
39
|
+
"dynos": 1,
|
40
|
+
"workers": 0
|
41
|
+
}
|
42
|
+
EJSON
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.rename_app_url(apikey)
|
46
|
+
base_url apikey, "apps/example_old"
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.rename_app
|
50
|
+
<<-EJSON
|
51
|
+
{
|
52
|
+
"name": "example_new"
|
53
|
+
}
|
54
|
+
EJSON
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.transfer_app_url(apikey)
|
58
|
+
base_url apikey, "apps/example"
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.transfer_app
|
62
|
+
<<-EJSON
|
63
|
+
{
|
64
|
+
"name": "name"
|
65
|
+
}
|
66
|
+
EJSON
|
67
|
+
end
|
68
|
+
|
27
69
|
def self.apps_by_name_url(apikey)
|
28
70
|
base_url(apikey, "apps/example")
|
29
71
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heroku-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httparty
|
@@ -110,10 +110,12 @@ files:
|
|
110
110
|
- lib/heroku-client/api.rb
|
111
111
|
- lib/heroku-client/heroku_obj.rb
|
112
112
|
- lib/heroku-client/http.rb
|
113
|
+
- lib/heroku-client/json_util.rb
|
113
114
|
- lib/heroku-client/version.rb
|
114
115
|
- spec/heroku-client/api_spec.rb
|
115
116
|
- spec/heroku-client/heroku_obj_spec.rb
|
116
117
|
- spec/heroku-client/http_spec.rb
|
118
|
+
- spec/heroku-client/json_util_spec.rb
|
117
119
|
- spec/heroku-client_spec.rb
|
118
120
|
- spec/responses/api.rb
|
119
121
|
- spec/spec_helper.rb
|
@@ -145,6 +147,8 @@ test_files:
|
|
145
147
|
- spec/heroku-client/api_spec.rb
|
146
148
|
- spec/heroku-client/heroku_obj_spec.rb
|
147
149
|
- spec/heroku-client/http_spec.rb
|
150
|
+
- spec/heroku-client/json_util_spec.rb
|
148
151
|
- spec/heroku-client_spec.rb
|
149
152
|
- spec/responses/api.rb
|
150
153
|
- spec/spec_helper.rb
|
154
|
+
has_rdoc:
|