Skip to content

Commit 5403178

Browse files
committed
jest tests
1 parent 5ac7f01 commit 5403178

4 files changed

Lines changed: 116 additions & 3 deletions

File tree

packages/components/src/internal/components/domainproperties/models.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,12 @@ describe('PropDescType', () => {
564564
expect(acceptablePropertyType(DATETIME_TYPE, TIME_RANGE_URI)).toBeFalsy();
565565
expect(acceptablePropertyType(DATE_TYPE, TIME_RANGE_URI)).toBeFalsy();
566566
expect(acceptablePropertyType(TIME_TYPE, DATE_RANGE_URI)).toBeFalsy();
567+
568+
// GitHub Issue 951: multiline text cannot convert to text choice
569+
expect(acceptablePropertyType(TEXT_CHOICE_TYPE, MULTILINE_RANGE_URI)).toBeFalsy();
570+
// but multiline text can still convert to other string types
571+
expect(acceptablePropertyType(TEXT_TYPE, MULTILINE_RANGE_URI)).toBeTruthy();
572+
expect(acceptablePropertyType(MULTILINE_TYPE, MULTILINE_RANGE_URI)).toBeTruthy();
567573
});
568574
});
569575

packages/components/src/internal/components/editable/utils.test.ts

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { List, Map } from 'immutable';
33
import { QueryInfo } from '../../../public/QueryInfo';
44
import { QueryColumn, QueryLookup } from '../../../public/QueryColumn';
55

6-
import { DATE_RANGE_URI, NON_NEGATIVE_NUMBER_CONCEPT_URI } from '../domainproperties/constants';
6+
import { DATE_RANGE_URI, MULTI_CHOICE_RANGE_URI, NON_NEGATIVE_NUMBER_CONCEPT_URI } from '../domainproperties/constants';
77

88
import sampleSetQueryInfoJSON from '../../../test/data/sampleSetAllFieldTypes-getQueryDetails.json';
99

@@ -390,6 +390,77 @@ describe('getValidatedEditableGridValue', () => {
390390
});
391391
});
392392

