pupilfirst_xapi 0.2.2 → 0.3.4

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: f4c1f6e893b9a58bb193b6ddcbdf806ae9c341c3ff5527f3a2ba6a528cda7a05
4
- data.tar.gz: 87858bf6e6a1b2beaa9bc8a85f9e7bc22424788a8011bc1a476f96fcd52d8370
3
+ metadata.gz: ab3ca34388c5e492e15f05a5768d692af65e56c3f088a1a2958143ab2dcf6152
4
+ data.tar.gz: 80bf4e923f96112d5e1f175f811fcaf1dc7c27709bcd7c937b09eeae4d89c755
5
5
  SHA512:
6
- metadata.gz: a9a7da4741a9151c9251e7f9a31dc149d303a213fadb94cbdccd9a65578fb21bc7adfadfec168f30d6dbbf614fdb372aeb8ac2a967547628d427c046c0c3d944
7
- data.tar.gz: 606c6d2f23faccbc6d30ee80e49b912148a862cc9855ea10814e1d64cd18300ece70469daea7f72093d5dad1cc176a1ddb2b5818a850bb9de9e88ab66982356c
6
+ metadata.gz: ac920b2427236772f18041c7219405fa05812248cc0745029ab62a72896076fb6335dac990e59783b653a6c7c3c5b922610e74b442c75c7a29d9c9fc6a77cb60
7
+ data.tar.gz: 3680b27bd76f6e184ffd307dfa50e9b97e27d46f85c19d49c827e430e02a87be75d6cbff741edbb1219fc19f82d8f755165675149eb273321104fb96511f82e4
@@ -1,6 +1,7 @@
1
1
  require_relative 'objects/builder'
2
2
  require_relative 'objects/course'
3
3
  require_relative 'objects/target'
4
+ require_relative 'objects/video_start'
4
5
 
5
6
  module PupilfirstXapi
6
7
  module Objects
@@ -11,5 +12,14 @@ module PupilfirstXapi
11
12
  def self.target(target, uri_for)
12
13
  Target.new.call(target, uri_for)
13
14
  end
15
+
16
+ def self.video_start(student, video_id, uri_for)
17
+ VideoStart.new.call(student, video_id, uri_for)
18
+ end
19
+
20
+
21
+ def self.video_end(student, video_id, uri_for)
22
+ VideoEnd.new.call(student, video_id, uri_for)
23
+ end
14
24
  end
15
25
  end
@@ -10,6 +10,7 @@ module PupilfirstXapi
10
10
  name: course.name,
11
11
  description: course.description
12
12
  ).tap do |obj|
13
+ obj.with_extension('http://id.tincanapi.com/extension/ending-position', course.targets.count)
13
14
  if course.ends_at.present?
14
15
  duration = ActiveSupport::Duration.build(course.ends_at - course.created_at).iso8601
15
16
  obj.with_extension("http://id.tincanapi.com/extension/planned-duration", duration)
@@ -4,7 +4,6 @@ module PupilfirstXapi
4
4
  def call(target, uri_for)
5
5
  course = target.course
6
6
  target_uri = uri_for.call(target)
7
- course_uri = uri_for.call(course)
8
7
 
9
8
  Builder.new(
10
9
  id: target_uri,
@@ -12,8 +11,8 @@ module PupilfirstXapi
12
11
  name: target.title,
13
12
  description: target.description
14
13
  ).tap do |obj|
15
- obj.with_extension('course_id', course_uri)
16
- obj.with_extension('course_name', course.name)
14
+ obj.with_extension('http://id.tincanapi.com/extension/host', Objects.course(course, uri_for).as_json)
15
+ obj.with_extension('http://id.tincanapi.com/extension/position', target.sort_index)
17
16
  end.call
18
17
  end
19
18
  end
