Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 1217 - csv upload validation #1403

Open
wants to merge 18 commits into
base: development
Choose a base branch
from

Conversation

SageMar
Copy link
Contributor

@SageMar SageMar commented Dec 5, 2024

Description

"The create meter page stops admins from entering bad values by constraining choices and/or checking before saving. It would be good if the CSV meter upload page did similar checks." After a talk with Steve, it was decided that this validation should be done in JavaScript on the back-end, so these validations are inside the uploadMeters.js file.

Done in collaboration with @cmatthews444

Partly Addresses #1217

This adds validations for the following variables:

  • Enabled
  • Disabled
  • Type
  • Timezone
  • Area
  • Cumulative
  • Reset
  • Timesort
  • End Only
  • Area Unit
  • Min Val
  • Max Val
  • Disabled Checks

Type of change

(Check the ones that apply by placing an "x" instead of the space in the [ ] so it becomes [x])

  • Note merging this changes the database configuration.
  • This change requires a documentation update

Checklist

(Note what you have done by placing an "x" instead of the space in the [ ] so it becomes [x]. It is hoped you do all of them.)

  • I have followed the OED pull request ideas
  • I have removed text in ( ) from the issue request
  • You acknowledge that every person contributing to this work has signed the OED Contributing License Agreement and each author is listed in the Description section.

Limitations

This does not cover every single validation done on a CSV file - it only covers those listed above.

@huss
Copy link
Member

huss commented Jan 20, 2025

@SageMar & @cmatthews444 I saw you made some changes since my comments and wanted to see where this PR is at. Are you planning to do more work on this, do you need any help or is that status something else? Thanks.

@SageMar
Copy link
Contributor Author

SageMar commented Jan 20, 2025

@huss We are definitely still here finishing it up. It's been difficult to find the time between other projects this quarter, but we're aiming to fix the last errors and at least get in the validations we listed in the opening post for this PR.

When we last left off with the code, we had 3 errors still occurring which we were working to figure out what they mean. It would actually help a ton if you're able to give clarification on them as they're not quite as straightforward as the others we got. If it's easier to chat about this over Discord we can schedule a time on Friday (if you're available, I believe we can both make ourselves available any time on Friday other than 1pm PST), but if they're not too complicated to sum up here that would be great.

  1. Meter testing files starting 'pipe100' doing 'Second meter upload where incorrectly provides meter identifier so fails' with 2

  2. Meter testing files starting 'pipe101' doing 'Second meter with same name so fails but first meter exists' with 1 requests

  3. Meter testing files starting 'pipe103' doing 'Uploading meters using Email. First succeeds then the second meter upload fails because it incorrectly provides meter identifier' with 2 requests

@huss
Copy link
Member

huss commented Jan 20, 2025

@SageMar

  1. Meter testing files starting 'pipe100' doing 'Second meter upload where incorrectly provides meter identifier so fails' with 2
  2. Meter testing files starting 'pipe103' doing 'Uploading meters using Email. First succeeds then the second meter upload fails because it incorrectly provides meter identifier' with 2 requests

Both of these failed because it expected OED to report a success code (200) but it received an error code (400). I would debug this by adding a console.log to the code to print out the response text since that might indicate what went wrong.

  1. Meter testing files starting 'pipe101' doing 'Second meter with same name so fails but first meter exists' with 1 requests

This one is curious because the returned error is Failed to upload meters due to internal OED Error: For meter pipe101 the area entry of 33 is invalid. Area must be a number greater than 0. but the value of 33 is greater than 0. I'm guessing you added a test that the area is valid. It may not be working as desired and/or it is returning new info so the test needs to be updated. I would first want to figure out why the test seems to have a message that is inconsistent on 33 > 0.

Do you want to work on these yourselves? I can also help (either working with you or by myself). Let me know what you prefer and if you want/need more information.

@SageMar
Copy link
Contributor Author

SageMar commented Jan 24, 2025

Do you want to work on these yourselves? I can also help (either working with you or by myself). Let me know what you prefer and if you want/need more information.

@huss

I think we'll at least give it a try ourselves with that information. If we're still stuck by Tuesday, I'll reach out again! Thank you!

…ecked, now it converts strings to ints and functions
@SageMar SageMar marked this pull request as ready for review January 24, 2025 21:11
@SageMar
Copy link
Contributor Author

SageMar commented Jan 24, 2025

@huss In case you were curious about what caused the issues, it seems the confusing error on pipe101 was what effected all of them. For come reason those files in particular had the number under area coming in as undefined, so using parseInt() on the value ended up fixing all three.

