excon-hypermedia 0.5.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # rubocop:disable Metrics/AbcSize
3
4
  # rubocop:disable Metrics/LineLength
4
5
 
@@ -10,20 +11,16 @@ module Excon
10
11
  # Verifies the Excon connection consuming HyperMedia APIs.
11
12
  #
12
13
  class IntegrationTest < HyperMediaTest
13
- def api
14
- Excon.get('https://www.example.org/api.json')
15
- end
16
-
17
14
  def test_request
18
15
  response = api.rel('product', expand: { uid: 'bicycle' }).get
19
16
 
20
- assert response.body.include?('https://www.example.org/product/bicycle')
17
+ assert response.body.include?('/product/bicycle')
21
18
  end
22
19
 
23
20
  def test_request_using_link_rel
24
21
  response = api.resource._links.product.rel(expand: { uid: 'bicycle' }).get
25
22
 
26
- assert response.body.include?('https://www.example.org/product/bicycle')
23
+ assert response.body.include?('/product/bicycle')
27
24
  end
28
25
 
29
26
  def test_nested_request
@@ -45,7 +42,7 @@ module Excon
45
42
  def test_expand_in_get
46
43
  response = api.rel('product').get(expand: { uid: 'bicycle' })
47
44
 
48
- assert response.body.include?('https://www.example.org/product/bicycle')
45
+ assert response.body.include?('/product/bicycle')
49
46
  end
50
47
 
51
48
  def test_link
@@ -89,14 +86,12 @@ module Excon
89
86
  end
90
87
 
91
88
  def test_request_with_json_content_type
92
- api = Excon.get('https://www.example.org/api_v2.json', hypermedia: true)
93
- response = api.rel('product', expand: { uid: 'bicycle' }).get
89
+ response = api_v2.rel('product', expand: { uid: 'bicycle' }).get
94
90
 
95
- assert response.body.include?('https://www.example.org/product/bicycle')
96
- end
97
-
98
- def teardown
99
- Excon.stubs.clear
91
+ assert response.body.include?('/product/bicycle')
100
92
  end
101
93
  end
102
94
  end
95
+
96
+ # rubocop:enable Metrics/AbcSize
97
+ # rubocop:enable Metrics/LineLength
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:disable Metrics/MethodLength
3
2
 
4
3
  require_relative '../test_helper'
5
4
 
@@ -10,17 +9,17 @@ module Excon
10
9
  #
11
10
  class LinkTest < Minitest::Test
12
11
  def self
13
- '{ "href": "https://www.example.org/hello" }'
12
+ '{ "href": "https://example.org/hello" }'
14
13
  end
15
14
 
16
15
  def templated
17
- '{ "href": "https://www.example.org/hello/{receiver}", "templated": "true" }'
16
+ '{ "href": "https://example.org/hello/{receiver}", "templated": "true" }'
18
17
  end
19
18
 
20
19
  def full
21
- <<-EOF
20
+ <<-JSON
22
21
  {
23
- "href": "https://www.example.org/goodbye/{receiver}",
22
+ "href": "https://example.org/goodbye/{receiver}",
24
23
  "templated": "true",
25
24
  "type": "json",
26
25
  "deprecation": true,
@@ -29,7 +28,7 @@ module Excon
29
28
  "title": "Goodbye!",
30
29
  "hreflang": "en-gb"
31
30
  }
32
- EOF
31
+ JSON
33
32
  end
34
33
 
35
34
  def data(name)
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:disable Metrics/MethodLength
3
2
 
4
3
  require_relative '../test_helper'
5
4
 
@@ -10,18 +9,18 @@ module Excon
10
9
  #
11
10
  class LinksTest < Minitest::Test
12
11
  def body
13
- <<-EOF
12
+ <<-JSON
14
13
  {
15
14
  "_links": {
16
15
  "self": {
17
- "href": "https://www.example.org/product/bicycle"
16
+ "href": "https://example.org/product/bicycle"
18
17
  },
19
18
  "parts": {
20
- "href": "https://www.example.org/product/bicycle/parts"
19
+ "href": "https://example.org/product/bicycle/parts"
21
20
  }
22
21
  }
23
22
  }
24
- EOF
23
+ JSON
25
24
  end
26
25
 
27
26
  def data
@@ -37,7 +36,7 @@ module Excon
37
36
  end
38
37
 
39
38
  def test_link_properties
40
- assert_equal %w(self parts), links.to_h.keys
39
+ assert_equal %w[self parts], links.to_h.keys
41
40
  end
42
41
  end
43
42
  end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Metrics/AbcSize
