@controleonline/ui-customers 1.0.81

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 (102) hide show
  1. package/.github/agents/developer.agent.md +30 -0
  2. package/.github/agents/devops.agent.md +30 -0
  3. package/.github/agents/qa.agent.md +30 -0
  4. package/.github/agents/security.agent.md +30 -0
  5. package/.scrutinizer.yml +20 -0
  6. package/AGENTS.md +50 -0
  7. package/FUNDING.yml +1 -0
  8. package/README.md +23 -0
  9. package/docs/technical/Client-Details-Franquia-Filial.md +18 -0
  10. package/docs/technical/Client-Details-People-Name-Case.md +103 -0
  11. package/docs/technical/Cliente-Vendedor-Vinculo-e-Permissoes.md +152 -0
  12. package/docs/wiki.md +1 -0
  13. package/package.json +32 -0
  14. package/scripts/validate-wiki-pointer.cjs +13 -0
  15. package/src/react/components/tabs/AddressesTab.js +494 -0
  16. package/src/react/components/tabs/CategoriesTab.js +196 -0
  17. package/src/react/components/tabs/ClassificationChips.js +494 -0
  18. package/src/react/components/tabs/ContactTab.js +621 -0
  19. package/src/react/components/tabs/ContactTab.styles.js +119 -0
  20. package/src/react/components/tabs/ContractsTab.js +13 -0
  21. package/src/react/components/tabs/DocumentsTab.js +463 -0
  22. package/src/react/components/tabs/DocumentsTab.styles.js +133 -0
  23. package/src/react/components/tabs/EmployeeContactRow.js +83 -0
  24. package/src/react/components/tabs/EmployeesTab.js +454 -0
  25. package/src/react/components/tabs/EmployeesTab.styles.js +172 -0
  26. package/src/react/components/tabs/FiscalTab.js +6 -0
  27. package/src/react/components/tabs/FranchiseCommissionSection.js +307 -0
  28. package/src/react/components/tabs/FranchiseLinksManageModal.js +215 -0
  29. package/src/react/components/tabs/FranchiseLinksTab.js +282 -0
  30. package/src/react/components/tabs/GeneralTab.js +466 -0
  31. package/src/react/components/tabs/GeneralTab.styles.js +101 -0
  32. package/src/react/components/tabs/MediaTab.js +356 -0
  33. package/src/react/components/tabs/PeopleCategoriesPanel.js +601 -0
  34. package/src/react/components/tabs/ProductsTab.js +236 -0
  35. package/src/react/components/tabs/ProductsTab.styles.js +143 -0
  36. package/src/react/components/tabs/SalesmanCommissionBlock.js +120 -0
  37. package/src/react/components/tabs/SalesmanManageModal.js +208 -0
  38. package/src/react/components/tabs/SalesmanTab.js +436 -0
  39. package/src/react/components/tabs/SalesmanTab.styles.js +4 -0
  40. package/src/react/components/tabs/UserApiKeyModal.js +90 -0
  41. package/src/react/components/tabs/UserFormModal.js +301 -0
  42. package/src/react/components/tabs/UsersTab.js +426 -0
  43. package/src/react/components/tabs/UsersTab.styles.js +283 -0
  44. package/src/react/components/tabs/UsersTab.styles.test.js +42 -0
  45. package/src/react/components/tabs/contactMutationMessage.js +18 -0
  46. package/src/react/components/tabs/employeeContacts.js +214 -0
  47. package/src/react/components/tabs/employeeUnlink.js +68 -0
  48. package/src/react/components/tabs/employeesTabHelpers.js +227 -0
  49. package/src/react/components/tabs/franchiseCommissionHelpers.js +134 -0
  50. package/src/react/components/tabs/franchiseLinksTab.helpers.js +247 -0
  51. package/src/react/components/tabs/generalTabHelpers.js +120 -0
  52. package/src/react/components/tabs/salesmanTab.helpers.js +114 -0
  53. package/src/react/components/tabs/salesmanTabHelpers.js +173 -0
  54. package/src/react/components/tabs/salesmanTabMedia.js +55 -0
  55. package/src/react/components/tabs/salesmanTabSession.js +39 -0
  56. package/src/react/components/tabs/useEmployeeUnlink.js +58 -0
  57. package/src/react/components/tabs/useFranchiseLinksManage.js +215 -0
  58. package/src/react/components/tabs/useSalesmanManage.js +222 -0
  59. package/src/react/components/tabs/usersTabHelpers.js +221 -0
  60. package/src/react/domain/productSupplierFlow.js +37 -0
  61. package/src/react/index.js +4 -0
  62. package/src/react/pages/ClientDetailsSkeleton.js +84 -0
  63. package/src/react/pages/clientDetailsHelpers.js +17 -0
  64. package/src/react/pages/clients.js +27 -0
  65. package/src/react/pages/details.js +529 -0
  66. package/src/react/pages/details.page.styles.js +105 -0
  67. package/src/react/pages/details.styles.js +15 -0
  68. package/src/react/pages/employees.js +69 -0
  69. package/src/react/pages/franchisees.js +30 -0
  70. package/src/react/pages/prospects.js +21 -0
  71. package/src/react/pages/provider.js +21 -0
  72. package/src/react/router/routes.js +104 -0
  73. package/src/react/styles/details.js +571 -0
  74. package/src/store/people_categories/index.js +72 -0
  75. package/src/tests/browser/manager/client-details-create-user.spec.js +321 -0
  76. package/src/tests/browser/manager/client-details-employee-unlink.spec.js +215 -0
  77. package/src/tests/browser/manager/client-details-employees-refresh.spec.js +271 -0
  78. package/src/tests/browser/manager/client-details-enable.spec.js +241 -0
  79. package/src/tests/browser/manager/client-details-fiscal-tabs.spec.js +410 -0
  80. package/src/tests/browser/manager/client-details-franchise-commission.spec.js +318 -0
  81. package/src/tests/browser/manager/client-details-franchise-links.spec.js +365 -0
  82. package/src/tests/browser/manager/client-details-media.spec.js +405 -0
  83. package/src/tests/browser/manager/client-details-relationships.spec.js +313 -0
  84. package/src/tests/browser/manager/client-details-salesman-commission.spec.js +291 -0
  85. package/src/tests/browser/manager/client-details-salesman-manage.spec.js +448 -0
  86. package/src/tests/react/components/tabs/contactMutationMessage.test.js +25 -0
  87. package/src/tests/react/components/tabs/employeeContacts.test.js +266 -0
  88. package/src/tests/react/components/tabs/employeeUnlink.test.js +67 -0
  89. package/src/tests/react/components/tabs/employeesTabHelpers.media.test.js +78 -0
  90. package/src/tests/react/components/tabs/employeesTabHelpers.test.js +64 -0
  91. package/src/tests/react/components/tabs/fiscalTabContract.test.mjs +29 -0
  92. package/src/tests/react/components/tabs/franchiseCommissionHelpers.test.js +128 -0
  93. package/src/tests/react/components/tabs/franchiseLinksTab.helpers.test.mjs +166 -0
  94. package/src/tests/react/components/tabs/generalTabHelpers.test.js +130 -0
  95. package/src/tests/react/components/tabs/peopleMediaTabs.test.js +322 -0
  96. package/src/tests/react/components/tabs/salesmanTab.helpers.test.mjs +75 -0
  97. package/src/tests/react/components/tabs/salesmanTabHelpers.test.js +142 -0
  98. package/src/tests/react/components/tabs/salesmanTabHelpers.test.mjs +92 -0
  99. package/src/tests/react/components/tabs/usersTabHelpers.test.js +59 -0
  100. package/src/tests/react/domain/productSupplierFlow.test.mjs +55 -0
  101. package/src/tests/react/pages/clientDetailsHelpers.test.js +98 -0
  102. package/src/tests/react/pages/employees.test.js +44 -0
