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

Don't require label in entity update and allow other blank updates #1035

Merged
merged 10 commits into from
Nov 14, 2023

Conversation

ktuite
Copy link
Member

@ktuite ktuite commented Oct 30, 2023

Closes getodk/central#527 by allowing an entity update submission with no <label> tag specified.

Specifying a blank <label></label> will be treated as ignoring the label (but only during an update).

Specifying an empty property <age></age> can now be used to set that property to blank.

The PR also adds a new Problem for not being able to find the base version of an entity, which should fix this one case of not seeing any error on frontend: getodk/central#536

What has been done to verify that this works as intended?

tests

should probably add tests for the new individual functions i added, but most of the cases are also tested through higher level tests.

Why is this the best possible solution? Were any other approaches considered?

This led me to refactor validateEntity(). It used to be that there was some validation spread out through the code (e.g. checking the dataset first to know if it existed) and then this one validation function. Awkwardly, that function took 4 different kinds of input (submissions vs. api crossed with create vs. update) and it also slightly modified the object it was checking to "help" prepare data to put into an Entity frame. It wasn't really helping!

Now the different fields are validated when they are pulled out because they are only needed in certain cases, e.g. baseVersion is only relevant in an update from a submission, and label can or can't be blank depending on the context. (on an update from a submission, if it is blank, it will be ignored, but in other cases, it will throw an error.)

How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?

Better entity update behavior, clearer errors.

Does this change require updates to the API documentation? If so, please update docs/api.md as part of this PR.

I don't think so.

Before submitting this PR, please make sure you have:

  • run make test-full and confirmed all checks still pass OR confirm CircleCI build passes
  • verified that any code from external sources are properly credited in comments or that everything is internally sourced

lib/data/entity.js Outdated Show resolved Hide resolved
@matthew-white matthew-white self-requested a review October 31, 2023 03:23
Copy link
Member

@matthew-white matthew-white left a comment

Choose a reason for hiding this comment

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

Just leaving some initial thoughts/ideas. Good call on distinguishing between no <label> tag at all and a blank <label></label>. 👍

// that is ok -- the label just wont be updated on the entity.
// TODO: do something different with validateEntity because it has too
// many special, subtle cases.
if (!(update === '1' || update === 'true') && (!label || label.trim() === ''))
Copy link
Member

Choose a reason for hiding this comment

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

Is there any chance we could get parseSubmissionXml() to convert the create and update attributes to JavaScript booleans? I think the result would be more readable relative to the first "or" condition here involving update.

// that is ok -- the label just wont be updated on the entity.
// TODO: do something different with validateEntity because it has too
// many special, subtle cases.
if (!(update === '1' || update === 'true') && (!label || label.trim() === ''))
Copy link
Member

Choose a reason for hiding this comment

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

I'm thinking of getodk/central#514 and wondering whether we should adjust the logic here slightly. Rather than "if the update attribute is not true, then require a label," it could be "if the create attribute is true, then require a label, even if the update attribute is also true." We could also come back to this later.

Copy link
Member Author

Choose a reason for hiding this comment

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

see totally new logic - instead of calling this validateEntity function that tries to do it all, while also manipulating the structure, the each field is pulled out and validated on its own to build up the new entity def.

lib/data/entity.js Outdated Show resolved Hide resolved
lib/data/submission.js Outdated Show resolved Hide resolved
lib/util/problem.js Outdated Show resolved Hide resolved
lib/model/query/entities.js Outdated Show resolved Hide resolved
Copy link
Member

@matthew-white matthew-white left a comment

Choose a reason for hiding this comment

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

Feels like a nice improvement and a clearer approach than validateEntity() was 👍

lib/data/entity.js Outdated Show resolved Hide resolved
lib/util/problem.js Outdated Show resolved Hide resolved
lib/data/entity.js Outdated Show resolved Hide resolved
}

if (body.label != null)
if (typeof body.label !== 'string')
throw Problem.user.invalidDataTypeOfParameter({ field: 'label', expected: 'string' });
else if (body.label.trim() === '')
throw Problem.user.missingParameter({ field: 'label' });
Copy link
Member

Choose a reason for hiding this comment

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

Is there a different Problem that could be used here? The message of this Problem is "Required parameter label missing.", but the label isn't actually required. Maybe a 400.8 (unexpectedValue)?

const { fieldsFor } = require(appRoot + '/test/util/schema');
const testData = require(appRoot + '/test/data/xml');

describe('extracting and validating entities', () => {
describe('validateEntity', () => {
Copy link
Member

Choose a reason for hiding this comment

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

Is there other test coverage for the cases here? For example, I'm having trouble finding a test that verifies that trying to create an entity via submission without a label results in an error. Similarly, I'm not seeing a test about the case where the baseVersion attribute isn't an integer. I could be missing them though.

@ktuite ktuite merged commit 5296c9a into master Nov 14, 2023
5 checks passed
@ktuite ktuite deleted the ktuite/entity_update_label branch November 14, 2023 01:12
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.

Don't require an entity update via submission to specify a label
2 participants