jasper-client 0.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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 xforty technologies
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,116 @@
1
+ = jasper_client
2
+
3
+ A client API for accessing jasper reports repository service.
4
+
5
+ The list, get, and runReport actions are supported.
6
+
7
+ JasperClient provides a mechanism to construct service requests
8
+ using Xml::Builder. Client methods (list, get, run_report) yield
9
+ to a block which is passed a builder to the guts of the SOAP
10
+ request. This allows for an easy mechanism to create XML that
11
+ is added to a request.
12
+
13
+ An example list request document:
14
+
15
+ <?xml version="1.0" encoding="utf-8"?>
16
+ <soapenv:Envelope
17
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
18
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
19
+ xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
20
+ xmlns:axis="http://axis2.ws.jasperserver.jaspersoft.com">
21
+ <soapenv:Body>
22
+ <axis:list soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
23
+ <requestXmlString xsi:type="xsd:string">
24
+ <![CDATA[
25
+ <request operationName="list">
26
+ <argument name="LIST_RESOURCES"/>
27
+ <argument name="RESOURCE_TYPE">reportUnit</argument>
28
+ <argument name="START_FROM_DIRECTORY">/Reports/xforty</argument>
29
+ </request>
30
+ ]]>
31
+ </requestXmlString>
32
+ </axis:list>
33
+ </soapenv:Body>
34
+ </soapenv:Envelope>
35
+
36
+ When a call to list is made, a builder is passed to the block provided.
37
+ The above request could be executed using the list example below. In
38
+ a nuttshell, the caller needs to construct the body/ children of the
39
+ <request></request> element. Short work can be made of this by
40
+ telling builder what to construct.
41
+
42
+ == Example list request
43
+
44
+ A typical request might looks look like the following:
45
+
46
+ client = JasperClient::RepositoryService.new(wsdl, user, pass)
47
+
48
+ response = client.list do |request|
49
+ request.argument :name => "LIST_RESOURCES"
50
+ request.argument 'reportUnit', :name => "RESOURCE_TYPE"
51
+ request.argument '/Reports/xforty', :name => 'START_FROM_DIRECTORY'
52
+ end
53
+
54
+ response.success?
55
+
56
+ For more information see JasperClient::RepositoryService::Response::ListResponse.
57
+
58
+ == Example get request
59
+
60
+ response = client.get do |req|
61
+ req.resourceDescriptor :name => 'jrlogo', :wsType => 'img', :uriString => '/Reports/xforty/user_list', :isNew => 'false'
62
+ end
63
+
64
+ puts "Is successful: #{response.success?}"
65
+
66
+ For more information see JasperClient::RepositoryService::Response::GetResponse.
67
+
68
+ == Example runReport request
69
+
70
+ response = client.run_report do |req|
71
+ req.argument 'HTML', :name => 'RUN_OUTPUT_FORMAT'
72
+
73
+ req.resourceDescriptor :name => 'JRLogo',
74
+ :wsType => 'img',
75
+ :uriString => '/reports/xforty/user_list',
76
+ :isNew => 'false'
77
+ end
78
+
79
+ puts "Is successful: #{response.success?}"
80
+
81
+ puts "Parts? #{response.parts.count}"
82
+
83
+ response.parts.each do |part|
84
+ puts "Part: #{part.suggested_filename}"
85
+ end
86
+
87
+ For more information see JasperClient::RepositoryService::Response::RunReportResponse.
88
+
89
+ The class of the request depends on the type of request. It will be of
90
+ type ListResponse, GetResponse, or RunReportResponse.
91
+
92
+ Response types are specific to the request. Response types include
93
+ ListResponse, GetResponse, RunReportResponse, etc. Non-report
94
+ responses tend to be focused around the Resource class, which
95
+ represnets <resourceDescriptor> xml response elements.
96
+
97
+ == Reports
98
+
99
+ Reports are unique. A report response is a multipart related mime
100
+ document. The parts include the XML SOAP response, the report content
101
+ (which might be a PDF, a CSV, or an HTML file with accompanying images
102
+ in their individual parts).
103
+
104
+ == Future
105
+
106
+ In the future helper methods for helping to hone in on various
107
+ kinds of info from the server will be built. For example, you might
108
+ want ot just find or list particular resource types like reports,
109
+ queries, etc.
110
+
111
+ Additionaly, the ability to update resources could be provided, but
112
+ we didn't have any use for this right now so we didn't focus on this.
113
+
114
+ == Copyright
115
+
116
+ Copyright (c) 2010 xforty technologies. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,62 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "jasper-client"
8
+ gem.summary = %Q{Client for JasperServer}
9
+ gem.description = %Q{Client for JasperServer}
10
+ gem.email = "alibby@xforty.com"
11
+ gem.homepage = "http://github.com/alibby/jasper-client"
12
+ gem.authors = ["Andrew Libby"]
13
+ # gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
+ gem.files = FileList["[A-Z]*", "{bin,generators,lib,test}/**/*"]
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ require 'rake/testtask'
23
+ Rake::TestTask.new(:test) do |test|
24
+ test.libs << 'lib' << 'test'
25
+ test.pattern = 'test/**/test_*.rb'
26
+ test.verbose = true
27
+ end
28
+
29
+ begin
30
+ require 'rcov/rcovtask'
31
+ Rcov::RcovTask.new do |test|
32
+ test.libs << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+ rescue LoadError
37
+ task :rcov do
38
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
39
+ end
40
+ end
41
+
42
+ task :test => :check_dependencies
43
+
44
+ task :default => :test
45
+
46
+ require 'rake/rdoctask'
47
+ Rake::RDocTask.new do |rdoc|
48
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
+
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = "jasper-client #{version}"
52
+ rdoc.rdoc_files.include('README*')
53
+ rdoc.rdoc_files.include('lib/**/*.rb')
54
+ end
55
+
56
+ desc "Clean up everything (rcov, rdoc, pkg)"
57
+ task :clean => [:clobber_rcov, :clobber_rdoc] do
58
+ rm_rf 'pkg'
59
+ end
60
+
61
+
62
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,9 @@
1
+
2
+ require 'rubygems'
3
+ require 'savon'
4
+ require 'builder'
5
+ require 'nokogiri'
6
+
7
+ require 'jasper-client/string'
8
+ require 'jasper-client/http_multipart'
9
+ require 'jasper-client/jasper_client'
@@ -0,0 +1,132 @@
1
+ require 'net/http'
2
+
3
+ # A mixin to add basic RFC 2387 MIME Multipart/Related
4
+ # response support.
5
+ #
6
+ # A multipart http response has several sections which are
7
+ # intended to be treated as indpendent objects. The
8
+ # Multipart/Related response is used when all of the objects
9
+ # are related to one another. Typcially multipart is used
10
+ # to have alternative versions of the same content. This is
11
+ # not the case with multipart related.
12
+ #
13
+ # This mixen was written while using the Savon SOAP API, but
14
+ # it's intended to be mixed in to Net::HTTP and does not have
15
+ # any known dependencies on Savon.
16
+ #
17
+ # http://www.faqs.org/rfcs/rfc2387.html
18
+ module HTTPMultipart
19
+
20
+ # An RFC2387 multipart part.
21
+ #
22
+ # http://www.faqs.org/rfcs/rfc2387.html
23
+ class Part
24
+ # This makes headers for each part have the same interface
25
+ # as they do on Net::HTTPResponse.
26
+ include ::Net::HTTPHeader
27
+
28
+ attr_reader :body
29
+ # Initialize this response part.
30
+ def initialize(part_str)
31
+ h,b = part_str.split("\r\n\r\n", 2)
32
+ initialize_http_header Hash[ *h.split("\r\n").map { |hdr| hdr.split(/:\s*/, 2) }.flatten ]
33
+ @body = b
34
+ end
35
+
36
+ # Content type supertype (for text/html, this would be 'text')
37
+ def content_supertype
38
+ content_type.split('/')[0]
39
+ end
40
+
41
+ # Content type subtype. (for text/html, this woudl be 'html')
42
+ def content_subtype
43
+ content_type.split('/')[1]
44
+ end
45
+
46
+ # The suggested filename is the content_id witout the surrounding <> characters.
47
+ # the extension is derived from the mime-subtype.
48
+ def suggested_filename
49
+ "%s.%s" % [ content_id.first.gsub(/<|>/, ''), content_subtype ]
50
+ end
51
+
52
+ # get the content id. Each part has a content-id It's typical to use this as a basis
53
+ # for a fhile name.
54
+ def content_id
55
+ to_hash.fetch('content-id')
56
+ end
57
+
58
+ # Write the content from this part to a file having name.
59
+ def write_to_file(name = :internal)
60
+ name = suggested_filename if :internal == name
61
+
62
+ open(name, 'w') do |fh|
63
+ fh.write self.body
64
+ end
65
+ end
66
+ end
67
+
68
+ # Am I multipart?
69
+ def multipart?
70
+ %w{multipart/related}.include? content_type
71
+ end
72
+
73
+ # Fetch the multipart boundary.
74
+ def multipart_boundary
75
+ content_type_fields['boundary']
76
+ end
77
+
78
+ # The ID of the "start part" or initial part of the multipart related
79
+ # response.
80
+ def start
81
+ content_type_fields['start']
82
+ end
83
+
84
+ # Return the start part.
85
+ def start_part
86
+ parts.select { |p| p.content_id.first == start }.first.body
87
+ end
88
+
89
+ # return an array of parts.
90
+ def parts
91
+ pts = body.split("--%s" % [ multipart_boundary ])
92
+ pts.shift
93
+ pts.reject { |part| part == "--\r\n" }.map { |part| Part.new(part) }
94
+ end
95
+
96
+ # Iterate through each part calling the block.
97
+ # A Part is yielded to the block.
98
+ def each_part(&block)
99
+ if multipart?
100
+ parts.each do |part|
101
+ yield part
102
+ end
103
+ else
104
+ yield self
105
+ end
106
+ end
107
+
108
+ private
109
+
110
+ # Digest a content type header value into it's component parts.
111
+ # When we've got a multipart response, there are a few fields in the
112
+ # content-type header like the boundary, start content id, etc. For
113
+ # more info on this see RFC 2387 The MIME Multipart/Related content-type
114
+ def content_type_fields
115
+ headers_split = to_hash.fetch('content-type').first.split(/\s*;\s*/)
116
+ headers_split.shift # skip first element which is the mime type and subtype (text/xml or the like)
117
+ Hash[ *headers_split.map { |pair|
118
+
119
+ # The regex below is intended match things like charset="utf-8" and charset=utf-8.
120
+ matches = pair.match(/^(.*?)=(?:"(.*)"|(.*))$/)
121
+ matches[1,2] if matches
122
+ }.flatten ]
123
+ end
124
+ end
125
+
126
+ class Net::HTTPResponse
127
+ include HTTPMultipart
128
+ end
129
+
130
+ class Net::HTTPOK
131
+ include HTTPMultipart
132
+ end
@@ -0,0 +1,250 @@
1
+ # Contiainer for things belonging to jasper client.
2
+ module JasperClient
3
+ # a Jasper Server resource.
4
+ #
5
+ # A Jasperserver resource is a generic concept used to represent almost anything
6
+ # in a jasper server. It can be a file, an image, pre-run report output, a query,
7
+ # a report control, etc. We attempt to boil down the resource to something
8
+ # relatively consumable by application developers.
9
+ class Resource
10
+ attr_reader :name, :type, :uri_string, :label, :description, :creation_date, :properties, :resources
11
+
12
+ # Take a Nokogiri::XML object of a
13
+ def initialize(soap)
14
+ return unless soap.respond_to?(:search)
15
+
16
+ @name = soap['name']
17
+ @type = soap['wsType']
18
+ @uri_string = soap['uriString']
19
+ @label = soap.search('./label/node()').inner_text
20
+ @description = soap.search('./description/node()').inner_text
21
+ @createion_date = soap.search('./creation_date/node()').inner_text
22
+
23
+ initialize_properties soap.search('./resourceProperty')
24
+ initialize_resources soap.search('./resourceDescriptor')
25
+ end
26
+
27
+ private
28
+
29
+ # extract all <resourceProperty> tags from the resource and turn them
30
+ # into a hash in @properties.
31
+ def initialize_properties(properties)
32
+ @properties = Hash.new
33
+ properties.each do |prop|
34
+ @properties[prop['name']] = prop.inner_text.strip
35
+ end
36
+ end
37
+
38
+ # extract all <resourceDescriptor> tags and turn them into Resource objects.
39
+ def initialize_resources(resources)
40
+ @resources = []
41
+ resources.each do |res|
42
+ @resources << Resources.new(res)
43
+ end
44
+ end
45
+ end
46
+
47
+ # A crack at a Jasper Server client for the repository service.
48
+ #
49
+ # This client sits on top of several common Ruby APIs including
50
+ # the Savon SOAP API, XmlBuilder, and nokogiri.
51
+ class RepositoryService < ::Savon::Client
52
+
53
+ # Set this to true if you'd like to have Savon log to stderr
54
+ ::Savon::Request.log = false;
55
+
56
+ # Request XML is built using the Request.
57
+ #
58
+ # A request looks like:
59
+ #
60
+ # <?xml version="1.0" encoding="utf-8"?>
61
+ # <soapenv:Envelope
62
+ # xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
63
+ # xmlns:xsd="http://www.w3.org/2001/XMLSchema"
64
+ # xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
65
+ # xmlns:axis="http://axis2.ws.jasperserver.jaspersoft.com">
66
+ # <soapenv:Body>
67
+ # <axis:list soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
68
+ # <requestXmlString xsi:type="xsd:string">
69
+ # <![CDATA[
70
+ # <request operationName="list">
71
+ # <argument name="LIST_RESOURCES"/>
72
+ # <argument name="RESOURCE_TYPE">reportUnit</argument>
73
+ # <argument name="START_FROM_DIRECTORY">/Reports/xforty</argument>
74
+ # </request>
75
+ # ]]>
76
+ # </requestXmlString>
77
+ # </axis:list>
78
+ # </soapenv:Body>
79
+ # </soapenv:Envelope>
80
+ #
81
+ # The soap envelope, body, and action (in this case axis:list) elements
82
+ # are automatically constructed by Savon. The requestXmlString element and
83
+ # sub elements are created by the build() method. This method yields a builder
84
+ # that is expected to create the contents of the request element (the arugment
85
+ # tags in this case).
86
+ class Request
87
+ attr_reader :name
88
+
89
+ # Create a new Request. The name passed is the
90
+ # request name (eg list, get, runReport).
91
+ def initialize(name)
92
+ @name = name
93
+ end
94
+
95
+ # Takes a block which is yielded with an XML builder
96
+ # that represents the internal XML inside the <request>
97
+ # tags in the request.
98
+ def build(&block)
99
+ inner_xml = Builder::XmlMarkup.new :indent => 2
100
+ inner_xml.request 'operationName' => soap_method do |request|
101
+ yield request
102
+ end
103
+
104
+ body = Builder::XmlMarkup.new :indent => 2
105
+ body.requestXmlString { |request_string| request_string.cdata! inner_xml.target! }
106
+ end
107
+
108
+ # Returns the soap method name for this request.
109
+ def soap_method
110
+ self.name.to_s.underscore
111
+ end
112
+ end
113
+
114
+ # A response subclass exists for each type of response. There is a response type for
115
+ # each type of request (list, get, runReport). Code common to all response types is
116
+ # put into the Response class, otherwise responses are named CamelizedRequestNameResponse.
117
+ # So for example ListResponse, GetResponse, RunReportResponse.
118
+ class Response
119
+ attr_reader :xml_doc, :resources
120
+
121
+ # "0" if the request was successfully processed by the server.
122
+ def return_code
123
+ xml_doc.search('//returnCode').inner_text
124
+ end
125
+
126
+ # return true if the response is successful.
127
+ def success?
128
+ "0" == return_code
129
+ end
130
+
131
+ # return "OK" on success, since successful responses don't seem to have
132
+ # messages. When the response is not successful, the message is pulled
133
+ # from the response xml.
134
+ def message
135
+ if success?
136
+ "OK"
137
+ else
138
+ xml_doc.search('//returnMessage/node()').inner_text
139
+ end
140
+ end
141
+
142
+ # Search the response using xpath. When this Responses xml_doc
143
+ # does not have a search method, a string with inner_text and inner_html
144
+ # methods are added. The reson for this is so unwitting callers
145
+ # won't need to have the extra logic to make sure that that this response
146
+ # has a valid xml_doc.
147
+ def search(path)
148
+ return xml_doc.search(path) if xml_doc.respond_to?(:search)
149
+
150
+ # return something that acts like a dom element (nokogiri)
151
+ x = ""
152
+ class << x
153
+ def inner_text; ""; end
154
+ alias inner_html inner_text
155
+ end
156
+ x
157
+ end
158
+
159
+ # Extract resourceDescriptors from the response and drop them into @resources.
160
+ def collect_resources
161
+ @resources = @xml_doc.search('./resourceDescriptor').map { |r| Resource.new(r) }
162
+ end
163
+
164
+ # Response from a list request.
165
+ class ListResponse < Response
166
+ # Initialize the list response from a Savon response. The listReturn element is
167
+ # pulled from the response, and each resourceDescriptor child of that element is
168
+ # collected into a list as each item in the list.
169
+ def initialize(savon_response)
170
+ soap_doc = Nokogiri::XML savon_response.to_xml
171
+ @xml_doc = Nokogiri::XML soap_doc.search('//listReturn/node()').inner_text
172
+ collect_resources
173
+ end
174
+
175
+ # Get a list of items from the list response. Each of the items in the list
176
+ # returned is a JasperClient::Resource.
177
+ def items
178
+ resources
179
+ end
180
+ end
181
+
182
+ # Response from a get request.
183
+ class GetResponse < Response
184
+ # Initialize the list response from a Savon response. The getReturn element is
185
+ # pulled from the response, and each resourceDescriptor is processed into info about
186
+ # the resource involved.
187
+ def initialize(savon_response)
188
+ savon_response.tap do |soap|
189
+ soap_doc = Nokogiri::XML soap.to_xml
190
+ @xml_doc = Nokogiri::XML soap_doc.search('//getReturn/node()').inner_text
191
+ collect_resources
192
+ end
193
+ end
194
+ end
195
+
196
+ # Response from a runReport request.
197
+ class RunReportResponse < Response
198
+ attr_reader :http
199
+ def initialize(savon_response)
200
+ savon_response.tap do |soap|
201
+ @http = soap.http
202
+ xml = http.multipart? ? http.start_part : soap.http.body # soap.to_hash.fetch(:run_report_response).fetch(:run_report_return)
203
+ soap_doc = Nokogiri::XML xml
204
+ @xml_doc = Nokogiri::XML soap_doc.search('//runReportReturn/node()').inner_text
205
+ end
206
+ end
207
+
208
+ # return the multipart related parts from the http response.
209
+ # When the response is not multipart, an empty list is returned.
210
+ def parts
211
+ http.multipart? ? http.parts : []
212
+ end
213
+ end
214
+ end
215
+
216
+ attr_reader :wsdl_url, :username, :password
217
+
218
+ # Initialize the JapserClient with a URL (points to the
219
+ # repository service), a username, and a password.
220
+ def initialize(wsdl_url, username, password)
221
+ @wsdl_url = wsdl_url.to_s
222
+ @username = username.to_s
223
+ @password = password.to_s
224
+
225
+ super @wsdl_url
226
+ request.basic_auth @username, @password
227
+ end
228
+
229
+ # return true if name indicates a supported request.
230
+ def supported_request?(name)
231
+ [:get, :list, :run_report].include? name.to_sym
232
+ end
233
+
234
+ # Essentially a proxy to method_missing for Savon. If the method call is
235
+ # to a known request type, build XML with a request object and then
236
+ # execute the Savon request.
237
+ def method_missing(name, *params, &block)
238
+ if supported_request?(name)
239
+ req = Request.new(name)
240
+ request_xml = req.build(&block)
241
+
242
+ savon_response = super(name) { |soap| soap.body = request_xml.to_s }
243
+ response_class = Response.const_get "%sResponse" % [ name.to_s.humpify.to_sym ]
244
+ response_class.new savon_response
245
+ else
246
+ super(name, params)
247
+ end
248
+ end
249
+ end
250
+ end
@@ -0,0 +1,19 @@
1
+ # Logic for both of these were lifted from the rails
2
+ # source tree. We don't call active support directly because
3
+ # we didn't want to depend on those gems merely for these
4
+ # two bits of functionality.
5
+ class String
6
+ def underscore
7
+ word = self.to_s.dup
8
+ word.gsub!(/::/, '/')
9
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
10
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
11
+ word.tr!("-", "_")
12
+ word.downcase!
13
+ word
14
+ end
15
+
16
+ def humpify
17
+ self.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
18
+ end
19
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'jasper-client'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,98 @@
1
+ require 'helper'
2
+
3
+ class TestJasperClient < Test::Unit::TestCase
4
+ def setup_connection
5
+ wsdl = 'http://127.0.0.1:8080/jasperserver/services/repository?wsdl'
6
+ user = 'jasperadmin'
7
+ pass = user
8
+ JasperClient::RepositoryService.new(wsdl, user, pass)
9
+ end
10
+
11
+ def bad_connection
12
+ wsdl = 'http://127.0.0.1:8081/jasperserver/services/repository?wsdl'
13
+ user = 'jasperadmin'
14
+ pass = user
15
+ JasperClient::RepositoryService.new(wsdl, user, pass)
16
+ end
17
+
18
+ should "respond to list requests" do
19
+ client = setup_connection
20
+ response = client.list do |request|
21
+ request.argument :name => "LIST_RESOURCES"
22
+ request.argument 'reportUnit', :name => "RESOURCE_TYPE"
23
+ request.argument '/Reports/xforty', :name => 'START_FROM_DIRECTORY'
24
+ end
25
+
26
+ assert(response.return_code == "0")
27
+ end
28
+
29
+ should "respond to get requests" do
30
+ client = setup_connection
31
+ response = client.get do |req|
32
+ req.resourceDescriptor :name => 'jrlogo', :wsType => 'img', :uriString => '/Reports/xforty/user_list', :isNew => 'false'
33
+ end
34
+ assert(response.return_code == "0")
35
+ end
36
+
37
+ should "respond to runReport requests" do
38
+ client = setup_connection
39
+ response = client.run_report do |req|
40
+ req.argument 'HTML', :name => 'RUN_OUTPUT_FORMAT'
41
+
42
+ req.resourceDescriptor :name => 'JRLogo',
43
+ :wsType => 'img',
44
+ :uriString => '/reports/xforty/user_list',
45
+ :isNew => 'false'
46
+ end
47
+ assert(response.return_code == "0")
48
+ assert(response.parts.count > 0)
49
+ end
50
+
51
+ should "should detect bad connection" do
52
+ assert_raise(Errno::ECONNREFUSED) do
53
+ client = bad_connection
54
+ response = client.run_report do |req|
55
+ req.argument 'HTML', :name => 'RUN_OUTPUT_FORMAT'
56
+
57
+ req.resourceDescriptor :name => 'JRLogo',
58
+ :wsType => 'img',
59
+ :uriString => '/reports/xforty/user_list',
60
+ :isNew => 'false'
61
+ end
62
+ end
63
+ end
64
+
65
+ should "produce string message when report path is bad" do
66
+ client = setup_connection
67
+ response = client.run_report do |req|
68
+ req.resourceDescriptor :name => 'jrlogo', :wsType => 'img', :uriString => '/Reports/xfortys/user_list', :isNew => 'false'
69
+ end
70
+
71
+ assert(response.message.class == String)
72
+ end
73
+
74
+ should "return valid message on bad report path" do
75
+ client = setup_connection
76
+ response = client.run_report do |req|
77
+ req.resourceDescriptor :name => 'jrlogo', :wsType => 'img', :uriString => '/Reports/xfortys/user_list', :isNew => 'false'
78
+ end
79
+
80
+ assert(response.message.length > 0)
81
+ end
82
+
83
+ should "fetch on a bad resource path should be unsuccessful" do
84
+ client = setup_connection
85
+ response = client.run_report do |req|
86
+ req.resourceDescriptor :name => 'jrlogo', :wsType => 'img', :uriString => '/Reports/xfortys/user_list', :isNew => 'false'
87
+ end
88
+ assert(response.success? == false)
89
+ end
90
+
91
+ should "fetch on a bad resource path should have non 'OK' message" do
92
+ client = setup_connection
93
+ response = client.run_report do |req|
94
+ req.resourceDescriptor :name => 'jrlogo', :wsType => 'img', :uriString => '/Reports/xfortys/user_list', :isNew => 'false'
95
+ end
96
+ assert(response.message != 'OK')
97
+ end
98
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jasper-client
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Andrew Libby
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-10-01 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Client for JasperServer
22
+ email: alibby@xforty.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - LICENSE
29
+ - README.rdoc
30
+ files:
31
+ - LICENSE
32
+ - README.rdoc
33
+ - Rakefile
34
+ - VERSION
35
+ - lib/jasper-client.rb
36
+ - lib/jasper-client/http_multipart.rb
37
+ - lib/jasper-client/jasper_client.rb
38
+ - lib/jasper-client/string.rb
39
+ - test/helper.rb
40
+ - test/test_jasper_client.rb
41
+ has_rdoc: true
42
+ homepage: http://github.com/alibby/jasper-client
43
+ licenses: []
44
+
45
+ post_install_message:
46
+ rdoc_options:
47
+ - --charset=UTF-8
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.3.6
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: Client for JasperServer
71
+ test_files:
72
+ - test/helper.rb
73
+ - test/test_jasper_client.rb