Using patch to edit shots from web-frontend.

This commit is contained in:
2016-10-04 14:16:58 +02:00
parent 459ba6c89f
commit 91abe917cd
4 changed files with 82 additions and 23 deletions

View File

@@ -29,6 +29,7 @@ VALID_PATCH_OPERATIONS = {
u'from-web': {
u'properties.status',
u'properties.notes',
u'description',
},
}
log = logging.getLogger(__name__)
@@ -114,13 +115,17 @@ class ShotManager(object):
"""
api = pillar_api()
shot = pillarsdk.Node.find(shot_id, api=api)
shot = pillarsdk.Node({'_id': shot_id})
shot._etag = fields.pop('_etag')
shot.name = fields.pop('name')
shot.description = fields.pop('description')
shot.properties.status = fields.pop('status')
shot.properties.notes = fields.pop('notes', '').strip() or None
patch = {
'op': 'from-web',
'$set': {
'description': fields.pop('description', '').strip() or None,
'properties.notes': (fields.pop('notes', '') or '').strip() or None,
'properties.status': fields.pop('status'),
}
}
# shot._etag = fields.pop('_etag')
self._log.info('Saving shot %s', shot.to_dict())
@@ -128,8 +133,7 @@ class ShotManager(object):
self._log.warning('edit_shot(%r, ...) called with unknown fields %r; ignoring them.',
shot_id, fields)
shot.update(api=api)
return shot
shot.patch(patch, api=api)
def node_setattr(node, key, value):

View File

@@ -92,8 +92,11 @@ def save(project, shot_id):
log.debug('Form data: %s', request.form)
shot_dict = request.form.to_dict()
shot = current_attract.shot_manager.edit_shot(shot_id, **shot_dict)
current_attract.shot_manager.edit_shot(shot_id, **shot_dict)
# Return the patched node in all its glory.
api = pillar_api()
shot = pillarsdk.Node.find(shot_id, api=api)
return pillar.api.utils.jsonify(shot.to_dict())

View File

@@ -2,12 +2,9 @@
form#shot_form(onsubmit="return shot_save('{{shot._id}}', '{{ url_for('attract.shots.perproject.save', project_url=project['url'], shot_id=shot._id) }}')")
input(type='hidden',name='_etag',value='{{ shot._etag }}')
.input-transparent-group
input.input-transparent.item-name(
name="name",
type="text",
placeholder='Name',
value="{{ shot.name | hide_none }}")
h2 {{ shot.name | hide_none }}
button.copy-to-clipboard.btn.item-id(
style="margin-left: auto",
name="Copy to Clipboard",
type="button",
data-clipboard-text="{{ shot._id }}",

View File

@@ -91,6 +91,7 @@ class ShotManagerTest(AbstractShotTest):
@responses.activate
def test_edit_shot(self):
shot = self.create_shot()
pre_edit_shot = shot.to_dict()
with self.app.test_request_context():
# Log in as project admin user
@@ -98,25 +99,27 @@ class ShotManagerTest(AbstractShotTest):
self.mock_blenderid_validate_happy()
self.assertRaises(sdk_exceptions.PreconditionFailed,
self.smngr.edit_shot,
shot_id=shot['_id'],
name=u'ผัดไทย',
description=u'Shoot the Pad Thai',
status='todo',
_etag='jemoeder')
# No Etag checking, see T49555
# self.assertRaises(sdk_exceptions.PreconditionFailed,
# self.smngr.edit_shot,
# shot_id=shot['_id'],
# name=u'ผัดไทย',
# description=u'Shoot the Pad Thai',
# status='todo',
# _etag='jemoeder')
self.smngr.edit_shot(shot_id=shot['_id'],
name=u'ผัดไทย',
description=u'Shoot the Pad Thai',
status='todo',
notes=None,
_etag=shot._etag)
# Test directly with MongoDB
with self.app.test_request_context():
nodes_coll = self.app.data.driver.db['nodes']
found = nodes_coll.find_one(ObjectId(shot['_id']))
self.assertEqual(u'ผัดไทย', found['name'])
self.assertEqual(pre_edit_shot['name'], found['name']) # shouldn't be edited.
self.assertEqual(u'todo', found['properties']['status'])
self.assertEqual(u'Shoot the Pad Thai', found['description'])
self.assertNotIn(u'notes', found['properties'])
@@ -189,14 +192,66 @@ class PatchShotTest(AbstractShotTest):
patch = {
'op': 'from-blender',
'$set': {
'name': u'"shot" is "geschoten" in Dutch',
'properties.trim_start_in_frames': 123,
'properties.duration_in_edit_in_frames': 4215,
'properties.cut_in_timeline_in_frames': 1245,
'properties.status': 'todo',
'properties.status': u'on_hold',
}
}
self.patch(url, json=patch, auth_token='token')
dbnode = self.get(url, auth_token='token').json()
self.assertEqual(u'"shot" is "geschoten" in Dutch', dbnode['name'])
self.assertEqual(123, dbnode['properties']['trim_start_in_frames'])
self.assertEqual(u'on_hold', dbnode['properties']['status'])
@responses.activate
def test_patch_from_web_happy(self):
shot = self.create_shot()
self.create_valid_auth_token(ctd.EXAMPLE_PROJECT_OWNER_ID, 'token')
url = '/api/nodes/%s' % shot._id
patch = {
'op': 'from-web',
'$set': {
'description': u'Таким образом, этот человек заходит в бар, и говорит…',
'properties.notes': u'Два бокала вашей лучшей водки, пожалуйста.',
'properties.status': u'final',
}
}
self.patch(url, json=patch, auth_token='token')
dbnode = self.get(url, auth_token='token').json()
self.assertEqual(u'Таким образом, этот человек заходит в бар, и говорит…',
dbnode['description'])
self.assertEqual(u'Два бокала вашей лучшей водки, пожалуйста.',
dbnode['properties']['notes'])
self.assertEqual(u'final', dbnode['properties']['status'])
self.assertEqual(u'New shot', dbnode['name'])
@responses.activate
def test_patch_from_web_happy_nones(self):
shot = self.create_shot()
self.create_valid_auth_token(ctd.EXAMPLE_PROJECT_OWNER_ID, 'token')
url = '/api/nodes/%s' % shot._id
patch = {
'op': 'from-web',
'$set': {
'description': None,
'properties.notes': None,
'properties.status': u'final',
}
}
self.patch(url, json=patch, auth_token='token')
dbnode = self.get(url, auth_token='token').json()
self.assertNotIn('description', dbnode)
self.assertNotIn('notes', dbnode['properties'])
self.assertEqual(u'final', dbnode['properties']['status'])
self.assertEqual(u'New shot', dbnode['name'])
@responses.activate
def test_patch_bad_op(self):
shot = self.create_shot()