smartring 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 837a79f27bba855d63ff0055ef98af9f3b065c09f4d9172a8107af31a15fde77
4
- data.tar.gz: 5afc964127b1f19de3c0c8462e854c98e24a6df02a4341625ef94b4ee5204bfe
3
+ metadata.gz: 91f5539a019096679d33badec75a70fa363e4f81e3f51cee66ef8cf5b69863ec
4
+ data.tar.gz: '0967632d3a9dd84bf5453038a32b898a75faf06ad67e812e774d8df4c46fb49a'
5
5
  SHA512:
6
- metadata.gz: a6aa2a8fb795346e6e4bad8b49737bc2e4b09af53ab6668b71f32818e061415c882767a94f5807bc83094b82e11f6ec8e299f42c76d8503a85df232411fa61c8
7
- data.tar.gz: 4cabd64289c24452b2365045d4b3a0d286086c8a4725ba6032e44f0fd37d45d10d0177ac0485e354971f851cab944261b96a5eec32d14f5cb08e183795aed04f
6
+ metadata.gz: eea04bdad4bd887734963968c8d2cda50c0306c67fa50fec85083dd098772d733a076ad1f8fab0a9f63203997aa40ff164029bf7368f7140e8a73d0e987aea5f
7
+ data.tar.gz: 4d0fe2605c97a2cb83f7b0208b78d8a34a8f12ee017b254c7c9216943868a4d7546d129d9d69e0cdfbd184e1503be45914105b52d17edbb9a22cfe8131528dae
@@ -5,6 +5,7 @@ require 'smartling/auth'
5
5
  require 'smartling/files'
6
6
  require 'smartling/contexts'
7
7
  require 'smartling/strings'
8
+ require 'smartling/jobs'
8
9
  require 'smartling/verbs'
9
10
  require 'hipsterhash'
10
11
  require 'forwardable'
@@ -16,6 +17,7 @@ module Smartling
16
17
  include Auth
17
18
  include Files
18
19
  include Strings
20
+ include Jobs
19
21
  include Contexts
20
22
  include Verbs
21
23
 
