farscape 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aaaa9b7314cc73ef0fd43a9de2e7f17f78999636
4
- data.tar.gz: ff6f62f5301162b952821b23a80be847fac1627e
3
+ metadata.gz: 42ff32e415677a4ca1cb6419518d7cbf78a6df1c
4
+ data.tar.gz: 2f7d3081526f4e913c7b4d66f35378db2212de31
5
5
  SHA512:
6
- metadata.gz: 401dc3a255241d08565bc7067e6933b8450e48a97b87af028011e5600a41db720570731059486269daf4e95200c0f283cd5068666c90ff702699fa7de7e2022a
7
- data.tar.gz: dbf7b5362bc58a66771ba67b8f8b822a17947eafc92ee5ca043019c3d2a76eb9907272919790b5dc23980e940f35f170e83f72724965509d19d20d2baf5ef5ef
6
+ metadata.gz: a45910ae4df9afafafa01805c07de5948c5a912367f5ee184b870d26167b75710d2c49055cd34d08fbaae804be542c683fc42c41d409e30007bfc44343b1fcd0
7
+ data.tar.gz: 8ee0a64cefcad9ecfc1e4c50c7f295031467b84846920baf1baffa1a3391dda3fead82eeda67144c78511cf41a8f922caf44c4a49fade8ad1a1fd395dd8324b5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ # 1.3.0
2
+ * Add discover method and configuration to the Farscape agent.
3
+
1
4
  # 1.2.0
2
5
  * Add support for templated URIs and POST requests
3
6
 
data/Gemfile.lock CHANGED
@@ -1,14 +1,5 @@
1
1
  GIT
2
- remote: git@github.com:mdsol/representors.git
3
- revision: 958dc778d62897f09dd0200f3690f96cb5265b98
4
- branch: 0-0-stable
5
- specs:
6
- representors (0.0.3)
7
- addressable (~> 2.3)
8
- rake
9
-
10
- GIT
11
- remote: https://www.github.com/mdsol-share/crichton.git
2
+ remote: https://github.com/mdsol-share/crichton.git
12
3
  revision: 63c74ce781a41538454b81fd8c44dc36117aa92b
13
4
  branch: develop
14
5
  specs:
@@ -24,7 +15,7 @@ GIT
24
15
  rake
25
16
 
26
17
  GIT
27
- remote: https://www.github.com/mdsol/moya.git
18
+ remote: https://github.com/mdsol/moya.git
28
19
  revision: 6e8b324dee6335e5d56d320ba0a605b6ebae8574
29
20
  branch: develop
30
21
  specs:
@@ -40,13 +31,12 @@ GIT
40
31
  PATH
41
32
  remote: .
42
33
  specs:
43
- farscape (1.0.1)
34
+ farscape (1.3.0)
44
35
  activesupport
45
- addressable (~> 2.3.0)
46
- dice_bag
47
- faraday (~> 0.8.8)
48
- faraday_middleware (~> 0.9)
36
+ addressable (~> 2.3)
37
+ faraday (~> 0.9)
49
38
  rake
39
+ representors (~> 0.0.5)
50
40
 
51
41
  GEM
52
42
  remote: https://rubygems.org/
@@ -77,47 +67,41 @@ GEM
77
67
  minitest (~> 5.1)
78
68
  thread_safe (~> 0.1)
79
69
  tzinfo (~> 1.1)
80
- activeuuid (0.6.0)
70
+ activeuuid (0.6.1)
81
71
  activerecord (>= 3.1)
82
72
  uuidtools
83
- addressable (2.3.7)
73
+ addressable (2.3.8)
84
74
  arel (5.0.1.20140414130214)
85
- awesome_print (1.1.0)
86
75
  builder (3.2.2)
87
- coderay (1.1.0)
76
+ byebug (9.0.5)
88
77
  colorize (0.6.0)
89
- crack (0.4.2)
78
+ concurrent-ruby (1.0.2)
79
+ crack (0.4.3)
90
80
  safe_yaml (~> 1.0.0)
91
- dice_bag (0.8.0)
81
+ dice_bag (0.9.0)
92
82
  rake
