From ca910b6f27df88e5de140314ed77a309f54e0ed4 Mon Sep 17 00:00:00 2001
From: Usman Khalid <usman@opencraft.com>
Date: Thu, 30 Aug 2018 05:02:02 +0500
Subject: [PATCH] Collect static asset URLs from
 static_replace.replace_static_urls

Allows users to keep track of which static asset URLs were found in given text,
and what they were replaced from/to.
---
 common/djangoapps/static_replace/__init__.py  | 13 +++++++++-
 .../test/test_static_replace.py               | 25 +++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/common/djangoapps/static_replace/__init__.py b/common/djangoapps/static_replace/__init__.py
index 1e82b9fa9b1..467086c8c04 100644
--- a/common/djangoapps/static_replace/__init__.py
+++ b/common/djangoapps/static_replace/__init__.py
@@ -148,7 +148,7 @@ def make_static_urls_absolute(request, html):
     )
 
 
-def replace_static_urls(text, data_directory=None, course_id=None, static_asset_path=''):
+def replace_static_urls(text, data_directory=None, course_id=None, static_asset_path='', static_paths_out=None):
     """
     Replace /static/$stuff urls either with their correct url as generated by collectstatic,
     (/static/$md5_hashed_stuff) or by the course-specific content static url
@@ -159,19 +159,29 @@ def replace_static_urls(text, data_directory=None, course_id=None, static_asset_
     data_directory: The directory in which course data is stored
     course_id: The course identifier used to distinguish static content for this course in studio
     static_asset_path: Path for static assets, which overrides data_directory and course_namespace, if nonempty
+    static_paths_out: (optional) pass an array to collect tuples for each static URI found:
+      * the original unmodified static URI
+      * the updated static URI (will match the original if unchanged)
     """
 
+    if static_paths_out is None:
+        static_paths_out = []
+
     def replace_static_url(original, prefix, quote, rest):
         """
         Replace a single matched url.
         """
+        original_uri = "".join([prefix, rest])
         # Don't mess with things that end in '?raw'
         if rest.endswith('?raw'):
+            static_paths_out.append((original_uri, original_uri))
             return original
 
         # In debug mode, if we can find the url as is,
         if settings.DEBUG and finders.find(rest, True):
+            static_paths_out.append((original_uri, original_uri))
             return original
+
         # if we're running with a MongoBacked store course_namespace is not None, then use studio style urls
         elif (not static_asset_path) and course_id:
             # first look in the static file pipeline and see if we are trying to reference
@@ -213,6 +223,7 @@ def replace_static_urls(text, data_directory=None, course_id=None, static_asset_
                     rest, str(err)))
                 url = "".join([prefix, course_path])
 
+        static_paths_out.append((original_uri, url))
         return "".join([quote, url, quote])
 
     return process_static_urls(text, replace_static_url, data_dir=static_asset_path or data_directory)
diff --git a/common/djangoapps/static_replace/test/test_static_replace.py b/common/djangoapps/static_replace/test/test_static_replace.py
index e9c3779dcd8..a789d2bff12 100644
--- a/common/djangoapps/static_replace/test/test_static_replace.py
+++ b/common/djangoapps/static_replace/test/test_static_replace.py
@@ -174,6 +174,31 @@ def test_static_url_with_query(mock_modulestore, mock_storage):
     assert replace_static_urls(pre_text, DATA_DIRECTORY, COURSE_KEY) == post_text
 
 
+@pytest.mark.django_db
+@patch('static_replace.staticfiles_storage', autospec=True)
+@patch('xmodule.modulestore.django.modulestore', autospec=True)
+def test_static_paths_out(mock_modulestore, mock_storage):
+    """
+    Tests the side-effect of passing an array to collect static_paths_out.
+
+    * if a static URL is changed, then its changed URL is returned.
+    * if a static URL is unchanged, then the unchanged URL is returned.
+    * xblock paths are not included in the static_paths_out array.
+    """
+    mock_storage.exists.return_value = False
+    mock_modulestore.return_value = Mock(MongoModuleStore)
+
+    static_url = '/static/LAlec04_controller.swf?csConfigFile=/static/LAlec04_config.xml&name1=value1&name2=value2'
+    static_course_url = '/c4x/org/course/asset/LAlec04_controller.swf?csConfigFile=%2Fc4x%2Forg%2Fcourse%2Fasset%2FLAlec04_config.xml&name1=value1&name2=value2'
+    raw_url = '/static/js/capa/protex/protex.nocache.js?raw'
+    xblock_url = '/static/xblock/resources/babys_first.lil_xblock/public/images/pacifier.png'
+    pre_text = 'EMBED src ="{}" xblock={} text <tag a="{}"/><div class="'.format(static_url, xblock_url, raw_url)
+    post_text = 'EMBED src ="{}" xblock={} text <tag a="{}"/><div class="'.format(static_course_url, xblock_url, raw_url)
+    static_paths = []
+    assert replace_static_urls(pre_text, DATA_DIRECTORY, COURSE_KEY, static_paths_out=static_paths) == post_text
+    assert static_paths == [(static_url, static_course_url), (raw_url, raw_url)]
+
+
 def test_regex():
     yes = ('"/static/foo.png"',
            '"/static/foo.png"',
-- 
GitLab