@@ -0,0 +1,448 @@
1
+ const {expect, test} = require('playwright/test');
2
+ const {API_ORIGIN} = require('../../../../../../../src/tests/browser/apiOrigin');
3
+ const {version: appVersion} = require('../../../../../../../package.json');
4
+
5
+ const CORS_HEADERS = {
6
+ 'access-control-allow-origin': '*',
7
+ 'access-control-allow-headers':
8
+ 'API-TOKEN, APP-DOMAIN, DEVICE, ACCEPT, CONTENT-TYPE, X-Requested-With',
9
+ 'access-control-allow-methods': 'GET,POST,PUT,PATCH,DELETE,OPTIONS',
10
+ };
11
+
12
+ const jsonHeaders = () => ({
13
+ ...CORS_HEADERS,
14
+ 'content-type': 'application/ld+json; charset=utf-8',
15
+ });
16
+
17
+ const collection = member => ({
18
+ member,
19
+ 'hydra:member': member,
20
+ totalItems: member.length,
21
+ 'hydra:totalItems': member.length,
22
+ });
23
+
24
+ const themeColors = {
25
+ primary: '#1C8FBD',
26
+ secondary: '#0169D9',
27
+ background: '#F3F7FB',
28
+ text: '#0F172A',
29
+ textSecondary: '#6C7787',
30
+ border: '#D7E1EC',
31
+ headerBackground: '#F3F7FB',
32
+ headerBorder: '#D7E1EC',
33
+ headerText: '#0F172A',
34
+ cardBackground: '#FFFFFF',
35
+ cardBorder: '#D7E1EC',
36
+ cardText: '#0F172A',
37
+ cardIcon: '#1C8FBD',
38
+ cardShadow: '#1C8FBD',
39
+ listItemBackground: '#F1F8FB',
40
+ listItemText: '#0F172A',
41
+ listItemSubtitleText: '#6C7787',
42
+ loadingSpinner: '#1C8FBD',
43
+ buttonBackground: '#1C8FBD',
44
+ buttonBorder: '#1C8FBD',
45
+ buttonIcon: '#FFFFFF',
46
+ buttonText: '#FFFFFF',
47
+ buttonShadow: '#1C8FBD',
48
+ buttonBackgroundSecondary: '#FFFFFF',
49
+ buttonBorderSecondary: '#D7E1EC',
50
+ buttonIconSecondary: '#0169D9',
51
+ buttonTextSecondary: '#0169D9',
52
+ buttonDisabledBackground: '#CBD5E1',
53
+ tabBarBackground: '#FFFFFF',
54
+ tabBarBorder: '#D7E1EC',
55
+ menuSelectedBorder: '#1C8FBD',
56
+ menuSelectedText: '#1C8FBD',
57
+ pageBackground: '#F3F7FB',
58
+ modalOverlay: 'rgba(15,23,42,0.45)',
59
+ modalBackground: '#FFFFFF',
60
+ modalText: '#0F172A',
61
+ modalShadow: '#1C8FBD',
62
+ inputBackground: '#FFFFFF',
63
+ inputBorder: '#D7E1EC',
64
+ };
65
+
66
+ const company = {
67
+ '@id': '/people/2',
68
+ id: 2,
69
+ name: 'CONTROLE ONLINE',
70
+ alias: 'CONTROLE ONLINE',
71
+ panel_enabled: true,
72
+ enabled: true,
73
+ commercial_enabled: true,
74
+ theme: {colors: themeColors},
75
+ configs: {},
76
+ };
77
+
78
+ const client = {
79
+ '@id': '/people/29',
80
+ id: 29,
81
+ name: 'LAVE GO FRANQUIAS LTDA',
82
+ alias: 'LAVE-GO',
83
+ peopleType: 'J',
84
+ enable: true,
85
+ };
86
+
87
+ const sellerLinked = {
88
+ '@id': '/people/40',
89
+ id: 40,
90
+ name: 'VENDEDOR VINCULADO',
91
+ alias: 'VINC',
92
+ peopleType: 'F',
93
+ };
94
+
95
+ const sellerAvailable = {
96
+ '@id': '/people/42',
97
+ id: 42,
98
+ name: 'VENDEDOR DISPONIVEL',
99
+ alias: 'DISP',
100
+ peopleType: 'F',
101
+ };
102
+
103
+ /**
104
+ * Stateful mock for manage CRUD: list, create, update, delete people_links.
105
+ */
106
+ const mockManagerApi = async (page, {appType = 'MANAGER', roles = ['ROLE_SUPER']} = {}) => {
107
+ const linksState = [
108
+ {
109
+ '@id': '/people_links/501',
110
+ id: 501,
111
+ company: sellerLinked,
112
+ people: client,
113
+ linkType: 'sellers-client',
114
+ comission: 10,
115
+ minimum_comission: 2,
116
+ },
117
+ ];
118
+ let nextId = 600;
119
+
120
+ await page.route(`${API_ORIGIN}/**`, async route => {
121
+ const request = route.request();
122
+ const url = new URL(request.url());
123
+ const pathname = url.pathname.replace(/^\/+/, '');
124
+ const method = request.method();
125
+
126
+ if (method === 'OPTIONS') {
127
+ return route.fulfill({status: 204, headers: CORS_HEADERS, body: ''});
128
+ }
129
+
130
+ if (pathname === 'people/29' || pathname === 'people/29/') {
131
+ return route.fulfill({
132
+ status: 200,
133
+ headers: jsonHeaders(),
134
+ body: JSON.stringify(client),
135
+ });
136
+ }
137
+
138
+ if (pathname === 'people' || pathname.startsWith('people?')) {
139
+ const query = Object.fromEntries(url.searchParams);
140
+ // Available salesmen for company (link.linkType=salesman)
141
+ if (query['link.linkType'] === 'salesman' || query.linkType === 'salesman') {
142
+ return route.fulfill({
143
+ status: 200,
144
+ headers: jsonHeaders(),
145
+ body: JSON.stringify(collection([sellerLinked, sellerAvailable])),
146
+ });
147
+ }
148
+ return route.fulfill({
149
+ status: 200,
150
+ headers: jsonHeaders(),
151
+ body: JSON.stringify(collection([client])),
152
+ });
153
+ }
154
+
155
+ if (pathname === 'people_links' || pathname.startsWith('people_links')) {
156
+ const query = Object.fromEntries(url.searchParams);
157
+
158
+ if (method === 'GET') {
159
+ if (query.linkType === 'sellers-client') {
160
+ return route.fulfill({
161
+ status: 200,
162
+ headers: jsonHeaders(),
163
+ body: JSON.stringify(collection([...linksState])),
164
+ });
165
+ }
166
+ if (query.linkType === 'salesman') {
167
+ return route.fulfill({
168
+ status: 200,
169
+ headers: jsonHeaders(),
170
+ body: JSON.stringify(
171
+ collection([
172
+ {
173
+ '@id': '/people_links/601',
174
+ id: 601,
175
+ company,
176
+ people: sellerLinked,
177
+ linkType: 'salesman',
178
+ comission: 8,
179
+ minimum_comission: 1,
180
+ },
181
+ {
182
+ '@id': '/people_links/602',
183
+ id: 602,
184
+ company,
185
+ people: sellerAvailable,
186
+ linkType: 'salesman',
187
+ comission: 12,
188
+ minimum_comission: 3,
189
+ },
190
+ ]),
191
+ ),
192
+ });
193
+ }
194
+ return route.fulfill({
195
+ status: 200,
196
+ headers: jsonHeaders(),
197
+ body: JSON.stringify(collection([])),
198
+ });
199
+ }
200
+
201
+ if (method === 'POST') {
202
+ let body = {};
203
+ try {
204
+ body = JSON.parse(request.postData() || '{}');
205
+ } catch (_) {
206
+ body = {};
207
+ }
208
+ const sellerIri =
209
+ typeof body.company === 'string'
210
+ ? body.company
211
+ : body.company?.['@id'] || body.company?.id;
212
+ const seller =
213
+ sellerIri === sellerAvailable['@id'] || sellerIri === 42 || sellerIri === '42'
214
+ ? sellerAvailable
215
+ : sellerLinked;
216
+ nextId += 1;
217
+ const created = {
218
+ '@id': `/people_links/${nextId}`,
219
+ id: nextId,
220
+ company: seller,
221
+ people: client,
222
+ linkType: body.linkType || 'sellers-client',
223
+ comission: body.comission ?? body.commission ?? null,
224
+ minimum_comission:
225
+ body.minimum_comission ?? body.minimumComission ?? null,
226
+ };
227
+ linksState.push(created);
228
+ return route.fulfill({
229
+ status: 201,
230
+ headers: jsonHeaders(),
231
+ body: JSON.stringify(created),
232
+ });
233
+ }
234
+
235
+ if (method === 'PUT' || method === 'PATCH') {
236
+ const idMatch = pathname.match(/people_links\/(\d+)/);
237
+ const id = idMatch ? Number(idMatch[1]) : null;
238
+ let body = {};
239
+ try {
240
+ body = JSON.parse(request.postData() || '{}');
241
+ } catch (_) {
242
+ body = {};
243
+ }
244
+ const idx = linksState.findIndex(l => l.id === id);
245
+ if (idx >= 0) {
246
+ linksState[idx] = {
247
+ ...linksState[idx],
248
+ comission:
249
+ body.comission ?? body.commission ?? linksState[idx].comission,
250
+ minimum_comission:
251
+ body.minimum_comission ??
252
+ body.minimumComission ??
253
+ linksState[idx].minimum_comission,
254
+ };
255
+ return route.fulfill({
256
+ status: 200,
257
+ headers: jsonHeaders(),
258
+ body: JSON.stringify(linksState[idx]),
259
+ });
260
+ }
261
+ return route.fulfill({
262
+ status: 404,
263
+ headers: jsonHeaders(),
264
+ body: JSON.stringify({detail: 'Not found'}),
265
+ });
266
+ }
267
+
268
+ if (method === 'DELETE') {
269
+ const idMatch = pathname.match(/people_links\/(\d+)/);
270
+ const id = idMatch ? Number(idMatch[1]) : null;
271
+ const idx = linksState.findIndex(l => l.id === id);
272
+ if (idx >= 0) {
273
+ linksState.splice(idx, 1);
274
+ }
275
+ return route.fulfill({
276
+ status: 204,
277
+ headers: CORS_HEADERS,
278
+ body: '',
279
+ });
280
+ }
281
+ }
282
+
283
+ if (pathname.startsWith('people_media') || pathname === 'medias') {
284
+ return route.fulfill({
285
+ status: 200,
286
+ headers: jsonHeaders(),
287
+ body: JSON.stringify(collection([])),
288
+ });
289
+ }
290
+
291
+ if (pathname === 'menus-people') {
292
+ return route.fulfill({
293
+ status: 200,
294
+ headers: jsonHeaders(),
295
+ body: JSON.stringify({modules: {}}),
296
+ });
297
+ }
298
+
299
+ if (pathname === 'configs/discovery-configs') {
300
+ return route.fulfill({
301
+ status: 200,
302
+ headers: jsonHeaders(),
303
+ body: JSON.stringify({configs: {}}),
304
+ });
305
+ }
306
+
307
+ return route.fulfill({
308
+ status: 200,
309
+ headers: jsonHeaders(),
310
+ body: JSON.stringify(collection([])),
311
+ });
312
+ });
313
+
314
+ await page.addInitScript(
315
+ ({version, roles, appType}) => {
316
+ localStorage.setItem(
317
+ 'session',
318
+ JSON.stringify({
319
+ id: 19,
320
+ people: '/people/19',
321
+ api_key: 'test-api-key',
322
+ active: 1,
323
+ mycompany: 2,
324
+ roles,
325
+ }),
326
+ );
327
+ localStorage.setItem('app-type', appType);
328
+ localStorage.setItem('config', JSON.stringify({language: 'pt-br'}));
329
+ localStorage.setItem(
330
+ 'device',
331
+ JSON.stringify({
332
+ id: 'web-manager',
333
+ device: 'web-manager',
334
+ type: 'WEB',
335
+ appName: 'Browser Manager',
336
+ appVersion: version,
337
+ buildNumber: version,
338
+ systemName: 'web',
339
+ systemVersion: 'web',
340
+ deviceType: 'web',
341
+ metadata: {},
342
+ }),
343
+ );
344
+ },
345
+ {version: appVersion, roles, appType},
346
+ );
347
+ };
348
+
349
+ test.describe('manager client salesman manage CRUD', () => {
350
+ test('MANAGER: shows add button, opens modal, links new salesman', async ({
351
+ page,
352
+ }) => {
353
+ await mockManagerApi(page, {appType: 'MANAGER', roles: ['ROLE_SUPER']});
354
+ await page.goto(
355
+ '/client-details?clientId=29&contextKey=client&initialTab=sellers',
356
+ );
357
+
358
+ await expect(page.getByTestId('salesman-manage-add-btn')).toBeVisible({
359
+ timeout: 15000,
360
+ });
361
+ await expect(page.getByText('VENDEDOR VINCULADO', {exact: false})).toBeVisible({
362
+ timeout: 10000,
363
+ });
364
+
365
+ await page.getByTestId('salesman-manage-add-btn').click();
366
+ await expect(page.getByTestId('salesman-manage-modal')).toBeVisible({
367
+ timeout: 10000,
368
+ });
369
+ await expect(page.getByTestId('salesman-manage-modal-title')).toContainText(
370
+ 'Vincular',
371
+ );
372
+
373
+ // Select available seller via native select (Picker web renders as select)
374
+ const picker = page.getByTestId('salesman-manage-seller-picker');
375
+ await expect(picker).toBeVisible();
376
+ // RN-web Picker often exposes a select inside
377
+ const select = picker.locator('select').first();
378
+ if (await select.count()) {
379
+ await select.selectOption({value: '/people/42'});
380
+ } else {
381
+ // Fallback: click option text if custom picker
382
+ await page.getByText('VENDEDOR DISPONIVEL', {exact: false}).first().click();
383
+ }
384
+
385
+ await page.getByTestId('salesman-manage-commission-input').fill('18');
386
+ await page.getByTestId('salesman-manage-minimum-input').fill('4');
387
+ await page.getByTestId('salesman-manage-save-btn').click();
388
+
389
+ await expect(page.getByTestId('salesman-manage-modal')).toHaveCount(0, {
390
+ timeout: 10000,
391
+ });
392
+ await expect(
393
+ page.getByText('VENDEDOR DISPONIVEL', {exact: false}),
394
+ ).toBeVisible({timeout: 10000});
395
+ });
396
+
397
+ test('MANAGER: edit and delete row actions present for linked salesman', async ({
398
+ page,
399
+ }) => {
400
+ await mockManagerApi(page, {appType: 'MANAGER', roles: ['ROLE_SUPER']});
401
+ await page.goto(
402
+ '/client-details?clientId=29&contextKey=client&initialTab=sellers',
403
+ );
404
+
405
+ await expect(page.getByTestId('salesman-manage-edit-501')).toBeVisible({
406
+ timeout: 15000,
407
+ });
408
+ await expect(page.getByTestId('salesman-manage-delete-501')).toBeVisible();
409
+
410
+ await page.getByTestId('salesman-manage-edit-501').click();
411
+ await expect(page.getByTestId('salesman-manage-modal')).toBeVisible({
412
+ timeout: 10000,
413
+ });
414
+ await expect(page.getByTestId('salesman-manage-modal-title')).toContainText(
415
+ 'Editar',
416
+ );
417
+ await page.getByTestId('salesman-manage-commission-input').fill('22');
418
+ await page.getByTestId('salesman-manage-save-btn').click();
419
+ await expect(page.getByTestId('salesman-manage-modal')).toHaveCount(0, {
420
+ timeout: 10000,
421
+ });
422
+
423
+ // Delete — MessageService showDialog (custom UI confirm)
424
+ await page.getByTestId('salesman-manage-delete-501').click();
425
+ await expect(
426
+ page.getByText(/Deseja realmente remover este vendedor/i),
427
+ ).toBeVisible({timeout: 10000});
428
+ await page.getByText('Remover', {exact: true}).last().click();
429
+ // After delete the edit control for 501 should disappear
430
+ await expect(page.getByTestId('salesman-manage-edit-501')).toHaveCount(0, {
431
+ timeout: 10000,
432
+ });
433
+ });
434
+
435
+ test('non-MANAGER: no administrative CRUD controls', async ({page}) => {
436
+ await mockManagerApi(page, {appType: 'SHOP', roles: ['ROLE_EMPLOYEE']});
437
+ await page.goto(
438
+ '/client-details?clientId=29&contextKey=client&initialTab=sellers',
439
+ );
440
+
441
+ // List may still render linked salesmen, but manage controls must be absent
442
+ await page.waitForTimeout(2000);
443
+ await expect(page.getByTestId('salesman-manage-add-btn')).toHaveCount(0);
444
+ await expect(page.getByTestId('salesman-manage-edit-501')).toHaveCount(0);
445
+ await expect(page.getByTestId('salesman-manage-delete-501')).toHaveCount(0);
446
+ await expect(page.getByTestId('salesman-manage-modal')).toHaveCount(0);
447
+ });
448
+ });
@@ -0,0 +1,25 @@
1
+ const {describe, expect, it} = global
2
+
3
+ const {
4
+ resolveContactMutationMessage,
5
+ } = require('../../../../react/components/tabs/contactMutationMessage')
6
+
7
+ describe('contactMutationMessage', () => {
8
+ it('hides raw people iri errors behind a readable contact message', () => {
9
+ expect(
10
+ resolveContactMutationMessage({
11
+ message: 'Item not found for "/people/30".',
12
+ }),
13
+ ).toBe(
14
+ 'Este contato esta vinculado a empresa, mas o cadastro direto dele nao esta disponivel para edicao no momento.',
15
+ )
16
+ })
17
+
18
+ it('keeps other backend messages when they are already readable', () => {
19
+ expect(
20
+ resolveContactMutationMessage({
21
+ detail: 'Telefone ja cadastrado para outra pessoa.',
22
+ }),
23
+ ).toBe('Telefone ja cadastrado para outra pessoa.')
24
+ })
25
+ })