action_kit_rest 0.1.1
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.
- checksums.yaml +15 -0
- data/.document +5 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +112 -0
- data/LICENSE.txt +24 -0
- data/README.md +23 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/action_kit_rest.gemspec +107 -0
- data/lib/action_kit_rest.rb +30 -0
- data/lib/action_kit_rest/action.rb +7 -0
- data/lib/action_kit_rest/api.rb +53 -0
- data/lib/action_kit_rest/base.rb +37 -0
- data/lib/action_kit_rest/client.rb +35 -0
- data/lib/action_kit_rest/list.rb +12 -0
- data/lib/action_kit_rest/page.rb +11 -0
- data/lib/action_kit_rest/pages/base.rb +20 -0
- data/lib/action_kit_rest/pages/import_page.rb +9 -0
- data/lib/action_kit_rest/pages/signup_page.rb +9 -0
- data/lib/action_kit_rest/railties.rb +7 -0
- data/lib/action_kit_rest/response/collection.rb +25 -0
- data/lib/action_kit_rest/response/raise_error.rb +25 -0
- data/lib/action_kit_rest/response/validation_error.rb +19 -0
- data/lib/action_kit_rest/response/wrapper.rb +120 -0
- data/lib/action_kit_rest/tag.rb +20 -0
- data/lib/action_kit_rest/user.rb +7 -0
- data/lib/action_kit_rest/version.rb +10 -0
- data/spec/action_kit_rest/logger_spec.rb +20 -0
- data/spec/action_kit_rest/page_spec.rb +87 -0
- data/spec/action_kit_rest/pages/input_page_spec.rb +55 -0
- data/spec/action_kit_rest/user_spec.rb +32 -0
- data/spec/fixtures/error.json +1 -0
- data/spec/fixtures/page/collection.json +984 -0
- data/spec/fixtures/page/object.json +18 -0
- data/spec/fixtures/user/object.json +1 -0
- data/spec/spec_helper.rb +43 -0
- metadata +237 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
module ActionKitRest
|
2
|
+
class Base < Vertebrae::Model
|
3
|
+
|
4
|
+
def list(filters = {})
|
5
|
+
client.get_request(normalized_base_path, filters)
|
6
|
+
end
|
7
|
+
|
8
|
+
def get(id)
|
9
|
+
client.get_request("#{normalized_base_path}#{id}/")
|
10
|
+
end
|
11
|
+
|
12
|
+
def create(params)
|
13
|
+
resp = client.post_json_request(normalized_base_path, params)
|
14
|
+
id = extract_id_from_response(resp)
|
15
|
+
get(id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def update(id, params)
|
19
|
+
client.put_json_request("#{normalized_base_path}#{id}/", params)
|
20
|
+
get(id)
|
21
|
+
end
|
22
|
+
|
23
|
+
def normalized_base_path
|
24
|
+
"#{base_path}/"
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def extract_id_from_response(resp)
|
30
|
+
extract_id_from_location(resp.response.headers["location"])
|
31
|
+
end
|
32
|
+
|
33
|
+
def extract_id_from_location(location)
|
34
|
+
location.scan(/\/(\d+)\/$/).first.first
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'action_kit_rest/api'
|
2
|
+
|
3
|
+
module ActionKitRest
|
4
|
+
class Client < API
|
5
|
+
|
6
|
+
def page
|
7
|
+
@page ||= ActionKitRest::Page.new(client: self)
|
8
|
+
end
|
9
|
+
|
10
|
+
def import_page
|
11
|
+
@import_page ||= ActionKitRest::Pages::ImportPage.new(client: self)
|
12
|
+
end
|
13
|
+
|
14
|
+
def signup_page
|
15
|
+
@signup_page ||= ActionKitRest::Pages::SignupPage.new(client: self)
|
16
|
+
end
|
17
|
+
|
18
|
+
def action
|
19
|
+
@action ||= ActionKitRest::Action.new(client: self)
|
20
|
+
end
|
21
|
+
|
22
|
+
def tag
|
23
|
+
@tag ||= ActionKitRest::Tag.new(client: self)
|
24
|
+
end
|
25
|
+
|
26
|
+
def list
|
27
|
+
@list ||= ActionKitRest::List.new(client: self)
|
28
|
+
end
|
29
|
+
|
30
|
+
def user
|
31
|
+
@user ||= ActionKitRest::User.new(client: self)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ActionKitRest
|
2
|
+
module Pages
|
3
|
+
class Base < ActionKitRest::Base
|
4
|
+
# allows finding by name
|
5
|
+
def find(name)
|
6
|
+
response = list(name: name)
|
7
|
+
response.obj.first
|
8
|
+
end
|
9
|
+
|
10
|
+
def find_or_create(params)
|
11
|
+
page = find(params[:name])
|
12
|
+
if page.blank?
|
13
|
+
page = create(params)
|
14
|
+
end
|
15
|
+
page
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# A class responsible for proxing to faraday response &
|
2
|
+
# or a pagination collection.
|
3
|
+
module ActionKitRest
|
4
|
+
module Response
|
5
|
+
class Collection
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
attr_reader :meta
|
9
|
+
attr_reader :objects
|
10
|
+
|
11
|
+
|
12
|
+
def initialize(meta, objects)
|
13
|
+
@meta = meta
|
14
|
+
@objects = objects
|
15
|
+
end
|
16
|
+
|
17
|
+
def each(&block)
|
18
|
+
# todo handle pagination somehow!
|
19
|
+
objects.each do |o|
|
20
|
+
block.call(o)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module ActionKitRest
|
2
|
+
module Response
|
3
|
+
class RaiseError < Faraday::Response::Middleware
|
4
|
+
|
5
|
+
def on_complete(response)
|
6
|
+
status_code = response[:status].to_i
|
7
|
+
if (400...600).include? status_code
|
8
|
+
if status_code == 400
|
9
|
+
raise ActionKitRest::Response::ValidationError.new(url: response[:url].to_s, body: response[:body])
|
10
|
+
elsif status_code == 404
|
11
|
+
raise ActionKitRest::Response::NotFound.new(response[:url].to_s)
|
12
|
+
else
|
13
|
+
raise Exception.new(error_message(response))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def error_message(response)
|
19
|
+
"#{response[:method].to_s.upcase} #{response[:url].to_s}: #{response[:status]} \n\n #{response[:body] if response[:body]}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class NotFound < Exception ; end
|
24
|
+
end # Response::RaiseError
|
25
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActionKitRest
|
2
|
+
module Response
|
3
|
+
class ValidationError < StandardError
|
4
|
+
attr_accessor :errors, :url, :body
|
5
|
+
|
6
|
+
def initialize(params)
|
7
|
+
self.url = params[:url]
|
8
|
+
self.body = params[:body]
|
9
|
+
self.errors = JSON.parse(params[:body])['errors']
|
10
|
+
super()
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
"#{super()} \n url: #{url} \n body: #{body} \n errors: #{errors}"
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module ActionKitRest
|
2
|
+
module Response
|
3
|
+
class Wrapper
|
4
|
+
include Enumerable
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
attr_reader :response
|
8
|
+
attr_reader :kind
|
9
|
+
attr_reader :obj
|
10
|
+
|
11
|
+
def_delegators :body, :empty?, :size, :include?, :length, :to_a, :first, :flatten, :include?, :keys, :[]
|
12
|
+
|
13
|
+
def initialize(response)
|
14
|
+
@response = response
|
15
|
+
|
16
|
+
if response.body.respond_to?(:meta) && response.body.meta
|
17
|
+
@kind = :collection
|
18
|
+
@obj = ActionKitRest::Response::Collection.new(response.body.meta, response.body.objects)
|
19
|
+
else
|
20
|
+
@kind = :object
|
21
|
+
@obj = response.body
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def collection?
|
26
|
+
kind == :collection
|
27
|
+
end
|
28
|
+
|
29
|
+
def object?
|
30
|
+
kind == :object
|
31
|
+
end
|
32
|
+
|
33
|
+
# Request url
|
34
|
+
def url
|
35
|
+
response.env[:url].to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
def body=(value)
|
39
|
+
@body = value
|
40
|
+
@env[:body] = value
|
41
|
+
end
|
42
|
+
|
43
|
+
# Response raw body
|
44
|
+
def body
|
45
|
+
@body ? @body : response.body
|
46
|
+
end
|
47
|
+
|
48
|
+
# Response status
|
49
|
+
def status
|
50
|
+
response.status
|
51
|
+
end
|
52
|
+
|
53
|
+
def success?
|
54
|
+
response.success?
|
55
|
+
end
|
56
|
+
|
57
|
+
def redirect?
|
58
|
+
status.to_i >= 300 && status.to_i < 400
|
59
|
+
end
|
60
|
+
|
61
|
+
def client_error?
|
62
|
+
status.to_i >= 400 && status.to_i < 500
|
63
|
+
end
|
64
|
+
|
65
|
+
def server_error?
|
66
|
+
status.to_i >= 500 && status.to_i < 600
|
67
|
+
end
|
68
|
+
|
69
|
+
# Lookup an attribute from the body if hash, otherwise behave like array index.
|
70
|
+
# Convert any key to string before calling.
|
71
|
+
#
|
72
|
+
def [](key)
|
73
|
+
if self.body.is_a?(Array)
|
74
|
+
self.body[key]
|
75
|
+
else
|
76
|
+
self.body.send(:"#{key}")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Return response body as string
|
81
|
+
#
|
82
|
+
def to_s
|
83
|
+
body.to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
# Convert the ResponseWrapper into a Hash
|
87
|
+
#
|
88
|
+
def to_hash
|
89
|
+
body.to_hash
|
90
|
+
end
|
91
|
+
|
92
|
+
# Convert the ResponseWrapper into an Array
|
93
|
+
#
|
94
|
+
def to_ary
|
95
|
+
body.to_ary
|
96
|
+
end
|
97
|
+
|
98
|
+
# if a raw object, just delegate
|
99
|
+
def method_missing(method_name, *args, &block)
|
100
|
+
if object?
|
101
|
+
obj.send(method_name, &block)
|
102
|
+
else
|
103
|
+
super
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Iterate over each resource inside the collection
|
108
|
+
#
|
109
|
+
def each(&block)
|
110
|
+
if collection?
|
111
|
+
obj.each do |o|
|
112
|
+
block.call(o)
|
113
|
+
end
|
114
|
+
else
|
115
|
+
raise("can only iterate over collections")
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ActionKitRest
|
2
|
+
class Tag < Base
|
3
|
+
def base_path
|
4
|
+
'tag'
|
5
|
+
end
|
6
|
+
|
7
|
+
def find(name)
|
8
|
+
response = list(name: name)
|
9
|
+
response.obj.first
|
10
|
+
end
|
11
|
+
|
12
|
+
def find_or_create(name)
|
13
|
+
tag = find(name)
|
14
|
+
if tag.blank?
|
15
|
+
tag = create(name: name)
|
16
|
+
end
|
17
|
+
tag
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActionKitRest do
|
4
|
+
describe 'logging' do
|
5
|
+
it "should have a logger" do
|
6
|
+
ActionKitRest.respond_to?(:logger).should be_true
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should be able to log debug methods" do
|
10
|
+
ActionKitRest.logger.respond_to?(:debug).should be_true
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be settable" do
|
14
|
+
ActionKitRest.respond_to?(:logger=).should be_true
|
15
|
+
log = mock()
|
16
|
+
ActionKitRest.logger = log
|
17
|
+
ActionKitRest.logger.should == log
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActionKitRest::Page do
|
4
|
+
before(:each) do
|
5
|
+
@actionkit = ActionKitRest.new(host: 'test.com')
|
6
|
+
|
7
|
+
logger = mock
|
8
|
+
logger.stub(:debug).and_return(true)
|
9
|
+
|
10
|
+
ActionKitRest.stub(:logger).and_return(logger)
|
11
|
+
Vertebrae::Base.stub(:logger).and_return(logger)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'configuration' do
|
15
|
+
it 'should propagate the host to the page' do
|
16
|
+
@actionkit.connection.configuration.host.should == 'test.com'
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have a client" do
|
20
|
+
@actionkit.page.client.should_not be_nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
describe "retrieval" do
|
26
|
+
before(:each) do
|
27
|
+
stub_get(request_path).to_return(:body => body, :status => status,
|
28
|
+
:headers => {:content_type => "application/json; charset=utf-8"})
|
29
|
+
end
|
30
|
+
|
31
|
+
describe ".list" do
|
32
|
+
let(:status) { 200 }
|
33
|
+
let(:body) { fixture('page/collection.json') }
|
34
|
+
let(:request_path) { 'page/' }
|
35
|
+
|
36
|
+
it "should allow listing the objects" do
|
37
|
+
pages = @actionkit.page.list
|
38
|
+
|
39
|
+
pages.should be_an_instance_of(ActionKitRest::Response::Wrapper)
|
40
|
+
|
41
|
+
pages.each do | obj |
|
42
|
+
obj.should be_an_instance_of(Hashie::Mash)
|
43
|
+
obj.should respond_to(:goal)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe ".page" do
|
49
|
+
|
50
|
+
let(:body) { fixture('page/object.json') }
|
51
|
+
let(:request_path) { 'page/1/' }
|
52
|
+
|
53
|
+
describe "success" do
|
54
|
+
let(:status) { 200 }
|
55
|
+
it "should return a single object" do
|
56
|
+
page = @actionkit.page.get(1)
|
57
|
+
page.goal.should == 10
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "not found" do
|
62
|
+
let(:status) { 404 }
|
63
|
+
|
64
|
+
it "should return nil" do
|
65
|
+
lambda{ @actionkit.page.get(1).should == nil }.should raise_exception(ActionKitRest::Response::NotFound)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "error" do
|
70
|
+
let(:status) { 400 }
|
71
|
+
let(:body) { fixture('error.json') }
|
72
|
+
|
73
|
+
it "should raise an ak validation response error" do
|
74
|
+
lambda{ @actionkit.page.get(1) }.should raise_exception(ActionKitRest::Response::ValidationError)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "an error" do
|
79
|
+
let(:status) { 500 }
|
80
|
+
|
81
|
+
it "should return nil" do
|
82
|
+
lambda{ @actionkit.page.get(1).should == nil }.should raise_exception
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|