Repository: provectus/kafka-ui
Issue: Incorrect topic message content type (avro -> json)
Labels: type/bug
scope/frontend
status/accepted

**Describe the bug**
When opening a message of a topic (while using avro converters), in kafka-ui it's shown as JSON. However, if you check the http response in the browser F12 console it's shown as AVRO.

**Set up**
(How do you run the app? 
Which version of the app are you running? Provide either docker image version or check commit hash at the top left corner. We won't be able to help you without this information.)

<img width="456" alt="image" src="https://user-images.githubusercontent.com/94184844/149524120-98b8e50d-a3e7-48b2-98b9-6b5563c5b67c.png">

**Steps to Reproduce**
Steps to reproduce the behavior:

1. Create connector with avro key and value converter
2. Check the message in the topic
3. Json type is shown as content of the message

**Expected behavior**
(A clear and concise description of what you expected to happen)

Avro type is shown as content of the message

**Screenshots**
(If applicable, add screenshots to help explain your problem)

<img width="1578" alt="image" src="https://user-images.githubusercontent.com/94184844/149523892-79fd09b1-c992-4864-831f-1fc4b81a8141.png">

<img width="495" alt="image" src="https://user-images.githubusercontent.com/94184844/149524052-6ec7679e-7fa8-41ca-90ff-e39c20273eec.png">

**Additional context**
(Add any other context about the problem here)


Issue comments:

Pull request review comments:

Patch that resolved the issue:
diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Message.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Message.tsx
index 39154105606..9112b5e1df9 100644
--- a/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Message.tsx
+++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Message.tsx
@@ -27,6 +27,8 @@ const Message: React.FC<{ message: TopicMessage }> = ({
     key,
     partition,
     content,
+    valueFormat,
+    keyFormat,
     headers,
   },
 }) => {
@@ -72,7 +74,9 @@ const Message: React.FC<{ message: TopicMessage }> = ({
       {isOpen && (
         <MessageContent
           messageKey={key}
+          messageKeyFormat={keyFormat}
           messageContent={content}
+          messageContentFormat={valueFormat}
           headers={headers}
           timestamp={timestamp}
           timestampType={timestampType}
diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/MessageContent/MessageContent.styled.ts b/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/MessageContent/MessageContent.styled.ts
index b4d74a12d16..e09c10728a5 100644
--- a/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/MessageContent/MessageContent.styled.ts
+++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/MessageContent/MessageContent.styled.ts
@@ -1,7 +1,7 @@
 import styled from 'styled-components';
 import { Colors } from 'theme/theme';
 
-export const MessageContentWrapper = styled.tr`
+export const Wrapper = styled.tr`
   background-color: ${Colors.neutral[5]};
   & > td {
     padding: 16px;
@@ -14,7 +14,7 @@ export const MessageContentWrapper = styled.tr`
   }
 `;
 
-export const StyledSection = styled.div`
+export const Section = styled.div`
   padding: 0 16px;
   display: flex;
   gap: 1px;
diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/MessageContent/MessageContent.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/MessageContent/MessageContent.tsx
index 207d4dba72f..8ccb4937870 100644
--- a/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/MessageContent/MessageContent.tsx
+++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/MessageContent/MessageContent.tsx
@@ -2,25 +2,17 @@ import { TopicMessageTimestampTypeEnum } from 'generated-sources';
 import React from 'react';
 import JSONViewer from 'components/common/JSONViewer/JSONViewer';
 import { SecondaryTabs } from 'components/common/Tabs/SecondaryTabs.styled';
-import { isObject } from 'lodash';
 import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
 
-import {
-  ContentBox,
-  StyledSection,
-  MessageContentWrapper,
-  Metadata,
-  MetadataLabel,
-  MetadataMeta,
-  MetadataValue,
-  MetadataWrapper,
-} from './MessageContent.styled';
+import * as S from './MessageContent.styled';
 
 type Tab = 'key' | 'content' | 'headers';
 
 export interface MessageContentProps {
   messageKey?: string;
+  messageKeyFormat?: string;
   messageContent?: string;
+  messageContentFormat?: string;
   headers?: { [key: string]: string | undefined };
   timestamp?: Date;
   timestampType?: TopicMessageTimestampTypeEnum;
@@ -28,7 +20,9 @@ export interface MessageContentProps {
 
 const MessageContent: React.FC<MessageContentProps> = ({
   messageKey,
+  messageKeyFormat,
   messageContent,
+  messageContentFormat,
   headers,
   timestamp,
   timestampType,
@@ -58,25 +52,12 @@ const MessageContent: React.FC<MessageContentProps> = ({
   };
   const keySize = new TextEncoder().encode(messageKey).length;
   const contentSize = new TextEncoder().encode(messageContent).length;
-  const isContentJson = () => {
-    try {
-      return isObject(messageContent && JSON.parse(messageContent));
-    } catch {
-      return false;
-    }
-  };
-  const isKeyJson = () => {
-    try {
-      return isObject(messageKey && JSON.parse(messageKey));
-    } catch {
-      return false;
-    }
-  };
+
   return (
-    <MessageContentWrapper>
+    <S.Wrapper>
       <td colSpan={10}>
-        <StyledSection>
-          <ContentBox>
+        <S.Section>
+          <S.ContentBox>
             <SecondaryTabs>
               <button
                 type="button"
@@ -101,41 +82,39 @@ const MessageContent: React.FC<MessageContentProps> = ({
               </button>
             </SecondaryTabs>
             <JSONViewer data={activeTabContent() || ''} />
-          </ContentBox>
-          <MetadataWrapper>
-            <Metadata>
-              <MetadataLabel>Timestamp</MetadataLabel>
+          </S.ContentBox>
+          <S.MetadataWrapper>
+            <S.Metadata>
+              <S.MetadataLabel>Timestamp</S.MetadataLabel>
               <span>
-                <MetadataValue>{timestamp?.toLocaleString()}</MetadataValue>
-                <MetadataMeta>Timestamp type: {timestampType}</MetadataMeta>
+                <S.MetadataValue>{timestamp?.toLocaleString()}</S.MetadataValue>
+                <S.MetadataMeta>Timestamp type: {timestampType}</S.MetadataMeta>
               </span>
-            </Metadata>
+            </S.Metadata>
 
-            <Metadata>
-              <MetadataLabel>Content</MetadataLabel>
+            <S.Metadata>
+              <S.MetadataLabel>Content</S.MetadataLabel>
               <span>
-                <MetadataValue>
-                  {isContentJson() ? 'JSON' : 'Text'}
-                </MetadataValue>
-                <MetadataMeta>
+                <S.MetadataValue>{messageContentFormat}</S.MetadataValue>
+                <S.MetadataMeta>
                   Size: <BytesFormatted value={contentSize} />
-                </MetadataMeta>
+                </S.MetadataMeta>
               </span>
-            </Metadata>
+            </S.Metadata>
 
-            <Metadata>
-              <MetadataLabel>Key</MetadataLabel>
+            <S.Metadata>
+              <S.MetadataLabel>Key</S.MetadataLabel>
               <span>
-                <MetadataValue>{isKeyJson() ? 'JSON' : 'Text'}</MetadataValue>
-                <MetadataMeta>
+                <S.MetadataValue>{messageKeyFormat}</S.MetadataValue>
+                <S.MetadataMeta>
                   Size: <BytesFormatted value={keySize} />
-                </MetadataMeta>
+                </S.MetadataMeta>
               </span>
-            </Metadata>
-          </MetadataWrapper>
-        </StyledSection>
+            </S.Metadata>
+          </S.MetadataWrapper>
+        </S.Section>
       </td>
-    </MessageContentWrapper>
+    </S.Wrapper>
   );
 };
 
diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/MessageContent/__tests__/MessageContent.spec.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/MessageContent/__tests__/MessageContent.spec.tsx
index ad0f65380b4..2a085d97ce8 100644
--- a/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/MessageContent/__tests__/MessageContent.spec.tsx
+++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/MessageContent/__tests__/MessageContent.spec.tsx
@@ -15,7 +15,9 @@ const setupWrapper = (props?: Partial<MessageContentProps>) => {
       <tbody>
         <MessageContent
           messageKey='"test-key"'
+          messageKeyFormat="JSON"
           messageContent='{"data": "test"}'
+          messageContentFormat="AVRO"
           headers={{ header: 'test' }}
           timestamp={new Date(0)}
           timestampType={TopicMessageTimestampTypeEnum.CREATE_TIME}
@@ -32,6 +34,17 @@ describe('MessageContent screen', () => {
   beforeEach(() => {
     render(setupWrapper());
   });
+
+  describe('renders', () => {
+    it('key format in document', () => {
+      expect(screen.getByText('JSON')).toBeInTheDocument();
+    });
+
+    it('content format in document', () => {
+      expect(screen.getByText('AVRO')).toBeInTheDocument();
+    });
+  });
+
   describe('when switched to display the key', () => {
     it('has a tab with is-active classname', () => {
       const keyTab = screen.getAllByText('Key');


Test patch: