-
Notifications
You must be signed in to change notification settings - Fork 5
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
Y24-149 exhaust samples moved to destroyed location #2121
base: develop
Are you sure you want to change the base?
Y24-149 exhaust samples moved to destroyed location #2121
Conversation
…estroyed location barcodes
…hausting samples if destroyed location is scanned
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good start, couple questions.
Do we have some way in Traction UI of representing exhausted libraries. Is an exhausted library just one thats volume equals its used_volume or does it also have to be destroyed? Might be useful to have an exhausted badge or something?
src/stores/pacbioLibraries.js
Outdated
|
||
async fetchLibraries(filterOptions) { | ||
const { success, data, meta, errors, libraries, tubes, tags, requests } = | ||
await fetchLibraries({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this naming should be changed so its clear this isnt a recursive function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What decides whether a method goes in utilities or goes into the store? I normally consider utilities as data formatting, etc but some of these make requests to the service as well. Not sure whether that belongs better in the store or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the primary aim is to enable methods that format data, specifically those requiring additional information, to return the expected data. For example, the librariesArray
method requires tubes, requests, and tags to return the information it expects. Splitting these into separate utility functions allows for easier unit testing locally, as it is much trickier to test this functionality using the factory.
I have splitted other methods based on how they are reused across different parts of the application. For instance, fetching libraries is used within the store, but it is also required in other places that do not need to rely on the store method or store state. By splitting it out, these methods can operate independently. Fetching can now be done outside the store, and the same method can be used within store to set store values as needed.
Another approach could have been to split these internally into two separate methods within the store - one method explicitly to fetch information and another method that uses this method to set the store state. However, I felt that separating them into utilities makes the logic clearer and keeps the fetchLibraries method more generic.
Hope it makes sense. Please share your thoughts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth a general review to set a standard so we know where to put stuff.
We do have situations where we have calls to the service outside the store but maybe we should think about moving all calls to services in the services folder and standardising naming to remove any ambiguity.
location_barcode.value, | ||
uniqueBarcodesArray.value, | ||
) | ||
if (success && exhaustedLibraries.length > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This message formatting should probably be handled by exhaustLibraryVolumeIfDestroyed
as exhaustedLibraries are only used for the message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again I have noticed this pattern where we are checking the length as well as success. It seems pertinent to move it handle response with a flag e.g. hasData.
I thought the same.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth a general review to set a standard so we know where to put stuff.
We do have situations where we have calls to the service outside the store but maybe we should think about moving all calls to services in the services folder and standardising naming to remove any ambiguity.
location_barcode.value, | ||
uniqueBarcodesArray.value, | ||
) | ||
if (success && exhaustedLibraries.length > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again I have noticed this pattern where we are checking the length as well as success. It seems pertinent to move it handle response with a flag e.g. hasData.
} from '@/stores/utilities/pacbioLibraries.js' | ||
import PacbioLibraryFactory from '@tests/factories/PacbioLibraryFactory.js' | ||
import { beforeEach, describe, expect, it } from 'vitest' | ||
import { libraryPayload } from '../../../../src/stores/utilities/pacbioLibraries' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a file type to pacbioLibraries?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added lots of advisory comments.
I struggled a bit to understand what was going on as there is a lot of mocking.
I don't think these comments should stop deployment from branch if it is working.
VITE_ENVIRONMENT=development | ||
VITE_DESTROYED_LOCATION_BARCODE=lw-destroyed-217 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are youn planning to add the destroyed location to the deployment project or just the .env files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is already added in deployment project https://github.com/sanger/deployment/pull/533
@@ -2,7 +2,8 @@ VITE_TRACTION_BASE_URL=http://traction | |||
VITE_TRACTION_GRAPHQL_URL=http://traction/graphql | |||
VITE_PRINTMYBARCODE_BASE_URL=http://printmybarcode | |||
VITE_SAMPLEEXTRACTION_BASE_URL=http://sampleextraction | |||
VITE_LABWHERE_BASE_URL=http://labwhere | |||
VITE_LABWHERE_BASE_URL=http://localhost:3003 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to do this in .env.development.local
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is an e2e test to check for volume exhaustion when the entered location barcode matches the destroyed location barcode, as specified in the corresponding .env file. This test will fail during CI if the correct configuration is not set. Is there are any better approaches to handle this scenario?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ok. That is a problem. How does it work for all of our other api calls. We don't set traction url to a real one? It sounds like the intercept is not being handled correctly maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, we are simply comparing the entered barcode with the value of the environment variable read within the method. I think this is different from other cases where we can intercept commands to mock network requests and responses, eliminating the need for the real ones. I tried various approaches, such as using Cypress config to define a value, but it didn't work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand now. It is the barcode you are checking which is why it needs to be in .env
exhaustLibrayVolume, | ||
formatAndTransformLibraries, | ||
} from '@/stores/utilities/pacbioLibraries.js' | ||
import { getPacbioLibraryResources } from '@/services/traction/PacbioLibrary.js' | ||
|
||
const labwhereFetch = FetchWrapper(import.meta.env['VITE_LABWHERE_BASE_URL'], 'LabWhere') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Advisory: Creating the variables like this rather than using dependency injection makes it more difficult to test which is why you need to mock fetch globally I think!
A different way to do it would be to pass a type into the function which could have the various bits of configuration.
describe('client', () => { | ||
const mockFetch = vi.fn() | ||
const labwhereLocationsFactory = LabwhereLocationsFactory() | ||
beforeEach(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what I am referring to above.
We are essentially mocking fetch globally because of what we are doing in the client.
] | ||
|
||
beforeEach(() => { | ||
vi.clearAllMocks() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not entirely sure what is going on but would be slightly concerned that we are pretty much mocking all of the functions. It would be good to know why. This could create technical debt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ones you mentioned are not included as part of this PR.
The current implementation of the LabWhere client methods and FetchWrapper directly calls the fetch API to interact with LabWhere services. I believe this approach was taken because the LabWhere APIs do not always return JSON responses, and the client methods are designed as wrappers around these APIs to handle various response formats and content types.
These methods are globally mocked since all exported methods involve calling LabWhere, and the tests need to simulate different response formats for different methods. As you mentioned, it could likely be rewritten to pass in a fetch function, allowing tests to be written without relying on global mocking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice piece of work.
I think we could also use dependency injection for the destroyed location barcode and turn it into a type but I think you have done more than enough on this for now. There will be more work on location tracking so we can look again in the future.
Closes #1780
Changes proposed in this pull request
Instructions for Reviewers
[All PRs] - Confirm PR template filled
[Feature Branches] - Review code
[Production Merges to
main
]- Check story numbers included
- Check for debug code
- Check version