help_spot 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore CHANGED
@@ -1,4 +1,4 @@
1
1
  pkg
2
2
  doc
3
3
  *.gem
4
- config/help_spot.yml
4
+ *.gemspec
data/README.rdoc CHANGED
@@ -6,20 +6,22 @@ For information on HelpSpot: http://www.userscape.com/products/helpspot/
6
6
 
7
7
  Details of HelpSpot's API are at: http://www.userscape.com/helpdesk/index.php?pg=kb.book&id=6
8
8
 
9
- == License
9
+ = Installation
10
10
 
11
- Licensed under the MIT License. See the included LICENSE file.
11
+ A gem has been pushed to gemcutter[http://gemcutter.org/]
12
12
 
13
- = Usage
13
+ Once you have gemcutter setup as a gem source:
14
14
 
15
- == Installation
15
+ gem install help_spot
16
16
 
17
- Copy the <tt>config/help_spot.yml.sample</tt> file to <tt>THE_ROOT_DIR_OF_YOUR_APP/config/help_spot.yml</tt>. Edit the file to have some sensible values.
17
+ = Usage
18
18
 
19
- Somewhere in your application, you'll want to do this once:
19
+ help_spot = HelpSpot.new("https://support.yourwebsite.com/api/", "user@localhost.com", "sekrit")
20
20
 
21
- <tt>HelpSpot.configure</tt>
21
+ == Documentation
22
22
 
23
- In my app, it also turns out it's useful to do this once:
23
+ Documentation is hosted at rdoc.info[http://rdoc.info/projects/jnewland/help_spot]
24
+
25
+ == License
24
26
 
25
- <tt>HELPSPOT_CATEGORIES = HelpSpot.category_key_value_pairs</tt>
27
+ Licensed under the MIT License. See the included LICENSE file.
data/Rakefile CHANGED
@@ -1,21 +1,25 @@
1
- require 'rubygems'
2
- require 'rake'
1
+ $LOAD_PATH.unshift 'lib'
2
+ require 'help_spot/version'
3
3
 
4
4
  begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
+ gem.version = HelpSpot::VERSION
7
8
  gem.name = "help_spot"
8
- gem.summary = %Q{A package for interacting with UserScape's HelpSpot product.}
9
- gem.description = %Q{A package for interacting with UserScape's HelpSpot product.}
9
+ gem.summary = %Q{API wrapper for HelpSpot}
10
+ gem.description = %Q{API wrapper for HelpSpot}
10
11
  gem.email = "jnewland@gmail.com"
11
12
  gem.homepage = "http://github.com/jnewland/help_spot"
12
- gem.authors = ["Jamie Wilson","Jesse Newland"]
13
- gem.add_development_dependency "rspec"
13
+ gem.authors = ["Jesse Newland"]
14
+ gem.add_development_dependency "rspec", "= 1.3.0"
15
+ gem.add_development_dependency "fakeweb"
16
+ gem.add_dependency "hashie", "~> 0.1.8"
17
+ gem.add_dependency "httparty", "~> 0.5.0"
14
18
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
19
  end
16
20
  Jeweler::GemcutterTasks.new
17
21
  rescue LoadError
18
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
22
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
23
  end
20
24
 
21
25
  require 'spec/rake/spectask'
@@ -36,14 +40,10 @@ task :default => :spec
36
40
 
37
41
  require 'rake/rdoctask'
38
42
  Rake::RDocTask.new do |rdoc|
39
- if File.exist?('VERSION')
40
- version = File.read('VERSION')
41
- else
42
- version = ""
43
- end
43
+ version = HelpSpot::VERSION
44
44
 
45
45
  rdoc.rdoc_dir = 'rdoc'
46
46
  rdoc.title = "help_spot #{version}"
47
47
  rdoc.rdoc_files.include('README*')
48
48
  rdoc.rdoc_files.include('lib/**/*.rb')
49
- end
49
+ end
data/TODO ADDED
@@ -0,0 +1,35 @@
1
+ Unimplemented API Methods
2
+
3
+ private.customer.getPasswordByEmail
4
+ private.customer.setPasswordByEmail
5
+ private.request.addTimeEvent
6
+ private.request.deleteTimeEvent
7
+ private.request.getTimeEvents
8
+ private.request.getMailboxes
9
+ private.request.merge
10
+ private.filter.getColumnNames
11
+ private.timetracker.search
12
+ private.user.getFilters
13
+ private.user.preferences
14
+ private.util.getActiveStaff
15
+ customer.getRequests
16
+ request.create
17
+ request.update
18
+ request.getCategories
19
+ request.getCustomFields
20
+ request.get
21
+ forums.list
22
+ forums.get
23
+ forums.getTopics
24
+ forums.getPosts
25
+ forums.createTopic
26
+ forums.createPost
27
+ forums.search
28
+ kb.list
29
+ kb.get
30
+ kb.getBookTOC
31
+ kb.getPage
32
+ kb.search
33
+ kb.voteHelpful
34
+ kb.voteNotHelpful
35
+ util.getFieldLabels
@@ -0,0 +1,3 @@
1
+ class HelpSpot
2
+ VERSION = '0.0.3'
3
+ end
data/lib/help_spot.rb CHANGED
@@ -1,200 +1,87 @@
1
- require 'uri'
2
- require 'net/http'
3
- require 'net/https'
4
- require 'json'
5
-
6
- ##
7
- # help_spot
8
- #
9
- # A partial basic implementation of a HelpSpot API interface
10
- #
11
- # == Using help_spot
12
- #
13
- # === Basics
14
- #
15
- # Copy and edit the included config file. Include the gem in your app. Call the configure method. Hit the API.
16
- #
17
- # require 'help_spot'
18
- # HelpSpot.configure(:config_file => '/path/to/help_spot.yml')
19
- # HelpSpot.forums_list
20
- #
21
- # => [{"xForumId"=>"1", "fClosed"=>"0", "sForumName"=>"The First Forum", "iOrder"=>"0", "sDescription"=>"A test forum"}, {"xForumId"=>"2", "fClosed"=>"0", "sForumName"=>"Secondary Forum", "iOrder"=>"0", "sDescription"=>"Forum #2"}]
22
- #
23
-
24
- module HelpSpot
25
- class << self
26
-
27
- # Loads the config file.
28
- #
29
- # == Options
30
- # * config_file (optional)
31
- # Defaults to '/config/help_spot.yml'
32
- # Shouldn't be required when using merb or Rails.
33
- #
34
- def configure(args={})
35
- # work out the default app_root
36
- if defined?(Merb)
37
- app_root = Merb.root
38
- elsif defined?(Rails)
39
- app_root = RAILS_ROOT
40
- else
41
- app_root = '.'
42
- end
43
-
44
- config_file = args[:config_file] || '/config/help_spot.yml'
45
- yml_file = app_root+config_file
46
-
47
- raise yml_file+" not found" unless File.exist? yml_file
48
- @config = YAML.load_file(yml_file)
49
- end
50
-
51
- # sends a feedback request to HelpSpot and returns the request ID number and access key
52
- #
53
- # == Options
54
- # In addition to note you must also have at least one of the following set: first_name, last_name, user_id, email or phone
55
- # * note
56
- # The body of the ticket
57
- # * category
58
- # * first_name
59
- # * last_name
60
- # * user_id
61
- # * email
62
- # * phone
63
- # * urgent
64
- # A boolean flag. Defaults to false.
65
- #
66
- def create(args)
67
- help_form = {:tNote => args[:note],
68
- :xCategory => args[:category],
69
- :sFirstName => args[:first_name],
70
- :sLastName => args[:last_name],
71
- :sUserId => args[:user_id],
72
- :sEmail => args[:email],
73
- :sPhone => args[:phone],
74
- :fUrgent => args[:urgent]}.reject!{|k,v| v == nil}
75
-
76
- JSON.parse(api_request('request.create', 'POST', help_form))['xRequest'] rescue []
77
- end
78
-
79
- # Returns an array of tickets belonging to a given user id.
80
- #
81
- # == Authentication
82
- # This method does require authentication.
83
- #
84
- # == Options
85
- # * user_id
86
- # The user who's tickets you wish to view.
87
- #
88
- def get_by_user_id(args)
89
- JSON.parse(api_request('private.request.search', 'GET', {:sUserId => args[:user_id]}))['request'] rescue nil
90
- end
91
-
92
- # Returns ticket categories.
93
- #
94
- # == Authentication
95
- # This method does require authentication.
96
- #
97
- # == Options
98
- # * include_deleted
99
- # true if you want to include deleted categories.
100
- #
101
- def categories(args={})
102
- res = api_request('private.request.getCategories', 'GET')
103
- res = JSON.parse(res)['category'] rescue []
104
-
105
- unless args[:include_deleted] and args[:include_deleted] == true
106
- res.reject!{|k, v| v['fDeleted'] == '1'} rescue []
107
- end
108
-
109
- return res
110
- end
111
-
112
- # Returns an array of non-deleted categories, as key value pairs. Useful for select lists.
113
- #
114
- # == Authentication
115
- # This method does require authentication.
116
- #
117
- def category_key_value_pairs
118
- categories.collect{|k,v| [k,v['sCategory']]} rescue []
119
- end
120
-
121
- # Returns non-deleted categories, with a list of predefined categories removed
122
- #
123
- def category_key_value_pairs_without(categories=nil)
124
- categories ||= @config['hidden_categories'] rescue nil
125
-
126
- orig_categories = category_key_value_pairs
127
- if categories
128
- categories.each do |category|
129
- orig_categories.reject!{|i| i[1] == category}
130
- end
131
- end
132
- orig_categories
133
- end
134
-
135
- # Returns an array of forums
136
- #
137
- def forums_list
138
- JSON.parse(HelpSpot.api_request('forums.list'))['forum'] rescue []
139
- end
140
-
141
- # Returns an array of forums
142
- #
143
- # == Options
144
- # * forum_id
145
- # The numeric id of the forum you want.
146
- def forum_get(args)
147
- JSON.parse(HelpSpot.api_request('forums.get', 'GET', :xForumId => args[:forum_id])) rescue []
1
+ require 'hashie'
2
+ require 'httparty'
3
+ require 'help_spot/version'
4
+
5
+ class HelpSpot
6
+ include HTTParty
7
+ format :xml
8
+ mattr_inheritable :base
9
+
10
+ def initialize(base, user, pass)
11
+ self.class.base_uri base
12
+ self.class.basic_auth user, pass
13
+ end
14
+
15
+ # Verify authentication credentials
16
+ #
17
+ def authenticated?
18
+ version = api_request(:get, 'private.version')
19
+ return false if version.errors
20
+ return true if version.results.version
21
+ false
22
+ end
23
+
24
+ def create_request(options = {})
25
+ raise ArgumentError unless options[:tNote] && options[:xCategory]
26
+ raise ArgumentError unless options[:sFirstName] || options[:sLastName] || options[:sUserId] || options[:sEmail] || options[:sPhone]
27
+ api_request(:post, 'private.request.create', options, :item => 'request').xRequest.to_i
28
+ end
29
+
30
+ def update_request(id, options = {})
31
+ api_request(:post, 'private.request.update', options.merge(:xRequest => id), :item => 'request').xRequest.to_i
32
+ end
33
+
34
+ def request(id, options = {})
35
+ response = api_request(:get, 'private.request.get', options.merge(:xRequest => id), :item => 'request')
36
+ #munge even further the request history
37
+ response.request_history = response.request_history.map { |item| item[1].first }
38
+ response
39
+ end
40
+
41
+ def search_requests(options = {})
42
+ api_request(:get, 'private.request.search', options, {:collection => 'requests', :item => 'request'})
43
+ end
44
+
45
+ def categories
46
+ api_request(:get, 'private.request.getCategories', {:fDeleted => 0}, {:collection => 'categories', :item => 'category'})
47
+ end
48
+
49
+ def status_types
50
+ api_request(:get, 'private.request.getStatusTypes', {:fActiveOnly => 1}, {:collection => 'results', :item => 'status'})
51
+ end
52
+
53
+ def custom_fields(options = {})
54
+ api_request(:get, 'private.request.getCustomFields', options, {:collection => 'customfields', :item => 'field'})
55
+ end
56
+
57
+ def filter(id, options = {})
58
+ api_request(:get, 'private.filter.get', options.merge(:xFilter => id), {:collection => 'filter', :item => 'request'})
59
+ end
60
+
61
+ private
62
+
63
+ def api_request(http_method, method, options = {}, munge_options = {})
64
+ parsed_options = {}
65
+ if http_method == :get
66
+ parsed_options[:query] = options
67
+ else
68
+ parsed_options[:query] = {}
69
+ parsed_options[:body] = options
148
70
  end
149
-
150
- # Returns an array of topics from a given forum
151
- #
152
- # == Options
153
- # * forum_id
154
- # The numeric id of the forum you want.
155
- # * start
156
- # record set position to start at
157
- # * length
158
- # how many records to return
159
- #
160
- def forum_get_topics(args={})
161
- JSON.parse(HelpSpot.api_request('forums.getTopics', 'GET', {:xForumId => args[:forum_id]}.merge(args)))['topic'] rescue []
162
- end
163
-
164
- # Returns an array of posts from a given topic
165
- #
166
- # == Options
167
- # * topic_id
168
- # The numeric id of the topic
169
- #
170
- def forum_get_topic_posts(args={})
171
- JSON.parse(HelpSpot.api_request('forums.getPosts', 'GET', :xTopicId => args[:topic_id]))['post'] rescue []
172
- end
173
-
174
- def api_request(api_method, http_method='POST', args={})
175
- api_params = {:method => api_method, :output => 'json'}.merge(args)
176
- query_params = api_params.collect{|k,v| [k.to_s, v.to_s]} # [URI.encode(k.to_s),URI.encode(v.to_s.gsub(/\ /, '+'))]
177
- built_query = query_params.collect{|i| i.join('=')}.join('&') # make a query string
178
-
179
- ru = URI::parse(@config['root_url']) # where ru = ROOT_URL
180
- merged_query = [built_query, (ru.query == '' ? nil : ru.query)].compact.join('&') # merge our generated query string with the ROOT_URL's query string
181
-
182
- url = URI::HTTP.new(ru.scheme, ru.userinfo, ru.host, ru.port, ru.registry, ru.path, ru.opaque, merged_query, ru.fragment)
183
-
184
- request = nil
185
- if http_method == 'POST'
186
- request = Net::HTTP::Post.new(url.path)
187
- request.set_form_data(query_params)
71
+ parsed_options[:query].merge!(:method => method)
72
+ response = self.class.send(http_method, '/index.php', parsed_options)
73
+ if munge_options[:collection]
74
+ return [] unless collection = response[munge_options[:collection]][munge_options[:item]]
75
+ if collection.is_a?(Array)
76
+ collection.map { |item| Hashie::Mash.new(item) }
188
77
  else
189
- request = Net::HTTP::Get.new(url.path+'?'+url.query)
78
+ Hashie::Mash.new(collection)
190
79
  end
191
- request.basic_auth @config['username'], @config['password']
192
- http = Net::HTTP.new(url.host, url.port)
193
- http.use_ssl = (url.scheme == 'https')
194
- response = http.start { |h| h.request(request) }
195
-
196
- response.body
80
+ elsif munge_options[:item]
81
+ Hashie::Mash.new(response[munge_options[:item]])
82
+ else
83
+ Hashie::Mash.new(response)
197
84
  end
85
+ end
198
86
 
199
- end # class
200
- end # module
87
+ end
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <errors>
3
+ <error>
4
+ <id>2</id>
5
+ <description>User authentication failed</description>
6
+ </error>
7
+ </errors>
@@ -0,0 +1,53 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <filter>
3
+ <request>
4
+ <xRequest>12624</xRequest>
5
+ <fOpenedVia>Email</fOpenedVia>
6
+ <xOpenedViaId>Customer.Service</xOpenedViaId>
7
+ <xPersonOpenedBy />
8
+ <xPersonAssignedTo>Henry Yount</xPersonAssignedTo>
9
+ <fOpen>1</fOpen>
10
+ <xStatus>Active</xStatus>
11
+ <fUrgent>0</fUrgent>
12
+ <xCategory>Feature Request</xCategory>
13
+ <dtGMTOpened>July 12, 2007</dtGMTOpened>
14
+ <dtGMTClosed />
15
+ <sRequestPassword>pgupzu</sRequestPassword>
16
+ <sTitle>Upload documents over 1gig</sTitle>
17
+ <sUserId>8389332</sUserId>
18
+ <sFirstName>Harry</sFirstName>
19
+ <sLastName>Waterman</sLastName>
20
+ <sEmail>hw@example.com</sEmail>
21
+ <sPhone>845.555.1234</sPhone>
22
+ <iLastReplyBy>0</iLastReplyBy>
23
+ <fTrash>0</fTrash>
24
+ <dtGMTTrashed />
25
+ <fullname>Harry Waterman</fullname>
26
+ <tNote>I would like to be able to upload documents over 1 gigabyte.</tNote>
27
+ </request>
28
+ <request>
29
+ <xRequest>12451</xRequest>
30
+ <fOpenedVia>Phone</fOpenedVia>
31
+ <xOpenedViaId />
32
+ <xPersonOpenedBy>Tiffany Prince</xPersonOpenedBy>
33
+ <xPersonAssignedTo>Henry Yount</xPersonAssignedTo>
34
+ <fOpen>0</fOpen>
35
+ <xStatus>Problem Solved</xStatus>
36
+ <fUrgent>0</fUrgent>
37
+ <xCategory>Feature Request</xCategory>
38
+ <dtGMTOpened>September 19, 2007</dtGMTOpened>
39
+ <dtGMTClosed>September 30, 2007</dtGMTClosed>
40
+ <sRequestPassword>vyzfua</sRequestPassword>
41
+ <sTitle>Improved searching</sTitle>
42
+ <sUserId />
43
+ <sFirstName>Sarah</sFirstName>
44
+ <sLastName>Ryan</sLastName>
45
+ <sEmail />
46
+ <sPhone />
47
+ <iLastReplyBy>0</iLastReplyBy>
48
+ <fTrash>0</fTrash>
49
+ <dtGMTTrashed />
50
+ <fullname>Sarah Ryan</fullname>
51
+ <tNote>I would like to see the searching imrpoved in the upcoming release.</tNote>
52
+ </request>
53
+ </filter>
@@ -0,0 +1,89 @@
1
+ <request>
2
+ <xRequest>12745</xRequest>
3
+ <fOpenedVia>Web Service</fOpenedVia>
4
+ <xOpenedViaId>0</xOpenedViaId>
5
+ <xPersonOpenedBy />
6
+ <xPersonAssignedTo>Ian Landsman</xPersonAssignedTo>
7
+ <fOpen>1</fOpen>
8
+ <xStatus>Active</xStatus>
9
+ <fUrgent>0</fUrgent>
10
+ <xCategory>Bugs</xCategory>
11
+ <dtGMTOpened>September 24, 2007</dtGMTOpened>
12
+ <dtGMTClosed />
13
+ <sRequestPassword>itetxb</sRequestPassword>
14
+ <sTitle />
15
+ <sUserId>12345</sUserId>
16
+ <sFirstName />
17
+ <sLastName />
18
+ <sEmail />
19
+ <sPhone />
20
+ <iLastReplyBy>Ian Landsman</iLastReplyBy>
21
+ <fTrash>0</fTrash>
22
+ <dtGMTTrashed />
23
+ <fullname> </fullname>
24
+ <request_history>
25
+ <item>
26
+ <xRequestHistory>1378</xRequestHistory>
27
+ <xRequest>12745</xRequest>
28
+ <xPerson>Ian Landsman</xPerson>
29
+ <dtGMTChange>Tue, September 25, 2007, 11:00 AM</dtGMTChange>
30
+ <fPublic>1</fPublic>
31
+ <fInitial>0</fInitial>
32
+ <tLog />
33
+ <tNote><p>An HTML note example</p></tNote>
34
+ <tEmailHeaders />
35
+ <fNoteIsHTML>1</fNoteIsHTML>
36
+ <fMergedFromRequest>0</fMergedFromRequest>
37
+ <files>
38
+ <file>
39
+ <sFileMimeType>application/pdf</sFileMimeType>
40
+ <sFilename>Invoice.pdf</sFilename>
41
+ <xDocumentId>60</xDocumentId>
42
+ <public_url>http://www.domain.com/index.php?pg=file&from=3&id=60&reqid=12745&reqhisid=1378</public_url>
43
+ <private_url>http://www.domain.com/admin.php?pg=file&from=0&id=60&showfullsize=1&download=1</private_url>
44
+ </file>
45
+ </files>
46
+ </item>
47
+ <item>
48
+ <xRequestHistory>1377</xRequestHistory>
49
+ <xRequest>12745</xRequest>
50
+ <xPerson>Ian Landsman</xPerson>
51
+ <dtGMTChange>Tue, September 25, 2007, 11:00 AM</dtGMTChange>
52
+ <fPublic>0</fPublic>
53
+ <fInitial>0</fInitial>
54
+ <tLog>Category changed from "" to "Bugs"</tLog>
55
+ <tNote />
56
+ <tEmailHeaders />
57
+ <fNoteIsHTML>0</fNoteIsHTML>
58
+ <fMergedFromRequest>0</fMergedFromRequest>
59
+ </item>
60
+ <item>
61
+ <xRequestHistory>1376</xRequestHistory>
62
+ <xRequest>12745</xRequest>
63
+ <xPerson> </xPerson>
64
+ <dtGMTChange>Mon, September 24, 2007, 08:03 PM</dtGMTChange>
65
+ <fPublic>1</fPublic>
66
+ <fInitial>0</fInitial>
67
+ <tLog />
68
+ <tNote>Plain text update to the request.</tNote>
69
+ <tEmailHeaders />
70
+ <fNoteIsHTML>0</fNoteIsHTML>
71
+ <fMergedFromRequest>0</fMergedFromRequest>
72
+ <files />
73
+ </item>
74
+ <item>
75
+ <xRequestHistory>1375</xRequestHistory>
76
+ <xRequest>12745</xRequest>
77
+ <xPerson> </xPerson>
78
+ <dtGMTChange>Mon, September 24, 2007, 07:44 PM</dtGMTChange>
79
+ <fPublic>1</fPublic>
80
+ <fInitial>1</fInitial>
81
+ <tLog />
82
+ <tNote>This is the request.</tNote>
83
+ <tEmailHeaders />
84
+ <fNoteIsHTML>0</fNoteIsHTML>
85
+ <fMergedFromRequest>0</fMergedFromRequest>
86
+ <files />
87
+ </item>
88
+ </request_history>
89
+ </request>
@@ -0,0 +1,46 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <categories>
3
+ <category>
4
+ <xCategory>1</xCategory>
5
+ <sCategory>Pre Sales Question</sCategory>
6
+ <fDeleted>0</fDeleted>
7
+ <fAllowPublicSubmit>1</fAllowPublicSubmit>
8
+ <xPersonDefault>1</xPersonDefault>
9
+ <fAutoAssignTo>0</fAutoAssignTo>
10
+ <sPersonList>
11
+ <person>
12
+ <xPerson>3</xPerson>
13
+ <fullname>Steve Benson</fullname>
14
+ <assigned_requests>6</assigned_requests>
15
+ </person>
16
+ <person>
17
+ <xPerson>4</xPerson>
18
+ <fullname>Tiffany Prince</fullname>
19
+ <assigned_requests>7</assigned_requests>
20
+ </person>
21
+ <person>
22
+ <xPerson>5</xPerson>
23
+ <fullname>Henry Yount</fullname>
24
+ <assigned_requests>8</assigned_requests>
25
+ </person>
26
+ </sPersonList>
27
+ <sCustomFieldList>
28
+ <xCustomField>2</xCustomField>
29
+ <xCustomField>13</xCustomField>
30
+ </sCustomFieldList>
31
+ <reportingTags>
32
+ <tag>
33
+ <xReportingTag>5</xReportingTag>
34
+ <sReportingTag>Pricing</sReportingTag>
35
+ </tag>
36
+ <tag>
37
+ <xReportingTag>9</xReportingTag>
38
+ <sReportingTag>Support Options</sReportingTag>
39
+ </tag>
40
+ <tag>
41
+ <xReportingTag>7</xReportingTag>
42
+ <sReportingTag>System Requirements</sReportingTag>
43
+ </tag>
44
+ </reportingTags>
45
+ </category>
46
+ </categories>
@@ -0,0 +1,52 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <customfields>
3
+ <field>
4
+ <xCustomField>10</xCustomField>
5
+ <fieldName>Ajax Lookup</fieldName>
6
+ <isRequired>1</isRequired>
7
+ <isPublic>0</isPublic>
8
+ <fieldType>ajax</fieldType>
9
+ <iOrder>0</iOrder>
10
+ <sTxtSize />
11
+ <lrgTextRows />
12
+ <listItems />
13
+ <iDecimalPlaces>0</iDecimalPlaces>
14
+ <sRegex />
15
+ <sAjaxUrl>http://www.domain.com/ajax_field_lookup.php</sAjaxUrl>
16
+ <isAlwaysVisible>0</isAlwaysVisible>
17
+ </field>
18
+ <field>
19
+ <xCustomField>7</xCustomField>
20
+ <fieldName>VIP Customer</fieldName>
21
+ <isRequired>0</isRequired>
22
+ <isPublic>1</isPublic>
23
+ <fieldType>checkbox</fieldType>
24
+ <iOrder>0</iOrder>
25
+ <sTxtSize />
26
+ <lrgTextRows />
27
+ <listItems />
28
+ <iDecimalPlaces>0</iDecimalPlaces>
29
+ <sRegex />
30
+ <sAjaxUrl />
31
+ <isAlwaysVisible>0</isAlwaysVisible>
32
+ </field>
33
+ <field>
34
+ <xCustomField>2</xCustomField>
35
+ <fieldName>Database Type</fieldName>
36
+ <isRequired>0</isRequired>
37
+ <isPublic>1</isPublic>
38
+ <fieldType>select</fieldType>
39
+ <iOrder>0</iOrder>
40
+ <sTxtSize />
41
+ <lrgTextRows />
42
+ <listItems>
43
+ <item>MySQL</item>
44
+ <item>MS SQL Server</item>
45
+ <item>PostgreSQL</item>
46
+ </listItems>
47
+ <iDecimalPlaces>0</iDecimalPlaces>
48
+ <sRegex />
49
+ <sAjaxUrl />
50
+ <isAlwaysVisible>0</isAlwaysVisible>
51
+ </field>
52
+ </customfields>
@@ -0,0 +1,35 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <results>
3
+ <status>
4
+ <sStatus>Active</sStatus>
5
+ <xStatus>1</xStatus>
6
+ </status>
7
+ <status>
8
+ <sStatus>Problem Solved</sStatus>
9
+
10
+ <xStatus>3</xStatus>
11
+ </status>
12
+ <status>
13
+ <sStatus>Not Fixable</sStatus>
14
+ <xStatus>4</xStatus>
15
+ </status>
16
+ <status>
17
+
18
+ <sStatus>Customer Unreachable</sStatus>
19
+ <xStatus>5</xStatus>
20
+ </status>
21
+ <status>
22
+ <sStatus>Customer Found Solution</sStatus>
23
+ <xStatus>6</xStatus>
24
+ </status>
25
+
26
+ <status>
27
+ <sStatus>Software Bug</sStatus>
28
+ <xStatus>7</xStatus>
29
+ </status>
30
+ <status>
31
+ <sStatus>SPAM</sStatus>
32
+ <xStatus>2</xStatus>
33
+
34
+ </status>
35
+ </results>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <request>
3
+ <xRequest>12746</xRequest>
4
+ </request>
@@ -0,0 +1,52 @@
1
+ <requests>
2
+ <request>
3
+ <xRequest>12650</xRequest>
4
+ <fOpenedVia>Phone</fOpenedVia>
5
+ <xOpenedViaId>0</xOpenedViaId>
6
+ <xPersonOpenedBy>Ian Landsman</xPersonOpenedBy>
7
+ <xPersonAssignedTo>Ian Landsman</xPersonAssignedTo>
8
+ <fOpen>1</fOpen>
9
+ <xStatus>Active</xStatus>
10
+ <fUrgent>1</fUrgent>
11
+ <xCategory>Bugs</xCategory>
12
+ <dtGMTOpened>January 16, 2006</dtGMTOpened>
13
+ <dtGMTClosed />
14
+ <sRequestPassword>oxvgys</sRequestPassword>
15
+ <sTitle>RE: Update on Your Request</sTitle>
16
+ <sUserId />
17
+ <sFirstName />
18
+ <sLastName>landsman</sLastName>
19
+ <sEmail />
20
+ <sPhone />
21
+ <iLastReplyBy>0</iLastReplyBy>
22
+ <fTrash>0</fTrash>
23
+ <dtGMTTrashed />
24
+ <fullname> landsman</fullname>
25
+ <tNote><span class="initsubject">Some text here</span> - Help with printer issue please.</tNote>
26
+ </request>
27
+ <request>
28
+ <xRequest>12733</xRequest>
29
+ <fOpenedVia>Web Service</fOpenedVia>
30
+ <xOpenedViaId>0</xOpenedViaId>
31
+ <xPersonOpenedBy />
32
+ <xPersonAssignedTo>Ian Landsman</xPersonAssignedTo>
33
+ <fOpen>1</fOpen>
34
+ <xStatus>Active</xStatus>
35
+ <fUrgent>0</fUrgent>
36
+ <xCategory>Bugs</xCategory>
37
+ <dtGMTOpened>September 13, 2007</dtGMTOpened>
38
+ <dtGMTClosed />
39
+ <sRequestPassword>bwpkqv</sRequestPassword>
40
+ <sTitle />
41
+ <sUserId>567</sUserId>
42
+ <sFirstName />
43
+ <sLastName />
44
+ <sEmail />
45
+ <sPhone />
46
+ <iLastReplyBy>0</iLastReplyBy>
47
+ <fTrash>0</fTrash>
48
+ <dtGMTTrashed />
49
+ <fullname> </fullname>
50
+ <tNote><span class="initsubject">Text Here</span> - Need printer assistance.</tNote>
51
+ </request>
52
+ </requests>
@@ -0,0 +1,4 @@
1
+ <results>
2
+ <version>1.3</version>
3
+ <min_version>1.0</min_version>
4
+ </results>
@@ -1,7 +1,87 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe "HelpSpot" do
4
- it "fails" do
5
- fail "hey buddy, you should probably rename this file and start specing for real"
4
+ it "should provide a version constant" do
5
+ HelpSpot::VERSION.should be_instance_of(String)
6
6
  end
7
- end
7
+ before :each do
8
+ @help_spot = HelpSpot.new("https://support.local/api/", "foobar@localhost.com", "sekrit")
9
+ end
10
+ describe "verifying authentcation" do
11
+ it "returns true when properly authenticated" do
12
+ @help_spot.stub_get('/api/index.php?method=private.version', 'version.xml')
13
+ @help_spot.authenticated?.should be_true
14
+ end
15
+ it "returns false when not properly authenticated" do
16
+ @help_spot.stub_http_response_with('error.xml')
17
+ @help_spot.authenticated?.should be_false
18
+ end
19
+ end
20
+
21
+ describe 'requests' do
22
+ describe "being created" do
23
+ before(:each) do
24
+ @help_spot.stub_post('/api/index.php?method=private.request.create', 'request.id.xml')
25
+ end
26
+ it "require a note, a category, and some contact info" do
27
+ lambda { @help_spot.create_request() }.should raise_exception
28
+ lambda { @help_spot.create_request(:tNote => 'foo') }.should raise_exception
29
+ lambda { @help_spot.create_request(:xCategory => 1) }.should raise_exception
30
+ lambda { @help_spot.create_request(:tNote => 'foo', :xCategory => 1) }.should raise_exception
31
+ %w(sFirstName sLastName sUserId sEmail sPhone).each do |valid_contact_info|
32
+ lambda { @help_spot.create_request(:tNote => 'foo', :xCategory => 1, valid_contact_info.intern => 'foo') }.should_not raise_exception
33
+ end
34
+ end
35
+ it "return the request id" do
36
+ @help_spot.create_request(:tNote => 'foo', :xCategory => 1, :sEmail => 'needy@customer.com').should == 12746
37
+ end
38
+ end
39
+ describe "being updated" do
40
+ before(:each) do
41
+ @help_spot.stub_post('/api/index.php?method=private.request.update', 'request.id.xml')
42
+ end
43
+ it "return the request id" do
44
+ @help_spot.update_request(12746, :tNote => 'foo', :xCategory => 1, :sEmail => 'needy@customer.com').should == 12746
45
+ end
46
+ end
47
+ it "should be accessible" do
48
+ @help_spot.stub_get('/api/index.php?method=private.request.get&xRequest=12745', 'request.get.xml')
49
+ request = @help_spot.request(12745)
50
+ request.xPersonAssignedTo.should == 'Ian Landsman'
51
+ request.request_history.first.xPerson.should == 'Ian Landsman'
52
+ end
53
+ it "should be searchable" do
54
+ @help_spot.stub_get('/api/index.php?method=private.request.search&sSearch=printer', 'request.search.xml')
55
+ requests = @help_spot.search_requests(:sSearch => 'printer')
56
+ requests.first.xPersonAssignedTo.should == 'Ian Landsman'
57
+ end
58
+ end
59
+ describe 'categories' do
60
+ it "can be listed" do
61
+ @help_spot.stub_get('/api/index.php?method=private.request.getCategories&fDeleted=0', 'request.getCategories.xml')
62
+ categories = @help_spot.categories
63
+ categories.sCategory.should == 'Pre Sales Question'
64
+ end
65
+ end
66
+ describe 'statuses' do
67
+ it "can be listed" do
68
+ @help_spot.stub_get('/api/index.php?method=private.request.getStatusTypes&fActiveOnly=1', 'request.getStatusTypes.xml')
69
+ statues = @help_spot.status_types
70
+ statues.first.sStatus.should == 'Active'
71
+ end
72
+ end
73
+ describe 'custom fields' do
74
+ it "can be listed" do
75
+ @help_spot.stub_get('/api/index.php?method=private.request.getCustomFields', 'request.getCustomFields.xml')
76
+ fields = @help_spot.custom_fields
77
+ fields.first.fieldName.should == 'Ajax Lookup'
78
+ end
79
+ end
80
+ describe 'filters' do
81
+ it "can have their requests retrieved" do
82
+ @help_spot.stub_get('/api/index.php?method=private.filter.get&xFilter=1234', 'filter.get.xml')
83
+ requests = @help_spot.filter(1234)
84
+ requests.first.tNote.should == 'I would like to be able to upload documents over 1 gigabyte.'
85
+ end
86
+ end
87
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --backtrace
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,52 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__))
2
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
1
  require 'help_spot'
4
2
  require 'spec'
5
3
  require 'spec/autorun'
4
+ require 'fakeweb'
6
5
 
7
- Spec::Runner.configure do |config|
8
-
9
- end
6
+ FakeWeb.allow_net_connect = false
7
+
8
+ class HelpSpot
9
+
10
+ def help_spot_url(path)
11
+ uri = URI.parse(self.class.default_options[:base_uri])
12
+ uri.path, uri.query = path.split('?')
13
+ uri.userinfo = "#{self.class.default_options[:basic_auth][:username]}:#{self.class.default_options[:basic_auth][:password]}".gsub(/@/, '%40')
14
+ uri.to_s
15
+ end
16
+
17
+ def file_fixture(filename)
18
+ open(File.join(File.dirname(__FILE__), 'fixtures', "#{filename.to_s}")).read
19
+ end
20
+
21
+ def stub_get(path, filename, status=nil)
22
+ options = {:body => file_fixture(filename)}
23
+ options.merge!({:status => status}) unless status.nil?
24
+ FakeWeb.register_uri(:get, help_spot_url(path), options)
25
+ end
26
+
27
+ def stub_post(path, filename)
28
+ FakeWeb.register_uri(:post, help_spot_url(path), :body => file_fixture(filename))
29
+ end
30
+
31
+ def stub_put(path, filename)
32
+ FakeWeb.register_uri(:put, help_spot_url(path), :body => file_fixture(filename))
33
+ end
34
+
35
+ def stub_delete(path, filename)
36
+ FakeWeb.register_uri(:delete, help_spot_url(path), :body => file_fixture(filename))
37
+ end
38
+
39
+ def stub_http_response_with(filename)
40
+ format = filename.split('.').last.intern
41
+ data = file_fixture(filename)
42
+
43
+ response = Net::HTTPOK.new("1.1", 200, "Content for you")
44
+ response.stub!(:body).and_return(data)
45
+
46
+ http_request = HTTParty::Request.new(Net::HTTP::Get, 'http://localhost', :format => format)
47
+ http_request.stub!(:perform_actual_request).and_return(response)
48
+
49
+ HTTParty::Request.should_receive(:new).at_least(1).and_return(http_request)
50
+ end
51
+
52
+ end
metadata CHANGED
@@ -1,29 +1,58 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: help_spot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
- - Jamie Wilson
8
7
  - Jesse Newland
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
11
 
13
- date: 2009-10-11 00:00:00 -04:00
12
+ date: 2010-01-24 00:00:00 -05:00
14
13
  default_executable:
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: rspec
18
17
  type: :development
19
18
  version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - "="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.3.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: fakeweb
27
+ type: :development
28
+ version_requirement:
20
29
  version_requirements: !ruby/object:Gem::Requirement
21
30
  requirements:
22
31
  - - ">="
23
32
  - !ruby/object:Gem::Version
24
33
  version: "0"
25
34
  version:
26
- description: A package for interacting with UserScape's HelpSpot product.
35
+ - !ruby/object:Gem::Dependency
36
+ name: hashie
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.1.8
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: httparty
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.5.0
54
+ version:
55
+ description: API wrapper for HelpSpot
27
56
  email: jnewland@gmail.com
28
57
  executables: []
29
58
 
@@ -32,17 +61,26 @@ extensions: []
32
61
  extra_rdoc_files:
33
62
  - LICENSE
34
63
  - README.rdoc
64
+ - TODO
35
65
  files:
36
66
  - .gitignore
37
- - History.txt
38
67
  - LICENSE
39
68
  - README.rdoc
40
69
  - Rakefile
41
- - VERSION
42
- - config/help_spot.yml.sample
43
- - help_spot.gemspec
70
+ - TODO
44
71
  - lib/help_spot.rb
72
+ - lib/help_spot/version.rb
73
+ - spec/fixtures/error.xml
74
+ - spec/fixtures/filter.get.xml
75
+ - spec/fixtures/request.get.xml
76
+ - spec/fixtures/request.getCategories.xml
77
+ - spec/fixtures/request.getCustomFields.xml
78
+ - spec/fixtures/request.getStatusTypes.xml
79
+ - spec/fixtures/request.id.xml
80
+ - spec/fixtures/request.search.xml
81
+ - spec/fixtures/version.xml
45
82
  - spec/help_spot_spec.rb
83
+ - spec/spec.opts
46
84
  - spec/spec_helper.rb
47
85
  has_rdoc: true
48
86
  homepage: http://github.com/jnewland/help_spot
@@ -68,10 +106,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
106
  requirements: []
69
107
 
70
108
  rubyforge_project:
71
- rubygems_version: 1.3.3
109
+ rubygems_version: 1.3.5
72
110
  signing_key:
73
111
  specification_version: 3
74
- summary: A package for interacting with UserScape's HelpSpot product.
112
+ summary: API wrapper for HelpSpot
75
113
  test_files:
76
114
  - spec/help_spot_spec.rb
77
115
  - spec/spec_helper.rb
data/History.txt DELETED
@@ -1,14 +0,0 @@
1
- == 0.0.2 2009-10-11
2
-
3
- * Add to SSL
4
- * Release to Gemcutter
5
-
6
- == 0.0.1.4 2009-02-09
7
-
8
- * Pushed to github
9
-
10
- == 0.0.1 2009-01-05
11
-
12
- * 1 major enhancement:
13
- * Initial release
14
-
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.0.2
@@ -1,6 +0,0 @@
1
- root_url: http://www.example.com/helpspot/api/index.php?format=json
2
- username: helpspot_user@example.com
3
- password: my_p@ssw0rd
4
- hidden_categories:
5
- - Deactivations
6
- - 'Contact Us'
data/help_spot.gemspec DELETED
@@ -1,54 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE
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{help_spot}
8
- s.version = "0.0.2"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Jamie Wilson", "Jesse Newland"]
12
- s.date = %q{2009-10-11}
13
- s.description = %q{A package for interacting with UserScape's HelpSpot product.}
14
- s.email = %q{jnewland@gmail.com}
15
- s.extra_rdoc_files = [
16
- "LICENSE",
17
- "README.rdoc"
18
- ]
19
- s.files = [
20
- ".gitignore",
21
- "History.txt",
22
- "LICENSE",
23
- "README.rdoc",
24
- "Rakefile",
25
- "VERSION",
26
- "config/help_spot.yml.sample",
27
- "help_spot.gemspec",
28
- "lib/help_spot.rb",
29
- "spec/help_spot_spec.rb",
30
- "spec/spec_helper.rb"
31
- ]
32
- s.homepage = %q{http://github.com/jnewland/help_spot}
33
- s.rdoc_options = ["--charset=UTF-8"]
34
- s.require_paths = ["lib"]
35
- s.rubygems_version = %q{1.3.3}
36
- s.summary = %q{A package for interacting with UserScape's HelpSpot product.}
37
- s.test_files = [
38
- "spec/help_spot_spec.rb",
39
- "spec/spec_helper.rb"
40
- ]
41
-
42
- if s.respond_to? :specification_version then
43
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
44
- s.specification_version = 3
45
-
46
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
47
- s.add_development_dependency(%q<rspec>, [">= 0"])
48
- else
49
- s.add_dependency(%q<rspec>, [">= 0"])
50
- end
51
- else
52
- s.add_dependency(%q<rspec>, [">= 0"])
53
- end
54
- end