Skip to content

Commit 9e226a4

Browse files
committed
Considering Alias for creating Item (at traditional processing)
Added following processings to prevent to creating (and updating) Item when there is an Alias that has same name with specified Item. - traditional create view - traditional edit view - traditional copy job - traditional import job
1 parent 34003d1 commit 9e226a4

File tree

3 files changed

+128
-1
lines changed

3 files changed

+128
-1
lines changed

entry/tasks.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ def _do_import_entries(job: Job):
153153

154154
entry: Entry = Entry.objects.filter(name=entry_data["name"], schema=entity).first()
155155
if not entry:
156+
# skip to create Item when another duplicated Alias exists
157+
if not entity.is_available(entry_data["name"]):
158+
continue
159+
156160
entry = Entry(name=entry_data["name"], schema=entity, created_user=user)
157161

158162
# for history record
@@ -544,8 +548,16 @@ def copy_entry(self, job: Job) -> tuple[JobStatus, str, None] | None:
544548
@may_schedule_until_job_is_ready
545549
def do_copy_entry(self, job: Job) -> tuple[JobStatus, str, None]:
546550
src_entry = Entry.objects.get(id=job.target.id)
547-
548551
params = json.loads(job.params)
552+
553+
# abort this job when there is duplicated Alias exists
554+
if not src_entry.schema.is_available(params["new_name"]):
555+
return (
556+
JobStatus.ERROR,
557+
"Duplicated Alias(name=%s) exists in this model" % params["new_name"],
558+
src_entry
559+
)
560+
549561
dest_entry = Entry.objects.filter(schema=src_entry.schema, name=params["new_name"]).first()
550562
if not dest_entry:
551563
dest_entry = src_entry.clone(job.user, name=params["new_name"])

entry/tests/test_view.py

+107
Original file line numberDiff line numberDiff line change
@@ -2098,6 +2098,25 @@ def test_edit_entry_with_trigger_configuration(self):
20982098
self.assertEqual(entry.get_attrv("address").value, "Chiyoda ward")
20992099
self.assertEqual(entry.get_attrv("address").referral.id, pref_info["tokyo"].id)
21002100

2101+
def test_edit_when_another_same_named_alias_exists(self):
2102+
user = self.guest_login()
2103+
2104+
# create Model, Item and Alias that is same name with updating Item in this test
2105+
model = self.create_entity(user, "Mountain")
2106+
item = self.add_entry(user, "Everest", model)
2107+
item.add_alias("Chomolungma")
2108+
2109+
resp = self.client.post(
2110+
reverse("entry:do_edit", args=[item.id]),
2111+
json.dumps({
2112+
"entry_name": "Chomolungma",
2113+
"attrs": [],
2114+
}),
2115+
"application/json",
2116+
)
2117+
self.assertEqual(resp.status_code, 400)
2118+
self.assertEqual(resp.content.decode("utf-8"), "Duplicate named Alias is existed")
2119+
21012120
@patch(
21022121
"entry.tasks.create_entry_attrs.delay",
21032122
Mock(side_effect=tasks.create_entry_attrs),
@@ -2133,6 +2152,25 @@ def test_post_create_just_limit_of_value(self):
21332152
AttributeValue.MAXIMUM_VALUE_SIZE,
21342153
)
21352154

2155+
def test_create_when_another_same_named_alias_exists(self):
2156+
user = self.guest_login()
2157+
2158+
# create Model, Item and Alias that is same name with creating Item in this test
2159+
model = self.create_entity(user, "Mountain")
2160+
item = self.add_entry(user, "Everest", model)
2161+
item.add_alias("Chomolungma")
2162+
2163+
resp = self.client.post(
2164+
reverse("entry:do_create", args=[model.id]),
2165+
json.dumps({
2166+
"entry_name": "Chomolungma",
2167+
"attrs": [],
2168+
}),
2169+
"application/json",
2170+
)
2171+
self.assertEqual(resp.status_code, 400)
2172+
self.assertEqual(resp.content.decode("utf-8"), "Duplicate named Alias is existed")
2173+
21362174
@patch("entry.tasks.edit_entry_attrs.delay", Mock(side_effect=tasks.edit_entry_attrs))
21372175
def test_post_edit_just_limit_of_value(self):
21382176
user = self.admin_login()
@@ -3242,6 +3280,45 @@ def test_permission_check_for_copy_request(self):
32423280
if copied_entry is not None:
32433281
copied_entry.delete()
32443282

