test_linker 0.1.1 → 1.0.0

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.
@@ -1,4 +1,4 @@
1
- require_relative 'error'
1
+ require File.expand_path(File.dirname(__FILE__) + '/error')
2
2
 
3
3
  # This module contains methods that aren't a part of the TestLink API. They
4
4
  # intend to make accessing TestLink database info easier.
@@ -18,17 +18,14 @@ module TestLinker::Helpers
18
18
  #
19
19
  # @param [String] project_name Name of the project to search for.
20
20
  # @return [Fixnum] ID of project matching project_name.
21
- # @raise [TestLinker::Error] When ID cannot be found for given
22
- # project_name.
23
- def test_project_id project_name
21
+ def project_id project_name
24
22
  if @version < "1.0"
25
- project = projects.find { |project| project["name"] == project_name }
23
+ project = projects.find { |project| project[:name] == project_name }
26
24
  else
27
- project = test_project_by_name(project_name).first
28
- raise TestLinker::Error, project['message'] if project['code']
25
+ project = project_by_name(project_name).first
29
26
  end
30
27
 
31
- project.nil? ? nil : project['id'].to_i
28
+ project.nil? ? nil : project[:id].to_i
32
29
  end
33
30
 
34
31
  # Gets info about test plans within a project
@@ -37,21 +34,19 @@ module TestLinker::Helpers
37
34
  # @param [String] plan_name Name of the plan to search for.
38
35
  # @return [Fixnum] ID of plan matching project_name and plan_name. 0 if the
39
36
  # test plan wasn't found.
40
- # @raise [RuntimeError] When unable to find matching project and plan names.
41
37
  def test_plan_id(project_name, plan_name)
42
38
  if @version < "1.0"
43
- project_id = test_project_id project_name
44
- test_plans = project_test_plans(project_id)
39
+ project_id = project_id project_name
40
+ test_plans = test_plans(project_id)
45
41
 
46
42
  test_plan = test_plans.first.values.find do |project_test_plan|
47
- project_test_plan["name"] == plan_name
43
+ project_test_plan[:name] == plan_name
48
44
  end
49
45
  else
50
46
  test_plan = test_plan_by_name(project_name, plan_name).first
51
- raise TestLinker::Error, test_plan['message'] if test_plan['code']
52
47
  end
53
48
 
54
- test_plan.nil? ? nil : test_plan['id'].to_i
49
+ test_plan.nil? ? nil : test_plan[:id].to_i
55
50
  end
56
51
 
57
52
  # Gets the ID for the given build name.
@@ -60,52 +55,57 @@ module TestLinker::Helpers
60
55
  # @param [String] plan_name Name of the plan to search for.
61
56
  # @param [String] build_name Name of the build to search for.
62
57
  # @return [Fixnum] ID of plan matching project_name and plan_name
63
- # @raise [TestLinker::Error] When unable to find matching
64
- # project/plan/build names.
65
58
  def build_id(project_name, plan_name, build_name)
66
59
  plan_id = test_plan_id(project_name, plan_name)
67
60
  builds = builds_for_test_plan plan_id
68
61
 
69
- builds.each do |build|
70
- if build['name'] == build_name
71
- return build['id'].to_i
72
- end
62
+ build = builds.find do |build|
63
+ build[:name] == build_name
73
64
  end
74
65
 
75
- raise TestLinker::Error,
76
- "Unable to find build named #{build_name} for #{plan_name} in #{project_name}"
66
+ build.nil? ? nil : build[:id].to_i
67
+ end
68
+
69
+ # Finds a list of projects whose attribute (given via the +match_attribute+
70
+ # parameter) matches +regex+.
71
+ #
72
+ # @param [Regexp] regex The expression to match project names on.
73
+ # @param [Symbol] match_attribute Attribute of the projects to match on.
74
+ # @return [Array] An array of projects that match the Regexp.
75
+ def find_projects(regex, match_attribute=:name)
76
+ project_list = projects
77
+
78
+ project_list.find_all do |project|
79
+ project[match_attribute] =~ regex
80
+ end
77
81
  end
78
82
 
79
- # @param [Fixnum,String] project_id
83
+ # Finds a list of test plans whose attribute (given via the +match_attribute+
84
+ # parameter) matches +regex+.
85
+ #
86
+ # @param [Fixnum,String] project_id ID of the project that the test plans
87
+ # belong to.
80
88
  # @param [Regexp] regex The expression to match test plan names on.
81
89
  # @return [Array] An array of test plans that match the Regexp.
82
- def find_test_plans(project_id, regex)
83
- list = []
84
- test_plan_list = project_test_plans(project_id).first
90
+ def find_test_plans(project_id, regex, match_attribute=:name)
91
+ test_plan_list = test_plans(project_id)
85
92
 
86
- test_plan_list.each_value do |test_plan_info|
87
- if test_plan_info["name"] =~ regex
88
- list << test_plan_info
89
- end
93
+ test_plan_list.first.values.find_all do |project_test_plan|
94
+ project_test_plan[match_attribute] =~ regex
90
95
  end
91
-
92
- list
93
96
  end
94
-
97
+
95
98
  # @param [String] project_name
96
99
  # @param [String] suite_name
97
- # @return [Fixnum] ID of the requested test suite.
98
- # @raise [TestLinker::Error] If no test suite was found by the given name.
100
+ # @return [Fixnum] ID of the requested test suite. nil if not found.
99
101
  def first_level_test_suite_id(project_name, suite_name)
100
- test_suites = first_level_test_suites_for_test_project(test_project_id(project_name))
102
+ test_suites = first_level_test_suites_for_project(project_id(project_name))
101
103
 
102
- test_suites.each do |test_suite|
103
- if test_suite['name'] == suite_name
104
- return test_suite['id'].to_i
105
- end
104
+ test_suite = test_suites.find do |test_suite|
105
+ test_suite[:name] == suite_name
106
106
  end
107
107
 
108
- raise TestLinker::Error, "Suite #{suite_name} not found."
108
+ test_suite.nil? ? nil : test_suite[:id].to_i
109
109
  end
110
110
 
111
111
  # Gets info about test case within a test plan within a project.
@@ -114,21 +114,14 @@ module TestLinker::Helpers
114
114
  # @param [String] plan_name Name of the plan to search for.
115
115
  # @param [String] test_case_name Name of the test case to search for.
116
116
  # @return [Hash] Info on the first matching test case.
