spdocgen 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA512:
3
+ metadata.gz: c2f64220f543247a047013d39dc6cebee4390b8fcc531b67cd5e8a86073298a4f401b0c7fd6abe97894a736f9449219c04460dc631a99a6f492942c8d5c4acfa
4
+ data.tar.gz: ee878ee4a4a915378cb266ed2b1f0cd0cbd36a4086ced6178a020dc199288a198966da9a96c0285178fb1d5d328e7e084e57dc0211ef0e3328bba69039fdccbf
5
+ SHA1:
6
+ metadata.gz: f084863ea5fc6784ac2bf2a57e800d6cddcf4a1b
7
+ data.tar.gz: 72ba51d7f0976b343ed747a95abcf96751fdf8d7
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in spdocgen.gemspec
4
+ gemspec
5
+
6
+ gem 'rspec'
7
+ gem 'rack'
8
+ gem 'thin'
9
+ gem 'uuid'
10
+
11
+ gem 'net-ssh'
12
+ gem 'net-scp'
13
+ gem 'highline'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Software Projects
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # SP Docgen for Ruby
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'spdocgen'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install spdocgen
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ require "bundler/gem_tasks"
2
+ require 'net/ssh'
3
+ require 'net/ssh/authentication/methods/password'
4
+ require 'net/scp'
5
+ require 'highline/import'
6
+
7
+ task :push => :build do
8
+ def upload(ssh)
9
+ filename = "spdocgen-#{SPDocgen::VERSION}.gem"
10
+ print "Uploading #{filename}..."
11
+ u = ssh.scp.upload("pkg/#{filename}", "/var/www/rubygems/gems/#{filename}") do
12
+ print '.'
13
+ end
14
+ u.wait
15
+ puts
16
+ ssh.exec! '/usr/local/rvm/bin/gem generate_index --directory=/var/www/rubygems'
17
+ end
18
+
19
+ opts = Net::SSH.configuration_for('sp43.sp.local')
20
+ begin
21
+ Net::SSH.start('sp43.sp.local', 'rubygems', :auth_methods => %w[publickey]) {|o| upload(o)}
22
+ rescue
23
+ password = ask("rubygems@sp43.sp.local's password: ") { |q| q.echo = false }
24
+ Net::SSH.start('sp43.sp.local', 'rubygems', :password => password) {|o| upload(o)}
25
+ end
26
+ end
data/lib/spdocgen.rb ADDED
@@ -0,0 +1,15 @@
1
+ require "spdocgen/version"
2
+
3
+ module SPDocgen
4
+ autoload :Configuration, 'spdocgen/configuration'
5
+ autoload :Document, 'spdocgen/document'
6
+ autoload :DocumentSet, 'spdocgen/document_set'
7
+ autoload :Protocol, 'spdocgen/protocol'
8
+
9
+ autoload :DownloadRequest, 'spdocgen/download_request'
10
+ autoload :DownloadResponse, 'spdocgen/download_response'
11
+ autoload :RenderRequest, 'spdocgen/render_request'
12
+ autoload :RenderResponse, 'spdocgen/render_response'
13
+ autoload :StatusRequest, 'spdocgen/status_request'
14
+ autoload :StatusResponse, 'spdocgen/status_response'
15
+ end
@@ -0,0 +1,31 @@
1
+ module SPDocgen
2
+ class Configuration
3
+ class <<self
4
+ attr_accessor :configuration_file
5
+
6
+ def current
7
+ env = nil
8
+ env = Rails.env if defined? Rails
9
+ env ||= ENV['RAILS_ENV']
10
+ env ||= ENV['RACK_ENV']
11
+ raise 'Unable to determine environment' if env.nil?
12
+
13
+ c = read
14
+ raise "Environment not defined in SPDocgen configuration: #{env}" if c[env].nil?
15
+ (c['global'] || {}).merge(c[env])
16
+ end
17
+
18
+ private
19
+
20
+ def read
21
+ if defined? Rails
22
+ self.configuration_file ||= File.join(Rails.root, 'config', 'spdocgen.yml')
23
+ elsif self.configuration_file.nil?
24
+ raise 'Unable to determine a default location for SPDocgen configuration'
25
+ end
26
+
27
+ @configuration ||= YAML.load_file(self.configuration_file)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ module SPDocgen
2
+ class Document
3
+ attr_reader :xmlns, :data_sources
4
+ def initialize
5
+ @xmlns = {}
6
+ @data_sources = []
7
+ end
8
+
9
+ def build(xml)
10
+ raise "#{self.class.name} does not define a 'build' method"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ module SPDocgen
2
+ class DocumentSet
3
+ attr_reader :xmlns, :data_sources
4
+ attr_accessor :documents
5
+
6
+ def initialize
7
+ @xmlns = {}
8
+ @data_sources = []
9
+ end
10
+
11
+ def all_data_sources
12
+ mapped = (data_sources + documents.collect(&:data_sources).flatten).inject({}) do |map, ds|
13
+ map[ds.id] = ds
14
+ map
15
+ end
16
+ mapped.values.sort_by(&:id)
17
+ end
18
+
19
+ def all_xmlns
20
+ documents.inject(@xmlns){|map, doc| map.merge(doc.xmlns)}
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ require 'uri'
2
+
3
+ module SPDocgen
4
+ class DownloadRequest
5
+ attr_accessor :uri
6
+
7
+ def initialize(uri)
8
+ self.uri = uri
9
+ end
10
+
11
+ def download
12
+ SPDocgen::Protocol.instance.download(URI.parse(self.uri))
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ module SPDocgen
2
+ class DownloadResponse
3
+ attr_accessor :body, :content_type, :content_encoding, :content_disposition
4
+
5
+ def initialize(body, content_type, content_encoding, content_disposition)
6
+ self.body = body
7
+ self.content_type = content_type
8
+ self.content_encoding = content_encoding
9
+ self.content_disposition = content_disposition
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,80 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+
4
+ module SPDocgen
5
+ class Protocol
6
+ def self.instance
7
+ @instance ||= self.new Configuration.current
8
+ end
9
+
10
+ def initialize(config)
11
+ @base_url = config['base_url']
12
+ @render_path = config['render_path']
13
+ @username = config['username']
14
+ @password = config['password']
15
+
16
+ url = URI.parse @base_url
17
+ @http = Net::HTTP.new url.host, url.port
18
+ @http.use_ssl = (url.scheme =~ /https/i)
19
+
20
+ @downloaders = {}
21
+ end
22
+
23
+ def download(parsed_uri)
24
+ with_downloader_for(parsed_uri) do |http|
25
+ req = Net::HTTP::Get.new parsed_uri.request_uri
26
+ req['Accept'] = '*/*'
27
+ req.basic_auth @username, @password
28
+
29
+ response = http.request(req)
30
+
31
+ raise "Unable to download: #{parsed_uri.to_s} .. Response was #{response.code} #{response.message} : #{response.body ? response.body : ''} - request is #{req.to_s}" unless response.is_a? Net::HTTPOK
32
+
33
+ SPDocgen::DownloadResponse.new response.body, response.content_type, response['content-encoding'], response['content-disposition']
34
+ end
35
+ end
36
+
37
+ def submit(xml)
38
+ request = Net::HTTP::Post.new render_url
39
+ request.body = xml
40
+ request['Content-Type'] = 'application/xml'
41
+
42
+ SPDocgen::RenderResponse.new do_request(request).body
43
+ end
44
+
45
+ def poll(uri)
46
+ request = Net::HTTP::Get.new uri
47
+ SPDocgen::StatusResponse.new do_request(request).body
48
+ end
49
+
50
+ private
51
+
52
+ def http
53
+ @http.start unless @http.started?
54
+ @http
55
+ end
56
+
57
+ def render_url
58
+ URI.join(@base_url, @render_path).to_s
59
+ end
60
+
61
+ def with_downloader_for(u, &block)
62
+ host = u.class.new(u.scheme, nil, u.host, u.port, nil, '', nil, nil, nil, false).to_s
63
+
64
+ downloader = Net::HTTP.new(u.host, u.port)
65
+ downloader.use_ssl = (u.scheme =~ /https/i)
66
+
67
+ downloader.start(&block)
68
+ end
69
+
70
+ def do_request(request)
71
+ request['Accept'] = 'application/xml'
72
+ request.basic_auth @username, @password
73
+
74
+ response = http.request request
75
+ raise 'Response did not contain XML' unless response.code == '200' and response['content-type'] =~ /xml/i
76
+
77
+ response
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,76 @@
1
+ require 'nokogiri'
2
+
3
+ module SPDocgen
4
+ class RenderRequest
5
+ attr_accessor :metadata, :xml
6
+
7
+ def initialize(document_set)
8
+ raise "Document set should inherit from #{DocumentSet.name}" unless document_set.is_a? DocumentSet
9
+ raise "Documents should inherit from #{Document.name}" unless document_set.documents.all?{|doc| doc.is_a? Document}
10
+
11
+ @document_set = document_set
12
+ @xmlns = {
13
+ 'xmlns:dgr' => 'http://www.sp.com.au/docgen/schemas/wsh',
14
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
15
+ }.merge(document_set.all_xmlns)
16
+
17
+ raise 'XML namespace definitions should start with xmlns:' unless @xmlns.keys.all?{|k| k.start_with? 'xmlns:'}
18
+
19
+ @metadata = {}
20
+ if document_set.respond_to? :metadata
21
+ @metadata = document_set.metadata
22
+ end
23
+ end
24
+
25
+ def build
26
+ raise 'Already built' if @xml
27
+ raise 'No data sources' if @document_set.nil? or @document_set.documents.nil? or @document_set.documents.empty?
28
+
29
+ builder = Nokogiri::XML::Builder.new :encoding => 'utf-8' do |xml|
30
+ # Clients that treat this as a real builder sometimes need to call 'tag!'
31
+ # That's ok.
32
+ def xml.tag!(*args, &bl)
33
+ # Handle reserved names correctly
34
+ name = args.shift + '_'
35
+ send name, *args, &bl
36
+ end
37
+
38
+ xml.DocGenRequest @xmlns do
39
+ # See http://stackoverflow.com/questions/1829425/creating-an-xml-document-with-a-namespaced-root-element-with-nokogiri-builder
40
+ xml.parent.namespace = xml.parent.namespace_definitions.find{|ns| ns.prefix == 'dgr'}
41
+ dgr = xml['dgr']
42
+ dgr.MetaData do
43
+ self.metadata.each do |k,v|
44
+ dgr.MetaDataEntry do
45
+ dgr.Key k
46
+ dgr.Value v
47
+ end
48
+ end
49
+ end
50
+
51
+ dgr.SharedXmlDataSources do
52
+ @document_set.all_data_sources.each do |data_source|
53
+ dgr.SharedXmlDataSource 'sharedXmlDataSourceId' => data_source.id do
54
+ data_source.build(xml)
55
+ end
56
+ end
57
+ end
58
+
59
+ dgr.DocumentRequests do
60
+ @document_set.documents.each do |document|
61
+ document.build(xml)
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ @xml = builder.to_xml
68
+ end
69
+
70
+ def submit
71
+ raise 'Request needs to be built first' unless @xml
72
+
73
+ SPDocgen::Protocol.instance.submit @xml
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,17 @@
1
+ require 'nokogiri'
2
+
3
+ module SPDocgen
4
+ class RenderResponse
5
+ attr_reader :uuid, :uri
6
+
7
+ def initialize(xml)
8
+ document = Nokogiri::XML.parse(xml, nil, 'UTF-8')
9
+ raise 'Not a render response' unless document.root.name == 'RenderResponse'
10
+
11
+ @uuid = document.xpath('/RenderResponse/Uuid').text
12
+ @uri = document.xpath('/RenderResponse/StatusUri').text
13
+
14
+ raise "Invalid render response #{xml}" unless !@uuid.blank? && !@uri.blank?
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ module SPDocgen
2
+ class StatusRequest
3
+ def initialize(uri)
4
+ @uri = uri
5
+ end
6
+
7
+ def poll
8
+ SPDocgen::Protocol.instance.poll @uri
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,74 @@
1
+ require 'nokogiri'
2
+
3
+ module SPDocgen
4
+ class StatusResponse
5
+ #<StatusResponse>
6
+ #<DocGenRequestStatuses>
7
+ #<DocGenRequestStatus>
8
+ #<Uuid>9f576898-8d74-432e-80b8-dacbaf8d7bf6</Uuid>
9
+ #<State>Failed</State>
10
+ #<DocumentRequests>
11
+ #<DocumentRequest ServerId='5614' ClientId='b3b98dc0-449c-012f-238b-0026b92085d1' State='Timeout'>
12
+ #<Documents></Documents>
13
+ #</DocumentRequest>
14
+ #</DocumentRequests>
15
+ #</DocGenRequestStatus>
16
+ #</DocGenRequestStatuses>
17
+ #</StatusResponse>
18
+ def initialize(xml)
19
+ document = Nokogiri::XML.parse(xml, nil, 'UTF-8')
20
+ raise 'Not a render response' unless document.root.name == 'StatusResponse'
21
+
22
+ document.xpath('/StatusResponse/DocGenRequestStatuses/DocGenRequestStatus').each do |node|
23
+ uuid = node.xpath('Uuid').text
24
+ state = node.xpath('State').text
25
+ requests = node.xpath('DocumentRequests/DocumentRequest').collect do |req|
26
+ documents = req.xpath('Documents/Document').collect do |doc|
27
+ name = doc.xpath('Name')
28
+ uri = doc.xpath('Uri')
29
+ metadata = doc.xpath('MetaDataEntries/MetaDataEntry').inject({}) do |map,md|
30
+ map[md.xpath('Key').text] = md.xpath('Value').text
31
+ map
32
+ end
33
+
34
+ {
35
+ :reference => doc['Reference'],
36
+ :num_pages => doc['NumPages'].to_i,
37
+ :name => name.text,
38
+ :uri => uri.text,
39
+ :metadata => metadata
40
+ }
41
+ end
42
+
43
+ {
44
+ :server_id => req['ServerId'],
45
+ :request_guid => req['ClientId'],
46
+ :state => req['State'],
47
+ :documents => documents
48
+ }
49
+ end
50
+
51
+ record_status uuid, state, requests
52
+ end
53
+ end
54
+
55
+ def uuids
56
+ @uuids ||= []
57
+ end
58
+
59
+ def status(uuid)
60
+ @status ||= {}
61
+ @status[uuid] ||= {}
62
+ end
63
+
64
+ private
65
+ def record_status(uuid, state, requests)
66
+ self.uuids << uuid
67
+ self.status(uuid).merge!(
68
+ :uuid => uuid,
69
+ :state => state,
70
+ :requests => requests
71
+ )
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,4 @@
1
+ module SPDocgen
2
+ # Please use Semantic Versioning - http://semver.org/
3
+ VERSION = "1.1.2"
4
+ end
data/spdocgen.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'spdocgen/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "spdocgen"
8
+ gem.version = SPDocgen::VERSION
9
+ gem.authors = ["Shaun Mangelsdorf"]
10
+ gem.email = ["smangelsdorf@sp.com.au"]
11
+ gem.description = %q{Ruby client library for rendering and downloading documents from SP Docgen}
12
+ gem.summary = %q{SP Docgen client library}
13
+ gem.homepage = "http://sp.docgen.net.au"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_runtime_dependency 'nokogiri'
21
+ end
data/spec/config.yml ADDED
@@ -0,0 +1,4 @@
1
+ test:
2
+ username: test
3
+ password: test
4
+ render_path: /render
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe SPDocgen::DownloadRequest do
4
+ subject do
5
+ SPDocgen::DownloadRequest.new server.url('/download/file.txt')
6
+ end
7
+
8
+ it 'downloads the file' do
9
+ server.response = [200, {'content-type' => 'text/plain'}, "test file"]
10
+
11
+ response = subject.download
12
+ response.should be_a SPDocgen::DownloadResponse
13
+ response.body.should == "test file"
14
+ response.content_type.should == 'text/plain'
15
+ response.content_encoding.should be_nil
16
+ end
17
+
18
+ it 'includes the content encoding' do
19
+ server.response = [200, {'content-type' => 'text/plain', 'content-encoding' => 'gzip'}, "test file"]
20
+
21
+ response = subject.download
22
+ response.should be_a SPDocgen::DownloadResponse
23
+ response.body.should == "test file"
24
+ response.content_type.should == 'text/plain'
25
+ response.content_encoding.should == 'gzip'
26
+ end
27
+
28
+ it 'includes the content disposition' do
29
+ server.response = [200, {'content-type' => 'text/plain', 'content-disposition' => 'attachment; filename=test.txt'}, 'test file']
30
+ response = subject.download
31
+ response.should be_a SPDocgen::DownloadResponse
32
+ response.content_disposition.should == 'attachment; filename=test.txt'
33
+ end
34
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ require 'uuid'
4
+
5
+ describe SPDocgen::RenderRequest do
6
+ class TestDocumentSet < SPDocgen::DocumentSet
7
+ end
8
+
9
+ class BadTestDocument < SPDocgen::Document
10
+ end
11
+ class TestDocument < SPDocgen::Document
12
+ def build(xml)
13
+ xml.DocumentRequest 'test-xml'
14
+ end
15
+ end
16
+ class NamespaceDocument < SPDocgen::Document
17
+ def initialize
18
+ super
19
+ xmlns['xmlns:test'] = 'http://example.org/test'
20
+ end
21
+
22
+ def build(xml)
23
+ xml.DocumentRequest do
24
+ xml['test'].TestXml
25
+ end
26
+ end
27
+ end
28
+
29
+ before :each do
30
+ @uuid = UUID.generate
31
+ end
32
+
33
+ subject do
34
+ end
35
+
36
+ it 'should reject document sets of the wrong type' do
37
+ lambda {
38
+ set = Object.new
39
+ SPDocgen::RenderRequest.new set
40
+ }.should raise_error(RuntimeError, /should inherit from/)
41
+ end
42
+
43
+ it 'should reject documents of the wrong type' do
44
+ lambda {
45
+ set = TestDocumentSet.new
46
+ set.documents = [Object.new]
47
+ SPDocgen::RenderRequest.new set
48
+ }.should raise_error(RuntimeError, /should inherit from/)
49
+ end
50
+
51
+ it 'should not build a bad implementation' do
52
+ set = TestDocumentSet.new
53
+ set.documents = [BadTestDocument.new]
54
+ req = SPDocgen::RenderRequest.new set
55
+ lambda {
56
+ req.build
57
+ }.should raise_error(RuntimeError, /does not define/)
58
+ end
59
+
60
+ it 'should build' do
61
+ set = TestDocumentSet.new
62
+ set.documents = [TestDocument.new]
63
+ req = SPDocgen::RenderRequest.new set
64
+ req.build
65
+ req.xml.should match /test-xml/
66
+ end
67
+
68
+ it 'should build with namespaces' do
69
+ set = TestDocumentSet.new
70
+ set.documents = [NamespaceDocument.new]
71
+ req = SPDocgen::RenderRequest.new set
72
+ req.build
73
+ req.xml.should match /<test:TestXml\/>/
74
+ end
75
+
76
+ it 'should submit' do
77
+ server.response = [200, {'content-type' => 'application/xml'}, %{
78
+ <RenderResponse>
79
+ <Uuid>#{@uuid}</Uuid>
80
+ <StatusUri>#{server.url("/status/#{@uuid}")}</StatusUri>
81
+ </RenderResponse>
82
+ }]
83
+
84
+ set = TestDocumentSet.new
85
+ set.documents = [TestDocument.new]
86
+ req = SPDocgen::RenderRequest.new set
87
+ req.build
88
+
89
+ response = req.submit
90
+ response.should be_a SPDocgen::RenderResponse
91
+ response.uuid.should == @uuid
92
+ response.uri.should end_with @uuid
93
+ end
94
+ end
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'spdocgen'
5
+ require 'test_server'
6
+
7
+ require 'tempfile'
8
+ require 'yaml'
9
+
10
+ RSpec.configure do |config|
11
+ config.add_setting :server
12
+ config.add_setting :spdocgen_configuration
13
+
14
+ config.server = SPDocgen::TestServer.new
15
+ config.server.start
16
+
17
+ config.include SPDocgen::TestServerHelper
18
+
19
+ config.before :suite do
20
+ ENV['RACK_ENV'] = 'test'
21
+
22
+ yml = Tempfile.new(['spdocgen-config', '.yml'])
23
+ template = YAML.load_file File.join(File.dirname(__FILE__), 'config.yml')
24
+ template['test'].merge!('base_url' => config.server.base_url)
25
+ yml.write YAML.dump(template)
26
+ yml.close
27
+
28
+ config.spdocgen_configuration = yml
29
+ SPDocgen::Configuration.configuration_file = yml.path
30
+ end
31
+
32
+ config.after :suite do
33
+ config.spdocgen_configuration.unlink
34
+ end
35
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ require 'uuid'
4
+
5
+ describe SPDocgen::StatusRequest do
6
+ subject do
7
+ SPDocgen::StatusRequest.new server.url('/download/file.txt')
8
+ end
9
+
10
+ before :each do
11
+ @request = UUID.generate
12
+ @uuid = UUID.generate
13
+ end
14
+
15
+ def status_response(state, request_state, documents)
16
+ doc_xml = documents.collect do |doc|
17
+ %{<Document Reference='#{doc[:reference]}' NumPages='#{doc[:num_pages] || 1}'>
18
+ <Name>#{doc[:name]}</Name>
19
+ <Uri>#{doc[:uri]}</Uri>
20
+ <MetaDataEntries>
21
+ <MetaDataEntry>
22
+ <Key>test</Key>
23
+ <Value>this is a test</Value>
24
+ </MetaDataEntry>
25
+ </MetaDataEntries>
26
+ </Document>}
27
+ end.join('')
28
+
29
+ %{<StatusResponse>
30
+ <DocGenRequestStatuses>
31
+ <DocGenRequestStatus>
32
+ <Uuid>#{@uuid}</Uuid>
33
+ <State>#{state}</State>
34
+ <DocumentRequests>
35
+ <DocumentRequest ServerId='1' ClientId='#{@request}' State='#{request_state}'>
36
+ <Documents>#{doc_xml}</Documents>
37
+ </DocumentRequest>
38
+ </DocumentRequests>
39
+ </DocGenRequestStatus>
40
+ </DocGenRequestStatuses>
41
+ </StatusResponse>
42
+ }
43
+ end
44
+
45
+ it 'polls for status' do
46
+ response_body = status_response('Failed', 'Timeout', [])
47
+ server.response = [200, {'content-type' => 'application/xml'}, response_body]
48
+ response = subject.poll
49
+
50
+ response.should be_a SPDocgen::StatusResponse
51
+ end
52
+
53
+ it 'determines a request has failed' do
54
+ response_body = status_response('Failed', 'Timeout', [])
55
+ server.response = [200, {'content-type' => 'application/xml'}, response_body]
56
+ response = subject.poll
57
+
58
+ response.status(@uuid)[:state].should == 'Failed'
59
+ req_status = response.status(@uuid)[:requests].first
60
+ req_status[:request_guid].should == @request
61
+ req_status[:state].should == 'Timeout'
62
+ req_status[:documents].should be_empty
63
+ end
64
+
65
+ it 'determines a request has succeeded' do
66
+ doc_uuid = UUID.generate
67
+
68
+ documents = []
69
+ documents << {:reference => doc_uuid, :num_pages => 5, :name => 'Test.file', :uri => server.url('/test.file')}
70
+
71
+ response_body = status_response('Completed', 'Completed', documents)
72
+ server.response = [200, {'content-type' => 'application/xml'}, response_body]
73
+ response = subject.poll
74
+
75
+ response.status(@uuid)[:state].should == 'Completed'
76
+ req_status = response.status(@uuid)[:requests].first
77
+ req_status[:request_guid].should == @request
78
+ req_status[:state].should == 'Completed'
79
+ req_status[:documents].should_not be_empty
80
+
81
+ doc_status = req_status[:documents].first
82
+ doc_status[:name].should == 'Test.file'
83
+ doc_status[:uri].should end_with '/test.file'
84
+ doc_status[:reference].should == doc_uuid
85
+ doc_status[:num_pages].should == 5
86
+ doc_status[:metadata].should_not be_empty
87
+ doc_status[:metadata]['test'].should == 'this is a test'
88
+ end
89
+ end
@@ -0,0 +1,52 @@
1
+ require 'net/http'
2
+ require 'rack'
3
+ require 'rack/handler/thin'
4
+
5
+ module SPDocgen
6
+ class TestServer
7
+ attr_accessor :env, :response
8
+
9
+ def initialize
10
+ @host = '127.0.0.1'
11
+ @port = find_available_port
12
+ end
13
+
14
+ def base_url
15
+ "http://#{@host}:#{@port}"
16
+ end
17
+
18
+ def url(path)
19
+ URI.join(base_url, path).to_s
20
+ end
21
+
22
+ def call(env)
23
+ self.env = env
24
+ response.tap{self.response = nil}
25
+ end
26
+
27
+ def start
28
+ @thread = Thread.new do
29
+ Rack::Handler::Thin.run self, :Host => @host, :Port => @port do |server|
30
+ @server = server
31
+ end
32
+ end
33
+ sleep(0.1) until @server and @server.running?
34
+ end
35
+
36
+ private
37
+
38
+ # Stolen from Capybara
39
+ def find_available_port
40
+ server = TCPServer.new(@host, 0)
41
+ server.addr[1]
42
+ ensure
43
+ server.close if server
44
+ end
45
+ end
46
+
47
+ module TestServerHelper
48
+ def server
49
+ RSpec.configuration.server
50
+ end
51
+ end
52
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spdocgen
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Shaun Mangelsdorf
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2015-11-20 00:00:00 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
16
+ prerelease: false
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - &id002
20
+ - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ type: :runtime
24
+ version_requirements: *id001
25
+ description: Ruby client library for rendering and downloading documents from SP Docgen
26
+ email:
27
+ - smangelsdorf@sp.com.au
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files: []
33
+
34
+ files:
35
+ - .gitignore
36
+ - Gemfile
37
+ - LICENSE.txt
38
+ - README.md
39
+ - Rakefile
40
+ - lib/spdocgen.rb
41
+ - lib/spdocgen/configuration.rb
42
+ - lib/spdocgen/document.rb
43
+ - lib/spdocgen/document_set.rb
44
+ - lib/spdocgen/download_request.rb
45
+ - lib/spdocgen/download_response.rb
46
+ - lib/spdocgen/protocol.rb
47
+ - lib/spdocgen/render_request.rb
48
+ - lib/spdocgen/render_response.rb
49
+ - lib/spdocgen/status_request.rb
50
+ - lib/spdocgen/status_response.rb
51
+ - lib/spdocgen/version.rb
52
+ - spdocgen.gemspec
53
+ - spec/config.yml
54
+ - spec/download_request_spec.rb
55
+ - spec/render_request_spec.rb
56
+ - spec/spec_helper.rb
57
+ - spec/status_request_spec.rb
58
+ - spec/test_server.rb
59
+ homepage: http://sp.docgen.net.au
60
+ licenses: []
61
+
62
+ metadata: {}
63
+
64
+ post_install_message:
65
+ rdoc_options: []
66
+
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - *id002
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - *id002
75
+ requirements: []
76
+
77
+ rubyforge_project:
78
+ rubygems_version: 2.0.11
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: SP Docgen client library
82
+ test_files:
83
+ - spec/config.yml
84
+ - spec/download_request_spec.rb
85
+ - spec/render_request_spec.rb
86
+ - spec/spec_helper.rb
87
+ - spec/status_request_spec.rb
88
+ - spec/test_server.rb