Repository: learningequality/kolibri

Issue:
no mastery achieved on pdf's
### Observed behavior

Mastery is not achieved (no complete icon, and no points earned) after spending time scrolling through the pdf.

### Expected behavior

PDF is 9 pages long. Mastery is expected after 4.5 minutes.  The 'in progress' icon appears but mastery is never achieved.

### Steps to reproduce

1. Select a pdf content, like this one: https://instantschools-v2.learningequality.org/learn/#/topics/c/2d902e00e30245799081fda4da5cabd0
2. Keep pdf open for 5+ minutes
3. No mastery achieved 
![pdfmastery](https://user-images.githubusercontent.com/5150483/32923423-5c6e00ee-caec-11e7-9e8a-3925f09f2a23.png)


### Context

* Kolibri version:  0.6.1 pex on online demo server
* Operating system: pex
* Browser: Chrome
URL: https://instantschools-v2.learningequality.org/learn/#/topics/c/2d902e00e30245799081fda4da5cabd0



Discussion:

Resolving patch:
diff --git a/kolibri/content/management/commands/importcontent.py b/kolibri/content/management/commands/importcontent.py
--- a/kolibri/content/management/commands/importcontent.py
+++ b/kolibri/content/management/commands/importcontent.py
@@ -5,7 +5,7 @@
 from kolibri.tasks.management.commands.base import AsyncCommand
 from requests.exceptions import HTTPError
 
-from ...utils import annotation, paths, transfer, import_export_content
+from ...utils import annotation, import_export_content, paths, transfer
 
 # constants to specify the transfer method to be used
 DOWNLOAD_METHOD = "download"
@@ -108,7 +108,6 @@ def _transfer(self, method, channel_id, path=None, node_ids=None, exclude_node_i
         files_to_download, total_bytes_to_transfer = import_export_content.get_files_to_transfer(
             channel_id, node_ids, exclude_node_ids, False)
 
-        downloaded_files = []
         number_of_skipped_files = 0
         file_checksums_to_annotate = []
 
@@ -149,9 +148,6 @@ def _transfer(self, method, channel_id, path=None, node_ids=None, exclude_node_i
                                 length = len(chunk)
                                 overall_progress_update(length)
                                 file_dl_progress_update(length)
-                            else:
-                                # If the for loop didn't break, add this to downloaded files.
-                                downloaded_files.append(dest)
 
                     file_checksums_to_annotate.append(f.id)
 
@@ -162,17 +158,15 @@ def _transfer(self, method, channel_id, path=None, node_ids=None, exclude_node_i
                     number_of_skipped_files += 1
                     overall_progress_update(f.file_size)
 
+            annotation.set_availability(channel_id, file_checksums_to_annotate)
+
+            if number_of_skipped_files > 0:
+                logging.warning(
+                    "{} files are skipped, because they are not found in the given external drive.".format(
+                        number_of_skipped_files))
+
             if self.is_cancelled():
-                # Cancelled, clean up any already downloading files.
-                for dest in downloaded_files:
-                    os.remove(dest)
                 self.cancel()
-            else:
-                if number_of_skipped_files > 0:
-                    logging.warning(
-                        "{} files are skipped, because they are not found in the given external drive.".format(number_of_skipped_files))
-
-                annotation.set_availability(channel_id, file_checksums_to_annotate)
 
     def handle_async(self, *args, **options):
         if options['command'] == 'network':


Test patch:
diff --git a/kolibri/content/test/test_import_export.py b/kolibri/content/test/test_import_export.py
--- a/kolibri/content/test/test_import_export.py
+++ b/kolibri/content/test/test_import_export.py
@@ -127,8 +127,8 @@ def test_remote_cancel_during_transfer(self, is_cancelled_mock, cancel_mock, Fil
     @patch('kolibri.content.management.commands.importcontent.transfer.FileDownload')
     @patch('kolibri.content.management.commands.importcontent.AsyncCommand.cancel')
     @patch('kolibri.content.management.commands.importcontent.AsyncCommand.is_cancelled', side_effect=[False, False, False, False, False, True, True, True])
-    def test_remote_cancel_after_file_copy_file_deleted(self, is_cancelled_mock, cancel_mock, FileDownloadMock, local_path_mock, remote_path_mock,
-                                                        start_progress_mock, annotation_mock):
+    def test_remote_cancel_after_file_copy_file_not_deleted(self, is_cancelled_mock, cancel_mock, FileDownloadMock, local_path_mock, remote_path_mock,
+                                                            start_progress_mock, annotation_mock):
         # If transfer is cancelled after transfer of first file
         local_path_1 = tempfile.mkstemp()[1]
         local_path_2 = tempfile.mkstemp()[1]
@@ -139,11 +139,9 @@ def test_remote_cancel_after_file_copy_file_deleted(self, is_cancelled_mock, can
         call_command("importcontent", "network", self.the_channel_id)
         # Check that the command itself was also cancelled.
         cancel_mock.assert_called_with()
-        # Check that the temp file we created where the first file was being downloaded to has been deleted
-        self.assertFalse(os.path.exists(local_path_1))
-        annotation_mock.mark_local_files_as_available.assert_not_called()
-        annotation_mock.set_leaf_node_availability_from_local_file_availability.assert_not_called()
-        annotation_mock.recurse_availability_up_tree.assert_not_called()
+        # Check that the temp file we created where the first file was being downloaded to has not been deleted
+        self.assertTrue(os.path.exists(local_path_1))
+        annotation_mock.set_availability.assert_called()
 
     @patch('kolibri.content.management.commands.importcontent.transfer.FileCopy')
     @patch('kolibri.content.management.commands.importcontent.AsyncCommand.cancel')
@@ -175,9 +173,7 @@ def test_local_cancel_during_transfer(self, is_cancelled_mock, cancel_mock, File
         FileCopyMock.assert_called_with(local_src_path, local_dest_path)
         FileCopyMock.assert_has_calls([call().cancel()])
         cancel_mock.assert_called_with()
-        annotation_mock.mark_local_files_as_available.assert_not_called()
-        annotation_mock.set_leaf_node_availability_from_local_file_availability.assert_not_called()
-        annotation_mock.recurse_availability_up_tree.assert_not_called()
+        annotation_mock.set_availability.assert_called()
 
 
 @override_settings(