Skip to content
This repository was archived by the owner on Apr 18, 2024. It is now read-only.

Commit 6436e4e

Browse files
hlomzikbmartel
andauthored
fix: LSDV-4601: Show correct author of draft (#1351)
* fix: LSDV-4601: Show correct author of draft The problem is when userA views draft with comments from userB. It's possible to see current user as an author if userB has username. * createdBy can also have first and last names! Fix code and tests --------- Co-authored-by: hlomzik <[email protected]> Co-authored-by: bmartel <[email protected]>
1 parent 4fc6e34 commit 6436e4e

File tree

3 files changed

+36
-15
lines changed

3 files changed

+36
-15
lines changed

src/stores/Annotation/store.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import { destroy, getEnv, getParent, getRoot, types } from 'mobx-state-tree';
22

3+
import { errorBuilder } from '../../core/DataValidator/ConfigValidator';
4+
import { DataValidator, ValidationError, VALIDATORS } from '../../core/DataValidator';
5+
import { guidGenerator } from '../../core/Helpers';
36
import Registry from '../../core/Registry';
47
import Tree from '../../core/Tree';
58
import Types from '../../core/Types';
6-
import Utils from '../../utils';
7-
import { guidGenerator } from '../../core/Helpers';
8-
import { DataValidator, ValidationError, VALIDATORS } from '../../core/DataValidator';
9-
import { errorBuilder } from '../../core/DataValidator/ConfigValidator';
9+
import { StoreExtender } from '../../mixins/SharedChoiceStore/extender';
1010
import { ViewModel } from '../../tags/visual';
11+
import Utils from '../../utils';
1112
import { FF_DEV_1621, FF_DEV_3034, FF_DEV_3391, FF_DEV_3617, isFF } from '../../utils/feature-flags';
13+
import { emailFromCreatedBy } from '../../utils/utilities';
1214
import { Annotation } from './Annotation';
1315
import { HistoryItem } from './HistoryItem';
14-
import { StoreExtender } from '../../mixins/SharedChoiceStore/extender';
1516

1617
const SelectedItem = types.union(Annotation, HistoryItem);
1718

@@ -323,9 +324,9 @@ const AnnotationStoreModel = types
323324
let actual_user;
324325

325326
if (isFF(FF_DEV_3034)) {
326-
// drafts can be created by other user, but we don't have much info
327-
// so parse "id", get email and find user by it
328-
const email = item.createdBy?.replace(/,\s*\d+$/, '');
327+
// drafts can be created by other user, but we don't have much info
328+
// so parse "id", get email and find user by it
329+
const email = emailFromCreatedBy(item.createdBy);
329330
const user = email && self.store.users.find(user => user.email === email);
330331

331332
if (user) actual_user = user.id;

src/utils/__tests__/utilities.test.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
/* global it, describe, expect, test */
2-
import { getUrl, isString, isStringEmpty, isStringJSON, toTimeString } from '../utilities';
2+
import { emailFromCreatedBy, getUrl, isString, isStringEmpty, isStringJSON, toTimeString } from '../utilities';
3+
4+
describe('Helper function emailFromCreatedBy', () => {
5+
expect(emailFromCreatedBy('[email protected], 12')).toBe('[email protected]');
6+
// empty username, not a rare case
7+
expect(emailFromCreatedBy(' [email protected], 12')).toBe('[email protected]');
8+
expect(emailFromCreatedBy('usrnm [email protected], 12')).toBe('[email protected]');
9+
// first and last name
10+
expect(emailFromCreatedBy('Abc Def [email protected], 12')).toBe('[email protected]');
11+
// complex case
12+
expect(emailFromCreatedBy('Ab.C [email protected] [email protected], 12')).toBe('[email protected]');
13+
// just a email, should not be a real case though
14+
expect(emailFromCreatedBy('[email protected]')).toBe('[email protected]');
15+
});
316

417
/**
518
* isString

src/utils/utilities.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,15 +184,22 @@ export const chunks = <T extends any[]>(source: T, chunkSize: number): T[][] =>
184184
return result;
185185
};
186186

187-
export const userDisplayName = (user: any = {}) => {
188-
const firstName = user.firstName ?? user.firstName;
189-
const lastName = user.lastName ?? user.lastName;
187+
export const userDisplayName = (user: Record<string, string> = {}) => {
188+
const { firstName, lastName } = user;
190189

191190
return (firstName || lastName)
192191
? [firstName, lastName].filter(n => !!n).join(' ').trim()
193-
: (user.username)
194-
? user.username
195-
: user.email;
192+
: (user.username || user.email);
193+
};
194+
195+
/**
196+
* This name supposed to be username, but most likely it's first_name and last_name
197+
* @param {string} createdBy string like "[<name> ]<email>, <id>"
198+
* @returns {string} email
199+
*/
200+
export const emailFromCreatedBy = (createdBy: string) => {
201+
// get the email followed by id and cut off the id
202+
return createdBy?.match(/([^@,\s]+@[^@,\s]+)(,\s*\d+)?$/)?.[1];
196203
};
197204

198205
export const camelizeKeys = (object: any): Record<string, unknown> => {

0 commit comments

Comments
 (0)