(un)delete on project also (un)delete file documents.

Note that undeleting files cannot be done via Eve, as it doesn't support
PATCHing collections. Instead, direct MongoDB modification is used to set
_deleted=False and provide new _etag and _updated values.
This commit is contained in:
2018-01-30 17:29:28 +01:00
parent 7d1b08bf58
commit f8ff30fb4d
5 changed files with 144 additions and 23 deletions

View File

@@ -295,22 +295,17 @@ class HomeProjectTest(AbstractHomeProjectTest):
self._create_user_with_token(roles={'subscriber'}, token='token')
# Create home project by getting it.
resp = self.client.get('/api/bcloud/home-project',
headers={'Authorization': self.make_header('token')})
self.assertEqual(200, resp.status_code, resp.data)
before_delete_json_proj = json.loads(resp.data)
resp = self.get('/api/bcloud/home-project', auth_token='token')
before_delete_json_proj = resp.json()
# Delete the project.
resp = self.client.delete('/api/projects/%s' % before_delete_json_proj['_id'],
headers={'Authorization': self.make_header('token'),
'If-Match': before_delete_json_proj['_etag']})
self.assertEqual(204, resp.status_code, resp.data)
self.delete(f'/api/projects/{before_delete_json_proj["_id"]}',
auth_token='token', etag=before_delete_json_proj['_etag'],
expected_status=204)
# Recreate home project by getting it.
resp = self.client.get('/api/bcloud/home-project',
headers={'Authorization': self.make_header('token')})
self.assertEqual(200, resp.status_code, resp.data)
after_delete_json_proj = json.loads(resp.data)
resp = self.get('/api/bcloud/home-project', auth_token='token')
after_delete_json_proj = resp.json()
self.assertEqual(before_delete_json_proj['_id'],
after_delete_json_proj['_id'])

View File

@@ -1,13 +1,15 @@
# -*- encoding: utf-8 -*-
"""Unit tests for creating and editing projects_blueprint."""
import datetime
import functools
import json
import logging
import urllib.request, urllib.parse, urllib.error
from bson import ObjectId
import bson.tz_util
from pymongo.collection import ReturnDocument
from pillar.tests import AbstractPillarTest
log = logging.getLogger(__name__)
@@ -370,6 +372,68 @@ class ProjectEditTest(AbstractProjectTest):
'If-Match': project_info['_etag']})
self.assertEqual(204, resp.status_code, resp.data)
def test_delete_files_too(self):
# Create test project with a file.
project_info = self._create_user_and_project(['subscriber'])
project_id = project_info['_id']
fid, _ = self.ensure_file_exists({'project': ObjectId(project_id)})
with self.app.app_context():
files_coll = self.app.db('files')
nowish = datetime.datetime.now(tz=bson.tz_util.utc) - datetime.timedelta(seconds=5)
db_file_before = files_coll.find_one_and_update({'_id': fid},
{'$set': {'_updated': nowish}},
return_document=ReturnDocument.AFTER)
# DELETE by owner should also soft-delete the file documents.
self.delete(f'/api/projects/{project_id}',
auth_token='token', etag=project_info['_etag'],
expected_status=204)
resp = self.get(f'/api/files/{fid}', expected_status=404)
self.assertEqual(str(fid), resp.json()['_id'])
with self.app.app_context():
db_file_after = files_coll.find_one(fid)
self.assertGreater(db_file_after['_updated'], db_file_before['_updated'])
self.assertNotEqual(db_file_after['_etag'], db_file_before['_etag'])
def test_undelete_with_put__files_too(self):
from pillar.api.utils import remove_private_keys
# Create test project with a file.
project_info = self._create_user_and_project(['subscriber'])
project_id = project_info['_id']
fid, _ = self.ensure_file_exists({'project': ObjectId(project_id)})
# DELETE by owner should also soft-delete the file documents.
proj_url = f'/api/projects/{project_id}'
self.delete(proj_url, auth_token='token', etag=project_info['_etag'],
expected_status=204)
resp = self.get(proj_url, auth_token='token', expected_status=404)
etag = resp.json()['_etag']
with self.app.app_context():
files_coll = self.app.db('files')
now = datetime.datetime.now(tz=bson.tz_util.utc) - datetime.timedelta(seconds=5)
db_file_before = files_coll.find_one_and_update({'_id': fid},
{'$set': {'_updated': now}},
return_document=ReturnDocument.AFTER)
# PUT on the project should also restore the files.
self.put(proj_url, auth_token='token', etag=etag,
json=remove_private_keys(project_info))
resp = self.get(f'/api/files/{fid}')
self.assertEqual(str(fid), resp.json()['_id'])
with self.app.app_context():
db_file_after = files_coll.find_one(fid)
self.assertGreater(db_file_after['_updated'], db_file_before['_updated'])
self.assertNotEqual(db_file_after['_etag'], db_file_before['_etag'])
class ProjectNodeAccess(AbstractProjectTest):
def setUp(self, **kwargs):