helix 0.0.2.8.pre → 0.0.2.9.pre

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.
@@ -9,6 +9,7 @@ require 'helix/image'
9
9
  require 'helix/config'
10
10
  require 'helix/statistics'
11
11
  require 'helix/library'
12
+ require 'to_xml'
12
13
 
13
14
  module Helix
14
15
  end
@@ -12,7 +12,7 @@ module Helix
12
12
  # Helix::Album.resource_label_sym #=> :album
13
13
  #
14
14
  # @return [Symbol] Name of the class.
15
- def self.resource_label_sym; super; end
15
+ def self.resource_label_sym; :album; end
16
16
 
17
17
  # Currently update is unsupported for album.
18
18
  #
@@ -65,7 +65,7 @@ module Helix
65
65
  #
66
66
  # @return [String] The guid name for a specific class.
67
67
  def self.guid_name
68
- "#{self.resource_label_sym}_id"
68
+ "#{resource_label_sym}_id"
69
69
  end
70
70
 
71
71
  # Creates a string associated with a class name pluralized
@@ -75,7 +75,7 @@ module Helix
75
75
  #
76
76
  # @return [String] The class name pluralized
77
77
  def self.plural_resource_label
78
- "#{self.resource_label_sym}s"
78
+ "#{resource_label_sym}s"
79
79
  end
80
80
 
81
81
  METHODS_DELEGATED_TO_CLASS.each do |meth|
@@ -97,6 +97,26 @@ module Helix
97
97
  @config ||= Helix::Config.instance
98
98
  end
99
99
 
100
+ # Looks up the custom field value for a given name.
101
+ #
102
+ # @example
103
+ # video.custom_field('stars_kevin_bacon') #=> "true"
104
+ #
105
+ # @return [String] The value whose key is the given custom field name.
106
+ def custom_field(k)
107
+ custom_fields[k]
108
+ end
109
+
110
+ # Returns all custom fields.
111
+ #
112
+ # @example
113
+ # video.custom_fields #=> { "stars_kevin_bacon" => "true" }
114
+ #
115
+ # @return [Hash] The custom fields in the form { name1 => value1, name2 => value2, ... }
116
+ def custom_fields
117
+ modified_attributes['custom_fields']
118
+ end
119
+
100
120
  # Creates a string that associates to the class id.
101
121
  #
102
122
  # @example
@@ -182,8 +202,11 @@ module Helix
182
202
  end
183
203
 
184
204
  def modified_attributes
205
+ return if @attributes.nil?
185
206
  custom_fields = @attributes['custom_fields']
186
207
  return @attributes if custom_fields.nil?
208
+ return @attributes unless custom_fields.respond_to?(:first)
209
+ return @attributes unless custom_fields.first.respond_to?(:[])
187
210
  return @attributes if custom_fields.first['name'].nil?
188
211
  new_cfs = custom_fields.inject({}) do |memo,cf|
189
212
  memo.merge(cf['name'] => cf['value'])
@@ -191,9 +214,5 @@ module Helix
191
214
  @attributes.merge('custom_fields' => new_cfs)
192
215
  end
193
216
 
194
- def self.resource_label_sym
195
- to_s.split('::').last.singularize.downcase.to_sym
196
- end
197
-
198
217
  end
199
218
  end
@@ -36,7 +36,10 @@ module Helix
36
36
  def self.load(yaml_file_location = DEFAULT_FILENAME)
37
37
  config = self.instance
38
38
  config.instance_variable_set(:@filename, yaml_file_location)
39
- creds = YAML.load(File.open(yaml_file_location)).symbolize_keys
39
+ creds = YAML.load(File.open(yaml_file_location)).inject({}) do |memo,pair|
40
+ k, v = *pair
41
+ memo.merge(k.to_sym => v)
42
+ end
40
43
  config.instance_variable_set(:@credentials, creds)
41
44
  RestClient.proxy = config.proxy
42
45
  config
@@ -83,13 +86,13 @@ module Helix
83
86
  # @return [Array] The accumulated attribute Hashes for ORM instances
