From 5d2fbc85990d8c2d34af08f50cc7183bc717b7b9 Mon Sep 17 00:00:00 2001
From: Ambrus Simon <ambrussimon@invenshure.com>
Date: Tue, 2 May 2017 19:25:19 +0200
Subject: [PATCH] add tests for /upload/reaper endpoint

---
 test/integration_tests/python/conftest.py     | 26 ++++--
 test/integration_tests/python/test_uploads.py | 93 ++++++++++++++++++-
 2 files changed, 105 insertions(+), 14 deletions(-)

diff --git a/test/integration_tests/python/conftest.py b/test/integration_tests/python/conftest.py
index 115a1b8a..8a10ece6 100644
--- a/test/integration_tests/python/conftest.py
+++ b/test/integration_tests/python/conftest.py
@@ -175,6 +175,20 @@ def file_form():
     return file_form
 
 
+@pytest.fixture(scope='session')
+def merge_dict():
+
+    def merge_dict(a, b):
+        """Merge two dicts into the first recursively"""
+        for key, value in b.iteritems():
+            if key in a and isinstance(a[key], dict) and isinstance(b[key], dict):
+                merge_dict(a[key], b[key])
+            else:
+                a[key] = b[key]
+
+    return merge_dict
+
+
 @pytest.fixture(scope='module')
 def log(request):
     """Return logger for the test module for easy logging from tests"""
@@ -218,7 +232,7 @@ class DataBuilder(object):
 
         # merge any kwargs on top of the default payload
         payload = copy.deepcopy(_default_payload[resource])
-        merge_dict(payload, kwargs)
+        _merge_dict(payload, kwargs)
 
         # add missing required unique fields using randstr
         # such fields are: [user._id, group._id, gear.gear.name]
@@ -306,12 +320,4 @@ class DataBuilder(object):
 # as "private singletons" in the module. This seemed the least confusing.
 _default_payload = default_payload()
 _api_db = api_db()
-
-
-def merge_dict(a, b):
-    """Merge two dicts into the first recursively"""
-    for key, value in b.iteritems():
-        if key in a and isinstance(a[key], dict) and isinstance(b[key], dict):
-            merge_dict(a[key], b[key])
-        else:
-            a[key] = b[key]
+_merge_dict = merge_dict()
diff --git a/test/integration_tests/python/test_uploads.py b/test/integration_tests/python/test_uploads.py
index 4122e481..0e78b03c 100644
--- a/test/integration_tests/python/test_uploads.py
+++ b/test/integration_tests/python/test_uploads.py
@@ -1,16 +1,101 @@
 import json
 
 import dateutil.parser
+import pytest
+
+
+# TODO switch to upload_file_form in all uid(-match)/label/reaper upload tests
+# after #772 (coverage-low-hanging 3) gets merged to avoid conflict hell
+@pytest.fixture(scope='function')
+def upload_file_form(file_form, merge_dict, randstr):
+    def create_form(**meta_override):
+        prefix = randstr()
+        names = ('project', 'subject', 'session', 'acquisition', 'unused')
+        files = {name: '{}-{}.csv'.format(prefix, name) for name in names}
+        meta = {
+            'project': {
+                'label': prefix + '-project-label',
+                'files': [{'name': files['project']}]
+            },
+            'session': {
+                'uid': prefix + '-session-uid',
+                'label': prefix + '-session-label',
+                'subject': {
+                    'code': prefix + '-subject-code',
+                    'files': [{'name': files['subject']}]
+                },
+                'files': [{'name': files['session']}]
+            },
+            'acquisition': {
+                'uid': prefix + '-acquisition-uid',
+                'label': prefix + '-acquisition-label',
+                'files': [{'name': files['acquisition']}]
+            }
+        }
+        if meta_override:
+            merge_dict(meta, meta_override)
+        return file_form(*files.values(), meta=meta)
 
+    return create_form
 
-def test_upload_without_login(as_public):
-    r = as_public.post('/upload/uid')
-    assert r.status_code == 403
 
+def test_reaper_upload(data_builder, randstr, upload_file_form, as_admin):
+    group_1 = data_builder.create_group()
+    prefix = randstr()
+    project_label_1 = prefix + '-project-label-1'
+    session_uid = prefix + '-session-uid'
+
+    # reaper-upload files to group_1/project_label_1 using session_uid
+    r = as_admin.post('/upload/reaper', files=upload_file_form(
+        group={'_id': group_1},
+        project={'label': project_label_1},
+        session={'uid': session_uid},
+    ))
+    assert r.ok
+
+    # get session created by the upload
+    project_1 = as_admin.get('/groups/' + group_1 + '/projects').json()[0]['_id']
+    session = as_admin.get('/projects/' + project_1 + '/sessions').json()[0]['_id']
+    assert len(as_admin.get('/projects/' + project_1 + '/sessions').json()) == 1
+    assert len(as_admin.get('/sessions/' + session + '/acquisitions').json()) == 1
+    assert len(as_admin.get('/sessions/' + session).json()['files']) == 1
+
+    # move session to group_2/project_2
+    group_2 = data_builder.create_group()
+    project_2 = data_builder.create_project(group=group_2, label=prefix + '-project-label-2')
+    as_admin.put('/sessions/' + session, json={'project': project_2})
+    assert len(as_admin.get('/projects/' + project_1 + '/sessions').json()) == 0
+    assert len(as_admin.get('/projects/' + project_2 + '/sessions').json()) == 1
+
+    # reaper-upload files using existing session_uid and incorrect group/project
+    r = as_admin.post('/upload/reaper', files=upload_file_form(
+        group={'_id': group_1},
+        project={'label': project_label_1},
+        session={'uid': session_uid},
+    ))
+    assert r.ok
+
+    # verify no new sessions were created and that group/project was ignored
+    # NOTE uploaded project file is NOT stored in this scenario!
+    assert len(as_admin.get('/projects/' + project_1 + '/sessions').json()) == 0
+    assert len(as_admin.get('/projects/' + project_2 + '/sessions').json()) == 1
 
-def test_uid_upload(data_builder, file_form, as_admin, as_user):
+    # verify that acquisition creation/file uploads worked
+    assert len(as_admin.get('/sessions/' + session + '/acquisitions').json()) == 2
+    assert len(as_admin.get('/sessions/' + session).json()['files']) == 2
+
+    # clean up
+    data_builder.delete_group(group_1, recursive=True)
+    data_builder.delete_group(group_2, recursive=True)
+
+
+def test_uid_upload(data_builder, file_form, as_admin, as_user, as_public):
     group = data_builder.create_group()
 
+    # try to uid-upload w/o logging in
+    r = as_public.post('/upload/uid')
+    assert r.status_code == 403
+
     # try to uid-upload w/o metadata
     r = as_admin.post('/upload/uid', files=file_form('test.csv'))
     assert r.status_code == 500
-- 
GitLab