mirror of
https://github.com/langgenius/dify.git
synced 2026-06-01 14:38:12 +08:00
fix: allow tag rename without type payload
This commit is contained in:
@ -25,6 +25,10 @@ class TagBasePayload(BaseModel):
|
||||
type: TagType = Field(description="Tag type")
|
||||
|
||||
|
||||
class TagUpdateRequestPayload(BaseModel):
|
||||
name: str = Field(description="Tag name", min_length=1, max_length=50)
|
||||
|
||||
|
||||
class TagBindingPayload(BaseModel):
|
||||
tag_ids: list[str] = Field(description="Tag IDs to bind")
|
||||
target_id: str = Field(description="Target ID to bind tags to")
|
||||
@ -68,6 +72,7 @@ class TagResponse(ResponseModel):
|
||||
register_schema_models(
|
||||
console_ns,
|
||||
TagBasePayload,
|
||||
TagUpdateRequestPayload,
|
||||
TagBindingPayload,
|
||||
TagBindingRemovePayload,
|
||||
TagListQueryParam,
|
||||
@ -118,7 +123,7 @@ class TagListApi(Resource):
|
||||
|
||||
@console_ns.route("/tags/<uuid:tag_id>")
|
||||
class TagUpdateDeleteApi(Resource):
|
||||
@console_ns.expect(console_ns.models[TagBasePayload.__name__])
|
||||
@console_ns.expect(console_ns.models[TagUpdateRequestPayload.__name__])
|
||||
@setup_required
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@ -129,8 +134,8 @@ class TagUpdateDeleteApi(Resource):
|
||||
if not (current_user.has_edit_permission or current_user.is_dataset_editor):
|
||||
raise Forbidden()
|
||||
|
||||
payload = TagBasePayload.model_validate(console_ns.payload or {})
|
||||
tag = TagService.update_tags(UpdateTagPayload(name=payload.name, type=payload.type), tag_id)
|
||||
payload = TagUpdateRequestPayload.model_validate(console_ns.payload or {})
|
||||
tag = TagService.update_tags(UpdateTagPayload(name=payload.name), tag_id)
|
||||
|
||||
binding_count = TagService.get_tag_binding_count(tag_id)
|
||||
|
||||
|
||||
@ -31,7 +31,9 @@ from services.tag_service import (
|
||||
TagBindingCreatePayload,
|
||||
TagBindingDeletePayload,
|
||||
TagService,
|
||||
UpdateTagPayload,
|
||||
)
|
||||
from services.tag_service import (
|
||||
UpdateTagPayload as UpdateTagServicePayload,
|
||||
)
|
||||
|
||||
register_enum_models(service_api_ns, DatasetPermissionEnum)
|
||||
@ -556,7 +558,7 @@ class DatasetTagsApi(DatasetApiResource):
|
||||
|
||||
payload = TagUpdatePayload.model_validate(service_api_ns.payload or {})
|
||||
tag_id = payload.tag_id
|
||||
tag = TagService.update_tags(UpdateTagPayload(name=payload.name, type=TagType.KNOWLEDGE), tag_id)
|
||||
tag = TagService.update_tags(UpdateTagServicePayload(name=payload.name), tag_id)
|
||||
|
||||
binding_count = TagService.get_tag_binding_count(tag_id)
|
||||
|
||||
|
||||
@ -21,7 +21,6 @@ class SaveTagPayload(BaseModel):
|
||||
|
||||
class UpdateTagPayload(BaseModel):
|
||||
name: str = Field(min_length=1, max_length=50)
|
||||
type: TagType
|
||||
|
||||
|
||||
class TagBindingCreatePayload(BaseModel):
|
||||
|
||||
@ -759,7 +759,7 @@ class TestTagService:
|
||||
tag = TagService.save_tags(tag_args)
|
||||
|
||||
# Update args
|
||||
update_args = UpdateTagPayload(name="updated_name", type="knowledge")
|
||||
update_args = UpdateTagPayload(name="updated_name")
|
||||
|
||||
# Act: Execute the method under test
|
||||
result = TagService.update_tags(update_args, tag.id)
|
||||
@ -799,7 +799,7 @@ class TestTagService:
|
||||
|
||||
non_existent_tag_id = str(uuid.uuid4())
|
||||
|
||||
update_args = UpdateTagPayload(name="updated_name", type="knowledge")
|
||||
update_args = UpdateTagPayload(name="updated_name")
|
||||
|
||||
# Act & Assert: Verify proper error handling
|
||||
with pytest.raises(NotFound) as exc_info:
|
||||
@ -830,7 +830,7 @@ class TestTagService:
|
||||
tag2 = TagService.save_tags(tag2_args)
|
||||
|
||||
# Try to update second tag with first tag's name
|
||||
update_args = UpdateTagPayload(name="first_tag", type="app")
|
||||
update_args = UpdateTagPayload(name="first_tag")
|
||||
|
||||
# Act & Assert: Verify proper error handling
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
|
||||
@ -14,6 +14,7 @@ from controllers.console.tag.tags import (
|
||||
TagUpdateDeleteApi,
|
||||
)
|
||||
from models.enums import TagType
|
||||
from services.tag_service import UpdateTagPayload
|
||||
|
||||
|
||||
def unwrap(func):
|
||||
@ -147,7 +148,7 @@ class TestTagUpdateDeleteApi:
|
||||
api = TagUpdateDeleteApi()
|
||||
method = unwrap(api.patch)
|
||||
|
||||
payload = {"name": "updated", "type": "knowledge"}
|
||||
payload = {"name": "updated"}
|
||||
|
||||
with app.test_request_context("/", json=payload):
|
||||
with (
|
||||
@ -159,7 +160,7 @@ class TestTagUpdateDeleteApi:
|
||||
patch(
|
||||
"controllers.console.tag.tags.TagService.update_tags",
|
||||
return_value=tag,
|
||||
),
|
||||
) as update_tags_mock,
|
||||
patch(
|
||||
"controllers.console.tag.tags.TagService.get_tag_binding_count",
|
||||
return_value=3,
|
||||
@ -168,6 +169,9 @@ class TestTagUpdateDeleteApi:
|
||||
result, status = method(api, "tag-1")
|
||||
|
||||
assert status == 200
|
||||
update_payload, tag_id = update_tags_mock.call_args.args
|
||||
assert update_payload == UpdateTagPayload(name="updated")
|
||||
assert tag_id == "tag-1"
|
||||
assert result["binding_count"] == "3"
|
||||
|
||||
def test_patch_forbidden(self, app: Flask, readonly_user, payload_patch):
|
||||
|
||||
@ -48,7 +48,7 @@ export const tagUpdateContract = base
|
||||
name: string
|
||||
}
|
||||
}>())
|
||||
.output(type<unknown>())
|
||||
.output(type<Tag>())
|
||||
|
||||
export const tagDeleteContract = base
|
||||
.route({
|
||||
|
||||
@ -187,15 +187,20 @@ describe('consoleQuery tag mutation defaults', () => {
|
||||
queryClient.setQueryData(appListKey, [targetTag, otherTag])
|
||||
queryClient.setQueryData(knowledgeListKey, [knowledgeTag])
|
||||
|
||||
const updatedTag = createTag({
|
||||
...targetTag,
|
||||
name: 'After',
|
||||
binding_count: 5,
|
||||
})
|
||||
const mutationOptions = consoleQuery.tags.update.mutationOptions()
|
||||
await mutationOptions.onSuccess?.(
|
||||
undefined,
|
||||
updatedTag,
|
||||
{
|
||||
params: {
|
||||
tagId: targetTag.id,
|
||||
},
|
||||
body: {
|
||||
name: 'After',
|
||||
name: 'Ignored Client Name',
|
||||
},
|
||||
},
|
||||
undefined,
|
||||
@ -203,10 +208,7 @@ describe('consoleQuery tag mutation defaults', () => {
|
||||
)
|
||||
|
||||
expect(queryClient.getQueryData(appListKey)).toEqual([
|
||||
{
|
||||
...targetTag,
|
||||
name: 'After',
|
||||
},
|
||||
updatedTag,
|
||||
otherTag,
|
||||
])
|
||||
expect(queryClient.getQueryData(knowledgeListKey)).toEqual([knowledgeTag])
|
||||
|
||||
@ -108,16 +108,13 @@ export const consoleQuery = createTanstackQueryUtils(consoleClient, {
|
||||
},
|
||||
update: {
|
||||
mutationOptions: {
|
||||
onSuccess: (_data, variables, _onMutateResult, context) => {
|
||||
onSuccess: (updatedTag, variables, _onMutateResult, context) => {
|
||||
context.client.setQueriesData(
|
||||
{
|
||||
queryKey: consoleQuery.tags.list.key({ type: 'query' }),
|
||||
},
|
||||
(oldTags: Tag[] | undefined) => oldTags?.map(tag => tag.id === variables.params.tagId
|
||||
? {
|
||||
...tag,
|
||||
name: variables.body.name,
|
||||
}
|
||||
? updatedTag
|
||||
: tag),
|
||||
)
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user