hypertext_client 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,6 @@
1
+ ## 0.0.2 (September 24, 2010)
2
+
3
+ Support belongs_to for parent/child relationships, client classes in module.
1
4
 
2
5
  ## 0.0.1 (September 23, 2010)
3
6
 
@@ -18,16 +18,20 @@
18
18
 
19
19
  # Hypertext provides an HTTP client based on HTTParty, with a few assumptions baked in.
20
20
  module HypertextClient
21
- VERSION = '0.0.1'
21
+ VERSION = '0.0.2'
22
22
 
23
23
  extend ActiveSupport::Concern
24
24
  # Include HTTParty
25
25
  @_dependencies = [HTTParty, ActiveModel::Conversion, ActiveModel::Validations]
26
26
 
27
27
  class NotFoundException < HTTParty::ResponseError; end
28
+ class MissingArgumentError < ArgumentError; end
28
29
 
29
30
  included do
30
31
  extend ActiveModel::Naming
32
+ class_attribute :parents
33
+ class_attribute :base_endpoint
34
+ self.parents = []
31
35
  raise 'HypertextClient depends on ObjectStruct. Inherit from ObjectStruct.' unless self.ancestors.include? ObjectStruct
32
36
  end
33
37
 
@@ -68,7 +72,7 @@ module HypertextClient
68
72
 
69
73
  # Get a related property.
70
74
  def get_related(related)
71
- klass = related.to_s.singularize.classify.constantize
75
+ klass = (self.class.name.split('::').first + '::' + related.to_s.singularize.classify).constantize
72
76
  result = klass.get(send (related.to_s+'_url').to_sym)
73
77
 
74
78
  (class << self; self; end).instance_eval do
@@ -86,7 +90,13 @@ module HypertextClient
86
90
 
87
91
  # Specify a base url for the client.
88
92
  def base_url(base)
89
- base_uri base + '/' + self.to_s.parameterize.pluralize
93
+ self.base_endpoint = base
94
+ base_uri self.base_endpoint + '/' + self.name.split('::').last.parameterize.pluralize
95
+ end
96
+
97
+ def belongs_to(*classes)
98
+ self.parents += classes.select {|c| c.respond_to? :model_name}
99
+ base_url self.base_endpoint + '/' + self.parents.map {|parent| parent.model_name.split('::').last.parameterize}.map{|name| "#{name.pluralize}/|#{name.singularize}|"} * '/'
90
100
  end
91
101
 
92
102
  # Override HTTParty's methods to allow assumptions about a '/' path.
@@ -104,6 +114,16 @@ module HypertextClient
104
114
  path = ''
105
115
  end
106
116
 
117
+ if self.parents.count > 0
118
+ options = args.first
119
+ raise MissingArgumentError.new("Options hash required; must include parent ids") unless options.is_a? Hash
120
+ self.parents.each do |parent|
121
+ key = parent.model_name.split('::').last.parameterize.singularize.to_sym
122
+ raise MissingArgumentError.new("Missing required argument: #{key}") unless options.has_key? key
123
+ base_uri self.base_uri.gsub("|#{key}|", options[key])
124
+ end
125
+ end
126
+
107
127
  response = super(path, *args)
108
128
  case response.code
109
129
  when (200..299)
@@ -16,6 +16,7 @@
16
16
  #
17
17
  # ---------------------------------------------------------------------------
18
18
 
19
+ require 'active_support/core_ext/class/attribute'
19
20
  require 'active_support/inflector'
20
21
  require 'active_support/concern'
21
22
  require 'active_model'
@@ -8,7 +8,7 @@ begin; require 'redgreen'; rescue LoadError; end
8
8
 
9
9
  require 'hypertext_client'
10
10
 
11
- FAKE_ENDPOINT = "http://api.widgetsinc.com"
11
+ FAKE_ENDPOINT = "http://api.skynetinc.com"
12
12
 
13
13
  FakeWeb.allow_net_connect = false
