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

Refactor: handle controlled terms as objects #374

Merged
merged 5 commits into from
Mar 14, 2023

Conversation

surchs
Copy link
Contributor

@surchs surchs commented Mar 10, 2023

Closes #371

  • controlled terms are now handled as objects with {label: "human readable label", identifier: "https://example.org/vocab/termID"}
  • the categorical annotation component and all involved tests are updated. This mostly meant changing the way vue-select handles data to objects. See: https://vue-select.org/guide/values.html#transforming-selections
  • the hard-coded controlled terms in the store (for now only "sex") have been updated to correspond to this format

Overall the changes are limited, because the code can mostly just handle terms as objects already.

Two things to note:

  1. Right now, we still store only a string literal in the valueMapping part of the dataDictionary, but now we store the identifier and not the label. In the future we might store the complete term object if we decide that it is necessary
  2. I updated the third unit test for selectCategoricalOption to overwrite the stored value as described in the test

Note:

Need to use the reduce option in vue-select to
handle objects as options and identify them based on their
identifier while showing the label to the user
No functional changes, just passing the expected data,
now that terms are objects and not literals any more.
No functional changes, but updated examples to pass around identifiers
instead of human readable labels as before.

Also changed the third test to actually rewrite the same value as
asserted.
@surchs surchs requested a review from jarmoza March 10, 2023 13:22
@jarmoza
Copy link
Contributor

jarmoza commented Mar 10, 2023

@surchs Interesting! Will take a look. We should have some of these integration PRs for the annotation page being merged in today/early next week, so I'll consider best order for the merges. Could be yours here should be first!

Copy link
Contributor

@jarmoza jarmoza left a comment

Choose a reason for hiding this comment

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

@surchs Just one question and maybe 1-2 light changes. I think this should go in before my PR with Arman that he's reviewing now.

Let me know what you think.


// Setup
cy.mount(annotCategorical, {
computed: Object.assign(store.getters, { getCategoricalOptions: () => (p_column) => [],
Copy link
Contributor

@jarmoza jarmoza Mar 14, 2023

Choose a reason for hiding this comment

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

@surchs Can you explain the reasoning behind this Object.assign and also the null return value of getSelectedOption mock?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the reasoning behind this Object.assign

this just creates a new Object of store.getters where the getCategoricalOptions and getSelectedOptions attributes are overwritten with what's shown above without changing the original store object defined at the beginning. An alternative way to do this would be to add the beforeEach hook to define the store and then directly change the store object in the setup of this test store.getters.getCategoricalOptions = .... The main goal here is to change how these getters behave for this specific test from how they are defined at the beginning.

the null return value of getSelectedOption mock

as mentioned in the test name, the goal here is to just check whether the component is able to deal with a null return value from the getter. The reason for this is that we now expect the getter to return an object where it previously returned a string literal - and I expect the (yet to be implemented) getter to return null if no selection has been made so far. So we want to be sure that the component can handle that.

Copy link
Contributor

@jarmoza jarmoza Mar 14, 2023

Choose a reason for hiding this comment

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

this just creates a new Object of store.getters where the getCategoricalOptions and getSelectedOptions attributes >are overwritten with what's shown above without changing the original store object defined at the beginning. An >alternative way to do this would be to add the beforeEach hook to define the store and then directly change the store >object in the setup of this test store.getters.getCategoricalOptions = .... The main goal here is to change how these >getters behave for this specific test from how they are defined at the beginning.

Okay for now. I'll convert this to the beforeEach when I merge these changes with my PR changes - which I have done already in my new version of this test file. One of the reasons I asked about the Object.assign is I've seen some oddness with store.getters functions being shown as undefined by Cypress. The solution was to redefine the store in a beforeEach before each test.

as mentioned in the test name, the goal here is to just check whether the component is able to deal with a null return >value from the getter. The reason for this is that we now expect the getter to return an object where it previously >returned a string literal - and I expect the (yet to be implemented) getter to return null if no selection has been made >so far. So we want to be sure that the component can handle that.

👍

mutations.selectCategoricalOption(store.state, "female", "column1", "F");
mutations.selectCategoricalOption(store.state, "female", "column1", "Female");
mutations.selectCategoricalOption(store.state, "https://example.org/female", "column1", "F");
mutations.selectCategoricalOption(store.state, "https://example.org/male", "column1", "F");
Copy link
Contributor

Choose a reason for hiding this comment

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

Selecting 'F' for 'male'?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, that wouldn't be a correct choice. But the syntax works the other way around. It's:

selectCategoricalOption(p_state, p_optionValue, p_columnName, p_rawValue) {

so here I'm selecting "male" for "F" when I have previously selected "female" for "F", thus overwriting the previous value. Before we just assiged the same selection to two different raw values and so we weren't testing that we can overwrite something.

Copy link
Contributor

Choose a reason for hiding this comment

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

Gotcha

@surchs
Copy link
Contributor Author

surchs commented Mar 14, 2023

@jarmoza: I responded to your two points. See if that resolves your change requests. Let me know if you want this PR to go before #375 or the other way around, I'm good with either.

@jarmoza
Copy link
Contributor

jarmoza commented Mar 14, 2023

@surchs Approved to merge. As I explain above, I'll handle any merge conflicts with my PR that will be merged next.

@surchs surchs merged commit 9e8d0f2 into dev_components_talk_to_store_directly Mar 14, 2023
@surchs surchs deleted the surchs/issue371 branch March 14, 2023 21:21
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.

2 participants