diff --git a/hivemq-edge/src/frontend/src/components/MQTT/Topic.spec.cy.tsx b/hivemq-edge/src/frontend/src/components/MQTT/Topic.spec.cy.tsx
index 3a0a45df8d..8ecf9c95ae 100644
--- a/hivemq-edge/src/frontend/src/components/MQTT/Topic.spec.cy.tsx
+++ b/hivemq-edge/src/frontend/src/components/MQTT/Topic.spec.cy.tsx
@@ -2,6 +2,8 @@
import { MOCK_TOPIC_REF1 } from '@/__test-utils__/react-flow/topics.ts'
+import { formatTopicString } from '@/components/MQTT/topic-utils.ts'
+
import Topic from './Topic.tsx'
describe('Topic', () => {
@@ -12,7 +14,7 @@ describe('Topic', () => {
it('should render', () => {
cy.mountWithProviders()
- cy.getByTestId('topic-wrapper').should('contain.text', 'root/topic/ref/1')
+ cy.getByTestId('topic-wrapper').should('contain.text', formatTopicString('root/topic/ref/1'))
})
it('should be accessible', () => {
diff --git a/hivemq-edge/src/frontend/src/components/MQTT/Topic.tsx b/hivemq-edge/src/frontend/src/components/MQTT/Topic.tsx
index 1cd0abcd42..4556ec1e72 100644
--- a/hivemq-edge/src/frontend/src/components/MQTT/Topic.tsx
+++ b/hivemq-edge/src/frontend/src/components/MQTT/Topic.tsx
@@ -2,6 +2,7 @@ import { FC, ReactNode } from 'react'
import { Tag, TagLabel, TagProps } from '@chakra-ui/react'
import TopicIcon from '@/components/Icons/TopicIcon.tsx'
+import { formatTopicString } from '@/components/MQTT/topic-utils.ts'
// TODO[NVL] Not sure adding ReactNode as possible children is a good move.
interface TopicProps extends TagProps {
@@ -9,7 +10,7 @@ interface TopicProps extends TagProps {
}
const Topic: FC = ({ topic, ...rest }) => {
- const expandedTopic = typeof topic === 'string' ? topic.split('/').join(' / ') : topic
+ const expandedTopic = typeof topic === 'string' ? formatTopicString(topic) : topic
return (
diff --git a/hivemq-edge/src/frontend/src/components/MQTT/topic-utils.spec.ts b/hivemq-edge/src/frontend/src/components/MQTT/topic-utils.spec.ts
new file mode 100644
index 0000000000..bc62f38a44
--- /dev/null
+++ b/hivemq-edge/src/frontend/src/components/MQTT/topic-utils.spec.ts
@@ -0,0 +1,19 @@
+import { expect } from 'vitest'
+import { formatTopicString } from '@/components/MQTT/topic-utils.ts'
+
+interface TestEachSuite {
+ topic: string
+ expected: string
+}
+
+describe('formatTopicString', () => {
+ it.each([
+ { topic: '', expected: '' },
+ { topic: '12345', expected: '12345' },
+ { topic: '123/45', expected: '123 / 45' },
+ { topic: '12/3/45', expected: '12 / 3 / 45' },
+ { topic: '12/3/45/', expected: '12 / 3 / 45 / ' },
+ ])('should returns $expected with $topic', ({ topic, expected }) => {
+ expect(formatTopicString(topic)).toStrictEqual(expected)
+ })
+})
diff --git a/hivemq-edge/src/frontend/src/components/MQTT/topic-utils.ts b/hivemq-edge/src/frontend/src/components/MQTT/topic-utils.ts
new file mode 100644
index 0000000000..fce24b48fc
--- /dev/null
+++ b/hivemq-edge/src/frontend/src/components/MQTT/topic-utils.ts
@@ -0,0 +1,3 @@
+const TOPIC_SEPARATOR = ' / '
+
+export const formatTopicString = (topic: string) => topic.split('/').join(TOPIC_SEPARATOR)
diff --git a/hivemq-edge/src/frontend/src/modules/EdgeVisualisation/components/nodes/NodeAdapter.spec.cy.tsx b/hivemq-edge/src/frontend/src/modules/EdgeVisualisation/components/nodes/NodeAdapter.spec.cy.tsx
index 8796df14f4..eb29395221 100644
--- a/hivemq-edge/src/frontend/src/modules/EdgeVisualisation/components/nodes/NodeAdapter.spec.cy.tsx
+++ b/hivemq-edge/src/frontend/src/modules/EdgeVisualisation/components/nodes/NodeAdapter.spec.cy.tsx
@@ -4,7 +4,9 @@ import { mockReactFlow } from '@/__test-utils__/react-flow/providers.tsx'
import { MOCK_NODE_ADAPTER } from '@/__test-utils__/react-flow/nodes.ts'
import { MOCK_TOPIC_REF1, MOCK_TOPIC_REF2 } from '@/__test-utils__/react-flow/topics.ts'
import { MOCK_ADAPTER_ID } from '@/__test-utils__/mocks.ts'
+
import { mockProtocolAdapter } from '@/api/hooks/useProtocolAdapters/__handlers__'
+import { formatTopicString } from '@/components/MQTT/topic-utils.ts'
import NodeAdapter from './NodeAdapter.tsx'
@@ -21,8 +23,8 @@ describe('NodeAdapter', () => {
cy.getByTestId('connection-status').should('contain.text', 'Connected')
cy.getByTestId('topics-container')
.should('be.visible')
- .should('contain.text', MOCK_TOPIC_REF1)
- .should('contain.text', MOCK_TOPIC_REF2)
+ .should('contain.text', formatTopicString(MOCK_TOPIC_REF1))
+ .should('contain.text', formatTopicString(MOCK_TOPIC_REF2))
})
it('should be accessible', () => {
diff --git a/hivemq-edge/src/frontend/src/modules/EdgeVisualisation/components/nodes/NodeBridge.spec.cy.tsx b/hivemq-edge/src/frontend/src/modules/EdgeVisualisation/components/nodes/NodeBridge.spec.cy.tsx
index 5751c37bfa..a3283d7161 100644
--- a/hivemq-edge/src/frontend/src/modules/EdgeVisualisation/components/nodes/NodeBridge.spec.cy.tsx
+++ b/hivemq-edge/src/frontend/src/modules/EdgeVisualisation/components/nodes/NodeBridge.spec.cy.tsx
@@ -2,10 +2,12 @@
import { MOCK_NODE_BRIDGE } from '@/__test-utils__/react-flow/nodes.ts'
import { mockReactFlow } from '@/__test-utils__/react-flow/providers.tsx'
+import { MOCK_TOPIC_ACT1, MOCK_TOPIC_ALL } from '@/__test-utils__/react-flow/topics.ts'
import { mockProtocolAdapter } from '@/api/hooks/useProtocolAdapters/__handlers__'
+import { formatTopicString } from '@/components/MQTT/topic-utils.ts'
+
import NodeBridge from './NodeBridge.tsx'
-import { MOCK_TOPIC_ACT1, MOCK_TOPIC_ALL } from '@/__test-utils__/react-flow/topics.ts'
describe('NodeBridge', () => {
beforeEach(() => {
@@ -24,8 +26,14 @@ describe('NodeBridge', () => {
// .should('contain.text', MOCK_TOPIC_REF2)
cy.getByTestId('topics-container').should('have.length', 2)
- cy.getByTestId('topics-container').eq(0).should('be.visible').should('contain.text', MOCK_TOPIC_ACT1)
- cy.getByTestId('topics-container').eq(1).should('be.visible').should('contain.text', MOCK_TOPIC_ALL)
+ cy.getByTestId('topics-container')
+ .eq(0)
+ .should('be.visible')
+ .should('contain.text', formatTopicString(MOCK_TOPIC_ACT1))
+ cy.getByTestId('topics-container')
+ .eq(1)
+ .should('be.visible')
+ .should('contain.text', formatTopicString(MOCK_TOPIC_ALL))
})
it('should be accessible', () => {
diff --git a/hivemq-edge/src/frontend/src/modules/EdgeVisualisation/components/parts/TopicsContainer.spec.cy.tsx b/hivemq-edge/src/frontend/src/modules/EdgeVisualisation/components/parts/TopicsContainer.spec.cy.tsx
index f320f61491..c14b9fb843 100644
--- a/hivemq-edge/src/frontend/src/modules/EdgeVisualisation/components/parts/TopicsContainer.spec.cy.tsx
+++ b/hivemq-edge/src/frontend/src/modules/EdgeVisualisation/components/parts/TopicsContainer.spec.cy.tsx
@@ -1,8 +1,10 @@
///
+import { formatTopicString } from '@/components/MQTT/topic-utils.ts'
+
import TopicsContainer from './TopicsContainer.tsx'
-describe('NodeListener', () => {
+describe('TopicsContainer', () => {
beforeEach(() => {
cy.viewport(400, 400)
})
@@ -22,8 +24,8 @@ describe('NodeListener', () => {
)
cy.getByTestId('topic-wrapper').should('have.length', 2)
- cy.getByTestId('topic-wrapper').eq(0).should('contain.text', 'my/first/topic')
- cy.getByTestId('topic-wrapper').eq(1).should('contain.text', 'my/second/topic')
+ cy.getByTestId('topic-wrapper').eq(0).should('contain.text', formatTopicString('my/first/topic'))
+ cy.getByTestId('topic-wrapper').eq(1).should('contain.text', formatTopicString('my/second/topic'))
cy.getByTestId('topics-show-more').should('not.exist')
})
@@ -46,8 +48,8 @@ describe('NodeListener', () => {
)
cy.getByTestId('topic-wrapper').should('have.length', 2)
- cy.getByTestId('topic-wrapper').eq(0).should('contain.text', 'my/first/topic')
- cy.getByTestId('topic-wrapper').eq(1).should('contain.text', 'my/second/topic')
+ cy.getByTestId('topic-wrapper').eq(0).should('contain.text', formatTopicString('my/first/topic'))
+ cy.getByTestId('topic-wrapper').eq(1).should('contain.text', formatTopicString('my/second/topic'))
cy.getByTestId('topics-show-more').should('be.visible').should('contain.text', '+1')
})