diff --git a/web/app/components/plugins/card/card-more-info.tsx b/web/app/components/plugins/card/card-tags.tsx
similarity index 89%
rename from web/app/components/plugins/card/card-more-info.tsx
rename to web/app/components/plugins/card/card-tags.tsx
index 1f9cde9a22..0a8e1fccfa 100644
--- a/web/app/components/plugins/card/card-more-info.tsx
+++ b/web/app/components/plugins/card/card-tags.tsx
@@ -5,7 +5,7 @@ type Props = {
tags: string[]
}
-const CardMoreInfoComponent = ({
+const CardTagsComponent = ({
tags,
}: Props) => {
return (
@@ -29,6 +29,6 @@ const CardMoreInfoComponent = ({
}
// Memoize to prevent unnecessary re-renders when tags array hasn't changed
-const CardMoreInfo = React.memo(CardMoreInfoComponent)
+const CardTags = React.memo(CardTagsComponent)
-export default CardMoreInfo
+export default CardTags
diff --git a/web/app/components/plugins/card/index.spec.tsx b/web/app/components/plugins/card/index.spec.tsx
index 8406d6753d..0266c03740 100644
--- a/web/app/components/plugins/card/index.spec.tsx
+++ b/web/app/components/plugins/card/index.spec.tsx
@@ -11,7 +11,7 @@ import DownloadCount from './base/download-count'
import OrgInfo from './base/org-info'
import Placeholder, { LoadingPlaceholder } from './base/placeholder'
import Title from './base/title'
-import CardMoreInfo from './card-more-info'
+import CardTags from './card-tags'
// ================================
// Import Components Under Test
// ================================
@@ -642,9 +642,9 @@ describe('Card', () => {
})
// ================================
-// CardMoreInfo Component Tests
+// CardTags Component Tests
// ================================
-describe('CardMoreInfo', () => {
+describe('CardTags', () => {
beforeEach(() => {
vi.clearAllMocks()
})
@@ -654,66 +654,24 @@ describe('CardMoreInfo', () => {
// ================================
describe('Rendering', () => {
it('should render without crashing', () => {
- render()
+ render()
expect(document.body).toBeInTheDocument()
})
- it('should render download count when provided', () => {
- render()
+ it('should render tags in uppercase', () => {
+ render()
- expect(screen.getByText('1,000')).toBeInTheDocument()
+ expect(screen.getByText('SEARCH')).toBeInTheDocument()
+ expect(screen.getByText('IMAGE')).toBeInTheDocument()
})
- it('should render tags when provided', () => {
- render()
+ it('should render at most two tags', () => {
+ render()
- expect(screen.getByText('search')).toBeInTheDocument()
- expect(screen.getByText('image')).toBeInTheDocument()
- })
-
- it('should render both download count and tags with separator', () => {
- render()
-
- expect(screen.getByText('500')).toBeInTheDocument()
- expect(screen.getByText('·')).toBeInTheDocument()
- expect(screen.getByText('tag1')).toBeInTheDocument()
- })
- })
-
- // ================================
- // Props Testing
- // ================================
- describe('Props', () => {
- it('should not render download count when undefined', () => {
- render()
-
- expect(screen.queryByTestId('ri-install-line')).not.toBeInTheDocument()
- })
-
- it('should not render separator when download count is undefined', () => {
- render()
-
- expect(screen.queryByText('·')).not.toBeInTheDocument()
- })
-
- it('should not render separator when tags are empty', () => {
- render()
-
- expect(screen.queryByText('·')).not.toBeInTheDocument()
- })
-
- it('should render hash symbol before each tag', () => {
- render()
-
- expect(screen.getByText('#')).toBeInTheDocument()
- })
-
- it('should set title attribute with hash prefix for tags', () => {
- render()
-
- const tagElement = screen.getByTitle('# search')
- expect(tagElement).toBeInTheDocument()
+ expect(screen.getByText('ONE')).toBeInTheDocument()
+ expect(screen.getByText('TWO')).toBeInTheDocument()
+ expect(screen.queryByText('THREE')).not.toBeInTheDocument()
})
})
@@ -722,54 +680,8 @@ describe('CardMoreInfo', () => {
// ================================
describe('Memoization', () => {
it('should be memoized with React.memo', () => {
- expect(CardMoreInfo).toBeDefined()
- expect(typeof CardMoreInfo).toBe('object')
- })
- })
-
- // ================================
- // Edge Cases Tests
- // ================================
- describe('Edge Cases', () => {
- it('should handle zero download count', () => {
- render()
-
- // 0 should still render since downloadCount is defined
- expect(screen.getByText('0')).toBeInTheDocument()
- })
-
- it('should handle empty tags array', () => {
- render()
-
- expect(screen.queryByText('#')).not.toBeInTheDocument()
- })
-
- it('should handle large download count', () => {
- render()
-
- expect(screen.getByText('1,234,567,890')).toBeInTheDocument()
- })
-
- it('should handle many tags', () => {
- const tags = Array.from({ length: 10 }, (_, i) => `tag${i}`)
- render()
-
- expect(screen.getByText('tag0')).toBeInTheDocument()
- expect(screen.getByText('tag9')).toBeInTheDocument()
- })
-
- it('should handle tags with special characters', () => {
- render()
-
- expect(screen.getByText('tag-with-dash')).toBeInTheDocument()
- expect(screen.getByText('tag_with_underscore')).toBeInTheDocument()
- })
-
- it('should truncate long tag names', () => {
- const longTag = 'a'.repeat(200)
- const { container } = render()
-
- expect(container.querySelector('.truncate')).toBeInTheDocument()
+ expect(CardTags).toBeDefined()
+ expect(typeof CardTags).toBe('object')
})
})
})
@@ -1688,7 +1600,7 @@ describe('Icon', () => {
render(
}
+ footer={}
/>,
)
@@ -1700,9 +1612,8 @@ describe('Icon', () => {
expect(screen.getByText('Tool')).toBeInTheDocument()
expect(screen.getByTestId('partner-badge')).toBeInTheDocument()
expect(screen.getByTestId('verified-badge')).toBeInTheDocument()
- expect(screen.getByText('5,000')).toBeInTheDocument()
- expect(screen.getByText('search')).toBeInTheDocument()
- expect(screen.getByText('api')).toBeInTheDocument()
+ expect(screen.getByText('SEARCH')).toBeInTheDocument()
+ expect(screen.getByText('API')).toBeInTheDocument()
})
it('should render loading state correctly', () => {
@@ -1728,12 +1639,12 @@ describe('Icon', () => {
}
+ footer={}
/>,
)
expect(screen.getByTestId('ri-check-line')).toBeInTheDocument()
- expect(screen.getByText('100')).toBeInTheDocument()
+ expect(screen.getByText('TAG1')).toBeInTheDocument()
})
})
@@ -1817,9 +1728,9 @@ describe('Icon', () => {
})
it('should have title attribute on tags', () => {
- render()
+ render()
- expect(screen.getByTitle('# search')).toBeInTheDocument()
+ expect(screen.getByTitle('search')).toBeInTheDocument()
})
it('should have semantic structure', () => {
@@ -1864,11 +1775,11 @@ describe('Icon', () => {
expect(endTime - startTime).toBeLessThan(1000)
})
- it('should handle CardMoreInfo with many tags', () => {
+ it('should handle CardTags with many tags', () => {
const tags = Array.from({ length: 20 }, (_, i) => `tag-${i}`)
const startTime = performance.now()
- render()
+ render()
const endTime = performance.now()
expect(endTime - startTime).toBeLessThan(100)
diff --git a/web/app/components/plugins/marketplace/index.spec.tsx b/web/app/components/plugins/marketplace/index.spec.tsx
index 1c0c700177..9cbe2c0c7d 100644
--- a/web/app/components/plugins/marketplace/index.spec.tsx
+++ b/web/app/components/plugins/marketplace/index.spec.tsx
@@ -322,11 +322,10 @@ vi.mock('@/app/components/plugins/card', () => ({
),
}))
-// Mock CardMoreInfo component
-vi.mock('@/app/components/plugins/card/card-more-info', () => ({
- default: ({ downloadCount, tags }: { downloadCount: number, tags: string[] }) => (
-
-
{downloadCount}
+// Mock CardTags component
+vi.mock('@/app/components/plugins/card/card-tags', () => ({
+ default: ({ tags }: { tags: string[] }) => (
+
{tags.join(',')}
),
diff --git a/web/app/components/plugins/marketplace/list/card-wrapper.tsx b/web/app/components/plugins/marketplace/list/card-wrapper.tsx
index 0328d1952e..35895641b1 100644
--- a/web/app/components/plugins/marketplace/list/card-wrapper.tsx
+++ b/web/app/components/plugins/marketplace/list/card-wrapper.tsx
@@ -8,7 +8,7 @@ import * as React from 'react'
import { useMemo } from 'react'
import Button from '@/app/components/base/button'
import Card from '@/app/components/plugins/card'
-import CardMoreInfo from '@/app/components/plugins/card/card-more-info'
+import CardTags from '@/app/components/plugins/card/card-tags'
import { useTags } from '@/app/components/plugins/hooks'
import InstallFromMarketplace from '@/app/components/plugins/install-plugin/install-from-marketplace'
import { getPluginDetailLinkInMarketplace, getPluginLinkInMarketplace } from '../utils'
@@ -49,7 +49,7 @@ const CardWrapperComponent = ({
key={plugin.name}
payload={plugin}
footer={(
-
)}
@@ -95,7 +95,7 @@ const CardWrapperComponent = ({
payload={plugin}
disableOrgLink
footer={(
-
)}
diff --git a/web/app/components/plugins/marketplace/list/index.spec.tsx b/web/app/components/plugins/marketplace/list/index.spec.tsx
index 31419030a4..01fffc0c66 100644
--- a/web/app/components/plugins/marketplace/list/index.spec.tsx
+++ b/web/app/components/plugins/marketplace/list/index.spec.tsx
@@ -131,11 +131,10 @@ vi.mock('@/app/components/plugins/card', () => ({
),
}))
-// Mock CardMoreInfo component
-vi.mock('@/app/components/plugins/card/card-more-info', () => ({
- default: ({ downloadCount, tags }: { downloadCount: number, tags: string[] }) => (
-
-
{downloadCount}
+// Mock CardTags component
+vi.mock('@/app/components/plugins/card/card-tags', () => ({
+ default: ({ tags }: { tags: string[] }) => (
+
{tags.join(',')}
),
@@ -983,7 +982,7 @@ describe('CardWrapper (via List integration)', () => {
expect(screen.getByTestId('card-test-plugin')).toBeInTheDocument()
})
- it('should render CardMoreInfo with download count and tags', () => {
+ it('should render CardTags with tags', () => {
const plugin = createMockPlugin({
name: 'test-plugin',
install_count: 5000,
@@ -998,8 +997,7 @@ describe('CardWrapper (via List integration)', () => {
/>,
)
- expect(screen.getByTestId('card-more-info')).toBeInTheDocument()
- expect(screen.getByTestId('download-count')).toHaveTextContent('5000')
+ expect(screen.getByTestId('card-tags')).toBeInTheDocument()
})
})
diff --git a/web/app/components/tools/provider-list.tsx b/web/app/components/tools/provider-list.tsx
index 48fd4ef29d..6cc089c96a 100644
--- a/web/app/components/tools/provider-list.tsx
+++ b/web/app/components/tools/provider-list.tsx
@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next'
import Input from '@/app/components/base/input'
import TabSliderNew from '@/app/components/base/tab-slider-new'
import Card from '@/app/components/plugins/card'
-import CardMoreInfo from '@/app/components/plugins/card/card-more-info'
+import CardTags from '@/app/components/plugins/card/card-tags'
import { useTags } from '@/app/components/plugins/hooks'
import Empty from '@/app/components/plugins/marketplace/empty'
import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel'
@@ -183,7 +183,7 @@ const ProviderList = () => {
name: collection.plugin_id ? collection.plugin_id.split('/')[1] : collection.name,
} as any}
footer={(
-
getTagLabel(label)) || []}
/>
)}