Skip to content

Commit

Permalink
[explorer] task: Added convert message to utf8 feature
Browse files Browse the repository at this point in the history
Problem: Unable convert message payload from hex to utf 8
Solution: Add a button, and the user can convert hex to utf 8 value.
  • Loading branch information
AnthonyLaw authored Jan 14, 2025
1 parent 7ef06fe commit 49dec96
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 3 deletions.
117 changes: 117 additions & 0 deletions __tests__/components/fileds/MessageField.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import MessageField from '../../../src/components/fields/MessageField.vue';
import UI from '../../../src/store/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';

const setupStoreMount = value => {
const uiModule = {
namespaced: true,
getters: {
getNameByKey: UI.getters.getNameByKey
}
};

const store = new Vuex.Store({
modules: {
ui: uiModule
}
});

return shallowMount(MessageField, {
store,
localVue,
propsData: {
value
}
});
};

const localVue = createLocalVue();
localVue.use(Vuex);

describe('MessageField component', () => {
it('renders props data', ()=> {
// Arrange + Act:
const wrapper = setupStoreMount({
type: 0,
payload: 'Hello, World!'
});

// Assert:
expect(wrapper.vm.message).toMatch('Hello, World!');
});

describe('Button convert message format', () => {
it('renders button when plain message payload is hex value', () => {
// Arrange + Act:
const wrapper = setupStoreMount({
type: 0,
payload: '48656C6F2066726F6D2073796D626F6C20736E6170'
});

// Assert:
expect(wrapper.find('.viewOptions').exists()).toBe(true);
});

it('convert hex message to utf-8 format when click on the button', () => {
// Arrange:
const wrapper = setupStoreMount({
type: 0,
payload: '48656C6F2066726F6D2073796D626F6C20736E6170'
});

// Act:
wrapper.find('.viewOptions').trigger('click');

// Assert:
expect(wrapper.vm.message).toMatch('Helo from symbol snap');
});

it('convert utf-8 message to hex format when click on the button', () => {
// Arrange:
const wrapper = setupStoreMount({
type: 0,
payload: '48656C6F2066726F6D2073796D626F6C20736E6170'
});

// first click to convert hex to utf-8
wrapper.find('.viewOptions').trigger('click');

// Act:
// second click to convert utf-8 to hex
wrapper.find('.viewOptions').trigger('click');

// Assert:
expect(wrapper.vm.message).toMatch('48656C6F2066726F6D2073796D626F6C20736E6170');
});

const assertConvertFormatButtonNotRender = value => {
// Arrange + Act:
const wrapper = setupStoreMount(value);

// Assert:
expect(wrapper.find('.viewOptions').exists()).toBe(false);
};

it('does not render convert message button when plain message payload is non hex value', () => {
assertConvertFormatButtonNotRender({
type: 0,
payload: 'Hello, World!'
});
});

it('does not render convert message format button if encrypted message', () => {
assertConvertFormatButtonNotRender({
type: 1,
payload: '48656C6F2066726F6D2073796D626F6C20736E6170'
});
});

it('does not render convert message button when plain message payload is empty', () => {
assertConvertFormatButtonNotRender({
type: 0,
payload: ''
});
});
});
});
4 changes: 4 additions & 0 deletions __tests__/config/jest.setup.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { TextDecoder, TextEncoder } from 'util';

/* Mock init http */
jest.mock('../../src/infrastructure/http', () => {
return {
Expand Down Expand Up @@ -31,3 +33,5 @@ jest.mock('../../src/infrastructure/http', () => {
timezone: 'Local'
};
});

Object.assign(global, { TextDecoder, TextEncoder });
56 changes: 53 additions & 3 deletions src/components/fields/MessageField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
<div>
<div v-if="isPlainMessage">
{{ message }}

<div v-if="isHexString">
<div
class="viewOptions"
@click="convertViewFormat">
{{ viewFormatTitle }}
</div>
</div>
</div>

<div v-else @click="clickToView">
Expand All @@ -36,7 +44,7 @@

<script>
import TableView from '@/components/tables/TableView.vue';
import { MessageType } from 'symbol-sdk';
import { MessageType, Convert } from 'symbol-sdk';
export default {
name: 'MessageField',
Expand All @@ -49,12 +57,13 @@ export default {
},
data () {
return {
isClick: true
isClick: true,
isViewAsUTF8: false
};
},
computed: {
message () {
return this.value.payload;
return this.getMessage();
},
messageType () {
return this.value.type;
Expand All @@ -64,11 +73,33 @@ export default {
},
title () {
return `Click to view ${this.getKeyName(`messageTypeDescriptor_${this.messageType}`)}`;
},
viewFormatTitle () {
return this.isViewAsUTF8 ? `View as default` : `View as utf-8`;
},
isHexString () {
return this.value.payload && Convert.isHexString(this.value.payload);
}
},
methods: {
clickToView () {
this.isClick = !this.isClick;
},
convertViewFormat () {
this.isViewAsUTF8 = !this.isViewAsUTF8;
},
getMessage () {
if (this.isViewAsUTF8) {
return this.convertToUtf8(this.value.payload);
}
return this.value.payload;
},
convertToUtf8 (payload) {
if (this.isHexString) {
const hexToUint8 = Convert.hexToUint8(payload);
return new TextDecoder('utf-8').decode(hexToUint8);
}
return payload;
}
}
};
Expand All @@ -90,4 +121,23 @@ export default {
text-decoration: underline;
}
}
.viewOptions {
display: flex;
justify-content: center;
margin-top: 10px;
max-width: 150px;
width: 100%;
border-radius: 5px;
border-width: 1px;
border-style: solid;
padding: 5px 10px;
border-color: var(--clickable-text);
color: var(--clickable-text);
:hover > & {
cursor: pointer;
text-decoration: underline;
}
}
</style>

0 comments on commit 49dec96

Please sign in to comment.