@farm-investimentos/front-mfe-components 11.6.1 → 11.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/front-mfe-components.common.js +5949 -5820
  2. package/dist/front-mfe-components.common.js.map +1 -1
  3. package/dist/front-mfe-components.css +1 -1
  4. package/dist/front-mfe-components.umd.js +5949 -5820
  5. package/dist/front-mfe-components.umd.js.map +1 -1
  6. package/dist/front-mfe-components.umd.min.js +1 -1
  7. package/dist/front-mfe-components.umd.min.js.map +1 -1
  8. package/package.json +1 -1
  9. package/src/components/Buttons/ConfirmButton/ConfirmButton.stories.js +4 -12
  10. package/src/components/Buttons/ConfirmButton/ConfirmButton.vue +5 -15
  11. package/src/components/Buttons/ConfirmButton/__tests__/ConfirmButton.spec.js +0 -19
  12. package/src/components/Buttons/DangerButton/DangerButton.stories.js +3 -1
  13. package/src/components/Buttons/DangerButton/DangerButton.vue +3 -9
  14. package/src/components/Buttons/DangerButton/__tests__/DangerButton.spec.js +0 -19
  15. package/src/components/CopyToClipboard/CopyToClipboard.stories.js +22 -0
  16. package/src/components/CopyToClipboard/CopyToClipboard.vue +9 -2
  17. package/src/components/MainFilter/MainFilter.scss +1 -1
  18. package/src/components/MainFilter/MainFilter.vue +14 -8
  19. package/src/components/MainFilter/__tests__/MainFilter.spec.js +4 -0
  20. package/src/components/ResourceMetaInfo/ResourceMetaInfo.scss +14 -0
  21. package/src/components/ResourceMetaInfo/ResourceMetaInfo.stories.js +119 -0
  22. package/src/components/ResourceMetaInfo/ResourceMetaInfo.vue +100 -0
  23. package/src/components/ResourceMetaInfo/__tests__/ResourceMetaInfo.spec.js +128 -0
  24. package/src/components/ResourceMetaInfo/index.ts +4 -0
  25. package/src/components/Tabs/Tabs.stories.js +11 -0
  26. package/src/components/TextFieldV2/TextFieldV2.scss +1 -1
  27. package/src/components/TextFieldV2/TextFieldV2.stories.js +25 -1
  28. package/src/components/TextFieldV2/TextFieldV2.vue +4 -2
  29. package/src/components/Tooltip/Tooltip.vue +4 -1
  30. package/src/components/Typography/BodyText/BodyText.stories.js +2 -2
  31. package/src/components/Typography/Caption/Caption.stories.js +2 -1
  32. package/src/components/Typography/Heading/Heading.stories.js +2 -1
  33. package/src/components/Typography/OverlayText/OverlayText.stories.js +2 -1
  34. package/src/components/Typography/Subtitle/Subtitle.stories.js +2 -3
  35. package/src/main.ts +2 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farm-investimentos/front-mfe-components",
3
- "version": "11.6.1",
3
+ "version": "11.7.0",
4
4
  "author": "farm investimentos",
5
5
  "private": false,
6
6
  "main": "./dist/front-mfe-components.common.js",