393+
test('multi-choice column with valid values', () => {
394+
const multiChoiceCol = new QueryColumn({
395+
jsonType: 'string',
396+
rangeURI: MULTI_CHOICE_RANGE_URI,
397+
validValues: ['alpha', 'beta', 'gamma'],
398+
});
399+
400+
const validArray = [{ display: 'alpha' }, { display: 'beta' }];
401+
expect(getValidatedEditableGridValue(validArray, multiChoiceCol)).toStrictEqual({
402+
message: undefined,
403+
value: validArray,
404+
});
405+
});
406+
407+
test('multi-choice column with invalid choice', () => {
408+
const multiChoiceCol = new QueryColumn({
409+
jsonType: 'string',
410+
rangeURI: MULTI_CHOICE_RANGE_URI,
411+
validValues: ['alpha', 'beta', 'gamma'],
412+
});
413+
414+
const invalidArray = [{ display: 'alpha' }, { display: 'invalid' }];
415+
expect(getValidatedEditableGridValue(invalidArray, multiChoiceCol)).toStrictEqual({
416+
message: { message: "'invalid' is not a valid choice" },
417+
value: invalidArray,
418+
});
419+
});
420+
421+
test('multi-choice column with duplicate choice', () => {
422+
const multiChoiceCol = new QueryColumn({
423+
jsonType: 'string',
424+
rangeURI: MULTI_CHOICE_RANGE_URI,
425+
validValues: ['alpha', 'beta', 'gamma'],
426+
});
427+
428+
const invalidArray = [{ display: 'alpha' }, { display: 'alpha' }];
429+
expect(getValidatedEditableGridValue(invalidArray, multiChoiceCol)).toStrictEqual({
430+
message: { message: "Duplicate values not allowed: alpha." },
431+
value: invalidArray,
432+
});
433+
});
434+
435+
test('multi-choice column exceeding 10 items', () => {
436+
const multiChoiceCol = new QueryColumn({
437+
jsonType: 'string',
438+
rangeURI: MULTI_CHOICE_RANGE_URI,
439+
validValues: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'],
440+
});
441+
442+
const tooMany = Array.from({ length: 11 }, (_, i) => ({ display: String.fromCharCode(97 + i) }));
443+
expect(getValidatedEditableGridValue(tooMany, multiChoiceCol)).toStrictEqual({
444+
message: { message: 'Too many values. Maximum allowed is 10.' },
445+
value: tooMany,
446+
});
447+
});
448+
449+
test('multi-choice column with exactly 10 items is valid', () => {
450+
const values = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
451+
const multiChoiceCol = new QueryColumn({
452+
jsonType: 'string',
453+
rangeURI: MULTI_CHOICE_RANGE_URI,
454+
validValues: values,
455+
});
456+
457+
const tenItems = values.map(v => ({ display: v }));
458+
expect(getValidatedEditableGridValue(tenItems, multiChoiceCol)).toStrictEqual({
459+
message: undefined,
460+
value: tenItems,
461+
});
462+
});
463+
393464
test('required column', () => {
394465
const requiredCol = new QueryColumn({ jsonType: 'string', required: true, caption: 'ReqCol' });
395466

packages/components/src/internal/components/editable/utils.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ interface ValidatedValue {
3030
export const getValidatedEditableGridValue = (origValue: any, col: QueryColumn): ValidatedValue => {
3131
// col ?? {} so it's safe to destructure
3232
const { caption, isDateOnlyColumn, jsonType, required, scale, validValues } = col ?? {};
33-
const isMultiChoice = col.isMultiChoice;
33+
const isMultiChoice = col?.isMultiChoice;
3434
const isDateTimeType = jsonType === 'date';
3535
const isDateType = isDateTimeType && isDateOnlyColumn;
3636
let message;
@@ -57,8 +57,14 @@ export const getValidatedEditableGridValue = (origValue: any, col: QueryColumn):
5757
message = 'Too many values. Maximum allowed is 10.';
5858
}
5959
else if (validValues) {
60+
const seen = new Set();
6061
origValue.forEach(val => {
6162
const trimmed = val.display?.toString().trim();
63+
if (seen.has(trimmed)) {
64+
message = `Duplicate values not allowed: ${trimmed}.`
65+
return false;
66+
}
67+
seen.add(trimmed);
6268
if (validValues.indexOf(trimmed) === -1) {
6369
message = `'${trimmed}' is not a valid choice`;
6470
return false;

packages/components/src/internal/components/entities/actions.test.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Map } from 'immutable';
22

3-
import { extractEntityTypeOptionFromRow, getChosenParentData, sampleGenCellKey } from './actions';
3+
import { extractEntityTypeOptionFromRow, getChosenParentData, getIdentifyingFieldDisplayValue, sampleGenCellKey } from './actions';
44
import { EntityDataType, EntityIdCreationModel } from './models';
55
import { DataClassDataType, SampleTypeDataType } from './constants';
66

@@ -86,3 +86,33 @@ describe('sampleGenCellKey', () => {
8686
expect(sampleGenCellKey(null, 'Ancestors/Sources/Study', 1)).toBe('ancestors/sources/study&&1');
8787
});
8888
});
89+
90+
describe('getIdentifyingFieldDisplayValue', () => {
91+
test('returns formattedValue when available', () => {
92+
expect(getIdentifyingFieldDisplayValue({ formattedValue: 'formatted', displayValue: 'display', value: 'raw' })).toBe('formatted');
93+
});
94+
95+
test('falls back to displayValue when formattedValue is undefined', () => {
96+
expect(getIdentifyingFieldDisplayValue({ displayValue: 'display', value: 'raw' })).toBe('display');
97+
});
98+
99+
test('falls back to value when formattedValue and displayValue are undefined', () => {
100+
expect(getIdentifyingFieldDisplayValue({ value: 'raw' })).toBe('raw');
101+
});
102+
103+
test('joins array values with comma and space', () => {
104+
expect(getIdentifyingFieldDisplayValue({ value: ['a', 'b', 'c'] })).toBe('a, b, c');
105+
});
106+
107+
test('joins array formattedValue with comma and space', () => {
108+
expect(getIdentifyingFieldDisplayValue({ formattedValue: ['x', 'y'] })).toBe('x, y');
109+
});
110+
111+
test('returns single string value as-is', () => {
112+
expect(getIdentifyingFieldDisplayValue({ value: 'single' })).toBe('single');
113+
});
114+
115+
test('handles single-element array', () => {
116+
expect(getIdentifyingFieldDisplayValue({ value: ['only'] })).toBe('only');
117+
});
118+
});

0 commit comments

Comments
 (0)