Skip to content

Commit 6c67fa0

Browse files
committed
Completely overwrite content instances on resource data import
Fixes #1502
1 parent b62a0c3 commit 6c67fa0

File tree

4 files changed

+69
-31
lines changed

4 files changed

+69
-31
lines changed

Tekst-API/tekst/models/common.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,6 @@ async def insert(self, **kwargs):
127127
async def apply_updates(
128128
self,
129129
updates_model: ModelBase,
130-
*,
131-
write_to_db: bool = True,
132130
) -> "DocumentBase":
133131
"""
134132
Custom method to apply updates to the document, excluding any fields that are
@@ -148,10 +146,7 @@ async def apply_updates(
148146
# set attribute
149147
setattr(self, field, getattr(updates_model, field))
150148

151-
if write_to_db:
152-
return await self.replace()
153-
else:
154-
return self
149+
return await self.replace()
155150

156151
@classmethod
157152
def _validate_against_field(

Tekst-API/tekst/routers/resources.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -828,8 +828,7 @@ async def _import_resource_task(
828828

829829
# get content models
830830
content_model = resource_types_mgr.get(resource_doc.resource_type).content_model()
831-
doc_model: ContentBaseDocument = content_model.document_model()
832-
content_update_model = content_model.update_model()
831+
content_doc_model: ContentBaseDocument = content_model.document_model()
833832

834833
created_count = 0
835834
updated_count = 0
@@ -857,24 +856,28 @@ async def _import_resource_task(
857856
raise errors.E_400_IMPORT_ID_NON_EXISTENT
858857

859858
# check if this content already exists
860-
content_doc = await doc_model.find_one(
861-
doc_model.resource_id == resource_doc.id,
862-
doc_model.location_id == loc_id,
859+
content_doc = await content_doc_model.find_one(
860+
content_doc_model.resource_id == resource_doc.id,
861+
content_doc_model.location_id == loc_id,
863862
)
864863

865-
# validate content against model
864+
# create ready-to-write content model instances
865+
# and validate content against model
866866
try:
867867
if content_doc:
868-
await content_doc.apply_updates(
869-
content_update_model(
870-
resource_type=resource_doc.resource_type,
871-
**content,
872-
),
873-
write_to_db=False,
868+
# this is an update to an existing content document
869+
# (we replace it COMPLETELY but keep the ID)
870+
new_content_doc = content_doc_model(
871+
id=content_doc.id,
872+
resource_type=resource_doc.resource_type,
873+
resource_id=resource_doc.id,
874+
location_id=loc_id,
875+
**content,
874876
)
875-
contents.append((content_doc, True))
877+
contents.append((new_content_doc, True))
876878
else:
877-
content_doc = doc_model(
879+
# this is a new content document
880+
content_doc = content_doc_model(
878881
resource_type=resource_doc.resource_type,
879882
resource_id=resource_doc.id,
880883
location_id=loc_id,

Tekst-API/tests/test_api_contents.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ async def test_find_contents(
118118
)["resources"][0]
119119
await login(is_superuser=True)
120120

121-
# find all contents
121+
# find all contents of resource
122122
resp = await test_client.get(
123123
"/contents",
124124
params={"res": [resource_id], "limit": 100},
@@ -127,7 +127,7 @@ async def test_find_contents(
127127
assert isinstance(resp.json(), list)
128128
assert len(resp.json()) > 0
129129

130-
# find all contents of resource
130+
# find all contents
131131
resp = await test_client.get(
132132
"/contents",
133133
params={"limit": 100},

Tekst-API/tests/test_api_resources.py

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,15 +1268,6 @@ async def test_import_resource(
12681268
assert "id" in resp.json()
12691269
assert not await wait_for_task_success(resp.json()["id"])
12701270

1271-
# upload valid resource data file
1272-
resp = await test_client.post(
1273-
f"/resources/{resource_id}/import",
1274-
files={"file": ("foo.json", import_sample_string, "application/json")},
1275-
)
1276-
assert_status(202, resp)
1277-
assert "id" in resp.json()
1278-
assert await wait_for_task_success(resp.json()["id"])
1279-
12801271
# fail to upload resource data without write permissions
12811272
await login()
12821273
resp = await test_client.post(
@@ -1314,6 +1305,55 @@ async def test_import_resource(
13141305
assert "id" in resp.json()
13151306
assert not await wait_for_task_success(resp.json()["id"])
13161307

1308+
# upload valid resource data file
1309+
resp = await test_client.post(
1310+
f"/resources/{resource_id}/import",
1311+
files={"file": ("foo.json", import_sample_string, "application/json")},
1312+
)
1313+
assert_status(202, resp)
1314+
assert "id" in resp.json()
1315+
assert await wait_for_task_success(resp.json()["id"])
1316+
1317+
# upload update to valid resource data
1318+
resp = await test_client.post(
1319+
f"/resources/{resource_id}/import",
1320+
files={
1321+
"file": (
1322+
"foo.json",
1323+
json.dumps(
1324+
{
1325+
"contents": [
1326+
{
1327+
"locationId": additional_location_id,
1328+
"text": "Frustrationstoleranz",
1329+
},
1330+
],
1331+
"resourceId": resource_id,
1332+
}
1333+
),
1334+
"application/json",
1335+
)
1336+
},
1337+
)
1338+
assert_status(202, resp)
1339+
assert "id" in resp.json()
1340+
assert await wait_for_task_success(resp.json()["id"])
1341+
1342+
# check if content doc was updated correctly:
1343+
# find all contents of resource
1344+
resp = await test_client.get(
1345+
"/contents",
1346+
params={"res": [resource_id], "limit": 100},
1347+
)
1348+
assert_status(200, resp)
1349+
assert isinstance(resp.json(), list)
1350+
assert len(resp.json()) > 0
1351+
# check if target content is a-okay
1352+
for c in resp.json():
1353+
if c["locationId"] == additional_location_id:
1354+
assert c["text"] == "Frustrationstoleranz"
1355+
break
1356+
13171357

13181358
@pytest.mark.anyio
13191359
async def test_export_content(

0 commit comments

Comments
 (0)