mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
AAE-47527 Populate people and group widgets from process response (#12082)
This commit is contained in:
@@ -91,7 +91,7 @@ describe('FormFieldValueAdapterService', () => {
|
||||
|
||||
it('single-select: should wrap a user object into a single-element array', () => {
|
||||
const field = makeField(FormFieldTypes.PEOPLE, null);
|
||||
const user = { firstName: 'Test', lastName: 'User' };
|
||||
const user = { username: 'testuser', firstName: 'Test', lastName: 'User' };
|
||||
expect(service.adapt(user, field)).toEqual([user]);
|
||||
});
|
||||
|
||||
@@ -107,7 +107,7 @@ describe('FormFieldValueAdapterService', () => {
|
||||
|
||||
it('single-select: should keep a single-element array', () => {
|
||||
const field = makeField(FormFieldTypes.PEOPLE, null);
|
||||
expect(service.adapt([{ firstName: 'Test' }], field)).toEqual([{ firstName: 'Test' }]);
|
||||
expect(service.adapt([{ username: 'test', firstName: 'Test' }], field)).toEqual([{ username: 'test', firstName: 'Test' }]);
|
||||
});
|
||||
|
||||
it('single-select: should return null when given an empty array', () => {
|
||||
@@ -134,12 +134,15 @@ describe('FormFieldValueAdapterService', () => {
|
||||
|
||||
it('multi-select: should wrap a single object into an array', () => {
|
||||
const field = makeField(FormFieldTypes.PEOPLE, null, { multiple: true });
|
||||
expect(service.adapt({ firstName: 'Test' }, field)).toEqual([{ firstName: 'Test' }]);
|
||||
expect(service.adapt({ username: 'testuser', firstName: 'Test' }, field)).toEqual([{ username: 'testuser', firstName: 'Test' }]);
|
||||
});
|
||||
|
||||
it('multi-select: should keep an array of users (idempotent)', () => {
|
||||
const field = makeField(FormFieldTypes.PEOPLE, null, { multiple: true });
|
||||
const users = [{ firstName: 'Alice' }, { firstName: 'Bob' }];
|
||||
const users = [
|
||||
{ username: 'alice', firstName: 'Alice' },
|
||||
{ username: 'bob', firstName: 'Bob' }
|
||||
];
|
||||
expect(service.adapt(users, field)).toEqual(users);
|
||||
});
|
||||
|
||||
@@ -147,6 +150,58 @@ describe('FormFieldValueAdapterService', () => {
|
||||
const field = makeField(FormFieldTypes.PEOPLE, null, { multiple: true });
|
||||
expect(service.adapt(['Test User'], field)).toEqual([{ firstName: 'Test', lastName: 'User' }]);
|
||||
});
|
||||
|
||||
it('should canonicalize a process-response user object (userName → username, drop displayName)', () => {
|
||||
const field = makeField(FormFieldTypes.PEOPLE, null);
|
||||
const processUser = {
|
||||
id: 'u1',
|
||||
email: 'k@x.io',
|
||||
lastName: 'Richards',
|
||||
userName: 'krichards',
|
||||
firstName: 'Keith',
|
||||
displayName: 'Keith Richards'
|
||||
};
|
||||
expect(service.adapt(processUser, field)).toEqual([
|
||||
{ id: 'u1', username: 'krichards', firstName: 'Keith', lastName: 'Richards', email: 'k@x.io' }
|
||||
]);
|
||||
});
|
||||
|
||||
it('should canonicalize an array-wrapped process-response user object', () => {
|
||||
const field = makeField(FormFieldTypes.PEOPLE, null);
|
||||
const processUser = {
|
||||
id: 'u1',
|
||||
email: 'k@x.io',
|
||||
lastName: 'Richards',
|
||||
userName: 'krichards',
|
||||
firstName: 'Keith',
|
||||
displayName: 'Keith Richards'
|
||||
};
|
||||
expect(service.adapt([processUser], field)).toEqual([
|
||||
{ id: 'u1', username: 'krichards', firstName: 'Keith', lastName: 'Richards', email: 'k@x.io' }
|
||||
]);
|
||||
});
|
||||
|
||||
it('should preserve an already-canonical user object (idempotent)', () => {
|
||||
const field = makeField(FormFieldTypes.PEOPLE, null);
|
||||
const canonical = { id: 'u1', username: 'krichards', firstName: 'Keith', lastName: 'Richards' };
|
||||
expect(service.adapt(canonical, field)).toEqual([canonical]);
|
||||
});
|
||||
|
||||
it('should keep a user with only id', () => {
|
||||
const field = makeField(FormFieldTypes.PEOPLE, null);
|
||||
expect(service.adapt({ id: 'u1' }, field)).toEqual([{ id: 'u1', username: '' }]);
|
||||
});
|
||||
|
||||
it('should filter out an object with none of id, username, or email', () => {
|
||||
const field = makeField(FormFieldTypes.PEOPLE, null);
|
||||
expect(service.adapt({ firstName: 'Keith', lastName: 'Richards' }, field)).toBeNull();
|
||||
});
|
||||
|
||||
it('should drop non-string and blank fields from a process-response user object', () => {
|
||||
const field = makeField(FormFieldTypes.PEOPLE, null);
|
||||
const processUser = { id: null, username: 'krichards', firstName: 42, lastName: ' ', email: 'k@x.io' };
|
||||
expect(service.adapt(processUser, field)).toEqual([{ username: 'krichards', email: 'k@x.io' }]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Group adapter', () => {
|
||||
@@ -181,6 +236,16 @@ describe('FormFieldValueAdapterService', () => {
|
||||
const field = makeField(FormFieldTypes.FUNCTIONAL_GROUP, null, { multiple: true });
|
||||
expect(service.adapt(['Eng', 'QA'], field)).toEqual([{ name: 'Eng' }, { name: 'QA' }]);
|
||||
});
|
||||
|
||||
it('should canonicalize a process-response group object', () => {
|
||||
const field = makeField(FormFieldTypes.FUNCTIONAL_GROUP, null);
|
||||
expect(service.adapt({ id: 'grp1', name: 'Finance' }, field)).toEqual([{ id: 'grp1', name: 'Finance' }]);
|
||||
});
|
||||
|
||||
it('should filter out a group object with neither id nor name', () => {
|
||||
const field = makeField(FormFieldTypes.FUNCTIONAL_GROUP, null);
|
||||
expect(service.adapt({}, field)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Dropdown adapter', () => {
|
||||
|
||||
@@ -27,10 +27,23 @@ interface AdaptedUser {
|
||||
lastName?: string;
|
||||
}
|
||||
|
||||
interface CanonicalUser {
|
||||
id?: string;
|
||||
username: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
email?: string;
|
||||
}
|
||||
|
||||
interface AdaptedGroup {
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface CanonicalGroup {
|
||||
id?: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class FormFieldValueAdapterService {
|
||||
private readonly adapters = new Map<string, FormFieldValueAdapter>();
|
||||
@@ -102,7 +115,26 @@ export class FormFieldValueAdapterService {
|
||||
|
||||
private toUser(entry: unknown): unknown {
|
||||
if (typeof entry !== 'string') {
|
||||
return entry;
|
||||
if (!entry || typeof entry !== 'object') {
|
||||
return null;
|
||||
}
|
||||
const source = entry as Record<string, unknown>;
|
||||
const username = this.toStringField(source['username'] ?? source['userName']);
|
||||
const id = this.toStringField(source['id']);
|
||||
const email = this.toStringField(source['email']);
|
||||
const firstName = this.toStringField(source['firstName']);
|
||||
const lastName = this.toStringField(source['lastName']);
|
||||
if (!id && !username && !email) {
|
||||
return null;
|
||||
}
|
||||
const user: CanonicalUser = {
|
||||
...(id !== undefined ? { id } : {}),
|
||||
username: username ?? '',
|
||||
...(firstName !== undefined ? { firstName } : {}),
|
||||
...(lastName !== undefined ? { lastName } : {}),
|
||||
...(email !== undefined ? { email } : {})
|
||||
};
|
||||
return user;
|
||||
}
|
||||
const trimmed = entry.trim();
|
||||
if (this.isBlankToken(trimmed)) {
|
||||
@@ -122,7 +154,20 @@ export class FormFieldValueAdapterService {
|
||||
|
||||
private toGroup(entry: unknown): unknown {
|
||||
if (typeof entry !== 'string') {
|
||||
return entry;
|
||||
if (!entry || typeof entry !== 'object') {
|
||||
return null;
|
||||
}
|
||||
const source = entry as Record<string, unknown>;
|
||||
const name = this.toStringField(source['name']);
|
||||
const id = this.toStringField(source['id']);
|
||||
if (!name && !id) {
|
||||
return null;
|
||||
}
|
||||
const group: CanonicalGroup = {
|
||||
...(id !== undefined ? { id } : {}),
|
||||
name: name ?? ''
|
||||
};
|
||||
return group;
|
||||
}
|
||||
const trimmed = entry.trim();
|
||||
if (this.isBlankToken(trimmed)) {
|
||||
@@ -136,6 +181,10 @@ export class FormFieldValueAdapterService {
|
||||
return value === '' || value === '[]' || value === '{}';
|
||||
}
|
||||
|
||||
private toStringField(value: unknown): string | undefined {
|
||||
return typeof value === 'string' && value.trim() !== '' ? value : undefined;
|
||||
}
|
||||
|
||||
private toOptionId(entry: unknown): unknown {
|
||||
if (entry && typeof entry === 'object') {
|
||||
return (entry as Record<string, unknown>)['id'] ?? null;
|
||||
|
||||
Reference in New Issue
Block a user