kgrift 1.3.108
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 +7 -0
- data/KGrift/Gemfile +22 -0
- data/KGrift/README.md +66 -0
- data/KGrift/bin/kgrift +11 -0
- data/KGrift/grifter.yml +224 -0
- data/KGrift/internal_test_graphs/basic_test_graph_definition.yml +2915 -0
- data/KGrift/internal_test_graphs/unicode_test_graph_definition.yml +3070 -0
- data/KGrift/knewton_grifts/analytics_grifts.rb +103 -0
- data/KGrift/knewton_grifts/async_helper_grifts.rb +63 -0
- data/KGrift/knewton_grifts/authenticator_grifts.rb +46 -0
- data/KGrift/knewton_grifts/basic_grifts.rb +29 -0
- data/KGrift/knewton_grifts/batch_grifts.rb +14 -0
- data/KGrift/knewton_grifts/content_collection_grifts.rb +204 -0
- data/KGrift/knewton_grifts/content_collection_v1_grifts.rb +521 -0
- data/KGrift/knewton_grifts/content_eid_grifts.rb +41 -0
- data/KGrift/knewton_grifts/copy_grifts.rb +151 -0
- data/KGrift/knewton_grifts/deprecated_graph_and_taxonomy_grifts.rb +353 -0
- data/KGrift/knewton_grifts/goal_grifts.rb +203 -0
- data/KGrift/knewton_grifts/graph_and_taxonomy_grifts.rb +136 -0
- data/KGrift/knewton_grifts/graph_create_grifts.rb +34 -0
- data/KGrift/knewton_grifts/graph_query_grifts.rb +448 -0
- data/KGrift/knewton_grifts/graph_tools_grifts.rb +151 -0
- data/KGrift/knewton_grifts/graph_validation_grifts.rb +447 -0
- data/KGrift/knewton_grifts/helper_grifts.rb +92 -0
- data/KGrift/knewton_grifts/jmeter_data_grifts.rb +56 -0
- data/KGrift/knewton_grifts/learning_instance_grifts.rb +46 -0
- data/KGrift/knewton_grifts/looper_grifts.rb +34 -0
- data/KGrift/knewton_grifts/moxy_grifts.rb +64 -0
- data/KGrift/knewton_grifts/oauth_grifts.rb +182 -0
- data/KGrift/knewton_grifts/partner_grifts.rb +70 -0
- data/KGrift/knewton_grifts/partner_support_grifts.rb +85 -0
- data/KGrift/knewton_grifts/recommendation_setup_grifts.rb +215 -0
- data/KGrift/knewton_grifts/registration_grifts.rb +159 -0
- data/KGrift/knewton_grifts/registration_info_grifts.rb +23 -0
- data/KGrift/knewton_grifts/report_grifts.rb +122 -0
- data/KGrift/knewton_grifts/shell_command_grifts.rb +21 -0
- data/KGrift/knewton_grifts/student_flow_grifts.rb +560 -0
- data/KGrift/knewton_grifts/tag_grifts.rb +41 -0
- data/KGrift/knewton_grifts/test_data_grifts.rb +328 -0
- data/KGrift/knewton_grifts/test_user_grifts.rb +264 -0
- data/KGrift/lib/dtrace.rb +20 -0
- data/KGrift/lib/kgrift.rb +7 -0
- data/KGrift/test_data_generators/basic_book_and_taxonomies.rb +35 -0
- data/KGrift/test_data_generators/lo_test_graph.rb +34 -0
- data/KGrift/test_data_generators/partner_owned_book_and_taxonomies.rb +28 -0
- data/KGrift/test_data_generators/partner_owned_book_and_taxonomies_unicode.rb +28 -0
- data/KGrift/test_data_generators/sandcastle_book_and_taxonomies.rb +13 -0
- data/KGrift/test_data_generators/sandcastle_book_and_taxonomies.yml +3709 -0
- data/KGrift/test_data_generators/sandcastle_graph.rb +8 -0
- data/KGrift/test_data_generators/sandcastle_graph_definition.json +4483 -0
- data/KGrift/test_data_generators/sandcastle_graph_full.rb +7 -0
- data/KGrift/test_data_generators/sandcastle_taxonomies.yml +378 -0
- data/KGrift/test_data_generators/sandcastle_with_taxons.rb +56 -0
- data/KGrift/test_data_generators/sandcastle_with_taxons.yml +3994 -0
- data/KGrift/test_data_generators/test_users_and_partners.rb +76 -0
- data/kgrift.gemspec +43 -0
- metadata +144 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
#NOTICE: this only lists test partners, which does not include the Knewton partner
|
2
|
+
def list_partners overrides={}
|
3
|
+
params = {
|
4
|
+
"test_partners" => true
|
5
|
+
}.merge(overrides).delete_if{|k,v| v.nil?}
|
6
|
+
|
7
|
+
Log.info "Listing all partners"
|
8
|
+
kapi.get '/v0/partners?' + URI.encode_www_form(params), timeout: 3600
|
9
|
+
end
|
10
|
+
|
11
|
+
def list_prod_partners overrides={}
|
12
|
+
params = {
|
13
|
+
'test_partners' => false,
|
14
|
+
}.merge(overrides)
|
15
|
+
list_partners params
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_partner overrides={}
|
19
|
+
Log.info "Creating a partner"
|
20
|
+
kapi.post '/v0/partners', {
|
21
|
+
'name' => random_string,
|
22
|
+
'password' => random_string,
|
23
|
+
'is_testing' => true,
|
24
|
+
'display_name' => 'KGriftTestingPartner_' + random_string(16),
|
25
|
+
'rate_limit_multiplier' => 1.0,
|
26
|
+
}.merge(overrides)
|
27
|
+
end
|
28
|
+
|
29
|
+
def update_partner id, payload
|
30
|
+
Log.info "Updating partner: #{id}"
|
31
|
+
kapi.put "/v0/partners/#{id}", payload
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_partner id
|
35
|
+
Log.info "Getting a partner: " + id
|
36
|
+
kapi.get "/v0/partners/#{id}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete_partner id
|
40
|
+
Log.info "Deleting a partner: " + id
|
41
|
+
kapi.delete "/v0/partners/#{id}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_system_user id
|
45
|
+
Log.info "Creating a system user for partner: " + id
|
46
|
+
kapi.post "/v0/partners/#{id}/system-user", nil
|
47
|
+
end
|
48
|
+
|
49
|
+
#this will not raise an error if 409 conflict
|
50
|
+
# is returned on create call
|
51
|
+
def ensure_partner_exists overrides={}
|
52
|
+
Log.info 'Ensuring partner exists: ' + overrides['name'].to_s
|
53
|
+
create_partner overrides
|
54
|
+
return true
|
55
|
+
rescue Grifter::RequestException => e
|
56
|
+
if e.code == 409
|
57
|
+
Log.debug "Partner already exists"
|
58
|
+
return true
|
59
|
+
else
|
60
|
+
raise e
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def set_partner_rate_limit_multiplier id, multiplier
|
66
|
+
partner = get_partner id
|
67
|
+
update_payload = partner.merge 'rate_limit_multiplier' => multiplier
|
68
|
+
update_payload.delete 'id'
|
69
|
+
update_partner id, update_payload
|
70
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
#add_new_prod_partner is used for making production partners
|
2
|
+
#it makes system users as well
|
3
|
+
#by default it makes 1 system user and 1 old-style-system-user
|
4
|
+
#you can alter either count through the options passed in
|
5
|
+
def add_new_prod_partner display_name, options={}
|
6
|
+
if !display_name.kind_of?(String) || display_name.length < 3
|
7
|
+
raise "You must pass in a display name that is at least 3 characters long"
|
8
|
+
end
|
9
|
+
options.merge!({ 'display_name' => display_name })
|
10
|
+
set_prod_mode
|
11
|
+
set_account :prod_knerd
|
12
|
+
partner_data = add_new_partner options
|
13
|
+
print "\n\nNEW PARTNER:\n#{partner_data.to_yaml}\n"
|
14
|
+
partner_data
|
15
|
+
end
|
16
|
+
|
17
|
+
#add new test partner should be used anytime we are making
|
18
|
+
#a partner for internal testing use. Test partner are NEVER
|
19
|
+
#to be given externally as they are subject to being deleted without notice
|
20
|
+
def add_new_partner options={}
|
21
|
+
|
22
|
+
options = {
|
23
|
+
'num_system_users' => 1,
|
24
|
+
'is_testing' => false,
|
25
|
+
'filename' => 'new_partner_data.json',
|
26
|
+
'display_name' => 'KnewtonTestingPartner_' + random_string(16),
|
27
|
+
'rate_limit_multiplier' => 1.0,
|
28
|
+
}.merge(options)
|
29
|
+
|
30
|
+
new_partner_data = {
|
31
|
+
'client_id' => options.fetch('client_id', random_string(32)),
|
32
|
+
'client_secret' => options.fetch('client_secret', random_string(48)),
|
33
|
+
}
|
34
|
+
|
35
|
+
partner = create_partner 'name' => new_partner_data['client_id'],
|
36
|
+
'password' => new_partner_data['client_secret'],
|
37
|
+
'is_testing' => options['is_testing'],
|
38
|
+
'display_name' => options['display_name'],
|
39
|
+
'rate_limit_multiplier' => options['rate_limit_multiplier']
|
40
|
+
|
41
|
+
new_partner_data['partner_id'] = partner['id']
|
42
|
+
|
43
|
+
if options['num_system_users'] > 0
|
44
|
+
new_partner_data['system_users'] = options['num_system_users'].times.map do
|
45
|
+
new_system_user = create_system_user new_partner_data['partner_id']
|
46
|
+
{
|
47
|
+
'external_user_id' => new_system_user['external_user_id'],
|
48
|
+
'account_id' => new_system_user['id'],
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
new_partner_data['created_on'] = DateTime.now.to_s
|
54
|
+
new_partner_data['created_by'] = Etc.getlogin
|
55
|
+
|
56
|
+
File.open(options['filename'], 'w') do |f|
|
57
|
+
f.write(JSON.pretty_generate(new_partner_data))
|
58
|
+
Log.warn "Wrote the new partner data to #{options['filename']}"
|
59
|
+
end
|
60
|
+
|
61
|
+
return new_partner_data
|
62
|
+
end
|
63
|
+
|
64
|
+
def set_prod_mode
|
65
|
+
grifter_configuration[:services].keys.each do |svc|
|
66
|
+
self.send(svc).headers.delete 'knewton-test'
|
67
|
+
end
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
|
71
|
+
def set_test_mode
|
72
|
+
grifter_configuration[:services].keys.each do |svc|
|
73
|
+
self.send(svc).headers['knewton-test'] = 'true'
|
74
|
+
end
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
|
78
|
+
def get_client_id_from_partner_id partner_id
|
79
|
+
partner_record = nil
|
80
|
+
as_account :knerd do
|
81
|
+
partner_record = get_partner partner_id
|
82
|
+
end
|
83
|
+
partner_record['name']
|
84
|
+
end
|
85
|
+
|
@@ -0,0 +1,215 @@
|
|
1
|
+
"""
|
2
|
+
Grifts to setup state to test recommendations.
|
3
|
+
|
4
|
+
Use to setup tests verifying rec contracts. The terminology used is specified in the beginning of
|
5
|
+
the Recommendations Contracts document:
|
6
|
+
https://docs.google.com/document/d/1s0gBAPbBKdCUmkBmLh36tQk1-s9B7VD14sz22vWm4Ns/
|
7
|
+
"""
|
8
|
+
|
9
|
+
MAX_RANDOM_HISTORY_EVENTS=20
|
10
|
+
|
11
|
+
def setup_test_scenario scenario, graph_type
|
12
|
+
set_account(:partner)
|
13
|
+
test_data = {}
|
14
|
+
#get graph, create learning instance/goal/student/registration
|
15
|
+
test_data['graph'] = (get_test_data :simple_graphs)[graph_type]
|
16
|
+
test_data['learning_instance'] = create_learning_instance graph_id: test_data['graph']['id']
|
17
|
+
test_data['goal'] = generate_specified_goal test_data['graph'], test_data['learning_instance']['id'], scenario['goal'], scenario['target_date_offset']
|
18
|
+
test_data['student'] = add_new_student_to_learning_instance test_data['learning_instance']['id']
|
19
|
+
|
20
|
+
generate_student_history scenario['history'], test_data
|
21
|
+
|
22
|
+
test_data
|
23
|
+
end
|
24
|
+
|
25
|
+
#Generate student history of a specified type-- currently either None or Any (random)
|
26
|
+
def generate_student_history history_type, test_data
|
27
|
+
r = Random.new
|
28
|
+
if ENV.has_key? "REC_SEED"
|
29
|
+
r = Random.new ENV['REC_SEED']
|
30
|
+
end
|
31
|
+
|
32
|
+
case history_type
|
33
|
+
when "None"
|
34
|
+
return
|
35
|
+
when "Any"
|
36
|
+
num_events = r.rand(MAX_RANDOM_HISTORY_EVENTS)
|
37
|
+
num_events.times do
|
38
|
+
send_random_event_on_graph test_data['student']['registration_id'], test_data['graph']
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
#Default goal settings
|
44
|
+
DEFAULT_TARGET_SCORE = 0.7
|
45
|
+
DEFAULT_TARGET_DATE_OFFSET = 7
|
46
|
+
def generate_specified_goal graph, learning_instance_id, goal_type, target_date_offset=DEFAULT_TARGET_DATE_OFFSET
|
47
|
+
case goal_type
|
48
|
+
when "G[T][T]"
|
49
|
+
#Goal with on single-concept graph of concept T, with:
|
50
|
+
# - a single arbitrary assessment module within concept T
|
51
|
+
# - all modules under concept T recommendable.
|
52
|
+
|
53
|
+
#select the single concept T
|
54
|
+
concept = find_concept_by_name graph, 'T'
|
55
|
+
|
56
|
+
#Pick the single assessment module under concept T.
|
57
|
+
assessing_module = find_associated_assessing_bndl graph, concept['id']
|
58
|
+
|
59
|
+
#Pick the all modules under concept T as recommendable.
|
60
|
+
rec_modules = find_associated_assessing_atoms graph, concept['id']
|
61
|
+
|
62
|
+
goal = create_goal learning_instance_id, {
|
63
|
+
'target_modules' => [ {
|
64
|
+
'module_id' => assessing_module,
|
65
|
+
'target_score' => DEFAULT_TARGET_SCORE,
|
66
|
+
'target_date' => days_from_now(target_date_offset),
|
67
|
+
}],
|
68
|
+
'recommendable_modules' => rec_modules.map{|m| { "module_id" => m } },
|
69
|
+
}
|
70
|
+
when "G[T][P1,T]"
|
71
|
+
#Goal with on single-concept graph of concept T, with:
|
72
|
+
# - a single arbitrary assessment module within concept T
|
73
|
+
# - all modules under concepts P1 and T recommendable.
|
74
|
+
|
75
|
+
#select concepts
|
76
|
+
concept_t = find_concept_by_name graph, 'T'
|
77
|
+
concept_p1 = find_concept_by_name graph, 'P1'
|
78
|
+
|
79
|
+
#Pick the single assessment module under concept T.
|
80
|
+
assessing_module = find_associated_assessing_bndl graph, concept_t['id']
|
81
|
+
|
82
|
+
#Pick the all modules under concept T as recommendable.
|
83
|
+
rec_modules = []
|
84
|
+
rec_modules.concat( find_associated_assessing_atoms graph, concept_t['id'] )
|
85
|
+
rec_modules.concat( find_associated_assessing_atoms graph, concept_p1['id'] )
|
86
|
+
|
87
|
+
goal = create_goal learning_instance_id, {
|
88
|
+
'target_modules' => [ {
|
89
|
+
'module_id' => assessing_module,
|
90
|
+
'target_score' => DEFAULT_TARGET_SCORE,
|
91
|
+
'target_date' => days_from_now(target_date_offset),
|
92
|
+
}],
|
93
|
+
'recommendable_modules' => rec_modules.map{|m| { "module_id" => m } },
|
94
|
+
}
|
95
|
+
when "G[T][all]"
|
96
|
+
#Goal with on single-concept graph of concept T, with:
|
97
|
+
# - a single arbitrary assessment module within concept T
|
98
|
+
# - all atoms in the graph recommendable.
|
99
|
+
|
100
|
+
#select concepts
|
101
|
+
concept_t = find_concept_by_name graph, 'T'
|
102
|
+
|
103
|
+
#Pick the single assessment module under concept T.
|
104
|
+
assessing_module = find_associated_assessing_bndl graph, concept_t['id']
|
105
|
+
|
106
|
+
#Pick the all atoms as recommendable.
|
107
|
+
rec_modules = find_all_atom_ids graph
|
108
|
+
|
109
|
+
goal = create_goal learning_instance_id, {
|
110
|
+
'target_modules' => [ {
|
111
|
+
'module_id' => assessing_module,
|
112
|
+
'target_score' => DEFAULT_TARGET_SCORE,
|
113
|
+
'target_date' => days_from_now(target_date_offset),
|
114
|
+
}],
|
115
|
+
'recommendable_modules' => rec_modules.map{|m| { "module_id" => m } },
|
116
|
+
}
|
117
|
+
when "G[P1][all]"
|
118
|
+
#Goal with on single-concept graph of concept P1, with:
|
119
|
+
# - a single arbitrary assessment module within concept P1
|
120
|
+
# - all atoms in the graph recommendable.
|
121
|
+
|
122
|
+
#select concepts
|
123
|
+
concept_p1 = find_concept_by_name graph, 'P1'
|
124
|
+
|
125
|
+
#Pick the single assessment module under concept P1.
|
126
|
+
assessing_module = find_associated_assessing_bndl graph, concept_p1['id']
|
127
|
+
|
128
|
+
#Pick the all atoms as recommendable.
|
129
|
+
rec_modules = find_all_atom_ids graph
|
130
|
+
|
131
|
+
goal = create_goal learning_instance_id, {
|
132
|
+
'target_modules' => [ {
|
133
|
+
'module_id' => assessing_module,
|
134
|
+
'target_score' => DEFAULT_TARGET_SCORE,
|
135
|
+
'target_date' => days_from_now(target_date_offset),
|
136
|
+
}],
|
137
|
+
'recommendable_modules' => rec_modules.map{|m| { "module_id" => m } },
|
138
|
+
}
|
139
|
+
else
|
140
|
+
throw "Unrecognized goal type #{goal_type}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def complete_goal_with_percentage_correct registration_id, goal_id, percentage_correct, options={}
|
145
|
+
starting_event_threshold = 1.0 - percentage_correct
|
146
|
+
|
147
|
+
completion_data = complete_goal registration_id,
|
148
|
+
goal_id,
|
149
|
+
options.merge({:starting_event_threshold=>starting_event_threshold, :event_threshold_multiplier=>1.0})
|
150
|
+
|
151
|
+
completion_data
|
152
|
+
end
|
153
|
+
|
154
|
+
def complete_goal_with_percentage_correct_per_concept graph, registration_id, goal_id, percentages_correct, options={}
|
155
|
+
concept_thresholds = []
|
156
|
+
|
157
|
+
percentages_correct.each do |concept,percentage|
|
158
|
+
concept_thresholds << {
|
159
|
+
'id'=> (find_concept_by_name graph, concept)['id'],
|
160
|
+
'current_threshold' => (1.0-percentage),
|
161
|
+
'threshold_multiplier' => 1.0,
|
162
|
+
'num_fails_before_success' => 0,
|
163
|
+
}
|
164
|
+
end
|
165
|
+
|
166
|
+
completion_data = complete_goal registration_id,
|
167
|
+
goal_id,
|
168
|
+
options.merge({:concept_thresholds=>concept_thresholds})
|
169
|
+
|
170
|
+
completion_data
|
171
|
+
end
|
172
|
+
|
173
|
+
#Parses test data as used in the recommendations contracts tests, stripping irrelevent data and applying readable names
|
174
|
+
def humanize_completion_data test_data, graph_type, scenario_title, scenario
|
175
|
+
human_data = {}
|
176
|
+
human_data['date'] = Time.now
|
177
|
+
human_data['env'] = ENV['GRIFTER_ENVIRONMENT']
|
178
|
+
human_data['contract'] = scenario_title
|
179
|
+
human_data['graph_type'] = graph_type
|
180
|
+
human_data['goal_type'] = scenario['goal']
|
181
|
+
human_data['is_goal_complete'] = test_data['completion_data']['event_count'] <= scenario['max_adaptive_cycles']
|
182
|
+
human_data['contract_vars'] = test_data['contract_vars']
|
183
|
+
if test_data['preliminary_event_bodies']
|
184
|
+
human_data['preliminary_events'] = test_data['preliminary_event_bodies'].map do |event|
|
185
|
+
humanize_event_body test_data['graph'], event
|
186
|
+
end
|
187
|
+
end
|
188
|
+
human_data['adaptive_cycles'] = test_data['completion_data']['event_bodies_sent'].map do |event|
|
189
|
+
humanize_event_body test_data['graph'], event
|
190
|
+
end
|
191
|
+
human_data['concepts'] = humanize_concept_data test_data['graph']
|
192
|
+
|
193
|
+
human_data
|
194
|
+
end
|
195
|
+
|
196
|
+
def humanize_event_body graph, event
|
197
|
+
node = get_node_with_concept_and_content_type graph, event['module_id']
|
198
|
+
cycle_data = {
|
199
|
+
'concept' => node['concept']['name'],
|
200
|
+
'content_type' => node['content_type'],
|
201
|
+
'is_correct' => event['is_correct'],
|
202
|
+
'module_id' => event['module_id'],
|
203
|
+
}
|
204
|
+
end
|
205
|
+
|
206
|
+
def humanize_concept_data graph
|
207
|
+
concepts = (find_all_concept_ids graph).map do |concept|
|
208
|
+
concept = get_node_by_id graph, concept
|
209
|
+
{'id' => concept['id'], 'name' => concept['name']}
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def write_contract_yaml_report contract_filename, report_data
|
214
|
+
File.open("reports/contract_#{contract_filename}.yml", 'w') {|f| f.write YAML::dump(report_data) }
|
215
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
##STUFF RELATING TO REGISTRATION RESOURCES
|
2
|
+
def create_registration overrides={}
|
3
|
+
Log.info "Creating a registration"
|
4
|
+
# if account_id was passed in, we'll use that account id
|
5
|
+
# but, if account_id not provided, we'll make an account and return its details
|
6
|
+
account = nil
|
7
|
+
unless overrides['account_id']
|
8
|
+
account = create_account
|
9
|
+
overrides['account_id'] = account['id']
|
10
|
+
end
|
11
|
+
reg = kapi.post '/v0/registrations', {
|
12
|
+
'type' => 'learner',
|
13
|
+
'account_id' => nil,
|
14
|
+
'learning_instance_id' => '456',
|
15
|
+
}.merge(overrides)
|
16
|
+
reg['external_user_id'] = account['external_user_id'] if account
|
17
|
+
reg
|
18
|
+
end
|
19
|
+
|
20
|
+
def make_account_instructor_of account_id, learning_instance_id
|
21
|
+
Log.info "Creating a registration of type instructor for learning instance " + learning_instance_id + " account_id " + account_id
|
22
|
+
create_registration 'learning_instance_id' => learning_instance_id,
|
23
|
+
'account_id' => account_id,
|
24
|
+
'type' => "instructor"
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def add_new_student_to_learning_instance learning_instance_id, client_credentials=nil, options={}
|
29
|
+
client_credentials = get_client_credentials(:knewton) unless client_credentials
|
30
|
+
account = create_account
|
31
|
+
external_user_id = account['external_user_id']
|
32
|
+
account_id = account['id']
|
33
|
+
registration = create_registration 'learning_instance_id' => learning_instance_id,
|
34
|
+
'account_id' => account_id,
|
35
|
+
'type' => options.fetch('type', 'learner')
|
36
|
+
{
|
37
|
+
'external_user_id' => external_user_id,
|
38
|
+
'registration_id' => registration['id'],
|
39
|
+
'account_id' => account_id,
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_registration id
|
44
|
+
Log.info "Getting a registration " + id
|
45
|
+
kapi.get "/v0/registrations/#{id}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def delete_registration id
|
49
|
+
Log.info "Deleting a registration " + id
|
50
|
+
kapi.delete "/v0/registrations/#{id}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_registrations_for_account account_id
|
54
|
+
Log.info "Getting a registration for account " + account_id
|
55
|
+
kapi.get "/v0/accounts/#{account_id}/registrations"
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
##GOAL ACTIVATATION STUFF
|
60
|
+
def activate_registration_on_goal learning_instance_id, registration_id, goal_id
|
61
|
+
Log.info "Activating a goal for a registration"
|
62
|
+
kapi.put "/v0/learning-instances/#{learning_instance_id}/goals/#{goal_id}/registrations/#{registration_id}", {}
|
63
|
+
end
|
64
|
+
|
65
|
+
def deactivate_registration_on_goal learning_instance_id, registration_id, goal_id
|
66
|
+
Log.info "Deactivating a goal for a registration"
|
67
|
+
kapi.delete "/v0/learning-instances/#{learning_instance_id}/goals/#{goal_id}/registrations/#{registration_id}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def list_activated_registrations learning_instance_id, goal_id
|
71
|
+
Log.info "Listing activated registrations for a goal"
|
72
|
+
end
|
73
|
+
|
74
|
+
def check_if_activated learning_instance_id, registration_id, goal_id
|
75
|
+
Log.info "Checking if a specific registration is activated for a specific goal"
|
76
|
+
kapi.get "/v0/learning-instances/#{learning_instance_id}/goals/#{goal_id}/registrations/#{registration_id}"
|
77
|
+
return true
|
78
|
+
rescue Grifter::RequestException => e
|
79
|
+
if e.code == 404
|
80
|
+
return false
|
81
|
+
else
|
82
|
+
raise e
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
##SENDING IN EVENTS STUFF
|
88
|
+
def send_recommendation_followed registration_id, module_id, overrides={}
|
89
|
+
Log.info "Sending a recommendation followed event"
|
90
|
+
kapi.post "/v0/registrations/#{registration_id}/recommendation-followed-events", {
|
91
|
+
'module_id' => module_id,
|
92
|
+
'time_followed' => datetime,
|
93
|
+
'recommendation_id' => 987654,
|
94
|
+
}.merge(overrides)
|
95
|
+
end
|
96
|
+
|
97
|
+
def send_graded_event registration_id, module_id, overrides={}
|
98
|
+
Log.info "Sending a graded event"
|
99
|
+
kapi.post "/v0/registrations/#{registration_id}/graded-events", {
|
100
|
+
'response' => "sample of a response",
|
101
|
+
'duration' => 4321,
|
102
|
+
'module_id' => module_id,
|
103
|
+
'interaction_end_time' => datetime,
|
104
|
+
'score' => 0.99,
|
105
|
+
'is_correct' => true,
|
106
|
+
'is_complete' => true,
|
107
|
+
}.merge(overrides)
|
108
|
+
end
|
109
|
+
|
110
|
+
def send_ungraded_event registration_id, module_id, overrides={}
|
111
|
+
Log.info "Sending an ungraded event"
|
112
|
+
kapi.post "/v0/registrations/#{registration_id}/ungraded-events", {
|
113
|
+
'duration' => 876543,
|
114
|
+
'module_id' => module_id,
|
115
|
+
'is_complete' => true,
|
116
|
+
'interaction_end_time' => datetime,
|
117
|
+
}.merge(overrides)
|
118
|
+
end
|
119
|
+
|
120
|
+
def send_focus_event registration_id, goal_id, overrides={}
|
121
|
+
Log.info "Sending a focus event"
|
122
|
+
kapi.post "/v0/registrations/#{registration_id}/focus-events", {
|
123
|
+
'goal_id' => goal_id,
|
124
|
+
}.merge(overrides)
|
125
|
+
end
|
126
|
+
|
127
|
+
def send_random_event_on_graph registration_id, graph
|
128
|
+
atom_id = find_random_atom_id graph
|
129
|
+
send_correct_event_type_for_atom registration_id, atom_id, graph
|
130
|
+
end
|
131
|
+
|
132
|
+
def send_correct_event_type_for_atom registration_id, atom_id, graph
|
133
|
+
content_types = get_content_types graph, atom_id
|
134
|
+
|
135
|
+
if content_types.include? 'assesssment'
|
136
|
+
correct = [true, false].sample
|
137
|
+
send_graded_event registration_id, atom_id, is_correct: correct
|
138
|
+
else
|
139
|
+
send_ungraded_event registration_id, atom_id
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
## GETTING RECOMMENDATION STUFF
|
144
|
+
def get_recommendation registration_id, goal_id=nil, continued_recommendations=nil
|
145
|
+
goal_id = random_uuid unless goal_id #this only works in local mode, considering removing it
|
146
|
+
Log.info "Getting a recommendation for registration: " + registration_id + " goal: " + goal_id
|
147
|
+
query_params= { 'goal_id' => goal_id }
|
148
|
+
query_params['continued_recommendations'] = continued_recommendations if continued_recommendations
|
149
|
+
query_string = URI.encode_www_form(query_params)
|
150
|
+
kapi.get "/v0/registrations/#{registration_id}/recommendation?#{query_string}"
|
151
|
+
end
|
152
|
+
|
153
|
+
def send_batch_events registration_id, events, overrides={}
|
154
|
+
Log.info "Sending a batch of student events"
|
155
|
+
kapi.post "/v0/registrations/#{registration_id}/batch-events", {
|
156
|
+
'goal_id' => nil,
|
157
|
+
'events' => events
|
158
|
+
}.merge(overrides)
|
159
|
+
end
|