93
83
  diff-lcs (1.2.5)
94
84
  diffy (3.0.7)
95
85
  docile (1.1.5)
96
86
  erubis (2.7.0)
97
- faraday (0.8.9)
98
- multipart-post (~> 1.2.0)
99
- faraday_middleware (0.9.1)
100
- faraday (>= 0.7.4, < 0.10)
101
- hike (1.2.3)
87
+ faraday (0.9.2)
88
+ multipart-post (>= 1.2, < 3)
89
+ hashdiff (0.3.0)
102
90
  i18n (0.7.0)
103
- json (1.8.2)
91
+ json (1.8.3)
104
92
  launchy (2.4.3)
105
93
  addressable (~> 2.3)
106
- mail (2.6.3)
107
- mime-types (>= 1.16, < 3)
108
- method_source (0.8.2)
109
- mime-types (2.4.3)
110
- mini_portile (0.6.2)
111
- minitest (5.5.1)
112
- multi_json (1.11.0)
113
- multipart-post (1.2.0)
114
- nokogiri (1.6.6.2)
115
- mini_portile (~> 0.6.0)
116
- pry (0.10.1)
117
- coderay (~> 1.1.0)
118
- method_source (~> 0.8.1)
119
- slop (~> 3.4)
120
- rack (1.5.2)
94
+ mail (2.6.4)
95
+ mime-types (>= 1.16, < 4)
96
+ mime-types (3.1)
97
+ mime-types-data (~> 3.2015)
98
+ mime-types-data (3.2016.0521)
99
+ mini_portile2 (2.0.0)
100
+ minitest (5.9.0)
101
+ multipart-post (2.0.0)
102
+ nokogiri (1.6.7.2)
103
+ mini_portile2 (~> 2.0.0.rc2)
104
+ rack (1.5.5)
121
105
  rack-test (0.6.3)
122
106
  rack (>= 1.0)
123
107
  rails (4.1.8)
@@ -135,8 +119,11 @@ GEM
135
119
  activesupport (= 4.1.8)
136
120
  rake (>= 0.8.7)
137
121
  thor (>= 0.18.1, < 2.0)
138
- rake (0.9.6)
139
- redcarpet (3.2.2)
122
+ rake (11.1.2)
123
+ redcarpet (3.3.4)
124
+ representors (0.0.5)
125
+ addressable (~> 2.3)
126
+ rake
140
127
  rspec (2.99.0)
141
128
  rspec-core (~> 2.99.0)
142
129
  rspec-expectations (~> 2.99.0)
@@ -146,31 +133,28 @@ GEM
146
133
  diff-lcs (>= 1.1.3, < 2.0)
147
134
  rspec-mocks (2.99.3)
148
135
  safe_yaml (1.0.4)
149
- simplecov (0.9.2)
136
+ simplecov (0.11.2)
150
137
  docile (~> 1.1.0)
151
- multi_json (~> 1.0)
152
- simplecov-html (~> 0.9.0)
153
- simplecov-html (0.9.0)
154
- slop (3.6.0)
155
- sprockets (2.12.3)
156
- hike (~> 1.2)
157
- multi_json (~> 1.0)
158
- rack (~> 1.0)
159
- tilt (~> 1.1, != 1.3.0)
160
- sprockets-rails (2.2.4)
138
+ json (~> 1.8)
139
+ simplecov-html (~> 0.10.0)
140
+ simplecov-html (0.10.0)
141
+ sprockets (3.6.0)
142
+ concurrent-ruby (~> 1.0)
143
+ rack (> 1, < 3)
144
+ sprockets-rails (2.3.3)
161
145
  actionpack (>= 3.0)
162
146
  activesupport (>= 3.0)
163
147
  sprockets (>= 2.8, < 4.0)
164
- sqlite3 (1.3.10)
148
+ sqlite3 (1.3.11)
165
149
  thor (0.19.1)
166
150
  thread_safe (0.3.5)
167
- tilt (1.4.1)
168
151
  tzinfo (1.2.2)
169
152
  thread_safe (~> 0.1)