117
- # @raise [TestLinker::Error] When unable to find matching
118
- # project/plan/test case names.
119
117
  # @todo Need to update for having more than one of same test name inside test plan.
120
118
  def test_info(project_name, plan_name, test_case_name)
121
119
  test_plan_id = test_plan_id(project_name, plan_name)
122
120
  test_cases = test_cases_for_test_plan(test_plan_id)
123
121
 
124
- test_cases.each_value do |test_case_info|
125
- if test_case_info['name'] == test_case_name
126
- return test_case_info
127
- end
122
+ test_cases.values.find do |test_case|
123
+ test_case[:name] == test_case_name
128
124
  end
129
-
130
- raise TestLinker::Error,
131
- "Unable to find test named #{test_case_name} for #{plan_name} in #{project_name}"
132
125
  end
133
126
 
134
127
  # Gets info about test suite within a test plan within a project.
@@ -136,26 +129,19 @@ module TestLinker::Helpers
136
129
  # @param [String] project_name
137
130
  # @param [String] plan_name
138
131
  # @param [String] suite_name
139
- # @return [Fixnum,String] SuiteID
140
- # @raise [TestLinker::Error] When unable to find matching
141
- # project/plan/test case names.
132
+ # @return [Hash] The name and ID of the test suite.
142
133
  # @todo Need to update for having more than one of same test name inside test plan.
143
134
  def suite_info(project_name, plan_name, suite_name)
144
135
  test_plan_id = test_plan_id(project_name, plan_name)
145
136
  test_suites = test_suites_for_test_plan(test_plan_id)
146
137
 
147
138
  if test_suites.empty?
148
- return "Unable to find test suites in test plan #{plan_name} in #{project_name}"
139
+ return nil
149
140
  end
150
141
 
151
- test_suites.each do |suite|
152
- if suite["name"].include? suite_name
153
- return suite
154
- end
142
+ test_suites.find do |test_suite|
143
+ test_suite[:name].include? suite_name
155
144
  end
156
-
157
- raise TestLinker::Error,
158
- "Unable to find suite named #{suite_name} for #{plan_name} in #{project_name}"
159
145
  end
160
146
 
161
147
  # Get the ID of a first level suite, creating it if it does not exist.
@@ -168,9 +154,9 @@ module TestLinker::Helpers
168
154
  rescue RuntimeError
169
155
 
170
156
  # Create suite if it doesn't exist.
171
- project_id = test_project_id(project_name)
157
+ project_id = project_id(project_name)
172
158
 
173
- create_test_suite(project_id, suite_name).first['id']
159
+ create_test_suite(project_id, suite_name).first[:id]
174
160
  end
175
161
 
176
162
  # Get the ID of a suite with the given parent, creating it if it does not
@@ -182,50 +168,51 @@ module TestLinker::Helpers
182
168
  # @raise [TestLinker::Error] When unable to find matching
183
169
  # project/plan/test case names.
184
170
  def create_suite(suite_name, project_name, parent_id)
185
- project_id = test_project_id(project_name)
171
+ project_id = project_id(project_name)
186
172
  response = test_suites_for_test_suite(parent_id)
187
173
 
188
174
  if response.class == Array
189
- raise TestLinker::Error, response.first['message']
175
+ raise TestLinker::Error, response.first[:message]
190
176
  elsif response.class == Hash
191
- return response['id'] if response['name'] == suite_name
177
+ return response[:id] if response[:name] == suite_name
192
178
 
193
179
  response.each_value do |suite|
194
- return suite['id'] if suite['name'] == suite_name
180
+ return suite[:id] if suite[:name] == suite_name
195
181
  end
196
182
  end
197
183
 
198
- create_test_suite(project_id, suite_name, parent_id).first['id']
184
+ create_test_suite(project_id, suite_name, parent_id).first[:id]
199
185
  end
200
186
 
201
187
  # Creates test in test suite within a test plan within a project.
202
188
  #
203
- # @param [String] test_case_name
204
- # @param [String] suite_name
205
189
  # @param [String] project_name
190
+ # @param [String] plan_name
191
+ # @param [String] suite_name
192
+ # @param [String] test_case_name
206
193
  # @param [String] login
207
194
  # @param [String] summary
208
195
  # @param [String] steps
209
196
  # @param [String] expected_results
210
197
  # @return [Array] array-> array[0]=test case id, array[1]=test case version
211
198
  # @todo Need to update for having more than one of same test name inside test plan.
212
- def create_test_case_by_name(test_case_name, suite_name, project_name, login,
213
- summary, steps, expected_results)
199
+ def create_test_case_by_name(project_name, plan_name, suite_name,
200
+ test_case_name, login, summary, steps, expected_results)
214
201
 
215
- test_project_id = self.test_project_id(project_name)
202
+ test_project_id = self.project_id(project_name)
216
203
  test_suite_id = self.suite_info(project_name, plan_name, suite_name)
217
204
 
218
- result = create_test_case(login, test_project_id, test_suite_id, test_case_name,
219
- summary, steps, expected_results)
205
+ result = create_test_case(test_project_id, test_suite_id, test_case_name,
206
+ summary, steps, expected_results, login)
220
207
 
221
208
  if result.any?
222
209
  result.each do |result_ptr|
223
- if result_ptr["message"].eql? "Success!"
210
+ if result_ptr[:message].eql? "Success!"
224
211
  if result_ptr.has_key? "additionalInfo"
225
212
  result_info = result_ptr.fetch("additionalInfo")
226
- if result_info["msg"].eql? "ok"
227
- test_case_id = result_info["id"]
228
- test_case_version = result_info["version_number"]
213
+ if result_info[:msg].eql? "ok"
214
+ test_case_id = result_info[:id]
215
+ test_case_version = result_info[:version_number]
229
216
  return [test_case_id, test_case_version]
230
217
  else
231
218
  return -1
@@ -247,7 +234,7 @@ module TestLinker::Helpers
247
234
  # @todo Need to update for having more than one of same test name inside testplan
248
235
  def add_test_case_to_test_plan_by_name(project_name, plan_name, test_case_id,
249
236
  test_case_version)
250
- test_project_id = test_project_id(project_name)
237
+ test_project_id = project_id(project_name)
251
238
  test_plan_id = test_plan_id(project_name, plan_name)
252
239
 
