test(tag-management): cover tag name filter paths

This commit is contained in:
yyh
2026-05-11 18:59:38 +08:00
parent 165c250a1d
commit 803b41ef2b
4 changed files with 144 additions and 0 deletions
@@ -9,6 +9,7 @@ import services
from controllers.console import console_ns
from controllers.console.app.error import ProviderNotInitializeError
from controllers.console.datasets.datasets import (
ConsoleDatasetListQuery,
DatasetApi,
DatasetApiBaseUrlApi,
DatasetApiDeleteApi,
@@ -164,6 +165,11 @@ class TestDatasetList:
assert get_datasets_mock.call_args.kwargs["tag_names"] == ["Finance", "Support"]
assert status == 200
def test_query_model_trims_empty_tag_names(self):
query = ConsoleDatasetListQuery.model_validate({"tag_names": ["", " Finance ", "Support", " "]})
assert query.tag_names == ["Finance", "Support"]
def test_embedding_available_false(self, app: Flask):
api = DatasetListApi()
method = unwrap(api.get)
@@ -15,6 +15,7 @@ from .dataset_service_test_helpers import (
ProviderTokenNotInitError,
RagPipelineDatasetCreateEntity,
SimpleNamespace,
TenantAccountRole,
_make_knowledge_configuration,
_make_retrieval_model,
_make_session_context,
@@ -24,6 +25,60 @@ from .dataset_service_test_helpers import (
)
class TestDatasetServiceList:
"""Unit tests for dataset list filtering."""
def test_get_datasets_filters_by_tag_names(self):
dataset = DatasetServiceUnitDataFactory.create_dataset_mock(dataset_id="dataset-1")
user = SimpleNamespace(id="user-1", current_role=TenantAccountRole.OWNER)
with (
patch("services.dataset_service.db") as mock_db,
patch(
"services.dataset_service.TagService.get_target_ids_by_tag_names",
return_value=["dataset-1"],
) as tag_mock,
):
mock_db.session.scalars.return_value.all.return_value = []
mock_db.paginate.return_value = SimpleNamespace(items=[dataset], total=1)
datasets, total = DatasetService.get_datasets(
page=1,
per_page=20,
tenant_id="tenant-1",
user=user,
include_all=True,
tag_names=["Finance", "Support"],
)
assert datasets == [dataset]
assert total == 1
tag_mock.assert_called_once_with("knowledge", "tenant-1", ["Finance", "Support"])
mock_db.paginate.assert_called_once()
def test_get_datasets_returns_empty_when_tag_names_match_no_targets(self):
user = SimpleNamespace(id="user-1", current_role=TenantAccountRole.OWNER)
with (
patch("services.dataset_service.db") as mock_db,
patch("services.dataset_service.TagService.get_target_ids_by_tag_names", return_value=[]),
):
mock_db.session.scalars.return_value.all.return_value = []
datasets, total = DatasetService.get_datasets(
page=1,
per_page=20,
tenant_id="tenant-1",
user=user,
include_all=True,
tag_names=["Unknown"],
)
assert datasets == []
assert total == 0
mock_db.paginate.assert_not_called()
class TestDatasetServiceValidation:
"""Unit tests for DatasetService validation helpers."""
@@ -128,6 +128,20 @@ describe('TagSelector', () => {
expect(screen.getByRole('option', { name: /Backend/i })).toBeInTheDocument()
})
it('reports active state when the popup opens and closes', async () => {
const user = userEvent.setup()
const onActiveChange = vi.fn()
render(<TagSelector {...defaultProps} onActiveChange={onActiveChange} />)
const trigger = screen.getByRole('combobox', { name: /Frontend/i })
await user.click(trigger)
await screen.findByRole('combobox', { name: i18n.selectorPlaceholder })
await user.click(trigger)
expect(onActiveChange).toHaveBeenNthCalledWith(1, true)
expect(onActiveChange).toHaveBeenNthCalledWith(2, false)
})
it('applies added tags only when the popup closes', async () => {
const user = userEvent.setup()
render(<TagSelector {...defaultProps} />)
@@ -0,0 +1,69 @@
import type { ReactNode } from 'react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { renderHook, waitFor } from '@testing-library/react'
import { get } from '../base'
import { useDatasetList, useInfiniteDatasets } from './use-dataset'
vi.mock('../base', () => ({
get: vi.fn(),
post: vi.fn(),
}))
const createWrapper = () => {
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false },
},
})
return ({ children }: { children: ReactNode }) => (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
)
}
const datasetListResponse = {
data: [],
has_more: false,
limit: 20,
page: 1,
total: 0,
}
describe('dataset list hooks', () => {
beforeEach(() => {
vi.clearAllMocks()
vi.mocked(get).mockResolvedValue(datasetListResponse)
})
it('serializes dataset list filters with tag names', async () => {
renderHook(
() => useDatasetList({
initialPage: 1,
limit: 20,
tag_names: ['Finance', 'Support'],
}),
{ wrapper: createWrapper() },
)
await waitFor(() => {
expect(get).toHaveBeenCalledWith('/datasets?tag_names=Finance&tag_names=Support&limit=20&page=1')
})
})
it('normalizes infinite dataset list filters with tag names', async () => {
renderHook(
() => useInfiniteDatasets({
page: 2,
limit: 10,
tag_names: ['Finance'],
}),
{ wrapper: createWrapper() },
)
await waitFor(() => {
expect(get).toHaveBeenCalledWith('/datasets?page=2&limit=10&tag_names=Finance')
})
})
})