170
153
  uuidtools (2.1.5)
171
- webmock (1.13.0)
172
- addressable (>= 2.2.7)
154
+ webmock (2.0.3)
155
+ addressable (>= 2.3.6)
173
156
  crack (>= 0.3.2)
157
+ hashdiff
174
158
  yajl-ruby (1.2.1)
175
159
  yard (0.8.7.6)
176
160
 
@@ -178,15 +162,15 @@ PLATFORMS
178
162
  ruby
179
163
 
180
164
  DEPENDENCIES
181
- awesome_print (~> 1.1.0)
165
+ byebug
182
166
  crichton!
183
167
  farscape!
184
168
  moya!
185
- pry
186
- rake (~> 0.9)
187
- redcarpet
188
- representors!
169
+ redcarpet (~> 3.3)
189
170
  rspec (~> 2.14)
190
- simplecov (~> 0.7)
191
- webmock (~> 1.13.0)
192
- yard (~> 0.8.5)
171
+ simplecov (~> 0.11)
172
+ webmock (~> 2.0)
173
+ yard
174
+
175
+ BUNDLED WITH
176
+ 1.12.5
data/README.md CHANGED
@@ -15,43 +15,59 @@ a response with a supported Hypermedia media-type and a root that lists availabl
15
15
 
16
16
  ### A Hypermedia API
17
17
  For a interacting with an API (or individual service that supports a list of resources at its root), you enter the
18
- API and follow your nose using the `enter` method on the agent. This method returns a [Farscape::Representor]()
19
- instance with a simple state-machine interface of `attributes` (data) and `transitions` (link/form affordances) for
18
+ API and follow your nose using the `enter` method on the agent. This method returns a [Farscape::Representor](lib/farscape/representor.rb)
19
+ instance with a simple state-machine interface of `attributes` (data) and `transitions` (link/form affordances) for
20
20
  interacting with the resource representations.
21
21
 
22
22
  ```ruby
23
- agent = Farscape::Agent.new('http://example.com/my_api')
23
+ agent = Farscape::Agent.instance
24
24
 
25
- resources = agent.enter
25
+ resources = agent.enter('http://example.com/my_api')
26
26
  resources.attributes # => { meta: 'data', or: 'other data' }
27
27
  resources.transitions.keys # => ['http://example.com/rel/drds', 'http://example.com/rel/leviathans']
28
28
  ```
29
29
 
30
30
  ### A Hypermedia Discovery Service
31
- For interacting with a discovery service, Farscape supports follow your nose entry to select a registered resource
32
- or immediately loading a discoverable resource if known to be registered in the service *a priori*.
31
+ For interacting with a discovery service, you can use enter and follow your nose entry to select a registered resource or setup Farscape with a discovery server.
33
32
 
34
33
  ```ruby
35
- agent = Farscape::Agent.new('http://example.com/my_discovery_service')
34
+ # Setting discovery service to https://my_discovery_api
35
+ Farscape::Agent.config = { Farscape::Discovery::DISCOVERY_KEY => 'https://my_discovery_api' }
36
+ ```
36
37
 
37
- resources = agent.enter
38
- resources.attributes # => { meta: 'data', or: 'other data' }
39
- resources.transitions.keys # => ['http://example.com/rel/drds', 'http://example.com/rel/leviathans', 'next', 'last']
38
+ The discovery service must return a document with a list of resource names and their root URLs like:
39
+
40
+ ```json
41
+ {
42
+ "_links": {
43
+ "self": { "href": "https://my_discovery_api" },
44
+ "boxes": { "href": "https://smallboxesandpoliceboxes.com" },
45
+ "items": { "href": "https://sonicscrewdriversandotherthings.com/v1/{item}" }
46
+ }
47
+ }
48
+ ```
40
49
 
41
- drds = agent.enter('http://example.com/rel/drds')
42
- drds.attributes # => { total_count: 25, items: [...] }
43
- drds.transitions.keys # => ['self', 'search', 'create', 'next', 'last']
50
+ Farscape then can be used directly with resource names. Farscape will already do the heavy-lifting of contacting the discovery service and retrieving the root document of the resource.
44
51
 