@@ -0,0 +1,17 @@
1
+ module PupilfirstXapi
2
+ module Objects
3
+ class VideoEnd
4
+ def call(student, video_id, uri_for)
5
+ student_uri = uri_for.call(student)
6
+ puts video_id
7
+
8
+ Builder.new(
9
+ id: student_uri,
10
+ type: "http://activitystrea.ms/schema/1.0/event",
11
+ name: student.name,
12
+ description: "student started video #{video_id}"
13
+ ).call
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module PupilfirstXapi
2
+ module Objects
3
+ class VideoStart
4
+ def call(student, video_id, uri_for)
5
+ student_uri = uri_for.call(student)
6
+ puts video_id
7
+
8
+ Builder.new(
9
+ id: student_uri,
10
+ type: "http://activitystrea.ms/schema/1.0/event",
11
+ name: student.name,
12
+ description: "student started video #{video_id}"
13
+ ).call
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,6 +1,8 @@
1
1
  require "pupilfirst_xapi/statements/course_completed"
2
2
  require "pupilfirst_xapi/statements/course_registered"
3
3
  require "pupilfirst_xapi/statements/target_completed"
4
+ require "pupilfirst_xapi/statements/video_started"
5
+ require "pupilfirst_xapi/statements/video_ended"
4
6
 
5
7
  module PupilfirstXapi
6
8
  module Statements
@@ -17,6 +19,8 @@ module PupilfirstXapi
17
19
  :student_added => CourseRegistered,
18
20
  :submission_graded => TargetCompleted,
19
21
  :submission_automatically_verified => TargetCompleted,
22
+ :video_started => VideoStarted,
23
+ :video_ended => VideoEnded
20
24
  }
21
25
  end
22
26
  end
@@ -0,0 +1,19 @@
1
+ module PupilfirstXapi
2
+ module Statements
3
+ class VideoEnded
4
+ def initialize(repository, uri_for)
5
+ @repository = repository
6
+ @uri_for = uri_for
7
+ end
8
+
9
+ def call(actor_id:, resource_id:)
10
+ actor = @repository.call(:user, actor_id)
11
+ Xapi.create_statement(
12
+ actor: Actors.agent(actor),
13
+ verb: Verbs::VIDEO_ENDED,
14
+ object: Objects.video_end(actor, resource_id, @uri_for)
15
+ )
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module PupilfirstXapi
2
+ module Statements
3
+ class VideoStarted
4
+ def initialize(repository, uri_for)
5
+ @repository = repository
6
+ @uri_for = uri_for
7
+ end
8
+
9
+ def call(actor_id:, resource_id:)
10
+ actor = @repository.call(:user, actor_id)
11
+ Xapi.create_statement(
12
+ actor: Actors.agent(actor),
13
+ verb: Verbs::VIDEO_STARTED,
14
+ object: Objects.video_start(actor, resource_id, @uri_for)
15
+ )
16
+ end
17
+ end
18
+ end
19
+ end
@@ -3,5 +3,7 @@ module PupilfirstXapi
3
3
  COMPLETED = Xapi.create_verb(id: 'http://adlnet.gov/expapi/verbs/completed', name: 'completed')
4
4
  COMPLETED_ASSIGNMENT = Xapi.create_verb(id: 'https://w3id.org/xapi/dod-isd/verbs/completed-assignment', name: 'completed assignment')
5
5
  REGISTERED = Xapi.create_verb(id: 'http://adlnet.gov/expapi/verbs/registered', name: 'registered')
6
+ VIDEO_STARTED = Xapi.create_verb(id: 'http://activitystrea.ms/schema/1.0/start', name: 'start')
7
+ VIDEO_ENDED = Xapi.create_verb(id: 'http://activitystrea.ms/schema/1.0/consume', name: 'consumed')
6
8
  end
7
9
  end
@@ -1,3 +1,3 @@
1
1
  module PupilfirstXapi
2
- VERSION = '0.2.2'
2
+ VERSION = '0.3.4'
3
3
  end
