Repository: Cloud-CV/EvalAI

Issue:
Change path of storage of Evaluation Scripts
## Current behaviour

Currently, the evaluation scripts are stored in the `submission_files` directory which should not happen ideally.

## Solution
Modify the `RandomFile()` method such that the evaluation scripts should be uploaded in the `evaluation_scripts` directory instead of the `submission_files` directory. 



Discussion:
@deshraj : Why is this required ?
The `RandomFile()` definition sets the path of the uploaded file to be `submission_files/blah` and hence the evaluation scripts being uploaded are also stored in the submission_files. I hope I am clear now. 

Resolving patch:
diff --git a/apps/base/utils.py b/apps/base/utils.py
--- a/apps/base/utils.py
+++ b/apps/base/utils.py
@@ -2,7 +2,6 @@
 import uuid
 
 from django.conf import settings
-from django.utils.deconstruct import deconstructible
 
 from rest_framework.exceptions import NotFound
 from rest_framework.pagination import PageNumberPagination
@@ -24,20 +23,17 @@ def paginated_queryset(queryset, request, pagination_class=PageNumberPagination(
     return (paginator, result_page)
 
 
-@deconstructible
 class RandomFileName(object):
     def __init__(self, path):
         self.path = path
 
     def __call__(self, instance, filename):
         extension = os.path.splitext(filename)[1]
+        path = self.path
         if 'id' in self.path and instance.pk:
-            self.path = self.path.format(id=instance.pk)
-        elif 'id' not in self.path and instance.pk:
-            path = "submission_files/submission_{id}"
-            self.path = path.format(id=instance.pk)
+            path = self.path.format(id=instance.pk)
         filename = '{}{}'.format(uuid.uuid4(), extension)
-        filename = os.path.join(self.path, filename)
+        filename = os.path.join(path, filename)
         return filename
 
 


Test patch:
diff --git a/tests/unit/base/__init__.py b/tests/unit/base/__init__.py
new file mode 100644
diff --git a/tests/unit/base/test_utils.py b/tests/unit/base/test_utils.py
new file mode 100644
--- /dev/null
+++ b/tests/unit/base/test_utils.py
@@ -0,0 +1,109 @@
+import os
+
+from datetime import timedelta
+
+from django.conf import settings
+from django.contrib.auth.models import User
+from django.core.files.uploadedfile import SimpleUploadedFile
+from django.utils import timezone
+
+from allauth.account.models import EmailAddress
+from rest_framework.test import APITestCase, APIClient
+
+from base.utils import RandomFileName
+from challenges.models import Challenge, ChallengePhase
+from hosts.models import ChallengeHostTeam
+from jobs.models import Submission
+from participants.models import Participant, ParticipantTeam
+
+
+class BaseAPITestClass(APITestCase):
+
+    def setUp(self):
+        self.client = APIClient(enforce_csrf_checks=True)
+
+        self.user = User.objects.create(
+            username='someuser',
+            email="user@test.com",
+            password='secret_password')
+
+        EmailAddress.objects.create(
+            user=self.user,
+            email='user@test.com',
+            primary=True,
+            verified=True)
+
+        self.challenge_host_team = ChallengeHostTeam.objects.create(
+            team_name='Test Challenge Host Team',
+            created_by=self.user)
+
+        self.participant_team = ParticipantTeam.objects.create(
+            team_name='Participant Team for Challenge',
+            created_by=self.user)
+
+        self.participant = Participant.objects.create(
+            user=self.user,
+            status=Participant.SELF,
+            team=self.participant_team)
+
+        self.challenge = Challenge.objects.create(
+            title='Test Challenge',
+            description='Description for test challenge',
+            terms_and_conditions='Terms and conditions for test challenge',
+            submission_guidelines='Submission guidelines for test challenge',
+            creator=self.challenge_host_team,
+            start_date=timezone.now() - timedelta(days=2),
+            end_date=timezone.now() + timedelta(days=1),
+            published=False,
+            enable_forum=True,
+            anonymous_leaderboard=False)
+
+        try:
+            os.makedirs('/tmp/evalai')
+        except OSError:
+            pass
+
+        with self.settings(MEDIA_ROOT='/tmp/evalai'):
+            self.challenge_phase = ChallengePhase.objects.create(
+                name='Challenge Phase',
+                description='Description for Challenge Phase',
+                leaderboard_public=False,
+                is_public=True,
+                start_date=timezone.now() - timedelta(days=2),
+                end_date=timezone.now() + timedelta(days=1),
+                challenge=self.challenge,
+                test_annotation=SimpleUploadedFile('test_sample_file.txt',
+                                                   'Dummy file content', content_type='text/plain')
+            )
+
+        self.submission = Submission.objects.create(
+            participant_team=self.participant_team,
+            challenge_phase=self.challenge_phase,
+            created_by=self.challenge_host_team.created_by,
+            status='submitted',
+            input_file=self.challenge_phase.test_annotation,
+            method_name="Test Method",
+            method_description="Test Description",
+            project_url="http://testserver/",
+            publication_url="http://testserver/",
+            is_public=True,
+        )
+
+
+class TestRandomFileName(BaseAPITestClass):
+
+    def setUp(self):
+        super(TestRandomFileName, self).setUp()
+        self.test_file_path = os.path.join(settings.BASE_DIR, 'examples', 'example1', 'test_annotation.txt')
+
+    def test_random_file_name_without_id(self):
+        obj = RandomFileName("evaluation_scripts")
+        filepath = obj.__call__(self.challenge, self.test_file_path)
+        expected = "evaluation_scripts/{}".format(filepath.split('/')[1])
+        self.assertEqual(filepath, expected)
+
+    def test_random_file_name_with_id(self):
+        obj = RandomFileName("submission_files/submission_{id}")
+        filepath = obj.__call__(self.submission, self.test_file_path)
+        expected = "submission_files/submission_{}/{}".format(self.submission.pk, filepath.split('/')[2])
+        self.assertEqual(filepath, expected)