Skip to content

Commit 73193e3

Browse files
authored
add multi_entity_update_modes support to mockgun (#330)
1 parent 2c50a2c commit 73193e3

2 files changed

Lines changed: 123 additions & 5 deletions

File tree

shotgun_api3/lib/mockgun/mockgun.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,12 @@ def batch(self, requests):
335335
results.append(self.create(request["entity_type"], request["data"]))
336336
elif request["request_type"] == "update":
337337
# note: Shotgun.update returns a list of a single item
338-
results.append(self.update(request["entity_type"], request["entity_id"], request["data"])[0])
338+
results.append(
339+
self.update(request["entity_type"],
340+
request["entity_id"],
341+
request["data"],
342+
request.get("multi_entity_update_modes"))[0]
343+
)
339344
elif request["request_type"] == "delete":
340345
results.append(self.delete(request["entity_type"], request["entity_id"]))
341346
else:
@@ -387,13 +392,13 @@ def create(self, entity_type, data, return_fields=None):
387392

388393
return result
389394

390-
def update(self, entity_type, entity_id, data):
395+
def update(self, entity_type, entity_id, data, multi_entity_update_modes=None):
391396
self._validate_entity_type(entity_type)
392397
self._validate_entity_data(entity_type, data)
393398
self._validate_entity_exists(entity_type, entity_id)
394399

395400
row = self._db[entity_type][entity_id]
396-
self._update_row(entity_type, row, data)
401+
self._update_row(entity_type, row, data, multi_entity_update_modes)
397402

398403
return [dict((field, item) for field, item in row.items() if field in data or field in ("type", "id"))]
399404

@@ -818,13 +823,26 @@ def _row_matches_filters(self, entity_type, row, filters, filter_operator, retir
818823
else:
819824
raise ShotgunError("%s is not a valid filter operator" % filter_operator)
820825

821-
def _update_row(self, entity_type, row, data):
826+
def _update_row(self, entity_type, row, data, multi_entity_update_modes=None):
822827
for field in data:
823828
field_type = self._get_field_type(entity_type, field)
824829
if field_type == "entity" and data[field]:
825830
row[field] = {"type": data[field]["type"], "id": data[field]["id"]}
826831
elif field_type == "multi_entity":
827-
row[field] = [{"type": item["type"], "id": item["id"]} for item in data[field]]
832+
update_mode = multi_entity_update_modes.get(field, "set") if multi_entity_update_modes else "set"
833+
834+
if update_mode == "add":
835+
row[field] += [{"type": item["type"], "id": item["id"]} for item in data[field]]
836+
elif update_mode == "remove":
837+
row[field] = [
838+
item
839+
for item in row[field]
840+
for new_item in data[field]
841+
if item["id"] != new_item["id"]
842+
or item["type"] != new_item["type"]
843+
]
844+
elif update_mode == "set":
845+
row[field] = [{"type": item["type"], "id": item["id"]} for item in data[field]]
828846
else:
829847
row[field] = data[field]
830848

tests/test_mockgun.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,106 @@ def test_find_with_none(self):
270270
for item in items:
271271
self.assertTrue(len(item["users"]) > 0)
272272

273+
274+
class TestMultiEntityFieldUpdate(unittest.TestCase):
275+
"""
276+
Ensures multi entity field update modes work.
277+
"""
278+
279+
def setUp(self):
280+
"""
281+
Creates test data.
282+
"""
283+
284+
self._mockgun = Mockgun("https://test.shotgunstudio.com", login="user", password="1234")
285+
286+
# Create two versions to assign to the shot.
287+
self._version1 = self._mockgun.create("Version", {"code": "version1"})
288+
self._version2 = self._mockgun.create("Version", {"code": "version2"})
289+
self._version3 = self._mockgun.create("Version", {"code": "version3"})
290+
291+
# remove 'code' field for later comparisons
292+
del self._version1["code"]
293+
del self._version2["code"]
294+
del self._version3["code"]
295+
296+
# Create playlists
297+
self._add_playlist = self._mockgun.create(
298+
"Playlist",
299+
{"code": "playlist1", "versions": [self._version1, self._version2]}
300+
)
301+
self._remove_playlist = self._mockgun.create(
302+
"Playlist",
303+
{"code": "playlist1", "versions": [self._version1, self._version2, self._version3]}
304+
)
305+
self._set_playlist = self._mockgun.create(
306+
"Playlist",
307+
{"code": "playlist1", "versions": [self._version1, self._version2]}
308+
)
309+
310+
def test_update_add(self):
311+
"""
312+
Ensures that "add" multi_entity_update_mode works.
313+
"""
314+
self._mockgun.update(
315+
"Playlist", self._add_playlist["id"], {"versions": [self._version3]},
316+
multi_entity_update_modes={"versions": "add"}
317+
)
318+
319+
playlist = self._mockgun.find_one(
320+
"Playlist", [["id", "is", self._add_playlist["id"]]], ["versions"]
321+
)
322+
self.assertEqual(
323+
playlist["versions"], [self._version1, self._version2, self._version3]
324+
)
325+
326+
def test_update_remove(self):
327+
"""
328+
Ensures that "remove" multi_entity_update_mode works.
329+
"""
330+
self._mockgun.update(
331+
"Playlist", self._remove_playlist["id"], {"versions": [self._version2]},
332+
multi_entity_update_modes={"versions": "remove"}
333+
)
334+
335+
playlist = self._mockgun.find_one(
336+
"Playlist", [["id", "is", self._remove_playlist["id"]]], ["versions"]
337+
)
338+
self.assertEqual(playlist["versions"], [self._version1, self._version3])
339+
340+
def test_update_set(self):
341+
"""
342+
Ensures that "set" multi_entity_update_mode works.
343+
"""
344+
self._mockgun.update(
345+
"Playlist",
346+
self._set_playlist["id"],
347+
{"versions": [self._version2, self._version3]},
348+
multi_entity_update_modes={"versions": "set"}
349+
)
350+
351+
playlist = self._mockgun.find_one(
352+
"Playlist", [["id", "is", self._set_playlist["id"]]], ["versions"]
353+
)
354+
self.assertEqual(playlist["versions"], [self._version2, self._version3])
355+
356+
def test_batch_update(self):
357+
self._mockgun.batch(
358+
[
359+
{
360+
"request_type": "update",
361+
"entity_type": "Playlist",
362+
"entity_id": self._set_playlist["id"],
363+
"data": {"versions": [self._version1, self._version2]},
364+
"multi_entity_update_modes": {"versions": "set"}
365+
}
366+
]
367+
)
368+
playlist = self._mockgun.find_one(
369+
"Playlist", [["id", "is", self._set_playlist["id"]]], ["versions"]
370+
)
371+
self.assertEqual(playlist["versions"], [self._version1, self._version2])
372+
273373

274374
class TestFilterOperator(unittest.TestCase):
275375
"""

0 commit comments

Comments
 (0)