Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/release/RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
* The top must be greater than the bottom.
* The right must be greater than the left.
* [OSDEV-1662](https://opensupplyhub.atlassian.net/browse/OSDEV-1662) - Updated Logstash mapping configuration to handle the new `action_perform_by` field for OpenSearch.
* [OSDEV-1748](https://opensupplyhub.atlassian.net/browse/OSDEV-1748) - Aligned SLC with current v1/production-locations validation. Removed validation for `number_of_workers` min >= max.

### Architecture/Environment changes
* [OSDEV-1515](https://opensupplyhub.atlassian.net/browse/OSDEV-1515) - Removed `rds_allow_major_version_upgrade` and `rds_apply_immediately` from the environment tfvars files (e.g., terraform-production.tfvars) to set them to `false` again, as the default values in `/deployment/terraform/variables.tf` are `false`. This is necessary to prevent unintended PostgreSQL major version upgrades since the target PostgreSQL 16.3 version has been reached.
Expand Down
16 changes: 0 additions & 16 deletions src/django/api/serializers/v1/number_of_workers_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,6 @@ class NumberOfWorkersSerializer(serializers.Serializer):
}
)

def validate(self, data):
"""Ensure min is less than max"""
min_value = data.get('min')
max_value = data.get('max')

if (
min_value is not None
and max_value is not None
and min_value >= max_value
):
raise serializers.ValidationError(
{"min": "The min field must be less than max filed."}
)

return data

@staticmethod
def validate_object(value):
return isinstance(value, dict)
135 changes: 128 additions & 7 deletions src/react/src/__tests__/utils.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ const {
updateStateFromData,
getLastPathParameter,
generateRangeField,
parseContribData,
} = require('../util/util');

const {
Expand Down Expand Up @@ -1928,12 +1929,12 @@ it('should return { min, max } when value is a valid range string', () => {
});

it('should return { min: value, max: value } when value is a single string (not a range)', () => {
expect(generateRangeField('15')).toEqual({ min: '15', max: '15' });
expect(generateRangeField('test')).toEqual({ min: 'test', max: 'test' });
expect(generateRangeField('15')).toEqual({ min: 15, max: 15 });
expect(generateRangeField('test')).toEqual({ min: NaN, max: NaN });
});

it('should return { min: value, max: value } when value is an empty string', () => {
expect(generateRangeField('')).toEqual({ min: '', max: '' });
expect(generateRangeField('')).toEqual({ min: 0, max: 0 });
});

it('should return { min, max } correctly when value has extra spaces', () => {
Expand All @@ -1942,8 +1943,128 @@ it('should return { min, max } correctly when value has extra spaces', () => {
});

it('should return { min: value, max: value } for non-string and non-number values', () => {
expect(generateRangeField(null)).toEqual({ min: null, max: null });
expect(generateRangeField(undefined)).toEqual({ min: undefined, max: undefined });
expect(generateRangeField({})).toEqual({ min: {}, max: {} });
expect(generateRangeField([])).toEqual({ min: [], max: [] });
expect(generateRangeField(null)).toEqual({ min: 0, max: 0 });
expect(generateRangeField(undefined)).toEqual({ min: NaN, max: NaN });
expect(generateRangeField({})).toEqual({ min: NaN, max: NaN });
expect(generateRangeField([])).toEqual({ min: 0, max: 0 });
});

it('should return the base fields correctly', () => {
const input = {
name: 'KELLY- MOORE PAINT CO INC',
address: '710 AUZERAIS AVE, SAN JOSE, CA, 95126',
country: { value: 'US' },
};

const expectedOutput = {
source: 'SLC',
name: 'KELLY- MOORE PAINT CO INC',
address: '710 AUZERAIS AVE, SAN JOSE, CA, 95126',
country: 'US',
};

expect(parseContribData(input)).toEqual(expectedOutput);
});


it('should process array fields and keep non-empty values', () => {
const input = {
name: 'KELLY- MOORE PAINT CO INC',
address: '710 AUZERAIS AVE, SAN JOSE, CA, 95126',
country: { value: 'US' },
sector: ['Waste Management'],
parent_company: ['ParentCompanySingle'],
product_type: ['Shirts', 'Pants'],
};

const expectedOutput = {
source: 'SLC',
name: 'KELLY- MOORE PAINT CO INC',
address: '710 AUZERAIS AVE, SAN JOSE, CA, 95126',
country: 'US',
sector: ['Waste Management'],
parent_company: ['ParentCompanySingle'],
product_type: ['Shirts', 'Pants'],
};

expect(parseContribData(input)).toEqual(expectedOutput);
});

it('should handle an empty array by not including the field', () => {
const input = {
name: 'KELLY- MOORE PAINT CO INC',
address: '710 AUZERAIS AVE, SAN JOSE, CA, 95126',
country: { value: 'US' },
sector: [],
};

const expectedOutput = {
source: 'SLC',
name: 'KELLY- MOORE PAINT CO INC',
address: '710 AUZERAIS AVE, SAN JOSE, CA, 95126',
country: 'US',
};

expect(parseContribData(input)).toEqual(expectedOutput);
});

it('should handle number_of_workers correctly', () => {
const input = {
name: 'KELLY- MOORE PAINT CO INC',
address: '710 AUZERAIS AVE, SAN JOSE, CA, 95126',
country: { value: 'US' },
numberOfWorkers: '15',
};

const expectedOutput = {
source: 'SLC',
name: 'KELLY- MOORE PAINT CO INC',
address: '710 AUZERAIS AVE, SAN JOSE, CA, 95126',
country: 'US',
number_of_workers: { min: 15, max: 15 },
};

expect(parseContribData(input)).toEqual(expectedOutput);
});

it('should remove empty fields while keeping valid ones', () => {
const input = {
name: 'KELLY- MOORE PAINT CO INC',
address: '710 AUZERAIS AVE, SAN JOSE, CA, 95126',
country: { value: 'US' },
sector: [],
parent_company: null,
product_type: undefined,
location_type: ['RCRAInfo subtitle C (Hazardous waste handlers)'],
};

const expectedOutput = {
source: 'SLC',
name: 'KELLY- MOORE PAINT CO INC',
address: '710 AUZERAIS AVE, SAN JOSE, CA, 95126',
country: 'US',
location_type: ['RCRAInfo subtitle C (Hazardous waste handlers)'],
};

expect(parseContribData(input)).toEqual(expectedOutput);
});

it('should return only the source field if all other values are empty', () => {
const input = {
name: '',
address: '',
country: null,
sector: [],
parent_company: '',
product_type: undefined,
location_type: null,
processing_type: '',
numberOfWorkers: null,
};

const expectedOutput = {
source: 'SLC',
};

expect(parseContribData(input)).toEqual(expectedOutput);
});
57 changes: 23 additions & 34 deletions src/react/src/util/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import filter from 'lodash/filter';
import includes from 'lodash/includes';
import join from 'lodash/join';
import map from 'lodash/map';
import mapValues from 'lodash/mapValues';
import uniq from 'lodash/uniq';
import has from 'lodash/has';
import { isURL, isInt } from 'validator';
Expand Down Expand Up @@ -1433,7 +1434,12 @@ export const openInNewTab = url => {
if (newWindow) newWindow.opener = null;
};

const extractProductionLocationContributionValues = data => map(data, 'value');
const extractProductionLocationContributionValues = data => {
if (isArray(data)) {
return data.map(item => (item?.value ? item.value : item));
}
return data;
};

export const generateRangeField = value => {
if (typeof value === 'number') {
Expand All @@ -1445,45 +1451,28 @@ export const generateRangeField = value => {
return max !== undefined ? { min, max } : { min };
}

return { min: value, max: value };
return { min: Number(value), max: Number(value) };
};

export const parseContribData = contribData => {
const {
name,
address,
country,
sector,
productType,
locationType,
processingType,
numberOfWorkers,
parentCompany,
} = contribData;
// eslint-disable-next-line camelcase
const { numberOfWorkers, country, ...fields } = contribData;

const countryValue = country?.value;

const transformedFields = mapValues(
pickBy(fields, value => !isEmpty(value)),
extractProductionLocationContributionValues,
);

return {
...transformedFields,
// eslint-disable-next-line camelcase
...(numberOfWorkers && {
number_of_workers: generateRangeField(numberOfWorkers),
}),
country: countryValue,
source: DATA_SOURCES_ENUM.SLC,
name,
address,
country: country?.value,
sector: isArray(sector)
? extractProductionLocationContributionValues(sector)
: [],
parent_company: isArray(parentCompany)
? extractProductionLocationContributionValues(parentCompany)
: [],
product_type: isArray(productType)
? extractProductionLocationContributionValues(productType)
: [],
location_type: isArray(locationType)
? extractProductionLocationContributionValues(locationType)
: [],
processing_type: isArray(processingType)
? extractProductionLocationContributionValues(processingType)
: [],
number_of_workers: numberOfWorkers
? generateRangeField(numberOfWorkers)
: null,
};
};

Expand Down