@@ -15,7 +15,12 @@ RSpec.describe "#xapi", type: :job, perform_jobs: true do
15
15
  description: 'These guides are designed to make you immediately productive with Rails',
16
16
  created_at: Time.new(2021,01,01),
17
17
  ends_at: nil,
18
- uri: 'https://guides.rubyonrails.org/')
18
+ uri: 'https://guides.rubyonrails.org/',
19
+ targets: [
20
+ double(:target, title: '1st target', description: 'Seems easy'),
21
+ double(:target, title: '2nd target', description: 'Seems not easy')
22
+ ]
23
+ )
19
24
  }
20
25
  let(:getting_started) {
21
26
  double(:target,
@@ -77,6 +82,7 @@ RSpec.describe "#xapi", type: :job, perform_jobs: true do
77
82
  name: {'en-US' => 'Ruby on Rails Guides'},
78
83
  description: {'en-US' => 'These guides are designed to make you immediately productive with Rails'},
79
84
  type: 'http://adlnet.gov/expapi/activities/product',
85
+ extensions: {"http://id.tincanapi.com/extension/ending-position"=>2}
80
86
  },
81
87
  },
82
88
  timestamp: timestamp.iso8601,
data/spec/outbox_spec.rb CHANGED
@@ -4,8 +4,8 @@ module PupilfirstXapi
4
4
  RSpec.describe Outbox do
5
5
  let(:timestamp) { Time.now }
6
6
  let(:john) { double(:john, name: 'John Doe', email: 'john@doe.com') }
7
- let(:course) { double(:course, id: 32, name: 'Rails for Begginers', description: 'Seems easy', created_at: 1.week.ago, ends_at: nil) }
8
- let(:target) { double(:target, title: '1st target', description: 'Seems easy', course: course) }
7
+ let(:course) { double(:course, id: 32, name: 'Rails for Begginers', description: 'Seems easy', created_at: 1.week.ago, ends_at: nil, targets: []) }
8
+ let(:target) { double(:target, title: '1st target', description: 'Seems easy', course: course, sort_index: 7) }
9
9
  let(:good_one) { double(:timeline_event, target: target, passed?: true) }
10
10
  let(:bad_one) { double(:timeline_event, target: target, passed?: false) }
11
11
 
@@ -5,7 +5,11 @@ module PupilfirstXapi
5
5
  RSpec.describe CourseCompleted do
6
6
  it do
7
7
  john = double(:john, name: 'John Doe', email: 'john@doe.com')