45
- agent.enter('http://example.com/rel/unknown_resource') # => raises Farscape::Agent::UnknownEntryPoint
52
+ ```ruby
53
+ agent = Farscape::Agent.instance
54
+ boxes = agent.enter('boxes')
55
+ boxes.attributes # => { total_count: 13, items: [...] }
56
+
57
+ agent.enter('unknownresource') # raises Farscape::Discovery::NotFound
58
+
59
+ agent.enter('items', [{ items: 'bow-tie' }]) # Allows template variables
46
60
  ```
47
61
 
62
+
63
+
48
64
  ## API Interaction
49
- Entering an API takes you into its application state-machine and, as such, the interface for interacting with that
50
- application state is brain dead simple with Farscape. You have data that you read and hypermedia affordances that tell
65
+ Entering an API takes you into its application state-machine and, as such, the interface for interacting with that
66
+ application state is brain dead simple with Farscape. You have data that you read and hypermedia affordances that tell
51
67
  you what you can do next and you can invoke those affordances to do things. That's it.
52
68
 
53
- Farscape recognizes a number of media-types that support runtime knowledge of the underlying REST uniform-interface
54
- methods. For these full-featured media-types, the interaction with with resources is as simple as a browser where
69
+ Farscape recognizes a number of media-types that support runtime knowledge of the underlying REST uniform-interface
70
+ methods. For these full-featured media-types, the interaction with with resources is as simple as a browser where
55
71
  implementation of requests is completely abstracted from the user.
56
72
 
57
73
  The following simple examples highlight interacting with resource state-machines using Farscape.
@@ -128,7 +144,7 @@ new_drd.attributes # => { name: 'Pike' }
128
144
  new_drd.transitions.keys # => ['self', 'edit', 'delete', 'deactivate', 'leviathan']
