http_magic 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ae2f80540b2ebc639265dd8a2b4afffa39b72f27
4
+ data.tar.gz: 38ed7512bca5927a8961ce9279e85b61521902ad
5
+ SHA512:
6
+ metadata.gz: 0b9c6a898d4172ef774bc79e46a8b714d137270a0022bb3cf09f97d68b6b02e180d151b4d736bd9884b9e010cf8755b9e39c054a9ac95d82584b4f6b1fe4ae84
7
+ data.tar.gz: 53da0b3b6cdf245d2afcaefd1e0f8c3ab3a4e6522d3e344a1585cf14364a55c774d7ee4492e861bf4f4bb4c62d34b3a8c1d7dae6cc235e80ef2750329b3e9a99
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,45 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ http_magic (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ addressable (2.3.5)
10
+ coderay (1.1.0)
11
+ columnize (0.3.6)
12
+ crack (0.4.1)
13
+ safe_yaml (~> 0.9.0)
14
+ debugger (1.6.5)
15
+ columnize (>= 0.3.1)
16
+ debugger-linecache (~> 1.2.0)
17
+ debugger-ruby_core_source (~> 1.3.1)
18
+ debugger-linecache (1.2.0)
19
+ debugger-ruby_core_source (1.3.1)
20
+ method_source (0.8.2)
21
+ minitest (4.7.5)
22
+ pry (0.9.12.4)
23
+ coderay (~> 1.0)
24
+ method_source (~> 0.8)
25
+ slop (~> 3.4)
26
+ pry-debugger (0.2.2)
27
+ debugger (~> 1.3)
28
+ pry (~> 0.9.10)
29
+ rake (10.1.1)
30
+ safe_yaml (0.9.7)
31
+ slop (3.4.7)
32
+ webmock (1.16.1)
33
+ addressable (>= 2.2.7)
34
+ crack (>= 0.3.2)
35
+
36
+ PLATFORMS
37
+ ruby
38
+
39
+ DEPENDENCIES
40
+ http_magic!
41
+ minitest (~> 4.7.0)
42
+ pry
43
+ pry-debugger
44
+ rake
45
+ webmock (~> 1.16.0)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 GradesFirst
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ httpmagic
2
+ =========
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new(:test) do |test|
4
+ test.libs << 'test'
5
+ test.test_files = FileList["test/**/*.rb"].exclude("test/test_helper.rb")
6
+ test.verbose = false
7
+ test.warning = false
8
+ end
@@ -0,0 +1,23 @@
1
+
2
+ Gem::Specification.new do |s|
3
+ s.name = 'http_magic'
4
+ s.version = '0.1.1'
5
+ s.licenses = ['MIT']
6
+ s.summary = 'Provides a more Object Oriented interface to RESTful apis.'
7
+
8
+ s.author = 'GradesFirst'
9
+ s.email = 'tech@gradesfirst.com'
10
+ s.homepage = 'https://github.com/Thoughtwright-LLC/httpmagic'
11
+
12
+ s.files = Dir['{lib}/**/*.rb', 'bin/*', 'LICENSE', '*.md']
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test}/*`.split("\n")
15
+
16
+ s.require_paths = ['lib']
17
+
18
+ s.add_development_dependency 'rake', '~> 0'
19
+ s.add_development_dependency 'minitest', '~> 4.7'
20
+ s.add_development_dependency 'webmock', '~> 1.16'
21
+ s.add_development_dependency 'pry', '~> 0'
22
+ s.add_development_dependency 'pry-debugger', '~> 0'
23
+ end
data/lib/http_magic.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'http_magic/api'
2
+
3
+ module HttpMagic
4
+ end
@@ -0,0 +1,218 @@
1
+ require 'json'
2
+ require 'http_magic/uri'
3
+ require 'http_magic/request'
4
+
5
+ module HttpMagic
6
+ # A magical class that interacts with HTTP resources with a minimal amount of
7
+ # configuration.
8
+ #
9
+ # Assuming an api where the url http://www.example.com/api/v1/foo/99 responds
10
+ # with the following.
11
+ #
12
+ # Header:
13
+ #
14
+ # Content-Type: application/json
15
+ #
16
+ # Body:
17
+ #
18
+ # {
19
+ # "name": "Foo Bar"
20
+ # }
21
+ #
22
+ # == Example
23
+ #
24
+ # class ExampleApi < HttpMagic::Api
25
+ # url 'www.example.com'
26
+ # namespace 'api/v1'
27
+ # headers({'X-AuthToken' => 'token'})
28
+ # end
29
+ #
30
+ # ExampleApi.foo[99].get['name']
31
+ # => "Foo Bar"
32
+ #
33
+ # ExampleApi.foo.create.post(name: 'New Foo')
34
+ # => { 'name' => 'New Foo' }
35
+ class Api < BasicObject
36
+ # Makes the new method private so that instances of this class and it's
37
+ # children can only be instantiated through the class method method_missing.
38
+ # This is needed to enforce the intended usage of HttpMagic where the class
39
+ # is configured to represent an http location. Once it is configured, the
40
+ # location is interacted with dynamically with chained methods that correspond
41
+ # with parts of URNs found at the location.
42
+ class << self
43
+ private :new
44
+ end
45
+
46
+ # Sets or returns the request headers for an HttpMagic based class. The
47
+ # headers will be passed along to each resource request being made.
48
+ #
49
+ # == Example
50
+ #
51
+ # class ExampleApi < HttpMagic:Api
52
+ # url 'www.example.com'
53
+ # headers({'X-AuthToken' => 'token'})
54
+ # end
55
+ def self.headers(value = :not_provided)
56
+ unless value == :not_provided
57
+ @headers = value
58
+ end
59
+ @headers
60
+ end
61
+
62
+ # Sets or returns the namespace for an HttpMagic based class. The namespace
63
+ # will be prefixed to the urn for each request made to the url.
64
+ #
65
+ # Assuming an api where each resource is namespaced with 'api/v1' and where
66
+ # the url http://www.example.com/api/v1/foo/99 responds with the following.
67
+ #
68
+ # Header:
69
+ #
70
+ # Content-Type: application/json
71
+ #
72
+ # Body:
73
+ #
74
+ # {
75
+ # "name": "Foo Bar"
76
+ # }
77
+ #
78
+ # == Example
79
+ #
80
+ # class ExampleApi < HttpMagic:Api
81
+ # url 'www.example.com'
82
+ # namespace 'api/v1'
83
+ # end
84
+ #
85
+ # ExampleApi.foo[99].get['name']
86
+ # => "Foo Bar"
87
+ #
88
+ def self.namespace(value = :not_provided)
89
+ unless value == :not_provided
90
+ @namespace = value
91
+ end
92
+ @namespace
93
+ end
94
+
95
+ # Sets or returns the uniform resource locator for the HTTP resource.
96
+ #
97
+ # == Example
98
+ #
99
+ # class ExampleApi < HttpMagic::Api
100
+ # url 'www.example.com'
101
+ # end
102
+ def self.url(value = :not_provided)
103
+ unless value == :not_provided
104
+ @url = value
105
+ end
106
+ @url
107
+ end
108
+
109
+ # Class scoped method_missing that starts the magic of creating urns
110
+ # through meta programming by instantiating an instance of the class
111
+ # and delegating the first part of the urn to that instance. This method
112
+ # is an implementation of the Factory Method design pattern.
113
+ def self.method_missing(name, *args, &block)
114
+ new(@url, @namespace, @headers).__send__(name, *args)
115
+ end
116
+
117
+ def initialize(url, namespace, headers)
118
+ @uri = Uri.new(url)
119
+ @uri.namespace = namespace
120
+ @headers = headers
121
+ end
122
+
123
+ # Resource index reference intended to allow for the use of numbers in a urn
124
+ # such as the following 'foo/99' being referenced by ExampleApi.foo[99]. It
125
+ # can also be used to allow for HttpMagic methods to be specified for a urn
126
+ # such as 'foo/get' being referenced by ExampleApi.foo[:get]. Finally, it can
127
+ # be used for urn parts that are not valid Ruby methods such as 'foo/%5B%5D'
128
+ # being referenced by ExampleApi.foo["%5B%5D"].
129
+ #
130
+ # * part - a part of a urn such that 'foo' and 'bar' would be parts of the urn
131
+ # 'foo/bar'.
132
+ #
133
+ # Returns a reference to its instance so that urn parts can be chained
134
+ # together.
135
+ def [](part)
136
+ @uri.parts << part.to_s
137
+ self
138
+ end
139
+
140
+ # Gets a resource from the URI and returns it based on its content type.
141
+ # JSON content will be parsed and returned as equivalent Ruby objects. All
142
+ # other content types will be returned as text.
143
+ #
144
+ # Assuming an api where each resource is namespaced with 'api/v1' and where
145
+ # the url http://www.example.com/api/v1/foo/99 responds with the following.
146
+ #
147
+ # Header:
148
+ #
149
+ # Content-Type: application/json
150
+ #
151
+ # Body:
152
+ #
153
+ # {
154
+ # "name": "Foo Bar"
155
+ # }
156
+ #
157
+ # == Example
158
+ #
159
+ # class ExampleApi < HttpMagic::Api
160
+ # url 'www.example.com'
161
+ # namespace 'api/v1'
162
+ # end
163
+ #
164
+ # ExampleApi.foo[99].get
165
+ # => { "name" => "Foo Bar" }
166
+ def get
167
+ request = Request.new(@uri,
168
+ headers: @headers
169
+ )
170
+ request.get
171
+ end
172
+
173
+ # POST's a resource from the URI and returns the result based on its content
174
+ # type. JSON content will be parsed and returned as equivalent Ruby objects.
175
+ # All other content types will be returned as text.
176
+ #
177
+ # Assuming an api where each resource is namespaced with 'api/v1' and where
178
+ # the url http://www.example.com/api/v1/foo/create responds with the
179
+ # following when a 'name' is sent with the request.
180
+ #
181
+ # Header:
182
+ #
183
+ # Content-Type: application/json
184
+ #
185
+ # Body:
186
+ #
187
+ # {
188
+ # "name": "New Foo"
189
+ # }
190
+ #
191
+ # == Example
192
+ #
193
+ # class ExampleApi < HttpMagic::Api
194
+ # url 'www.example.com'
195
+ # namespace 'api/v1'
196
+ # end
197
+ #
198
+ # ExampleApi.foo.create.post(name: 'New Foo')
199
+ # => { "name" => "New Foo" }
200
+ def post(data = {})
201
+ request = Request.new(@uri,
202
+ headers: @headers,
203
+ data: data,
204
+ )
205
+ request.post
206
+ end
207
+
208
+ # Instance scoped method_missing that accumulates the URN parts used in
209
+ # forming the URI. It returns a reference to the current instance so that
210
+ # method and [] based parts can be chained together to from the URN. In the
211
+ # case of ExampleApi.foo[99] the 'foo' method is accumlated as a URN part
212
+ # that will form the resulting URI.
213
+ def method_missing(part, *args, &block)
214
+ @uri.parts << part.to_s
215
+ self
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,82 @@
1
+ require 'net/http'
2
+ require 'json'
3
+
4
+ module HttpMagic
5
+ # Encapsulating class to hold all of the infrastructure to make the actual
6
+ # requests to the api. It receives at a minimum a HttpMagic::Uri object which
7
+ # manages the url building.
8
+ #
9
+ # == Example
10
+ #
11
+ # uri_object = HttpMagic::Uri.new('http://example.com')
12
+ #
13
+ # request = Request.new(uri_object)
14
+ #
15
+ # request.get
16
+ # => { 'name' => 'Foo Bar' }
17
+ class Request
18
+ def initialize(uri, options = {})
19
+ @uri = uri
20
+ @data = options[:data] || {}
21
+ @options = {
22
+ headers: options[:headers] || {}
23
+ }
24
+ end
25
+
26
+ # Makes a GET request to the url provided by the Uri object and returns the
27
+ # resulting JSON data as a Ruby hash.
28
+ #
29
+ # == Example
30
+ #
31
+ # uri_object = HttpMagic::Uri.new('http://example.com')
32
+ #
33
+ # request = Request.new(uri_object)
34
+ #
35
+ # request.get
36
+ # => { 'name' => 'Foo Bar' }
37
+ def get
38
+ send_request :get
39
+ end
40
+
41
+ # Makes a POST request to the url provided by the Uri object and returns the
42
+ # resulting JSON data as a Ruby hash. If data was provided as an optional
43
+ # initialization parameter, then that is also POSTed.
44
+ #
45
+ # == Example
46
+ #
47
+ # uri_object = HttpMagic::Uri.new('http://example.com')
48
+ #
49
+ # request = Request.new(uri_object, data: { name: 'New Foo' })
50
+ #
51
+ # request.post
52
+ def post
53
+ if !@data.empty?
54
+ @options[:headers].merge!( 'content-type' => 'application/json' )
55
+ end
56
+
57
+ send_request :post
58
+ end
59
+
60
+ private
61
+
62
+ def http
63
+ return @http unless @http.nil?
64
+ @http = Net::HTTP.new(@uri.domain, 443)
65
+ @http.use_ssl = true
66
+ @http
67
+ end
68
+
69
+ def send_request(method)
70
+ response = http.send_request(method, @uri.urn, @data.to_json, @options[:headers])
71
+ if response && response.is_a?(Net::HTTPSuccess)
72
+ if response.content_type == 'application/json'
73
+ JSON.parse(response.body)
74
+ else
75
+ response.body
76
+ end
77
+ else
78
+ nil
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,74 @@
1
+
2
+ module HttpMagic
3
+ # Helper class that holds the parts of the URI and provides methods to put
4
+ # them together.
5
+ #
6
+ # == Example
7
+ #
8
+ # uri = HttpMagic::Uri.new('example.com')
9
+ # uri.build
10
+ # => "https://example.com/"
11
+ #
12
+ # uri.namespace = 'api/v2'
13
+ # uri.build
14
+ # => "https://example.com/api/v2"
15
+ #
16
+ # uri.parts = ['path']
17
+ # uri.build
18
+ # => "https://example.com/api/v2/path"
19
+ #
20
+ class Uri
21
+ attr_accessor :namespace, :parts
22
+
23
+ attr_reader :domain
24
+
25
+ def initialize(domain)
26
+ @domain = domain
27
+ @parts = []
28
+ end
29
+
30
+ # Builds a full uniform resource identifier.
31
+ #
32
+ # == Example
33
+ #
34
+ # uri = HttpMagic::Uri.new('example.com')
35
+ # uri.namespace = 'api/v1'
36
+ # uri.parts = %w(foo bar)
37
+ #
38
+ # uri.urn
39
+ # => "https://example.com/api/v1/foo/bar"
40
+ def build
41
+ "#{url}#{urn}"
42
+ end
43
+
44
+ # Uniform resource locator based on @domain value.
45
+ #
46
+ # == Example
47
+ #
48
+ # uri = HttpMagic::Uri.new('example.com')
49
+ #
50
+ # uri.url
51
+ # => "https://example.com/"
52
+ #
53
+ # uri.url(false)
54
+ # => "https://example.com"
55
+ def url
56
+ "https://#{@domain}"
57
+ end
58
+
59
+ # Uniform resource name for a resource.
60
+ #
61
+ # == Example
62
+ #
63
+ # uri = HttpMagic::Uri.new('example.com')
64
+ # uri.namespace = 'api/v1'
65
+ # uri.parts = %w(foo bar)
66
+ #
67
+ # uri.urn
68
+ # => "/api/v1/foo/bar"
69
+ def urn
70
+ resource_name = [@namespace, @parts].flatten.compact.join('/')
71
+ "/#{resource_name}"
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,68 @@
1
+ require 'test_helper'
2
+ require 'http_magic'
3
+
4
+ class HttpMagicTest < HttpMagic::Api
5
+ end
6
+
7
+ describe 'HttpMagic#get' do
8
+ before do
9
+ @url = HttpMagicTest.url 'www.example.com'
10
+ HttpMagicTest.namespace nil
11
+ HttpMagicTest.headers nil
12
+ end
13
+
14
+ it 'should return the root response' do
15
+ stub_request(:get, "https://#{@url}:443").
16
+ to_return(body: 'I am root!!')
17
+
18
+ assert_equal(
19
+ 'I am root!!',
20
+ HttpMagicTest.get
21
+ )
22
+ end
23
+
24
+ it 'should return the named resource' do
25
+ stub_request(:get, "https://#{@url}:443/bar").
26
+ to_return(body: 'A bear walked into a bar...')
27
+
28
+ assert_equal(
29
+ 'A bear walked into a bar...',
30
+ HttpMagicTest.bar.get
31
+ )
32
+ end
33
+
34
+ it 'should return the named resource' do
35
+ stub_request(:get, "https://#{@url}:443/bar/84").
36
+ to_return(body: 'Where Everybody Knows Your Name')
37
+
38
+ assert_equal(
39
+ 'Where Everybody Knows Your Name',
40
+ HttpMagicTest.bar[84].get
41
+ )
42
+ end
43
+
44
+ it 'should serialize JSON objects' do
45
+ stub_request(:get, "https://#{@url}:443/bar/99").
46
+ to_return(
47
+ headers: { 'Content-Type' => 'application/json' },
48
+ body: fixture_file('projects.json')
49
+ )
50
+
51
+ assert_equal(
52
+ 'GradesFirst',
53
+ HttpMagicTest.bar[99].get.first['name']
54
+ )
55
+ end
56
+
57
+ it 'should provide specified headers' do
58
+ stub_request(:get, "https://#{@url}:443/bar/84").
59
+ with(headers: { 'X-AuthToken' => 'test_token' }).
60
+ to_return(body: 'Where Everybody Knows Your Name')
61
+
62
+ HttpMagicTest.headers({ 'X-AuthToken' => 'test_token' })
63
+ assert_equal(
64
+ 'Where Everybody Knows Your Name',
65
+ HttpMagicTest.bar[84].get
66
+ )
67
+ end
68
+ end
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+ require 'http_magic'
3
+
4
+ class HttpMagicTest < HttpMagic::Api
5
+ end
6
+
7
+ describe 'HttpMagic#post' do
8
+ before do
9
+ @url = HttpMagicTest.url 'www.example.com'
10
+ HttpMagicTest.namespace nil
11
+ HttpMagicTest.headers nil
12
+ end
13
+
14
+ it 'should send POST request' do
15
+ stub_post = stub_request(:post, "https://#{@url}")
16
+
17
+ HttpMagicTest.post
18
+ assert_requested stub_post
19
+ end
20
+
21
+ it 'should send data with POST request' do
22
+ expected_data = {
23
+ apple: 'sauce',
24
+ banana: 'bread'
25
+ }
26
+ stub_post = stub_request(:post, "https://#{@url}/foo").with(
27
+ body: expected_data
28
+ )
29
+
30
+ HttpMagicTest.foo.post(expected_data)
31
+
32
+ assert_requested stub_post
33
+ end
34
+ end
@@ -0,0 +1,66 @@
1
+ [
2
+ {
3
+ "atom_enabled": false,
4
+ "version": 91975,
5
+ "name": "GradesFirst",
6
+ "velocity_averaged_over": 3,
7
+ "kind": "project",
8
+ "created_at": "2009-03-13T21:43:45Z",
9
+ "has_google_domain": false,
10
+ "point_scale_is_custom": false,
11
+ "current_iteration_number": 123,
12
+ "start_date": "2012-11-12",
13
+ "number_of_done_iterations_to_show": 4,
14
+ "updated_at": "2013-11-21T05:39:11Z",
15
+ "enable_incoming_emails": true,
16
+ "initial_velocity": 10,
17
+ "enable_following": true,
18
+ "account_id": 277647,
19
+ "start_time": "2009-03-16T05:00:00Z",
20
+ "enable_tasks": true,
21
+ "enable_planned_mode": true,
22
+ "week_start_day": "Monday",
23
+ "iteration_length": 2,
24
+ "time_zone": {
25
+ "kind": "time_zone",
26
+ "olson_name": "America/Chicago",
27
+ "offset": "-06:00"
28
+ },
29
+ "id": 10688,
30
+ "bugs_and_chores_are_estimatable": true,
31
+ "public": false,
32
+ "point_scale": "0,1,2,3,5,8"
33
+ },
34
+ {
35
+ "atom_enabled": false,
36
+ "version": 91975,
37
+ "name": "Technical",
38
+ "velocity_averaged_over": 3,
39
+ "kind": "project",
40
+ "created_at": "2009-03-13T21:43:45Z",
41
+ "has_google_domain": false,
42
+ "point_scale_is_custom": false,
43
+ "current_iteration_number": 123,
44
+ "start_date": "2012-11-12",
45
+ "number_of_done_iterations_to_show": 4,
46
+ "updated_at": "2013-11-21T05:39:11Z",
47
+ "enable_incoming_emails": true,
48
+ "initial_velocity": 10,
49
+ "enable_following": true,
50
+ "account_id": 277647,
51
+ "start_time": "2009-03-16T05:00:00Z",
52
+ "enable_tasks": true,
53
+ "enable_planned_mode": true,
54
+ "week_start_day": "Monday",
55
+ "iteration_length": 2,
56
+ "time_zone": {
57
+ "kind": "time_zone",
58
+ "olson_name": "America/Chicago",
59
+ "offset": "-06:00"
60
+ },
61
+ "id": 10687,
62
+ "bugs_and_chores_are_estimatable": true,
63
+ "public": false,
64
+ "point_scale": "0,1,2,3,5,8"
65
+ }
66
+ ]
@@ -0,0 +1,63 @@
1
+ require 'test_helper'
2
+ require 'http_magic/uri'
3
+ require 'http_magic/request'
4
+
5
+ describe 'HttpMagic::Request' do
6
+ before do
7
+ @domain = 'example.com'
8
+ @uri = HttpMagic::Uri.new(@domain)
9
+ end
10
+
11
+ it 'should make a request' do
12
+ stub_request = stub_request(
13
+ :get,
14
+ "https://#{@domain}/api/v2/path/to/something"
15
+ )
16
+
17
+ @uri.namespace = 'api/v2'
18
+ @uri.parts = ['path', 'to', 'something']
19
+ request = HttpMagic::Request.new(@uri)
20
+ request.get
21
+
22
+ assert_requested stub_request
23
+ end
24
+
25
+ it 'should return content on request' do
26
+ content = 'This is SPARTA!'
27
+ stub_request(:get, "https://#{@domain}").
28
+ to_return(body: content)
29
+
30
+ request = HttpMagic::Request.new(@uri)
31
+
32
+ assert_equal content, request.get
33
+ end
34
+
35
+ it 'should be able to post data as hash' do
36
+ expected_data = {
37
+ apple: 'crispy',
38
+ banana: 'soft'
39
+ }
40
+ stub_request = stub_request(:post, "https://#{@domain}").with(
41
+ body: expected_data.to_json,
42
+ headers: { 'content-type' => 'application/json' }
43
+ )
44
+
45
+ request = HttpMagic::Request.new(@uri, data: expected_data)
46
+ request.post
47
+
48
+ assert_requested stub_request
49
+ end
50
+
51
+ it 'should set correct headers' do
52
+ stub_request = stub_request(:get, "https://#{@domain}").
53
+ with(headers: { 'X-AuthToken' => 'test_token' })
54
+
55
+ request = HttpMagic::Request.new(
56
+ @uri,
57
+ headers: { 'X-AuthToken' => 'test_token' }
58
+ )
59
+ request.get
60
+
61
+ assert_requested stub_request
62
+ end
63
+ end
@@ -0,0 +1,18 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
2
+
3
+ require 'rubygems'
4
+ gem 'minitest' if RUBY_VERSION > '1.9'
5
+ require 'minitest/autorun'
6
+ require 'webmock/minitest'
7
+ require 'pry'
8
+
9
+ # Retreive the contents of fixture files to be used in tests. It is easier
10
+ # to view, modify and visualize text used in tests when it is stored in files.
11
+ # Also, it is much easier to reuse that text.
12
+ def fixture_file(file_name)
13
+ File.open(fixture_file_path(file_name), 'rb').read
14
+ end
15
+
16
+ def fixture_file_path(file_name)
17
+ File.join(File.dirname(__FILE__), 'fixtures', file_name)
18
+ end
data/test/uri_test.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+ require 'http_magic/uri'
3
+
4
+ describe 'HttpMagic::Uri' do
5
+ before do
6
+ @domain = 'example.com'
7
+ @uri = uri = HttpMagic::Uri.new(@domain)
8
+ end
9
+
10
+ it 'must have a domain param' do
11
+ assert_raises ArgumentError do
12
+ HttpMagic::Uri.new
13
+ end
14
+ end
15
+
16
+ it 'should return the domain' do
17
+ assert_equal @domain, @uri.domain
18
+ end
19
+
20
+ it 'can build a simple uri' do
21
+ assert_equal "https://#{@domain}/", @uri.build
22
+ end
23
+
24
+ it 'should have url' do
25
+ assert_equal "https://#{@domain}", @uri.url
26
+ end
27
+
28
+ it 'should create urn with parts' do
29
+ @uri.parts = ['path', 'to', 'something']
30
+ assert_equal '/path/to/something', @uri.urn
31
+ end
32
+
33
+ it 'should create urn with namespace' do
34
+ @uri.namespace = 'api/v2'
35
+ assert_equal '/api/v2', @uri.urn
36
+ end
37
+
38
+ it 'should create urn with namespace and parts combined' do
39
+ @uri.parts = ['path', 'to', 'something']
40
+ @uri.namespace = 'api/v2'
41
+ assert_equal '/api/v2/path/to/something', @uri.urn
42
+ end
43
+
44
+ it 'should create the full uri with urn included' do
45
+ @uri.parts = ['path', 'to', 'something']
46
+ @uri.namespace = 'api/v2'
47
+ assert_equal "https://#{@domain}/api/v2/path/to/something", @uri.build
48
+ end
49
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: http_magic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - GradesFirst
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '4.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '4.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: webmock
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.16'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.16'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-debugger
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email: tech@gradesfirst.com
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - .gitignore
90
+ - Gemfile
91
+ - Gemfile.lock
92
+ - LICENSE
93
+ - README.md
94
+ - Rakefile
95
+ - http_magic.gemspec
96
+ - lib/http_magic.rb
97
+ - lib/http_magic/api.rb
98
+ - lib/http_magic/request.rb
99
+ - lib/http_magic/uri.rb
100
+ - test/api/get_test.rb
101
+ - test/api/post_test.rb
102
+ - test/fixtures/projects.json
103
+ - test/request_test.rb
104
+ - test/test_helper.rb
105
+ - test/uri_test.rb
106
+ homepage: https://github.com/Thoughtwright-LLC/httpmagic
107
+ licenses:
108
+ - MIT
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.2.1
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: Provides a more Object Oriented interface to RESTful apis.
130
+ test_files: []