8
- course = double(:course, name: 'Rails for Begginers', description: 'Seems easy', created_at: 1.week.ago, ends_at: nil)
8
+ course = double(:course, name: 'Rails for Begginers', description: 'Seems easy', created_at: 1.week.ago, ends_at: nil,
9
+ targets: [
10
+ double(:target, title: '1st target', description: 'Seems easy'),
11
+ double(:target, title: '2nd target', description: 'Seems not easy')
12
+ ])
9
13
  data = {
10
14
  course: { 456 => course },
11
15
  user: { 123 => john },
@@ -5,7 +5,11 @@ module PupilfirstXapi
5
5
  RSpec.describe CourseRegistered do
6
6
  it do
7
7
  john = double(:john, name: 'John Doe', email: 'john@doe.com')
8
- course = double(:course, name: 'Rails for Begginers', description: 'Seems easy', created_at: 1.week.ago, ends_at: nil)
8
+ course = double(:course, name: 'Rails for Begginers', description: 'Seems easy', created_at: 1.week.ago, ends_at: nil,
9
+ targets: [
10
+ double(:target, title: '1st target', description: 'Seems easy'),
11
+ double(:target, title: '2nd target', description: 'Seems not easy')
12
+ ])
9
13
  data = {
10
14
  course: { 456 => course },
11
15
  user: { 123 => john },
@@ -25,7 +29,9 @@ module PupilfirstXapi
25
29
  expect(xapi.object.definition.type).to eq 'http://adlnet.gov/expapi/activities/product'
26
30
  expect(xapi.object.definition.name).to eq({'en-US' => 'Rails for Begginers'})
27
31
  expect(xapi.object.definition.description).to eq({'en-US' => 'Seems easy'})
28
- expect(xapi.object.definition.extensions).to eq nil
32
+ expect(xapi.object.definition.extensions).to eq ({
33
+ "http://id.tincanapi.com/extension/ending-position" => 2
34
+ })
29
35
  end
30
36
 
31
37
  it do
@@ -34,7 +40,11 @@ module PupilfirstXapi
34
40
  duration = ActiveSupport::Duration.build(ends_at - starts_at).iso8601
35
41
 
36
42
  john = double(:john, name: 'John Doe', email: 'john@doe.com')
37
- course = double(:course, name: 'Rails for Begginers', description: 'Seems easy', created_at: starts_at, ends_at: ends_at)
43
+ course = double(:course, name: 'Rails for Begginers', description: 'Seems easy', created_at: starts_at, ends_at: ends_at,
44
+ targets: [
45
+ double(:target, title: '1st target', description: 'Seems easy'),
46
+ double(:target, title: '2nd target', description: 'Seems not easy')
47
+ ])
38
48
  data = {
39
49
  course: { 456 => course },
40
50
  user: { 123 => john },
@@ -54,7 +64,10 @@ module PupilfirstXapi
54
64
  expect(xapi.object.definition.type).to eq 'http://adlnet.gov/expapi/activities/product'
55
65
  expect(xapi.object.definition.name).to eq({'en-US' => 'Rails for Begginers'})
56
66
  expect(xapi.object.definition.description).to eq({'en-US' => 'Seems easy'})
57
- expect(xapi.object.definition.extensions).to eq({"http://id.tincanapi.com/extension/planned-duration" => duration})
67
+ expect(xapi.object.definition.extensions).to eq({
68
+ "http://id.tincanapi.com/extension/planned-duration" => duration,
69
+ "http://id.tincanapi.com/extension/ending-position" => 2
70
+ })
58
71
  end
59
72
  end
60
73
  end
@@ -4,8 +4,12 @@ module PupilfirstXapi
4
4
  module Statements
5
5
  RSpec.describe TargetCompleted do
6
6
  it do
7
- course = double(:course, id: 17, name: 'Rails for Begginers', description: 'Seems easy', created_at: 1.week.ago, ends_at: nil)
8
- target = double(:target, title: '1st target', course: course, description: 'Seems easy')
7
+ course = double(:course, id: 17, name: 'Rails for Begginers', description: 'Seems easy', created_at: 1.week.ago, ends_at: nil,
8
+ targets: [
9
+ double(:target, title: '1st target', description: 'Seems easy'),
10
+ double(:target, title: '2nd target', description: 'Seems not easy')
11
+ ])
12
+ target = double(:target, title: '1st target', course: course, description: 'Seems easy', sort_index: 5)
9
13
  submission = double(:timeline_event, target: target, passed?: true)
10
14
  john = double(:john, name: 'John Doe', email: 'john@doe.com')
11
15
  data = {
@@ -27,14 +31,11 @@ module PupilfirstXapi
27
31
  expect(xapi.object.definition.type).to eq 'http://activitystrea.ms/schema/1.0/task'
28
32
  expect(xapi.object.definition.name).to eq({'en-US' => '1st target'})
29
33
  expect(xapi.object.definition.description).to eq({'en-US' => 'Seems easy'})
30
- expect(xapi.object.definition.extensions).to eq({
31
- 'course_id'=>'course-1',
32
- 'course_name'=>'Rails for Begginers'
33
- })
34
+ expect(xapi.object.definition.extensions['http://id.tincanapi.com/extension/host']['id']).to eq 'course-1'
34
35
  end
35
36
 
36
37
  it 'no-op when submission is not passed' do
37
- target = double(:target, title: '1st target', description: 'Seems easy')
38
+ target = double(:target, title: '1st target', description: 'Seems easy', sort_index: 3)
38
39
  submission = double(:timeline_event, target: target, passed?: false)
39
40
  john = double(:john, name: 'John Doe', email: 'john@doe.com')
40
41
  data = {
metadata CHANGED
@@ -1,22 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pupilfirst_xapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - GrowthTribe
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-13 00:00:00.000000000 Z
11
+ date: 2021-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: 6.0.3
20
17
  - - ">="
21
18
  - !ruby/object:Gem::Version
22
19
  version: 6.0.3.4
@@ -24,9 +21,6 @@ dependencies:
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
- - - "~>"
28
- - !ruby/object:Gem::Version
29
- version: 6.0.3
30
24
  - - ">="
31
25
  - !ruby/object:Gem::Version
32
26
  version: 6.0.3.4
@@ -86,7 +80,7 @@ dependencies:
86
80
  - - ">="
87
81
  - !ruby/object:Gem::Version
88
82
  version: '0'
89
- description:
83
+ description:
90
84
  email:
91
85
  - devs@growthtribe.io
92
86
  executables: []
@@ -103,11 +97,15 @@ files:
103
97
  - lib/pupilfirst_xapi/objects/builder.rb
104
98
  - lib/pupilfirst_xapi/objects/course.rb
105
99
  - lib/pupilfirst_xapi/objects/target.rb
100
+ - lib/pupilfirst_xapi/objects/video_end.rb
101
+ - lib/pupilfirst_xapi/objects/video_start.rb
106
102
  - lib/pupilfirst_xapi/outbox.rb
107
103
  - lib/pupilfirst_xapi/statements.rb
108
104
  - lib/pupilfirst_xapi/statements/course_completed.rb
109
105
  - lib/pupilfirst_xapi/statements/course_registered.rb
110
106
  - lib/pupilfirst_xapi/statements/target_completed.rb
107
+ - lib/pupilfirst_xapi/statements/video_ended.rb
108
+ - lib/pupilfirst_xapi/statements/video_started.rb
111
109
  - lib/pupilfirst_xapi/verbs.rb
112
110
  - lib/pupilfirst_xapi/version.rb
113
111
  - spec/integration_spec.rb
@@ -126,7 +124,7 @@ metadata:
126
124
  homepage_uri: https://github.com/growthtribeacademy/pupilfirst-xapi
127
125
  source_code_uri: https://github.com/growthtribeacademy/pupilfirst-xapi/pupilfirst_xapi
128
126
  changelog_uri: https://github.com/growthtribeacademy/pupilfirst-xapi/pupilfirst_xapi/CHANGELOG.md
129
- post_install_message:
127
+ post_install_message:
130
128
  rdoc_options: []
131
129
  require_paths:
132
130
  - lib
@@ -141,17 +139,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
139
  - !ruby/object:Gem::Version
142
140
  version: '0'
143
141
  requirements: []
144
- rubygems_version: 3.2.3
145
- signing_key:
142
+ rubygems_version: 3.1.6
143
+ signing_key:
146
144
  specification_version: 4
147
145
  summary: XAPI statements generator and publisher to LRS for Pupilfirst
148
146
  test_files:
149
- - spec/integration_spec.rb
150
147
  - spec/objects/builder_spec.rb
151
- - spec/outbox_job_spec.rb
152
- - spec/outbox_spec.rb
153
148
  - spec/rails_helper.rb
154
- - spec/spec_helper.rb
149
+ - spec/statements/target_completed_spec.rb
155
150
  - spec/statements/course_completed_spec.rb
156
151
  - spec/statements/course_registered_spec.rb
157
- - spec/statements/target_completed_spec.rb
152
+ - spec/spec_helper.rb
153
+ - spec/outbox_spec.rb
154
+ - spec/integration_spec.rb
155
+ - spec/outbox_job_spec.rb