@@ -0,0 +1,195 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smartling
4
+ # Methods for using the Smartling files API
5
+ module Jobs
6
+ def jobs(project_id: @project_id, job_name: nil, translation_job_uids:
7
+ nil, translation_job_status: nil, limit: nil, offset: nil,
8
+ sort_by: nil, sort_direction: nil)
9
+ path = "/jobs-api/v3/projects/#{project_id}/jobs"
10
+ query = {}
11
+ query[:jobName] = job_name unless job_name.nil?
12
+ query[:translationJobUids] = translation_job_uids
13
+ query[:translationJobStatus] = translation_job_status unless translation_job_status.nil?
14
+ query[:limit] = limit unless limit.nil?
15
+ query[:offset] = offset unless offset.nil?
16
+ query[:sortBy] = sort_by unless sort_by.nil?
17
+ query[:sortDirection] = sort_direction unless sort_direction.nil?
18
+ return get(path) if query.empty?
19
+ return get(path, query: query)
20
+ end
21
+
22
+ def create_job(project_id: @project_id, job_name: nil, target_locale_ids:
23
+ nil, description: nil, due_date: nil, reference_number:
24
+ nil, callback_url: nil, callback_method: nil)
25
+ path = "/jobs-api/v3/projects/#{project_id}/jobs"
26
+ body = {}
27
+ body[:jobName] = job_name unless job_name.nil?
28
+ unless target_locale_ids.nil?
29
+ body[:targetLocaleIds] = target_locale_ids
30
+ end
31
+ body[:description] = description unless description.nil?
32
+ body[:dueDate] = Time.parse(due_date.to_s).iso8601 unless due_date.nil?
33
+ body[:referenceNumber] = reference_number unless reference_number.nil?
34
+ body[:callbackUrl] = callback_url unless callback_url.nil?
35
+ body[:callbackMethod] = callback_method unless callback_method.nil?
36
+ return post(path) if body.empty?
37
+ post(path, body: body)
38
+ end
39
+
40
+ def job(project_id: @project_id, translation_job_uid:)
41
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/#{translation_job_uid}"
42
+ get(path)
43
+ end
44
+
45
+ def update_job(project_id: @project_id, translation_job_uid:,
46
+ job_name: nil, description: nil, due_date: nil,
47
+ reference_number: nil, callback_url: nil,
48
+ callback_method: nil)
49
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/#{translation_job_uid}"
50
+ body = {}
51
+ body[:jobName] = job_name unless job_name.nil?
52
+ body[:description] = description unless description.nil?
53
+ body[:dueDate] = Time.parse(due_date.to_s).iso8601 unless due_date.nil?
54
+ body[:referenceNumber] = reference_number unless reference_number.nil?
55
+ body[:callbackUrl] = callback_url unless callback_url.nil?
56
+ body[:callbackMethod] = callback_method unless callback_method.nil?
57
+ return put(path) if body.empty?
58
+ put(path, body: body)
59
+ end
60
+
61
+ def search_jobs(project_id: @project_id, translation_job_uids: nil,
62
+ file_uris: nil, hashcodes: nil)
63
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/search"
64
+ body = {}
65
+ unless translation_job_uids.nil?
66
+ body[:translationJobUids] = translation_job_uids
67
+ end
68
+ body[:hashcodes] = hashcodes unless hashcodes.nil?
69
+ body[:fileUris] = file_uris unless file_uris.nil?
70
+ return post(path) if body.empty?
71
+ post(path, body: body)
72
+ end
73
+
74
+ def job_files(project_id: @project_id, translation_job_uid:, offset: nil,
75
+ limit: nil)
76
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/#{translation_job_uid}"
77
+ path = path + '/files'
78
+ query = {}
79
+ query[:limit] = limit unless limit.nil?
80
+ query[:offset] = offset unless offset.nil?
81
+ return get(path) if query.empty?
82
+ get(path, query: query)
83
+ end
84
+
85
+ def job_progress(project_id: @project_id, translation_job_uid:,
86
+ file_uri: nil, offset: nil, limit: nil)
87
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/#{translation_job_uid}"
88
+ path = path + '/progress'
89
+ query = {}
90
+ query[:fileUri] = file_uri unless file_uri.nil?
91
+ query[:limit] = limit unless limit.nil?
92
+ query[:offset] = offset unless offset.nil?
93
+ return get(path) if query.empty?
94
+ get(path, query: query)
95
+ end
96
+
97
+ def add_file_to_job(project_id: @project_id, translation_job_uid:,
98
+ file_uri:, target_locale_ids: nil)
99
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/#{translation_job_uid}"
100
+ path = path + '/file/add'
101
+ body = {}
102
+ body[:fileUri] = file_uri
103
+ body[:targetLocaleIds] = target_locale_ids unless target_locale_ids.nil?
104
+ post(path, body: body)
105
+ end
106
+
107
+ def remove_file_from_job(project_id: @project_id, translation_job_uid:, file_uri:)
108
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/#{translation_job_uid}"
109
+ path = path + '/file/remove'
110
+ body = { fileUri: file_uri }
111
+ post(path, body: body)
112
+ end
113
+
114
+ def add_strings_to_job(project_id: @project_id, translation_job_uid:,
115
+ hashcodes:, target_locale_ids: nil,
116
+ move_enabled: nil)
117
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/#{translation_job_uid}"
118
+ path = path + '/strings/add'
119
+ body = {}
120
+ body[:hashcodes] = hashcodes
121
+ body[:targetLocaleIds] = target_locale_ids unless target_locale_ids.nil?
122
+ body[:moveEnabled] = move_enabled unless move_enabled.nil?
123
+ post(path, body: body)
124
+ end
125
+
126
+ def remove_strings_from_job(project_id: @project_id, translation_job_uid:,
127
+ hashcodes:, locale_ids: nil)
128
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/#{translation_job_uid}"
129
+ path = path + '/strings/remove'
130
+ body = {}
131
+ body[:hashcodes] = hashcodes
132
+ body[:localeIds] = locale_ids unless locale_ids.nil?
133
+ post(path, body: body)
134
+ end
135
+
136
+ def add_locale_to_job(project_id: @project_id, translation_job_uid:,
137
+ locale_id:, sync_content: nil)
138
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/#{translation_job_uid}"
139
+ path = path + "/locales/#{locale_id}"
140
+ body = {}
141
+ body[:syncContent] = sync_content unless sync_content.nil?
142
+ return post(path) if body.nil?
143
+ post(path, body: body)
144
+ end
145
+
146
+ def remove_locale_from_job(project_id: @project_id, translation_job_uid:,
147
+ locale_id: )
148
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/#{translation_job_uid}"
149
+ path = path + "/locales/#{locale_id}"
150
+ delete(path)
151
+ end
152
+
153
+ def close_job(project_id: @project_id, translation_job_uid:)
154
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/#{translation_job_uid}"
155
+ path = path + '/close'
156
+ post(path)
157
+ end
158
+
159
+ def cancel_job(project_id: @project_id, translation_job_uid:, reason: nil)
160
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/#{translation_job_uid}"
161
+ path = path + '/cancel'
162
+ body = {}
163
+ body[:reason] = reason unless reason.nil?
164
+ return post(path) if body.nil?
165
+ post(path, body: body)
166
+ end
167
+
168
+ def authorize_job(project_id: @project_id, translation_job_uid:,
169
+ locale_workflows: nil)
170
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/#{translation_job_uid}"
171
+ path = path + '/authorize'
172
+ case locale_workflows
173
+ when nil
174
+ return post(path)
175
+ when Array
176
+ body = {}
177
+ body[:localeWorkflows] = locale_workflows.map do |lw|
178
+ locale = lw[:target_locale_id] || lw.fetch('target_locale_id')
179
+ workflow = lw[:workflow_uid] || lw.fetch('workflow_uid')
180
+ { targetLocaleId: locale, workflowUid: workflow }
181
+ end
182
+ post(path, body: body)
183
+ else
184
+ raise ArgumentError, 'locale_workflows should be an array'
185
+ end
186
+ end
187
+
188
+ def job_process(project_id: @project_id, translation_job_uid:,
189
+ process_uid: )
190
+ path = "/jobs-api/v3/projects/#{project_id}/jobs/#{translation_job_uid}"
191
+ path = path + "/processes/#{process_uid}"
192
+ get(path)
193
+ end
194
+ end
195
+ end
@@ -10,6 +10,7 @@ describe Smartling::Client, :vcr do
10
10
  it('knows context') { assert client.is_a?(Smartling::Contexts) }
