canvas_link_migrator 1.0.18 → 1.0.19
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 +4 -4
- data/lib/canvas_link_migrator/imported_html_converter.rb +8 -5
- data/lib/canvas_link_migrator/link_parser.rb +6 -2
- data/lib/canvas_link_migrator/version.rb +1 -1
- data/spec/canvas_link_migrator/imported_html_converter_spec.rb +193 -0
- data/spec/fixtures/canvas_resource_map.json +0 -1
- data/spec/fixtures/canvas_resource_map_pages.json +0 -1
- metadata +16 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1295e9d9f0470130b2967896d1356ef0669d95082acf1f591347ee9896cae968
|
|
4
|
+
data.tar.gz: c28022e251c0755942ccdadb7462335ce3d97f29594d7ef7480c847a3c40bc2a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: da9757bd142342be4507fac11f7ad2c67f3b138f89a1db2e276ef5f80f363438b35512aef904ea0d6bfd9238c0d58ef90b5a21aaea0c8ededfe60456969e5bdc
|
|
7
|
+
data.tar.gz: cb128cfa720324395074336a325587d33940d6c664bf52df33988553347a8b4907ce1434e964194902920f7564276b1b9a0d88ed38c7d403a4c419869cdbc006
|
|
@@ -37,11 +37,14 @@ module CanvasLinkMigrator
|
|
|
37
37
|
LinkParser::REFERENCE_KEYWORDS.each { |ref| url.gsub!("%24#{ref}%24", "$#{ref}$") }
|
|
38
38
|
# create the link map for a single link (parse)
|
|
39
39
|
link_parsing_result = link_parser.parse_single_url(url, link_type)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
if link_parsing_result[:resolved]
|
|
41
|
+
link_parser.perform_substitutions_and_make_relative_if_possible(url, link_parsing_result)
|
|
42
|
+
else
|
|
43
|
+
link_parser.handle_unresolved_link(url, link_parsing_result, nil, nil, link_type, nil, nil)
|
|
44
|
+
# resolve_link! on the single element link map
|
|
45
|
+
link_resolver.resolve_link!(link_parsing_result, link_type)
|
|
46
|
+
link_parsing_result[:new_value]
|
|
47
|
+
end
|
|
45
48
|
end
|
|
46
49
|
|
|
47
50
|
def convert_exported_html(input_html)
|
|
@@ -180,7 +180,7 @@ module CanvasLinkMigrator
|
|
|
180
180
|
add_unresolved_link(result, item_type, mig_id, field)
|
|
181
181
|
end
|
|
182
182
|
|
|
183
|
-
def
|
|
183
|
+
def perform_substitutions_and_make_relative_if_possible(url, result)
|
|
184
184
|
new_url = result[:new_url] || url
|
|
185
185
|
unless CanvasLinkMigrator.relative_url?(new_url)
|
|
186
186
|
# perform configured substitutions
|
|
@@ -200,7 +200,11 @@ module CanvasLinkMigrator
|
|
|
200
200
|
nil
|
|
201
201
|
end
|
|
202
202
|
end
|
|
203
|
-
|
|
203
|
+
new_url
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def handle_resolved_link(url, result, node, attr)
|
|
207
|
+
node[attr] = perform_substitutions_and_make_relative_if_possible(url, result)
|
|
204
208
|
end
|
|
205
209
|
|
|
206
210
|
def unresolved(type, data = {})
|
|
@@ -438,5 +438,198 @@ describe CanvasLinkMigrator::ImportedHtmlConverter do
|
|
|
438
438
|
link = @converter.convert_single_link(test_string)
|
|
439
439
|
expect(link).to eq "/courses/2/files/9?verifier=u9&type=video&=&embedded=true"
|
|
440
440
|
end
|
|
441
|
+
|
|
442
|
+
it "handles $CANVAS_COURSE_REFERENCE$/ without crashing" do
|
|
443
|
+
link = @converter.convert_single_link("$CANVAS_COURSE_REFERENCE$/")
|
|
444
|
+
expect(link).to eq "#{@path}"
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
it "handles $CANVAS_COURSE_REFERENCE$/ with link_type: :media_object without crashing" do
|
|
448
|
+
# Not sure this is a realistic case, but we should at least not crash on it
|
|
449
|
+
link = @converter.convert_single_link("$CANVAS_COURSE_REFERENCE$/", link_type: :media_object)
|
|
450
|
+
expect(link).to eq "#{@path}"
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
it "handles external URLs without crashing" do
|
|
454
|
+
link = @converter.convert_single_link("http://example.com/")
|
|
455
|
+
expect(link).to eq "http://example.com/"
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
it "returns nil for failed assignment substitution" do
|
|
459
|
+
link = @converter.convert_single_link("$CANVAS_OBJECT_REFERENCE$/assignments/noexist")
|
|
460
|
+
# passing thru might also be acceptable
|
|
461
|
+
expect(link).to be_nil
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
it "doesn't care about existence of wiki page slugs" do
|
|
465
|
+
link = @converter.convert_single_link("$WIKI_REFERENCE$/pages/slug-no-exist")
|
|
466
|
+
expect(link).to eq "/courses/2/pages/slug-no-exist"
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
it "doesn't care about existence of wiki page slugs (with fragment)" do
|
|
470
|
+
link = @converter.convert_single_link("$WIKI_REFERENCE$/pages/slug-no-exist#hello-world")
|
|
471
|
+
expect(link).to eq "/courses/2/pages/slug-no-exist#hello-world"
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
it "passes through incorrectly used $CANVAS_OBJECT_REFERENCE$" do
|
|
475
|
+
link = @converter.convert_single_link("http://example.com/courses/123/assignments/$CANVAS_OBJECT_REFERENCE$")
|
|
476
|
+
# returning nil might also be acceptable
|
|
477
|
+
expect(link).to eq "http://example.com/courses/123/assignments/$CANVAS_OBJECT_REFERENCE$"
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
it "returns nil for failed assignment substitution (on a different domain)" do
|
|
481
|
+
link = @converter.convert_single_link("http://pineapple.edu/$CANVAS_OBJECT_REFERENCE$/assignments/g2fac96de3e3dc1270155dddedb5bb1ce")
|
|
482
|
+
# passing through might also be acceptable
|
|
483
|
+
expect(link).to be_nil
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
it "returns nil for failed assignment substitution (used instead of host)" do
|
|
487
|
+
link = @converter.convert_single_link("http://$CANVAS_OBJECT_REFERENCE$/assignments/g2fac96de3e3dc1270155dddedb5bb1ce")
|
|
488
|
+
expect(link).to be_nil
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
it "passes through $CANVAS_COURSE_REFERENCE$ used weirdly" do
|
|
492
|
+
link = @converter.convert_single_link("$CANVAS_COURSE_REFERENCE$<b>/foo")
|
|
493
|
+
# nil would probably also be acceptable
|
|
494
|
+
expect(link).to eq "$CANVAS_COURSE_REFERENCE$<b>/foo"
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
it "passes through $INVALID_KEYWORD$" do
|
|
498
|
+
link = @converter.convert_single_link("http://example.com/$INVALID_KEYWORD$/path")
|
|
499
|
+
expect(link).to eq "http://example.com/$INVALID_KEYWORD$/path"
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
it "handles %24CANVAS_OBJECT_REFERENCE%24 like $CANVAS_OBJECT_REFERENCE$" do
|
|
503
|
+
link = @converter.convert_single_link("%24CANVAS_OBJECT_REFERENCE%24/assignments/I")
|
|
504
|
+
expect(link).to eq "/courses/2/assignments/12"
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
it "preserves absolute URLs with query params and fragments" do
|
|
508
|
+
link = @converter.convert_single_link("https://example.com/123?456#789")
|
|
509
|
+
expect(link).to eq "https://example.com/123?456#789"
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
it "preserves absolute URLs to other courses" do
|
|
513
|
+
link = @converter.convert_single_link("https://example.com/courses/123/assignments/123")
|
|
514
|
+
expect(link).to eq "https://example.com/courses/123/assignments/123"
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
it "converts assignment reference by migration id" do
|
|
518
|
+
link = @converter.convert_single_link("$CANVAS_OBJECT_REFERENCE$/assignments/I")
|
|
519
|
+
expect(link).to eq "/courses/2/assignments/12"
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
it "relative-izes absolute URLs in course domains with fragments" do
|
|
523
|
+
# I'm not 100% sure how important this case is, but this follows the
|
|
524
|
+
# behavior of translated HTML
|
|
525
|
+
link = @converter.convert_single_link("http://apple.edu/courses/18/settings#tab-navigation")
|
|
526
|
+
expect(link).to eq "/courses/18/settings#tab-navigation"
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
it "converts course reference with fragment" do
|
|
530
|
+
link = @converter.convert_single_link("$CANVAS_COURSE_REFERENCE$/settings#tab-navigation")
|
|
531
|
+
expect(link).to eq "/courses/2/settings#tab-navigation"
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
it "converts wiki reference by slug" do
|
|
535
|
+
link = @converter.convert_single_link("$WIKI_REFERENCE$/pages/slug-a")
|
|
536
|
+
expect(link).to eq "/courses/2/pages/slug-a"
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
it "converts wiki reference with fragment" do
|
|
540
|
+
link = @converter.convert_single_link("$WIKI_REFERENCE$/pages/slug-a#hello-world")
|
|
541
|
+
expect(link).to eq "/courses/2/pages/slug-a#hello-world"
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
it "preserves absolute URLs with invalid keywords" do
|
|
545
|
+
link = @converter.convert_single_link("http://example.com/$WHATEVER$/foo")
|
|
546
|
+
expect(link).to eq "http://example.com/$WHATEVER$/foo"
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
it "preserves absolute URLs with malformed $123$ syntax" do
|
|
550
|
+
link = @converter.convert_single_link("http://example.com/$123$/foo")
|
|
551
|
+
expect(link).to eq "http://example.com/$123$/foo"
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
it "preserves absolute URLs with errant $ characters" do
|
|
555
|
+
link = @converter.convert_single_link("http://example.com/$/foo")
|
|
556
|
+
expect(link).to eq "http://example.com/$/foo"
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
it "doesn't crash on http://example.com/$CANVAS_COURSE_REFERENCE$/foo" do
|
|
560
|
+
link = @converter.convert_single_link("http://example.com/$CANVAS_COURSE_REFERENCE$/foo")
|
|
561
|
+
# I don't know if we actually care what happens here, as long as it doesn't crash.
|
|
562
|
+
# this seems to follow existing behavior for HTML translation
|
|
563
|
+
expect(link).to eq "/courses/2/foo"
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
it "passes through malformed reference with spaces" do
|
|
567
|
+
link = @converter.convert_single_link("$ $/path")
|
|
568
|
+
expect(link).to eq "$ $/path"
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
it "handles $CANVAS_COURSE_REFERENCE$ with other stuff" do
|
|
572
|
+
link = @converter.convert_single_link("$CANVAS_COURSE_REFERENCE$/assignments/")
|
|
573
|
+
expect(link).to eq "/courses/2/assignments/"
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
describe 'invalid references returning file_contents' do
|
|
577
|
+
# These are invalid or malformed reference syntax that get treated as relative file paths.
|
|
578
|
+
# They get prepended with the course file_contents path, matching the existing behavior
|
|
579
|
+
# for HTML content. These cause 'broken link' pages to show up in the UI.
|
|
580
|
+
# That said, I'm not 100% sure we care that much about the actual values as they are
|
|
581
|
+
# invalid, so feel free to change the specs if we decide to handle these
|
|
582
|
+
# differently (e.g. return nil)
|
|
583
|
+
|
|
584
|
+
it "passes through $CANVAS_COURSE_REFERENCE" do
|
|
585
|
+
link = @converter.convert_single_link("$CANVAS_COURSE_REFERENCE")
|
|
586
|
+
expect(link).to eq("/courses/2/file_contents/course%20files/$CANVAS_COURSE_REFERENCE")
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
it "passes through lone $123" do
|
|
590
|
+
link = @converter.convert_single_link("/$123")
|
|
591
|
+
expect(link).to eq "/courses/2/file_contents/course%20files/$123"
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
it "passes through errant $" do
|
|
595
|
+
link = @converter.convert_single_link("/$")
|
|
596
|
+
expect(link).to eq "/courses/2/file_contents/course%20files/$"
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
it "passes through errant lone $123" do
|
|
600
|
+
link = @converter.convert_single_link("$123")
|
|
601
|
+
expect(link).to eq "/courses/2/file_contents/course%20files/$123"
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
it "passes through errant lone $" do
|
|
605
|
+
link = @converter.convert_single_link("$")
|
|
606
|
+
expect(link).to eq "/courses/2/file_contents/course%20files/$"
|
|
607
|
+
end
|
|
608
|
+
|
|
609
|
+
it "passes through starting $INVALID_KEYWORD$" do
|
|
610
|
+
link = @converter.convert_single_link("$INVALID_KEYWORD$/path")
|
|
611
|
+
expect(link).to eq "/courses/2/file_contents/course%20files/$INVALID_KEYWORD$/path"
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
it "passes through errant $123$" do
|
|
615
|
+
link = @converter.convert_single_link("$123$/path")
|
|
616
|
+
expect(link).to eq "/courses/2/file_contents/course%20files/$123$/path"
|
|
617
|
+
end
|
|
618
|
+
|
|
619
|
+
it "doesn't crash when given $CANVAS_COURSE_REFERENCE$" do
|
|
620
|
+
link = @converter.convert_single_link("$CANVAS_COURSE_REFERENCE$")
|
|
621
|
+
expect(link).to eq "/courses/2/file_contents/course%20files/$CANVAS_COURSE_REFERENCE$"
|
|
622
|
+
end
|
|
623
|
+
|
|
624
|
+
it "doesn't crash on /courses/123/assignments/$CANVAS_OBJECT_REFERENCE$" do
|
|
625
|
+
link = @converter.convert_single_link("/courses/123/assignments/$CANVAS_OBJECT_REFERENCE$")
|
|
626
|
+
expect(link).to eq "/courses/2/file_contents/course%20files/courses/123/assignments/$CANVAS_OBJECT_REFERENCE$"
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
it "handles $$/path" do
|
|
630
|
+
link = @converter.convert_single_link("$$/path")
|
|
631
|
+
expect(link).to eq "/courses/2/file_contents/course%20files/$$/path"
|
|
632
|
+
end
|
|
633
|
+
end
|
|
441
634
|
end
|
|
442
635
|
end
|
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.19
|
|
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:
|
|
14
|
+
date: 2026-03-24 00:00:00.000000000 Z
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
17
17
|
name: activesupport
|
|
@@ -27,6 +27,20 @@ dependencies:
|
|
|
27
27
|
- - ">="
|
|
28
28
|
- !ruby/object:Gem::Version
|
|
29
29
|
version: '0'
|
|
30
|
+
- !ruby/object:Gem::Dependency
|
|
31
|
+
name: bigdecimal
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
33
|
+
requirements:
|
|
34
|
+
- - ">="
|
|
35
|
+
- !ruby/object:Gem::Version
|
|
36
|
+
version: '0'
|
|
37
|
+
type: :runtime
|
|
38
|
+
prerelease: false
|
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '0'
|
|
30
44
|
- !ruby/object:Gem::Dependency
|
|
31
45
|
name: nokogiri
|
|
32
46
|
requirement: !ruby/object:Gem::Requirement
|