84
87
  def get_aggregated_data_sets(url, plural_resource_label, original_opts={})
85
88
  data_sets, page, per_page = [], STARTING_PAGE
86
- until last_page?
89
+ begin
87
90
  aggregation_opts = original_opts.merge(page: page, per_page: ITEMS_PER_PAGE)
88
91
  raw_response = get_response(url, {sig_type: :view}.merge(aggregation_opts))
89
92
  data_set = raw_response[plural_resource_label]
90
93
  data_sets += data_set if data_set
91
94
  page += 1
92
- end
95
+ end until last_page?
93
96
  data_sets
94
97
  end
95
98
 
@@ -56,7 +56,7 @@ module Helix
56
56
  # @param [Hash] attrs The attributes for creating xml.
57
57
  # @return [String] Returns xml either from a raw entry or generated from attributes.
58
58
  def get_xml(attrs={})
59
- return attrs[:use_raw_xml] if attrs[:use_raw_xml].present?
59
+ return attrs[:use_raw_xml] if attrs[:use_raw_xml] && attrs[:use_raw_xml] != ''
60
60
  xml_opts = {root: :add }
61
61
  { list: { entry: attrs[:url_params] || {} } }.to_xml(xml_opts)
62
62
  end
@@ -12,7 +12,7 @@ module Helix
12
12
  # Helix::Image.resource_label_sym #=> :image
13
13
  #
14
14
  # @return [Symbol] Name of the class.
15
- def self.resource_label_sym; super; end
15
+ def self.resource_label_sym; :image; end
16
16
 
17
17
  end
18
18
 
@@ -14,7 +14,7 @@ module Helix
14
14
  # Helix::Library.resource_label_sym #=> :library
15
15
  #
16
16
  # @return [Symbol] Name of the class.
17
- def self.resource_label_sym; super; end
17
+ def self.resource_label_sym; :library; end
18
18
 
19
19
  # Creates a string associated with a class name pluralized
20
20
  #
@@ -135,7 +135,8 @@ module Helix
135
135
  url_opts.merge!(content_type: content_type) if content_type
136
136
  url = memo_cfg.build_url(url_opts)
137
137
  # We allow opts[:sig_type] for internal negative testing only.
138
- memo_cfg.get_response(url, {sig_type: :view}.merge(opts))
138
+ raw = memo_cfg.get_response(url, {sig_type: :view}.merge(opts))
139
+ standardize_raw_stats(raw)
139
140
  end
140
141
 
141
142
  def self.ingest(resource_label, original_opts)
@@ -154,7 +155,8 @@ module Helix
154
155
  url_opts.merge!(content_type: content_type) if content_type
155
156
  url = memo_cfg.build_url(url_opts)
156
157
  # We allow opts[:sig_type] for internal negative testing only.
157
- memo_cfg.get_response(url, {sig_type: :view}.merge(opts))
158
+ raw = memo_cfg.get_response(url, {sig_type: :view}.merge(opts))
159
+ standardize_raw_stats(raw)
158
160
  end
159
161
 
160
162
  def self.ingest_action_prefix_for(resource_label)
@@ -165,6 +167,14 @@ module Helix
165
167
  STORAGE_ACTION_FOR[resource_label].to_sym
166
168
  end
167
169
 
170
+ private
171
+
172
+ def self.standardize_raw_stats(raw)
173
+ return raw unless raw.respond_to?(:has_key?)
174
+ return raw unless raw.has_key?('statistics_reports')
175
+ raw['statistics_reports']
176
+ end
177
+
168
178
  end
169
179
 
170
180
  end
@@ -13,6 +13,25 @@ module Helix
13
13
  # Helix::Tag.resource_label_sym #=> :tag
14
14
  #
15
15
  # @return [Symbol] Name of the class.
16
- def self.resource_label_sym; super; end
16
+ def self.resource_label_sym; :tag; end
17
+
18
+ # This is being used to override the current way of calling to our system
19
+ # since the current way uses pagination. This method does not add in
20
+ # pagination. Adding paginaton to Tags currently breaks the call. This
21
+ # method should be a temporary fix.
22
+ #
23
+ # Does a GET call to the api and defaults to content_type xml and
24
+ # signature_type view.
25
+ #
26
+ #
27
+ # @param [Hash] opts a hash of options for parameters passed into the HTTP GET
28
+ # @return [Array] The array of attributes (for a model) in hash form.
29
+ def self.get_data_sets(opts)
30
+ url = config.build_url(content_type: opts[:content_type] || :xml,
31
+ resource_label: self.plural_resource_label)
32
+ # We allow opts[:sig_type] for internal negative testing only.
33
+ raw_response = config.get_response(url, {sig_type: :view}.merge(opts))
34
+ data_sets = raw_response[plural_resource_label]
35
+ end
17
36
  end
18
37
  end
@@ -14,7 +14,7 @@ module Helix
14
14
  # Helix::Track.resource_label_sym #=> :track
15
15
  #
16
16
  # @return [Symbol] Name of the class.
17
- def self.resource_label_sym; super; end
17
+ def self.resource_label_sym; :track; end
18
18
 
19
19
  end
20
20
 
@@ -1,5 +1,4 @@
1
1
  require 'helix/media'
2
- require 'active_support/core_ext'
3
2
 
4
3
  module Helix
5
4
 
@@ -15,7 +14,7 @@ module Helix
15
14
  # Helix::Video.resource_label_sym #=> :video
16
15
  #
17
16
  # @return [Symbol] Name of the class.
18
- def self.resource_label_sym; super; end
17
+ def self.resource_label_sym; :video; end
19
18
 
20
19
  # Used to create a slice video from an existing video.
21
20
  # API doc reference: /doc/api/video/slice
@@ -155,144 +155,265 @@ describe Helix::Base do
155
155
  end
156
156
  end
157
157
 
158
- describe "an instance" do
159
- let(:obj) { klass.new({}) }
158
+ shared_examples_for "builds URL for load" do
159
+ it "should call #guid" do
160
+ obj.should_receive(:guid) { 'some_guid' }
161
+ obj.send(meth)
162
+ end
163
+ it "should build_url(content_type: :json, guid: the_guid, resource_label: 'videos')" do
164
+ mock_config.should_receive(:build_url).with(content_type: :json, guid: 'some_guid', resource_label: 'videos')
165
+ RestClient.stub(:put)
166
+ obj.send(meth)
167
+ end
168
+ end
169
+
170
+ klasses = [ Helix::Album, Helix::Image, Helix::Track, Helix::Video ]
171
+ klasses.each do |klass|
172
+
173
+ describe "an instance of class #{klass.to_s}" do
174
+ let(:obj) { klass.new({}) }
160
175
 
161
176
  ### INSTANCE METHODS
162
177
 
163
- describe ".config" do
164
- let(:meth) { :config }
165
- subject { obj.method(meth) }
166
- its(:arity) { should eq(0) }
167
- describe "when called" do
168
- subject { obj.send(meth) }
169
- context "and @config is already set" do
170
- before(:each) do obj.instance_variable_set(:@config, :cached_val) end
171
- it { should be(:cached_val) }
178
+ describe ".config" do
179
+ let(:meth) { :config }
180
+ subject { obj.method(meth) }
181
+ its(:arity) { should eq(0) }
182
+ describe "when called" do
183
+ subject { obj.send(meth) }
184
+ context "and @config is already set" do
185
+ before(:each) do obj.instance_variable_set(:@config, :cached_val) end
186
+ it { should be(:cached_val) }
187
+ end
188
+ context "and @config is NOT already set" do
189
+ before(:each) do obj.instance_variable_set(:@config, nil) end
190
+ it { should eq(Helix::Config.instance) }
191
+ end
172
192
  end
173
- context "and @config is NOT already set" do
174
- before(:each) do obj.instance_variable_set(:@config, nil) end
175
- it { should eq(Helix::Config.instance) }
193
+ end
194
+
195
+ describe "#custom_field" do
196
+ let(:meth) { :custom_field }
197
+ describe "arity" do
198
+ subject { obj.method(meth) }
199
+ its(:arity) { should eq(1) }
200
+ end
201
+ it "should be modified_attributes['custom_fields'][arg]" do
202
+ obj.stub(:modified_attributes) { {'custom_fields' => {key1: :value1}} }
203
+ expect(obj.send(meth, :key1)).to be(:value1)
204
+ expect(obj.send(meth, :key2)).to be(nil)
176
205
  end