4
+ # rubocop:disable Metrics/LineLength
5
+
6
+ require_relative '../test_helper'
7
+
8
+ module Excon
9
+ class MiddlewareTest < Minitest::Test
10
+ def setup
11
+ Excon.defaults[:mock] = true
12
+ Excon.stub(
13
+ { :path => '/lowercase-content-type' },
14
+ {
15
+ headers: { 'content-type' => 'application/hal+json' },
16
+ body: '{}',
17
+ status: 200
18
+ }
19
+ )
20
+ Excon.stub(
21
+ { :path => '/uppercase-content-type' },
22
+ {
23
+ headers: { 'Content-Type' => 'application/hal+json' },
24
+ body: '{}',
25
+ status: 200
26
+ }
27
+ )
28
+ end
29
+
30
+ def test_request_with_lowercase_content_type
31
+ test = Excon.get(
32
+ 'http://example.com',
33
+ path: '/lowercase-content-type',
34
+ middlewares: Excon.defaults[:middlewares] + [Excon::HyperMedia::Middleware]
35
+ )
36
+
37
+ assert test.data[:hypermedia]
38
+ end
39
+
40
+ def test_request_with_uppercase_content_type
41
+ test = Excon.get(
42
+ 'http://example.com',
43
+ path: '/uppercase-content-type',
44
+ middlewares: Excon.defaults[:middlewares] + [Excon::HyperMedia::Middleware]
45
+ )
46
+
47
+ assert test.data[:hypermedia]
48
+ end
49
+
50
+ def teardown
51
+ Excon.stubs.clear
52
+ Excon.defaults[:mock] = false
53
+ end
54
+ end
55
+ end
56
+
57
+ # rubocop:enable Metrics/AbcSize
58
+ # rubocop:enable Metrics/LineLength
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:disable Metrics/MethodLength
3
2
 
4
3
  require_relative '../test_helper'
5
4
 
@@ -10,7 +9,7 @@ module Excon
10
9
  #
11
10
  class PropertiesTest < Minitest::Test
12
11
  def body
13
- <<-EOF
12
+ <<-JSON
14
13
  {
15
14
  "size": "49CM",
16
15
  "bike-type": "Mountain Bike",
@@ -21,7 +20,7 @@ module Excon
21
20
  "reflectors": true,
22
21
  "BMX": false
23
22
  }
24
- EOF
23
+ JSON
25
24
  end
26
25
 
27
26
  def data
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:disable Metrics/MethodLength
3
2
 
4
3
  require_relative '../test_helper'
5
4
 
@@ -10,17 +9,17 @@ module Excon
10
9
  #
11
10
  class ResourceObjectTest < Minitest::Test
12
11
  def body
13
- <<-EOF
12
+ <<-JSON
14
13
  {
15
14
  "_links": {
16
15
  "hello": {
17
- "href": "http://www.example.com/hello/{location}"
16
+ "href": "https://example.org/hello/{location}"
18
17
  }
19
18
  },
20
19
  "uid": "universe",
21
20
  "hello": "world"
22
21
  }
23
- EOF
22
+ JSON
24
23
  end
25
24
 
26
25
  def data
@@ -43,7 +42,16 @@ module Excon
43
42
  assert_equal 'universe', resource.uid
44
43
  assert_equal 'world', resource.hello
45
44
  assert_equal 'world', resource['hello']
46
- assert_equal nil, resource['invalid']
45
+ assert_nil resource['invalid']
46
+ end
47
+
48
+ def test_correctly_raising_no_method_error
49
+ assert_raises(NoMethodError) { resource.invalid }
50
+ end
51
+
52
+ def test_correctly_respond_to
53
+ assert_equal true, resource.respond_to?(:hello)
54
+ assert_equal false, resource.respond_to?(:invalid)
47
55
  end
48
56
  end
49
57
  end
@@ -9,7 +9,7 @@ module Excon
9
9
  #
10
10
  class ResponseTest < HyperMediaTest
11
11
  def response
12
- @response ||= Excon.get('https://example.org/product/bicycle')
12
+ bicycle
13
13
  end
14
14
 
