acts_as_sdata 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|