177
206
  end
178
- end
179
207
 
180
- describe "#guid" do
181
- let(:meth) { :guid }
182
- it "should return @attributes[guid_name]" do
183
- mock_attributes = mock(Object)
184
- obj.instance_variable_set(:@attributes, mock_attributes)
185
- obj.should_receive(:guid_name) { :the_guid_name }
186
- mock_attributes.should_receive(:[]).with(:the_guid_name) { :expected }
187
- expect(obj.send(meth)).to eq(:expected)
208
+ describe "#custom_fields" do
209
+ let(:meth) { :custom_fields }
210
+ describe "arity" do
211
+ subject { obj.method(meth) }
212
+ its(:arity) { should eq(0) }
213
+ end
214
+ it "should delegate to modified_attributes['custom_fields']" do
215
+ cfs = {key1: :value1}
216
+ obj.stub(:modified_attributes) { {'custom_fields' => cfs} }
217
+ expect(obj.send(meth)).to be(cfs)
218
+ end
188
219
  end
189
- end
190
220
 
191
- describe "#guid_name" do
192
- let(:meth) { :guid_name }
193
- it "should delegate to the class" do
194
- klass.should_receive(meth) { :expected }
195
- expect(obj.send(meth)).to be(:expected)
221
+ describe "#guid" do
222
+ let(:meth) { :guid }
223
+ it "should return @attributes[guid_name]" do
224
+ mock_attributes = mock(Object)
225
+ obj.instance_variable_set(:@attributes, mock_attributes)
226
+ obj.should_receive(:guid_name) { :the_guid_name }
227
+ mock_attributes.should_receive(:[]).with(:the_guid_name) { :expected }
228
+ expect(obj.send(meth)).to eq(:expected)
229
+ end
196
230
  end
197
- end
198
231
 
199
- describe "#load" do
200
- let(:meth) { :load }
201
- let(:mock_config) { mock(Helix::Config) }
202
- subject { obj.method(meth) }
203
- its(:arity) { should eq(-1) }
204
- before(:each) do
205
- obj.stub(:config) { mock_config }
206
- obj.stub(:guid) { 'some_guid' }
207
- obj.stub(:signature) { 'some_sig' }
208
- obj.stub(:massage_raw_attrs) { :massaged_attrs }
209
- mock_config.stub(:build_url) { :expected_url }
210
- mock_config.stub(:get_response) { :raw_attrs }
211
- klass.stub(:resource_label_sym) { :video }
232
+ describe "#guid_name" do
233
+ let(:meth) { :guid_name }
234
+ it "should delegate to the class" do
235
+ klass.should_receive(meth) { :expected }
236
+ expect(obj.send(meth)).to be(:expected)
237
+ end
212
238
  end
213
- shared_examples_for "builds URL for load" do
214
- it "should call #guid" do
215
- obj.should_receive(:guid) { 'some_guid' }
216
- obj.send(meth)
239
+
240
+ describe "#load" do
241
+ let(:meth) { :load }
242
+ let(:mock_config) { mock(Helix::Config) }
243
+ subject { obj.method(meth) }
244
+ its(:arity) { should eq(-1) }
245
+ before(:each) do
246
+ obj.stub(:config) { mock_config }
247
+ obj.stub(:guid) { 'some_guid' }
248
+ obj.stub(:signature) { 'some_sig' }
249
+ obj.stub(:massage_raw_attrs) { :massaged_attrs }
250
+ mock_config.stub(:build_url) { :expected_url }
251
+ mock_config.stub(:get_response) { :raw_attrs }
252
+ klass.stub(:resource_label_sym) { :video }
217
253
  end