15
15
  def test_response
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Metrics/ModuleLength
4
+
5
+ # :no-doc:
6
+ module Test
7
+ # :no-doc:
8
+ module Response
9
+ module_function
10
+
11
+ def api_body
12
+ <<-JSON
13
+ {
14
+ "_links": {
15
+ "self": {
16
+ "href": "http://localhost:8000/api.json"
17
+ },
18
+ "product": {
19
+ "href": "http://localhost:8000/product/{uid}",
20
+ "templated": true
21
+ }
22
+ }
23
+ }
24
+ JSON
25
+ end
26
+
27
+ def bicycle_body
28
+ <<-JSON
29
+ {
30
+ "_links": {
31
+ "self": {
32
+ "href": "http://localhost:8000/product/bicycle"
33
+ },
34
+ "handlebar": {
35
+ "href": "http://localhost:8000/product/handlebar"
36
+ },
37
+ "object_id": {
38
+ "href": "http://localhost:8000/product/bicycle/object_id_as_text"
39
+ },
40
+ "pump": {
41
+ "href": "http://localhost:8000/product/pump"
42
+ },
43
+ "wheels": [
44
+ { "href": "http://localhost:8000/product/bicycle/wheels/front" },
45
+ { "href": "http://localhost:8000/product/bicycle/wheels/rear" }
46
+ ]
47
+ },
48
+ "bike-type": "Mountain Bike",
49
+ "BMX": false,
50
+ "derailleurs": {
51
+ "back": 7,
52
+ "front": 3
53
+ },
54
+ "name": "bicycle",
55
+ "reflectors": true,
56
+ "_embedded": {
57
+ "pump": #{pump_body},
58
+ "wheels": [#{front_wheel_body}, #{rear_wheel_body}]
59
+ }
60
+ }
61
+ JSON
62
+ end
63
+
64
+ def handlebar_body
65
+ <<-JSON
66
+ {
67
+ "_links": {
68
+ "self": {
69
+ "href": "http://localhost:8000/product/handlebar"
70
+ }
71
+ },
72
+ "material": "Carbon fiber",
73
+ "reach": "75mm",
74
+ "bend": "compact"
75
+ }
76
+ JSON
77
+ end
78
+
79
+ def pump_body
80
+ <<-JSON
81
+ {
82
+ "_links": {
83
+ "self": {
84
+ "href": "http://localhost:8000/product/pump"
85
+ },
86
+ "parts": {
87
+ "href": "http://localhost:8000/product/pump/parts"
88
+ }
89
+ },
90
+ "weight": "2kg",
91
+ "type": "Floor Pump",
92
+ "valve-type": "Presta",
93
+ "_embedded": {
94
+ "parts": #{parts_body}
95
+ }
96
+
97
+ }
98
+ JSON
99
+ end
100
+
101
+ def parts_body
102
+ <<-JSON
103
+ {
104
+ "_links": {
105
+ "self": {
106
+ "href": "http://localhost:8000/product/pump/parts"
107
+ }
108
+ },
109
+ "count": 47
110
+ }
111
+ JSON
112
+ end
113
+
114
+ def rear_wheel_body
115
+ <<-JSON
116
+ {
117
+ "_links": {
118
+ "self": {
119
+ "href": "http://localhost:8000/product/bicycle/wheels/rear"
120
+ }
121
+ },
122
+ "position": "rear",
123
+ "lacing_pattern": "Radial"
124
+ }
125
+ JSON
126
+ end
127
+
128
+ def front_wheel_body
129
+ <<-JSON
130
+ {
131
+ "_links": {
132
+ "self": {
133
+ "href": "http://localhost:8000/product/bicycle/wheels/front"
134
+ }
135
+ },
136
+ "position": "front",
137
+ "lacing_pattern": "Radial/2-Cross"
138
+ }
139
+ JSON
140
+ end
141
+ end
142
+ end
143
+
144
+ # rubocop:enable Metrics/ModuleLength
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'webrick'
5
+ require 'logger'
6
+ require_relative 'responses'
7
+
8
+ server = WEBrick::HTTPServer.new(Port: 8000, Logger: Logger.new(STDERR))
9
+
10
+ def body(name)
11
+ Test::Response.send("#{name}_body")
12
+ end
13
+
14
+ endpoints = {
15
+ '/empty_json' => { body: '{}' },
16
+ '/api.json' => { body: body(:api) },
17
+ '/product/bicycle' => { body: body(:bicycle) },
18
+ '/product/bicycle/wheels/front' => { body: body(:front_wheel) },
19
+ '/product/bicycle/wheels/rear' => { body: body(:rear_wheel) },
20
+ '/product/pump' => { body: body(:pump) },
21
+ '/product/pump/parts' => { body: body(:parts) },
22
+ '/product/handlebar' => { body: body(:handlebar) },
23
+ '/api_v2.json' => { body: body(:api), headers: { 'Content-Type' => 'application/json' } }
24
+ }
25
+
26
+ endpoints.each do |path, params|
27
+ server.mount_proc(path) do |_, response|
28
+ response['Content-Type'] = 'application/hal+json'
29
+ params[:headers].to_h.each { |k, v| response[k] = v }
30
+
31
+ response.body = params[:body]
32
+ end
33
+ end
34
+
35
+ server.start