acts_as_sdata 1.0.0 → 1.0.1
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.
- data/.gitignore +3 -1
- data/Rakefile +0 -1
- data/VERSION +1 -1
- data/lib/s_data.rb +88 -0
- data/test/unit/controller_mixin/diagnosis_spec.rb +142 -118
- data/test/unit/spec_helpers/nokogiri_extensions.rb +6 -1
- metadata +4 -3
data/.gitignore
CHANGED
data/Rakefile
CHANGED
@@ -5,7 +5,6 @@ begin
|
|
5
5
|
|
6
6
|
Jeweler::Tasks.new do |gemspec|
|
7
7
|
gemspec.name = "acts_as_sdata"
|
8
|
-
gemspec.version = '1.0.0'
|
9
8
|
gemspec.authors = ["Daniel Vartanov", "Eugene Gilburg", "Michael Johnston"].sort
|
10
9
|
gemspec.email = "dan@vartanov.net"
|
11
10
|
gemspec.homepage = "http://sdata.sage.com/"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
1.0.1
|
data/lib/s_data.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'action_controller'
|
3
|
+
require 'atom' # TODO: add ratom _dependency_
|
4
|
+
|
5
|
+
module SData
|
6
|
+
class << self
|
7
|
+
def sdata_name(klass)
|
8
|
+
case klass
|
9
|
+
when SData::VirtualBase
|
10
|
+
klass.sdata_name
|
11
|
+
when Class
|
12
|
+
klass.respond_to?(:sdata_name) ? klass.sdata_name : nil
|
13
|
+
when String
|
14
|
+
klass.demodulize
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def sdata_url_component(klass)
|
19
|
+
SData.sdata_name(klass).camelize(:lower)
|
20
|
+
end
|
21
|
+
|
22
|
+
def sdata_collection_url_component(klass)
|
23
|
+
SData.sdata_url_component(klass).pluralize
|
24
|
+
end
|
25
|
+
|
26
|
+
def config
|
27
|
+
unless @config
|
28
|
+
@config = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'config','sdata.yml'))
|
29
|
+
app_config_file = ENV['SDATA_CONFIG_FILE']
|
30
|
+
app_config_file ||= File.join(RAILS_ROOT, 'config','sdata.yml') if defined?(RAILS_ROOT)
|
31
|
+
@config = @config.deep_merge(YAML.load_file(app_config_file)) unless app_config_file.nil?
|
32
|
+
@config = @config.with_indifferent_access
|
33
|
+
@config[:contracts] ||= []
|
34
|
+
@config[:defaultContract] ||= @config[:contracts].first
|
35
|
+
@config[:defaultContract] ||= "crmErp"
|
36
|
+
@config[:contract_namespace] ||= "SData::Contracts"
|
37
|
+
end
|
38
|
+
@config
|
39
|
+
end
|
40
|
+
|
41
|
+
def config=(conf)
|
42
|
+
@config = conf.with_indifferent_access
|
43
|
+
end
|
44
|
+
|
45
|
+
def sdata_contract_name(klassname)
|
46
|
+
if (klassname =~ /#{@config[:contract_namespace]}::([^:]*)::/)
|
47
|
+
$~[1].camelize(:lower)
|
48
|
+
else
|
49
|
+
raise "Cannot determine sdata_contract_name for #{klassname}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def contract_namespaces
|
55
|
+
config[:contracts].map{|contract| "#{config[:contract_namespace]}::#{contract.camelize}"}
|
56
|
+
end
|
57
|
+
|
58
|
+
# this is pby expensive and will have to be optimized by using const_get directly
|
59
|
+
# RADAR: this assumes resource names are unique across contracts. To change that must refactor sd_uuid to either
|
60
|
+
# have a contract attr or pby better just store fully qualified name in sd_class
|
61
|
+
def resource_class(klassname)
|
62
|
+
contract_namespaces.each do |ns|
|
63
|
+
begin
|
64
|
+
return "#{ns}::#{klassname}".constantize
|
65
|
+
rescue;end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def store_path
|
70
|
+
#TODO: remove dataset=nil and modify calls accordingly. dataset should not be implied at this level
|
71
|
+
['sdata', config[:application], config[:defaultContract]].compact.join('/')
|
72
|
+
end
|
73
|
+
|
74
|
+
def base_url
|
75
|
+
config[:base_url].chomp('/')
|
76
|
+
end
|
77
|
+
|
78
|
+
def endpoint
|
79
|
+
[base_url, store_path].join('/')
|
80
|
+
end
|
81
|
+
|
82
|
+
def reset!
|
83
|
+
@config = nil
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
@@ -45,52 +45,44 @@ describe ControllerMixin, "#sdata_collection" do
|
|
45
45
|
:params => {}
|
46
46
|
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
context "when one of entries is erroneous" do
|
48
|
+
context "when one entry is erroneous" do
|
51
49
|
before :each do
|
52
50
|
@controller.sdata_options[:model].stub! :all => [EntryDiagnosisCustomer.new, Customer.new]
|
51
|
+
@controller.should_receive(:render) do |hash|
|
52
|
+
@feed = hash[:xml]
|
53
|
+
end
|
54
|
+
@controller.sdata_collection
|
53
55
|
end
|
54
56
|
|
55
57
|
it "should respond with both entries" do
|
56
|
-
@
|
57
|
-
hash[:xml].entries.size.should == 2
|
58
|
+
@feed.entries.size.should == 2
|
58
59
|
|
59
|
-
|
60
|
-
|
60
|
+
failed_entries = @feed.entries.reject{ |e| e.diagnosis.nil? }
|
61
|
+
successful_entries = @feed.entries.select { |e| e.diagnosis.nil? }
|
61
62
|
|
62
|
-
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
@controller.sdata_collection
|
63
|
+
failed_entries.size.should == 1
|
64
|
+
successful_entries.size.should == 1
|
67
65
|
end
|
68
66
|
|
69
67
|
it "should compose diagnosis entry correctly" do
|
70
|
-
@
|
71
|
-
failed_entry = hash[:xml].entries.reject{ |e| e.diagnosis.nil? }.first
|
68
|
+
failed_entry = @feed.entries.reject{ |e| e.diagnosis.nil? }.first
|
72
69
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
77
|
-
@controller.sdata_collection
|
70
|
+
failed_entry.id.should_not be_nil
|
71
|
+
failed_entry.content.should_not be_nil
|
72
|
+
failed_entry.sdata_payload.should be_nil
|
78
73
|
end
|
79
74
|
|
80
75
|
it "should compose sdata:diagnosis properties correctly" do
|
81
|
-
@
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
diagnosis.xpath('sdata:stackTrace/text()').to_s.include?('/diagnosis_spec.rb').should be_true
|
92
|
-
end
|
93
|
-
@controller.sdata_collection
|
76
|
+
failed_entry = @feed.entries.reject{ |e| e.diagnosis.nil? }.first
|
77
|
+
failed_entry = parse_xml(failed_entry.to_xml)
|
78
|
+
|
79
|
+
diagnosis = failed_entry.xpath('/xmlns:entry/sdata:diagnosis').first
|
80
|
+
diagnosis.children.size.should == 4
|
81
|
+
|
82
|
+
diagnosis.xpath('sdata:severity/text()').to_s.should == 'error'
|
83
|
+
diagnosis.xpath('sdata:sdataCode/text()').to_s.should == 'ApplicationDiagnosis'
|
84
|
+
diagnosis.xpath('sdata:message/text()').to_s.should == "Exception while trying to construct payload map"
|
85
|
+
diagnosis.xpath('sdata:stackTrace/text()').to_s.include?('/diagnosis_spec.rb').should be_true
|
94
86
|
end
|
95
87
|
|
96
88
|
it "should correctly compose regular entry as well" do
|
@@ -99,7 +91,6 @@ describe ControllerMixin, "#sdata_collection" do
|
|
99
91
|
successful_entry.id.should_not be_nil
|
100
92
|
successful_entry.content.should_not be_nil
|
101
93
|
successful_entry.sdata_payload.should_not be_nil
|
102
|
-
successful_entry.content.should_not be_nil
|
103
94
|
end
|
104
95
|
@controller.sdata_collection
|
105
96
|
end
|
@@ -108,108 +99,141 @@ describe ControllerMixin, "#sdata_collection" do
|
|
108
99
|
it "should construct multiple diagnosis elements within the same entry to describe multiple caught exceptions" do
|
109
100
|
pending #not implemented, difficulties with rAtom
|
110
101
|
end
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
hash[:xml].entries.each do |entry|
|
118
|
-
entry.id.should_not be_nil
|
119
|
-
entry.sdata_payload.should_not be_nil
|
120
|
-
entry.content.should_not be_nil
|
121
|
-
entry.diagnosis.should be_nil
|
102
|
+
|
103
|
+
context "when feed is erroneous" do
|
104
|
+
before :each do
|
105
|
+
@controller.sdata_options[:model].stub! :all => [FeedDiagnosisCustomer.new, Customer.new]
|
106
|
+
@controller.should_receive(:render) do |hash|
|
107
|
+
@feed = hash[:xml]
|
122
108
|
end
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
109
|
+
@controller.sdata_collection
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should still include healthy entry into response" do
|
113
|
+
@feed.entries.size.should == 1
|
114
|
+
|
115
|
+
failed_entry = @feed.entries.first
|
116
|
+
failed_entry.id.should_not be_nil
|
117
|
+
failed_entry.sdata_payload.should_not be_nil
|
118
|
+
failed_entry.content.should_not be_nil
|
119
|
+
failed_entry.diagnosis.should be_nil
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should include feed diagnosis into response" do
|
123
|
+
failed_entry = parse_xml(@feed.to_xml)
|
124
|
+
feed_diagnoses = failed_entry.xpath('/xmlns:feed/sdata:diagnosis').first
|
125
|
+
feed_diagnoses.children.size.should == 1
|
126
|
+
diagnosis = feed_diagnoses.children.first
|
127
|
+
|
128
|
+
diagnosis.xpath('sdata:severity/text()').to_s.should == 'error'
|
129
|
+
diagnosis.xpath('sdata:sdataCode/text()').to_s.should == 'ApplicationDiagnosis'
|
130
|
+
diagnosis.xpath('sdata:message/text()').to_s.should == "Exception while trying to get customer id"
|
131
|
+
diagnosis.xpath('sdata:stackTrace').to_s.include?('/diagnosis_spec.rb').should == true
|
132
|
+
end
|
131
133
|
end
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
134
|
+
|
135
|
+
context "when both feed and entry are erroneous" do
|
136
|
+
before :each do
|
137
|
+
@controller.sdata_options[:model].stub! :all => [FeedDiagnosisCustomer.new, FeedDiagnosisCustomer.new, EntryDiagnosisCustomer.new, Customer.new, Customer.new]
|
138
|
+
@controller.should_receive(:render) do |hash|
|
139
|
+
@feed = hash[:xml]
|
140
|
+
@failed_entries = @feed.entries.reject{ |e| e.diagnosis.nil? }
|
141
|
+
@successful_entries = @feed.entries.select { |e| e.diagnosis.nil? }
|
142
|
+
end
|
143
|
+
@controller.sdata_collection
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should contain all three entries" do
|
147
|
+
@feed.entries.size.should == 3
|
148
|
+
|
149
|
+
@failed_entries.size.should == 1
|
150
|
+
@successful_entries.size.should == 2
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should compose entry diagnosis properly" do
|
154
|
+
failed_entry = @failed_entries.first
|
155
|
+
|
156
|
+
failed_entry.id.should_not be_nil
|
157
|
+
failed_entry.content.should_not be_nil
|
158
|
+
failed_entry.sdata_payload.should be_nil
|
159
|
+
|
160
|
+
feed_xml = parse_xml(@feed.to_xml)
|
161
|
+
diagnosis = feed_xml.xpath('//xmlns:entry/sdata:diagnosis').first
|
162
|
+
diagnosis.xpath('sdata:severity/text()').to_s.should == 'error'
|
163
|
+
diagnosis.xpath('sdata:sdataCode/text()').to_s.should == 'ApplicationDiagnosis'
|
164
|
+
diagnosis.xpath('sdata:message/text()').to_s.should == "Exception while trying to construct payload map"
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should compose healthy entries properly" do
|
168
|
+
@successful_entries.each do |entry|
|
140
169
|
entry.id.should_not be_nil
|
141
170
|
entry.content.should_not be_nil
|
142
|
-
|
143
|
-
entry.sdata_payload.should_not be_nil
|
144
|
-
else
|
145
|
-
entry.sdata_payload.should be_nil
|
146
|
-
entry.diagnosis[0].children.detect{|x|x.name=='sdata:severity'}.children[0].to_s.should == 'error'
|
147
|
-
entry.diagnosis[0].children.detect{|x|x.name=='sdata:sdataCode'}.children[0].to_s.should == 'ApplicationDiagnosis'
|
148
|
-
entry.diagnosis[0].children.detect{|x|x.name=='sdata:message'}.children[0].to_s.should == "Exception while trying to construct payload map"
|
149
|
-
end
|
171
|
+
entry.sdata_payload.should_not be_nil
|
150
172
|
end
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should contain feed diagnoses" do
|
176
|
+
feed_xml = parse_xml(@feed.to_xml)
|
177
|
+
|
178
|
+
feed_diagnoses = feed_xml.xpath('/xmlns:feed/sdata:diagnosis')
|
179
|
+
feed_diagnoses.count.should == 2
|
180
|
+
feed_diagnoses.each do |diagnosis|
|
181
|
+
diagnosis.xpath('sdata:diagnosis/sdata:severity/text()').to_s.should == 'error'
|
182
|
+
diagnosis.xpath('sdata:diagnosis/sdata:sdataCode/text()').to_s.should == 'ApplicationDiagnosis'
|
183
|
+
diagnosis.xpath('sdata:diagnosis/sdata:message/text()').to_s.should == 'Exception while trying to get customer id'
|
157
184
|
end
|
158
185
|
end
|
159
|
-
@controller.sdata_collection
|
160
186
|
end
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
hash[:xml].root.children.size.should == 1
|
168
|
-
hash[:xml].root.children[0].name.should == "sdata:diagnosis"
|
169
|
-
hash[:xml].root.children[0].children.size.should == 4
|
170
|
-
attributes = hash[:xml].root.children[0].children.collect{|c|c.name}.sort
|
171
|
-
attributes.should == ["sdata:message", "sdata:sdataCode", "sdata:severity", "sdata:stackTrace"]
|
172
|
-
hash[:xml].root.children[0].children.each do |child|
|
173
|
-
child.children.size.should == 1
|
174
|
-
case child.name
|
175
|
-
when "sdata:message"
|
176
|
-
child.children[0].to_s.should == "exception rendering collection"
|
177
|
-
when "sdata:sdataCode"
|
178
|
-
child.children[0].to_s.should == "ApplicationDiagnosis"
|
179
|
-
when "sdata:severity"
|
180
|
-
child.children[0].to_s.should == "error"
|
181
|
-
end
|
187
|
+
|
188
|
+
context "when exception is raised at the action method leve" do
|
189
|
+
before :each do
|
190
|
+
@controller.stub!(:sdata_scope).and_raise(Exception.new('exception rendering collection'))
|
191
|
+
@controller.should_receive(:render) do |hash|
|
192
|
+
@feed = hash[:xml]
|
182
193
|
end
|
194
|
+
@controller.sdata_collection
|
183
195
|
end
|
184
|
-
@controller.sdata_collection
|
185
|
-
end
|
186
|
-
|
187
196
|
|
197
|
+
it "should construct standalone exception with full xml header" do
|
198
|
+
@feed.class.should == LibXML::XML::Document
|
199
|
+
feed_xml = parse_xml(@feed.to_s)
|
200
|
+
feed_xml.xpath('/sdata:diagnoses/sdata:diagnosis').count.should == 1
|
201
|
+
diagnosis = feed_xml.xpath('/sdata:diagnoses/sdata:diagnosis').first
|
202
|
+
diagnosis.xpath('./node()').map(&:name_with_ns).to_set.should == ["sdata:message", "sdata:sdataCode", "sdata:severity", "sdata:stackTrace"].to_set
|
203
|
+
|
204
|
+
diagnosis.xpath("sdata:message/text()").to_s.should == "exception rendering collection"
|
205
|
+
diagnosis.xpath("sdata:sdataCode/text()").to_s.should == "ApplicationDiagnosis"
|
206
|
+
diagnosis.xpath("sdata:severity/text()").to_s.should == "error"
|
207
|
+
end
|
208
|
+
end
|
188
209
|
end
|
189
210
|
|
190
211
|
describe "given a controller which acts as sdata" do
|
191
212
|
before :all do
|
192
213
|
|
193
214
|
class NewBase < ActionController::Base
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
215
|
+
extend ControllerMixin
|
216
|
+
extend SData::ApplicationControllerMixin
|
217
|
+
|
218
|
+
acts_as_sdata :model => Customer,
|
219
|
+
:feed => { :id => 'some-unique-id',
|
220
|
+
:author => 'Test Author',
|
221
|
+
:path => '/test_resource',
|
222
|
+
:title => 'List of Test Items',
|
223
|
+
:default_items_per_page => 10,
|
224
|
+
:maximum_items_per_page => 100}
|
225
|
+
|
226
|
+
sdata_rescue_support
|
227
|
+
|
228
|
+
rescue_from Exception, :with => :global_rescue
|
229
|
+
|
230
|
+
def global_rescue
|
231
|
+
if request.env['REQUEST_URI'].match(/^\/sdata/)
|
232
|
+
#this case must happen in ALL rails environments (dev, test, prod, etc.)
|
233
|
+
sdata_global_rescue(exception, request.env['REQUEST_URI'])
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
213
237
|
end
|
214
238
|
|
215
239
|
before :each do
|
@@ -13,4 +13,9 @@ module Nokogiri::ElementExtensions
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
Nokogiri::XML::Element.__send__ :include, Nokogiri::ElementExtensions
|
16
|
+
Nokogiri::XML::Element.__send__ :include, Nokogiri::ElementExtensions
|
17
|
+
|
18
|
+
def parse_xml(xml)
|
19
|
+
options = Nokogiri::XML::ParseOptions::DEFAULT_XML | Nokogiri::XML::ParseOptions::NOBLANKS
|
20
|
+
Nokogiri::XML(xml, nil, nil, options)
|
21
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 1.0.
|
8
|
+
- 1
|
9
|
+
version: 1.0.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Daniel Vartanov
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-06-
|
19
|
+
date: 2010-06-30 00:00:00 +06:00
|
20
20
|
default_executable:
|
21
21
|
dependencies: []
|
22
22
|
|
@@ -40,6 +40,7 @@ files:
|
|
40
40
|
- generators/acts_as_sdata/acts_as_sdata_generator.rb
|
41
41
|
- generators/acts_as_sdata/templates/migration.rb
|
42
42
|
- init.rb
|
43
|
+
- lib/s_data.rb
|
43
44
|
- lib/s_data/active_record_extensions/base.rb
|
44
45
|
- lib/s_data/active_record_extensions/mixin.rb
|
45
46
|
- lib/s_data/active_record_extensions/sdata_uuid_mixin.rb
|