218
- it "should build_url(content_type: :json, guid: the_guid, resource_label: 'videos')" do
219
- mock_config.should_receive(:build_url).with(content_type: :json, guid: 'some_guid', resource_label: 'videos')
220
- RestClient.stub(:put)
221
- obj.send(meth)
254
+ context "when given no argument" do
255
+ it_behaves_like "builds URL for load"
256
+ it "should call klass.get_response(output_of_build_url, {sig_type: :view}) and return instance of klass" do
257
+ mock_config.should_receive(:get_response).with(:expected_url, {sig_type: :view})
258
+ expect(obj.send(meth)).to be_an_instance_of(klass)
259
+ end
260
+ it "should massage the raw_attrs" do
261
+ obj.should_receive(:massage_raw_attrs).with(:raw_attrs)
262
+ obj.send(meth)
263
+ end
264
+ end
265
+ context "when given an opts argument of {key1: :value1}" do
266
+ let(:opts) { {key1: :value1} }
267
+ it_behaves_like "builds URL for load"
268
+ it "should call klass.get_response(output_of_build_url, opts.merge(sig_type: :view)) and return instance of klass" do
269
+ mock_config.should_receive(:get_response).with(:expected_url, opts.merge(sig_type: :view))
270
+ expect(obj.send(meth, opts)).to be_an_instance_of(klass)
271
+ end
272
+ it "should massage the raw_attrs" do
273
+ obj.should_receive(:massage_raw_attrs).with(:raw_attrs)
274
+ obj.send(meth, opts)
275
+ end
222
276
  end
223
277
  end
224
- context "when given no argument" do
225
- it_behaves_like "builds URL for load"
226
- it "should call klass.get_response(output_of_build_url, {sig_type: :view}) and return instance of klass" do
227
- mock_config.should_receive(:get_response).with(:expected_url, {sig_type: :view})
228
- expect(obj.send(meth)).to be_an_instance_of(klass)
278
+
279
+ describe "#massage_raw_attrs" do
280
+ let(:meth) { :massage_raw_attrs }
281
+ let(:guid_name) { :the_guid_name }
282
+
283
+ subject { obj.method(meth) }
284
+ its(:arity) { should eq(1) }
285
+
286
+ before(:each) { obj.stub(:guid_name) { guid_name } }
287
+ context "when given {}" do
288
+ let(:raw_attrs) { {} }
289
+ subject { obj.send(meth, raw_attrs) }
290
+ it { should eq(nil) }
229
291
  end
230
- it "should massage the raw_attrs" do
231
- obj.should_receive(:massage_raw_attrs).with(:raw_attrs)
232
- obj.send(meth)
292
+ context "when given { guid_name => :the_val }" do
293
+ let(:raw_attrs) { { guid_name => :the_val } }
294
+ subject { obj.send(meth, raw_attrs) }
295
+ it { should eq(raw_attrs) }
233
296
  end
234
- end
235
- context "when given an opts argument of {key1: :value1}" do
236
- let(:opts) { {key1: :value1} }
237
- it_behaves_like "builds URL for load"
238
- it "should call klass.get_response(output_of_build_url, opts.merge(sig_type: :view)) and return instance of klass" do
239
- mock_config.should_receive(:get_response).with(:expected_url, opts.merge(sig_type: :view))
240
- expect(obj.send(meth, opts)).to be_an_instance_of(klass)
297
+ context "when given [{ guid_name => :the_val }]" do
298
+ let(:raw_attrs) { [{ guid_name => :the_val }] }
299
+ subject { obj.send(meth, raw_attrs) }
300
+ it { should eq(raw_attrs.first) }
241
301
  end
