multi fce stuff
This commit is contained in:
parent
49ece8dee6
commit
ddabfbeaa8
32 changed files with 1309 additions and 700 deletions
|
|
@ -327,6 +327,34 @@ class Tier2Tests(TestCase):
|
|||
f"/api/analyses/{analysis}", json.dumps({"source_blocks": keys[:2]}),
|
||||
content_type="application/json").status_code)
|
||||
|
||||
def test_source_roles_are_complete_and_unique_per_subject(self):
|
||||
analysis = self.register_analysis()
|
||||
keys = []
|
||||
for subject in ("face-1", "face-2"):
|
||||
for role in ("source/dense", "source/detected", "source/crops"):
|
||||
desc = json.loads(block_descriptor(analysis, role=role))
|
||||
desc["features"] = [subject]
|
||||
descriptor = json.dumps(desc, sort_keys=True, separators=(",", ":"))
|
||||
key = key_for(descriptor)
|
||||
self.assertEqual(201, self.post("/api/blocks", {
|
||||
"key": key, "descriptor": descriptor, "data": "AA==",
|
||||
}).status_code)
|
||||
keys.append(key)
|
||||
|
||||
def put(keys):
|
||||
return self.client.put(f"/api/analyses/{analysis}",
|
||||
json.dumps({"source_blocks": keys}),
|
||||
content_type="application/json")
|
||||
|
||||
self.assertEqual(400, put(keys[:-1]).status_code)
|
||||
self.assertEqual(400, put(keys + keys[:1]).status_code)
|
||||
self.assertEqual(200, put(keys).status_code)
|
||||
self.assertEqual(200, put(list(reversed(keys))).status_code)
|
||||
self.assertEqual(409, put(keys[:3]).status_code)
|
||||
self.assertEqual(set(keys), set(self.client.get(
|
||||
f"/api/analyses/{analysis}").json()["source_blocks"]))
|
||||
|
||||
|
||||
|
||||
@override_settings(BLOB_ROOT=BLOB_DIR)
|
||||
class DocumentTests(TestCase):
|
||||
|
|
|
|||
|
|
@ -433,12 +433,23 @@ def analysis_detail(request, key):
|
|||
try:
|
||||
keys = _body(request).get("source_blocks")
|
||||
roles = {"source/dense", "source/detected", "source/crops"}
|
||||
if not isinstance(keys, list) or len(keys) != len(roles) or len(set(keys)) != len(roles):
|
||||
raise Bad("an analysis needs one block for each source role")
|
||||
if (not isinstance(keys, list) or not keys
|
||||
or not all(isinstance(k, str) for k in keys) or len(set(keys)) != len(keys)):
|
||||
raise Bad("an analysis needs distinct source block keys")
|
||||
blocks = list(Block.objects.filter(key__in=keys))
|
||||
if (len(blocks) != len(roles) or {b.role for b in blocks} != roles
|
||||
or any(b.analysis_id != key for b in blocks)):
|
||||
raise Bad("source blocks must have distinct source roles and name this analysis")
|
||||
if len(blocks) != len(keys) or any(b.analysis_id != key for b in blocks):
|
||||
raise Bad("source blocks must exist and name this analysis")
|
||||
by_subject = {}
|
||||
for block in blocks:
|
||||
subjects = json.loads(block.descriptor).get("features", [])
|
||||
if (not isinstance(subjects, list) or len(subjects) > 1
|
||||
or any(not isinstance(s, str) or not s for s in subjects)):
|
||||
raise Bad("a source block must name one subject")
|
||||
# Older single-face analyses used an empty feature list.
|
||||
by_subject.setdefault(tuple(subjects), []).append(block.role)
|
||||
if any(len(found) != len(roles) or set(found) != roles
|
||||
for found in by_subject.values()):
|
||||
raise Bad("each subject needs one block for each source role")
|
||||
with transaction.atomic():
|
||||
row = Analysis.objects.select_for_update().get(key=key)
|
||||
current = set(row.source_blocks.values_list("key", flat=True))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue