lti2 0.0.1
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/MIT-LICENSE +20 -0
- data/README.rdoc +184 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/lti2/application.js +13 -0
- data/app/assets/stylesheets/lti2/application.css +15 -0
- data/app/controllers/lti2/application_controller.rb +4 -0
- data/app/helpers/lti2/application_helper.rb +4 -0
- data/app/views/layouts/lti2/application.html.erb +14 -0
- data/config/routes.rb +4 -0
- data/lib/lti2.rb +7 -0
- data/lib/lti2/engine.rb +9 -0
- data/lib/lti2/version.rb +3 -0
- data/lib/lti2_commons/lib/lti2_commons.rb +9 -0
- data/lib/lti2_commons/lib/lti2_commons/cache.rb +29 -0
- data/lib/lti2_commons/lib/lti2_commons/json_wrapper.rb +118 -0
- data/lib/lti2_commons/lib/lti2_commons/lti2_launch.rb +158 -0
- data/lib/lti2_commons/lib/lti2_commons/message_support.rb +218 -0
- data/lib/lti2_commons/lib/lti2_commons/oauth_request.rb +179 -0
- data/lib/lti2_commons/lib/lti2_commons/signer.rb +75 -0
- data/lib/lti2_commons/lib/lti2_commons/substitution_support.rb +87 -0
- data/lib/lti2_commons/lib/lti2_commons/utils.rb +28 -0
- data/lib/lti2_commons/lib/lti2_commons/version.rb +3 -0
- data/lib/lti2_commons/lib/lti2_commons/wire_log.rb +163 -0
- data/lib/lti2_commons/test/test_jsonpath.rb +255 -0
- data/lib/lti2_commons/test/test_jsonwrapper.rb +230 -0
- data/lib/lti2_commons/test/test_oauth_request.rb +143 -0
- data/lib/lti2_commons/test/test_substitution_support.rb +71 -0
- data/lib/lti2_commons/test/test_wire_log.rb +15 -0
- data/lib/tasks/lti2_tasks.rake +4 -0
- metadata +199 -0
@@ -0,0 +1,230 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "rubygems"
|
3
|
+
require 'json'
|
4
|
+
require 'jsonpath'
|
5
|
+
|
6
|
+
require File.expand_path('../../lib/lti2_commons/json_wrapper', __FILE__)
|
7
|
+
require File.expand_path('../../lib/lti2_commons/utils', __FILE__)
|
8
|
+
|
9
|
+
include Lti2Commons
|
10
|
+
include Utils
|
11
|
+
|
12
|
+
class TestJsonWrapper < Test::Unit::TestCase
|
13
|
+
def setup
|
14
|
+
@json_str =
|
15
|
+
<<PROXY
|
16
|
+
{
|
17
|
+
"@context" : [
|
18
|
+
"http://www.imsglobal.org/imspurl/lti/v2/ctx/ToolProxy",
|
19
|
+
"http://purl.org/blackboard/ctx/v1/iconStyle"
|
20
|
+
],
|
21
|
+
"@type" : "ToolProxy",
|
22
|
+
"@id" : "http://fabericious..com/ToolProxy/869e5ce5-214c-4e85-86c6-b99e8458a592",
|
23
|
+
"lti_version" : "LTI-2p0",
|
24
|
+
"tool_proxy_guid" : "869e5ce5-214c-4e85-86c6-b99e8458a592",
|
25
|
+
"tool_consumer_profile" : "http://lms.example.com/profile/b6ffa601-ce1d-4549-9ccf-145670a964d4",
|
26
|
+
"tool_profile" : {
|
27
|
+
"lti_version" : "LTI-2p0",
|
28
|
+
"product_instance" : {
|
29
|
+
"guid" : "fd75124a-140e-470f-944c-114d2d92bb40",
|
30
|
+
"product_info" : {
|
31
|
+
"product_name" : {
|
32
|
+
"default_value" : "Acme Assessments",
|
33
|
+
"key" : "tool.name"
|
34
|
+
},
|
35
|
+
"description" : {
|
36
|
+
"default_value" : "Acme Assessments provide an interactive test format.",
|
37
|
+
"key" : "tool.description"
|
38
|
+
},
|
39
|
+
"product_version" : "10.3",
|
40
|
+
"technical_description" : {
|
41
|
+
"default_value" : "Support provided for all LTI 1 extensions as well as LTI 2",
|
42
|
+
"key" : "tool.technical"
|
43
|
+
},
|
44
|
+
"product_family" : {
|
45
|
+
"code" : "assessment-tool",
|
46
|
+
"vendor" : {
|
47
|
+
"code" : "acme.com",
|
48
|
+
"name" : {
|
49
|
+
"default_value" : "Acme",
|
50
|
+
"key" : "tool.vendor.name"
|
51
|
+
},
|
52
|
+
"description" : {
|
53
|
+
"default_value" : "Acme is a leading provider of interactive tools for education",
|
54
|
+
"key" : "tool.vendor.description"
|
55
|
+
},
|
56
|
+
"website" : "http://acme.example.com",
|
57
|
+
"timestamp" : "2012-04-05T09:08:16-04:00",
|
58
|
+
"contact" : {
|
59
|
+
"email" : "info@example.com"
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
},
|
64
|
+
"support" : {
|
65
|
+
"email" : "helpdesk@example.com"
|
66
|
+
},
|
67
|
+
"service_provider" : {
|
68
|
+
"guid" : "18e7ea50-3d6d-4f6b-aff2-ed3ab577716c",
|
69
|
+
"provider_name" : {
|
70
|
+
"default_value" : "Acme Hosting",
|
71
|
+
"key" : "service_provider.name"
|
72
|
+
},
|
73
|
+
"description" : {
|
74
|
+
"default_value" : "Provider of high performance managed hosting environments",
|
75
|
+
"key" : "service_provider.description"
|
76
|
+
},
|
77
|
+
"support" : {
|
78
|
+
"email" : "support@acme-hosting.example.com"
|
79
|
+
},
|
80
|
+
"timestamp" : "2012-04-05T09:08:16-04:00"
|
81
|
+
}
|
82
|
+
},
|
83
|
+
"base_url_choice" : [
|
84
|
+
{ "default_base_url" : "http://acme.example.com",
|
85
|
+
"secure_base_url" : "https://acme.example.com",
|
86
|
+
"selector" : {
|
87
|
+
"applies_to" : [
|
88
|
+
"IconEndpoint",
|
89
|
+
"MessageHandler"
|
90
|
+
]
|
91
|
+
}
|
92
|
+
}
|
93
|
+
],
|
94
|
+
"resource_handler" : [
|
95
|
+
{
|
96
|
+
"resource_type": "urn:lti:ResourceType:{fabericious.lti.org}/handler/launchRequest",
|
97
|
+
"name" : {
|
98
|
+
"default_value" : "Acme Assessment",
|
99
|
+
"key" : "assessment.resource.name"
|
100
|
+
},
|
101
|
+
"description" : {
|
102
|
+
"default_value" : "An interactive assessment using the Acme scale.",
|
103
|
+
"key" : "assessment.resource.description"
|
104
|
+
},
|
105
|
+
"message" : [{
|
106
|
+
"message_type" : "basic-lti-launch-request",
|
107
|
+
"path" : "/handler/launchRequest",
|
108
|
+
"capability" : [
|
109
|
+
"Result.autocreate",
|
110
|
+
"Result.sourcedGUID"
|
111
|
+
],
|
112
|
+
"parameter" : [
|
113
|
+
{ "name" : "result_id",
|
114
|
+
"variable" : "$Result.sourcedGUID"
|
115
|
+
},
|
116
|
+
{ "name" : "discipline",
|
117
|
+
"fixed" : "chemistry"
|
118
|
+
}
|
119
|
+
]
|
120
|
+
}],
|
121
|
+
"icon_info" : [
|
122
|
+
{
|
123
|
+
"default_location" : {
|
124
|
+
"path" : "/images/bb/en/icon.png"
|
125
|
+
},
|
126
|
+
"key" : "iconStyle.default.path"
|
127
|
+
},
|
128
|
+
{ "icon_style" : "BbListElementIcon",
|
129
|
+
"default_location" : {
|
130
|
+
"path" : "/images/bb/en/listElement.png"
|
131
|
+
},
|
132
|
+
"key" : "iconStyle.bb.listElement.path"
|
133
|
+
},
|
134
|
+
{ "icon_style" : "BbPushButtonIcon",
|
135
|
+
"default_location" : {
|
136
|
+
"path" : "images/bb/en/pushButton.png"
|
137
|
+
},
|
138
|
+
"key" : "iconStyle.bb.pushButton.path"
|
139
|
+
}
|
140
|
+
]
|
141
|
+
}
|
142
|
+
]
|
143
|
+
},
|
144
|
+
"security_contract" : {
|
145
|
+
"shared_secret" : "ThisIsASecret!",
|
146
|
+
"tool_service" : [
|
147
|
+
{ "@type" : "RestServiceProfile",
|
148
|
+
"service" : "http://lms.example.com/profile/b6ffa601-ce1d-4549-9ccf-145670a964d4#ToolProxy.collection",
|
149
|
+
"action" : "POST"
|
150
|
+
},
|
151
|
+
{ "@type" : "RestServiceProfile",
|
152
|
+
"service" : "http://lms.example.com/profile/b6ffa601-ce1d-4549-9ccf-145670a964d4#ToolProxy.item",
|
153
|
+
"action" : [
|
154
|
+
"GET",
|
155
|
+
"PUT"
|
156
|
+
]
|
157
|
+
},
|
158
|
+
{ "@type" : "RestService",
|
159
|
+
"service" : "http://lms.example.com/profile/b6ffa601-ce1d-4549-9ccf-145670a964d4#Result.item",
|
160
|
+
"action" : [
|
161
|
+
"GET",
|
162
|
+
"PUT"
|
163
|
+
]
|
164
|
+
}
|
165
|
+
]
|
166
|
+
}
|
167
|
+
}
|
168
|
+
PROXY
|
169
|
+
|
170
|
+
@json_wrapper = JsonWrapper.new @json_str
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_constuctor
|
174
|
+
assert_not_nil @json_wrapper.root
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_at
|
178
|
+
assert_equal ["869e5ce5-214c-4e85-86c6-b99e8458a592"], @json_wrapper.at('tool_proxy_guid')
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_first_at
|
182
|
+
assert_equal "869e5ce5-214c-4e85-86c6-b99e8458a592", @json_wrapper.first_at('tool_proxy_guid')
|
183
|
+
assert_nil @json_wrapper.first_at('asdf')
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_each_leaf
|
187
|
+
counter = 0
|
188
|
+
@json_wrapper.each_leaf { |node| counter += 1 }
|
189
|
+
assert_equal 70, counter
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_deep_copy
|
193
|
+
new_json_wrapper = @json_wrapper.deep_copy
|
194
|
+
assert_not_equal new_json_wrapper.object_id, @json_wrapper.object_id
|
195
|
+
assert_equal "869e5ce5-214c-4e85-86c6-b99e8458a592", new_json_wrapper.first_at('tool_proxy_guid')
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_search
|
199
|
+
assert_equal "/handler/launchRequest",
|
200
|
+
( @json_wrapper.search 'tool_profile.resource_handler..message',
|
201
|
+
{ 'message_type' => "basic-lti-launch-request" },
|
202
|
+
"path")
|
203
|
+
assert_nil @json_wrapper.search 'tool_profile.resource_handler..message',
|
204
|
+
{ 'message_type' => "basic-lti-launch-request" },
|
205
|
+
"xxxx"
|
206
|
+
assert_nil @json_wrapper.search 'tool_profile.resource_handler..message',
|
207
|
+
{ 'message_type' => "xxx" },
|
208
|
+
"path"
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_select
|
212
|
+
assert_equal "http://acme.example.com",
|
213
|
+
@json_wrapper.select('tool_profile.base_url_choice',
|
214
|
+
"selector.applies_to", "MessageHandler", 'default_base_url')
|
215
|
+
assert_equal nil, @json_wrapper.select('tool_profile.xxxxx',
|
216
|
+
"selector.applies_to", "MessageHandler", 'default_base_url')
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_each_deep_with_substitution
|
220
|
+
hash = {"root" => {"child1" => "{value}1", "child2" => {"grandchild1" => "{grand}{value}1"}, "child3" => "{value}3"}}
|
221
|
+
json_hash = JsonWrapper.new hash
|
222
|
+
subst_hash = {'value' => 'VLU', 'great' => 'GRT', 'grand' => 'GRND'}
|
223
|
+
json_hash.substitute_text_in_all_nodes '{', '}', subst_hash
|
224
|
+
assert_equal "VLU1", json_hash.first_at('$..child1')
|
225
|
+
assert_equal "GRNDVLU1", json_hash.first_at('$..grandchild1')
|
226
|
+
end
|
227
|
+
|
228
|
+
ARGV = ['', "--name", "test_select"]
|
229
|
+
# Test::Unit::AutoRunner.run(false, nil, ARGV)
|
230
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path('../../lib/lti2_commons/message_support', __FILE__)
|
3
|
+
require File.expand_path('../../lib/lti2_commons/cache', __FILE__)
|
4
|
+
require File.expand_path('../../lib/lti2_commons/utils', __FILE__)
|
5
|
+
require File.expand_path('../../lib/lti2_commons/signer', __FILE__)
|
6
|
+
require File.expand_path('../../lib/lti2_commons/oauth_request', __FILE__)
|
7
|
+
|
8
|
+
require 'rack'
|
9
|
+
require 'oauth'
|
10
|
+
|
11
|
+
include Lti2Commons
|
12
|
+
include Signer
|
13
|
+
include Utils
|
14
|
+
include MessageSupport
|
15
|
+
include OAuth::RequestProxy
|
16
|
+
|
17
|
+
class TestOAuthRequest < Test::Unit::TestCase
|
18
|
+
def setup
|
19
|
+
@launch_url = 'http://localhost:3000/tenants/3'
|
20
|
+
# @launch_url = 'http://vst-bc.com/tenants/3/books'
|
21
|
+
@http_method = 'post'
|
22
|
+
@consumer_key = '12345'
|
23
|
+
@consumer_secret = 'secret'
|
24
|
+
@params = {'oauth_consumer_key'=>'12345', 'oauth_signature_method'=> "HMAC-SHA1", 'user_id'=>'jt'}
|
25
|
+
@oauth_request = OAuth::OAuthProxy::OAuthRequest.new \
|
26
|
+
"method" => @http_method,
|
27
|
+
"uri" => @launch_url,
|
28
|
+
"parameters" => @params
|
29
|
+
@nonce_cache = Lti2Commons::Cache.new :ttl => 300
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_stale_request(minutes_stale)
|
33
|
+
now = Time::now
|
34
|
+
stale_time = now + (minutes_stale*60.0)
|
35
|
+
# puts "Now: #{now} Stale_time: #{stale_time}]"
|
36
|
+
params = @params.dup
|
37
|
+
params['oauth_timestamp'] = stale_time.to_i
|
38
|
+
request = Lti2Commons::Signer.create_signed_request @launch_url, @http_method, @consumer_key, @consumer_secret, params
|
39
|
+
# dump_oauth_parameters request, "stale create"
|
40
|
+
request
|
41
|
+
end
|
42
|
+
|
43
|
+
def dump_oauth_parameters(request, label=nil)
|
44
|
+
puts ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
|
45
|
+
if label
|
46
|
+
puts "*** #{label}"
|
47
|
+
end
|
48
|
+
puts "non_oauth_parameters: #{request.non_oauth_parameters.inspect}"
|
49
|
+
puts "oauth_header: #{request.oauth_header}"
|
50
|
+
puts "oauth_parameters: #{request.oauth_parameters.inspect}"
|
51
|
+
puts "signature_base_string: #{request.signature_base_string}"
|
52
|
+
puts "signed? #{request.signed?}"
|
53
|
+
puts "signed_uri: #{request.signed_uri}"
|
54
|
+
puts "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_oauth_request
|
58
|
+
request = Signer.create_signed_request @launch_url, @http_method, @consumer_key, @consumer_secret, @params
|
59
|
+
dump_oauth_parameters(request, 'postsigning')
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_valid_request
|
63
|
+
request = Signer.create_signed_request @launch_url, @http_method, @consumer_key, @consumer_secret, @params
|
64
|
+
assert_not_nil request
|
65
|
+
assert_equal true, request.verify_signature?(@consumer_secret, @nonce_cache)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_create_signed_request_simple_post
|
69
|
+
request = Lti2Commons::Signer.create_signed_request @launch_url, @http_method, @consumer_key, @consumer_secret, @params
|
70
|
+
assert_not_nil request
|
71
|
+
signature_base_string = request.signature_base_string
|
72
|
+
assert_equal "POST&http%3A%2F%2Flocalhost%3A3000%2Ftenants%2F3&basiclti_submit%3DPress%2520t", signature_base_string[0..77]
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_create_signed_request_get
|
76
|
+
request = Lti2Commons::Signer.create_signed_request @launch_url, 'get', @consumer_key, @consumer_secret, @params
|
77
|
+
assert_not_nil request
|
78
|
+
signature_base_string = request.signature_base_string
|
79
|
+
assert_equal "GET&http%3A%2F%2Flocalhost%3A3000%2Ftenants%2F3&basiclti_submit%3DPress%2520t", signature_base_string[0..76]
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_create_signed_request_put
|
83
|
+
request = Lti2Commons::Signer.create_signed_request @launch_url, 'put', @consumer_key, @consumer_secret, @params
|
84
|
+
assert_not_nil request
|
85
|
+
signature_base_string = request.signature_base_string
|
86
|
+
assert_equal "PUT&http%3A%2F%2Flocalhost%3A3000%2Ftenants%2F3&basiclti_submit%3DPress%2520t", signature_base_string[0..76]
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_lti_message_body_from_signed_request
|
90
|
+
request = Signer.create_signed_request @launch_url, 'put', @consumer_key, @consumer_secret, @params
|
91
|
+
assert_not_nil request
|
92
|
+
assert_not_nil MessageSupport.create_lti_message_body_from_signed_request request
|
93
|
+
puts MessageSupport.create_lti_message_body_from_signed_request request
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_lti_message_body
|
97
|
+
assert_not_nil MessageSupport.create_lti_message_body @launch_url, @params
|
98
|
+
puts MessageSupport.create_lti_message_body @launch_url, @params
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_break_signature
|
102
|
+
request = Lti2Commons::Signer.create_signed_request @launch_url, @http_method, @consumer_key, @consumer_secret, @params
|
103
|
+
request.parameters['oauth_signature'] = "asdf"
|
104
|
+
assert_equal false, (request.verify_signature? @consumer_secret, @nonce_cache)
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_exception_on_signature_error
|
108
|
+
request = Lti2Commons::Signer.create_signed_request @launch_url, @http_method, @consumer_key, @consumer_secret, @params
|
109
|
+
request.parameters['oauth_signature'] = "asdf"
|
110
|
+
begin
|
111
|
+
request.verify_signature? @consumer_secret, @nonce_cache, false
|
112
|
+
fail "Exception expected here"
|
113
|
+
rescue
|
114
|
+
# expected
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_timeout_within_margin
|
119
|
+
request = create_stale_request 2
|
120
|
+
assert_equal true, (request.verify_signature? @consumer_secret, @nonce_cache)
|
121
|
+
request = create_stale_request(-2)
|
122
|
+
assert_equal true, (request.verify_signature? @consumer_secret, @nonce_cache)
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_timeout_error
|
126
|
+
request = create_stale_request 10
|
127
|
+
assert_equal false, (request.verify_signature? @consumer_secret, @nonce_cache)
|
128
|
+
request = create_stale_request(-10)
|
129
|
+
assert_equal false, (request.verify_signature? @consumer_secret, @nonce_cache)
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_duplicate_nonce
|
133
|
+
params = @params.dup
|
134
|
+
params['oauth_nonce'] = "1234"
|
135
|
+
request = Lti2Commons::Signer.create_signed_request @launch_url, @http_method, @consumer_key, @consumer_secret, params
|
136
|
+
assert_equal true, (request.verify_signature? @consumer_secret, @nonce_cache)
|
137
|
+
request = Lti2Commons::Signer.create_signed_request @launch_url, @http_method, @consumer_key, @consumer_secret, params
|
138
|
+
assert_equal false, (request.verify_signature? @consumer_secret, @nonce_cache)
|
139
|
+
end
|
140
|
+
|
141
|
+
ARGV = ['', "--name", "test_duplicate_nonce"]
|
142
|
+
Test::Unit::AutoRunner.run(false, nil, ARGV)
|
143
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path('../../lib/lti2_commons/substitution_support', __FILE__)
|
3
|
+
|
4
|
+
include Lti2Commons
|
5
|
+
include SubstitutionSupport
|
6
|
+
|
7
|
+
|
8
|
+
class TestObject
|
9
|
+
attr_accessor :user_id, :name
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@user_id = 'jt'
|
13
|
+
@name = "john.thomas"
|
14
|
+
@code = @name.reverse
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
@user_id
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class TestSubstitutionSupport < Test::Unit::TestCase
|
23
|
+
def setup
|
24
|
+
@resolver = Resolver.new
|
25
|
+
@resolver.add_resolver "user", {'name' => "jt", 'id' => "1234"}
|
26
|
+
@resolver.add_resolver "user", {'name' => "jt", 'id' => "9876", 'sport' => 'judo'}
|
27
|
+
@resolver.add_resolver "course", lambda { |x| "COURSE-#{x}"}
|
28
|
+
@resolver.add_resolver "resource", self.method(:resource_transform_sample)
|
29
|
+
@resolver.add_resolver "testobject", TestObject.new
|
30
|
+
@resolver.add_resolver "testnest", {'nestlevel' => 'inner'}
|
31
|
+
@resolver.add_resolver "*", {'ip'=> '192.168.2.177'}
|
32
|
+
end
|
33
|
+
|
34
|
+
def resource_transform_sample(name)
|
35
|
+
name.reverse
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_add_hash
|
39
|
+
assert_equal "jt", @resolver.resolve('user.name')
|
40
|
+
assert_equal "judo", @resolver.resolve('user.sport')
|
41
|
+
assert_equal "192.168.2.177", @resolver.resolve('user.ip')
|
42
|
+
assert_equal "192.168.2.177", @resolver.resolve('foo.ip')
|
43
|
+
assert_equal "user.notfound", @resolver.resolve('user.notfound')
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_add_block
|
47
|
+
assert_equal "COURSE-anything", @resolver.resolve('course.anything')
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_internal_method
|
51
|
+
assert_equal "fdsa", @resolver.resolve('resource.asdf')
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_testobject
|
55
|
+
assert_equal "john.thomas", @resolver.resolve('testobject.name')
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_nested_resolver
|
59
|
+
outer_resolver = Resolver.new
|
60
|
+
outer_resolver.add_resolver "testnest", {'nestlevel' => 'outer'}
|
61
|
+
outer_resolver.add_resolver "inner", @resolver
|
62
|
+
|
63
|
+
assert_equal "inner", @resolver.resolve('testnest.nestlevel')
|
64
|
+
assert_equal "outer", outer_resolver.resolve('testnest.nestlevel')
|
65
|
+
assert_equal "jt", outer_resolver.resolve('user.name')
|
66
|
+
assert_equal "COURSE-anything", outer_resolver.resolve('course.anything')
|
67
|
+
end
|
68
|
+
|
69
|
+
ARGV = ['', "--name", "test_nested_resolver"]
|
70
|
+
# Test::Unit::AutoRunner.run(false, nil, ARGV)
|
71
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path('../../lib/lti2_commons/wire_log', __FILE__)
|
2
|
+
require File.expand_path('../../lib/lti2_commons/mock_request', __FILE__)
|
3
|
+
|
4
|
+
wl = Lti2Commons::WireLogSupport::WireLog.new 'test', 'test.txt'
|
5
|
+
|
6
|
+
wl.clear_log
|
7
|
+
wl.log 'test'
|
8
|
+
wl.log 'tube'
|
9
|
+
|
10
|
+
wl.log <<aa
|
11
|
+
hello,
|
12
|
+
how are you?
|
13
|
+
aa
|
14
|
+
|
15
|
+
puts 'done'
|