242
- it "should massage the raw_attrs" do
243
- obj.should_receive(:massage_raw_attrs).with(:raw_attrs)
244
- obj.send(meth, opts)
302
+ end
303
+
304
+ describe "#method_missing" do
305
+ let(:meth) { :method_missing }
306
+ subject { obj.method(meth) }
307
+ its(:arity) { should eq(1) }
308
+ context "when given method_sym" do
309
+ let(:method_sym) { :method_sym }
310
+ let(:mock_attributes) { mock(Object) }
311
+ before(:each) do obj.instance_variable_set(:@attributes, mock_attributes) end
312
+ context "and @attributes[method_sym.to_s] raises an exception" do
313
+ before(:each) do mock_attributes.should_receive(:[]).with(method_sym.to_s).and_raise("some exception") end
314
+ it "should raise a NoMethodError" do
315
+ msg = "#{method_sym} is not recognized within #{klass}'s methods or @attributes"
316
+ expect(lambda { obj.send(meth, method_sym) }).to raise_error(msg)
317
+ end
318
+ end
319
+ context "and @attributes[method_sym.to_s] does NOT raise an exception" do
320
+ before(:each) do mock_attributes.should_receive(:[]).with(method_sym.to_s) { :expected } end
321
+ it "should return @attributes[method_sym.to_s]" do
322
+ expect(obj.send(meth, method_sym)).to eq(:expected)
323
+ end
324
+ end
245
325
  end
246
326
  end
247
- end
248
327
 
249
- describe "#massage_raw_attrs" do
250
- let(:meth) { :massage_raw_attrs }
251
- let(:guid_name) { :the_guid_name }
328
+ describe "modified_attributes" do
329
+ let(:meth) { :modified_attributes }
252
330
 
253
- subject { obj.method(meth) }
254
- its(:arity) { should eq(1) }
331
+ describe "arity" do
332
+ subject { obj.method(meth) }
333
+ its(:arity) { should eq(0) }
334
+ end
255
335
 
256
- before(:each) { obj.stub(:guid_name) { guid_name } }
257
- context "when given {}" do
258
- let(:raw_attrs) { {} }
259
- subject { obj.send(meth, raw_attrs) }
260
- it { should eq(nil) }
261
- end
262
- context "when given { guid_name => :the_val }" do
263
- let(:raw_attrs) { { guid_name => :the_val } }
264
- subject { obj.send(meth, raw_attrs) }
265
- it { should eq(raw_attrs) }
266
- end
267
- context "when given [{ guid_name => :the_val }]" do
268
- let(:raw_attrs) { [{ guid_name => :the_val }] }
269
- subject { obj.send(meth, raw_attrs) }
270
- it { should eq(raw_attrs.first) }
271
- end
272
- end
336
+ describe "access" do
337
+ subject { obj }
338
+ its(:private_methods) { should include(meth) }
339
+ end
273
340
 
274
- describe "#method_missing" do
275
- let(:meth) { :method_missing }
276
- subject { obj.method(meth) }
277
- its(:arity) { should eq(1) }
278
- context "when given method_sym" do
279
- let(:method_sym) { :method_sym }
280
- let(:mock_attributes) { mock(Object) }
281
- before(:each) do obj.instance_variable_set(:@attributes, mock_attributes) end
282
- context "and @attributes[method_sym.to_s] raises an exception" do
283
- before(:each) do mock_attributes.should_receive(:[]).with(method_sym.to_s).and_raise("some exception") end
284
- it "should raise a NoMethodError" do
285
- msg = "#{method_sym} is not recognized within #{klass}'s methods or @attributes"
286
- expect(lambda { obj.send(meth, method_sym) }).to raise_error(msg)
287
- end
341
+ subject { obj.send(meth) }
342
+ context "when @attributes is nil" do
343
+ before(:each) do obj.instance_variable_set(:@attributes, nil) end
344
+ it { should be(nil) }
288
345
  end
