async def test_correct_data_is_set_to_json_when_replacing(self):
     """Test operator replaces object and adds necessary info."""
     operator = Operator(self.client)
     with patch(
         "metadata_backend.api.operators.Operator._replace_object_from_db", return_value=self.accession_id
     ) as mocked_insert:
         with patch("metadata_backend.api.operators.datetime") as m_date:
             m_date.utcnow.return_value = datetime.datetime(2020, 4, 14)
             acc = await (operator._format_data_to_replace_and_add_to_db("study", self.accession_id, {}))
             mocked_insert.assert_called_once_with(
                 "study",
                 self.accession_id,
                 {"accessionId": self.accession_id, "dateModified": datetime.datetime(2020, 4, 14)},
             )
         self.assertEqual(acc, self.accession_id)
 async def test_query_skip_and_limit_are_set_correctly(self):
     """Test custom skip and limits."""
     operator = Operator(self.client)
     data = {"foo": "bar"}
     result = []
     operator.db_service.do_aggregate.side_effect = [result, [{"total": 0}]]
     with patch(
         "metadata_backend.api.operators.Operator._format_read_data",
         return_value=data,
     ):
         await operator.query_metadata_database("sample", {}, 3, 50, [])
         calls = [
             call(
                 "sample",
                 [
                     {"$match": {}},
                     {"$redact": {"$cond": {"if": {}, "then": "$$DESCEND", "else": "$$PRUNE"}}},
                     {"$skip": 50 * (3 - 1)},
                     {"$limit": 50},
                     {"$project": {"_id": 0}},
                 ],
             ),
             call(
                 "sample",
                 [
                     {"$match": {}},
                     {"$redact": {"$cond": {"if": {}, "then": "$$DESCEND", "else": "$$PRUNE"}}},
                     {"$count": "total"},
                 ],
             ),
         ]
         operator.db_service.do_aggregate.assert_has_calls(calls, any_order=True)
         self.assertEqual(operator.db_service.do_aggregate.call_count, 2)
 async def test_query_result_is_parsed_correctly(self):
     """Test JSON is read and correct pagination values are returned."""
     operator = Operator(self.client)
     multiple_result = [
         {
             "dateCreated": datetime.datetime(2020, 6, 14, 0, 0),
             "dateModified": datetime.datetime(2020, 6, 14, 0, 0),
             "accessionId": "EGA123456",
             "foo": "bar",
         },
         {
             "dateCreated": datetime.datetime(2020, 6, 14, 0, 0),
             "dateModified": datetime.datetime(2020, 6, 14, 0, 0),
             "accessionId": "EGA123456",
             "foo": "bar",
         },
     ]
     study_total = [{"total": 100}]
     operator.db_service.do_aggregate.side_effect = [multiple_result, study_total]
     query = MultiDictProxy(MultiDict([]))
     (
         parsed,
         page_num,
         page_size,
         total_objects,
     ) = await operator.query_metadata_database("sample", query, 1, 10, [])
     for doc in parsed:
         self.assertEqual(doc["dateCreated"], "2020-06-14T00:00:00")
         self.assertEqual(doc["dateModified"], "2020-06-14T00:00:00")
         self.assertEqual(doc["accessionId"], "EGA123456")
     self.assertEqual(page_num, 1)
     self.assertEqual(page_size, 2)
     self.assertEqual(total_objects, 100)
 async def test_json_update_raises_if_not_exists(self):
     """Test update method raises error."""
     operator = Operator(self.client)
     operator.db_service.exists.return_value = False
     operator.db_service.replace.return_value = True
     with self.assertRaises(HTTPNotFound):
         await operator.update_metadata_object("study", self.accession_id, {})
         operator.db_service.update.assert_called_once()
 async def test_deleting_metadata_deletes_json_and_xml(self):
     """Test metadata is deleted."""
     operator = Operator(self.client)
     operator.db_service.db_client = self.client
     operator.db_service.exists.return_value = True
     operator.db_service.delete.return_value = True
     await operator.delete_metadata_object("sample", "EGA123456")
     self.assertEqual(operator.db_service.delete.call_count, 2)
     operator.db_service.delete.assert_called_with("sample", "EGA123456")
 async def test_deleting_metadata_delete_raises_bad_request(self):
     """Test bad request error raised with delete."""
     operator = Operator(self.client)
     operator.db_service.db_client = self.client
     operator.db_service.exists.return_value = True
     operator.db_service.delete.return_value = False
     with self.assertRaises(HTTPBadRequest):
         await operator.delete_metadata_object("sample", "EGA123456")
         self.assertEqual(operator.db_service.delete.call_count, 2)
         operator.db_service.delete.assert_called_with("sample", "EGA123456")
 async def test_wront_data_is_set_to_json_when_replacing(self):
     """Test operator replace catches error."""
     operator = Operator(self.client)
     with patch("metadata_backend.api.operators.Operator._replace_object_from_db", return_value=self.accession_id):
         with patch("metadata_backend.api.operators.datetime") as m_date:
             m_date.utcnow.return_value = datetime.datetime(2020, 4, 14)
             with self.assertRaises(HTTPBadRequest):
                 await (
                     operator._format_data_to_replace_and_add_to_db(
                         "study",
                         self.accession_id,
                         {
                             "accessionId": self.accession_id,
                             "dateCreated": datetime.datetime(2020, 4, 14),
                             "dateModified": datetime.datetime(2020, 4, 14),
                             "publishDate": datetime.datetime(2020, 6, 14),
                         },
                     )
                 )
 async def test_non_empty_query_result_raises_notfound(self):
     """Test that 404 is raised with empty query result."""
     operator = Operator(self.client)
     operator.db_service.query = MagicMock()
     query = MultiDictProxy(MultiDict([]))
     with patch(
         "metadata_backend.api.operators.Operator._format_read_data",
         return_value=[],
     ):
         with self.assertRaises(HTTPNotFound):
             await operator.query_metadata_database("study", query, 1, 10, [])
 async def test_json_create_passes_and_returns_accessionId(self):
     """Test create method for JSON works."""
     operator = Operator(self.client)
     data = {
         "centerName": "GEO",
         "alias": "GSE10966",
         "descriptor": {"studyTitle": "Highly", "studyType": "Other"},
     }
     operator.db_service.create.return_value = True
     accession = await operator.create_metadata_object("study", data)
     operator.db_service.create.assert_called_once()
     self.assertEqual(accession, self.accession_id)
 async def test_working_query_params_are_passed_to_db_query(self):
     """Test that database is called with correct query."""
     operator = Operator(self.client)
     study_test = [
         {
             "publishDate": datetime.datetime(2020, 6, 14, 0, 0),
             "accessionId": "EDAG3945644754983408",
             "dateCreated": datetime.datetime(2020, 6, 14, 0, 0),
             "dateModified": datetime.datetime(2020, 6, 14, 0, 0),
         }
     ]
     study_total = [{"total": 0}]
     operator.db_service.do_aggregate.side_effect = [study_test, study_total]
     query = MultiDictProxy(MultiDict([("studyAttributes", "foo")]))
     await operator.query_metadata_database("study", query, 1, 10, [])
     calls = [
         call(
             "study",
             [
                 {
                     "$match": {
                         "$or": [
                             {"studyAttributes.tag": re.compile(".*foo.*", re.IGNORECASE)},
                             {"studyAttributes.value": re.compile(".*foo.*", re.IGNORECASE)},
                         ]
                     }
                 },
                 {"$redact": {"$cond": {"if": {}, "then": "$$DESCEND", "else": "$$PRUNE"}}},
                 {"$skip": 0},
                 {"$limit": 10},
                 {"$project": {"_id": 0}},
             ],
         ),
         call(
             "study",
             [
                 {
                     "$match": {
                         "$or": [
                             {"studyAttributes.tag": re.compile(".*foo.*", re.IGNORECASE)},
                             {"studyAttributes.value": re.compile(".*foo.*", re.IGNORECASE)},
                         ]
                     }
                 },
                 {"$redact": {"$cond": {"if": {}, "then": "$$DESCEND", "else": "$$PRUNE"}}},
                 {"$count": "total"},
             ],
         ),
     ]
     operator.db_service.do_aggregate.assert_has_calls(calls, any_order=True)
 def test_operator_fixes_single_document_presentation(self):
     """Test datetime is fixed and id removed."""
     study_test = {
         "publishDate": datetime.datetime(2020, 6, 14, 0, 0),
         "accessionId": "EDAG3945644754983408",
         "dateCreated": datetime.datetime(2020, 6, 14, 0, 0),
         "dateModified": datetime.datetime(2020, 6, 14, 0, 0),
     }
     result = Operator(self.client)._format_single_dict("study", study_test)
     self.assertEqual(result["publishDate"], "2020-06-14T00:00:00")
     self.assertEqual(result["dateCreated"], "2020-06-14T00:00:00")
     self.assertEqual(result["dateModified"], "2020-06-14T00:00:00")
     with self.assertRaises(KeyError):
         result["_Id"]
 async def test_non_working_query_params_are_not_passed_to_db_query(self):
     """Test that database with empty query, when url params are wrong."""
     operator = Operator(self.client)
     study_test = [
         {
             "publishDate": datetime.datetime(2020, 6, 14, 0, 0),
             "accessionId": "EDAG3945644754983408",
             "dateCreated": datetime.datetime(2020, 6, 14, 0, 0),
             "dateModified": datetime.datetime(2020, 6, 14, 0, 0),
         }
     ]
     study_total = [{"total": 0}]
     operator.db_service.do_aggregate.side_effect = [study_test, study_total]
     query = MultiDictProxy(MultiDict([("swag", "littinen")]))
     with patch(
         "metadata_backend.api.operators.Operator._format_read_data",
         return_value=study_test,
     ):
         await operator.query_metadata_database("study", query, 1, 10, [])
     calls = [
         call(
             "study",
             [
                 {"$match": {}},
                 {"$redact": {"$cond": {"if": {}, "then": "$$DESCEND", "else": "$$PRUNE"}}},
                 {"$skip": 0},
                 {"$limit": 10},
                 {"$project": {"_id": 0}},
             ],
         ),
         call(
             "study",
             [
                 {"$match": {}},
                 {"$redact": {"$cond": {"if": {}, "then": "$$DESCEND", "else": "$$PRUNE"}}},
                 {"$count": "total"},
             ],
         ),
     ]
     operator.db_service.do_aggregate.assert_has_calls(calls, any_order=True)
     self.assertEqual(operator.db_service.do_aggregate.call_count, 2)
 async def test_reading_metadata_works(self):
     """Test JSON is read from db correctly."""
     operator = Operator(self.client)
     data = {
         "dateCreated": datetime.datetime(2020, 6, 14, 0, 0),
         "dateModified": datetime.datetime(2020, 6, 14, 0, 0),
         "accessionId": "EGA123456",
         "foo": "bar",
     }
     operator.db_service.read.return_value = data
     read_data, c_type = await operator.read_metadata_object("sample", "EGA123456")
     operator.db_service.read.assert_called_once_with("sample", "EGA123456")
     self.assertEqual(c_type, "application/json")
     self.assertEqual(
         read_data,
         {
             "dateCreated": "2020-06-14T00:00:00",
             "dateModified": "2020-06-14T00:00:00",
             "accessionId": "EGA123456",
             "foo": "bar",
         },
     )
 async def test_db_error_update_raises_400_error(self):
     """Test update metadata HTTPBadRequest is raised."""
     operator = Operator(self.client)
     operator.db_service.exists.side_effect = ConnectionFailure
     with self.assertRaises(HTTPBadRequest):
         await operator.update_metadata_object("study", self.accession_id, {})
 async def test_db_error_raises_400_error(self):
     """Test read metadata HTTPBadRequest is raised."""
     operator = Operator(self.client)
     operator.db_service.read.side_effect = ConnectionFailure
     with self.assertRaises(HTTPBadRequest):
         await operator.read_metadata_object("study", "EGA123456")
 async def test_reading_with_non_valid_id_raises_error(self):
     """Test read metadata HTTPNotFound is raised."""
     operator = Operator(self.client)
     operator.db_service.read.return_value = False
     with self.assertRaises(HTTPNotFound):
         await operator.read_metadata_object("study", "EGA123456")