tin_can_api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +24 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +80 -0
  7. data/Rakefile +12 -0
  8. data/lib/tin_can_api/about.rb +15 -0
  9. data/lib/tin_can_api/activity.rb +41 -0
  10. data/lib/tin_can_api/activity_definition.rb +139 -0
  11. data/lib/tin_can_api/agent.rb +44 -0
  12. data/lib/tin_can_api/agent_account.rb +33 -0
  13. data/lib/tin_can_api/attachment.rb +64 -0
  14. data/lib/tin_can_api/client.rb +402 -0
  15. data/lib/tin_can_api/context.rb +54 -0
  16. data/lib/tin_can_api/context_activities.rb +102 -0
  17. data/lib/tin_can_api/documents/activity_profile_document.rb +15 -0
  18. data/lib/tin_can_api/documents/agent_profile_document.rb +15 -0
  19. data/lib/tin_can_api/documents/document.rb +20 -0
  20. data/lib/tin_can_api/documents/state_document.rb +15 -0
  21. data/lib/tin_can_api/enum.rb +42 -0
  22. data/lib/tin_can_api/errors.rb +9 -0
  23. data/lib/tin_can_api/group.rb +37 -0
  24. data/lib/tin_can_api/interaction_component.rb +32 -0
  25. data/lib/tin_can_api/interaction_type.rb +58 -0
  26. data/lib/tin_can_api/lrs_response.rb +14 -0
  27. data/lib/tin_can_api/query_result_format.rb +6 -0
  28. data/lib/tin_can_api/remote_lrs.rb +15 -0
  29. data/lib/tin_can_api/result.rb +45 -0
  30. data/lib/tin_can_api/score.rb +39 -0
  31. data/lib/tin_can_api/statement.rb +53 -0
  32. data/lib/tin_can_api/statement_ref.rb +31 -0
  33. data/lib/tin_can_api/statements/statements_base.rb +70 -0
  34. data/lib/tin_can_api/statements_query.rb +42 -0
  35. data/lib/tin_can_api/statements_query_v095.rb +42 -0
  36. data/lib/tin_can_api/statements_result.rb +17 -0
  37. data/lib/tin_can_api/sub_statement.rb +19 -0
  38. data/lib/tin_can_api/tcapi_version.rb +27 -0
  39. data/lib/tin_can_api/verb.rb +35 -0
  40. data/lib/tin_can_api/version.rb +4 -0
  41. data/lib/tin_can_api.rb +37 -0
  42. data/spec/fixtures/about.json +10 -0
  43. data/spec/fixtures/statement.json +33 -0
  44. data/spec/spec_helper.rb +106 -0
  45. data/spec/support/helpers.rb +43 -0
  46. data/spec/tin_can_api/activity_definition_spec.rb +37 -0
  47. data/spec/tin_can_api/activity_spec.rb +23 -0
  48. data/spec/tin_can_api/agent_account_spec.rb +13 -0
  49. data/spec/tin_can_api/agent_spec.rb +24 -0
  50. data/spec/tin_can_api/attachment_spec.rb +26 -0
  51. data/spec/tin_can_api/client_spec.rb +44 -0
  52. data/spec/tin_can_api/context_activities_spec.rb +57 -0
  53. data/spec/tin_can_api/context_spec.rb +32 -0
  54. data/spec/tin_can_api/group_spec.rb +15 -0
  55. data/spec/tin_can_api/interaction_component_spec.rb +18 -0
  56. data/spec/tin_can_api/result_spec.rb +26 -0
  57. data/spec/tin_can_api/score_spec.rb +12 -0
  58. data/spec/tin_can_api/statement_ref_spec.rb +19 -0
  59. data/spec/tin_can_api/statement_spec.rb +57 -0
  60. data/spec/tin_can_api/sub_statement_spec.rb +30 -0
  61. data/spec/tin_can_api/verb_spec.rb +17 -0
  62. data/tin_can_api.gemspec +30 -0
  63. metadata +238 -0
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ # Group model class
4
+ class Group < Agent
5
+
6
+ attr_accessor :members
7
+
8
+ def initialize(options={}, &block)
9
+ super(options, &block)
10
+
11
+ @object_type = 'Group'
12
+ @members = []
13
+ json = options.fetch(:json, nil)
14
+ if json
15
+ attributes = JSON.parse(json)
16
+ attributes['member'].each do |member|
17
+ members << Agent.new(json: member.to_json)
18
+ end
19
+ else
20
+ self.members = options.fetch(:members, nil)
21
+
22
+ if block_given?
23
+ block[self]
24
+ end
25
+ end
26
+ end
27
+
28
+ def serialize(version)
29
+ node = super(version)
30
+ if members.any?
31
+ node['member'] = members.map {|member| member.serialize(version)}
32
+ end
33
+ node
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ # InteractionComponent Class Description
4
+ class InteractionComponent
5
+
6
+ attr_accessor :id, :description
7
+
8
+ def initialize(options={}, &block)
9
+ json = options.fetch(:json, nil)
10
+ if json
11
+ attributes = JSON.parse(json)
12
+ self.id = attributes['id'] if attributes['id']
13
+ self.description = attributes['description'] if attributes['description']
14
+ else
15
+ self.id = options.fetch(:id, nil)
16
+ self.description = options.fetch(:description, nil)
17
+
18
+ if block_given?
19
+ block[self]
20
+ end
21
+ end
22
+ end
23
+
24
+ def serialize(version)
25
+ node = {}
26
+ node['id'] = id if id
27
+ node['description'] = description if description
28
+ node
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ # Possible interaction types
4
+ module InteractionType
5
+
6
+ CHOICE = {
7
+ to_s: 'choice',
8
+ get_value: proc{'choice'}
9
+ }
10
+
11
+ SEQUENCING = {
12
+ to_s: 'sequencing',
13
+ get_value: proc{'sequencing'}
14
+ }
15
+
16
+ LIKERT = {
17
+ to_s: 'likert',
18
+ get_value: proc{'likert'}
19
+ }
20
+
21
+ MATCHING = {
22
+ to_s: 'matching',
23
+ get_value: proc{'matching'}
24
+ }
25
+
26
+ PERFORMANCE = {
27
+ to_s: 'performance',
28
+ get_value: proc{'performance'}
29
+ }
30
+
31
+ TRUE_FALSE = {
32
+ to_s: 'true-false',
33
+ get_value: proc{'true-false'}
34
+ }
35
+
36
+ FILL_IN = {
37
+ to_s: 'fill-in',
38
+ get_value: proc{'fill-in'}
39
+ }
40
+
41
+ NUMERIC = {
42
+ to_s: 'numeric',
43
+ get_value: proc{'numeric'}
44
+ }
45
+
46
+ OTHER = {
47
+ to_s: 'other',
48
+ get_value: proc{'other'}
49
+ }
50
+
51
+ def type_by_string(type)
52
+ values.select{|v| v.to_s == type}.first
53
+ end
54
+
55
+ extend TinCanApi::Enum
56
+
57
+ end
58
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ class LrsResponse
4
+ attr_accessor :success, :error_message, :content, :status
5
+
6
+ def initialize(&block)
7
+ if block_given?
8
+ block[self]
9
+ end
10
+ end
11
+
12
+
13
+ end
14
+ end
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ module QueryResultFormat
4
+
5
+ end
6
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ require 'tin_can_api/tcapi_version'
3
+ module TinCanApi
4
+ # Class used to communicate with a TCAPI endpoint synchronously
5
+ class RemoteLRS
6
+ include TinCanApi::TCAPIVersion
7
+
8
+ attr_accessor :end_point, :user_name, :password, :version
9
+
10
+ def initialize(version=V101)
11
+ @version = version
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+ require 'ruby-duration'
3
+ module TinCanApi
4
+ # Result Model class
5
+ class Result
6
+
7
+ attr_accessor :score, :success, :completion, :duration, :response, :extensions
8
+
9
+ def initialize(options={}, &block)
10
+ json = options.fetch(:json, nil)
11
+ if json
12
+ attributes = JSON.parse(json)
13
+ self.score = TinCanApi::Score.new(json: attributes['score'].to_json) if attributes['score']
14
+ self.success = attributes['success'] if attributes['success']
15
+ self.completion = attributes['completion'] if attributes['completion']
16
+ self.duration = Duration.new(attributes['duration']) if attributes['duration']
17
+ self.response = attributes['response'] if attributes['response']
18
+ self.extensions = attributes['extensions'] if attributes['extensions']
19
+ else
20
+ self.score = options.fetch(:score, nil)
21
+ self.success = options.fetch(:success, nil)
22
+ self.completion = options.fetch(:completion, nil)
23
+ self.duration = options.fetch(:duration, nil)
24
+ self.response = options.fetch(:response, nil)
25
+ self.extensions = options.fetch(:extensions, nil)
26
+
27
+ if block_given?
28
+ block[self]
29
+ end
30
+ end
31
+ end
32
+
33
+ def serialize(version)
34
+ node = {}
35
+ node['score'] = score.serialize(version) if score
36
+ node['success'] = success if success
37
+ node['completion'] = completion if completion
38
+ node['duration'] = duration.iso8601 if duration
39
+ node['response'] = response if response
40
+ node['extensions'] = extensions if extensions
41
+
42
+ node
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ # Score model class
4
+ class Score
5
+
6
+ attr_accessor :scaled, :raw, :min, :max
7
+
8
+ def initialize(options={}, &block)
9
+ json = options.fetch(:json, nil)
10
+ if json
11
+ attributes = JSON.parse(json)
12
+ self.scaled = attributes['scaled'] if attributes['scaled']
13
+ self.raw = attributes['raw'] if attributes['raw']
14
+ self.min = attributes['min'] if attributes['min']
15
+ self.max = attributes['max'] if attributes['max']
16
+ else
17
+ self.scaled = options.fetch(:scaled, nil)
18
+ self.raw = options.fetch(:raw, nil)
19
+ self.min = options.fetch(:min, nil)
20
+ self.max = options.fetch(:max, nil)
21
+
22
+ if block_given?
23
+ block[self]
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ def serialize(version)
30
+ node = {}
31
+ node['scaled'] = scaled if scaled
32
+ node['raw'] = raw if raw
33
+ node['min'] = min if min
34
+ node['max'] = max if max
35
+ node
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ # Statement Class
4
+ class Statement < Statements::StatementsBase
5
+
6
+ attr_accessor :id, :stored, :authority, :version, :voided
7
+
8
+ def initialize(options={}, &block)
9
+ super(options, &block)
10
+ json = options.fetch(:json, nil)
11
+ if json
12
+ attributes = JSON.parse(json)
13
+ self.id = attributes['id'] if attributes['id']
14
+ self.stored = Time.parse(attributes['stored']) if attributes['stored']
15
+ self.authority = TinCanApi::Agent.new(json: attributes['authority'].to_json) if attributes['authority']
16
+ self.version = attributes['version'] if attributes['version']
17
+ self.voided = attributes['voided'] if attributes['voided']
18
+ else
19
+ self.id = options.fetch(:id, nil)
20
+ self.stored = options.fetch(:stored, nil)
21
+ self.authority = options.fetch(:authority, nil)
22
+ self.version = options.fetch(:version, nil)
23
+ self.voided = options.fetch(:voided, nil)
24
+
25
+ if block_given?
26
+ block[self]
27
+ end
28
+ end
29
+ end
30
+
31
+ def serialize(version)
32
+ node = super(version)
33
+
34
+ node['id'] = id if id
35
+ node['stored'] = stored.strftime('%FT%T%:z') if stored
36
+ node['authority'] = authority.serialize(version) if authority
37
+
38
+ if version == TinCanApi::TCAPIVersion::V095
39
+ node['voided'] = voided if voided
40
+ end
41
+
42
+ if version.ordinal <= TinCanApi::TCAPIVersion::V100.ordinal
43
+ node['version'] = version.to_s if version
44
+ end
45
+ node
46
+ end
47
+
48
+ def stamp
49
+ @id = SecureRandom.uuid
50
+ @timestamp = Time.now
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ # StatementRef Class used when referencing another statement from a statement's object property
4
+ class StatementRef
5
+
6
+ attr_accessor :object_type, :id
7
+
8
+ def initialize(options={}, &block)
9
+ @object_type = 'StatementRef'
10
+ json = options.fetch(:json, nil)
11
+ if json
12
+ attributes = JSON.parse(json)
13
+ self.id = attributes['id'] if attributes['id']
14
+ else
15
+ self.id = options.fetch(:id, nil)
16
+
17
+ if block_given?
18
+ block[self]
19
+ end
20
+ end
21
+ end
22
+
23
+ def serialize(version)
24
+ node = {}
25
+ node['id'] = id if id
26
+ node['objectType'] = object_type
27
+ node
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,70 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ module Statements
4
+ class StatementsBase
5
+
6
+ attr_accessor :actor, :verb, :object, :result, :context, :timestamp, :attachments, :voided
7
+
8
+ def initialize(options={}, &block)
9
+ @attachments = []
10
+ json = options.fetch(:json, nil)
11
+ if json
12
+ attributes = JSON.parse(json)
13
+ self.actor = TinCanApi::Agent.new(json: attributes['actor'].to_json) if attributes['actor']
14
+ self.verb = TinCanApi::Verb.new(json: attributes['verb'].to_json) if attributes['verb']
15
+ object_node = attributes['object']
16
+ if object_node
17
+ case object_node['objectType']
18
+ when 'Group', 'Agent'
19
+ self.object = TinCanApi::Agent.new(json: object_node.to_json)
20
+ when 'StatementRef'
21
+ self.object = TinCanApi::StatementRef.new(json: object_node.to_json)
22
+ when 'SubStatement'
23
+ self.object = TinCanApi::SubStatement.new(json: object_node.to_json)
24
+ else
25
+ self.object = TinCanApi::Activity.new(json: object_node.to_json)
26
+ end
27
+ end
28
+ self.result = TinCanApi::Result.new(json: attributes['result'].to_json) if attributes['result']
29
+ self.context = TinCanApi::Context.new(json: attributes['context'].to_json) if attributes['context']
30
+ self.timestamp = Time.parse(attributes['timestamp']) if attributes['timestamp']
31
+ self.voided = attributes['voided'] if attributes['voided']
32
+ if attributes['attachments']
33
+ attributes['attachments'].each do |attachment|
34
+ attachments << TinCanApi::Attachment.new(json: attachment.to_json)
35
+ end
36
+ end
37
+ else
38
+ self.actor = options.fetch(:actor, nil)
39
+ self.verb = options.fetch(:verb, nil)
40
+ self.object = options.fetch(:object, nil)
41
+ self.result = options.fetch(:result, nil)
42
+ self.context = options.fetch(:context, nil)
43
+ self.timestamp = options.fetch(:timestamp, nil)
44
+ self.attachments = options.fetch(:attachments, nil)
45
+ self.voided = options.fetch(:voided, nil)
46
+
47
+ if block_given?
48
+ block[self]
49
+ end
50
+ end
51
+ end
52
+
53
+ def serialize(version)
54
+ node = {}
55
+ node['actor'] = actor.serialize(version)
56
+ node['verb'] = verb.serialize(version)
57
+ node['object'] = object.serialize(version)
58
+ node['result'] = result.serialize(version) if result
59
+ node['context'] = context.serialize(version) if context
60
+ node['timestamp'] = timestamp.strftime('%FT%T%:z') if timestamp
61
+ if version.ordinal <= TinCanApi::TCAPIVersion::V100.ordinal
62
+ if attachments && attachments.any?
63
+ node['attachments'] = attachments.map {|element| element.serialize(version)}
64
+ end
65
+ end
66
+ node
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ class StatementsQuery
4
+
5
+ attr_reader :version, :verb_id
6
+ attr_accessor :agent, :activity_id, :registration, :related_activities, :related_agents
7
+ attr_accessor :stored_since, :stored_until, :limit, :format, :ascending
8
+
9
+ def initialize(&block)
10
+ self.version = TCAPIVersion::V101
11
+ if block_given?
12
+ block[self]
13
+ end
14
+ end
15
+
16
+ def verb_id=(value)
17
+ if value.is_a?(Verb)
18
+ @verb_id = value.id
19
+ else
20
+ @verb_id = Addressable::URI.parse(value)
21
+ end
22
+ end
23
+
24
+ def parameter_map
25
+ params = {}
26
+ params['agent'] = agent.serialize(version) if agent
27
+ params['verb'] = verb_id.to_s if verb_id
28
+ params['activity'] = activity_id.to_s if activity_id
29
+ params['registration'] = registration if registration
30
+ params['related_activities'] = related_activities if related_activities
31
+ params['related_agents'] = related_agents if related_agents
32
+ params['since'] = stored_since.strftime('%FT%T%:z') if stored_since
33
+ params['until'] = stored_until.strftime('%FT%T%:z') if stored_until
34
+ params['limit'] = limit if limit
35
+ params['format'] = format if format
36
+ params['ascending'] = ascending if ascending
37
+
38
+ params
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ class StatementsQueryV095
4
+
5
+ attr_reader :version, :verb_id
6
+ attr_accessor :object, :registration, :context, :actor, :stored_since, :stored_until, :limit
7
+ attr_accessor :authoritative, :sparse, :instructor, :ascending
8
+
9
+ def initialize(&block)
10
+ self.version = TCAPIVersion::V095
11
+ if block_given?
12
+ block[self]
13
+ end
14
+ end
15
+
16
+ def verb_id=(value)
17
+ if value.is_a?(Verb)
18
+ @verb_id = value.id
19
+ else
20
+ @verb_id = Addressable::URI.parse(value)
21
+ end
22
+ end
23
+
24
+ def parameter_map
25
+ params = {}
26
+ params['verb'] = verb_id.to_s if verb_id
27
+ params['object'] = object.serialize(version) if object
28
+ params['registration'] = registration if registration
29
+ params['context'] = context if context
30
+ params['actor'] = actor if actor
31
+ params['since'] = stored_since.strftime('%FT%T%:z') if stored_since
32
+ params['until'] = stored_until.strftime('%FT%T%:z') if stored_until
33
+ params['limit'] = limit if limit
34
+ params['authoritative'] = authoritative if authoritative
35
+ params['sparse'] = sparse if sparse
36
+ params['instructor'] = instructor.serialize(version) if instructor
37
+ params['ascending'] = ascending if ascending
38
+
39
+ params
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ # Statements result model class, returned by LRS calls to get multiple statements
4
+ class StatementsResult
5
+
6
+ attr_accessor :statements, :more_url
7
+
8
+ def initialize(options={})
9
+ json = options.fetch(:json, nil)
10
+ self.statements = []
11
+ if json
12
+ self.statements = json['statements'].map {|statement| Statement.new(json: statement)} if json['statements']
13
+ self.more_url = json['more'] if json['more']
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ class SubStatement < Statements::StatementsBase
4
+
5
+ attr_accessor :object_type
6
+
7
+ def initialize(options={}, &block)
8
+ @object_type = 'SubStatement'
9
+ super(options, &block)
10
+ end
11
+
12
+ def serialize(version)
13
+ node = super(version)
14
+ node['objectType'] = object_type
15
+ node
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ module TCAPIVersion
4
+
5
+ V101 = {
6
+ to_s: '1.0.1',
7
+ get_value: proc{'1.0.1'}
8
+ }
9
+
10
+ V100 = {
11
+ to_s: '1.0.0',
12
+ get_value: proc{'1.0.0'}
13
+ }
14
+
15
+ V095 = {
16
+ to_s: '0.95',
17
+ get_value: proc{'0.95'}
18
+ }
19
+
20
+ def latest_version
21
+ V101
22
+ end
23
+
24
+ extend TinCanApi::Enum
25
+
26
+ end
27
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ class Verb
4
+
5
+ attr_accessor :id, :display
6
+
7
+ def initialize(options={}, &block)
8
+ json = options.fetch(:json, nil)
9
+ if json
10
+ attributes = JSON.parse(json)
11
+ self.id = attributes['id'] if attributes['id']
12
+ self.display = attributes['display'] if attributes['display']
13
+ else
14
+ self.id = options.fetch(:id, nil)
15
+ self.display = options.fetch(:display, nil)
16
+
17
+ if block_given?
18
+ block[self]
19
+ end
20
+ end
21
+ end
22
+
23
+ def id=(value)
24
+ @id = Addressable::URI.parse(value) if value
25
+ end
26
+
27
+ def serialize(version)
28
+ node = {}
29
+ node['id'] = id.to_s if id
30
+ node['display'] = display if display
31
+ node
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+ module TinCanApi
3
+ VERSION = "0.0.1"
4
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ require 'tin_can_api/errors'
3
+ require 'tin_can_api/enum'
4
+ require 'tin_can_api/version'
5
+ require 'tin_can_api/interaction_type'
6
+ require 'tin_can_api/about'
7
+ require 'tin_can_api/agent_account'
8
+ require 'tin_can_api/agent'
9
+ require 'tin_can_api/group'
10
+ require 'tin_can_api/verb'
11
+ require 'tin_can_api/interaction_component'
12
+ require 'tin_can_api/documents/document'
13
+ require 'tin_can_api/score'
14
+ require 'tin_can_api/result'
15
+ require 'tin_can_api/attachment'
16
+ require 'tin_can_api/activity_definition'
17
+ require 'tin_can_api/activity'
18
+ require 'tin_can_api/context_activities'
19
+ require 'tin_can_api/context'
20
+ require 'tin_can_api/statements/statements_base'
21
+ require 'tin_can_api/statement'
22
+ require 'tin_can_api/sub_statement'
23
+ require 'tin_can_api/statement_ref'
24
+ require 'tin_can_api/statements_query'
25
+ require 'tin_can_api/statements_query_v095'
26
+ require 'tin_can_api/lrs_response'
27
+ require "tin_can_api/remote_lrs"
28
+ require 'tin_can_api/client'
29
+
30
+ begin
31
+ require 'pry'
32
+ rescue LoadError
33
+ end
34
+
35
+ module TinCanApi
36
+ # Your code goes here...
37
+ end
@@ -0,0 +1,10 @@
1
+ {
2
+ "extensions" : {
3
+ "http://id.tincanapi.com/extension/powered-by" : {
4
+ "name" : "Tin Can Engine",
5
+ "homePage" : "http://tincanapi.com/lrs-lms/lrs-for-lmss-home/",
6
+ "version" : "2012.1.0.8c644"
7
+ }
8
+ },
9
+ "version" : [ "0.9", "0.95", "1.0.1" ]
10
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "id": "06a6cbbb-b09c-4618-88a8-e8aa6884ad42",
3
+ "actor": {
4
+ "mbox": "mailto:tincanruby@tincanapi.com",
5
+ "objectType": "Agent"
6
+ },
7
+ "verb": {
8
+ "id": "http://adlnet.gov/expapi/verbs/experienced",
9
+ "display": {
10
+ "en-GB": "experienced",
11
+ "en-US": "experienced"
12
+ }
13
+ },
14
+ "timestamp": "2015-03-27T13:14:42.081Z",
15
+ "stored": "2015-03-27T13:14:42.081Z",
16
+ "authority": {
17
+ "account": {
18
+ "homePage": "http://example.com/",
19
+ "name": "ABCDEFGHI"
20
+ },
21
+ "objectType": "Agent"
22
+ },
23
+ "version": "1.0.1",
24
+ "object": {
25
+ "id": "http://tincanapi.com/TinCanRuby/Test/Unit/0",
26
+ "definition": {
27
+ "name": {"en-US": "TinCanJava Tests: Unit 0"},
28
+ "description": {"en-US": "Unit test 0 in the test suite for the Tin Can Ruby library."},
29
+ "type": "http://id.tincanapi.com/activitytype/unit-test"
30
+ },
31
+ "objectType": "Activity"
32
+ }
33
+ }