diff --git a/src/features/import/utils/problems/predictProblems.spec.ts b/src/features/import/utils/problems/predictProblems.spec.ts index b12fec4d6..3fa7edc3c 100644 --- a/src/features/import/utils/problems/predictProblems.spec.ts +++ b/src/features/import/utils/problems/predictProblems.spec.ts @@ -412,7 +412,7 @@ describe('predictProblem()', () => { selected: true, }, { - field: 'first_name', + field: 'last_name', kind: ColumnKind.FIELD, selected: true, }, @@ -424,6 +424,32 @@ describe('predictProblem()', () => { expect(problems).toEqual([]); }); + it('returns problem when ID is missing and only one of name column is configured', () => { + const sheet = makeFullSheet({ + columns: [ + { + idField: 'id', + kind: ColumnKind.ID_FIELD, + selected: true, + }, + { + field: 'first_name', + kind: ColumnKind.FIELD, + selected: true, + }, + ], + rows: [{ data: [null, 'Clara'] }], + }); + + const problems = predictProblems(sheet, 'SE', []); + expect(problems).toEqual([ + { + indices: [0], + kind: ImportProblemKind.MISSING_ID_AND_NAME, + }, + ]); + }); + it('returns problem when ID and name are configured but missing on a row', () => { const sheet = makeFullSheet({ columns: [ @@ -459,6 +485,65 @@ describe('predictProblem()', () => { ]); }); + it('returns problem when either the first name or last name value is missing', () => { + const sheet = makeFullSheet({ + columns: [ + { + field: 'first_name', + kind: ColumnKind.FIELD, + selected: true, + }, + { + field: 'last_name', + kind: ColumnKind.FIELD, + selected: true, + }, + { + field: 'email', + kind: ColumnKind.FIELD, + selected: true, + }, + ], + rows: [ + { data: ['Clara', 'Zetkin', 'zetkin@example.com'] }, + { data: ['John', '', 'john@example.com'] }, + ], + }); + + const problems = predictProblems(sheet, 'SE', []); + expect(problems).toEqual([ + { + indices: [1], + kind: ImportProblemKind.MISSING_ID_AND_NAME, + }, + ]); + }); + + it('returns correct problem when column is not configured', () => { + const sheet = makeFullSheet({ + columns: [ + { + kind: ColumnKind.UNKNOWN, + selected: false, + }, + ], + rows: [ + { data: ['Clara', 'Zetkin', 'zetkin@example.com'] }, + { data: ['John', '', 'john@example.com'] }, + ], + }); + + const problems = predictProblems(sheet, 'SE', []); + expect(problems).toEqual([ + { + kind: ImportProblemKind.UNCONFIGURED_ID_AND_NAME, + }, + { + kind: 'NO_IMPACT', + }, + ]); + }); + it('returns no problems when date column is configured and all cells have a value', () => { const sheet = makeFullSheet({ columns: [ diff --git a/src/features/import/utils/problems/predictProblems.ts b/src/features/import/utils/problems/predictProblems.ts index 33973e1d8..291064ab9 100644 --- a/src/features/import/utils/problems/predictProblems.ts +++ b/src/features/import/utils/problems/predictProblems.ts @@ -47,18 +47,6 @@ export function predictProblems( (col) => col.kind == ColumnKind.FIELD && col.field == 'last_name' ); - if (!sheetHasId) { - if (sheetHasFirstName && sheetHasLastName) { - problems.push({ - kind: ImportProblemKind.UNCONFIGURED_ID, - }); - } else { - problems.push({ - kind: ImportProblemKind.UNCONFIGURED_ID_AND_NAME, - }); - } - } - function accumulateFieldProblem(field: string, row: number) { const existing = problemByField[field]; if (existing) { @@ -76,6 +64,7 @@ export function predictProblems( customFields.forEach((field) => { customFieldsBySlug[field.slug] = field; }); + let missingValueInName = false; sheet.rows.forEach((row, index) => { const rowIndex = sheet.firstRowIsHeaders ? index - 1 : index; @@ -84,9 +73,8 @@ export function predictProblems( return; } + let missingFirstOrLastName = false; let rowHasId = false; - let rowHasFirstName = false; - let rowHasLastName = false; sheet.columns.forEach((column, colIndex) => { if (column.selected) { @@ -103,10 +91,6 @@ export function predictProblems( if (!valid) { accumulateFieldProblem(column.field, rowIndex); } - } else if (column.field == 'first_name') { - rowHasFirstName = true; - } else if (column.field == 'last_name') { - rowHasLastName = true; } else if ( column.field == 'email' && !isEmail(value.toString().trim()) @@ -134,26 +118,57 @@ export function predictProblems( } } hadImpact = true; + } else { + if ( + column.kind == ColumnKind.FIELD && + (column.field == 'first_name' || column.field == 'last_name') + ) { + missingFirstOrLastName = true; + missingValueInName = true; + } } } }); - if (sheetHasId && sheetHasFirstName && sheetHasLastName) { - if (!rowHasId && (!rowHasFirstName || !rowHasLastName)) { - if (!rowProblemByKind[ImportProblemKind.MISSING_ID_AND_NAME]) { - rowProblemByKind[ImportProblemKind.MISSING_ID_AND_NAME] = { - indices: [], - kind: ImportProblemKind.MISSING_ID_AND_NAME, - }; - } - - rowProblemByKind[ImportProblemKind.MISSING_ID_AND_NAME].indices.push( - rowIndex - ); + // When id is missing and first and last name columns configured but it is missing name value or + // when id is missing and one of name column configured + const problemWithIdColumn = + sheetHasId && + !rowHasId && + (sheetHasFirstName || sheetHasLastName) && + (missingFirstOrLastName || !sheetHasFirstName || !sheetHasLastName); + + // When there is no id column and first and last name columns are configured but missing name value + const problemWithNoIdColumn = + !sheetHasId && + sheetHasFirstName && + sheetHasLastName && + missingFirstOrLastName; + + if (problemWithIdColumn || problemWithNoIdColumn) { + const problemKey = ImportProblemKind.MISSING_ID_AND_NAME; + if (!rowProblemByKind[problemKey]) { + rowProblemByKind[problemKey] = { + indices: [], + kind: problemKey, + }; } + rowProblemByKind[problemKey].indices.push(rowIndex); } }); + if (!sheetHasId && !missingValueInName) { + if (sheetHasFirstName && sheetHasLastName) { + problems.push({ + kind: ImportProblemKind.UNCONFIGURED_ID, + }); + } else { + problems.push({ + kind: ImportProblemKind.UNCONFIGURED_ID_AND_NAME, + }); + } + } + if (!hadImpact) { problems.push({ kind: ImportProblemKind.NO_IMPACT,