alman 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.travis.yml +16 -0
  4. data/Gemfile +8 -0
  5. data/README.md +103 -0
  6. data/Rakefile +8 -0
  7. data/VERSION +1 -0
  8. data/alman.gemspec +29 -0
  9. data/bin/alman-console +7 -0
  10. data/gemfiles/default-with-activesupport.gemfile +10 -0
  11. data/gemfiles/json.gemfile +12 -0
  12. data/gemfiles/yajl.gemfile +12 -0
  13. data/lib/alman.rb +68 -0
  14. data/lib/alman/apibits/api_client.rb +28 -0
  15. data/lib/alman/apibits/api_endpoint.rb +11 -0
  16. data/lib/alman/apibits/api_list.rb +88 -0
  17. data/lib/alman/apibits/api_method.rb +95 -0
  18. data/lib/alman/apibits/api_object.rb +52 -0
  19. data/lib/alman/apibits/api_resource.rb +139 -0
  20. data/lib/alman/apibits/headers_builder.rb +47 -0
  21. data/lib/alman/apibits/params_builder.rb +27 -0
  22. data/lib/alman/apibits/path_builder.rb +38 -0
  23. data/lib/alman/apibits/requester.rb +104 -0
  24. data/lib/alman/apibits/util.rb +51 -0
  25. data/lib/alman/clients/default_client.rb +31 -0
  26. data/lib/alman/endpoints/bookings_endpoint.rb +36 -0
  27. data/lib/alman/endpoints/calendar_vacancies_endpoint.rb +35 -0
  28. data/lib/alman/endpoints/calendars_endpoint.rb +48 -0
  29. data/lib/alman/endpoints/vacancies_endpoint.rb +27 -0
  30. data/lib/alman/endpoints/vacancy_bookings_endpoint.rb +11 -0
  31. data/lib/alman/errors/alman_error.rb +13 -0
  32. data/lib/alman/errors/api_connection_error.rb +4 -0
  33. data/lib/alman/errors/api_error.rb +35 -0
  34. data/lib/alman/errors/authentication_error.rb +4 -0
  35. data/lib/alman/resources/booking.rb +62 -0
  36. data/lib/alman/resources/calendar.rb +65 -0
  37. data/lib/alman/resources/vacancy.rb +48 -0
  38. data/lib/alman/version.rb +3 -0
  39. data/test/alman/api_client_test.rb +51 -0
  40. data/test/alman/api_endpoint_test.rb +13 -0
  41. data/test/alman/api_list_test.rb +49 -0
  42. data/test/alman/api_method_test.rb +78 -0
  43. data/test/alman/headers_builder_test.rb +28 -0
  44. data/test/alman/params_builder_test.rb +57 -0
  45. data/test/alman/path_builder_test.rb +50 -0
  46. data/test/alman/requester_test.rb +86 -0
  47. data/test/alman/util_test.rb +51 -0
  48. data/test/test_data.rb +72 -0
  49. data/test/test_helper.rb +41 -0
  50. 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