253
240
  result = add_test_case_to_test_plan(test_project_id, test_plan_id,
@@ -255,7 +242,7 @@ module TestLinker::Helpers
255
242
 
256
243
  if result.any?
257
244
  #Only way to tell if success if with the key "feature_id"
258
- return result.has_key?("feature_id") ? true : false
245
+ return result.has_key?(:feature_id) ? true : false
259
246
  end
260
247
  end
261
248
  end
@@ -1,4 +1,4 @@
1
1
  class TestLinker
2
2
  # test_linker version
3
- VERSION = "0.1.1"
3
+ VERSION = "1.0.0"
4
4
  end
@@ -1,4 +1,4 @@
1
- require_relative 'error'
1
+ require File.expand_path(File.dirname(__FILE__) + '/error')
2
2
 
3
3
  class TestLinker
4
4
 
@@ -8,85 +8,83 @@ class TestLinker
8
8
 
9
9
  # Gets a test case by it's internal or external ID.
10
10
  #
11
- # @since TestLink API version 1.0
11
+ # @api TestLink API version 1.0
12
12
  # @param [Hash] options
13
13
  # @option options [Fixnum,String] testcaseid
14
14
  # @option options [Fixnum,String] testcaseexternalid
15
15
  # @option options [Fixnum,String] version The test case version. Default is most recent.
16
16
  # @return
17
17
  def test_case(options)
18
- args = { "devKey" => @dev_key }
19
- args.merge! options
20
- make_call("tl.getTestCase", args, "1.0")
18
+ make_call("tl.getTestCase", options, "1.0")
21
19
  end
22
20
  alias_method :getTestCase, :test_case
23
21
 
24
22
  # Gets full path from the given node till the top using nodes_hierarchy_table.
25
23
  #
26
- # @since TestLink API version 1.0
24
+ # @api TestLink API version 1.0
27
25
  # @param [Fixnum,String] node_id
28
26
  # @return
29
27
  def full_path node_id
30
- args = { "devKey" => @dev_key, "nodeID" => node_id }
28
+ args = { :nodeID => node_id }
31
29
  make_call("tl.getFullPath", args, "1.0")
32
30
  end
33
31
  alias_method :getFullPath, :full_path
34
32
 
35
33
  # Gets a test suite by the given ID.
36
34
  #
37
- # @since TestLink API version 1.0
35
+ # @api TestLink API version 1.0
38
36
  # @param [Fixnum,String] suite_id
39
37
  # @return
40
38
  def test_suite_by_id suite_id
41
- args = { "devKey" => @dev_key, "testsuiteid" => suite_id }
39
+ args = { :testsuiteid => suite_id }
42
40
  make_call("tl.getTestSuiteByID", args, "1.0")
43
41
  end
44
42
  alias_method :getTestSuiteByID, :test_suite_by_id
45
43
 
46
- # @since TestLink API version 1.0
44
+ # @api TestLink API version 1.0
47
45
  # @param [Fixnum,String] execution_id
48
46
  # @return [Hash] "status", "id", "message"
49
47
  def delete_execution execution_id
50
- args = { "devKey" => @dev_key, "executionid" => execution_id }
48
+ args = { :executionid => execution_id }
51
49
  make_call("tl.deleteExecution", args, "1.0")
52
50
  end
53
51
  alias_method :deleteExecution, :delete_execution
54
52
 
55
- # @since TestLink API version 1.0
53
+ # @api TestLink API version 1.0
56
54
  # @param [String] user_name
57
55
  # @return [Boolean,Hash] true if user exists, otherwise an error structure.
58
56
  def does_user_exist user_name
59
- args = { "devKey" => @dev_key, "user" => user_name }
57
+ args = { :user => user_name }
60
58
  make_call("tl.doesUserExist", args, "1.0")
61
59
  end
62
60
  alias_method :doesUserExist, :does_user_exist
63
61
 
64
62
  # Checks if the given Developer Key exist.
65
63
  #
66
- # @since TestLink API version 1.0
64
+ # @api TestLink API version 1.0
67
65
  # @param [String] dev_key
68
66
  # @return [Hash] "true" if it exists, otherwise error structure.
69
67
  def check_dev_key dev_key
70
- args = { "devKey" => dev_key }
68
+ args = { :devKey => dev_key }
71
69
  make_call("tl.checkDevKey", args, "1.0")
72
70
  end
73
71
  alias_method :checkDevKey, :check_dev_key
74
72
 
75
73
  # Uploads an attachment for a test case execution.
76
74
  #
77
- # @since TestLink API version 1.0
75
+ # @api TestLink API version 1.0
76
+ # @param [Fixnum,String] execution_id
78
77
  # @param [String] file_name
79
78
  # @param [String] mime_type
80
79
  # @param [String] content The Base64 encoded content of the attachment.
81
- # @param [Fixnum,String] execution_id
82
80
  # @param [Hash] options
83
81
  # @option options [String] title
84
82
  # @option options [String] description
85
83
  # @return
86
- def upload_execution_attachment(file_name, mime_type, content, execution_id,
84
+ def upload_execution_attachment(execution_id, file_name, mime_type, content,
87
85
  options={})
88
- args = { "devKey" => @dev_key, "executionid" => execution_id,
89
- "filename" => file_name, "filetype" => mime_type, "content" => content }
86
+ args = { :executionid => execution_id, :filename => file_name,
87
+ :filetype => mime_type, :content => content }
90
88
  args.merge! options
91
89
  make_call("tl.uploadExecutionAttachment", args, "1.0")
92
90
  end
@@ -95,7 +93,7 @@ class TestLinker
95
93
  # Uploads an attachment for a Requirement. The attachment content must be
96
94
  # Base64 encoded by the client before sending it.
97
95
  #
98
- # @since TestLink API version 1.0
96
+ # @api TestLink API version 1.0
99
97
  # @param [Fixnum,String] requirement_id
100
98
  # @param [String] file_name
101
99
  # @param [String] mime_type
@@ -104,10 +102,10 @@ class TestLinker
104
102
  # @option options [String] title
105
103
  # @option options [String] description
106
104
  # @return
107
- def upload_requirement_attachment(file_name, mime_type, content,
108
- requirement_id, options={})
109
- args = { "devKey" => @dev_key, "requirementid" => requirement_id,
110
- "filename" => file_name, "filetype" => mime_type, "content" => content }
105
+ def upload_requirement_attachment(requirement_id, file_name, mime_type,
106
+ content, options={})
107
+ args = { :requirementid => requirement_id, :filename => file_name,
108
+ :filetype => mime_type, :content => content }
111
109
  args.merge! options
112
110
  make_call("tl.uploadRequirementAttachment", args, "1.0")
113
111
  end
@@ -116,19 +114,19 @@ class TestLinker
116
114
  # Uploads an attachment for a Requirement Specification. The attachment
117
115
  # content must be Base64 encoded by the client before sending it.
118
116
  #
119
- # @since TestLink API version 1.0
117
+ # @api TestLink API version 1.0
118
+ # @param [Fixnum,String] requirement_specification_id
120
119
  # @param [String] file_name
121
120
  # @param [String] mime_type
122
121
  # @param [String] content The Base64 encoded content of the attachment.
123
- # @param [Fixnum,String] requirement_id
124
122
  # @param [Hash] options
125
123
  # @option options [String] title
126
124
  # @option options [String] description
127
125
  # @return
128
- def upload_requirement_specification_attachment(file_name, mime_type, content,
129
- requirement_specification_id, options={})
130
- args = { "devKey" => @dev_key, "reqspecid" => requirement_specification_id,
131
- "filename" => file_name, "filetype" => mime_type, "content" => content }
126
+ def upload_requirement_specification_attachment(requirement_specification_id,
127
+ file_name, mime_type, content, options={})
128
+ args = { :reqspecid => requirement_specification_id, :filename => file_name,
129
+ :filetype => mime_type, :content => content }
132
130
  args.merge! options
133
131
  make_call("tl.uploadRequirementSpecificationAttachment", args, "1.0")
134
132
  end
@@ -138,13 +136,13 @@ class TestLinker
138
136
  # Assign Requirements to a test case. Capable of assigning multiple
139
137
  # requirements. Requirements can belong to different Requirement Specs.
140
138
  #
141
- # @param [String] requirements
142
- # @param [Fixnum,String] test_case_external_id
143
139
  # @param [Fixnum,String] project_id
140
+ # @param [Fixnum,String] test_case_external_id
141
+ # @param [String] requirements
144
142
  # @return
145
- def assign_requirements(requirements, test_case_external_id, project_id)
146
- args = { "devKey" => @dev_key, "testcaseexternalid" => test_case_external_id,
147
- "testprojectid" => project_id, "requirements" => requirements }
143
+ def assign_requirements(project_id, test_case_external_id, requirements)
144
+ args = { :testcaseexternalid => test_case_external_id,
145
+ :testprojectid => project_id, :requirements => requirements }
148
146
  make_call("tl.assignRequirements", args, "1.0b5")
149
147
  end
150
148
  alias_method :assignRequirements, :assign_requirements
@@ -152,40 +150,40 @@ class TestLinker
152
150
  # Uploads an attachment for a Test Project. The attachment must be Base64
153
151
  # encoded by the client before sending it.
154
152
  #
155
- # @since TestLink API version 1.0
153
+ # @api TestLink API version 1.0
154
+ # @param [Fixnum,String] project_id
156
155
  # @param [String] file_name
157
156
  # @param [String] mime_type
158
157
  # @param [String] content The Base64 encoded content of the attachment.
159
- # @param [Fixnum,String] project_id
160
158
  # @param [Hash] options
161
159
  # @option options [String] title
162
160
  # @option options [String] description
163
161
  # @return
164
- def upload_test_project_attachment(file_name, mime_type, content, project_id,
162
+ def upload_project_attachment(project_id, file_name, mime_type, content,
165
163
  options={})
166
- args = { "devKey" => @dev_key, "testprojectid" => project_id,
167
- "filename" => file_name, "filetype" => mime_type, "content" => content }
164
+ args = { :testprojectid => project_id, :filename => file_name,
165
+ :filetype => mime_type, :content => content }
168
166
  args.merge! options
169
167
  make_call("tl.uploadTestProjectAttachment", args, "1.0")
170
168
  end
171
- alias_method :uploadTestProjectAttachment, :upload_test_project_attachment
169
+ alias_method :uploadTestProjectAttachment, :upload_project_attachment
172
170
 
173
171
  # Uploads an attachment for a Test Suite. The attachment must be Base64
174
172
  # encoded by the client before sending it.
175
173
  #
176
- # @since TestLink API version 1.0
174
+ # @api TestLink API version 1.0
175
+ # @param [Fixnum,String] suite_id
177
176
  # @param [String] file_name
178
177
  # @param [String] mime_type
179
178
  # @param [String] content The Base64 encoded content of the attachment.
180
- # @param [Fixnum,String] suite_id
181
179
  # @param [Hash] options
182
180
  # @option options [String] title
183
181
  # @option options [String] description
184
182
  # @return
185
- def upload_test_suite_attachment(file_name, mime_type, content, suite_id,
183
+ def upload_test_suite_attachment(suite_id, file_name, mime_type, content,
186
184
  options={})
187
- args = { "devKey" => @dev_key, "testsuiteid" => suite_id,
188
- "filename" => file_name, "filetype" => mime_type, "content" => content }
185
+ args = { :testsuiteid => suite_id, :filename => file_name,
186
+ :filetype => mime_type, :content => content }
189
187
  args.merge! options
190
188
  make_call("tl.uploadTestSuiteAttachment", args, "1.0")
191
189
  end
@@ -194,19 +192,19 @@ class TestLinker
194
192
  # Uploads an attachment for a Test Case. The attachment must be Base64
195
193
  # encoded by the client before sending it.
196
194
  #
197
- # @since TestLink API version 1.0
195
+ # @api TestLink API version 1.0
196
+ # @param [Fixnum,String] test_case_id
198
197
  # @param [String] file_name
199
198
  # @param [String] mime_type
200
199
  # @param [String] content The Base64 encoded content of the attachment.
201
- # @param [Fixnum,String] test_case_id
202
200
  # @param [Hash] options
203
201
  # @option options [String] title
204
202
  # @option options [String] description
205
203
  # @return
206
- def upload_test_case_attachment(file_name, mime_type, content, test_case_id,
204
+ def upload_test_case_attachment(test_case_id, file_name, mime_type, content,
207
205
  options={})
208
- args = { "devKey" => @dev_key, "testcaseid" => test_case_id,
209
- "filename" => file_name, "filetype" => mime_type, "content" => content }
206
+ args = { :testcaseid => test_case_id, :filename => file_name,
207
+ :filetype => mime_type, :content => content }
210
208
  args.merge! options
211
209
  make_call("tl.uploadTestCaseAttachment", args, "1.0")
212
210
  end
@@ -217,21 +215,20 @@ class TestLinker
217
215
  # key id in this table The attachment must be Base64 encoded by the client
218
216
  # before sending it.
219
217
  #
220
- # @since TestLink API version 1.0
218
+ # @api TestLink API version 1.0
219
+ # @param [Fixnum,String] foreign_key_id
220
+ # @param [String] foreign_key_table
221
221
  # @param [String] file_name
222
222
  # @param [String] mime_type
223
223
  # @param [String] content The Base64 encoded content of the attachment.
224
- # @param [Fixnum,String] foreign_key_id
225
- # @param [String] foreign_key_table
226
224
  # @param [Hash] options
227
225
  # @option options [String] title
228
226
  # @option options [String] description
229
227
  # @return
230
- def upload_attachment(file_name, mime_type, content, foreign_key_id,
231
- foreign_key_table, options={})
232
- args = { "devKey" => @dev_key, "fkid" => foreign_key_id,
233
- "fktable" => foreign_key_table, "filename" => file_name,
234
- "filetype" => mime_type, "content" => content }
228
+ def upload_attachment(foreign_key_id, foreign_key_table, file_name,
229
+ mime_type, content, options={})
230
+ args = { :fkid => foreign_key_id, :fktable => foreign_key_table,
231
+ :filename => file_name, :filetype => mime_type, :content => content }
235
232
  args.merge! options
236
233
  make_call("tl.uploadAttachment", args, "1.0")
237
234
  end
@@ -241,7 +238,7 @@ class TestLinker
241
238
  #
242
239
  # @return [String] "Hello!"
243
240
  def say_hello
244
- make_call("tl.sayHello", "", "1.0b5")
241
+ make_call("tl.sayHello", {}, "1.0b5")
245
242
  end
246
243
  alias_method :sayHello, :say_hello
247
244
  alias_method :ping, :say_hello
@@ -251,14 +248,14 @@ class TestLinker
251
248
  # @param [String] message The message to get the server to repeat back.
252
249
  # @return [String] The message sent to the server.
253
250
  def repeat message
254
- make_call("tl.repeat", { str: message }, "1.0b5")
251
+ make_call("tl.repeat", { :str => message }, "1.0b5")
255
252
  end
256
253
 
257
254
  # Returns info about the server's TestLink API.
258
255
  #
259
256
  # @return [String] Info about TestLink API version
260
257
  def about
261
- make_call("tl.about", "", "1.0b5")
258
+ make_call("tl.about", {}, "1.0b5")
262
259
  end
263
260
 
264
261
  # Gets a list of all projects.
@@ -266,7 +263,7 @@ class TestLinker
266
263
  # @return [Array<Hash>] List of all projects in TestLink and
267
264
  # their associated info.
268
265
  def projects
269
- make_call("tl.getProjects", { devKey: @dev_key }, "1.0b5" )
266
+ make_call("tl.getProjects", {}, "1.0b5" )
270
267
  end
271
268
  alias_method :getProjects, :projects
272
269
 
@@ -276,33 +273,32 @@ class TestLinker
276
273
  # @return [Array<Hash>] Array of all plans in a project and their associated
277
274
  # info.
278
275
  # @raise [TestLinker::Error] If a project by the given ID doesn't exist.
279
- def project_test_plans project_id
280
- args = { devKey: @dev_key, testprojectid: project_id }
276
+ def test_plans project_id
277
+ args = { :testprojectid => project_id }
281
278
  response = make_call("tl.getProjectTestPlans", args, "1.0b5")
282
279
  response == "" ? [{}] : response
283
280
  end
284
- alias_method :getProjectTestPlans, :project_test_plans
281
+ alias_method :getProjectTestPlans, :test_plans
285
282
 
286
283
  # Info about a test project with a given name.
287
284
  #
288
- # @since TestLink API version 1.0
285
+ # @api TestLink API version 1.0
289
286
  # @param [String] project_name Name of the project to search for.
290
287
  # @return [Array<Hash>] Info on matching project.
291
- def test_project_by_name project_name
292
- args = { devKey: @dev_key, testprojectname: project_name }
288
+ def project_by_name project_name
289
+ args = { :testprojectname => project_name }
293
290
  make_call('tl.getTestProjectByName', args, "1.0")
294
291
  end
295
- alias_method :getTestProjectByName, :test_project_by_name
292
+ alias_method :getTestProjectByName, :project_by_name
296
293
 
297
294
  # Gets the test plan with the given name.
298
295
  #
299
- # @since TestLink API version 1.0
300
- # @param [String] plan_name Name of the plan to search for.
296
+ # @api TestLink API version 1.0
301
297
  # @param [String] project_name Name of the project the plan is in.
298
+ # @param [String] plan_name Name of the plan to search for.
302
299
  # @return [Array<Hash>] Info on matching plan.
303
- def test_plan_by_name(plan_name, project_name)
304
- args = { devKey: @dev_key, testplanname: plan_name,
305
- testprojectname: project_name }
300
+ def test_plan_by_name(project_name, plan_name)
301
+ args = { :testplanname => plan_name, :testprojectname => project_name }
306
302
  make_call('tl.getTestPlanByName', args, "1.0")
307
303
  end
308
304
  alias_method :getTestPlanByName, :test_plan_by_name
@@ -312,29 +308,29 @@ class TestLinker
312
308
  # @param [Fixnum,String] plan_id ID of the plan to get suites for.
313
309
  # @return [Array<Hash>] List of all suites in plan and their associated info.
314
310
  def test_suites_for_test_plan plan_id
315
- args = { devKey: @dev_key, testplanid: plan_id }
311
+ args = { :testplanid => plan_id }
316
312
  make_call("tl.getTestSuitesForTestPlan", args, "1.0b5")
317
313
  end
318
314
  alias_method :getTestSuitesForTestPlan, :test_suites_for_test_plan
319
315
 
320
316
  # List test suites within a test plan alphabetically.
321
317
  #
322
- # @since API version 1.0
318
+ # @api TestLink API version 1.0
323
319
  # @param [Fixnum,String] plan_id ID of the plan to get suites for.
324
320
  # @return [Array<Hash>] List of all suites in plan and their associated info.
325
321
  def test_plan_platforms plan_id
326
- args = { devKey: @dev_key, testplanid: plan_id }
322
+ args = { :testplanid => plan_id }
327
323
  make_call("tl.getTestPlanPlatforms", args, "1.0")
328
324
  end
329
325
  alias_method :getTestPlanPlatforms, :test_plan_platforms
330
326
 
331
327
  # Gets a list of test suites that are direct children of the given test suite.
332
328
  #
333
- # @since API version 1.0
329
+ # @api TestLink API version 1.0
334
330
  # @param [Fixnum,String] suite_id ID of the suite to get suites for.
335
331
  # @return [Array<Hash>] List of all suites in plan and their associated info.
336
332
  def test_suites_for_test_suite suite_id
337
- args = { devKey: @dev_key, testsuiteid: suite_id }
333
+ args = { :testsuiteid => suite_id }
338
334
  make_call("tl.getTestSuitesForTestSuite", args, "1.0")
339
335
  end
340
336
  alias_method :getTestSuitesForTestSuite, :test_suites_for_test_suite
@@ -344,12 +340,12 @@ class TestLinker
344
340
  # @param [Fixnum,String] project_id ID of the project to get suites for.
345
341
  # @return [Array<Hash>] List of first level suites in project and their
346
342
  # associated info.
347
- def first_level_test_suites_for_test_project project_id
348
- args = { devKey: @dev_key, testprojectid: project_id }
343
+ def first_level_test_suites_for_project project_id
344
+ args = { :testprojectid => project_id }
349
345
  make_call("tl.getFirstLevelTestSuitesForTestProject", args, "1.0b5")
350
346
  end
351
347
  alias_method :getFirstLevelTestSuitesForTestProject,
352
- :first_level_test_suites_for_test_project
348
+ :first_level_test_suites_for_project
353
349
 
354
350
  # Info about test cases within a test plan.
355
351
  #
@@ -368,35 +364,34 @@ class TestLinker
368
364
  # @return [Hash] List of all test cases in the plan and their
369
365
  # associated info.
370
366
  def test_cases_for_test_plan(plan_id, options={})
371
- args = { devKey: @dev_key, testplanid: plan_id }
367
+ args = { :testplanid => plan_id }
372
368
  args.merge! options
373
369
  make_call("tl.getTestCasesForTestPlan", args, "1.0b5")
374
370
  end
375
371
  alias_method :getTestCasesForTestPlan, :test_cases_for_test_plan
376
372
 
377
- # @param [Fixnum,String] suite_id ID of the suite to retrieve test cases for.
378
373
  # @param [Fixnum,String] project_id
379
- # @param [Hash] options
380
- # @option options [Boolean] deep
381
- # @option options [String] details Default is "simple"; use "full" to get
374
+ # @param [Fixnum,String] suite_id ID of the suite to retrieve test cases for.
375
+ # @param [Boolean] deep
376
+ # @param [String] details Default is "simple"; use "full" to get
382
377
  # summary, steps & expected results.
383
378
  # @return [Array<Hash>] List of test cases in the given suite and their
384
379
  # associated info.
385
- def test_cases_for_test_suite(suite_id, project_id, deep=true, details="")
386
- args = { devKey: @dev_key, testsuiteid: suite_id,
387
- projectid: project_id, deep: deep, details: details }
380
+ def test_cases_for_test_suite(project_id, suite_id, deep=true, details="")
381
+ args = { :testsuiteid => suite_id, :projectid => project_id,
382
+ :deep => deep, :details => details }
388
383
  make_call("tl.getTestCasesForTestSuite", args, "1.0b5")
389
384
  end
390
385
  alias_method :getTestCasesForTestSuite, :test_cases_for_test_suite
391
386
 
392
387
  # Gets the summarized results grouped by platform.
393
388
  #
394
- # @since TestLink API version 1.0
389
+ # @api TestLink API version 1.0
395
390
  # @param [Fixnum,String] plan_id
396
391
  # @return [Hash] Contains "type" => platform, "total_tc" => X, "details =>
397
392
  # Array of counts.
398
393
  def totals_for_test_plan plan_id
399
- args = { devKey: @dev_key, testplanid: plan_id }
394
+ args = { :testplanid => plan_id }
400
395
  make_call("tl.getTotalsForTestPlan", args, "1.0")
401
396
  end
402
397
  alias_method :getTotalsForTestPlan, :totals_for_test_plan
@@ -408,14 +403,12 @@ class TestLinker
408
403
  # @param [Fixnum,String] testcaseexternalid If not present, testcaseid must be called.
409
404
  # @return [String]
410
405
  def test_case_attachments options
411
- args = { devKey: @dev_key }
412
- args.merge! options
413
- make_call("tl.getTestCaseAttachments", args, "1.0b5")
406
+ make_call("tl.getTestCaseAttachments", options, "1.0b5")
414
407
  end
415
408
  alias_method :getTestCaseAttachments, :test_case_attachments
416
409
 
417
- # @param [Fixnum,String] test_case_external_id
418
410
  # @param [Fixnum,String] project_id
411
+ # @param [Fixnum,String] test_case_external_id
419
412
  # @param [Fixnum] custom_field_name
420
413
  # @param [Hash] options
421
414
  # @option options [String] details Changes output information. If null or 'value',
@@ -423,11 +416,11 @@ class TestLinker
423
416
  # plus value and internal test case id; if 'simple', returns value plus custom
424
417
  # field name, label, and type (as code).
425
418
  # @return [Array<Hash>]
426
- def test_case_custom_field_design_value(custom_field_name,
427
- test_case_external_id, project_id, options={})
428
- args = { devKey: @dev_key, testprojectid: project_id,
429
- testcaseexternalid: test_case_external_id,
430
- customfieldname: custom_field_name }
419
+ def test_case_custom_field_design_value(project_id, test_case_external_id,
420
+ custom_field_name, options={})
421
+ args = { :testprojectid => project_id,
422
+ :testcaseexternalid => test_case_external_id,
423
+ :customfieldname => custom_field_name }
431
424
  args.merge! options
432
425
  make_call("tl.getTestCaseCustomFieldDesignValue", args, "1.0b5")
433
426
  end
@@ -445,19 +438,18 @@ class TestLinker
445
438
  # @return [Array<Hash>] List of all test cases in the DB matching
446
439
  # test_case_name and their associated info.
447
440
  def test_case_id_by_name(test_case_name, options={})
448
- args = { devKey: @dev_key, testcasename: test_case_name }
441
+ args = { :testcasename => test_case_name }
449
442
  args.merge! options
450
443
  make_call("tl.getTestCaseIDByName", args, "1.0b5")
451
444
  end
452
445
  alias_method :getTestCaseIDByName, :test_case_id_by_name
453
446
 
454
- # @param [Fixnum,String] test_case_id
455
- # @param [Fixnum,String] build_id
456
447
  # @param [Fixnum,String] plan_id
448
+ # @param [Fixnum,String] build_id
449
+ # @param [Fixnum,String] test_case_id
457
450
  # @return [Array<Hash>] Single element Array containing the result Hash.
458
- def last_execution_result(test_case_id, build_id, plan_id)
459
- args = { devKey: @dev_key, testplanid: plan_id,
460
- testcaseid: test_case_id, buildid: build_id }
451
+ def last_execution_result(plan_id, build_id, test_case_id)
452
+ args = { :testplanid => plan_id, :testcaseid => test_case_id, :buildid => build_id }
461
453
  make_call("tl.getLastExecutionResult", args, "1.0b5")
462
454
  end
463
455
  alias_method :getLastExecutionResult, :last_execution_result
@@ -468,7 +460,7 @@ class TestLinker
468
460
  # @return [Array<Hash>] List of all builds for the plan and their associated
469
461
  # info.
470
462
  def builds_for_test_plan plan_id
471
- args = { devKey: @dev_key, testplanid: plan_id }
463
+ args = { :testplanid => plan_id }
472
464
  make_call("tl.getBuildsForTestPlan", args, "1.0b5")
473
465
  end
474
466
  alias_method :getBuildsForTestPlan, :builds_for_test_plan
@@ -476,7 +468,7 @@ class TestLinker
476
468
  # @param [Fixnum,String] plan_id ID of the plan to get build for.
477
469
  # @return [Hash] Info for the latest build for the given test plan.
478
470
  def latest_build_for_test_plan plan_id
479
- args = { devKey: @dev_key, testplanid: plan_id }
471
+ args = { :testplanid => plan_id }
480
472
  make_call("tl.getLatestBuildForTestPlan", args, "1.0b5")
481
473
  end
482
474
  alias_method :getLatestBuildForTestPlan, :latest_build_for_test_plan
@@ -491,33 +483,31 @@ class TestLinker
491
483
  # @option options [Fixnum] active
492
484
  # @option options [Fixnum] public
493
485
  # @return
494
- def create_test_project(project_name, test_case_prefix, options={})
495
- args = { devKey: @dev_key, testprojectname: project_name,
496
- testcaseprefix: test_case_prefix }
486
+ def create_project(project_name, test_case_prefix, options={})
487
+ args = { :testprojectname => project_name, :testcaseprefix => test_case_prefix }
497
488
  args.merge! options
498
489
  make_call("tl.createTestProject", args, "1.0b5")
499
490
  end
500
- alias_method :createTestProject, :create_test_project
491
+ alias_method :createTestProject, :create_project
501
492
 
502
- # @since TestLink API version 1.0
503
- # @param [String] plan_name
493
+ # @api TestLink API version 1.0
504
494
  # @param [String] project_name
495
+ # @param [String] plan_name
505
496
  # @param [Hash] options
506
497
  # @option options [String] notes
507
498
  # @option options [String] active Defaults to 1.
508
499
  # @option options [String] public Defaults to 1.
509
500
  # @return
510
- def create_test_plan(plan_name, project_name, options={})
511
- args = { devKey: @dev_key, testplanname: plan_name,
512
- testprojectname: project_name }
501
+ def create_test_plan(project_name, plan_name, options={})
502
+ args = { :testplanname => plan_name, :testprojectname => project_name }
513
503
  args.merge! options
514
504
  make_call('tl.createTestPlan', args, "1.0")
515
505
  end
516
506
  alias_method :createTestPlan, :create_test_plan
517
507
 
508
+ # @param [Fixnum,String] project_id
518
509
  # @param [String] suite_name
519
510
  # @param [String] details
520
- # @param [Fixnum,String] project_id
521
511
  # @param [Hash] options
522
512
  # @option options [Fixnum,String] parentid Defaults to top level.
523
513
  # @option options [Fixnum] order Order inside parent container.
@@ -526,9 +516,9 @@ class TestLinker
526
516
  # @option options [Boolean] actiononduplicatedname Applicable only if
527
517
  # checkduplicatedname = true.
528
518
  # @return [Array<Hash>] Info about results of test suite creation.
529
- def create_test_suite(suite_name, details, project_id, options={})
530
- args = { devKey: @dev_key, testprojectid: project_id,
531
- testsuitename: suite_name, details: details }
519
+ def create_test_suite(project_id, suite_name, details, options={})
520
+ args = { :testprojectid => project_id, :testsuitename => suite_name,
521
+ :details => details }
532
522
  args.merge! options
533
523
  make_call('tl.createTestSuite', args, "1.0b5")
534
524
  end
@@ -536,23 +526,23 @@ class TestLinker
536
526
 
537
527
  # Creates a new build for a specific test plan.
538
528
  #
529
+ # @param [Fixnum,String] plan_id
539
530
  # @param [String] build_name
540
531
  # @param [String] build_notes
541
- # @param [Fixnum,String] plan_id
542
532
  # @return
543
- def create_build(build_name, build_notes, plan_id)
544
- args = { devKey: @dev_key, testplanid: plan_id,
545
- buildname: build_name, buildnotes: build_notes }
533
+ def create_build(plan_id, build_name, build_notes)
534
+ args = { :testplanid => plan_id, :buildname => build_name,
535
+ :buildnotes => build_notes }
546
536
  make_call("tl.createBuild", args, "1.0b5")
547
537
  end
548
538
  alias_method :createBuild, :create_build
549
539
 
540
+ # @param [Fixnum,String] project_id
541
+ # @param [Fixnum,String] suite_id
550
542
  # @param [String] test_case_name
551
543
  # @param [String] test_case_summary
552
544
  # @param [String] test_case_steps
553
545
  # @param [String] test_case_expected_results
554
- # @param [Fixnum,String] suite_id
555
- # @param [Fixnum,String] project_id
556
546
  # @param [String] login
557
547
  # @param [Hash] options
558
548
  # @option options [String] preconditions
@@ -563,16 +553,15 @@ class TestLinker
563
553
  # @option options [String] actiononduplicatedname
564
554
  # @option options [String] executiontype
565
555
  # @return
566
- def create_test_case(test_case_name, test_case_summary, test_case_steps,
567
- test_case_expected_results, suite_id, project_id, login, options={})
568
- args = { devKey: @dev_key,
569
- testcasename: test_case_name,
570
- testsuiteid: suite_id,
571
- testprojectid: project_id,
572
- authorlogin: login,
573
- summary: test_case_summary,
574
- steps: test_case_steps,
575
- expectedresults: test_case_expected_results }
556
+ def create_test_case(project_id, suite_id, test_case_name, test_case_summary,
557
+ test_case_steps, test_case_expected_results, login, options={})
558
+ args = { :testcasename => test_case_name,
559
+ :testsuiteid => suite_id,
560
+ :testprojectid => project_id,
561
+ :authorlogin => login,
562
+ :summary => test_case_summary,
563
+ :steps => test_case_steps,
564
+ :expectedresults => test_case_expected_results }
576
565
  args.merge! options
577
566
  make_call("tl.createTestCase", args, "1.0b5")
578
567
  end
@@ -580,21 +569,21 @@ class TestLinker
580
569
 
581
570
  # Adds a test case version to a test plan.
582
571
  #
572
+ # @param [Fixnum,String] project_id
573
+ # @param [Fixnum,String] plan_id
583
574
  # @param [Fixnum,String] test_case_external_id
584
575
  # @param [Fixnum,String] test_case_version
585
- # @param [Fixnum,String] plan_id
586
- # @param [Fixnum,String] project_id
587
576
  # @param [Hash] options Optional parameters for the method.
588
577
  # @option options [String] urgency
589
578
  # @option options [Fixnum] executionorder
590
579
  # @option options [Fixnum] platformid Only if test plan has no platforms.
591
580
  # (TestLink API >=1.0)
592
581
  # @return
593
- def add_test_case_to_test_plan(test_case_external_id, test_case_version,
594
- plan_id, project_id, options={})
595
- args = { devKey: @dev_key, testprojectid: project_id,
596
- testplanid: plan_id, testcaseexternalid: test_case_external_id,
597
- version: test_case_version }
582
+ def add_test_case_to_test_plan(project_id, plan_id, test_case_external_id,
583
+ test_case_version, options={})
584
+ args = { :testprojectid => project_id, :testplanid => plan_id,
585
+ :testcaseexternalid => test_case_external_id,
586
+ :version => test_case_version }
598
587
  args.merge! options
599
588
  make_call("tl.addTestCaseToTestPlan", args, "1.0b5")
600
589
  end
@@ -606,9 +595,9 @@ class TestLinker
606
595
  #
607
596
  # @see #test_case_execution_result=
608
597
  # @version TestLink API version 1.0 Beta 5
609
- # @param [Fixnum,String] test_case_id ID of the test case to post results to.
610
- # @param [String] status 'p', 'f', 's', or 'b' for Pass/Fail/Skip/Block
611
598
  # @param [Fixnum,String] plan_id ID of the test plan to post results to.
599
+ # @param [Fixnum,String] test_case_id ID of the test case to post results to.
600
+ # @param [String] status 'p', 'f', or 'b' for Pass/Fail/Block
612
601
  # @param [Hash] options
613
602
  # @option options [Fixnum,String] buildid ID of the build to post results to.
614
603
  # @option options [Fixnum,String] buildname Name of the build to post results to.
@@ -623,15 +612,15 @@ class TestLinker
623
612
  # @return [Hash] "status" of posting, "id" of the execution, "message"
624
613
  # giving success or failure info.
625
614
  # @raise [TestLinker::Error] If result fails to be posted for any reason.
626
- def report_test_case_result(test_case_id, status, plan_id, options={})
615
+ def report_test_case_result(plan_id, test_case_id, status, options={})
627
616
  if @version >= "1.0"
628
617
  message = "Method not supported in version #{@version}. "
629
618
  message << "Use #test_case_execution_result="
630
619
  raise TestLinker::Error, message
631
620
  end
632
621
 
633
- args = { devKey: @dev_key, testcaseid: test_case_id,
634
- testplanid: plan_id, status: status, guess: true }
622
+ args = { :testcaseid => test_case_id, :testplanid => plan_id,
623
+ :status => status, :guess => true }
635
624
  args.merge! options
636
625
  result = @server.call("tl.reportTCResult", args).first
637
626
 
@@ -647,10 +636,10 @@ class TestLinker
647
636
  # NOTE: will guess at last build, needs to be set to guarantee accuracy.
648
637
  #
649
638
  # @see #report_test_case_result
650
- # @since TestLink API version 1.0
651
- # @param [String] test_case_id ID of the test case to post results to.
652
- # @param [String] status 'p', 'f', 's', or 'b' for Pass/Fail/Skip/Block
639
+ # @api TestLink API version 1.0
653
640
  # @param [String] plan_id ID of the test plan to post results to.
641
+ # @param [String] test_case_id ID of the test case to post results to.
642
+ # @param [String] status 'p', 'f', or 'b' for Pass/Fail/Block
654
643
  # @param [Hash] options
655
644
  # @option options [Fixnum] buildid ID of the build to post results to.
656
645
  # @option options [String] buildname Name of the build to post results to.
@@ -664,15 +653,15 @@ class TestLinker
664
653
  # @return [Hash] "status" of posting, "id" of the execution, "message"
665
654
  # giving success or failure info.
666
655
  # @raise [TestLinker::Error] If result fails to be posted for any reason.
667
- def test_case_execution_result=(test_case_id, status, plan_id, options={})
656
+ def test_case_execution_result=(plan_id, test_case_id, status, options={})
668
657
  if @version < "1.0"
669
658
  message = "Method not supported in version #{@version}. "
670
659
  message << "Use #report_test_case_result"
671
660
  raise TestLinker::Error, message
672
661
  end
673
662
 
674
- args = { devKey: @dev_key, testcaseid: test_case_id,
675
- testplanid: plan_id, status: status, guess: true }
663
+ args = { :testcaseid => test_case_id, :testplanid => plan_id,
664
+ :status => status, :guess => true }
676
665
  args.merge! options
677
666
  result = @server.call("tl.setTestCaseExecutionResult", args).first
678
667