289
- context "and @attributes[method_sym.to_s] does NOT raise an exception" do
290
- before(:each) do mock_attributes.should_receive(:[]).with(method_sym.to_s) { :expected } end
291
- it "should return @attributes[method_sym.to_s]" do
292
- expect(obj.send(meth, method_sym)).to eq(:expected)
346
+ context "when @attributes is {}" do
347
+ before(:each) do obj.instance_variable_set(:@attributes, {}) end
348
+ it { should eq({}) }
349
+ end
350
+ bases = [ {}, {'k1' => 'v1', 'k2' => 'v2'} ]
351
+ potential_additions = [
352
+ {'custom_fields' => nil},
353
+ {'custom_fields' => [{}]},
354
+ {'custom_fields' => [{'name' => nil}]},
355
+ {'custom_fields' => [{'name' => nil}, {'name' => nil}]}
356
+ ]
357
+ bases.each do |base|
358
+ potential_additions.each do |additions|
359
+ attrs = base.merge(additions)
360
+ context "when @attributes is #{attrs}" do
361
+ before(:each) do obj.instance_variable_set(:@attributes, attrs) end
362
+ it { should eq(attrs) }
363
+ end
364
+ end
365
+ context "when @attributes is #{base.merge({'custom_fields' => [{'name' => 'some name'}]})}" do
366
+ before(:each) do
367
+ attrs = base.merge({'custom_fields' => [{'name' => 'some name'}]})
368
+ obj.instance_variable_set(:@attributes, attrs)
369
+ end
370
+ it { should eq(base.merge("custom_fields" => {"some name"=>nil})) }
371
+ end
372
+ context "when @attributes is #{base.merge({'custom_fields' => [{'name' => 'some name'}, {'name' => 'other name'}]})}" do
373
+ before(:each) do
374
+ attrs = base.merge({'custom_fields' => [{'name' => 'some name'}, {'name' => 'other name'}]})
375
+ obj.instance_variable_set(:@attributes, attrs)
376
+ end
377
+ it { should eq(base.merge("custom_fields" => {"some name"=>nil, "other name"=>nil})) }
378
+ end
379
+ context "when @attributes is #{base.merge({'custom_fields' => [{'name' => 'some name'}, {'name' => 'other name'}]})}" do
380
+ before(:each) do
381
+ attrs = base.merge({'custom_fields' => [{'name' => 'some name'}, {'name' => 'other name'}]})
382
+ obj.instance_variable_set(:@attributes, attrs)
383
+ end
384
+ it { should eq(base.merge("custom_fields" => {"some name"=>nil, "other name"=>nil})) }
385
+ end
386
+ context "when @attributes is #{base.merge({'custom_fields' => [{'name' => 'some name', 'value' => nil}]})}" do
387
+ before(:each) do
388
+ attrs = base.merge({'custom_fields' => [{'name' => 'some name', 'value' => nil}]})
389
+ obj.instance_variable_set(:@attributes, attrs)
390
+ end
391
+ it { should eq(base.merge("custom_fields" => {"some name"=>nil})) }
392
+ end
393
+ context "when @attributes is #{base.merge({'custom_fields' => [{'name' => 'some name', 'value' => nil}, {'name' => 'other name', 'value' => nil}]})}" do
394
+ before(:each) do
395
+ attrs = base.merge({'custom_fields' => [{'name' => 'some name', 'value' => nil}, {'name' => 'other name', 'value' => nil}]})
396
+ obj.instance_variable_set(:@attributes, attrs)
397
+ end
398
+ it { should eq(base.merge("custom_fields" => {"some name"=>nil, "other name"=>nil})) }
399
+ end
400
+ context "when @attributes is #{base.merge({'custom_fields' => [{'name' => 'some name', 'value' => 'some value'}]})}" do
401
+ before(:each) do
402
+ attrs = base.merge({'custom_fields' => [{'name' => 'some name', 'value' => 'some value'}]})
403
+ obj.instance_variable_set(:@attributes, attrs)
404
+ end
405
+ it { should eq(base.merge("custom_fields" => {"some name"=>"some value"})) }
406
+ end
407
+ context "when @attributes is #{base.merge({'custom_fields' => [{'name' => 'some name', 'value' => 'some value'}, {'name' => 'other name', 'value' => 'other value'}]})}" do
408
+ before(:each) do
409
+ attrs = base.merge({'custom_fields' => [{'name' => 'some name', 'value' => 'some value'}, {'name' => 'other name', 'value' => 'other value'}]})
410
+ obj.instance_variable_set(:@attributes, attrs)
411
+ end
412
+ it { should eq(base.merge("custom_fields" => {"some name"=>"some value", "other name"=>"other value"})) }
293
413
  end
294
414
  end
295
415
  end
416
+
296
417
  end
297
418
 
298
419
  end