canvas_link_migrator 1.0.8 → 1.0.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/canvas_link_migrator/link_parser.rb +5 -8
- data/lib/canvas_link_migrator/link_resolver.rb +34 -17
- data/lib/canvas_link_migrator/resource_map_service.rb +13 -13
- data/lib/canvas_link_migrator/version.rb +1 -1
- data/spec/canvas_link_migrator/imported_html_converter_spec.rb +23 -23
- data/spec/canvas_link_migrator/link_parser_spec.rb +13 -0
- data/spec/canvas_link_migrator/link_resolver_spec.rb +4 -4
- data/spec/fixtures/canvas_resource_map.json +21 -10
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38b2eee1dd99763edbef1c28dc90e5e47c6fb1d0d9d533fca3e0c519de0819d3
|
4
|
+
data.tar.gz: 0ab502f07ec831d35a77d8e0fb3bc4d2b04f2ea2579dce5cf16c9b3670a6bdca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be0b2b35cf07e574cf02e9fe70e63c26246126ad058d390a4a7db84917eb24ad56d6c5d77d2a3d683d8c23319922161630dca35990e4a2afd9f76dc1df38c97b
|
7
|
+
data.tar.gz: 9ddeed1d503d7c50c1f8be3b8357fe739c3c8e59aa1e05e2eded14956bfedcac90274803b74f932950f6e5210e6d5b3870cbbdfd793d5736634eba8fa1cd56b6
|
@@ -19,7 +19,6 @@
|
|
19
19
|
|
20
20
|
require "nokogiri"
|
21
21
|
require "digest"
|
22
|
-
require "addressable"
|
23
22
|
|
24
23
|
module CanvasLinkMigrator
|
25
24
|
class LinkParser
|
@@ -96,12 +95,15 @@ module CanvasLinkMigrator
|
|
96
95
|
|
97
96
|
# Replace old style media anchor tags with iframes
|
98
97
|
doc.search("a[id*='media_comment_']").each do |media_node|
|
98
|
+
next unless media_node["class"].match('instructure_inline_media_comment')
|
99
|
+
|
99
100
|
media_node.name = "iframe"
|
100
101
|
# smallest accepted size for iframe since we don't have the size available for these
|
101
102
|
media_node["style"] = "width: 320px; height: 240px; display: inline-block;"
|
102
103
|
media_node["title"] = media_node.text
|
103
104
|
media_node.child&.remove
|
104
|
-
|
105
|
+
media_type = media_node["class"].match(/(audio|video)/)&.[](1)
|
106
|
+
media_node["data-media-type"] = media_type if media_type
|
105
107
|
media_node["src"] = media_node["href"]
|
106
108
|
media_node.delete("href")
|
107
109
|
media_node["allowfullscreen"] = "allowfullscreen"
|
@@ -141,12 +143,7 @@ module CanvasLinkMigrator
|
|
141
143
|
url.gsub!("%24#{ref}%24", "$#{ref}$")
|
142
144
|
end
|
143
145
|
|
144
|
-
|
145
|
-
result = parse_url(url, node, attr)
|
146
|
-
rescue Addressable::URI::InvalidURIError
|
147
|
-
return
|
148
|
-
end
|
149
|
-
|
146
|
+
result = parse_url(url, node, attr)
|
150
147
|
if result[:resolved]
|
151
148
|
# resolved, just replace and carry on
|
152
149
|
new_url = result[:new_url] || url
|
@@ -18,6 +18,7 @@
|
|
18
18
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
19
|
|
20
20
|
require "active_support/core_ext/object"
|
21
|
+
require "addressable"
|
21
22
|
require "rack"
|
22
23
|
|
23
24
|
module CanvasLinkMigrator
|
@@ -44,6 +45,14 @@ module CanvasLinkMigrator
|
|
44
45
|
@attachment_path_id_lookup_lower ||= attachment_path_id_lookup&.transform_keys(&:downcase)
|
45
46
|
end
|
46
47
|
|
48
|
+
def add_verifier_to_query(url, uuid)
|
49
|
+
parsed_url = Addressable::URI.parse(url)
|
50
|
+
parsed_url.query_values = (parsed_url.query_values || {}).merge("verifier" => uuid)
|
51
|
+
parsed_url.to_s
|
52
|
+
rescue Addressable::InvalidURIError
|
53
|
+
url
|
54
|
+
end
|
55
|
+
|
47
56
|
# finds the :new_value to use to replace the placeholder
|
48
57
|
def resolve_link!(link)
|
49
58
|
case link[:link_type]
|
@@ -71,13 +80,17 @@ module CanvasLinkMigrator
|
|
71
80
|
linked_wiki_url = @migration_id_converter.convert_wiki_page_migration_id_to_slug(migration_id) || migration_id
|
72
81
|
link[:new_value] = "#{context_path}/pages/#{linked_wiki_url}#{query}"
|
73
82
|
elsif type == "attachments"
|
74
|
-
att_id = @migration_id_converter.convert_attachment_migration_id(migration_id)
|
83
|
+
att_id, uuid = @migration_id_converter.convert_attachment_migration_id(migration_id)
|
75
84
|
if att_id
|
76
|
-
|
85
|
+
new_url = "#{context_path}/files/#{att_id}/preview"
|
86
|
+
new_url = add_verifier_to_query(new_url, uuid) if uuid
|
87
|
+
link[:new_value] = new_url
|
77
88
|
end
|
78
89
|
elsif type == "media_attachments_iframe"
|
79
|
-
att_id = @migration_id_converter.convert_attachment_migration_id(migration_id)
|
80
|
-
|
90
|
+
att_id, uuid = @migration_id_converter.convert_attachment_migration_id(migration_id)
|
91
|
+
new_url = att_id ? "/media_attachments_iframe/#{att_id}#{link[:query]}" : link[:old_value]
|
92
|
+
new_url = add_verifier_to_query(new_url, uuid) if uuid
|
93
|
+
link[:new_value] = new_url
|
81
94
|
else
|
82
95
|
object_id = @migration_id_converter.convert_migration_id(type, migration_id)
|
83
96
|
if object_id
|
@@ -116,7 +129,7 @@ module CanvasLinkMigrator
|
|
116
129
|
end
|
117
130
|
link[:new_value] = new_url
|
118
131
|
when :file_ref
|
119
|
-
file_id = @migration_id_converter.convert_attachment_migration_id(link[:migration_id])
|
132
|
+
file_id, uuid = @migration_id_converter.convert_attachment_migration_id(link[:migration_id])
|
120
133
|
if file_id
|
121
134
|
rest = link[:rest].presence
|
122
135
|
rest ||= "/preview" unless link[:target_blank]
|
@@ -125,13 +138,15 @@ module CanvasLinkMigrator
|
|
125
138
|
# context prepended to the URL. This prevents
|
126
139
|
# redirects to non cross-origin friendly urls
|
127
140
|
# during a file fetch
|
128
|
-
if rest&.include?("icon_maker_icon=1")
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
141
|
+
new_url = if rest&.include?("icon_maker_icon=1")
|
142
|
+
"/files/#{file_id}#{rest}"
|
143
|
+
elsif link[:in_media_iframe]
|
144
|
+
"/media_attachments_iframe/#{file_id}#{rest}"
|
145
|
+
else
|
146
|
+
"#{context_path}/files/#{file_id}#{rest}"
|
147
|
+
end
|
148
|
+
new_url = add_verifier_to_query(new_url, uuid) if uuid
|
149
|
+
link[:new_value] = new_url
|
135
150
|
else
|
136
151
|
link[:missing_url] = link[:old_value].partition("$CANVAS_COURSE_REFERENCE$").last
|
137
152
|
end
|
@@ -200,6 +215,7 @@ module CanvasLinkMigrator
|
|
200
215
|
# CCHelper::file_query_string
|
201
216
|
params = Rack::Utils.parse_nested_query(qs.presence || "")
|
202
217
|
qs = []
|
218
|
+
qs << "verifier=#{file["uuid"]}" if file["uuid"].present?
|
203
219
|
new_action = ""
|
204
220
|
params.each do |k, v|
|
205
221
|
case k
|
@@ -217,23 +233,24 @@ module CanvasLinkMigrator
|
|
217
233
|
new_url
|
218
234
|
end
|
219
235
|
|
220
|
-
def media_attachment_iframe_url(file_id, media_type = nil)
|
236
|
+
def media_attachment_iframe_url(file_id, uuid = nil, media_type = nil)
|
221
237
|
url = "/media_attachments_iframe/#{file_id}?embedded=true"
|
222
238
|
url += "&type=#{media_type}" if media_type.present?
|
239
|
+
url += "&verifier=#{uuid}" if uuid.present?
|
223
240
|
url
|
224
241
|
end
|
225
242
|
|
226
243
|
def resolve_media_data(node, rel_path)
|
227
244
|
if rel_path && (file = find_file_in_context(rel_path[/^[^?]+/])) # strip query string for this search
|
228
|
-
media_id = file
|
245
|
+
media_id = file["media_entry_id"]
|
229
246
|
node["data-media-id"] = media_id # safe to delete?
|
230
|
-
media_attachment_iframe_url(file["id"], node["data-media-type"])
|
247
|
+
media_attachment_iframe_url(file["id"], file["uuid"], node["data-media-type"])
|
231
248
|
elsif rel_path&.match(/\/media_attachments_iframe\/\d+/)
|
232
249
|
# media attachment from another course or something
|
233
250
|
rel_path
|
234
251
|
elsif node["data-media-id"].present?
|
235
|
-
|
236
|
-
|
252
|
+
file_id, uuid = @migration_id_converter.convert_attachment_media_id(node["data-media-id"])
|
253
|
+
file_id ? media_attachment_iframe_url(file_id, uuid, node["data-media-type"]) : nil
|
237
254
|
else
|
238
255
|
node.delete("class")
|
239
256
|
node.delete("id")
|
@@ -89,7 +89,19 @@ module CanvasLinkMigrator
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def convert_attachment_migration_id(migration_id)
|
92
|
-
resources.dig("files", migration_id, "destination", "
|
92
|
+
resources.dig("files", migration_id, "destination")&.slice("id", "uuid")&.values
|
93
|
+
end
|
94
|
+
|
95
|
+
def media_map
|
96
|
+
@media_map ||= resources["files"].each_with_object({}) do |(_mig_id, file), map|
|
97
|
+
media_id = file.dig("destination", "media_entry_id")
|
98
|
+
next unless media_id
|
99
|
+
map[media_id] = file
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def convert_attachment_media_id(media_id)
|
104
|
+
media_map.dig(media_id, "destination")&.slice("id", "uuid")&.values
|
93
105
|
end
|
94
106
|
|
95
107
|
def convert_migration_id(type, migration_id)
|
@@ -106,17 +118,5 @@ module CanvasLinkMigrator
|
|
106
118
|
def lookup_attachment_by_migration_id(migration_id)
|
107
119
|
resources.dig("files", migration_id, "destination")
|
108
120
|
end
|
109
|
-
|
110
|
-
def media_map
|
111
|
-
@media_map ||= resources["files"].each_with_object({}) do |(_mig_id, file), map|
|
112
|
-
media_id = file.dig("destination", "media_entry_id")
|
113
|
-
next unless media_id
|
114
|
-
map[media_id] = file
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
def lookup_attachment_by_media_id(media_id)
|
119
|
-
media_map.dig(media_id, "destination")
|
120
|
-
end
|
121
121
|
end
|
122
122
|
end
|
@@ -75,7 +75,7 @@ describe CanvasLinkMigrator::ImportedHtmlConverter do
|
|
75
75
|
it "converts data-download-url for files without appending a context" do
|
76
76
|
html, bad_links = subject
|
77
77
|
expect(html).to eq(
|
78
|
-
"<img src=\"#{@path}files/5/download?download_frd=1\" alt=\"\" data-inst-icon-maker-icon=\"true\" data-download-url=\"/files/5/download?download_frd=1&icon_maker_icon=1\">"
|
78
|
+
"<img src=\"#{@path}files/5/download?download_frd=1&verifier=u5\" alt=\"\" data-inst-icon-maker-icon=\"true\" data-download-url=\"/files/5/download?download_frd=1&icon_maker_icon=1&verifier=u5\">"
|
79
79
|
)
|
80
80
|
expect(bad_links).to be_nil
|
81
81
|
end
|
@@ -83,7 +83,7 @@ describe CanvasLinkMigrator::ImportedHtmlConverter do
|
|
83
83
|
|
84
84
|
it "finds an attachment by migration id" do
|
85
85
|
test_string = %{<p>This is an image: <br /><img src="%24CANVAS_OBJECT_REFERENCE%24/attachments/F" alt=":(" /></p>}
|
86
|
-
expect(@converter.convert_exported_html(test_string)).to eq([%{<p>This is an image: <br><img src="#{@path}files/6/preview" alt=":("></p>}, nil])
|
86
|
+
expect(@converter.convert_exported_html(test_string)).to eq([%{<p>This is an image: <br><img src="#{@path}files/6/preview?verifier=u6" alt=":("></p>}, nil])
|
87
87
|
end
|
88
88
|
|
89
89
|
it "leaves relative user attachments alone" do
|
@@ -106,20 +106,20 @@ describe CanvasLinkMigrator::ImportedHtmlConverter do
|
|
106
106
|
expect(bad_links[0]).to include({ link_type: :file, missing_url: "/courses/2/file_contents/course%20files/test.png" })
|
107
107
|
|
108
108
|
expect(@converter.link_resolver).to receive(:attachment_path_id_lookup).twice.and_call_original
|
109
|
-
expect(@converter.convert_exported_html(test_string)).to eq([%{<p>This is an image: <br><img src="#{@path}files/5/preview" alt=":("></p>}, nil])
|
109
|
+
expect(@converter.convert_exported_html(test_string)).to eq([%{<p>This is an image: <br><img src="#{@path}files/5/preview?verifier=u5" alt=":("></p>}, nil])
|
110
110
|
end
|
111
111
|
|
112
112
|
it "finds an attachment by a path with a space" do
|
113
113
|
test_string = %(<img src="subfolder/with%20a%20space/test.png" alt="nope" />)
|
114
|
-
expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/6/preview" alt="nope">), nil])
|
114
|
+
expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/6/preview?verifier=u6" alt="nope">), nil])
|
115
115
|
|
116
116
|
test_string = %(<img src="subfolder/with+a+space/test.png" alt="nope" />)
|
117
|
-
expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/6/preview" alt="nope">), nil])
|
117
|
+
expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/6/preview?verifier=u6" alt="nope">), nil])
|
118
118
|
end
|
119
119
|
|
120
120
|
it "finds an attachment even if the link has an extraneous folder" do
|
121
121
|
test_string = %(<img src="anotherfolder/subfolder/test.png" alt="nope" />)
|
122
|
-
expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/7/preview" alt="nope">), nil])
|
122
|
+
expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/7/preview?verifier=u7" alt="nope">), nil])
|
123
123
|
end
|
124
124
|
|
125
125
|
it "finds an attachment by path if capitalization is different" do
|
@@ -127,18 +127,18 @@ describe CanvasLinkMigrator::ImportedHtmlConverter do
|
|
127
127
|
expect(@converter.link_resolver).to receive(:attachment_path_id_lookup).twice.and_return({ "subfolder/withcapital/test.png" => "F" })
|
128
128
|
|
129
129
|
test_string = %(<img src="subfolder/WithCapital/TEST.png" alt="nope" />)
|
130
|
-
expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/6/preview" alt="nope">), nil])
|
130
|
+
expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/6/preview?verifier=u6" alt="nope">), nil])
|
131
131
|
end
|
132
132
|
|
133
133
|
it "finds an attachment with query params" do
|
134
134
|
test_string = %(<img src="%24IMS_CC_FILEBASE%24/test.png?canvas_customaction=1&canvas_qs_customparam=1" alt="nope" />)
|
135
|
-
expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/5/customaction?customparam=1" alt="nope">), nil])
|
135
|
+
expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/5/customaction?verifier=u5&customparam=1" alt="nope">), nil])
|
136
136
|
|
137
137
|
test_string = %(<img src="%24IMS_CC_FILEBASE%24/test.png?canvas_qs_customparam2=3" alt="nope" />)
|
138
|
-
expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/5/preview?customparam2=3" alt="nope">), nil])
|
138
|
+
expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/5/preview?verifier=u5&customparam2=3" alt="nope">), nil])
|
139
139
|
|
140
140
|
test_string = %(<img src="%24IMS_CC_FILEBASE%24/test.png?notarelevantparam" alt="nope" />)
|
141
|
-
expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/5/preview" alt="nope">), nil])
|
141
|
+
expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/5/preview?verifier=u5" alt="nope">), nil])
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
@@ -221,9 +221,9 @@ describe CanvasLinkMigrator::ImportedHtmlConverter do
|
|
221
221
|
|
222
222
|
expected_string = <<~HTML.strip
|
223
223
|
<p>
|
224
|
-
with media object url: <iframe id="media_comment_m-stuff" class="instructure_inline_media_comment video_comment" style="width: 320px; height: 240px; display: inline-block;" title="this is a media comment" data-media-type="video" src="/media_attachments_iframe/5?embedded=true&type=video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-stuff"></iframe>
|
225
|
-
with file content url: <iframe id="media_comment_0_bq09qam2" class="instructure_inline_media_comment video_comment" style="width: 320px; height: 240px; display: inline-block;" title="this is a media comment" data-media-type="video" src="/media_attachments_iframe/6?embedded=true&type=video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="0_bq09qam2"></iframe>
|
226
|
-
with mediahref url: <iframe data-media-type="video" src="/media_attachments_iframe/9?type=video&
|
224
|
+
with media object url: <iframe id="media_comment_m-stuff" class="instructure_inline_media_comment video_comment" style="width: 320px; height: 240px; display: inline-block;" title="this is a media comment" data-media-type="video" src="/media_attachments_iframe/5?embedded=true&type=video&verifier=u5" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-stuff"></iframe>
|
225
|
+
with file content url: <iframe id="media_comment_0_bq09qam2" class="instructure_inline_media_comment video_comment" style="width: 320px; height: 240px; display: inline-block;" title="this is a media comment" data-media-type="video" src="/media_attachments_iframe/6?embedded=true&type=video&verifier=u6" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="0_bq09qam2"></iframe>
|
226
|
+
with mediahref url: <iframe data-media-type="video" src="/media_attachments_iframe/9?embedded=true&type=video&verifier=u9" data-media-id="m-yodawg"></iframe>
|
227
227
|
</p>
|
228
228
|
HTML
|
229
229
|
|
@@ -272,8 +272,8 @@ describe CanvasLinkMigrator::ImportedHtmlConverter do
|
|
272
272
|
HTML
|
273
273
|
expected_string = <<~HTML.strip
|
274
274
|
<p>
|
275
|
-
with wrong file in href: <iframe class="instructure_inline_media_comment video_comment" id="media_comment_m-stuff" style="width: 320px; height: 240px; display: inline-block;" title="this is a media comment" data-media-type="video" src="/media_attachments_iframe/5?embedded=true&type=video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-stuff"></iframe><br><br>
|
276
|
-
with no href: <iframe class="instructure_inline_media_comment video_comment" id="media_comment_m-stuff" style="width: 320px; height: 240px; display: inline-block;" title="" data-media-type="video" src="/media_attachments_iframe/5?embedded=true&type=video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-stuff"></iframe><br><br>
|
275
|
+
with wrong file in href: <iframe class="instructure_inline_media_comment video_comment" id="media_comment_m-stuff" style="width: 320px; height: 240px; display: inline-block;" title="this is a media comment" data-media-type="video" src="/media_attachments_iframe/5?embedded=true&type=video&verifier=u5" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-stuff"></iframe><br><br>
|
276
|
+
with no href: <iframe class="instructure_inline_media_comment video_comment" id="media_comment_m-stuff" style="width: 320px; height: 240px; display: inline-block;" title="" data-media-type="video" src="/media_attachments_iframe/5?embedded=true&type=video&verifier=u5" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-stuff"></iframe><br><br>
|
277
277
|
</p>
|
278
278
|
HTML
|
279
279
|
expect(@converter.convert_exported_html(test_string)).to eq([expected_string, nil])
|
@@ -281,33 +281,33 @@ describe CanvasLinkMigrator::ImportedHtmlConverter do
|
|
281
281
|
|
282
282
|
it "converts old RCE media object iframes" do
|
283
283
|
test_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" src="/media_objects_iframe/m-lolcat?type=video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-lolcat"></iframe>)
|
284
|
-
replacement_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" src="/media_attachments_iframe/8?embedded=true&type=video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-lolcat"></iframe>)
|
284
|
+
replacement_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" src="/media_attachments_iframe/8?embedded=true&type=video&verifier=u8" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-lolcat"></iframe>)
|
285
285
|
expect(@converter.convert_exported_html(test_string)).to eq([replacement_string, nil])
|
286
286
|
end
|
287
287
|
|
288
288
|
it "handles and repair half broken new RCE media iframes" do
|
289
289
|
test_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" src="%24IMS_CC_FILEBASE%24/#" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-lolcat"></iframe>)
|
290
|
-
repaired_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" src="/media_attachments_iframe/8?embedded=true&type=video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-lolcat"></iframe>)
|
290
|
+
repaired_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" src="/media_attachments_iframe/8?embedded=true&type=video&verifier=u8" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-lolcat"></iframe>)
|
291
291
|
expect(@converter.convert_exported_html(test_string)).to eq([repaired_string, nil])
|
292
292
|
end
|
293
293
|
|
294
294
|
it "converts source tags to RCE media iframes" do
|
295
295
|
test_string = %(<video style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-lolcat"><source src="/media_objects_iframe/m-lolcat?type=video" data-media-id="m-lolcat" data-media-type="video"></video>)
|
296
|
-
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-lolcat" src="/media_attachments_iframe/8?embedded=true&type=video"></iframe>)
|
296
|
+
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-lolcat" src="/media_attachments_iframe/8?embedded=true&type=video&verifier=u8"></iframe>)
|
297
297
|
expect(@converter.convert_exported_html(test_string)).to eq([converted_string, nil])
|
298
298
|
|
299
299
|
test_string = %(<audio style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-yodawg"><source src="/media_objects_iframe/m-yodawg?type=audio" data-media-id="m-yodawg" data-media-type="audio"></audio>)
|
300
|
-
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-yodawg" src="/media_attachments_iframe/9?embedded=true&type=audio"></iframe>)
|
300
|
+
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-yodawg" src="/media_attachments_iframe/9?embedded=true&type=audio&verifier=u9"></iframe>)
|
301
301
|
expect(@converter.convert_exported_html(test_string)).to eq([converted_string, nil])
|
302
302
|
end
|
303
303
|
|
304
304
|
it "converts source tags to RCE media attachment iframes" do
|
305
305
|
test_string = %(<video style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-stuff"><source src="$IMS-CC-FILEBASE$/subfolder/with a space/yodawg.mov?canvas_=1&canvas_qs_type=video&canvas_qs_amp=&canvas_qs_embedded=true&media_attachment=true" data-media-id="m-stuff" data-media-type="video"></video>)
|
306
|
-
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-yodawg" src="/media_attachments_iframe/9?embedded=true&type=video"></iframe>)
|
306
|
+
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-yodawg" src="/media_attachments_iframe/9?embedded=true&type=video&verifier=u9"></iframe>)
|
307
307
|
expect(@converter.convert_exported_html(test_string)).to eq([converted_string, nil])
|
308
308
|
|
309
309
|
test_string = %(<audio style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-stuff"><source src="$IMS-CC-FILEBASE$/lolcat.mp3?canvas_=1&canvas_qs_type=audio&canvas_qs_amp=&canvas_qs_embedded=true&media_attachment=true" data-media-id="m-stuff" data-media-type="audio"></video>)
|
310
|
-
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-lolcat" src="/media_attachments_iframe/8?embedded=true&type=audio"></iframe>)
|
310
|
+
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-lolcat" src="/media_attachments_iframe/8?embedded=true&type=audio&verifier=u8"></iframe>)
|
311
311
|
expect(@converter.convert_exported_html(test_string)).to eq([converted_string, nil])
|
312
312
|
end
|
313
313
|
|
@@ -323,11 +323,11 @@ describe CanvasLinkMigrator::ImportedHtmlConverter do
|
|
323
323
|
|
324
324
|
it "converts course copy style media attachmet iframe links" do
|
325
325
|
test_string = %(<video style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-yodawg"><source src="$CANVAS_COURSE_REFERENCE$/file_ref/I?media_attachment=true&type=video" data-media-id="m-yodawg" data-media-type="video"></video>)
|
326
|
-
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-yodawg" src="/media_attachments_iframe/9?type=video&
|
326
|
+
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-yodawg" src="/media_attachments_iframe/9?embedded=true&type=video&verifier=u9"></iframe>)
|
327
327
|
expect(@converter.convert_exported_html(test_string)).to eq([converted_string, nil])
|
328
328
|
|
329
329
|
test_string = %(<audio style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-lolcat"><source src="$CANVAS_COURSE_REFERENCE$/file_ref/H?media_attachment=true&type=audio" data-media-id="m-lolcat" data-media-type="audio"></audio>)
|
330
|
-
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-lolcat" src="/media_attachments_iframe/8?type=audio&
|
330
|
+
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-lolcat" src="/media_attachments_iframe/8?embedded=true&type=audio&verifier=u8"></iframe>)
|
331
331
|
expect(@converter.convert_exported_html(test_string)).to eq([converted_string, nil])
|
332
332
|
end
|
333
333
|
|
@@ -51,4 +51,17 @@ describe CanvasLinkMigrator::LinkParser do
|
|
51
51
|
expect{ parser.convert_link(doc.at_css('a'), "href", "wiki_page", "migrationid", "") }.not_to raise_error
|
52
52
|
end
|
53
53
|
end
|
54
|
+
|
55
|
+
describe "convert" do
|
56
|
+
it "does not change media anchor tags into iframes if they don't have inline_media_comment in the class" do
|
57
|
+
doc = Nokogiri::HTML5.fragment(%Q(<p><a id="media_comment_m-5HHT5LqZqPf7qhEJ7PbKtehCiunxM4BB" class=" instructure_video_link instructure_file_link" title="00-Personal Intro.m4v" href="https://xu.instructure.com/courses/83206/files/12176377/download?wrap=1" target="" data-api-endpoint="https://xu.instructure.com/api/v1/courses/83206/files/12176377" data-api-returntype="File">Click here to watch personal introduction</a></p>))
|
58
|
+
parser.convert(doc.to_html, "type", "lookup_id", "field")
|
59
|
+
expect(doc.to_html).to match(%Q(<p><a id="media_comment_m-5HHT5LqZqPf7qhEJ7PbKtehCiunxM4BB" class=" instructure_video_link instructure_file_link" title="00-Personal Intro.m4v" href="https://xu.instructure.com/courses/83206/files/12176377/download?wrap=1" target="" data-api-endpoint="https://xu.instructure.com/api/v1/courses/83206/files/12176377" data-api-returntype="File">Click here to watch personal introduction</a></p>))
|
60
|
+
end
|
61
|
+
|
62
|
+
it "does not crash if it can't find a video/audio_comment class name" do
|
63
|
+
doc = Nokogiri::HTML5.fragment(%Q(<a id="media_comment_m-4uoGqVdEqXhpqu2ZMytHSy9XMV73aQ7E" class="instructure_inline_media_comment" data-media_comment_type="video" data-alt=""></a>))
|
64
|
+
expect{ parser.convert(doc.to_html, "type", "lookup_id", "field") }.not_to raise_error
|
65
|
+
end
|
66
|
+
end
|
54
67
|
end
|
@@ -48,25 +48,25 @@ describe CanvasLinkMigrator::LinkResolver do
|
|
48
48
|
it "converts file_ref urls" do
|
49
49
|
link = { link_type: :file_ref, migration_id: "F" }
|
50
50
|
resolver.resolve_link!(link)
|
51
|
-
expect(link[:new_value]).to eq("/courses/2/files/6/preview")
|
51
|
+
expect(link[:new_value]).to eq("/courses/2/files/6/preview?verifier=u6")
|
52
52
|
end
|
53
53
|
|
54
54
|
it "does not suffix /preview to target blank links" do
|
55
55
|
link = { link_type: :file_ref, target_blank: true, migration_id: "F" }
|
56
56
|
resolver.resolve_link!(link)
|
57
|
-
expect(link[:new_value]).to eq("/courses/2/files/6")
|
57
|
+
expect(link[:new_value]).to eq("/courses/2/files/6?verifier=u6")
|
58
58
|
end
|
59
59
|
|
60
60
|
it "converts attachment urls" do
|
61
61
|
link = { link_type: :object, type: "attachments", migration_id: "E", query: "?foo=bar" }
|
62
62
|
resolver.resolve_link!(link)
|
63
|
-
expect(link[:new_value]).to eq("/courses/2/files/5/preview")
|
63
|
+
expect(link[:new_value]).to eq("/courses/2/files/5/preview?verifier=u5")
|
64
64
|
end
|
65
65
|
|
66
66
|
it "converts media_attachments_iframe urls" do
|
67
67
|
link = { link_type: :object, type: "media_attachments_iframe", migration_id: "F", query: "?foo=bar" }
|
68
68
|
resolver.resolve_link!(link)
|
69
|
-
expect(link[:new_value]).to eq("/media_attachments_iframe/6?foo=bar")
|
69
|
+
expect(link[:new_value]).to eq("/media_attachments_iframe/6?foo=bar&verifier=u6")
|
70
70
|
end
|
71
71
|
|
72
72
|
it "converts discussion_topic links" do
|
@@ -50,49 +50,60 @@
|
|
50
50
|
"E": {
|
51
51
|
"destination": {
|
52
52
|
"id": "5",
|
53
|
-
"media_entry_id": "m-stuff"
|
53
|
+
"media_entry_id": "m-stuff",
|
54
|
+
"uuid": "u5"
|
54
55
|
},
|
55
56
|
"source": {
|
56
57
|
"id": "3",
|
57
|
-
"media_entry_id": "m-stuff"
|
58
|
+
"media_entry_id": "m-stuff",
|
59
|
+
"uuid": "u3"
|
58
60
|
}
|
59
61
|
},
|
60
62
|
"F": {
|
61
63
|
"destination": {
|
62
64
|
"id": "6",
|
63
|
-
"media_entry_id": "0_bq09qam2"
|
65
|
+
"media_entry_id": "0_bq09qam2",
|
66
|
+
"uuid": "u6"
|
64
67
|
},
|
65
68
|
"source": {
|
66
69
|
"id": "4",
|
67
|
-
"media_entry_id": "0_bq09qam2"
|
70
|
+
"media_entry_id": "0_bq09qam2",
|
71
|
+
"uuid": "u4"
|
68
72
|
}
|
69
73
|
},
|
70
74
|
"G": {
|
71
75
|
"destination": {
|
72
|
-
"id": "7"
|
76
|
+
"id": "7",
|
77
|
+
"uuid": "u7"
|
73
78
|
},
|
74
79
|
"source": {
|
75
|
-
"id": "2"
|
80
|
+
"id": "2",
|
81
|
+
"uuid": "u2"
|
76
82
|
}
|
77
83
|
},
|
78
84
|
"H": {
|
79
85
|
"destination": {
|
80
86
|
"id": "8",
|
81
|
-
"media_entry_id": "m-lolcat"
|
87
|
+
"media_entry_id": "m-lolcat",
|
88
|
+
"uuid": "u8"
|
89
|
+
|
82
90
|
},
|
83
91
|
"source": {
|
84
92
|
"id": "3",
|
85
|
-
"media_entry_id": "m-lolcat"
|
93
|
+
"media_entry_id": "m-lolcat",
|
94
|
+
"uuid": "u3"
|
86
95
|
}
|
87
96
|
},
|
88
97
|
"I": {
|
89
98
|
"destination": {
|
90
99
|
"id": "9",
|
91
|
-
"media_entry_id": "m-yodawg"
|
100
|
+
"media_entry_id": "m-yodawg",
|
101
|
+
"uuid": "u9"
|
92
102
|
},
|
93
103
|
"source": {
|
94
104
|
"id": "4",
|
95
|
-
"media_entry_id": "m-yodawg"
|
105
|
+
"media_entry_id": "m-yodawg",
|
106
|
+
"uuid": "u4"
|
96
107
|
}
|
97
108
|
}
|
98
109
|
},
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: canvas_link_migrator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mysti Lilla
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2024-
|
14
|
+
date: 2024-06-07 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activesupport
|
@@ -162,7 +162,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
162
162
|
requirements:
|
163
163
|
- - ">="
|
164
164
|
- !ruby/object:Gem::Version
|
165
|
-
version: '
|
165
|
+
version: '2.7'
|
166
166
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
167
167
|
requirements:
|
168
168
|
- - ">="
|