11
11
  it('knows about files') { assert client.is_a?(Smartling::Files) }
12
12
  it('knows about strings') { assert client.is_a?(Smartling::Strings) }
13
+ it('knows about jobs') { assert client.is_a?(Smartling::Jobs) }
13
14
  it('knows how to authenticate') { assert client.is_a?(Smartling::Auth) }
14
15
 
15
16
  it 'can be created with options' do
@@ -0,0 +1,270 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ require 'smartling/jobs'
5
+
6
+ describe Smartling::Jobs do
7
+ let(:smartling) do
8
+ Class.new(Minitest::Mock) do
9
+ include Smartling::Jobs
10
+ end.new
11
+ end
12
+
13
+ after { smartling.verify }
14
+
15
+ describe 'jobs' do
16
+ it 'GETs the right path and query params' do
17
+ smartling.expect(:get, nil) do |path|
18
+ assert_match %r{jobs-api/v3/projects/1/jobs}, path
19
+ end
20
+ smartling.jobs(project_id: 1)
21
+ end
22
+
23
+ it 'passes other arguments too' do
24
+ smartling.expect(:get, nil) do |path, query:|
25
+ assert_match %r{jobs-api/v3/projects/1/jobs}, path
26
+ assert_equal 'ASC', query[:sortDirection]
27
+ assert_equal 'foo', query[:jobName]
28
+ assert_equal %w(1 2 3), query[:translationJobUids]
29
+ assert_equal 100, query[:limit]
30
+ assert_equal 20, query[:offset]
31
+ end
32
+ smartling.jobs(project_id: 1, job_name: 'foo', sort_direction: 'ASC',
33
+ translation_job_uids: %w(1 2 3), limit: 100, offset: 20)
34
+ end
35
+ end
36
+
37
+ describe 'create_job' do
38
+ it 'POSTs the right path and body' do
39
+ smartling.expect(:post, nil) do |path|
40
+ assert_match %r{jobs-api/v3/projects/1/jobs}, path
41
+ end
42
+ smartling.create_job(project_id: 1)
43
+ end
44
+
45
+ it 'builds the correct body' do
46
+ smartling.expect(:post, nil) do |path, body:|
47
+ assert_match %r{jobs-api/v3/projects/1/jobs}, path
48
+ assert_equal 'foo', body[:jobName]
49
+ assert_equal Time.parse('2000-01-01').iso8601, body[:dueDate]
50
+ assert_equal %w(de), body[:targetLocaleIds]
51
+ assert_equal '123', body[:referenceNumber]
52
+ assert_equal 'https://foo.bar', body[:callbackUrl]
53
+ end
54
+ smartling.create_job(project_id: 1, job_name: 'foo',
55
+ target_locale_ids: %w(de),
56
+ due_date: Time.parse('2000-01-01'),
57
+ reference_number: '123',
58
+ callback_url: 'https://foo.bar')
59
+ end
60
+ end
61
+
62
+ describe 'job' do
63
+ it 'GETs the right endpoint' do
64
+ smartling.expect(:get, nil) do |path|
65
+ assert_match %r{jobs-api/v3/projects/1/jobs/x}, path
66
+ end
67
+ smartling.job(project_id: 1, translation_job_uid: 'x')
68
+ end
69
+ end
70
+
71
+ describe 'update_job' do
72
+ it 'PUTs the right data to the right endpoint' do
73
+ smartling.expect(:put, nil) do |path, body:|
74
+ assert_match %r{jobs-api/v3/projects/1/jobs/x}, path
75
+ assert_equal 'D', body[:description]
76
+ assert_equal Time.parse('2001-01-01').iso8601, body[:dueDate]
77
+ assert_equal '123', body[:referenceNumber]
78
+ assert_equal 'https://x.y', body[:callbackUrl]
79
+ assert_equal 'GET', body[:callbackMethod]
80
+ end
81
+ smartling.update_job(project_id: 1, translation_job_uid: 'x',
82
+ description: 'D', due_date: '2001-01-01',
83
+ reference_number: '123', job_name: 'N',
84
+ callback_url: 'https://x.y',
85
+ callback_method: 'GET')
86
+ end
87
+ end
88
+
89
+ describe 'search_jobs' do
90
+ it 'POSTs the right body to the right endpoint' do
91
+ smartling.expect(:post, nil) do |path, body:|
92
+ assert_match %r{jobs-api/v3/projects/1/jobs/search}, path
93
+ assert_equal %w(a b), body[:hashcodes]
94
+ assert_equal %w(x y), body[:fileUris]
95
+ assert_equal %w(1 2), body[:translationJobUids]
96
+ end
97
+ smartling.search_jobs(project_id: 1, hashcodes: %w(a b),
98
+ file_uris: %w(x y),
99
+ translation_job_uids: %w(1 2))
100
+ end
101
+ end
102
+
103
+ describe 'job_files' do
104
+ it 'GETs the right endpoint' do
105
+ smartling.expect(:get, nil) do |path, query:|
106
+ assert_match %r{jobs-api/v3/projects/1/jobs/x/files}, path
107
+ assert_equal 3, query[:limit]
108
+ assert_equal 1, query[:offset]
109
+ end
110
+ smartling.job_files(project_id: 1, translation_job_uid: 'x', limit: 3,
111
+ offset: 1)
112
+ end
113
+ end
114
+
115
+ describe 'job_progress (with a file uid)' do
116
+ it 'GETs job progress for a file' do
117
+ smartling.expect(:get, nil) do |path, query:|
118
+ assert_match %r{jobs-api/v3/projects/1/jobs/x/progress}, path
119
+ assert_equal 'a', query[:fileUri]
120
+ end
121
+ smartling.job_progress(project_id: 1, translation_job_uid: 'x',
122
+ file_uri: 'a')
123
+ end
124
+ end
125
+
126
+ describe 'job_progress (without a file uid)' do
127
+ it 'GETs job progress for all files' do
128
+ smartling.expect(:get, nil) do |path|
129
+ assert_match %r{jobs-api/v3/projects/1/jobs/x/progress}, path
130
+ end
131
+ smartling.job_progress(project_id: 1, translation_job_uid: 'x')
132
+ end
133
+ end
134
+
135
+ describe 'add_strings_to_job' do
136
+ it 'POSTs the right body to the right endpoint' do
137
+ smartling.expect(:post, nil) do |path, body:|
138
+ assert_match %r{jobs-api/v3/projects/1/jobs/x/strings/add}, path
139
+ assert_equal true, body[:moveEnabled]
140
+ assert_equal %w(x y), body[:hashcodes]
141
+ assert_equal %w(de), body[:targetLocaleIds]
142
+ end
143
+ smartling.add_strings_to_job(project_id: 1, translation_job_uid: 'x',
144
+ move_enabled: true, hashcodes: %w(x y),
145
+ target_locale_ids: %w(de))
146
+ end
147
+ end
148
+
149
+ describe 'remove_strings_from_job' do
150
+ it 'POSTs the right body to the right endpoint' do
151
+ smartling.expect(:post, nil) do |path, body:|
152
+ assert_match %r{jobs-api/v3/projects/1/jobs/x/strings/remove}, path
153
+ assert_equal %w(x y), body[:hashcodes]
154
+ assert_equal %w(de), body[:localeIds]
155
+ end
156
+ smartling.remove_strings_from_job(project_id: 1,
157
+ translation_job_uid: 'x',
158
+ hashcodes: %w(x y),
159
+ locale_ids: %w(de))
160
+ end
161
+ end
162
+
163
+ describe 'add_file_to_job' do
164
+ it 'POSTs the right body to the right endpoint' do
165
+ smartling.expect(:post, nil) do |path, body:|
166
+ assert_match %r{jobs-api/v3/projects/1/jobs/x/file/add}, path
167
+ assert_equal 'z', body[:fileUri]
168
+ assert_equal %w(de), body[:targetLocaleIds]
169
+ end
170
+ smartling.add_file_to_job(project_id: 1, translation_job_uid: 'x',
171
+ file_uri: 'z', target_locale_ids: %w(de))
172
+ end
173
+ end
174
+
175
+ describe 'remove_file_from_job' do
176
+ it 'POSTs the right body to the right endpoint' do
177
+ smartling.expect(:post, nil) do |path, body:|
178
+ assert_match %r{jobs-api/v3/projects/1/jobs/x/file/remove}, path
179
+ assert_equal 'z', body[:fileUri]
180
+ end
181
+ smartling.remove_file_from_job(project_id: 1, translation_job_uid: 'x',
182
+ file_uri: 'z')
183
+ end
184
+ end
185
+
186
+ describe 'add_locale_to_job' do
187
+ it 'POSTs the right body to the right endpoint' do
188
+ smartling.expect(:post, nil) do |path, body:|
189
+ assert_match %r{jobs-api/v3/projects/1/jobs/x/locales/de-AT}, path
190
+ assert_equal true, body[:syncContent]
191
+ end
192
+ smartling.add_locale_to_job(project_id: 1, translation_job_uid: 'x',
193
+ locale_id: 'de-AT', sync_content: true)
194
+ end
195
+ end
196
+
197
+ describe 'remove_locale_from_job' do
198
+ it 'DELETEs the right endpoint' do
199
+ smartling.expect(:delete, nil) do |path|
200
+ assert_match %r{jobs-api/v3/projects/1/jobs/x/locales/de-AT}, path
201
+ end
202
+ smartling.remove_locale_from_job(project_id: 1,
203
+ translation_job_uid: 'x',
204
+ locale_id: 'de-AT')
205
+ end
206
+ end
207
+
208
+ describe 'close_job' do
209
+ it 'POSTs to the right endpoint' do
210
+ smartling.expect(:post, nil) do |path|
211
+ assert_match %r{jobs-api/v3/projects/1/jobs/x/close}, path
212
+ end
213
+ smartling.close_job(project_id: 1, translation_job_uid: 'x')
214
+ end
215
+ end
216
+
217
+ describe 'cancel_job' do
218
+ it 'POSTs the right body to the right endpoint' do
219
+ smartling.expect(:post, nil) do |path, body:|
220
+ assert_match %r{jobs-api/v3/projects/1/jobs/x/cancel}, path
221
+ assert_equal 'Laziness', body[:reason]
222
+ end
223
+ smartling.cancel_job(project_id: 1, translation_job_uid: 'x',
224
+ reason: 'Laziness')
225
+ end
226
+ end
227
+
228
+ describe 'authorize_job' do
229
+ it 'POSTs the right body to the right endpoint' do
230
+ smartling.expect(:post, nil) do |path, body:|
231
+ assert_match %r{jobs-api/v3/projects/1/jobs/x/authorize}, path
232
+ workflow = body[:localeWorkflows].first
233
+ assert_equal 'a', body[:localeWorkflows][0][:targetLocaleId]
234
+ assert_equal 'b', body[:localeWorkflows][0][:workflowUid]
235
+ assert_equal 'c', body[:localeWorkflows][1][:targetLocaleId]
236
+ assert_equal 'd', body[:localeWorkflows][1][:workflowUid]
237
+ end
238
+ locale_workflows = [
239
+ { target_locale_id: 'a', workflow_uid: 'b' },
240
+ { target_locale_id: 'c', workflow_uid: 'd' }
241
+ ]
242
+ smartling.authorize_job(project_id: 1, translation_job_uid: 'x',
243
+ locale_workflows: locale_workflows)
244
+ end
245
+
246
+ it 'does not require workflows' do
247
+ smartling.expect(:post, nil) do |path|
248
+ assert_match %r{jobs-api/v3/projects/1/jobs/x/authorize}, path
249
+ end
250
+ smartling.authorize_job(project_id: 1, translation_job_uid: 'x')
251
+ end
252
+
253
+ it 'explains about workflows if needed' do
254
+ assert_raises(ArgumentError) do
255
+ smartling.authorize_job(project_id: 1, translation_job_uid: 'x',
256
+ locale_workflows: {})
257
+ end
258
+ end
259
+ end
260
+
261
+ describe 'job_process' do
262
+ it 'GETs the right endpoint' do
263
+ smartling.expect(:get, nil) do |path|
264
+ assert_match %r{jobs-api/v3/projects/1/jobs/x/processes/y}, path
265
+ end
266
+ smartling.job_process(project_id: 1, translation_job_uid: 'x',
267
+ process_uid: 'y')
268
+ end
269
+ end
270
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smartring
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
7
  - JJ Buckley
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-04 00:00:00.000000000 Z
11
+ date: 2018-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dotenv
@@ -282,6 +282,7 @@ files:
282
282
  - lib/smartling/client.rb
283
283
  - lib/smartling/contexts.rb
284
284
  - lib/smartling/files.rb
285
+ - lib/smartling/jobs.rb
285
286
  - lib/smartling/strings.rb
286
287
  - lib/smartling/verbs.rb
287
288
  - lib/smartring.rb
@@ -289,6 +290,7 @@ files:
289
290
  - test/smartling/client_test.rb
290
291
  - test/smartling/contexts_test.rb
291
292
  - test/smartling/files_test.rb
293
+ - test/smartling/jobs_test.rb
292
294
  - test/smartling/strings_test.rb
293
295
  - test/smartling_test.rb
294
296
  - test/test_helper.rb