@@ -7,7 +7,8 @@ export default {
7
7
  docs: {
8
8
  description: {
9
9
  component: `Confirm button<br />
10
- selector: <em>farm-btn-confirm</em>
10
+ selector: <em>farm-btn-confirm</em><br />
11
+ <span style="color: var(--farm-primary-base);">ready for use</span>
11
12
  `,
12
13
  },
13
14
  },
@@ -16,22 +17,18 @@ export default {
16
17
  };
17
18
 
18
19
  export const Primary = () => ({
19
- components: { ConfirmButton },
20
20
  template: '<ConfirmButton>Confirm Button</ConfirmButton>',
21
21
  });
22
22
 
23
23
  export const HtmlMarkup = () => ({
24
- components: { ConfirmButton },
25
24
  template: '<ConfirmButton><em>I am italic</strong></em></ConfirmButton>',
26
25
  });
27
26
 
28
27
  export const Props = () => ({
29
- components: { ConfirmButton },
30
28
  template: '<ConfirmButton title="custom title">custom title (hover me)</ConfirmButton>',
31
29
  });
32
30
 
33
31
  export const Listener = () => ({
34
- components: { ConfirmButton },
35
32
  data() {
36
33
  return {
37
34
  x: 1,
@@ -48,11 +45,6 @@ export const Iconed = () => ({
48
45
  <ConfirmButton :icon="true">default icon</ConfirmButton>
49
46
  <ConfirmButton :icon="true" customIcon="information-outline">information-outline</ConfirmButton>
50
47
  <ConfirmButton :icon="true" customIcon="account-search">account-search</ConfirmButton>
48
+ <ConfirmButton :icon="true" customIcon="account-search" disabled>account-search</ConfirmButton>
51
49
  </div>`,
52
- });
53
-
54
- Primary.storyName = 'Básico';
55
- HtmlMarkup.storyName = 'Html Markup';
56
- Props.storyName = 'Props';
57
- Listener.storyName = 'Listener';
58
- Iconed.storyName = 'Icon';
50
+ });
@@ -1,6 +1,8 @@
1
1
  <template>
2
2
  <farm-btn v-bind="$attrs" v-on="$listeners">
3
- <i :class="{ mdi: true, [iconPath]: true, 'mr-3': true }" v-if="icon"></i>
3
+ <farm-icon v-if="icon" class="'mr-3">
4
+ {{ customIcon }}
5
+ </farm-icon>
4
6
  <slot></slot>
5
7
  </farm-btn>
6
8
  </template>
@@ -23,21 +25,9 @@ export default Vue.extend({
23
25
  */
24
26
  customIcon: {
25
27
  type: String,
26
- default: '',
27
- },
28
- },
29
- computed: {
30
- iconPath() {
31
- if (!this.customIcon) {
32
- return 'mdi-check';
33
- }
34
- return `mdi-${this.customIcon}`;
28
+ default: 'check',
35
29
  },
36
30
  },
37
31
  });
38
32
  </script>
39
- <style lang="scss" scoped>
40
- i.mdi {
41
- font-size: 1rem;
42
- }
43
- </style>
33
+
@@ -3,31 +3,12 @@ import ConfirmButton from '../ConfirmButton';
3
3
 
4
4
  describe('ConfirmButton component', () => {
5
5
  let wrapper;
6
- let component;
7
6
 
8
7
  beforeEach(() => {
9
8
  wrapper = shallowMount(ConfirmButton);
10
- component = wrapper.vm;
11
9
  });
12
10
 
13
11
  test('Created hook', () => {
14
12
  expect(wrapper).toBeDefined();
15
13
  });
16
-
17
- describe('Computed properties', () => {
18
- it('Should return default icon', () => {
19
- wrapper.setProps({
20
- icon: true,
21
- });
22
- expect(component.iconPath).toEqual('mdi-check');
23
- });
24
-
25
- it('Should return custom icon', async () => {
26
- await wrapper.setProps({
27
- icon: true,
28
- customIcon: 'information',
29
- });
30
- expect(component.iconPath).toEqual('mdi-information');
31
- });
32
- });
33
14
  });
@@ -7,7 +7,8 @@ export default {
7
7
  docs: {
8
8
  description: {
9
9
  component: `Danger button<br />
10
- selector: <em>farm-btn-fanger</em>
10
+ selector: <em>farm-btn-fanger</em><br />
11
+ <span style="color: var(--farm-primary-base);">ready for use</span>
11
12
  `,
12
13
  },
13
14
  },
@@ -43,5 +44,6 @@ export const Iconed = () => ({
43
44
  <farm-btn-danger :icon="true">default icon</farm-btn-danger>
44
45
  <farm-btn-danger :icon="true" customIcon="information-outline">information-outline</farm-btn-danger>
45
46
  <farm-btn-danger :icon="true" customIcon="account-search">account-search</farm-btn-danger>
47
+ <farm-btn-danger :icon="true" customIcon="account-search" disabled>account-search</farm-btn-danger>
46
48
  </div>`,
47
49
  });
@@ -1,6 +1,8 @@
1
1
  <template>
2
2
  <farm-btn v-bind="$attrs" v-on="$listeners" color="error">
3
- <i v-if="icon" :class="{mdi: true, [iconPath]: true, 'mr-3': true}"></i>
3
+ <farm-icon v-if="icon" class="'mr-3">
4
+ {{ customIcon }}
5
+ </farm-icon>
4
6
  <slot></slot>
5
7
  </farm-btn>
6
8
  </template>
@@ -26,13 +28,5 @@ export default Vue.extend({
26
28
  default: '',
27
29
  },
28
30
  },
29
- computed: {
30
- iconPath(): string {
31
- if (!this.customIcon) {
32
- return 'mdi-trash-can-outline';
33
- }
34
- return `mdi-${this.customIcon}`;
35
- },
36
- },
37
31
  });
38
32
  </script>
@@ -3,31 +3,12 @@ import DangerButton from '../DangerButton';
3
3
 
4
4
  describe('DangerButton component', () => {
5
5
  let wrapper;
6
- let component;
7
6
 
8
7
  beforeEach(() => {
9
8
  wrapper = shallowMount(DangerButton);
10
- component = wrapper.vm;
11
9
  });
12
10
 
13
11
  test('Created hook', () => {
14
12
  expect(wrapper).toBeDefined();
15
13
  });
16
-
17
- describe('Computed properties', () => {
18
- it('Should return default icon', () => {
19
- wrapper.setProps({
20
- icon: true,
21
- });
22
- expect(component.iconPath).toEqual('mdi-trash-can-outline');
23
- });
24
-
25
- it('Should return custom icon', async () => {
26
- await wrapper.setProps({
27
- icon: true,
28
- customIcon: 'information',
29
- });
30
- expect(component.iconPath).toEqual('mdi-information');
31
- });
32
- });
33
14
  });
@@ -41,3 +41,25 @@ export const CustomTooltipColor = () => ({
41
41
  <farm-copytoclipboard toCopy="To be copied" tooltip-color="info" />
42
42
  </div>`,
43
43
  });
44
+
45
+ export const Modal = () => ({
46
+ data() {
47
+ return {
48
+ value: false,
49
+ };
50
+ },
51
+ template: `<div>
52
+ <farm-btn @click="value = true">abrir</farm-btn>
53
+ <farm-modal v-model="value">
54
+ <template v-slot:content>
55
+ <farm-copytoclipboard toCopy="To be copied" :isIcon="false" />
56
+ </template>
57
+ </farm-modal>
58
+ </div>`,
59
+ });
60
+
61
+ export const SuccessTimeout = () => ({
62
+ template: `<div style="max-width: 480px; padding-top: 80px; padding-left: 80px;">
63
+ <farm-copytoclipboard toCopy="To be copied" success-timeout="5000" />
64
+ </div>`,
65
+ });
@@ -53,12 +53,19 @@ export default Vue.extend({
53
53
  >,
54
54
  default: 'secondary',
55
55
  },
56
+ /**
57
+ * Success message timeout (in ms)
58
+ */
59
+ successTimeout: {
60
+ type: [Number, String],
61
+ default: 2000,
62
+ },
56
63
  },
57
64
  setup(props) {
58
65
  const show = ref(false);
59
66
  const feedbackMessage = ref('');
60
67
  const disabled = ref(false);
61
- const { toCopy, isIcon, successMessage } = toRefs(props);
68
+ const { toCopy, isIcon, successMessage, successTimeout } = toRefs(props);
62
69
 
63
70
  const onClick = async () => {
64
71
  disabled.value = true;
@@ -73,7 +80,7 @@ export default Vue.extend({
73
80
  setTimeout(() => {
74
81
  show.value = false;
75
82
  disabled.value = false;
76
- }, 2000);
83
+ }, successTimeout.value);
77
84
  };
78
85
 
79
86
  return {
@@ -3,7 +3,7 @@ section {
3
3
  flex-direction: row;
4
4
 
5
5
  .farm-btn {
6
- margin-left: 1rem;
6
+ margin-left: 16px;
7
7
  }
8
8
 
9
9
  fieldset {
@@ -12,7 +12,7 @@
12
12
  </template>
13
13
  </farm-tooltip>
14
14
  </farm-label>
15
- <farm-textfield v-model="inputValue" :id="elementId" @keyup="onKeyUp" />
15
+ <farm-textfield-v2 v-model="inputValue" :id="elementId" @keyup="onKeyUp" />
16
16
  </fieldset>
17
17
  <farm-btn
18
18
  v-if="hasExtraFilters"
@@ -64,6 +64,9 @@ export default Vue.extend({
64
64
  type: String,
65
65
  default: '',
66
66
  },
67
+ /**
68
+ * Toggle filters
69
+ */
67
70
  showFilters: {
68
71
  type: Boolean,
69
72
  default: false,
@@ -100,18 +103,20 @@ export default Vue.extend({
100
103
  onFilterClick() {
101
104
  this.$emit('onClick');
102
105
  },
106
+ isInvalidKey(keyCode: Number) {
107
+ return (
108
+ (keyCode < 48 && keyCode !== 8 && keyCode !== 46) ||
109
+ (keyCode > 90 && keyCode < 96 && keyCode !== 91) ||
110
+ (keyCode > 105 && keyCode < 186)
111
+ );
112
+ },
103
113
  onKeyUp(event: KeyboardEvent) {
104
114
  const keyCode = event.keyCode;
105
115
  if (keyCode === 13) {
106
116
  this.$emit('onEnter', (event.target as HTMLInputElement).value);
107
117
  return false;
108
118
  }
109
-
110
- if (
111
- (keyCode < 48 && keyCode !== 8 && keyCode !== 46) ||
112
- (keyCode > 90 && keyCode < 96 && keyCode !== 91) ||
113
- (keyCode > 105 && keyCode < 186)
114
- ) {
119
+ if (this.isInvalidKey(keyCode)) {
115
120
  return false;
116
121
  }
117
122
  if (this.timer) {
@@ -119,7 +124,8 @@ export default Vue.extend({
119
124
  this.timer = null;
120
125
  }
121
126
  this.timer = setTimeout(() => {
122
- this.$emit('onInputChange', (event.target as HTMLInputElement).value);
127
+ console.log(this.inputValue);
128
+ this.$emit('onInputChange', this.inputValue);
123
129
  }, 750);
124
130
  },
125
131
  },
@@ -19,6 +19,10 @@ describe('MainFilter component', () => {
19
19
  component.onFilterClick();
20
20
  expect(wrapper.emitted().onClick).toBeTruthy();
21
21
  });
22
+
23
+ it('Should check if keyCode is valid', () => {
24
+ expect(component.isInvalidKey(120)).toBeTruthy();
25
+ });
22
26
  });
23
27
 
24
28
  describe('computed properties', () => {
@@ -0,0 +1,14 @@
1
+ .farm-resource-metainfo {
2
+ display: inline-flex;
3
+ flex-direction: column;
4
+ gap: 8px;
5
+
6
+ & div {
7
+ align-items: center;
8
+ display: inline-flex;
9
+
10
+ & .farm-icon {
11
+ margin-right: 8px;
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,119 @@
1
+ import ResourceMetaInfo from './ResourceMetaInfo.vue';
2
+
3
+ export default {
4
+ title: 'Display/ResourceMetaInfo',
5
+ component: ResourceMetaInfo,
6
+ parameters: {
7
+ docs: {
8
+ description: {
9
+ component: `ResourceMetaInfo<br />
10
+ selector: <em>farm-resource-metainfo</em><br />
11
+ <span style="color: var(--farm-primary-base);">ready for use</span>
12
+ `,
13
+ },
14
+ },
15
+ viewMode: 'docs',
16
+ },
17
+ };
18
+
19
+ export const Primary = () => ({
20
+ data() {
21
+ return {
22
+ value: false,
23
+ info: {
24
+ createdAt: '21/10/2022',
25
+ updatedAt: '21/10/2022',
26
+ username: 'Test User',
27
+ updatedHours: '10:10:10',
28
+ },
29
+ };
30
+ },
31
+ template: `<div>
32
+ <farm-resource-metainfo :infos="info" />
33
+ </div>`,
34
+ });
35
+
36
+ export const WithoutUpdate = () => ({
37
+ data() {
38
+ return {
39
+ value: false,
40
+ info: {
41
+ createdAt: '21/10/2022',
42
+ updatedAt: null,
43
+ username: 'Test User',
44
+ updatedHours: '10:10:10',
45
+ },
46
+ };
47
+ },
48
+ template: `<div>
49
+ <farm-resource-metainfo :infos="info" />
50
+ </div>`,
51
+ });
52
+
53
+ export const WithoutCreate = () => ({
54
+ data() {
55
+ return {
56
+ value: false,
57
+ info: {
58
+ createdAt: null,
59
+ updatedAt: '21/10/2022',
60
+ username: 'Test User',
61
+ updatedHours: '10:10:10',
62
+ },
63
+ };
64
+ },
65
+ template: `<div>
66
+ <farm-resource-metainfo :infos="info" />
67
+ </div>`,
68
+ });
69
+
70
+ export const ShowUpdateWithNA = () => ({
71
+ data() {
72
+ return {
73
+ value: false,
74
+ info: {
75
+ createdAt: null,
76
+ updatedAt: null,
77
+ username: null,
78
+ updatedHours: null,
79
+ },
80
+ };
81
+ },
82
+ template: `<div>
83
+ <farm-resource-metainfo :infos="info" show-empty-update />
84
+ </div>`,
85
+ });
86
+
87
+ export const ShowCreateWithNA = () => ({
88
+ data() {
89
+ return {
90
+ value: false,
91
+ info: {
92
+ createdAt: null,
93
+ updatedAt: null,
94
+ username: null,
95
+ updatedHours: null,
96
+ },
97
+ };
98
+ },
99
+ template: `<div>
100
+ <farm-resource-metainfo :infos="info" show-empty-create />
101
+ </div>`,
102
+ });
103
+
104
+ export const ShowBothWithNA = () => ({
105
+ data() {
106
+ return {
107
+ value: false,
108
+ info: {
109
+ createdAt: null,
110
+ updatedAt: null,
111
+ username: null,
112
+ updatedHours: null,
113
+ },
114
+ };
115
+ },
116
+ template: `<div>
117
+ <farm-resource-metainfo :infos="info" show-empty-create show-empty-update />
118
+ </div>`,
119
+ });
@@ -0,0 +1,100 @@
1
+ <template>
2
+ <div class="farm-resource-metainfo">
3
+ <div v-if="showCreate">
4
+ <farm-icon color="gray" size="14">calendar-blank</farm-icon>
5
+ <farm-caption color="gray" tag="p" variation="regular"
6
+ >Data de cadastro:
7
+ <farm-caption color="gray" variation="medium" tag="span">{{
8
+ formattedCreatedAt
9
+ }}</farm-caption>
10
+ </farm-caption>
11
+ </div>
12
+ <div v-if="showUpdate">
13
+ <farm-icon color="gray" size="14">history</farm-icon>
14
+
15
+ <farm-caption color="gray" tag="p" variation="regular"
16
+ >Última atualização feita por
17
+ <farm-caption color="gray" variation="medium" tag="span">{{
18
+ formattedUsername
19
+ }}</farm-caption
20
+ >, dia
21
+ <farm-caption color="gray" variation="medium" tag="span">{{
22
+ formattedUpdatedAt
23
+ }}</farm-caption>
24
+ às
25
+ <farm-caption color="gray" variation="medium" tag="span">{{
26
+ formattedUpdatedHours
27
+ }}</farm-caption>
28
+ </farm-caption>
29
+ </div>
30
+ </div>
31
+ </template>
32
+ <script lang="ts">
33
+ import Vue, { computed, PropType, toRefs } from 'vue';
34
+ import Icon from '../Icon';
35
+ import { Caption } from '../Typography';
36
+
37
+ interface ResourceMetaInfoProps {
38
+ createdAt: string;
39
+ updatedAt: string;
40
+ username: string;
41
+ updatedHours: string;
42
+ }
43
+
44
+ export default Vue.extend({
45
+ name: 'farm-resource-metainfo',
46
+ components: {
47
+ 'farm-icon': Icon,
48
+ 'farm-caption': Caption,
49
+ },
50
+ props: {
51
+ infos: {
52
+ required: true,
53
+ type: Object as PropType<ResourceMetaInfoProps>,
54
+ },
55
+ showEmptyCreate: {
56
+ type: Boolean,
57
+ default: false,
58
+ },
59
+ showEmptyUpdate: {
60
+ type: Boolean,
61
+ default: false,
62
+ },
63
+ },
64
+ setup(props) {
65
+ const { infos, showEmptyCreate, showEmptyUpdate } = toRefs(props);
66
+
67
+ const showUpdate = computed(
68
+ () =>
69
+ (infos.value.updatedAt !== null && infos.value.updatedAt !== undefined) ||
70
+ showEmptyUpdate.value
71
+ );
72
+
73
+ const showCreate = computed(
74
+ () =>
75
+ (infos.value.createdAt !== null && infos.value.createdAt !== undefined) ||
76
+ showEmptyCreate.value
77
+ );
78
+
79
+ const formattedCreatedAt = computed(() => infos.value.createdAt || 'N/A');
80
+
81
+ const formattedUpdatedAt = computed(() => infos.value.updatedAt || 'N/A');
82
+
83
+ const formattedUsername = computed(() => infos.value.username || 'N/A');
84
+
85
+ const formattedUpdatedHours = computed(() => infos.value.updatedHours || 'N/A');
86
+
87
+ return {
88
+ showUpdate,
89
+ showCreate,
90
+ formattedCreatedAt,
91
+ formattedUpdatedAt,
92
+ formattedUsername,
93
+ formattedUpdatedHours,
94
+ };
95
+ },
96
+ });
97
+ </script>
98
+ <style lang="scss" scoped>
99
+ @import 'ResourceMetaInfo.scss';
100
+ </style>
@@ -0,0 +1,128 @@
1
+ import { shallowMount } from '@vue/test-utils';
2
+ import ResourceMetaInfo from '../ResourceMetaInfo.vue';
3
+
4
+ describe('ResourceMetaInfo component', () => {
5
+ let wrapper;
6
+ let component;
7
+
8
+ beforeEach(() => {
9
+ wrapper = shallowMount(ResourceMetaInfo, {
10
+ propsData: {
11
+ infos: {
12
+ createdAt: '21/10/2022',
13
+ updatedAt: '21/10/2022',
14
+ username: 'Test User',
15
+ updatedHours: '10:10:10',
16
+ },
17
+ },
18
+ });
19
+
20
+ component = wrapper.vm;
21
+ });
22
+
23
+ test('Created hook', () => {
24
+ expect(wrapper).toBeDefined();
25
+ });
26
+
27
+ describe('mount component', () => {
28
+ it('renders correctly', () => {
29
+ expect(wrapper.element).toMatchSnapshot();
30
+ });
31
+ });
32
+
33
+ describe('Computed', () => {
34
+ describe('showUpdate', () => {
35
+ it('should return true when it has an update date', () => {
36
+ expect(component.showUpdate).toBeTruthy();
37
+ });
38
+
39
+ it('should return false when it has not an update date', async () => {
40
+ await wrapper.setProps({
41
+ infos: { updatedAt: null },
42
+ });
43
+ expect(component.showUpdate).toBeFalsy();
44
+ });
45
+
46
+ it('should return true when it has not an update date but showEmptyUpdate is true', async () => {
47
+ await wrapper.setProps({
48
+ infos: { updatedAt: null },
49
+ showEmptyUpdate: true,
50
+ });
51
+ expect(component.showUpdate).toBeTruthy();
52
+ });
53
+ });
54
+
55
+ describe('showCreate', () => {
56
+ it('should return true when it has an create date', () => {
57
+ expect(component.showCreate).toBeTruthy();
58
+ });
59
+
60
+ it('should return false when it has not an create date', async () => {
61
+ await wrapper.setProps({
62
+ infos: { createAt: null },
63
+ });
64
+ expect(component.showCreate).toBeFalsy();
65
+ });
66
+
67
+ it('should return true when it has not an update date but showEmptyCreate is true', async () => {
68
+ await wrapper.setProps({
69
+ infos: { createAt: null },
70
+ showEmptyCreate: true,
71
+ });
72
+ expect(component.showCreate).toBeTruthy();
73
+ });
74
+ });
75
+
76
+ describe('formattedCreatedAt', () => {
77
+ it('should return infos createdAt', () => {
78
+ expect(component.formattedCreatedAt).toBe('21/10/2022');
79
+ });
80
+
81
+ it('should return N/A when infos createdAt is empty', async () => {
82
+ await wrapper.setProps({
83
+ infos: { createAt: null },
84
+ });
85
+ expect(component.formattedCreatedAt).toBe('N/A');
86
+ });
87
+ });
88
+
89
+ describe('formattedUpdatedAt', () => {
90
+ it('should return infos updatedAt', () => {
91
+ expect(component.formattedUpdatedAt).toBe('21/10/2022');
92
+ });
93
+
94
+ it('should return N/A when infos updatedAt is empty', async () => {
95
+ await wrapper.setProps({
96
+ infos: { updatedAt: null },
97
+ });
98
+ expect(component.formattedUpdatedAt).toBe('N/A');
99
+ });
100
+ });
101
+
102
+ describe('formattedUsername', () => {
103
+ it('should return infos updatedAt', () => {
104
+ expect(component.formattedUsername).toBe('Test User');
105
+ });
106
+
107
+ it('should return N/A when infos username is empty', async () => {
108
+ await wrapper.setProps({
109
+ infos: { username: null },
110
+ });
111
+ expect(component.formattedUsername).toBe('N/A');
112
+ });
113
+ });
114
+
115
+ describe('formattedUpdatedHours', () => {
116
+ it('should return infos updatedHours', () => {
117
+ expect(component.formattedUpdatedHours).toBe('10:10:10');
118
+ });
119
+
120
+ it('should return N/A when infos updatedHours is empty', async () => {
121
+ await wrapper.setProps({
122
+ infos: { updatedHours: null },
123
+ });
124
+ expect(component.formattedUpdatedHours).toBe('N/A');
125
+ });
126
+ });
127
+ });
128
+ });