14
14
  FakeWeb.register_uri(:get,
@@ -26,6 +26,11 @@ FakeWeb.register_uri(:get,
26
26
  :body => {:name => 'Frobby Widget', :knob_url => FAKE_ENDPOINT + '/knobs/excellent_knob'}.to_json,
27
27
  :content_type => 'application/json')
28
28
 
29
+ FakeWeb.register_uri(:get,
30
+ FAKE_ENDPOINT + '/widgets/frobby_widget/buttons/red_button',
31
+ :body => {:description => 'Scary Red Button'}.to_json,
32
+ :content_type => 'application/json')
33
+
29
34
  FakeWeb.register_uri(:get,
30
35
  FAKE_ENDPOINT + '/widgets/not_there',
31
36
  :status => ['404', 'Not Found'],
@@ -33,47 +38,69 @@ FakeWeb.register_uri(:get,
33
38
  :content_type => 'application/json')
34
39
 
35
40
 
36
- class Widget < ObjectStruct
37
- include HypertextClient
38
- base_url FAKE_ENDPOINT
39
- headers 'Accept' => 'application/json'
41
+ module SkynetClient
42
+ extend ActiveSupport::Concern
43
+ @_dependencies = [HypertextClient]
44
+ included do
45
+ base_url FAKE_ENDPOINT
46
+ headers 'Accept' => 'application/json'
47
+ end
40
48
  end
41
49
 
42
- class Knob < ObjectStruct
43
- include HypertextClient
44
- base_url FAKE_ENDPOINT
45
- headers 'Accept' => 'application/json'
50
+ class SkynetClient::Widget < ObjectStruct
51
+ include SkynetClient
46
52
  end
47
53
 
54
+ class SkynetClient::Knob < ObjectStruct
55
+ include SkynetClient
56
+ end
57
+
58
+ class SkynetClient::Button < ObjectStruct
59
+ include SkynetClient
60
+ belongs_to Widget
61
+ end
62
+
63
+
48
64
  class HypertextClientTest < MiniTest::Unit::TestCase
49
65
  include ActiveModel::Lint::Tests
50
66
 
51
67
  def setup
52
68
  # For ActiveModel tests
53
- @model = Widget.get('frobby_widget')
69
+ @model = SkynetClient::Widget.get('frobby_widget')
54
70
  end
55
71
 
56
72
  def test_get_basic_resource
57
- assert_equal 'Frobby Widget', Widget.get('frobby_widget').name
73
+ assert_equal 'Frobby Widget', SkynetClient::Widget.get('frobby_widget').name
58
74
  end
59
75
 
60
76
  def test_should_raise_not_found
61
- assert_raises HypertextClient::NotFoundException do Widget.get('not_there') end
77
+ assert_raises HypertextClient::NotFoundException do SkynetClient::Widget.get('not_there') end
62
78
  end
63
79
 
64
80
  def test_should_get_index_array
65
- response = Widget.get
81
+ response = SkynetClient::Widget.get
66
82
  assert_instance_of Array, response
67
- assert response.all? {|e| e.instance_of? Widget}
83
+ assert response.all? {|e| e.instance_of? SkynetClient::Widget}
68
84
  end
69
85
 
70
86
  def test_traverse_related
71
- knob = Widget.get('frobby_widget').knob
87
+ knob = SkynetClient::Widget.get('frobby_widget').knob
72
88
  assert_equal 'Adjustormatic', knob.label
73
89
  end
74
90
 
75
91
  def test_has_related?
76
- assert Widget.get('frobby_widget').has_knob?
77
- refute Widget.get('frobby_widget').has_lever?
92
+ assert SkynetClient::Widget.get('frobby_widget').has_knob?
93
+ refute SkynetClient::Widget.get('frobby_widget').has_lever?
94
+ end
95
+
96
+ def test_request_child_resources
97
+ button = SkynetClient::Button.get 'red_button', :widget => 'frobby_widget'
98
+ assert_equal "Scary Red Button", button.description
99
+ end
100
+
101
+ def test_complain_if_no_parent_id_specified
102
+ assert_raises HypertextClient::MissingArgumentError do
103
+ SkynetClient::Button.get 'red_button'
104
+ end
78
105
  end
79
106
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Quid, Inc.
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-09-23 00:00:00 -07:00
17
+ date: 2010-09-24 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency