|
2 | 2 |
|
3 | 3 | import pytest
|
4 | 4 | import numpy as np
|
| 5 | +import re |
5 | 6 |
|
6 | 7 |
|
7 | 8 | import plotly.graph_objs as go
|
8 | 9 | import plotly.io as pio
|
9 | 10 | from plotly.io._utils import plotly_cdn_url
|
| 11 | +from plotly.offline.offline import get_plotlyjs |
| 12 | +from plotly.io._html import _generate_sri_hash |
10 | 13 |
|
11 | 14 |
|
12 | 15 | if sys.version_info >= (3, 3):
|
@@ -46,3 +49,41 @@ def test_html_deterministic(fig1):
|
46 | 49 | assert pio.to_html(fig1, include_plotlyjs="cdn", div_id=div_id) == pio.to_html(
|
47 | 50 | fig1, include_plotlyjs="cdn", div_id=div_id
|
48 | 51 | )
|
| 52 | + |
| 53 | + |
| 54 | +def test_cdn_includes_integrity_attribute(fig1): |
| 55 | + """Test that the CDN script tag includes an integrity attribute with SHA256 hash""" |
| 56 | + html_output = pio.to_html(fig1, include_plotlyjs="cdn") |
| 57 | + |
| 58 | + # Check that the script tag includes integrity attribute |
| 59 | + assert 'integrity="sha256-' in html_output |
| 60 | + assert 'crossorigin="anonymous"' in html_output |
| 61 | + |
| 62 | + # Verify it's in the correct script tag |
| 63 | + cdn_pattern = re.compile( |
| 64 | + r'<script[^>]*src="' |
| 65 | + + re.escape(plotly_cdn_url()) |
| 66 | + + r'"[^>]*integrity="sha256-[A-Za-z0-9+/=]+"[^>]*>' |
| 67 | + ) |
| 68 | + match = cdn_pattern.search(html_output) |
| 69 | + assert match is not None, "CDN script tag with integrity attribute not found" |
| 70 | + |
| 71 | + |
| 72 | +def test_cdn_integrity_hash_matches_bundled_content(fig1): |
| 73 | + """Test that the SRI hash in CDN script tag matches the bundled plotly.js content""" |
| 74 | + html_output = pio.to_html(fig1, include_plotlyjs="cdn") |
| 75 | + |
| 76 | + # Extract the integrity hash from the HTML output |
| 77 | + integrity_pattern = re.compile(r'integrity="(sha256-[A-Za-z0-9+/=]+)"') |
| 78 | + match = integrity_pattern.search(html_output) |
| 79 | + assert match is not None, "Integrity attribute not found" |
| 80 | + extracted_hash = match.group(1) |
| 81 | + |
| 82 | + # Generate expected hash from bundled content |
| 83 | + plotlyjs_content = get_plotlyjs() |
| 84 | + expected_hash = _generate_sri_hash(plotlyjs_content) |
| 85 | + |
| 86 | + # Verify they match |
| 87 | + assert ( |
| 88 | + extracted_hash == expected_hash |
| 89 | + ), f"Hash mismatch: expected {expected_hash}, got {extracted_hash}" |
0 commit comments