alman 0.0.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 +7 -0
- data/.gitignore +4 -0
- data/.travis.yml +16 -0
- data/Gemfile +8 -0
- data/README.md +103 -0
- data/Rakefile +8 -0
- data/VERSION +1 -0
- data/alman.gemspec +29 -0
- data/bin/alman-console +7 -0
- data/gemfiles/default-with-activesupport.gemfile +10 -0
- data/gemfiles/json.gemfile +12 -0
- data/gemfiles/yajl.gemfile +12 -0
- data/lib/alman.rb +68 -0
- data/lib/alman/apibits/api_client.rb +28 -0
- data/lib/alman/apibits/api_endpoint.rb +11 -0
- data/lib/alman/apibits/api_list.rb +88 -0
- data/lib/alman/apibits/api_method.rb +95 -0
- data/lib/alman/apibits/api_object.rb +52 -0
- data/lib/alman/apibits/api_resource.rb +139 -0
- data/lib/alman/apibits/headers_builder.rb +47 -0
- data/lib/alman/apibits/params_builder.rb +27 -0
- data/lib/alman/apibits/path_builder.rb +38 -0
- data/lib/alman/apibits/requester.rb +104 -0
- data/lib/alman/apibits/util.rb +51 -0
- data/lib/alman/clients/default_client.rb +31 -0
- data/lib/alman/endpoints/bookings_endpoint.rb +36 -0
- data/lib/alman/endpoints/calendar_vacancies_endpoint.rb +35 -0
- data/lib/alman/endpoints/calendars_endpoint.rb +48 -0
- data/lib/alman/endpoints/vacancies_endpoint.rb +27 -0
- data/lib/alman/endpoints/vacancy_bookings_endpoint.rb +11 -0
- data/lib/alman/errors/alman_error.rb +13 -0
- data/lib/alman/errors/api_connection_error.rb +4 -0
- data/lib/alman/errors/api_error.rb +35 -0
- data/lib/alman/errors/authentication_error.rb +4 -0
- data/lib/alman/resources/booking.rb +62 -0
- data/lib/alman/resources/calendar.rb +65 -0
- data/lib/alman/resources/vacancy.rb +48 -0
- data/lib/alman/version.rb +3 -0
- data/test/alman/api_client_test.rb +51 -0
- data/test/alman/api_endpoint_test.rb +13 -0
- data/test/alman/api_list_test.rb +49 -0
- data/test/alman/api_method_test.rb +78 -0
- data/test/alman/headers_builder_test.rb +28 -0
- data/test/alman/params_builder_test.rb +57 -0
- data/test/alman/path_builder_test.rb +50 -0
- data/test/alman/requester_test.rb +86 -0
- data/test/alman/util_test.rb +51 -0
- data/test/test_data.rb +72 -0
- data/test/test_helper.rb +41 -0
- metadata +208 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
module Alman
|
4
|
+
class ApiClientTest < ::Test::Unit::TestCase
|
5
|
+
setup do
|
6
|
+
@headers = {
|
7
|
+
:Accept => "application/json",
|
8
|
+
:Authorization => "Fake Auth"
|
9
|
+
}
|
10
|
+
@params = {
|
11
|
+
:customer_id => 123
|
12
|
+
}
|
13
|
+
@client = ApiClient.new(@headers, @params)
|
14
|
+
end
|
15
|
+
|
16
|
+
context '#execute' do
|
17
|
+
setup do
|
18
|
+
@api_method = mock
|
19
|
+
@api_method.stubs(:headers).returns({
|
20
|
+
:fake_header => "fake-header-val"
|
21
|
+
})
|
22
|
+
@api_method.stubs(:headers=)
|
23
|
+
@api_method.stubs(:params).returns({
|
24
|
+
:fake_param => "fake-param"
|
25
|
+
})
|
26
|
+
@api_method.stubs(:params=)
|
27
|
+
@api_method.stubs(:execute)
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'merge the client headers and params into the api_method' do
|
31
|
+
expected_headers = { :hello => true }
|
32
|
+
expected_params = { :goodbye => false }
|
33
|
+
|
34
|
+
ParamsBuilder.expects(:merge).with(@api_method.headers, @headers).returns(expected_headers)
|
35
|
+
ParamsBuilder.expects(:merge).with(@api_method.params, @params).returns(expected_params)
|
36
|
+
|
37
|
+
@api_method.expects(:headers=).with(expected_headers)
|
38
|
+
@api_method.expects(:params=).with(expected_params)
|
39
|
+
|
40
|
+
@client.execute(@api_method)
|
41
|
+
end
|
42
|
+
|
43
|
+
should 'call api_method.execute and return the results' do
|
44
|
+
expected = { :status => "success!" }
|
45
|
+
@api_method.expects(:execute).returns(expected)
|
46
|
+
assert_equal(expected, @client.execute(@api_method))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
module Alman
|
4
|
+
class ApiEndpointTest < ::Test::Unit::TestCase
|
5
|
+
context '#initialize' do
|
6
|
+
should 'set the client and parent' do
|
7
|
+
ep = ApiEndpoint.new("client", "parent")
|
8
|
+
assert_equal("client", ep.client)
|
9
|
+
assert_equal("parent", ep.parent)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
module Alman
|
4
|
+
class ApiListTest < ::Test::Unit::TestCase
|
5
|
+
|
6
|
+
context '#initialize' do
|
7
|
+
setup do
|
8
|
+
@fake_resource = { :data => "fake-data" }
|
9
|
+
@list = ApiList.new(ApiResource, [@fake_resource])
|
10
|
+
end
|
11
|
+
|
12
|
+
should 'set the klass' do
|
13
|
+
assert_equal(ApiResource, @list.klass)
|
14
|
+
end
|
15
|
+
|
16
|
+
should 'convert the data to klass instances' do
|
17
|
+
assert(@list.first.is_a?(ApiResource))
|
18
|
+
assert_equal(@fake_resource, @list.first.json)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context '#refresh_from' do
|
23
|
+
setup do
|
24
|
+
@fake_resource = { :data => "fake-data" }
|
25
|
+
@fake_method = "fake-api-method"
|
26
|
+
@fake_client = "fake-client"
|
27
|
+
@list = ApiList.new(ApiResource, [], "invalid", "invalid")
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'update the api_method' do
|
31
|
+
@list.refresh_from([@fake_resource], @fake_method)
|
32
|
+
assert_equal(@list.api_method, @fake_method)
|
33
|
+
end
|
34
|
+
|
35
|
+
should 'update the client' do
|
36
|
+
@list.refresh_from([@fake_resource], nil, @fake_client)
|
37
|
+
assert_equal(@list.client, @fake_client)
|
38
|
+
end
|
39
|
+
|
40
|
+
should 'clear existing data' do
|
41
|
+
@list.refresh_from(["new-data"])
|
42
|
+
|
43
|
+
assert_nil(@list.api_method)
|
44
|
+
assert_nil(@list.client)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
module Alman
|
4
|
+
class ApiMethodTest < ::Test::Unit::TestCase
|
5
|
+
setup do
|
6
|
+
@method = :get
|
7
|
+
@path = "/testing"
|
8
|
+
@params = { :param_a => "1" }
|
9
|
+
@headers = { :header_a => "a" }
|
10
|
+
@object = mock
|
11
|
+
@api_method = ApiMethod.new(@method, @path, @params, @headers, @object)
|
12
|
+
end
|
13
|
+
|
14
|
+
context '#initialize' do
|
15
|
+
should 'set the api_base' do
|
16
|
+
assert_equal(Alman.api_base, @api_method.api_base)
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'use PathBuilder with path, object, and params' do
|
20
|
+
PathBuilder.expects(:build).with(@path, @object, @params).returns(@path)
|
21
|
+
ApiMethod.new(@method, @path, @params, @headers, @object)
|
22
|
+
end
|
23
|
+
|
24
|
+
should 'use ParamsBuilder with params' do
|
25
|
+
ParamsBuilder.expects(:build).with(@params).returns(@params)
|
26
|
+
ApiMethod.new(@method, @path, @params, @headers, @object)
|
27
|
+
end
|
28
|
+
|
29
|
+
should 'use HeadersBuilder with headers, api_key, and nil auth_header' do
|
30
|
+
HeadersBuilder.expects(:build).with(@headers).returns(@headers)
|
31
|
+
ApiMethod.new(@method, @path, @params, @headers, @object)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context '#execute' do
|
36
|
+
setup do
|
37
|
+
@mock_response = mock
|
38
|
+
@mock_response.stubs(:body).returns('{"status": "success"}')
|
39
|
+
@mock_response.stubs(:code).returns(200)
|
40
|
+
end
|
41
|
+
|
42
|
+
should 'call Requester.request with the set attrs' do
|
43
|
+
Requester.expects(:request).with(@method, @api_method.url, @api_method.params, @api_method.headers).returns(@mock_response)
|
44
|
+
@api_method.execute
|
45
|
+
end
|
46
|
+
|
47
|
+
should 'create an ApiError if the request fails' do
|
48
|
+
Requester.expects(:request).raises(RestClient::RequestTimeout.new)
|
49
|
+
|
50
|
+
assert_raises(ApiError) { @api_method.execute }
|
51
|
+
end
|
52
|
+
|
53
|
+
should 'return the response parsed as json' do
|
54
|
+
Requester.expects(:request).returns(@mock_response)
|
55
|
+
assert_equal({:status => "success"}, @api_method.execute)
|
56
|
+
end
|
57
|
+
|
58
|
+
should 'return an AuthenticationError if the status is 401' do
|
59
|
+
error = RestClient::ExceptionWithResponse.new
|
60
|
+
error.expects(:http_code).returns(401)
|
61
|
+
|
62
|
+
Requester.expects(:request).raises(error)
|
63
|
+
assert_raises(AuthenticationError) { @api_method.execute }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context '#response_json' do
|
68
|
+
setup do
|
69
|
+
@api_method.response_body = 'not-valid-json'
|
70
|
+
end
|
71
|
+
|
72
|
+
should 'throw an error if the response_body isnt valid json' do
|
73
|
+
assert_raises(ApiError) { @api_method.response_json }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
module Alman
|
4
|
+
class HeadersBuilderTest < ::Test::Unit::TestCase
|
5
|
+
|
6
|
+
setup do
|
7
|
+
@headers = {
|
8
|
+
:dog => "dog-value"
|
9
|
+
}
|
10
|
+
@built_headers = HeadersBuilder.build(@headers)
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'set the user_agent' do
|
14
|
+
assert(@built_headers.has_key?(:user_agent))
|
15
|
+
assert(@built_headers[:user_agent].include?(Alman::VERSION))
|
16
|
+
assert(@built_headers[:user_agent].include?(Alman.api_version))
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'set a client user agent' do
|
20
|
+
# This can be raw or json encoded depending on various things
|
21
|
+
unless @built_headers.has_key?(:x_alman_client_user_agent) ||
|
22
|
+
@built_headers.has_key?(:x_alman_client_raw_user_agent)
|
23
|
+
raise "No valid client user agent found"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
module Alman
|
4
|
+
class ParamsBuilderTest < ::Test::Unit::TestCase
|
5
|
+
|
6
|
+
setup do
|
7
|
+
@params = {
|
8
|
+
:dog => "dog-value",
|
9
|
+
"string" => "str-value"
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
context '#clean' do
|
14
|
+
setup do
|
15
|
+
@built_params = ParamsBuilder.clean(@params)
|
16
|
+
end
|
17
|
+
|
18
|
+
should 'convert keys to symbols' do
|
19
|
+
assert(@built_params.has_key?(:string))
|
20
|
+
assert_equal(@params["string"], @built_params[:string])
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'not have any string keys' do
|
24
|
+
@built_params.each do |k, v|
|
25
|
+
assert(k.is_a?(Symbol))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context '#merge' do
|
31
|
+
setup do
|
32
|
+
@to_merge = {
|
33
|
+
:string => "other-str-value",
|
34
|
+
"cat" => "cat-value"
|
35
|
+
}
|
36
|
+
@built_params = ParamsBuilder.merge(@params, @to_merge)
|
37
|
+
end
|
38
|
+
|
39
|
+
should 'convert keys to symbols' do
|
40
|
+
assert(@built_params.has_key?(:cat))
|
41
|
+
assert(@built_params.has_key?(:string))
|
42
|
+
assert(!@built_params.has_key?("string"))
|
43
|
+
end
|
44
|
+
|
45
|
+
should 'merge in all values' do
|
46
|
+
assert_equal(@params[:dog], @built_params[:dog])
|
47
|
+
assert_equal(@to_merge[:string], @built_params[:string])
|
48
|
+
assert_equal(@to_merge["cat"], @built_params[:cat])
|
49
|
+
end
|
50
|
+
|
51
|
+
should 'prioritize values in @to_merge' do
|
52
|
+
assert_equal(@to_merge[:string], @built_params[:string])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
module Alman
|
4
|
+
class PathBuilderTest < ::Test::Unit::TestCase
|
5
|
+
class FakeClass
|
6
|
+
def abc; return "abc-value"; end
|
7
|
+
def self.xyz; return "xyz-value"; end
|
8
|
+
end
|
9
|
+
|
10
|
+
setup do
|
11
|
+
@params = {
|
12
|
+
:dog => "dog-value"
|
13
|
+
}
|
14
|
+
@obj = FakeClass.new
|
15
|
+
end
|
16
|
+
|
17
|
+
should 'use instance methods' do
|
18
|
+
path = "/a/:abc/123"
|
19
|
+
expected = "/a/abc-value/123"
|
20
|
+
|
21
|
+
actual = PathBuilder.build(path, @obj, nil)
|
22
|
+
assert_equal(expected, actual)
|
23
|
+
end
|
24
|
+
|
25
|
+
should 'use class methods' do
|
26
|
+
path = "/a/:xyz/123"
|
27
|
+
expected = "/a/xyz-value/123"
|
28
|
+
|
29
|
+
actual = PathBuilder.build(path, FakeClass, nil)
|
30
|
+
assert_equal(expected, actual)
|
31
|
+
end
|
32
|
+
|
33
|
+
should 'use param values' do
|
34
|
+
path = "/a/:dog/123"
|
35
|
+
expected = "/a/dog-value/123"
|
36
|
+
|
37
|
+
actual = PathBuilder.build(path, nil, @params)
|
38
|
+
assert_equal(expected, actual)
|
39
|
+
end
|
40
|
+
|
41
|
+
should 'use both methods and params' do
|
42
|
+
path = "/a/:dog/:abc/123"
|
43
|
+
expected = "/a/dog-value/abc-value/123"
|
44
|
+
|
45
|
+
actual = PathBuilder.build(path, @obj, @params)
|
46
|
+
assert_equal(expected, actual)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
module Alman
|
4
|
+
class RequesterTest < ::Test::Unit::TestCase
|
5
|
+
setup do
|
6
|
+
end
|
7
|
+
|
8
|
+
context '#prepare_params' do
|
9
|
+
setup do
|
10
|
+
@url = "test_url"
|
11
|
+
@params = { :a => 1, :b => [2, 3] }
|
12
|
+
end
|
13
|
+
|
14
|
+
should 'convert :get params to a query string' do
|
15
|
+
url, params = Requester.prepare_params(:get, @url, @params)
|
16
|
+
assert(url != @url)
|
17
|
+
assert(params.nil?)
|
18
|
+
end
|
19
|
+
|
20
|
+
should 'convert :delete params to a query string' do
|
21
|
+
url, params = Requester.prepare_params(:delete, @url, @params)
|
22
|
+
assert(url != @url)
|
23
|
+
assert(params.nil?)
|
24
|
+
end
|
25
|
+
|
26
|
+
should 'convert :head params to a query string' do
|
27
|
+
url, params = Requester.prepare_params(:head, @url, @params)
|
28
|
+
assert(url != @url)
|
29
|
+
assert(params.nil?)
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'method = :post' do
|
33
|
+
setup do
|
34
|
+
@method = :post
|
35
|
+
end
|
36
|
+
|
37
|
+
should 'not convert params to a query string if a file is in them' do
|
38
|
+
expected = { file: File.new(__FILE__) }
|
39
|
+
url, params = Requester.prepare_params(@method, @url, expected)
|
40
|
+
assert_equal(expected, params)
|
41
|
+
end
|
42
|
+
|
43
|
+
should 'convert params to a query string if a file is not present' do
|
44
|
+
url, params = Requester.prepare_params(@method, @url, @params)
|
45
|
+
assert(params.is_a?(String))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context '#query_string' do
|
51
|
+
should 'join #query_array results with an "&"' do
|
52
|
+
start = { :a => 1, :b => [2, 3] }
|
53
|
+
expected = ["a=1", "b[]=2", "b[]=3"]
|
54
|
+
|
55
|
+
actual = Requester.query_string(start).split('&')
|
56
|
+
actual.each do |str|
|
57
|
+
assert(expected.include?(str))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context '#query_array' do
|
63
|
+
should 'convert { :a => "value" } to ["a=value"]' do
|
64
|
+
start = { :a => "value" }
|
65
|
+
finish = ["a=value"]
|
66
|
+
|
67
|
+
assert_equal(finish, Requester.query_array(start))
|
68
|
+
end
|
69
|
+
|
70
|
+
should 'convert { :a => { :b => { :c => "cvalue" } } } to ["a[b][c]=cvalue"]' do
|
71
|
+
start = { :a => { :b => { :c => "cvalue" } } }
|
72
|
+
finish = ["a[b][c]=cvalue"]
|
73
|
+
|
74
|
+
assert_equal(finish, Requester.query_array(start))
|
75
|
+
end
|
76
|
+
|
77
|
+
should 'convert { :a => [1, 2] } to ["a[]=1", "a[]=2"]' do
|
78
|
+
start = { :a => [1, 2] }
|
79
|
+
finish = ["a[]=1", "a[]=2"]
|
80
|
+
|
81
|
+
assert_equal(finish, Requester.query_array(start))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
module Alman
|
4
|
+
class UtilTest < ::Test::Unit::TestCase
|
5
|
+
context '#symbolize_keys' do
|
6
|
+
should "convert keys to symbols" do
|
7
|
+
start = {
|
8
|
+
'foo' => 'bar',
|
9
|
+
'array' => [{ 'foo' => 'bar' }],
|
10
|
+
'nested' => {
|
11
|
+
1 => 2,
|
12
|
+
:symbol => 9,
|
13
|
+
'string' => nil
|
14
|
+
}
|
15
|
+
}
|
16
|
+
finish = {
|
17
|
+
:foo => 'bar',
|
18
|
+
:array => [{ :foo => 'bar' }],
|
19
|
+
:nested => {
|
20
|
+
1 => 2,
|
21
|
+
:symbol => 9,
|
22
|
+
:string => nil
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
symbolized = Util.symbolize_keys(start)
|
27
|
+
assert_equal(finish, symbolized)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context '#sorta_deep_clone' do
|
32
|
+
# Super hand wavy test.. but it works for now so whatever.
|
33
|
+
should 'clone well enough that we dont accidentally alter json' do
|
34
|
+
start = { :a => "abc", :b => [ { :c => "c-1" }, { :c => "c-2" } ] }
|
35
|
+
cloned = Util.sorta_deep_clone(start)
|
36
|
+
|
37
|
+
cloned[:a] = "123"
|
38
|
+
cloned[:b] << { :c => "c-3" }
|
39
|
+
cloned[:b][0][:c] = "c-one"
|
40
|
+
|
41
|
+
assert_equal({ :a => "abc", :b => [ { :c => "c-1" }, { :c => "c-2" } ] }, start)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context '#constantize' do
|
46
|
+
should 'convert :ApiResource to the class object' do
|
47
|
+
assert_equal(ApiResource, Util.constantize(:ApiResource))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|