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.
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