129
145
  ```
130
146
 
131
- For more examples and information on using Faraday with media-types that require specifying uniform-interface methods
147
+ For more examples and information on using Faraday with media-types that require specifying uniform-interface methods
132
148
  and other protocol idioms when invoking transitions, see [Using Farscape]().
133
149
 
134
150
  ## Alternate Interface
@@ -1,16 +1,32 @@
1
1
  require 'farscape/representor'
2
2
  require 'farscape/clients'
3
+ require 'farscape/discovery'
3
4
 
4
5
  module Farscape
5
6
  class Agent
6
-
7
+
7
8
  include BaseAgent
8
-
9
+
9
10
  PROTOCOL = :http
10
11
 
11
12
  attr_reader :media_type
12
13
  attr_reader :entry_point
13
-
14
+
15
+ class << self
16
+ # Prevents multiple threads from accessing the same agent.
17
+ def instance
18
+ Thread.current[:farscape_agent] ||= Agent.new
19
+ end
20
+
21
+ def config
22
+ @farscape_config || {}
23
+ end
24
+
25
+ def config=(farscape_config)
26
+ @farscape_config = farscape_config
27
+ end
28
+ end
29
+
14
30
  def initialize(entry = nil, media = :hale, safe = false, plugin_hash = {})
15
31
  @entry_point = entry
16
32
  @media_type = media
@@ -23,10 +39,19 @@ module Farscape
23
39
  safe? ? SafeRepresentorAgent : RepresentorAgent
24
40
  end
25
41
 
26
- def enter(entry = entry_point)
27
- @entry_point ||= entry
42
+ # Discovers provided a key and template_variables.
43
+ # This method is here to be easily overwritten or monkey-patched if needed.
44
+ def discover_entry_point(key, template_variables = {})
45
+ Discovery.new.discover(self.class.config, key, template_variables)
46
+ end
47
+
48
+ def enter(entry = entry_point, template_variables = {})
28
49
  raise "No Entry Point Provided!" unless entry
29
- response = client.invoke(url: entry, headers: get_accept_header(media_type))
50
+ @entry_point ||= entry
51
+ unless Addressable::URI.parse(@entry_point).absolute?
52
+ @entry_point = discover_entry_point(@entry_point, template_variables)
53
+ end
54
+ response = client.invoke(url: @entry_point, headers: get_accept_header(media_type))
30
55
  find_exception(response)
31
56
  end
32
57
 
@@ -100,7 +125,7 @@ module Farscape
100
125
  end
101
126
 
102
127
  private
103
-
128
+
104
129
  def default_plugin_hash
105
130
  {
106
131
  plugins: Farscape.plugins.dup, # A hash of plugins keyed by the plugin name
@@ -0,0 +1,32 @@
1
+ module Farscape
2
+ # This class provide discovery capabilities to Farscape.
3
+ class Discovery
4
+
5
+ DISCOVERY_KEY = :discovery_uri
6
+
7
+ class NotFound < NameError
8
+ end
9
+
10
+ # This is the simplest type of discovery. We assume that the url we will call will provide us
11
+ # document with links which keys are the names we want to discover and hrefs are root URLS.
12
+ # Templated URLs are supported, an exception will be raised if the template does not match the variables.
13
+ # {
14
+ # "_links": {
15
+ # "boxes": { "href": "https://smallboxesandpoliceboxes.com" },
16
+ # "items": { "href": "https://sonicscrewdriversandotherthings.com/v1/{item}" }
17
+ # }
18
+ # }
19
+ def discover(config, key, url_template_variables)
20
+ discovery_uri = config[DISCOVERY_KEY]
21
+ raise NotFound, "No discovery uri setup for Farscape. Discovery of #{key} unavailable" unless discovery_uri
22
+ raise NotFound, "Discover URL #{discovery_uri} is not a valid URL." unless discovery_uri =~ URI::regexp
23
+ discovery_document = Farscape::Agent.new(discovery_uri).enter
24
+ if discovery_document.kind_of?(Faraday::Response) # Parse errors give us a raw Faraday Response
25
+ raise NotFound, "The discovery document for #{key} is not valid JSON. We got: #{discovery_document.body}"
26
+ end
27
+ found = discovery_document.transitions[key.to_s]
28
+ raise NotFound, "No key '#{key}' found in the response from the discovery service." unless found
29
+ found.uri(url_template_variables)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,95 @@
1
+ module Farscape
2
+ class PlatformResources
3
+ ROOT_ITEMS_KEY = 'items'.freeze
4
+
5
+ class NotFound < StandardError; end
6
+
7
+ def self.agent
8
+ @agent ||= Agent.new # This is only done once in the application because is expensive
9
+ # @agent is global to the application. We dup it so each thread has its own copy
10
+ Thread.current[:farscape_agent] ||= @agent.dup
11
+ end
12
+
13
+ def self.root_for(resource_name, template_variables = {})
14
+ rescuing_farscape(resource_name) do
15
+ Farscape.logger.info("Discovering #{resource_name} providing data >#{template_variables}<")
16
+ root = agent.discover(resource_name, template_variables)
17
+ Farscape.logger.info("Accessing the root #{root} for #{resource_name}")
18
+ agent.instance_variable_set(:@entry_point, root)
19
+ agent.enter(root)
20
+ end
21
+ end
22
+
23
+ def self.items_for(resource_name, template_variables = {})
24
+ root_document = root_for(resource_name, template_variables)
25
+ attributes = root_document_data(resource_name, root_document)
26
+ attributes[ROOT_ITEMS_KEY] || []
27
+ end
28
+
29
+ def self.root_document_data(resource_name, root_document)
30
+ if root_document.respond_to?(:attributes)
31
+ Farscape.logger.debug("Called #{resource_name} and got #{root_document.attributes[ROOT_ITEMS_KEY]}")
32
+ root_document.attributes
33
+ elsif root_document.respond_to?(:body) # Farscape will happily return a Faraday Response when it can not be parsed
34
+ Farscape.logger.error("The document retrieved for #{resource_name} is not valid JSON. We got: >#{root_document.body}<")
35
+ {}
36
+ else
37
+ Farscape.logger.error("Unknown response trying to access #{resource_name}. We got: >#{root_document}<")
38
+ {}
39
+ end
40
+ rescue StandardError => e
41
+ log_error("Error accessing the attributes on the root of #{resource_name}", e)
42
+ {}
43
+ end
44
+
45
+ def self.rescuing_farscape(resource_name)
46
+ yield
47
+ rescue Net::ReadTimeout => e
48
+ log_error("Network read error accessing #{resource_name}", e)
49
+ rescue Farscape::Exceptions::NotFound => e
50
+ log_error("Resource not found accessing #{resource_name}", e)
51
+ rescue Farscape::Exceptions::Forbidden => e
52
+ log_error("Forbidden access accessing #{resource_name}", e)
53
+ rescue Farscape::Exceptions::InternalServerError => e
54
+ log_error("The server responded with an internal server error when accessing #{resource_name}", e)
55
+ rescue Farscape::Discovery::KeyNotFound => e
56
+ log_error("The resource #{resource_name} is not registered in our Hypermedia discovery service", e)
57
+ rescue StandardError => e
58
+ Farscape.logger.error("Unknown error class '#{e.class}'")
59
+ log_error("Unknown error accessing #{resource_name}", e)
60
+ end
61
+
62
+ # This is a simple wrapper over Farscape::Agent which provides access to the URL on the enter method.
63
+ # Recreating the agent is very costly. As it tries to load the plugins and these may be heavy
64
+ # Specially the discovery service plugin is trying to load a file from disk every single time.
65
+ # We need to access a variable inside farscape to reuse the agent more than once.
66
+ # Once Farscape has a version which let us reuse the agent we will delete this helper.
67
+ class Agent
68
+ def initialize
69
+ @agent = Farscape::Agent.new
70
+ end
71
+
72
+ def enter(root)
73
+ @agent.instance_variable_set(:@entry_point, root)
74
+ @agent.enter(root)
75
+ end
76
+
77
+ def discover(resource_name, template_variables)
78
+ if @agent.respond_to?(:discover)
79
+ @agent.discover(resource_name)
80
+ else
81
+ @agent.enter(resource_name)
82
+ end
83
+ end
84
+
85
+ def method_missing(name, *args, &block)
86
+ @agent.send(name, *args, &block)
87
+ end
88
+ end
89
+
90
+ def self.log_error(message, e)
91
+ Farscape.logger.error("Hippocrates Error, class #{e.class} \n #{message}: '#{e.message}' \n #{e.backtrace.join("\n")}")
92
+ nil
93
+ end
94
+ end
95
+ end
@@ -1,6 +1,6 @@
1
1
  # Used to prevent the class/module from being loaded more than once
2
2
  unless defined?(::Farscape::VERSION)
3
3
  module Farscape
4
- VERSION = '1.2.0'.freeze
4
+ VERSION = '1.3.0'.freeze
5
5
  end
6
6
  end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Farscape::Agent do
4
+ describe '#instance' do
5
+ it 'returns an Farscape::Agent object' do
6
+ expect(described_class.instance.class).to eq(described_class)
7
+ end
8
+
9
+ it 'returns the same agent if called twice' do
10
+ agent1 = described_class.instance
11
+ expect(described_class.instance).to eq(agent1)
12
+ end
13
+ end
14
+
15
+ describe '#config' do
16
+ it 'defaults to an empty hash' do
17
+ expect(described_class.config).to eq({})
18
+ end
19
+
20
+ it 'can be set' do
21
+ described_class.config = { me: 'too' }
22
+ expect(described_class.config).to eq( me: 'too' )
23
+ described_class.config = nil
24
+ end
25
+ end
26
+ end
@@ -3,6 +3,42 @@ require 'spec_helper'
3
3
  describe Farscape::Agent do
4
4
  let(:entry_point) { "http://localhost:#{RAILS_PORT}"}
5
5
 
6
+ describe '#discover' do
7
+ let(:resource_name) { 'user' }
8
+ let(:links) do
9
+ {
10
+ _links: {
11
+ resource_name => { href: entry_point }
12
+ }
13
+ }
14
+ end
15
+ before do
16
+ described_class.config = { discovery_uri: "https://www.example.com" }
17
+ stub_request(:any, "https://www.example.com").to_return(body: links.to_json)
18
+ end
19
+ after do
20
+ described_class.config = nil
21
+ end
22
+
23
+ it 'returns a Farscape::Representor from a name' do
24
+ expect(Farscape::Agent.new(resource_name).enter).to be_a Farscape::RepresentorAgent
25
+ end
26
+
27
+ it 'raises Discovery::NotFound if the name does not exist in the discovery service' do
28
+ expect{ Farscape::Agent.new('unknown').enter }.to raise_error Farscape::Discovery::NotFound
29
+ end
30
+
31
+ it 'raises Discovery::NotFound if the discovery url is not setup' do
32
+ described_class.config = nil
33
+ expect{ Farscape::Agent.new.discover_entry_point(resource_name) }.to raise_error Farscape::Discovery::NotFound
34
+ end
35
+
36
+ it 'raises Discovery::NotFound if the discovery url is not a proper url' do
37
+ described_class.config = { discovery_uri: "aaaaa" }
38
+ expect{ Farscape::Agent.new.discover_entry_point(resource_name) }.to raise_error Farscape::Discovery::NotFound
39
+ end
40
+ end
41
+
6
42
  describe '#enter' do
7
43
  it 'returns a Farscape::Representor' do
8
44
  expect(Farscape::Agent.new(entry_point).enter).to be_a Farscape::RepresentorAgent
@@ -276,7 +276,6 @@ describe Farscape do
276
276
  Farscape.register_plugin(name: :Wormlet, type: :discovery, extensions: {Agent: [ServiceCatalogue]})
277
277
  expect(Farscape::Agent.new(:moya).enter.transitions.keys).to include("drds")
278
278
  expect(Farscape::Agent.new.enter(:moya).transitions.keys).to include("drds")
279
- expect { Farscape::Agent.new.omitting(:discovery).enter(:moya).transitions.keys }.to raise_error(NoMethodError)
280
279
  end
281
280
 
282
281
  end
data/spec/spec_helper.rb CHANGED
@@ -5,6 +5,9 @@ require 'crichton'
5
5
  require 'representors'
6
6
  require 'moya'
7
7
 
8
+ require 'webmock/rspec'
9
+
10
+
8
11
  RAILS_PORT = 1234
9
12
  SPEC_DIR = File.expand_path("..", __FILE__)
10
13
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
@@ -12,6 +15,9 @@ require 'farscape'
12
15
 
13
16
  Dir["#{SPEC_DIR}/support/*.rb"].each { |f| require f }
14
17
 
18
+
19
+ WebMock.disable_net_connect!(allow_localhost: true)
20
+
15
21
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
16
22
  RSpec.configure do |config|
17
23
  config.treat_symbols_as_metadata_keys_with_true_values = true
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: farscape
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark W. Foster
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-17 00:00:00.000000000 Z
11
+ date: 2016-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '2.14'
125
+ - !ruby/object:Gem::Dependency
126
+ name: webmock
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '2.0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '2.0'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: simplecov
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -171,14 +185,17 @@ files:
171
185
  - lib/farscape/client/base_client.rb
172
186
  - lib/farscape/client/http_client.rb
173
187
  - lib/farscape/clients.rb
188
+ - lib/farscape/discovery.rb
174
189
  - lib/farscape/errors.rb
175
190
  - lib/farscape/helpers/partially_ordered_list.rb
176
191
  - lib/farscape/logger.rb
192
+ - lib/farscape/platform_resources.rb
177
193
  - lib/farscape/plugins.rb
178
194
  - lib/farscape/representor.rb
179
195
  - lib/farscape/transition.rb
180
196
  - lib/farscape/version.rb
181
197
  - lib/plugins/plugins.rb
198
+ - spec/lib/farscape/agent_spec.rb
182
199
  - spec/lib/farscape/cache_spec.rb
183
200
  - spec/lib/farscape/integration/entry_point_spec.rb
184
201
  - spec/lib/farscape/integration/interface_spec.rb