fax_finder 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.project ADDED
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <projectDescription>
3
+ <name>fax_finder</name>
4
+ <comment></comment>
5
+ <projects>
6
+ </projects>
7
+ <buildSpec>
8
+ </buildSpec>
9
+ <natures>
10
+ </natures>
11
+ </projectDescription>
data/Changelog ADDED
File without changes
data/LICENSE ADDED
File without changes
data/README.rdoc ADDED
@@ -0,0 +1 @@
1
+ Readme coming soon.
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/rdoctask'
6
+ require 'rake/testtask'
7
+
8
+ begin
9
+ require 'jeweler'
10
+ Jeweler::Tasks.new do |gem|
11
+ gem.name = "fax_finder"
12
+ gem.summary = "Provides support MultiTech's FaxFinder server"
13
+ gem.authors = ["Erich L. Timkar"]
14
+ gem.email = "erich@hordesoftware.com"
15
+ gem.homepage = "http://github.com/erichhorde/fax_finder"
16
+ gem.rubyforge_project = "fax_finder"
17
+
18
+ gem.add_dependency('nokogiri', '1.4.4')
19
+ gem.add_dependency('builder', '~> 2.1.2')
20
+ gem.add_development_dependency('test-unit', '~> 2')
21
+ gem.add_development_dependency('mocha', '>= 0.9')
22
+
23
+ end
24
+
25
+ # Jeweler::RubyforgeTasks.new do |rubyforge|
26
+ # rubyforge.doc_task = "rdoc"
27
+ # end
28
+ rescue LoadError
29
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
30
+ end
31
+
32
+ Rake::RDocTask.new do |rdoc|
33
+ files =['README.rdoc', 'lib/**/*.rb']
34
+ rdoc.rdoc_files.add(files)
35
+ rdoc.main = "README.rdoc" # page to start on
36
+ rdoc.title = "fax_finder: Ruby Support for Multitech's FaxFinder Server"
37
+ rdoc.rdoc_dir = 'rdoc' # rdoc output folder
38
+ rdoc.options << '--line-numbers'
39
+ end
40
+
41
+ Rake::TestTask.new do |t|
42
+ t.test_files = FileList['test/**/*.rb']
43
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,68 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{fax_finder}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Erich L. Timkar"]
12
+ s.date = %q{2011-05-02}
13
+ s.email = %q{erich@hordesoftware.com}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE",
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".project",
20
+ "Changelog",
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "fax_finder.gemspec",
26
+ "fax_finder.tmproj",
27
+ "lib/fax_finder.rb",
28
+ "lib/fax_finder/query.rb",
29
+ "lib/fax_finder/request.rb",
30
+ "lib/fax_finder/response.rb",
31
+ "lib/fax_finder/send.rb",
32
+ "test/fixtures/send_request_external.xml",
33
+ "test/fixtures/send_request_inline.xml",
34
+ "test/fixtures/send_response_success.xml",
35
+ "test/query_test.rb",
36
+ "test/request_test.rb",
37
+ "test/response_test.rb",
38
+ "test/send_test.rb",
39
+ "test/test_helper.rb"
40
+ ]
41
+ s.homepage = %q{http://github.com/erichhorde/fax_finder}
42
+ s.require_paths = ["lib"]
43
+ s.rubyforge_project = %q{fax_finder}
44
+ s.rubygems_version = %q{1.7.2}
45
+ s.summary = %q{Provides support MultiTech's FaxFinder server}
46
+
47
+ if s.respond_to? :specification_version then
48
+ s.specification_version = 3
49
+
50
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
51
+ s.add_runtime_dependency(%q<nokogiri>, ["= 1.4.4"])
52
+ s.add_runtime_dependency(%q<builder>, ["~> 2.1.2"])
53
+ s.add_development_dependency(%q<test-unit>, ["~> 2"])
54
+ s.add_development_dependency(%q<mocha>, [">= 0.9"])
55
+ else
56
+ s.add_dependency(%q<nokogiri>, ["= 1.4.4"])
57
+ s.add_dependency(%q<builder>, ["~> 2.1.2"])
58
+ s.add_dependency(%q<test-unit>, ["~> 2"])
59
+ s.add_dependency(%q<mocha>, [">= 0.9"])
60
+ end
61
+ else
62
+ s.add_dependency(%q<nokogiri>, ["= 1.4.4"])
63
+ s.add_dependency(%q<builder>, ["~> 2.1.2"])
64
+ s.add_dependency(%q<test-unit>, ["~> 2"])
65
+ s.add_dependency(%q<mocha>, [">= 0.9"])
66
+ end
67
+ end
68
+
data/fax_finder.tmproj ADDED
@@ -0,0 +1,124 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>currentDocument</key>
6
+ <string>lib/fax_finder/request.rb</string>
7
+ <key>documents</key>
8
+ <array>
9
+ <dict>
10
+ <key>expanded</key>
11
+ <true/>
12
+ <key>name</key>
13
+ <string>fax_finder</string>
14
+ <key>regexFolderFilter</key>
15
+ <string>!.*/(\.[^/]*|CVS|_darcs|_MTN|\{arch\}|blib|.*~\.nib|.*\.(framework|app|pbproj|pbxproj|xcode(proj)?|bundle))$</string>
16
+ <key>sourceDirectory</key>
17
+ <string></string>
18
+ </dict>
19
+ </array>
20
+ <key>fileHierarchyDrawerWidth</key>
21
+ <integer>352</integer>
22
+ <key>metaData</key>
23
+ <dict>
24
+ <key>Changelog</key>
25
+ <dict>
26
+ <key>caret</key>
27
+ <dict>
28
+ <key>column</key>
29
+ <integer>0</integer>
30
+ <key>line</key>
31
+ <integer>0</integer>
32
+ </dict>
33
+ <key>firstVisibleColumn</key>
34
+ <integer>0</integer>
35
+ <key>firstVisibleLine</key>
36
+ <integer>0</integer>
37
+ </dict>
38
+ <key>lib/fax_finder/query.rb</key>
39
+ <dict>
40
+ <key>caret</key>
41
+ <dict>
42
+ <key>column</key>
43
+ <integer>49</integer>
44
+ <key>line</key>
45
+ <integer>14</integer>
46
+ </dict>
47
+ <key>firstVisibleColumn</key>
48
+ <integer>0</integer>
49
+ <key>firstVisibleLine</key>
50
+ <integer>0</integer>
51
+ </dict>
52
+ <key>lib/fax_finder/request.rb</key>
53
+ <dict>
54
+ <key>caret</key>
55
+ <dict>
56
+ <key>column</key>
57
+ <integer>28</integer>
58
+ <key>line</key>
59
+ <integer>5</integer>
60
+ </dict>
61
+ <key>columnSelection</key>
62
+ <false/>
63
+ <key>firstVisibleColumn</key>
64
+ <integer>0</integer>
65
+ <key>firstVisibleLine</key>
66
+ <integer>0</integer>
67
+ <key>selectFrom</key>
68
+ <dict>
69
+ <key>column</key>
70
+ <integer>15</integer>
71
+ <key>line</key>
72
+ <integer>5</integer>
73
+ </dict>
74
+ <key>selectTo</key>
75
+ <dict>
76
+ <key>column</key>
77
+ <integer>28</integer>
78
+ <key>line</key>
79
+ <integer>5</integer>
80
+ </dict>
81
+ </dict>
82
+ <key>lib/fax_finder/response.rb</key>
83
+ <dict>
84
+ <key>caret</key>
85
+ <dict>
86
+ <key>column</key>
87
+ <integer>11</integer>
88
+ <key>line</key>
89
+ <integer>42</integer>
90
+ </dict>
91
+ <key>firstVisibleColumn</key>
92
+ <integer>0</integer>
93
+ <key>firstVisibleLine</key>
94
+ <integer>0</integer>
95
+ </dict>
96
+ <key>test/response_test.rb</key>
97
+ <dict>
98
+ <key>caret</key>
99
+ <dict>
100
+ <key>column</key>
101
+ <integer>70</integer>
102
+ <key>line</key>
103
+ <integer>37</integer>
104
+ </dict>
105
+ <key>firstVisibleColumn</key>
106
+ <integer>0</integer>
107
+ <key>firstVisibleLine</key>
108
+ <integer>9</integer>
109
+ </dict>
110
+ </dict>
111
+ <key>openDocuments</key>
112
+ <array>
113
+ <string>Changelog</string>
114
+ <string>lib/fax_finder/request.rb</string>
115
+ <string>lib/fax_finder/response.rb</string>
116
+ <string>lib/fax_finder/query.rb</string>
117
+ <string>test/response_test.rb</string>
118
+ </array>
119
+ <key>showFileHierarchyDrawer</key>
120
+ <true/>
121
+ <key>windowFrame</key>
122
+ <string>{{404, 240}, {1276, 768}}</string>
123
+ </dict>
124
+ </plist>
@@ -0,0 +1,28 @@
1
+ require 'nokogiri'
2
+ require 'builder'
3
+
4
+ module FaxFinder
5
+
6
+ class Query < Request
7
+ def self.get(fax_key, entry_key)
8
+ self.post(){
9
+ construct_http_request(fax_key, entry_key)
10
+ }
11
+ end
12
+
13
+ def self.construct_http_request(fax_key, entry_key)
14
+ request = Net::HTTP::Get.new(self.path(fax_key, entry_key))
15
+ request.basic_auth self.user, self.password
16
+ request.set_content_type(Request::CONTENT_TYPE)
17
+ request
18
+ end
19
+
20
+ def self.path(fax_key, entry_key)
21
+ params=[BASE_PATH, fax_key, entry_key].reject{ |p| p.nil? }
22
+ File.join(*params)
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+
@@ -0,0 +1,64 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+
4
+ module FaxFinder
5
+ module Constants
6
+ BASE_PATH='/ffws/v1/ofax'
7
+ DEFAULT_PORT=80
8
+ DEFAULT_SSL=false
9
+ end
10
+
11
+ module RequestClassMethods
12
+ attr_reader :host, :user, :password, :port, :ssl
13
+ def configure(_host, _user, _password, _port=Request::DEFAULT_PORT, _ssl=Request::DEFAULT_SSL)
14
+ @host, @user, @password, @port, @ssl=_host, _user, _password, _port, _ssl
15
+ end
16
+
17
+ def reset
18
+ @host=@user=@password=nil
19
+ @port=Request::DEFAULT_PORT
20
+ @ssl=Request::DEFAULT_SSL
21
+ end
22
+
23
+ def post
24
+ response_body=nil
25
+ begin
26
+ Net::HTTP.start(Request.host, Request.port) { |http|
27
+ http.use_ssl=Request.ssl
28
+ http_request = yield
29
+ http_request.basic_auth Request.user, Request.password
30
+ http_request.set_content_type(Request::CONTENT_TYPE)
31
+ http_response = http.request(http_request)
32
+ response_body=http_response.body
33
+ }
34
+ rescue Errno::ECONNREFUSED => e
35
+ response_body=Responses::NO_CONNECTION
36
+ rescue RuntimeError => e
37
+ response_body=Responses::APPLICATION_ERROR.gsub(Responses::ERROR_GSUB, e.message)
38
+ end
39
+ Response.new(Nokogiri::XML(response_body))
40
+ end
41
+
42
+ # def proces_http_response(http_response)
43
+ # return
44
+ # end
45
+ #
46
+ def formatted_fax_finder_time(time)
47
+ result=nil
48
+ if time
49
+ result=(time.utc? ? time : time.utc).strftime(Request::TIME_FORMAT)
50
+ end
51
+ result
52
+ end
53
+
54
+ end
55
+
56
+ class Request
57
+ include Constants
58
+ TIME_FORMAT="%Y-%m-%dT%H:%M:%S"
59
+ CONTENT_TYPE='text/xml'
60
+ end
61
+
62
+ end
63
+
64
+ FaxFinder::Request.send(:extend, FaxFinder::RequestClassMethods)
@@ -0,0 +1,54 @@
1
+ module FaxFinder
2
+ module Responses
3
+ ERROR_GSUB='####MESSAGE#####'
4
+
5
+ NO_CONNECTION =<<-EOXML
6
+ <response>
7
+ <message>No connection to fax server</message>
8
+ <fax_entry>
9
+ <state>error</state>
10
+ </fax_entry>
11
+ </response>
12
+ EOXML
13
+
14
+ APPLICATION_ERROR =<<-EOXML
15
+ <response>
16
+ <message>####MESSAGE#####</message>
17
+ <fax_entry>
18
+ <state>error</state>
19
+ </fax_entry>
20
+ </response>
21
+ EOXML
22
+ end
23
+
24
+ class Response
25
+ attr_reader :doc, :state, :fax_entry_url, :fax_key, :entry_key, :try_number, :message, :schedule_message
26
+ REGEXP_KEYS=/([0-9A-F]+)\/([0-9A-F]+)$/
27
+ XPATH_STATE='//fax_entry/state'
28
+ XPATH_FAX_ENTRY_URL='//fax_entry/fax_entry_url'
29
+ XPATH_TRY_NUMBER='//fax_entry/try_number'
30
+ XPATH_MESSAGE='//response/message'
31
+ XPATH_SCHEDULE_MESSAGE='//fax_entry/schedule_message'
32
+
33
+ def initialize(_doc)
34
+ @doc=_doc
35
+ if self.doc
36
+ @message=self.doc.xpath(XPATH_MESSAGE).text
37
+ @state=self.doc.xpath(XPATH_STATE).text
38
+ if @state != 'error'
39
+ @fax_entry_url=self.doc.xpath(XPATH_FAX_ENTRY_URL).text
40
+ @fax_key, @entry_key=self.extract_fax_and_entry_key(self.fax_entry_url)
41
+ @try_number=self.doc.xpath(XPATH_TRY_NUMBER).text.to_i
42
+ @schedule_message=self.doc.xpath(XPATH_SCHEDULE_MESSAGE).text
43
+ end
44
+ end
45
+ end
46
+
47
+ def extract_fax_and_entry_key(_url)
48
+ match=REGEXP_KEYS.match(_url)
49
+ match[1,2] if match
50
+ end
51
+
52
+ end
53
+
54
+ end
@@ -0,0 +1,65 @@
1
+ require 'nokogiri'
2
+ require 'builder'
3
+
4
+ module FaxFinder
5
+ module SendClassMethods
6
+
7
+ def post(recipient_fax, external_url, options={})
8
+ super(){
9
+ construct_http_request(recipient_fax, external_url, options)
10
+ }
11
+ end
12
+
13
+ def construct_xml(recipient_fax, external_url, options={})
14
+ xml = ""
15
+ builder = Builder::XmlMarkup.new(:target => xml, :indent => 2 )
16
+ builder.instruct!(:xml, :version=>'1.0', :encoding=>'UTF-8')
17
+
18
+ time=options[:schedule_all_at]
19
+ time=time.utc if time && !time.utc?
20
+ formatted_time=time ? time.strftime(Request::TIME_FORMAT) : nil
21
+
22
+ builder.schedule_fax {
23
+ builder.cover_page do
24
+ # builder.subject(options[:subject])
25
+ # builder.comment(options[:comment])
26
+ builder.enabled('false')
27
+ end
28
+
29
+ builder.recipient do
30
+ builder.fax_number(recipient_fax)
31
+ builder.organization(options[:recipient_organization])
32
+ builder.phone_number(options[:recipient_phone_number])
33
+ builder.name(options[:recipient_name])
34
+ end
35
+
36
+ builder.sender do
37
+ builder.fax_number(options[:sender_fax_number])
38
+ builder.phone_number(options[:sender_phone_number])
39
+ builder.organization(options[:sender_organization])
40
+ builder.name(options[:sender_name])
41
+ end
42
+
43
+ builder.attachment do
44
+ builder.location('external')
45
+ builder.url(external_url)
46
+ end
47
+ builder.schedule_all_at(formatted_fax_finder_time(options[:schedule_all_at]))
48
+ }
49
+ xml
50
+ end
51
+
52
+ def construct_http_request(recipient_fax, external_url, options={})
53
+ request = Net::HTTP::Post.new(Request::BASE_PATH)
54
+ request.body=construct_xml(recipient_fax, external_url, options)
55
+ request
56
+ end
57
+
58
+ end
59
+
60
+ class Send < Request
61
+ end
62
+
63
+ end
64
+
65
+ FaxFinder::Send.send(:extend, FaxFinder::SendClassMethods)
data/lib/fax_finder.rb ADDED
@@ -0,0 +1,32 @@
1
+ #--
2
+ # (The MIT License)
3
+ #
4
+ # Copyright (c) 2008 Szymon Nowak & Pawel Kozlowski (U2I)
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to
8
+ # deal in the Software without restriction, including without limitation the
9
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10
+ # sell copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22
+ # IN THE SOFTWARE.
23
+ #++
24
+ #
25
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
26
+ require 'net/http'
27
+ require 'net/https'
28
+
29
+ require 'fax_finder/response.rb'
30
+ require 'fax_finder/request.rb'
31
+ require 'fax_finder/send.rb'
32
+ require 'fax_finder/query.rb'
@@ -0,0 +1,35 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <schedule_fax>
3
+ <cover_page>
4
+ <url>https://192.168.2.1/ffws/v1/data/cover_pages/default.pdf</url>
5
+ <enabled>true</enabled>
6
+ <subject>Test Subject</subject>
7
+ <comments>Test Message</comments>
8
+ </cover_page>
9
+ <sender>
10
+ <name>Sender Name</name>
11
+ <organization>Sender Org</organization>
12
+ <phone_number>218-555-3333</phone_number>
13
+ <fax_number>218-555-3334</fax_number>
14
+ <email_address>sender@example.com</email_address>
15
+ </sender>
16
+ <recipient>
17
+ <name>Rcpt 1 Name</name>
18
+ <organization>Rcpt 1 Org</organization>
19
+ <fax_number>-218-555-3335</fax_number>
20
+ <phone_number>218-555-3336</phone_number>
21
+ </recipient>
22
+ <attachment>
23
+ <location>inline</location>
24
+ <name>attachment1.txt</name>
25
+ <content_type>text/plain</content_type>
26
+ <content_transfer_encoding>base64</content_transfer_encoding>
27
+ <content>dGVzdA==</content>
28
+ </attachment>
29
+ <max_tries>3</max_tries>
30
+ <priority>3</priority>
31
+ <try_interval>30</try_interval>
32
+ <receipt>failure</receipt>
33
+ <receipt_attachment>none</receipt_attachment>
34
+ <schedule_all_at>2008-08-07T20:30:00</schedule_all_at>
35
+ </schedule_fax>
@@ -0,0 +1,35 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <schedule_fax>
3
+ <cover_page>
4
+ <url>https://192.168.2.1/ffws/v1/data/cover_pages/default.pdf</url>
5
+ <enabled>true</enabled>
6
+ <subject>Test Subject</subject>
7
+ <comments>Test Message</comments>
8
+ </cover_page>
9
+ <sender>
10
+ <name>Sender Name</name>
11
+ <organization>Sender Org</organization>
12
+ <phone_number>218-555-3333</phone_number>
13
+ <fax_number>218-555-3334</fax_number>
14
+ <email_address>sender@example.com</email_address>
15
+ </sender>
16
+ <recipient>
17
+ <name>Rcpt 1 Name</name>
18
+ <organization>Rcpt 1 Org</organization>
19
+ <fax_number>-218-555-3335</fax_number>
20
+ <phone_number>218-555-3336</phone_number>
21
+ </recipient>
22
+ <attachment>
23
+ <location>inline</location>
24
+ <name>attachment1.txt</name>
25
+ <content_type>text/plain</content_type>
26
+ <content_transfer_encoding>base64</content_transfer_encoding>
27
+ <content>dGVzdA==</content>
28
+ </attachment>
29
+ <max_tries>3</max_tries>
30
+ <priority>3</priority>
31
+ <try_interval>30</try_interval>
32
+ <receipt>failure</receipt>
33
+ <receipt_attachment>none</receipt_attachment>
34
+ <schedule_all_at>2008-08-07T20:30:00</schedule_all_at>
35
+ </schedule_fax>
@@ -0,0 +1,43 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <response>
3
+ <message>Success</message>
4
+ <fax_entry>
5
+ <fax_entry_url>https://192.168.2.1/ffws/v1/ofax/0000001B/0000</fax_entry_url>
6
+ <fax_url>https://192.168.2.1/ffws/v1/ofax/0000001B</fax_url>
7
+ <state>preprocessing</state>
8
+ <schedule_message>Successfully sent fax</schedule_message>
9
+ <created>2008-08-01 08:43:29</created>
10
+ <stime>2008-08-01 08:52:29</stime>
11
+ <try_number>1</try_number>
12
+ <agent>FFWS</agent>
13
+ <preview>https://192.168.2.1/ffws/v1/data/preview/0000001B-0000.pdf</preview>
14
+ <cover_page>
15
+ <url>https://192.168.2.1/ffws/v1/data/cover_pages/default.pdf</url>
16
+ <enabled>true</enabled>
17
+ <subject>Test Subject</subject>
18
+ <comments>Test Message</comments>
19
+ </cover_page>
20
+ <sender>
21
+ <username>admin</username>
22
+ <name>Sender Name</name>
23
+ <organization>Sender Org</organization>
24
+ <phone_number>218-555-3333</phone_number>
25
+ <fax_number>218-555-3334</fax_number>
26
+ <email_address>sender@example.com</email_address>
27
+ </sender>
28
+ <recipient>
29
+ <name>Rcpt 1 Name</name>
30
+ <organization>Rcpt 1 Org</organization>
31
+ <fax_number>218-555-3335</fax_number>
32
+ <phone_number>218-555-3336</phone_number>
33
+ </recipient>
34
+ <max_tries>3</max_tries>
35
+ <priority>3</priority>
36
+ <try_interval>30</try_interval>
37
+ <receipt>failure</receipt>
38
+ <receipt_attachment>none</receipt_attachment>
39
+ <pages>0</pages>
40
+ <approver></approver>
41
+ <approval_time></approval_time>
42
+ </fax_entry>
43
+ </response>
@@ -0,0 +1,51 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ module FaxFinder
4
+ class QueryGetTest<Test::Unit::TestCase
5
+ def setup
6
+ Request.configure('example.com', 'user', 'password')
7
+ end
8
+
9
+ def test_get
10
+ Query.get('user', 'password')
11
+ end
12
+
13
+ def test_gets_returns_response
14
+ assert_instance_of(FaxFinder::Response, Query.get(nil, nil))
15
+ end
16
+ end
17
+
18
+ class QueryConstructHttpRequestTest<Test::Unit::TestCase
19
+ def setup
20
+ Request.configure('example.com', 'user', 'password')
21
+ @http_request=Query.construct_http_request('fax_key', 'entry_key')
22
+ end
23
+
24
+ def test_returns_a_get
25
+ assert_instance_of(Net::HTTP::Get, @http_request)
26
+ end
27
+
28
+ def test_sets_path
29
+ assert_equal(Query.path('fax_key', 'entry_key'), @http_request.path)
30
+ end
31
+
32
+ def test_sets_basic_auth
33
+ assert_not_nil(@http_request['authorization'])
34
+ end
35
+
36
+ def test_sets_content_type
37
+ assert_equal('text/xml', @http_request['Content-Type'])
38
+ end
39
+ end
40
+
41
+ class QueryPathTest<Test::Unit::TestCase
42
+ def setup
43
+ end
44
+
45
+ def test_constructs_using_base_path
46
+ assert_equal(Request::BASE_PATH+'/'+'fax_key' +'/'+'entry_key', Query.path('fax_key', 'entry_key'))
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,110 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ module FaxFinder
4
+
5
+ class RequestSetupTest<Test::Unit::TestCase
6
+ def setup
7
+ Request.configure('example.com', 'user', 'password', 123, true)
8
+ end
9
+
10
+ def test_setup_host
11
+ assert_equal('example.com', Request.host)
12
+ end
13
+
14
+ def test_setup_user
15
+ assert_equal('user', Request.user)
16
+ end
17
+
18
+ def test_setup_password
19
+ assert_equal('password', Request.password)
20
+ end
21
+
22
+ def test_setup_port
23
+ assert_equal(123, Request.port)
24
+ end
25
+
26
+ def test_setup_ssl
27
+ assert_equal(true, Request.ssl)
28
+ end
29
+
30
+ end
31
+
32
+ class RequestResetTest<Test::Unit::TestCase
33
+ def setup
34
+ Request.configure('example.com', 'user', 'password', 123, true)
35
+ Request.reset
36
+ end
37
+
38
+ def test_resets_host
39
+ assert_nil(Request.host)
40
+ end
41
+
42
+ def test_resets_user
43
+ assert_nil(Request.user)
44
+ end
45
+
46
+ def test_resets_port
47
+ assert_nil(Request.port)
48
+ end
49
+
50
+ def test_resets_password
51
+ assert_nil(Request.password)
52
+ end
53
+
54
+ def test_resets_port
55
+ assert_equal(80, Request.port)
56
+ end
57
+
58
+ def test_resets_ssl
59
+ assert_equal(false, Request.ssl)
60
+ end
61
+
62
+ end
63
+
64
+ class MockRequest<FaxFinder::Request
65
+ def self.post
66
+ super(){
67
+ construct_http_request
68
+ }
69
+ end
70
+
71
+ def self.construct_http_request
72
+ request = Net::HTTP::Get.new('/ffws/v1/ofax')
73
+ request.basic_auth self.user, self.password
74
+ request.set_content_type(Request::CONTENT_TYPE)
75
+ request
76
+ end
77
+ end
78
+
79
+ class RequestPostConnectionFailureTest<Test::Unit::TestCase
80
+ def setup
81
+ @response=nil
82
+ Request.configure(nil, 'user', 'password', 123, true)
83
+ @post=lambda{
84
+ @response=MockRequest.post
85
+ }
86
+ end
87
+
88
+ def test_handles_connection_failure
89
+ @host=nil
90
+ assert_nothing_thrown { @post.call }
91
+ end
92
+
93
+ def test_returns_a_response
94
+ @post.call
95
+ assert_instance_of(FaxFinder::Response, @response)
96
+ end
97
+
98
+ def test_sets_the_state
99
+ @post.call
100
+ assert_equal('error', @response.state)
101
+ end
102
+
103
+ def test_sets_the_message
104
+ @post.call
105
+ assert_equal('No connection to fax server', @response.message)
106
+ end
107
+
108
+ end
109
+
110
+ end
@@ -0,0 +1,62 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ module FaxFinder
4
+ class ResponseConstructorTest<Test::Unit::TestCase
5
+ def setup
6
+ @response=Response.new(Nokogiri::XML(File.open('test/fixtures/send_response_success.xml')))
7
+ end
8
+
9
+ def test_handles_nil
10
+ assert_nothing_thrown { Response.new(nil) }
11
+ end
12
+
13
+ def test_sets_state
14
+ assert_equal('preprocessing', @response.state)
15
+ end
16
+
17
+ def test_set_fax_key
18
+ assert_equal('0000001B', @response.fax_key)
19
+ end
20
+
21
+ def test_set_entry_key
22
+ assert_equal('0000', @response.entry_key)
23
+ end
24
+
25
+ def test_set_fax_entry_url
26
+ assert_equal('https://192.168.2.1/ffws/v1/ofax/0000001B/0000', @response.fax_entry_url)
27
+ end
28
+
29
+ def test_set_try_number
30
+ assert_equal(1, @response.try_number)
31
+ end
32
+
33
+ def test_set_message
34
+ assert_equal('Success', @response.message)
35
+ end
36
+
37
+ def test_sets_schedule_message
38
+ assert_equal('Successfully sent fax', @response.schedule_message)
39
+ end
40
+ end
41
+
42
+ class ResponseMethodsTest<Test::Unit::TestCase
43
+ def setup
44
+ @response=Response.new#(Nokogiri::XML(File.open('test/fixtures/send_response_success.xml')))
45
+ end
46
+
47
+ def extract_fax_and_entry_key_handles_nil
48
+ assert_nothing_thrown {
49
+ assert_equal([nil, nil], @response.extract_fax_and_entry_key(nil) )
50
+ }
51
+ end
52
+
53
+ def extract_fax_and_entry_key_handles_parses_url
54
+ assert_nothing_thrown { @response.extract_fax_and_entry_key(nil) }
55
+ end
56
+
57
+ def extract_fax_and_entry_key_handles_parses_url
58
+ assert_equal(['0000001B','0000'], @response.extract_fax_and_entry_key('https://192.168.2.1/ffws/v1/ofax/0000001B/0000'))
59
+ end
60
+
61
+ end
62
+ end
data/test/send_test.rb ADDED
@@ -0,0 +1,118 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ module FaxFinder
4
+ OPTIONS={:subject=>'Something',
5
+ :comment=>'Comment',
6
+ :recipient_name=>'recipient_name',
7
+ :recipient_organization=>'recipient_organization',
8
+ :recipient_phone_number=>'5647382910',
9
+ :sender_fax_number=>'0123456789',
10
+ :sender_name=>'sender_name',
11
+ :sender_organization=>'sender_organization',
12
+ :sender_phone_number=>'0987654321',
13
+ :schedule_all_at=>Time.now.utc
14
+ }
15
+
16
+ class SendPostTest<Test::Unit::TestCase
17
+ def setup
18
+ Request.configure('example.com', 'user', 'password')
19
+ end
20
+
21
+ def test_post
22
+ Send.post('user', 'password')
23
+ end
24
+
25
+ def test_posts_returns_response
26
+ assert_instance_of(FaxFinder::Response, Send.post(nil, nil))
27
+ end
28
+ end
29
+
30
+ class SendConstructXMLTest<Test::Unit::TestCase
31
+ def setup
32
+ @doc=Nokogiri::XML(Send.construct_xml('1234567890', 'https://localhost/something', OPTIONS))
33
+ end
34
+
35
+ def test_returns_string_and_doesnt_blow_up
36
+ assert_nothing_thrown { assert_instance_of(String, Send.construct_xml(nil, nil)) }
37
+ end
38
+
39
+ def test_includes_subject
40
+ assert_equal('Something', @doc.xpath('//schedule_fax/cover_page/subject').text)
41
+ end
42
+
43
+ def test_includes_comment
44
+ assert_equal('Comment', @doc.xpath('//schedule_fax/cover_page/comment').text)
45
+ end
46
+
47
+ def test_includes_recipient_name
48
+ assert_equal('recipient_name', @doc.xpath('//schedule_fax/recipient/name').text)
49
+ end
50
+
51
+ def test_includes_recipient_organization
52
+ assert_equal('recipient_organization', @doc.xpath('//schedule_fax/recipient/organization').text)
53
+ end
54
+
55
+ def test_includes_recipient_fax_number
56
+ assert_equal('1234567890', @doc.xpath('//schedule_fax/recipient/fax_number').text)
57
+ end
58
+
59
+ def test_includes_recipient_phone_number
60
+ assert_equal('5647382910', @doc.xpath('//schedule_fax/recipient/phone_number').text)
61
+ end
62
+
63
+ def test_includes_sender_fax
64
+ assert_equal('0123456789', @doc.xpath('//schedule_fax/sender/fax_number').text)
65
+ end
66
+
67
+ def test_includes_sender_organization
68
+ assert_equal('sender_organization', @doc.xpath('//schedule_fax/sender/organization').text)
69
+ end
70
+
71
+ def test_includes_sender_fax_number
72
+ assert_equal('0123456789', @doc.xpath('//schedule_fax/sender/fax_number').text)
73
+ end
74
+
75
+ def test_includes_sender_phone_number
76
+ assert_equal('0987654321', @doc.xpath('//schedule_fax/sender/phone_number').text)
77
+ end
78
+
79
+ def test_includes_attachment_location
80
+ assert_equal('external', @doc.xpath('//schedule_fax/attachment/location').text)
81
+ end
82
+
83
+ def test_includes_attachment_url
84
+ assert_equal('https://localhost/something', @doc.xpath('//schedule_fax/attachment/url').text)
85
+ end
86
+
87
+ def test_includes_schedule_all_at
88
+ assert_equal(Time.now.utc.strftime(Request::TIME_FORMAT), @doc.xpath('//schedule_fax/schedule_all_at').text)
89
+ end
90
+
91
+ def test_converts_to_utc
92
+ @doc=Nokogiri::XML(Send.construct_xml('1234567890', 'https://localhost/something', OPTIONS.merge(:schedule_all_at=>Time.now)))
93
+ assert_equal(Time.now.utc.strftime(Request::TIME_FORMAT), @doc.xpath('//schedule_fax/schedule_all_at').text)
94
+ end
95
+
96
+ end
97
+
98
+ class SendConstructHttpRequestTest<Test::Unit::TestCase
99
+ def setup
100
+ Request.configure('example.com', 'user', 'password')
101
+ @http_request=Send.construct_http_request('1234567890', 'https://localhost/something', OPTIONS)
102
+ end
103
+
104
+ def test_returns_a_post
105
+ assert_instance_of(Net::HTTP::Post, @http_request)
106
+ end
107
+
108
+ def test_sets_body
109
+ assert_equal(Send.construct_xml('1234567890', 'https://localhost/something', OPTIONS), @http_request.body)
110
+ end
111
+
112
+ def test_sets_path
113
+ assert_equal(Request::BASE_PATH, @http_request.path)
114
+ end
115
+
116
+ end
117
+
118
+ end
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ gem 'test-unit', '~> 2'
3
+ require 'test/unit'
4
+ gem 'mocha'
5
+ require 'mocha'
6
+ # require 'builder'
7
+
8
+ require File.join( File.dirname(__FILE__), '..','lib', 'fax_finder.rb')
9
+
10
+ class Class
11
+ def publicize_instance_methodss
12
+ saved_private_instance_methods = self.private_instance_methods
13
+ self.class_eval { public(*saved_private_instance_methods) }
14
+ yield
15
+ self.class_eval { private(*saved_private_instance_methods) }
16
+ end
17
+
18
+ def publicize_class_methods
19
+ saved_private_class_methods = self.private_methods(false)
20
+ self.class_eval { public_class_method(*saved_private_class_methods) }
21
+ yield
22
+ self.class_eval { private_class_method(*saved_private_class_methods) }
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fax_finder
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Erich L. Timkar
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-05-02 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: nokogiri
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - "="
27
+ - !ruby/object:Gem::Version
28
+ hash: 15
29
+ segments:
30
+ - 1
31
+ - 4
32
+ - 4
33
+ version: 1.4.4
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: builder
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 15
45
+ segments:
46
+ - 2
47
+ - 1
48
+ - 2
49
+ version: 2.1.2
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: test-unit
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ hash: 7
61
+ segments:
62
+ - 2
63
+ version: "2"
64
+ type: :development
65
+ version_requirements: *id003
66
+ - !ruby/object:Gem::Dependency
67
+ name: mocha
68
+ prerelease: false
69
+ requirement: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ hash: 25
75
+ segments:
76
+ - 0
77
+ - 9
78
+ version: "0.9"
79
+ type: :development
80
+ version_requirements: *id004
81
+ description:
82
+ email: erich@hordesoftware.com
83
+ executables: []
84
+
85
+ extensions: []
86
+
87
+ extra_rdoc_files:
88
+ - LICENSE
89
+ - README.rdoc
90
+ files:
91
+ - .project
92
+ - Changelog
93
+ - LICENSE
94
+ - README.rdoc
95
+ - Rakefile
96
+ - VERSION
97
+ - fax_finder.gemspec
98
+ - fax_finder.tmproj
99
+ - lib/fax_finder.rb
100
+ - lib/fax_finder/query.rb
101
+ - lib/fax_finder/request.rb
102
+ - lib/fax_finder/response.rb
103
+ - lib/fax_finder/send.rb
104
+ - test/fixtures/send_request_external.xml
105
+ - test/fixtures/send_request_inline.xml
106
+ - test/fixtures/send_response_success.xml
107
+ - test/query_test.rb
108
+ - test/request_test.rb
109
+ - test/response_test.rb
110
+ - test/send_test.rb
111
+ - test/test_helper.rb
112
+ homepage: http://github.com/erichhorde/fax_finder
113
+ licenses: []
114
+
115
+ post_install_message:
116
+ rdoc_options: []
117
+
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ hash: 3
126
+ segments:
127
+ - 0
128
+ version: "0"
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ hash: 3
135
+ segments:
136
+ - 0
137
+ version: "0"
138
+ requirements: []
139
+
140
+ rubyforge_project: fax_finder
141
+ rubygems_version: 1.7.2
142
+ signing_key:
143
+ specification_version: 3
144
+ summary: Provides support MultiTech's FaxFinder server
145
+ test_files: []
146
+