It passed tests and appears to be working for everything on our end, but let us know if there's anything else that needs to be changed! Thanks for always being so helpful.

Copy link
Member

@huss huss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks to @SageMar & @cmatthews444 for continued work on this issue. I reviewed/tested and made some comments. Please let me know if you need any help with this.

// Verify area unit - have to parse float to ensure it can read in integer numbers like "33"
const areaInput = parseFloat(meter[9]);
if (areaInput) {
if (!isValidArea(areaInput)){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a small point but here and a few other lines don't have spaces: ){ vs ) }. Formatting with VSC should clear this up. I can do it if you prefer.

@@ -8,17 +8,18 @@ const Meter = require('../../models/Meter');
const readCsv = require('../pipeline-in-progress/readCsv');
const Unit = require('../../models/Unit');
const { normalizeBoolean } = require('./validateCsvUploadParams');
const { type } = require('os');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this include may have been accidentally added as I don't think it is used.

* @returns true or false
*/
function isValidAreaUnit(areaUnit) {
const validTypes = ['feet', 'meters', 'none'];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using the standard enum would be better. See src/server/models/Unit.js for areaUnitType. This will allow it to adjust if the allowed values are changed. Also, the error msg above with these values should be constructed by looping over the enum. Also for potential future changes the comment(s) listing the values could be updated about the enum rather than specifics.

*/
function isValidTimeSort(timeSortValue) {
// must be one of the three values
if (timeSortValue == 'increasing' || timeSortValue == 'decreasing'){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to above about enum, see src/server/services/csvPipeline/validateCsvUploadParams.js for MeterTimeSortTypesJS.

* @returns true or false
*/
function isValidMeterType(meterTypeString) {
const validTypes = ['egauge', 'mamac', 'metasys', 'obvius', 'other'];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same enum and see src/server/models/Meter.js for `Meter.type``.

* @param {number} rowIndex - The current row index for error reporting.
*/
function validateBooleanFields(meter, rowIndex) {
// all inputs that involve a true or false all bieng validated together.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bieng ->> being


if (isNaN(minValue)){
// do nothing, pass it through
} else if (isNaN(minValue) || minValue < -9007199254740991 || minValue >= maxValue){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think OED is allowing minValue = maxValue. This applies below.

This did raise the question in my mind that the maxValue is used before it is validated. Should they be checked for isNan, isNumber first, then min/max value and finally if min > max?

const timezone = meter[5];
if (timezone){
if (!isValidTimeZone(timezone)){
let msg = `For meter ${meter[0]}, ${timeSortValue} is not a valid time zone.`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think timeSortValue should be for time zone instead.

throw new CSVPipelineError(msg, undefined, 500);
}
// Need to reverse latitude & longitude because standard GPS gives in that order but a GPSPoint for the
// DB is longitude, latitude.
meter[6] = switchGPS(gpsInput);
}

// Verify area unit - have to parse float to ensure it can read in integer numbers like "33"
const areaInput = parseFloat(meter[9]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting you parseFloat before the check for being a number and if it is undefined.

throw new CSVPipelineError(msg, undefined, 500);
}
// Need to reverse latitude & longitude because standard GPS gives in that order but a GPSPoint for the
// DB is longitude, latitude.
meter[6] = switchGPS(gpsInput);
}

// Verify area unit - have to parse float to ensure it can read in integer numbers like "33"
const areaInput = parseFloat(meter[9]);
if (areaInput) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check can fail in certain circumstances. I tested and 0 (zero) and -1 returns false so the area check does not happen. I also notice that 0.1 or any value with a decimal part does not work but it should. Finally, this allowed letters for numbers to pass the test. This may impact other tests you added. I did not try a fix so let me know if you have issues in resolving.

@cmatthews444
Copy link
Contributor

@huss We are planning on working on this later this week, will reach and let you know if we need help from there.

@SageMar
Copy link
Contributor Author

SageMar commented Feb 12, 2025

@huss Do you have any time to meet with us on Friday in the Discord channel? Just looking to get a little clarification on some of the fixes. We're both available anytime after 11AM PST. Thanks!

@huss
Copy link
Member

huss commented Feb 13, 2025

@huss Do you have any time to meet with us on Friday in the Discord channel? Just looking to get a little clarification on some of the fixes. We're both available anytime after 11AM PST. Thanks!

@SageMar Sure. Would 12:00 PT work for you?

@SageMar
Copy link
Contributor Author

SageMar commented Feb 13, 2025

@SageMar Sure. Would 12:00 PT work for you?

Yup, that works great! See you then

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants