Skip to content

Commit

Permalink
geosolutions-it#10770: Vector files import limits
Browse files Browse the repository at this point in the history
Description:
- handle checking the file size for imported vector layers only
- show a warning notification for each layer has size larger than the configurable limit if configured
- add translations
- add test units
  • Loading branch information
mahmoudadel54 committed Jan 24, 2025
1 parent d3d0ee6 commit f22436a
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,56 @@ describe('useFiles enhancer', () => {
ReactDOM.render(<EnhancedSink layers={[layer]}
setLayers={actions.setLayers} warning={handlers.warning} onClose={handlers.onClose} />, document.getElementById("container"));

});
it('useFiles rendering with layer having size exceed the max limit should call warnig()', (done) => {
const handlers = {
warning: () => {},
onClose: () => {},
loadAnnotations: () => {},
loadMap: () => {}
};
const warningSpy = expect.spyOn(handlers, 'warning');

const actions = {
setLayers: (layers) => {
expect(layers).toExist();
// length is 1 since just one layer is valid and the another is invalid for its size
expect(layers.length).toBe(1);
expect(warningSpy).toHaveBeenCalled();
done();
}
};

const sink = createSink( props => {
expect(props).toExist();
expect(props.layers).toExist();
expect(props.useFiles).toExist();
props.useFiles({layers: props.layers});

});
const EnhancedSink = useFiles(sink);

const layers = [{
type: 'vector', name: "FileName", hideLoading: true,
bbox: {crs: "EPSG:4326"},
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-20, 30]
},
"properties": {
"prop0": "value0"
}
}]
}, {
type: 'vector', name: "FileName01", hideLoading: true,
exceedFileMaxSize: true,
"features": []
}];
ReactDOM.render(<EnhancedSink layers={layers}
setLayers={actions.setLayers} warning={handlers.warning} onClose={handlers.onClose} />, document.getElementById("container"));

});
it('useFiles rendering with new annotation layer', (done) => {

Expand Down
17 changes: 15 additions & 2 deletions web/client/components/import/dragZone/enhancers/processFiles.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { compose, createEventHandler, mapPropsStream } from 'recompose';
import Rx from 'rxjs';

import { isAnnotation, importJSONToAnnotations } from '../../../../plugins/Annotations/utils/AnnotationsUtils';
import ConfigUtils from '../../../../utils/ConfigUtils';
import ConfigUtils, { getConfigProp } from '../../../../utils/ConfigUtils';
import {
MIME_LOOKUPS,
checkShapePrj,
Expand All @@ -25,7 +25,8 @@ import {
readZip,
recognizeExt,
shpToGeoJSON,
readGeoJson
readGeoJson,
isFileSizeExceedMaxLimit
} from '../../../../utils/FileUtils';
import { geoJSONToLayer } from '../../../../utils/LayersUtils';

Expand Down Expand Up @@ -66,6 +67,17 @@ const checkFileType = (file) => {
const readFile = (onWarnings) => (file) => {
const ext = recognizeExt(file.name);
const type = file.type || MIME_LOOKUPS[ext];
// Check the file size first before file conversion process to avoid this useless effort
const isVectorFileSizeConfigurable = getConfigProp('importedVectorFileSizeInMB');
const isVectorFile = type !== 'application/json'; // skip json as json is for map file
if (isVectorFileSizeConfigurable && isVectorFile) {
const fileSizeLimitInMB = getConfigProp('importedVectorFileSizeInMB');
if (isFileSizeExceedMaxLimit(file, fileSizeLimitInMB)) {
// add 'exceedFileMaxSize' and fileSizeLimitInMB into layer object to be used in useFiles
return [[{ "type": "FeatureCollection", features: [], "fileName": file.name, exceedFileMaxSize: true, fileSizeLimitInMB }]];
}
}

const projectionDefs = ConfigUtils.getConfigProp('projectionDefs') || [];
const supportedProjections = (projectionDefs.length && projectionDefs.map(({code}) => code) || []).concat(["EPSG:4326", "EPSG:3857", "EPSG:900913"]);
if (type === 'application/vnd.google-earth.kml+xml') {
Expand Down Expand Up @@ -193,5 +205,6 @@ export default compose(
})
);
}

)
);
11 changes: 10 additions & 1 deletion web/client/components/import/dragZone/enhancers/useFiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,18 @@ export default compose(
} else {
let validLayers = [];
layers.forEach((layer) => {
const valid = layer.type === "vector" ? checkIfLayerFitsExtentForProjection(layer) : true;
const isFileSizeNotValid = !!layer?.exceedFileMaxSize; // this check is for file size limit for vector layer
const valid = layer.type === "vector" ? (checkIfLayerFitsExtentForProjection(layer) && !isFileSizeNotValid) : true;
if (valid) {
validLayers.push(layer);
} else if (isFileSizeNotValid) {
warning({
title: "notification.warning",
message: "mapImport.errors.exceedFileSizeLimit",
autoDismiss: 6,
position: "tc",
values: {filename: layer.name ?? " ", maxfilesize: layer?.fileSizeLimitInMB ?? 10}
});
} else {
warning({
title: "notification.warning",
Expand Down
3 changes: 2 additions & 1 deletion web/client/translations/data.de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -1583,7 +1583,8 @@
"fileNotSupported": "Datei wird nicht unterstützt",
"unknownError": "Beim Import ist ein unbekannter Fehler aufgetreten",
"projectionNotSupported": "Die Projektion der Datei, die Sie importieren möchten, wird nicht unterstützt",
"fileBeyondBoundaries": "Die Datei {Dateiname} kann nicht importiert werden, da sie nicht zu den Kartengrenzen passt"
"fileBeyondBoundaries": "Die Datei {Dateiname} kann nicht importiert werden, da sie nicht zu den Kartengrenzen passt",
"exceedFileSizeLimit": "Die Datei {filename}, die Sie importieren möchten, überschreitet die maximale Dateigröße von {maxfilesize} MB"
}
},
"mapExport": {
Expand Down
1 change: 1 addition & 0 deletions web/client/translations/data.en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -1544,6 +1544,7 @@
"fileNotSupported": "File not supported",
"unknownError": "there was an unknown error during import",
"projectionNotSupported": "The projection of the file(s) you're trying to import is not supported",
"exceedFileSizeLimit": "The file {filename} you're trying to import is exceeded the max file size limit {maxfilesize} MB",
"fileBeyondBoundaries": "The file {filename} cannot be imported because it does not fit the map boundaries"
}
},
Expand Down
3 changes: 2 additions & 1 deletion web/client/translations/data.es-ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -1545,7 +1545,8 @@
"fileNotSupported": "Archivo no compatible",
"unknownError": "hubo un error desconocido durante la importación",
"projectionNotSupported": "La proyección del archivo que está intentando importar no es compatible",
"fileBeyondBoundaries": "El archivo {filename} no se pudo importar porque no encaja dentro de los límites del mapa"
"fileBeyondBoundaries": "El archivo {filename} no se pudo importar porque no encaja dentro de los límites del mapa",
"exceedFileSizeLimit": "El archivo {filename} que estás intentando importar ha superado el límite máximo de tamaño de archivo {maxfilesize} MB"
}
},
"mapExport": {
Expand Down
3 changes: 2 additions & 1 deletion web/client/translations/data.fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -1545,7 +1545,8 @@
"fileNotSupported": "Fichier non pris en charge",
"unknownError": "il y a eu une erreur inconnue lors de l'import",
"projectionNotSupported": "La projection du/des fichier(s) que vous essayez d'importer n'est pas prise en charge",
"fileBeyondBoundaries": "Le fichier {filename} ne peut pas être importé car il ne correspond pas aux limites de la carte"
"fileBeyondBoundaries": "Le fichier {filename} ne peut pas être importé car il ne correspond pas aux limites de la carte",
"exceedFileSizeLimit": "Le fichier {filename} que vous essayez d'importer dépasse la limite de taille de fichier maximale {maxfilesize} Mo"
}
},
"mapExport": {
Expand Down
3 changes: 2 additions & 1 deletion web/client/translations/data.is-IS.json
Original file line number Diff line number Diff line change
Expand Up @@ -1425,7 +1425,8 @@
"fileNotSupported": "File not supported",
"unknownError": "there was an unknown error during import",
"projectionNotSupported": "The projection of the file(s) you're trying to import is not supported",
"fileBeyondBoundaries": "The file {filename} cannot be imported because it does not fit the map boundaries"
"fileBeyondBoundaries": "The file {filename} cannot be imported because it does not fit the map boundaries",
"exceedFileSizeLimit": "The file {filename} you're trying to import is exceeded the max file size limit {maxfilesize} MB"
}
},
"mapExport": {
Expand Down
3 changes: 2 additions & 1 deletion web/client/translations/data.it-IT.json
Original file line number Diff line number Diff line change
Expand Up @@ -1542,7 +1542,8 @@
"fileNotSupported": "File non supportato",
"unknownError": "si è verificato un errore sconosciuto durante l'importazione",
"projectionNotSupported": "La proiezione del file che stai tentando di importare non è supportata",
"fileBeyondBoundaries": "Il file {nomefile} non può essere importato perché non si adatta ai confini della mappa"
"fileBeyondBoundaries": "Il file {nomefile} non può essere importato perché non si adatta ai confini della mappa",
"exceedFileSizeLimit": "Il file {filename} che stai tentando di importare ha superato il limite massimo di dimensione file {maxfilesize} MB"
}
},
"mapExport": {
Expand Down
12 changes: 12 additions & 0 deletions web/client/utils/FileUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,15 @@ export const checkShapePrj = function(buffer) {
});
});
};

/**
* Checks if the file size exceeds the size limit or not. Returns true if exceeding the limit and false if not.
*/
export const isFileSizeExceedMaxLimit = (file, fileSizeLimitInMb) => {
const fileSizeLimitInByte = fileSizeLimitInMb * 1024 * 1024;
const fileSizeInBype = file.size;
if (fileSizeInBype <= fileSizeLimitInByte) {
return false;
}
return true;
};
14 changes: 13 additions & 1 deletion web/client/utils/__tests__/FileUtils-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
import expect from 'expect';

import {readJson, readZip, checkShapePrj} from '../FileUtils';
import {readJson, readZip, checkShapePrj, isFileSizeExceedMaxLimit} from '../FileUtils';
import axios from '../../libs/ajax';

describe('FilterUtils', () => {
Expand All @@ -31,4 +31,16 @@ describe('FilterUtils', () => {
});
});
});
it('isFileSizeExceedMaxLimit with large size exceed the max', () => {
const maxLimitInMega = 1;
const fileWithSizeExceedMaxLimit = 2 * 1024 * 1024;
let isFileSizeValid = isFileSizeExceedMaxLimit({size: fileWithSizeExceedMaxLimit}, maxLimitInMega);
expect(isFileSizeValid).toEqual(true);
});
it('isFileSizeExceedMaxLimit with small file size less than max', () => {
const maxLimitInMega = 1;
const fileWithSizeNotExceedMaxLimit = 0.5 * 1024 * 1024;
let isFileSizeValid = isFileSizeExceedMaxLimit({size: fileWithSizeNotExceedMaxLimit}, maxLimitInMega);
expect(isFileSizeValid).toEqual(false);
});
});

0 comments on commit f22436a

Please sign in to comment.