3283+
@patch("entry.tasks.copy_entry.delay", Mock(side_effect=tasks.copy_entry))
3284+
def test_copy_when_duplicated_named_alias_exists(self):
3285+
user = self.admin_login()
3286+
3287+
model = self.create_entity(user, "Mountain")
3288+
item_src = Entry.objects.create(name="Everest", created_user=user, schema=model)
3289+
item_src.add_alias("Chomolungma")
3290+
3291+
resp = self.client.post(
3292+
reverse("entry:do_copy", args=[item_src.id]),
3293+
json.dumps({
3294+
# Chomolungma is duplicated with Alias of Everest
3295+
"entries": "Mt.Fuji\nK2\nChomolungma",
3296+
}),
3297+
"application/json",
3298+
)
3299+
self.assertEqual(resp.status_code, 200)
3300+
3301+
# check Chomolungma copy job was failed
3302+
copy_job = Job.objects.filter(user=user, operation=JobOperation.COPY_ENTRY).first()
3303+
self.assertEqual(copy_job.text, "Copy completed [%5d/%5d]" % (3, 3))
3304+
self.assertEqual(copy_job.target.entry, item_src)
3305+
self.assertEqual(copy_job.status, JobStatus.DONE)
3306+
3307+
# check Job of COPY has expected attributes
3308+
do_copy_jobs = Job.objects.filter(user=user, operation=JobOperation.DO_COPY_ENTRY)
3309+
self.assertEqual(do_copy_jobs.count(), 3)
3310+
3311+
EXPECTED_PARAMS = [
3312+
("Mt.Fuji", JobStatus.DONE, "original entry: Everest"),
3313+
("K2", JobStatus.DONE, "original entry: Everest"),
3314+
("Chomolungma", JobStatus.ERROR, "Duplicated Alias(name=Chomolungma) exists in this model"),
3315+
]
3316+
for (index, (name, status, text)) in enumerate(EXPECTED_PARAMS):
3317+
job = do_copy_jobs[index]
3318+
self.assertEqual(json.loads(job.params)["new_name"], name)
3319+
self.assertEqual(job.status, status)
3320+
self.assertEqual(job.text, text)
3321+
32453322
@patch("entry.tasks.copy_entry.delay", Mock(side_effect=tasks.copy_entry))
32463323
def test_post_copy_with_valid_entry(self):
32473324
user = self.admin_login()
@@ -3549,6 +3626,36 @@ def test_import_entry(self):
35493626
res = self._es.get(index=settings.ES_CONFIG["INDEX_NAME"], id=entry.id)
35503627
self.assertTrue(res["found"])
35513628

3629+
@patch(
3630+
"trigger.tasks.may_invoke_trigger.delay",
3631+
Mock(side_effect=trigger_tasks.may_invoke_trigger),
3632+
)
3633+
@patch("entry.tasks.import_entries.delay", Mock(side_effect=tasks.import_entries))
3634+
def test_import_when_duplicated_named_alias_exists(self):
3635+
user = self.admin_login()
3636+
3637+
# create Item and Alias that is duplicated with importing Item ("entry1")
3638+
item = self.add_entry(user, "TestItem", self._entity)
3639+
item.add_alias("entry1")
3640+
3641+
# This import_data03 has following Items (entry1, entry2 and entry3)
3642+
with self.open_fixture_file("import_data03.yaml") as fp:
3643+
resp = self.client.post(reverse("entry:do_import", args=[self._entity.id]), {"file": fp})
3644+
self.assertEqual(resp.status_code, 303)
3645+
3646+
# check expected values are set in the job attributes
3647+
job = Job.objects.filter(operation=JobOperation.IMPORT_ENTRY).last()
3648+
self.assertEqual(job.status, JobStatus.DONE)
3649+
self.assertEqual(job.text, "")
3650+
3651+
# check "entry1" wasn't created because same named Alias has already been registered
3652+
whole_items = Entry.objects.filter(schema=self._entity, is_active=True)
3653+
self.assertEqual(whole_items.count(), 3)
3654+
self.assertEqual(
3655+
sorted([x.name for x in whole_items.all()]),
3656+
sorted(["TestItem", "entry2", "entry3"])
3657+
)
3658+
35523659
@patch(
35533660
"trigger.tasks.may_invoke_trigger.delay",
35543661
Mock(side_effect=trigger_tasks.may_invoke_trigger),

entry/views.py

+8
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ def do_create(request, entity_id, recv_data):
233233
).exists():
234234
return HttpResponse("Duplicate name entry is existed", status=400)
235235

236+
# check duplicated Alias is existed
237+
if not entity.is_available(recv_data["entry_name"]):
238+
return HttpResponse("Duplicate named Alias is existed", status=400)
239+
236240
# validate contexts of each attributes
237241
err = _validate_input(recv_data, entity)
238242
if err:
@@ -333,6 +337,10 @@ def do_edit(request, entry_id, recv_data):
333337
if Entry.objects.filter(query).exists():
334338
return HttpResponse("Duplicate name entry is existed", status=400)
335339

340+
# check duplicated Alias is existed
341+
if not entry.schema.is_available(recv_data["entry_name"]):
342+
return HttpResponse("Duplicate named Alias is existed", status=400)
343+
336344
# validate contexts of each attributes
337345
err = _validate_input(recv_data, entry)
338346
if err:

0 commit comments

Comments
 (0)