klink-ruby-api 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,522 @@
1
+ # = Introduction
2
+ # The Klink Ruby API is a Ruby wrapper library to be used with a Klink web server. It provides a simple, easy to use
3
+ # llbrary of methods to access data and other information from a Remedy server.
4
+ #
5
+
6
+ require 'net/http'
7
+ require 'uri'
8
+ require 'rexml/document'
9
+ require 'yaml'
10
+ include REXML
11
+
12
+
13
+ module Kinetic
14
+ # Represents a connection to a Klink server.
15
+ class Link
16
+
17
+ Kinetic::Link::VERSION = '1.0.6'
18
+
19
+ @@link_api_version = "Kinetic Link #{Kinetic::Link::VERSION}"
20
+
21
+ # required connection information to connect to an ar_server via klink
22
+ @@user = nil
23
+ @@password = nil
24
+ @@klink_server = nil
25
+ @@ar_server = nil
26
+
27
+ # initialize to false
28
+ # set to connected once we have all the info needed to connect
29
+ @@connected = false
30
+
31
+ # TODO - Remove this function???
32
+ # Is this the right place for it to be?
33
+ # (Renamed - to see if anything else breaks)
34
+ # Max 30 chars unique
35
+ # can return less than 30 chars
36
+ # currently only numbers
37
+ # TODO - include alpha with case
38
+ # currently 10^30 uniques
39
+ # with mixed alpha 62^30
40
+ # possibly use sha1
41
+ def self.xxxget_guid
42
+ return (rand.to_s.split('.')[1].to_s + rand.to_s.split('.')[1].to_s).slice(0,30)
43
+ end
44
+
45
+ # setup connection info
46
+ # Example: Demo,"","klinkserver:8081.yourcompany.com,remedy.yourcompany.com
47
+ # TODO -- add AR Server port??? -- how does that work with Klink?
48
+ def self.set_connection(user,password,klink_server,ar_server)
49
+ @@user = user
50
+ @@password = password
51
+ @@klink_server = klink_server
52
+ @@ar_server = ar_server
53
+ end
54
+
55
+ # return true false, if false also return a message of how it failed
56
+ # get a list of forms - if that works - all is well
57
+ # all servers have some sort of form available to public
58
+ def self.test_connection
59
+ # This block tests the connection to the klink server alone
60
+ begin
61
+ html = Net::HTTP.get(URI.parse("http://#{@@klink_server}/klink/about"))
62
+ raise unless html =~ /<a href="http:\/\/www\.kineticdata\.com">/
63
+ rescue
64
+ return false, %`Could not connect to the specified Kinetic Link server "#{@@klink_server}"`
65
+ end
66
+ # This block tests the connection to the klink server and the remedy server
67
+ # by attempting to retrieve data from the remedy server through klink
68
+ begin
69
+ if(self.structures.length > 0) then
70
+ return true
71
+ else
72
+ return false, %`Could not find any forms on server "#{@@ar_server}"`
73
+ end
74
+ rescue Timeout::Error
75
+ return false, %`Timeout occured when attempting to retrieve data from server "#{@@ar_server}"`
76
+ rescue
77
+ return false, %`Exception raised when attempting to retrieve data from server "#{@@ar_server}"`
78
+ end
79
+ end
80
+
81
+ # connect if possible return status of connection
82
+ def self.establish_connection
83
+ if(@@ar_server == nil) then
84
+
85
+ # TODO - grab this from somewhere
86
+ environment = $klink_env
87
+
88
+ raise "No environment set" if(environment == nil)
89
+
90
+ # TODO - assumes it finds a file
91
+ klink_config = YAML::load_file(
92
+ File.expand_path(File.join(".",'klink.yml')))
93
+
94
+ begin
95
+ @@user=klink_config[environment]['user']
96
+ @@password=klink_config[environment]['password']
97
+ @@klink_server=klink_config[environment]['klink_server']
98
+ @@ar_server=klink_config[environment]['ar_server']
99
+ rescue
100
+ raise "Problem reading environment: #{$klink_env}"
101
+ end
102
+
103
+
104
+ end
105
+
106
+ # Temp set to true
107
+ @@connected = true
108
+
109
+ # Set to actual
110
+ @@connected = self.test_connection
111
+
112
+
113
+ return true
114
+ end
115
+
116
+ # delete record with id from the form
117
+ def self.delete(form_name, request_id)
118
+ self.establish_connection if @@connected == false
119
+
120
+ uri = URI.escape("http://#{@@klink_server}/klink/delete/#{@@user}:#{@@password}@#{@@ar_server}/#{form_name}/#{request_id}")
121
+
122
+ response = Net::HTTP.get(URI.parse(uri))
123
+ xmldoc = Document.new response
124
+
125
+ ret_val = nil
126
+ error = nil
127
+
128
+ xmldoc.elements.each('Response') { |entry_item|
129
+ ret_val = entry_item.attributes['Success']
130
+ if ret_val == 'false' then
131
+ xmldoc.elements.each('Response/Messages/Message') {|error_item|
132
+ if error_item.attributes['MessageNumber'] == '302'
133
+ then error = '302' # Record does not exist
134
+ end
135
+ }
136
+ end
137
+ }
138
+
139
+ # 302 == <Message MessageNumber="302" Type="ERROR">Entry does not exist in database</Message>
140
+ raise response.to_s if (ret_val == "false" && error != '302')
141
+
142
+ return ret_val
143
+
144
+ end
145
+
146
+ # Finds the entry on the form identified by the request_id parameter. If the fields parameter is specified,
147
+ # only those fields will be retrieved from the form. There can be a noticeable performance gain when
148
+ # retrieving only a subset of fields from large forms.
149
+ #
150
+ # - form_name - the name of the form to retrieve records from
151
+ # - request_id - the value of the Request ID field for the record to be retrieved
152
+ # - fields - an optional list (Array, or comma-separated String) of field ids to retrieve (default is all fields)
153
+ #
154
+ # Returns a hash that represents the record. The hash contains a mapping of fields id to field value for each field specified.
155
+ #
156
+ def self.entry(form_name, request_id, fields = nil)
157
+ self.establish_connection if @@connected == false
158
+
159
+ # build up the string of field ids to return
160
+ fields ||= ''
161
+ fields = fields.join(",") if fields.is_a? Array
162
+ fields.gsub!(' ', '')
163
+ field_list = "?items=#{fields}" unless fields.nil? || fields.empty?
164
+
165
+ uri = URI.escape("http://#{@@klink_server}/klink/entry/#{@@user}:#{@@password}@#{@@ar_server}/#{form_name}/#{request_id}#{field_list}")
166
+
167
+ response = Net::HTTP.get(URI.parse(uri))
168
+ xmldoc = Document.new(response)
169
+
170
+ ret_val = Hash.new
171
+
172
+ # TODO -- handle 'Status History' -- right now I just convert to ''
173
+ xmldoc.elements.each('Response/Result/Entry/EntryItem') { |entry_item|
174
+ ret_val[entry_item.attributes['ID']] = entry_item.text || ''
175
+ }
176
+
177
+ return ret_val
178
+
179
+ end
180
+
181
+ # Finds all the records from a form that match the qualification. If only a subset of fields on the form
182
+ # should be returned, please see the entries_with_fields method.
183
+ #
184
+ # - form_name - the name of the form to retrieve records from
185
+ # - qual - an optional qualification used to select the records: i.e. "1=1"
186
+ # - sort - an optional list (Array, or comma-separated String) of field ids to sort the results
187
+ #--
188
+ # TODO: Add sort order (ASC | DESC)
189
+ #++
190
+ # Returns an array of Request IDs of the records on the form that match the qualification, sorted in the order specified with the sort parameter.
191
+ #
192
+ def self.entries(form_name, qual = nil, sort = nil)
193
+ self.establish_connection if @@connected == false
194
+
195
+ qual ||= ''
196
+ qualification = "?qualification=#{qual}"
197
+
198
+ sort ||= ''
199
+ sort = options.join(",") if sort.is_a? Array
200
+ sort.gsub!(' ', '')
201
+ sort_list = "&sort=#{sort}" unless sort.nil? || sort.empty?
202
+
203
+ uri = URI.escape("http://#{@@klink_server}/klink/entries/#{@@user}:#{@@password}@#{@@ar_server}/#{form_name}#{qualification}#{sort_list}")
204
+
205
+ response = Net::HTTP.get(URI.parse(uri))
206
+ xmldoc = Document.new(response)
207
+
208
+ ret_val = Array.new
209
+
210
+ xmldoc.elements.each('Response/Result/EntryList/Entry') { |id|
211
+ ret_val << id.attributes['ID']
212
+ }
213
+
214
+ return ret_val
215
+
216
+ end
217
+
218
+ # Finds all the records from a form that match the qualification. If the fields option is specified, only those fields will be retrieved from the form.
219
+ # There can be a noticeable performance gain when retrieving only a subset of fields from large forms. If any of the specified fields is a diary
220
+ # field, or a long character field that cannot be returned with ARGetList, the call will silently fall back to retrieving a list of entry ids,
221
+ # then retrieving each entry separately.
222
+ #
223
+ # - form_name - the name of the form to retrieve records from
224
+ # - options - an optional hash of additional parameters to use with the query
225
+ #
226
+ # Available Options
227
+ # - :qual - an optional qualification used to select the records: i.e. "1=1"
228
+ # - :sort - an optional list (Array, or comma-separated String) of field ids to sort the results
229
+ # - :fields - an optional list (Array, or comma-separated String) of field ids to retrieve (default is no fields)
230
+ #--
231
+ # TODO: Add sort order (ASC | DESC)
232
+ #++
233
+ # Returns an array of hashes that represent each record that matched the qualification. Each hash in the array contains a mapping of fields id to field value.
234
+ #
235
+ def self.entries_with_fields(form_name, options = {})
236
+ self.establish_connection if @@connected == false
237
+
238
+ # build up the qualification as the first parameter - not necessary as the first, but we need to include the ? somewhere.
239
+ qual = options[:qual] || ''
240
+ qualification = "?qualification=#{qual}"
241
+
242
+ # build up the string of sort fields
243
+ sort = options[:sort] || ''
244
+ sort = options.join(",") if sort.is_a? Array
245
+ sort.gsub!(' ', '')
246
+ sort_list = "&sort=#{sort}" unless sort.nil? || sort.empty?
247
+
248
+ # build up the string of field ids to return
249
+ fields = options[:fields] || ''
250
+ fields = fields.join(",") if fields.is_a? Array
251
+ fields.gsub!(' ', '')
252
+ field_list = "&items=#{fields}" unless fields.nil? || fields.empty?
253
+
254
+ uri = URI.escape("http://#{@@klink_server}/klink/entries/#{@@user}:#{@@password}@#{@@ar_server}/#{form_name}#{qualification}#{sort_list}#{field_list}")
255
+
256
+ ret_val = Array.new
257
+
258
+ # try to get the results
259
+ begin
260
+ response = Net::HTTP.get(URI.parse(uri))
261
+ xmldoc = Document.new(response)
262
+
263
+ # check if there are any errors retrieving dialry fields or character fields that are too long
264
+ if xmldoc.root.attributes['Success'] == "false"
265
+ message = xmldoc.elements["Response/Messages/Message"]
266
+ message_text = message.text if message
267
+ raise StandardError.new(message_text || "Fall back to retrieving each record individually")
268
+ end
269
+
270
+ xmldoc.elements.each('Response/Result/EntryList/Entry') { |id|
271
+ entry = { '1' => id.attributes['ID'] }
272
+ id.elements.each('EntryItem') { |item_id|
273
+ entry[item_id.attributes['ID']] = item_id.text || ''
274
+ }
275
+ ret_val << entry
276
+ }
277
+ rescue StandardError => e
278
+ # if there was a problem, try to get a list of ids, then retrieve each record individually
279
+ self.entries(form_name, qual, sort).each { |entry_id|
280
+ ret_val << self.entry(form_name, entry_id, fields)
281
+ }
282
+ end
283
+
284
+ return ret_val
285
+ end
286
+
287
+ # return a list of statistics
288
+ # TODO - need to take params
289
+ def self.statistics(items = {})
290
+ self.establish_connection if @@connected == false
291
+
292
+ param_list = "?items=#{items}" if items.size > 0
293
+ uri = URI.escape("http://#{@@klink_server}/klink/statistics/#{@@user}:#{@@password}@#{@@ar_server}#{param_list}")
294
+
295
+ response = Net::HTTP.get(URI.parse(uri))
296
+ xmldoc = Document.new(response)
297
+
298
+ ret_val = Hash.new
299
+
300
+ xmldoc.elements.each('Response/Result/Statistics/Statistic') { |stat|
301
+ ret_val[stat.attributes['Name']]=stat.text ||=''
302
+ }
303
+
304
+ return ret_val
305
+
306
+ end
307
+
308
+ # return a list of configurations
309
+ # TODO - need to take params
310
+ def self.configurations(items = {})
311
+ self.establish_connection if @@connected == false
312
+
313
+ param_list = "?items=#{items}" if items.size > 0
314
+ uri = URI.escape("http://#{@@klink_server}/klink/configurations/#{@@user}:#{@@password}@#{@@ar_server}#{param_list}")
315
+
316
+ response = Net::HTTP.get(URI.parse(uri))
317
+ xmldoc = Document.new(response)
318
+
319
+ ret_val = Hash.new
320
+
321
+ xmldoc.elements.each('Response/Result/Configurations/Configuration') { |conf|
322
+ ret_val[conf.attributes['Name']]=conf.text ||=''
323
+ }
324
+
325
+ return ret_val
326
+
327
+ end
328
+
329
+ # return a list of structures
330
+ def self.structures
331
+ self.establish_connection if @@connected == false
332
+
333
+ uri = URI.escape("http://#{@@klink_server}/klink/structures/#{@@user}:#{@@password}@#{@@ar_server}")
334
+
335
+ response = Net::HTTP.get(URI.parse(uri))
336
+ xmldoc = Document.new(response)
337
+
338
+ ret_val = Array.new
339
+
340
+ xmldoc.elements.each('Response/Result/Structures/Structure') { |structure|
341
+ ret_val << structure.attributes['ID'] ||=''
342
+ }
343
+
344
+ return ret_val
345
+
346
+ end
347
+
348
+ # TODO - make cleaner and make into a library
349
+ # I just never found it in a library
350
+ def self.clean_input(v)
351
+
352
+ new_v = v.is_a?(String) ? v.clone : v
353
+
354
+ if v.class == String then
355
+ new_v.gsub!(/&/, '&amp;')
356
+ new_v.gsub!(/\n/, '&#10;')
357
+ new_v.gsub!(/\r/, '&#13;') # TODO - never tested
358
+ new_v.gsub!(/\</, '&lt;')
359
+ new_v.gsub!(/\>/, '&gt;')
360
+ end
361
+
362
+ return new_v
363
+
364
+ end
365
+
366
+
367
+ def self.structure(form_name)
368
+ self.establish_connection if @@connected == false
369
+
370
+ uri = URI.escape("http://#{@@klink_server}/klink/structure/#{@@user}:#{@@password}@#{@@ar_server}/#{form_name}")
371
+
372
+ response = Net::HTTP.get(URI.parse(uri))
373
+ xmldoc = Document.new(response)
374
+
375
+ structure_map = Hash.new
376
+ xmldoc.elements.each('Response/Result/Structure/StructureItem') { |structure_item|
377
+
378
+ # structure_map[structure_item.attributes['ID']] = structure_item.attributes['Name']
379
+
380
+ name = structure_item.attributes['Name']
381
+ id = structure_item.attributes['ID']
382
+ type = structure_item.attributes['Type'] # DATA/ATTACHMENT
383
+
384
+
385
+ field_hash = Hash.new
386
+
387
+ field_hash["Name"] = name
388
+ field_hash["ID"] = id
389
+ field_hash["Type"] = type
390
+
391
+ structure_item.elements.each('DataType') { |value|
392
+ field_hash["DataType"] = value.text
393
+ }
394
+
395
+ structure_item.elements.each('DefaultValue') { |value|
396
+ field_hash["DefaultValue"] = value.text
397
+ }
398
+
399
+ structure_item.elements.each('EntryMode') { |value|
400
+ field_hash["EntryMode"] = value.text
401
+ }
402
+
403
+ attr = Array.new
404
+ structure_item.elements.each('Attributes/Attribute') { |value|
405
+
406
+ attr << value.text
407
+ }
408
+ field_hash["attributes"] = attr
409
+
410
+
411
+ # TODO - store it by name and by id -- easier to find
412
+ #structure_map[name] = field_hash
413
+ structure_map[id] = field_hash
414
+
415
+ }
416
+ return structure_map
417
+ end
418
+
419
+ def self.build_connection
420
+
421
+ # if port info is included - need to breakup and attach to that port
422
+ if /:/.match(@@klink_server) then
423
+ (location,port) = @@klink_server.split ':'
424
+ http = Net::HTTP.new location, port
425
+ else
426
+ http = Net::HTTP.new @@klink_server
427
+ end
428
+
429
+ end
430
+
431
+ # TODO - return values of more than just ID
432
+ def self.write(form_name, record_id, name_values = nil)
433
+
434
+ self.establish_connection if @@connected == false
435
+
436
+ http = self.build_connection
437
+
438
+ headers = {
439
+ 'Content-Type' => 'application/xml',
440
+ 'User-Agent' => @@link_api_version
441
+ }
442
+
443
+ data = ""
444
+
445
+ if record_id.nil? then
446
+ # create
447
+ data = %|<Entry Structure="#{form_name}">|
448
+ else
449
+ # update
450
+ data = %|<Entry ID="#{record_id}" Structure="#{form_name}">|
451
+ end
452
+
453
+ name_values.each do |n,v|
454
+ if v != nil then
455
+ new_v = Link::clean_input(v)
456
+ data += %|<EntryItem ID="#{n}">#{new_v}</EntryItem>|
457
+ end
458
+ end
459
+
460
+ data += "</Entry>"
461
+
462
+ if record_id.nil? then
463
+ response, data = http.post(URI.escape("/klink/create/#{@@user}:#{@@password}@#{@@ar_server}"), data, headers)
464
+ else
465
+ response, data = http.post(URI.escape("/klink/update/#{@@user}:#{@@password}@#{@@ar_server}"), data, headers)
466
+ end
467
+
468
+ xmldoc = Document.new data
469
+ ret_val = ""
470
+
471
+
472
+ # This is a create - return ID number
473
+ if record_id.nil? then
474
+ xmldoc.elements.each('Response/Result/Entry') { |entry|
475
+ ret_val = entry.attributes['ID'] ||=''
476
+ }
477
+
478
+ raise xmldoc.to_s if ret_val == ''
479
+ return ret_val
480
+ end
481
+
482
+ # Fall through to update -- were we successful in the actual update?
483
+ xmldoc.elements.each('Response') { |entry_item|
484
+ ret_val = entry_item.attributes['Success']
485
+ # TODO - this will not happen as Klink has a bug in updates
486
+ # See Redmine#1179
487
+ if ret_val == 'false' then
488
+ raise xmldoc.to_s
489
+ end
490
+
491
+ if ret_val == 'true' then
492
+
493
+ # Catch bug #1179 -- look for ERROR in message type - if so -- raise an issue
494
+ xmldoc.elements.each('Response/Messages/Message') {|error_item|
495
+ if error_item.attributes['Type'] == 'ERROR' then
496
+ raise xmldoc.to_s
497
+ end
498
+ }
499
+
500
+
501
+ end
502
+
503
+
504
+ }
505
+
506
+
507
+ return true
508
+
509
+ end
510
+
511
+ def self.create(form_name, name_values = nil)
512
+ self.write(form_name, nil, name_values)
513
+ end
514
+
515
+ def self.update(form_name, record_id, name_values = nil)
516
+ x = self.write(form_name, record_id, name_values)
517
+ return x
518
+ end
519
+
520
+ end
521
+
522
+ end
@@ -0,0 +1 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'kinetic', 'link.rb'))
@@ -0,0 +1,68 @@
1
+ require File.dirname(__FILE__) +'/../test_helper'
2
+
3
+
4
+ class ConfigurationsTest < Test::Unit::TestCase
5
+ def test_get_configurations
6
+
7
+ assert_nothing_thrown {
8
+ configs = Kinetic::Link.configurations
9
+
10
+ assert_not_nil configs
11
+ assert_kind_of Hash,configs
12
+
13
+
14
+ }
15
+
16
+
17
+ end
18
+
19
+ def test_get_configuration
20
+
21
+ config_name = "HOSTNAME"
22
+
23
+ assert_nothing_thrown {
24
+ config = Kinetic::Link.configurations(config_name)
25
+
26
+ assert_not_nil config
27
+ assert_kind_of Hash,config
28
+ assert_not_nil config[config_name]
29
+ assert_kind_of String, config[config_name]
30
+
31
+ }
32
+
33
+
34
+ end
35
+
36
+
37
+
38
+
39
+ def test_get_multi_configurations
40
+
41
+ config_name = "HOSTNAME,OPERATING_SYSTEM"
42
+ config_one = "HOSTNAME"
43
+
44
+
45
+ assert_nothing_thrown {
46
+ config = Kinetic::Link.configurations(config_name)
47
+
48
+ assert_not_nil config
49
+ assert_kind_of Hash,config
50
+ assert (config.keys.size == 2)
51
+ assert_not_nil config[config_one]
52
+ assert_kind_of String, config[config_one]
53
+
54
+ }
55
+
56
+
57
+ end
58
+
59
+
60
+
61
+ end
62
+
63
+
64
+
65
+
66
+
67
+
68
+
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) +'/../test_helper'
2
+
3
+ class KineticLink_CreateTest < Test::Unit::TestCase
4
+
5
+ def test_create_simple
6
+ fields = {'2' => 'Tester', '4' => 'Shayne', '8' => 'Test entry'}
7
+ assert_nothing_thrown {
8
+ record = Kinetic::Link.create("KLINK_CanonicalForm", fields)
9
+ assert_not_nil(record)
10
+ assert_match(/^\d+$/,record)
11
+ Kinetic::Link.delete("KLINK_CanonicalForm", record)
12
+ }
13
+ end
14
+
15
+ def test_create_with_missing_required
16
+ #Missing a required field, 8 is required.
17
+ fields = {'2' => 'Tester', '4' => 'Shayne','8' => ''}
18
+ record = nil
19
+ assert_throws (:runtime_error) {
20
+ record = Kinetic::Link.create("KLINK_CanonicalForm", fields)
21
+ }
22
+ rescue RuntimeError
23
+ assert_nil(record)
24
+ end
25
+
26
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) +'/../test_helper'
2
+
3
+ class KineticLink_DeleteTest < Test::Unit::TestCase
4
+
5
+ def test_delete_simple
6
+ fields = {'2' => "Klink", '4' => "Shayne", '8' => "Test entry - #{Time.now}"}
7
+ new_record = Kinetic::Link.create("KLINK_CanonicalForm", fields)
8
+ success = ''
9
+ assert_nothing_thrown {
10
+ success = Kinetic::Link.delete("KLINK_CanonicalForm", new_record)
11
+ }
12
+ assert_not_nil(success)
13
+ assert_match(/^true$/,success)
14
+ end
15
+
16
+ def test_delete_record_does_not_exist
17
+ success = nil
18
+ assert_nothing_thrown {
19
+ success = Kinetic::Link.delete("KLINK_CanonicalForm", "DOES_NOT_EXIST")
20
+ }
21
+ rescue RuntimeError
22
+ assert_nil(success)
23
+ end
24
+
25
+ def test_delete_record_with_error
26
+ fields = {'2' => "Klink", '4' => "Shayne", '8' => "No can delete"}
27
+ #TODO create this filter
28
+ # this creates a record that will have a filter against it preventing delete
29
+ new_record = Kinetic::Link.create("KLINK_CanonicalForm", fields)
30
+ success = nil
31
+ assert_throws (:runtime_error) {
32
+ success = Kinetic::Link.delete("KLINK_CanonicalForm", new_record)
33
+ }
34
+ rescue RuntimeError
35
+ assert_nil(success)
36
+ end
37
+
38
+ end
@@ -0,0 +1,45 @@
1
+ require File.dirname(__FILE__) +'/../test_helper'
2
+
3
+ class KineticLink_EntriesTest < Test::Unit::TestCase
4
+
5
+ def test_entries_simple
6
+ entries = nil
7
+ assert_nothing_thrown {
8
+ entries = Kinetic::Link::entries('User')
9
+ }
10
+ assert_not_nil(entries)
11
+ assert_instance_of(Array,entries)
12
+ end
13
+
14
+ def test_entries_param_001
15
+ entries = nil
16
+ param = %|'Request ID'!="0"|
17
+ assert_nothing_thrown {
18
+ entries = Kinetic::Link::entries('User', param)
19
+ }
20
+ assert_not_nil(entries)
21
+ assert_instance_of(Array,entries)
22
+ end
23
+
24
+ def test_entries_param_002
25
+ entries = nil
26
+ param = %|'request_id'="000000000000027"|
27
+ assert_nothing_thrown {
28
+ entries = Kinetic::Link::entries('User', param)
29
+ }
30
+ assert_not_nil(entries)
31
+ assert_instance_of(Array,entries)
32
+ end
33
+
34
+ def test_entries_param_003
35
+ entries = nil
36
+ param = %|1=1|
37
+ assert_nothing_thrown {
38
+ entries = Kinetic::Link::entries('User', param)
39
+ }
40
+ assert_not_nil(entries)
41
+ assert_instance_of(Array,entries)
42
+ end
43
+
44
+ end
45
+