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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 949c23c7d951df591af05de644bc829ceada5889aed295bb8e8dee5b897054ee
4
- data.tar.gz: 8418a95af9eca811bf3e3848987bbd83bef233ca7aadaf33455f277cecb759b0
3
+ metadata.gz: 1295e9d9f0470130b2967896d1356ef0669d95082acf1f591347ee9896cae968
4
+ data.tar.gz: c28022e251c0755942ccdadb7462335ce3d97f29594d7ef7480c847a3c40bc2a
5
5
  SHA512:
6
- metadata.gz: 0e886dbeaefd433185a7036739dba643c4c26add118b0dd737ee79db6e1dd7e384ba1a5389491023a857b72727055f494e2894746e5f55849ea13f11855c5b4b
7
- data.tar.gz: 97f130e22876d639a79faf0b062442252df9392b8e2338a6bf6b46793a83d815b954b43e34f4e1ff1fce97f7e4856b4ca34e5085e1b212c58f653dc05ff89c9d
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
- link_parser.handle_parsed_url(url, link_parsing_result, nil, nil, link_type, nil, nil)
41
- # resolve_link! on the single element link map
42
- link_resolver.resolve_link!(link_parsing_result, link_type)
43
- # return the new value
44
- link_parsing_result[:new_value]
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 handle_resolved_link(url, result, node, attr)
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
- node[attr] = new_url
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 = {})
@@ -1,3 +1,3 @@
1
1
  module CanvasLinkMigrator
2
- VERSION = "1.0.18"
2
+ VERSION = "1.0.19"
3
3
  end
@@ -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&amp=&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
@@ -8,7 +8,6 @@
8
8
  "test.png": "E",
9
9
  "media_objects/0_bq09qam2": "F"
10
10
  },
11
- "contains_migration_ids": true,
12
11
  "destination_course": "2",
13
12
  "destination_hosts": [
14
13
  "apple.edu",
@@ -7,7 +7,6 @@
7
7
  "lolcat.mp3": "H",
8
8
  "test.png": "E"
9
9
  },
10
- "contains_migration_ids": true,
11
10
  "destination_course": "2",
12
11
  "destination_hosts": [
13
12
  "apple.edu",
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.18
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: 2025-07-15 00:00:00.000000000 Z
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