tin_can_api 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +7 -0
- data/README.md +6 -13
- data/lib/tin_can_api.rb +0 -1
- data/lib/tin_can_api/remote_lrs.rb +390 -2
- data/lib/tin_can_api/version.rb +1 -1
- data/spec/tin_can_api/{client_spec.rb → remote_lrs_spec.rb} +5 -5
- metadata +5 -5
- data/lib/tin_can_api/client.rb +0 -402
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34eb8a3a0790178d886e761965671f776b61257d
|
4
|
+
data.tar.gz: 7078806b6b01848da7096efb4ec86cf39053a0c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83e078eddade7130ed70c6c9277af8192adfe53d79f78ccc0106d8f2e901c35212e0df0f7a68e8e09c9ab3814554b093263a764bb975a172f9cc81347443aec7
|
7
|
+
data.tar.gz: 14bd8ef72039acbbd3fe49545f1a94bc646a16443098cc2711386f672afc8fb63ebaa7cd8a4625ea83e88e27fec8bda66cf1e962e5234e625f239206e341536c
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
## Contributing
|
2
|
+
|
3
|
+
1. Fork it ( https://github.com/pwcoleman/tin_can_api/fork )
|
4
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
5
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
6
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
7
|
+
5. Create a new Pull Request
|
data/README.md
CHANGED
@@ -28,9 +28,9 @@ Or install it yourself as:
|
|
28
28
|
|
29
29
|
## Usage
|
30
30
|
|
31
|
-
Create a
|
31
|
+
Create a remote LRS using basic auth
|
32
32
|
```ruby
|
33
|
-
|
33
|
+
remote_lrs = TinCanApi::RemoteLRS.new do |c|
|
34
34
|
c.end_point = 'https://some.endpoint.com'
|
35
35
|
c.user_name = 'user'
|
36
36
|
c.password = 'password'
|
@@ -40,8 +40,8 @@ end
|
|
40
40
|
Connect to the 'about' endpoint to get version information
|
41
41
|
|
42
42
|
```ruby
|
43
|
-
# use the
|
44
|
-
response =
|
43
|
+
# use the remote LRS from above
|
44
|
+
response = remote_lrs.about
|
45
45
|
# check if it is successful
|
46
46
|
if response.success
|
47
47
|
# access the TinCanApi::About instance
|
@@ -62,19 +62,12 @@ statement = TinCanApi::Statement.new do |s|
|
|
62
62
|
s.object = activity
|
63
63
|
end
|
64
64
|
|
65
|
-
response =
|
65
|
+
response = remote_lrs.save_statement(statement)
|
66
66
|
if response.success
|
67
67
|
# access the statement
|
68
68
|
response.content
|
69
69
|
end
|
70
70
|
```
|
71
71
|
|
72
|
-
For more API calls check out the TinCanApi::
|
72
|
+
For more API calls check out the TinCanApi::RemoteLRS class
|
73
73
|
|
74
|
-
## Contributing
|
75
|
-
|
76
|
-
1. Fork it ( https://github.com/pwcoleman/tin_can_api/fork )
|
77
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
78
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
79
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
80
|
-
5. Create a new Pull Request
|
data/lib/tin_can_api.rb
CHANGED
@@ -1,14 +1,402 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require 'faraday'
|
3
|
+
require 'addressable/uri'
|
2
4
|
require 'tin_can_api/tcapi_version'
|
3
5
|
module TinCanApi
|
4
6
|
# Class used to communicate with a TCAPI endpoint synchronously
|
5
7
|
class RemoteLRS
|
6
8
|
include TinCanApi::TCAPIVersion
|
7
9
|
|
10
|
+
VALID_PARAMS = %w(end_point user_name password version)
|
11
|
+
|
8
12
|
attr_accessor :end_point, :user_name, :password, :version
|
9
13
|
|
10
|
-
def initialize(
|
11
|
-
|
14
|
+
def initialize(options={}, &block)
|
15
|
+
setup_options(options)
|
16
|
+
yield_or_eval(&block) if block_given?
|
17
|
+
@version ||= latest_version
|
18
|
+
end
|
19
|
+
|
20
|
+
def about
|
21
|
+
response = connection.get("#{path}about")
|
22
|
+
LrsResponse.new do |lrs|
|
23
|
+
lrs.status = response.status
|
24
|
+
if response.status== 200
|
25
|
+
lrs.content = About.new(json: response.body)
|
26
|
+
lrs.success = true
|
27
|
+
else
|
28
|
+
lrs.success = false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def save_statement(statement)
|
34
|
+
# TODO: Complete this
|
35
|
+
if statement.id
|
36
|
+
response = connection.put do |req|
|
37
|
+
req.url("#{path}statements")
|
38
|
+
req.headers['Content-Type'] = 'application/json'
|
39
|
+
req.params.merge!({'statementId' => statement.id})
|
40
|
+
req.body = statement.serialize(latest_version).to_json
|
41
|
+
end
|
42
|
+
else
|
43
|
+
response = connection.post do |req|
|
44
|
+
req.url("#{path}statements")
|
45
|
+
req.headers['Content-Type'] = 'application/json'
|
46
|
+
req.body = statement.serialize(latest_version).to_json
|
47
|
+
end
|
48
|
+
end
|
49
|
+
LrsResponse.new do |lrs|
|
50
|
+
lrs.status = response.status
|
51
|
+
lrs.content = statement
|
52
|
+
if response.status == 200
|
53
|
+
statement.id = JSON.parse(response.body).first
|
54
|
+
lrs.success = true
|
55
|
+
elsif response.status == 204
|
56
|
+
lrs.success = true
|
57
|
+
else
|
58
|
+
lrs.success = false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def save_statements(statements)
|
64
|
+
# TODO: Complete this
|
65
|
+
if statements.empty?
|
66
|
+
return LrsResponse.new do |lrs|
|
67
|
+
lrs.success = true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
response = connection.post do |req|
|
71
|
+
req.url("#{path}statements")
|
72
|
+
req.headers['Content-Type'] = 'application/json'
|
73
|
+
req.body = statements.map {|s| s.serialize(latest_version)}.to_json
|
74
|
+
end
|
75
|
+
LrsResponse.new do |lrs|
|
76
|
+
lrs.status = response.status
|
77
|
+
if response.status == 200
|
78
|
+
lrs.content = statements
|
79
|
+
ids = JSON.parse(response.body)
|
80
|
+
statements.each_with_index do |statement, index|
|
81
|
+
statement.id = ids[index]
|
82
|
+
end
|
83
|
+
lrs.success = true
|
84
|
+
else
|
85
|
+
lrs.success = false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def retrieve_statement(id)
|
91
|
+
get_statement(id, 'statementId')
|
92
|
+
end
|
93
|
+
|
94
|
+
def retrieve_voided_statement(id)
|
95
|
+
param_name = version == TCAPIVersion.V095 ? 'statementId' : 'voidedStatementId'
|
96
|
+
get_statement(id, param_name)
|
97
|
+
end
|
98
|
+
|
99
|
+
def query_statements(statement_query)
|
100
|
+
# TODO: Complete this
|
101
|
+
query = statement_query
|
102
|
+
unless query
|
103
|
+
query = version == TCAPIVersion::V095 ? StatementsQueryV095.new : StatementsQuery.new
|
104
|
+
end
|
105
|
+
# Error if the query parameters don't match the LRS version
|
106
|
+
raise Errors::IncompatibleTCAPIVersion, "Attempted to issue #{version} query using a #{query.version} set of query parameters." unless version == query.version
|
107
|
+
|
108
|
+
response = connection.get do |req|
|
109
|
+
req.url("#{path}statements")
|
110
|
+
req.params.merge!(query.parameter_map)
|
111
|
+
end
|
112
|
+
LrsResponse.new do |lrs|
|
113
|
+
lrs.status = response.status
|
114
|
+
if response.status == 200
|
115
|
+
# TODO: FIX THIS
|
116
|
+
lrs.success = true
|
117
|
+
lrs.content = StatementsResult.new(json: response.body)
|
118
|
+
else
|
119
|
+
lrs.success = false
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def more_statements(more_url)
|
125
|
+
# TODO: Complete this
|
126
|
+
# more_url is relative to the endpoint's server root
|
127
|
+
response = connection.get do |req|
|
128
|
+
req.url("#{path}#{more_url}")
|
129
|
+
end
|
130
|
+
LrsResponse.new do |lrs|
|
131
|
+
lrs.status = response.status
|
132
|
+
if response.status == 200
|
133
|
+
# TODO: FIX THIS
|
134
|
+
lrs.success = true
|
135
|
+
lrs.content = StatementsResult.new(json: response.body)
|
136
|
+
else
|
137
|
+
lrs.success = false
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def retrieve_state_ids(activity, agent, registration)
|
143
|
+
# TODO: Complete this
|
144
|
+
query_params = {
|
145
|
+
'activityId' => activity.id,
|
146
|
+
'agent' => agent.serialize(version).to_json
|
147
|
+
}
|
148
|
+
query_params['registration'] = registration if registration
|
149
|
+
get_profile_keys('activities/state', query_params)
|
150
|
+
end
|
151
|
+
|
152
|
+
def retrieve_state(id, activity, agent, registration)
|
153
|
+
# TODO: Complete this
|
154
|
+
query_params = {
|
155
|
+
'stateId' => id,
|
156
|
+
'activityId' => activity.id,
|
157
|
+
'agent' => agent.serialize(version).to_json
|
158
|
+
}
|
159
|
+
document = StateDocument.new do |sd|
|
160
|
+
sd.id = id
|
161
|
+
sd.activity = activity
|
162
|
+
sd.agent = agent
|
163
|
+
end
|
164
|
+
lrs_response = get_document('activities/state', query_params, document)
|
165
|
+
if lrs_response.status == 200
|
166
|
+
lrs_response.content = document
|
167
|
+
end
|
168
|
+
lrs_response
|
169
|
+
end
|
170
|
+
|
171
|
+
def save_state(state)
|
172
|
+
# TODO: Complete this
|
173
|
+
query_params = {
|
174
|
+
'stateId' => state.id,
|
175
|
+
'activityId' => state.activity.id,
|
176
|
+
'agent' => state.agent.serialize(version).to_json
|
177
|
+
}
|
178
|
+
save_document('activities/state', query_params, state)
|
179
|
+
end
|
180
|
+
|
181
|
+
def delete_state(state)
|
182
|
+
# TODO: Complete this
|
183
|
+
query_params = {
|
184
|
+
'stateId' => state.id,
|
185
|
+
'activityId' => state.activity.id,
|
186
|
+
'agent' => state.agent.serialize(version).to_json
|
187
|
+
}
|
188
|
+
query_params['registration'] = state.registration if state.registration
|
189
|
+
delete_document('activities/state', query_params)
|
190
|
+
end
|
191
|
+
|
192
|
+
def clear_state(activity, agent, registration)
|
193
|
+
# TODO: Complete this
|
194
|
+
query_params = {
|
195
|
+
'activityId' => activity.id,
|
196
|
+
'agent' => agent.serialize(version).to_json
|
197
|
+
}
|
198
|
+
query_params['registration'] = registration if registration
|
199
|
+
delete_document('activities/state', query_params)
|
200
|
+
end
|
201
|
+
|
202
|
+
def retrieve_activity_profile_ids(activity)
|
203
|
+
# TODO: Complete this
|
204
|
+
query_params = {
|
205
|
+
'activityId' => activity.id
|
206
|
+
}
|
207
|
+
get_profile_keys('activities/profile', query_params)
|
208
|
+
end
|
209
|
+
|
210
|
+
def retrieve_activity_profile(id, activity)
|
211
|
+
# TODO: Complete this
|
212
|
+
query_params = {
|
213
|
+
'profileId' => id,
|
214
|
+
'activityId' => activity.id,
|
215
|
+
}
|
216
|
+
document = ActivityProfileDocument.new do |apd|
|
217
|
+
apd.id = id
|
218
|
+
apd.activity = activity
|
219
|
+
end
|
220
|
+
lrs_response = get_document('activities/profile', query_params, document)
|
221
|
+
if lrs_response.status == 200
|
222
|
+
lrs_response.content = document
|
223
|
+
end
|
224
|
+
lrs_response
|
225
|
+
end
|
226
|
+
|
227
|
+
def save_activity_profile(profile)
|
228
|
+
# TODO: Complete this
|
229
|
+
query_params = {
|
230
|
+
'profileId' => profile.id,
|
231
|
+
'activityId' => profile.activity.id,
|
232
|
+
}
|
233
|
+
save_document('activities/profile', query_params, profile)
|
234
|
+
end
|
235
|
+
|
236
|
+
def delete_activity_profile(profile)
|
237
|
+
# TODO: Complete this
|
238
|
+
query_params = {
|
239
|
+
'profileId' => profile.id,
|
240
|
+
'activityId' => profile.activity.id,
|
241
|
+
}
|
242
|
+
delete_document('activities/profile', query_params)
|
243
|
+
end
|
244
|
+
|
245
|
+
def retrieve_agent_profile_ids(agent)
|
246
|
+
# TODO: Complete this
|
247
|
+
query_params = {
|
248
|
+
'agent' => agent.serialize(version).to_json
|
249
|
+
}
|
250
|
+
get_profile_keys('agents/profile', query_params)
|
251
|
+
end
|
252
|
+
|
253
|
+
def retrieve_agent_profile(id, agent)
|
254
|
+
# TODO: Complete this
|
255
|
+
query_params = {
|
256
|
+
'profileId' => id,
|
257
|
+
'agent' => agent.serialize(version).to_json
|
258
|
+
}
|
259
|
+
document = AgentProfileDocument.new do |apd|
|
260
|
+
apd.id = id
|
261
|
+
apd.agent = agent
|
262
|
+
end
|
263
|
+
lrs_response = get_document('agents/profile', query_params, document)
|
264
|
+
if lrs_response.status == 200
|
265
|
+
lrs_response.content = document
|
266
|
+
end
|
267
|
+
lrs_response
|
268
|
+
end
|
269
|
+
|
270
|
+
def save_agent_profile(profile)
|
271
|
+
# TODO: Complete this
|
272
|
+
query_params = {
|
273
|
+
'profileId' => profile.id,
|
274
|
+
'agent' => profile.agent.serialize(version).to_json
|
275
|
+
}
|
276
|
+
save_document('agents/profile', query_params, profile)
|
277
|
+
end
|
278
|
+
|
279
|
+
def delete_agent_profile(profile)
|
280
|
+
# TODO: Complete this
|
281
|
+
query_params = {
|
282
|
+
'profileId' => profile.id,
|
283
|
+
'agent' => profile.agent.serialize(version).to_json
|
284
|
+
}
|
285
|
+
delete_document('agents/profile', query_params)
|
286
|
+
end
|
287
|
+
|
288
|
+
private
|
289
|
+
|
290
|
+
def setup_options(options={})
|
291
|
+
options.each_pair do |key, value|
|
292
|
+
if value && VALID_PARAMS.include?(key.to_s)
|
293
|
+
instance_variable_set("@#{key}", value)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
def yield_or_eval(&block)
|
299
|
+
return unless block
|
300
|
+
block.arity < 1 ? instance_eval(&block) : block[self]
|
301
|
+
end
|
302
|
+
|
303
|
+
def uri
|
304
|
+
@uri ||= Addressable::URI.parse(end_point)
|
305
|
+
end
|
306
|
+
|
307
|
+
def path
|
308
|
+
@path ||= uri.path
|
309
|
+
@path += '/' unless @path.end_with?('/')
|
310
|
+
@path
|
311
|
+
end
|
312
|
+
|
313
|
+
def connection
|
314
|
+
base_url = "#{uri.scheme}://#{uri.host}"
|
315
|
+
base_url = "#{base_url}:#{uri.port}" if uri.port
|
316
|
+
@connection ||= Faraday.new(:url => base_url) do |faraday|
|
317
|
+
faraday.request :url_encoded # form-encode POST params
|
318
|
+
faraday.response :logger # log requests to STDOUT
|
319
|
+
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
|
320
|
+
faraday.headers['X-Experience-API-Version'] = version.to_s
|
321
|
+
faraday.basic_auth(user_name, password)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
def get_statement(id, parameter)
|
326
|
+
response = connection.get do |req|
|
327
|
+
req.url("#{path}statements")
|
328
|
+
req.headers['Content-Type'] = 'application/json'
|
329
|
+
req.params.merge!({parameter => id})
|
330
|
+
end
|
331
|
+
LrsResponse.new do |lrs|
|
332
|
+
lrs.status = response.status
|
333
|
+
if response.status== 200
|
334
|
+
lrs.content = Statement.new(json: response.body)
|
335
|
+
lrs.success = true
|
336
|
+
else
|
337
|
+
lrs.success = false
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
def get_document(resource, params, document)
|
343
|
+
response = connection.get do |req|
|
344
|
+
req.url("#{path}#{resource}")
|
345
|
+
req.params.merge!(params)
|
346
|
+
end
|
347
|
+
LrsResponse.new do |lrs|
|
348
|
+
lrs.status = response.status
|
349
|
+
if response.status == 200
|
350
|
+
lrs.success = true
|
351
|
+
# TODO FIX THIS
|
352
|
+
elsif response.status == 404
|
353
|
+
lrs.success = true
|
354
|
+
else
|
355
|
+
lrs.success = false
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
def delete_document(resource, params)
|
361
|
+
response = connection.delete do |req|
|
362
|
+
req.url("#{path}#{resource}")
|
363
|
+
req.params.merge!(params)
|
364
|
+
end
|
365
|
+
LrsResponse.new do |lrs|
|
366
|
+
lrs.status = response.status
|
367
|
+
if response.status == 204
|
368
|
+
lrs.success = true
|
369
|
+
else
|
370
|
+
lrs.success = false
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
def save_document(resource, params, document)
|
376
|
+
# TODO: Complete this
|
377
|
+
response = connection.put do |req|
|
378
|
+
req.url("#{path}#{resource}")
|
379
|
+
req.headers['Content-Type'] = 'application/json'
|
380
|
+
req.headers['If-Match'] = document.etag if document.etag
|
381
|
+
req.params.merge!(params)
|
382
|
+
req.body = document.content
|
383
|
+
end
|
384
|
+
LrsResponse.new do |lrs|
|
385
|
+
lrs.status = response.status
|
386
|
+
if response.status == 204
|
387
|
+
lrs.success = true
|
388
|
+
else
|
389
|
+
lrs.success = false
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
def get_profile_keys(resource, params)
|
395
|
+
# TODO FIX THIS
|
396
|
+
connection.get do |req|
|
397
|
+
req.url("#{path}#{resource}")
|
398
|
+
req.params.merge!(params)
|
399
|
+
end
|
12
400
|
end
|
13
401
|
|
14
402
|
end
|
data/lib/tin_can_api/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
describe TinCanApi::
|
4
|
+
describe TinCanApi::RemoteLRS do
|
5
5
|
include Helpers
|
6
6
|
|
7
7
|
describe 'about' do
|
@@ -13,13 +13,13 @@ describe TinCanApi::Client do
|
|
13
13
|
body: fixture('about.json'),
|
14
14
|
headers: {})
|
15
15
|
|
16
|
-
|
16
|
+
remote_lrs = TinCanApi::RemoteLRS.new do |c|
|
17
17
|
c.end_point = 'http://www.example.com'
|
18
18
|
c.user_name = 'user'
|
19
19
|
c.password = 'password'
|
20
20
|
end
|
21
21
|
|
22
|
-
response =
|
22
|
+
response = remote_lrs.about
|
23
23
|
expect(response.success).to be(true)
|
24
24
|
end
|
25
25
|
|
@@ -31,13 +31,13 @@ describe TinCanApi::Client do
|
|
31
31
|
body: fixture('about.json'),
|
32
32
|
headers: {})
|
33
33
|
|
34
|
-
|
34
|
+
remote_lrs = TinCanApi::RemoteLRS.new do |c|
|
35
35
|
c.end_point = 'http://www.example.com'
|
36
36
|
c.user_name = 'user'
|
37
37
|
c.password = 'password'
|
38
38
|
end
|
39
39
|
|
40
|
-
response =
|
40
|
+
response = remote_lrs.about
|
41
41
|
expect(response.content).to be_a(TinCanApi::About)
|
42
42
|
end
|
43
43
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tin_can_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Coleman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -132,6 +132,7 @@ extra_rdoc_files: []
|
|
132
132
|
files:
|
133
133
|
- .gitignore
|
134
134
|
- .rspec
|
135
|
+
- CONTRIBUTING.md
|
135
136
|
- Gemfile
|
136
137
|
- LICENSE.txt
|
137
138
|
- README.md
|
@@ -143,7 +144,6 @@ files:
|
|
143
144
|
- lib/tin_can_api/agent.rb
|
144
145
|
- lib/tin_can_api/agent_account.rb
|
145
146
|
- lib/tin_can_api/attachment.rb
|
146
|
-
- lib/tin_can_api/client.rb
|
147
147
|
- lib/tin_can_api/context.rb
|
148
148
|
- lib/tin_can_api/context_activities.rb
|
149
149
|
- lib/tin_can_api/documents/activity_profile_document.rb
|
@@ -179,11 +179,11 @@ files:
|
|
179
179
|
- spec/tin_can_api/agent_account_spec.rb
|
180
180
|
- spec/tin_can_api/agent_spec.rb
|
181
181
|
- spec/tin_can_api/attachment_spec.rb
|
182
|
-
- spec/tin_can_api/client_spec.rb
|
183
182
|
- spec/tin_can_api/context_activities_spec.rb
|
184
183
|
- spec/tin_can_api/context_spec.rb
|
185
184
|
- spec/tin_can_api/group_spec.rb
|
186
185
|
- spec/tin_can_api/interaction_component_spec.rb
|
186
|
+
- spec/tin_can_api/remote_lrs_spec.rb
|
187
187
|
- spec/tin_can_api/result_spec.rb
|
188
188
|
- spec/tin_can_api/score_spec.rb
|
189
189
|
- spec/tin_can_api/statement_ref_spec.rb
|
@@ -225,11 +225,11 @@ test_files:
|
|
225
225
|
- spec/tin_can_api/agent_account_spec.rb
|
226
226
|
- spec/tin_can_api/agent_spec.rb
|
227
227
|
- spec/tin_can_api/attachment_spec.rb
|
228
|
-
- spec/tin_can_api/client_spec.rb
|
229
228
|
- spec/tin_can_api/context_activities_spec.rb
|
230
229
|
- spec/tin_can_api/context_spec.rb
|
231
230
|
- spec/tin_can_api/group_spec.rb
|
232
231
|
- spec/tin_can_api/interaction_component_spec.rb
|
232
|
+
- spec/tin_can_api/remote_lrs_spec.rb
|
233
233
|
- spec/tin_can_api/result_spec.rb
|
234
234
|
- spec/tin_can_api/score_spec.rb
|
235
235
|
- spec/tin_can_api/statement_ref_spec.rb
|
data/lib/tin_can_api/client.rb
DELETED
@@ -1,402 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'faraday'
|
3
|
-
require 'addressable/uri'
|
4
|
-
require 'tin_can_api/tcapi_version'
|
5
|
-
module TinCanApi
|
6
|
-
# Class used to communicate with a TCAPI endpoint synchronously
|
7
|
-
class Client
|
8
|
-
include TinCanApi::TCAPIVersion
|
9
|
-
|
10
|
-
VALID_PARAMS = %w(end_point user_name password version)
|
11
|
-
|
12
|
-
attr_accessor :end_point, :user_name, :password, :version
|
13
|
-
|
14
|
-
def initialize(options={}, &block)
|
15
|
-
setup_options(options)
|
16
|
-
yield_or_eval(&block) if block_given?
|
17
|
-
@version ||= latest_version
|
18
|
-
end
|
19
|
-
|
20
|
-
def about
|
21
|
-
response = connection.get("#{path}about")
|
22
|
-
LrsResponse.new do |lrs|
|
23
|
-
lrs.status = response.status
|
24
|
-
if response.status== 200
|
25
|
-
lrs.content = About.new(json: response.body)
|
26
|
-
lrs.success = true
|
27
|
-
else
|
28
|
-
lrs.success = false
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def save_statement(statement)
|
34
|
-
# TODO: Complete this
|
35
|
-
if statement.id
|
36
|
-
response = connection.put do |req|
|
37
|
-
req.url("#{path}statements")
|
38
|
-
req.headers['Content-Type'] = 'application/json'
|
39
|
-
req.params.merge!({'statementId' => statement.id})
|
40
|
-
req.body = statement.serialize(latest_version).to_json
|
41
|
-
end
|
42
|
-
else
|
43
|
-
response = connection.post do |req|
|
44
|
-
req.url("#{path}statements")
|
45
|
-
req.headers['Content-Type'] = 'application/json'
|
46
|
-
req.body = statement.serialize(latest_version).to_json
|
47
|
-
end
|
48
|
-
end
|
49
|
-
LrsResponse.new do |lrs|
|
50
|
-
lrs.status = response.status
|
51
|
-
lrs.content = statement
|
52
|
-
if response.status == 200
|
53
|
-
statement.id = JSON.parse(response.body).first
|
54
|
-
lrs.success = true
|
55
|
-
elsif response.status == 204
|
56
|
-
lrs.success = true
|
57
|
-
else
|
58
|
-
lrs.success = false
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def save_statements(statements)
|
64
|
-
# TODO: Complete this
|
65
|
-
if statements.empty?
|
66
|
-
return LrsResponse.new do |lrs|
|
67
|
-
lrs.success = true
|
68
|
-
end
|
69
|
-
end
|
70
|
-
response = connection.post do |req|
|
71
|
-
req.url("#{path}statements")
|
72
|
-
req.headers['Content-Type'] = 'application/json'
|
73
|
-
req.body = statements.map {|s| s.serialize(latest_version)}.to_json
|
74
|
-
end
|
75
|
-
LrsResponse.new do |lrs|
|
76
|
-
lrs.status = response.status
|
77
|
-
if response.status == 200
|
78
|
-
lrs.content = statements
|
79
|
-
ids = JSON.parse(response.body)
|
80
|
-
statements.each_with_index do |statement, index|
|
81
|
-
statement.id = ids[index]
|
82
|
-
end
|
83
|
-
lrs.success = true
|
84
|
-
else
|
85
|
-
lrs.success = false
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def retrieve_statement(id)
|
91
|
-
get_statement(id, 'statementId')
|
92
|
-
end
|
93
|
-
|
94
|
-
def retrieve_voided_statement(id)
|
95
|
-
param_name = version == TCAPIVersion.V095 ? 'statementId' : 'voidedStatementId'
|
96
|
-
get_statement(id, param_name)
|
97
|
-
end
|
98
|
-
|
99
|
-
def query_statements(statement_query)
|
100
|
-
# TODO: Complete this
|
101
|
-
query = statement_query
|
102
|
-
unless query
|
103
|
-
query = version == TCAPIVersion::V095 ? StatementsQueryV095.new : StatementsQuery.new
|
104
|
-
end
|
105
|
-
# Error if the query parameters don't match the LRS version
|
106
|
-
raise Errors::IncompatibleTCAPIVersion, "Attempted to issue #{version} query using a #{query.version} set of query parameters." unless version == query.version
|
107
|
-
|
108
|
-
response = connection.get do |req|
|
109
|
-
req.url("#{path}statements")
|
110
|
-
req.params.merge!(query.parameter_map)
|
111
|
-
end
|
112
|
-
LrsResponse.new do |lrs|
|
113
|
-
lrs.status = response.status
|
114
|
-
if response.status == 200
|
115
|
-
# TODO: FIX THIS
|
116
|
-
lrs.success = true
|
117
|
-
lrs.content = StatementsResult.new(json: response.body)
|
118
|
-
else
|
119
|
-
lrs.success = false
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
def more_statements(more_url)
|
125
|
-
# TODO: Complete this
|
126
|
-
# more_url is relative to the endpoint's server root
|
127
|
-
response = connection.get do |req|
|
128
|
-
req.url("#{path}#{more_url}")
|
129
|
-
end
|
130
|
-
LrsResponse.new do |lrs|
|
131
|
-
lrs.status = response.status
|
132
|
-
if response.status == 200
|
133
|
-
# TODO: FIX THIS
|
134
|
-
lrs.success = true
|
135
|
-
lrs.content = StatementsResult.new(json: response.body)
|
136
|
-
else
|
137
|
-
lrs.success = false
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
def retrieve_state_ids(activity, agent, registration)
|
143
|
-
# TODO: Complete this
|
144
|
-
query_params = {
|
145
|
-
'activityId' => activity.id,
|
146
|
-
'agent' => agent.serialize(version).to_json
|
147
|
-
}
|
148
|
-
query_params['registration'] = registration if registration
|
149
|
-
get_profile_keys('activities/state', query_params)
|
150
|
-
end
|
151
|
-
|
152
|
-
def retrieve_state(id, activity, agent, registration)
|
153
|
-
# TODO: Complete this
|
154
|
-
query_params = {
|
155
|
-
'stateId' => id,
|
156
|
-
'activityId' => activity.id,
|
157
|
-
'agent' => agent.serialize(version).to_json
|
158
|
-
}
|
159
|
-
document = StateDocument.new do |sd|
|
160
|
-
sd.id = id
|
161
|
-
sd.activity = activity
|
162
|
-
sd.agent = agent
|
163
|
-
end
|
164
|
-
lrs_response = get_document('activities/state', query_params, document)
|
165
|
-
if lrs_response.status == 200
|
166
|
-
lrs_response.content = document
|
167
|
-
end
|
168
|
-
lrs_response
|
169
|
-
end
|
170
|
-
|
171
|
-
def save_state(state)
|
172
|
-
# TODO: Complete this
|
173
|
-
query_params = {
|
174
|
-
'stateId' => state.id,
|
175
|
-
'activityId' => state.activity.id,
|
176
|
-
'agent' => state.agent.serialize(version).to_json
|
177
|
-
}
|
178
|
-
save_document('activities/state', query_params, state)
|
179
|
-
end
|
180
|
-
|
181
|
-
def delete_state(state)
|
182
|
-
# TODO: Complete this
|
183
|
-
query_params = {
|
184
|
-
'stateId' => state.id,
|
185
|
-
'activityId' => state.activity.id,
|
186
|
-
'agent' => state.agent.serialize(version).to_json
|
187
|
-
}
|
188
|
-
query_params['registration'] = state.registration if state.registration
|
189
|
-
delete_document('activities/state', query_params)
|
190
|
-
end
|
191
|
-
|
192
|
-
def clear_state(activity, agent, registration)
|
193
|
-
# TODO: Complete this
|
194
|
-
query_params = {
|
195
|
-
'activityId' => activity.id,
|
196
|
-
'agent' => agent.serialize(version).to_json
|
197
|
-
}
|
198
|
-
query_params['registration'] = registration if registration
|
199
|
-
delete_document('activities/state', query_params)
|
200
|
-
end
|
201
|
-
|
202
|
-
def retrieve_activity_profile_ids(activity)
|
203
|
-
# TODO: Complete this
|
204
|
-
query_params = {
|
205
|
-
'activityId' => activity.id
|
206
|
-
}
|
207
|
-
get_profile_keys('activities/profile', query_params)
|
208
|
-
end
|
209
|
-
|
210
|
-
def retrieve_activity_profile(id, activity)
|
211
|
-
# TODO: Complete this
|
212
|
-
query_params = {
|
213
|
-
'profileId' => id,
|
214
|
-
'activityId' => activity.id,
|
215
|
-
}
|
216
|
-
document = ActivityProfileDocument.new do |apd|
|
217
|
-
apd.id = id
|
218
|
-
apd.activity = activity
|
219
|
-
end
|
220
|
-
lrs_response = get_document('activities/profile', query_params, document)
|
221
|
-
if lrs_response.status == 200
|
222
|
-
lrs_response.content = document
|
223
|
-
end
|
224
|
-
lrs_response
|
225
|
-
end
|
226
|
-
|
227
|
-
def save_activity_profile(profile)
|
228
|
-
# TODO: Complete this
|
229
|
-
query_params = {
|
230
|
-
'profileId' => profile.id,
|
231
|
-
'activityId' => profile.activity.id,
|
232
|
-
}
|
233
|
-
save_document('activities/profile', query_params, profile)
|
234
|
-
end
|
235
|
-
|
236
|
-
def delete_activity_profile(profile)
|
237
|
-
# TODO: Complete this
|
238
|
-
query_params = {
|
239
|
-
'profileId' => profile.id,
|
240
|
-
'activityId' => profile.activity.id,
|
241
|
-
}
|
242
|
-
delete_document('activities/profile', query_params)
|
243
|
-
end
|
244
|
-
|
245
|
-
def retrieve_agent_profile_ids(agent)
|
246
|
-
# TODO: Complete this
|
247
|
-
query_params = {
|
248
|
-
'agent' => agent.serialize(version).to_json
|
249
|
-
}
|
250
|
-
get_profile_keys('agents/profile', query_params)
|
251
|
-
end
|
252
|
-
|
253
|
-
def retrieve_agent_profile(id, agent)
|
254
|
-
# TODO: Complete this
|
255
|
-
query_params = {
|
256
|
-
'profileId' => id,
|
257
|
-
'agent' => agent.serialize(version).to_json
|
258
|
-
}
|
259
|
-
document = AgentProfileDocument.new do |apd|
|
260
|
-
apd.id = id
|
261
|
-
apd.agent = agent
|
262
|
-
end
|
263
|
-
lrs_response = get_document('agents/profile', query_params, document)
|
264
|
-
if lrs_response.status == 200
|
265
|
-
lrs_response.content = document
|
266
|
-
end
|
267
|
-
lrs_response
|
268
|
-
end
|
269
|
-
|
270
|
-
def save_agent_profile(profile)
|
271
|
-
# TODO: Complete this
|
272
|
-
query_params = {
|
273
|
-
'profileId' => profile.id,
|
274
|
-
'agent' => profile.agent.serialize(version).to_json
|
275
|
-
}
|
276
|
-
save_document('agents/profile', query_params, profile)
|
277
|
-
end
|
278
|
-
|
279
|
-
def delete_agent_profile(profile)
|
280
|
-
# TODO: Complete this
|
281
|
-
query_params = {
|
282
|
-
'profileId' => profile.id,
|
283
|
-
'agent' => profile.agent.serialize(version).to_json
|
284
|
-
}
|
285
|
-
delete_document('agents/profile', query_params)
|
286
|
-
end
|
287
|
-
|
288
|
-
private
|
289
|
-
|
290
|
-
def setup_options(options={})
|
291
|
-
options.each_pair do |key, value|
|
292
|
-
if value && VALID_PARAMS.include?(key.to_s)
|
293
|
-
instance_variable_set("@#{key}", value)
|
294
|
-
end
|
295
|
-
end
|
296
|
-
end
|
297
|
-
|
298
|
-
def yield_or_eval(&block)
|
299
|
-
return unless block
|
300
|
-
block.arity < 1 ? instance_eval(&block) : block[self]
|
301
|
-
end
|
302
|
-
|
303
|
-
def uri
|
304
|
-
@uri ||= Addressable::URI.parse(end_point)
|
305
|
-
end
|
306
|
-
|
307
|
-
def path
|
308
|
-
@path ||= uri.path
|
309
|
-
@path += '/' unless @path.end_with?('/')
|
310
|
-
@path
|
311
|
-
end
|
312
|
-
|
313
|
-
def connection
|
314
|
-
base_url = "#{uri.scheme}://#{uri.host}"
|
315
|
-
base_url = "#{base_url}:#{uri.port}" if uri.port
|
316
|
-
@connection ||= Faraday.new(:url => base_url) do |faraday|
|
317
|
-
faraday.request :url_encoded # form-encode POST params
|
318
|
-
faraday.response :logger # log requests to STDOUT
|
319
|
-
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
|
320
|
-
faraday.headers['X-Experience-API-Version'] = version.to_s
|
321
|
-
faraday.basic_auth(user_name, password)
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
def get_statement(id, parameter)
|
326
|
-
response = connection.get do |req|
|
327
|
-
req.url("#{path}statements")
|
328
|
-
req.headers['Content-Type'] = 'application/json'
|
329
|
-
req.params.merge!({parameter => id})
|
330
|
-
end
|
331
|
-
LrsResponse.new do |lrs|
|
332
|
-
lrs.status = response.status
|
333
|
-
if response.status== 200
|
334
|
-
lrs.content = Statement.new(json: response.body)
|
335
|
-
lrs.success = true
|
336
|
-
else
|
337
|
-
lrs.success = false
|
338
|
-
end
|
339
|
-
end
|
340
|
-
end
|
341
|
-
|
342
|
-
def get_document(resource, params, document)
|
343
|
-
response = connection.get do |req|
|
344
|
-
req.url("#{path}#{resource}")
|
345
|
-
req.params.merge!(params)
|
346
|
-
end
|
347
|
-
LrsResponse.new do |lrs|
|
348
|
-
lrs.status = response.status
|
349
|
-
if response.status == 200
|
350
|
-
lrs.success = true
|
351
|
-
# TODO FIX THIS
|
352
|
-
elsif response.status == 404
|
353
|
-
lrs.success = true
|
354
|
-
else
|
355
|
-
lrs.success = false
|
356
|
-
end
|
357
|
-
end
|
358
|
-
end
|
359
|
-
|
360
|
-
def delete_document(resource, params)
|
361
|
-
response = connection.delete do |req|
|
362
|
-
req.url("#{path}#{resource}")
|
363
|
-
req.params.merge!(params)
|
364
|
-
end
|
365
|
-
LrsResponse.new do |lrs|
|
366
|
-
lrs.status = response.status
|
367
|
-
if response.status == 204
|
368
|
-
lrs.success = true
|
369
|
-
else
|
370
|
-
lrs.success = false
|
371
|
-
end
|
372
|
-
end
|
373
|
-
end
|
374
|
-
|
375
|
-
def save_document(resource, params, document)
|
376
|
-
# TODO: Complete this
|
377
|
-
response = connection.put do |req|
|
378
|
-
req.url("#{path}#{resource}")
|
379
|
-
req.headers['Content-Type'] = 'application/json'
|
380
|
-
req.headers['If-Match'] = document.etag if document.etag
|
381
|
-
req.params.merge!(params)
|
382
|
-
req.body = document.content
|
383
|
-
end
|
384
|
-
LrsResponse.new do |lrs|
|
385
|
-
lrs.status = response.status
|
386
|
-
if response.status == 204
|
387
|
-
lrs.success = true
|
388
|
-
else
|
389
|
-
lrs.success = false
|
390
|
-
end
|
391
|
-
end
|
392
|
-
end
|
393
|
-
|
394
|
-
def get_profile_keys(resource, params)
|
395
|
-
# TODO FIX THIS
|
396
|
-
connection.get do |req|
|
397
|
-
req.url("#{path}#{resource}")
|
398
|
-
req.params.merge!(params)
|
399
|
-
end
|
400
|
-
end
|
401
|
-
end
|
402
|
-
end
|