Unverified Commit e0963c5b authored by Andrey Azov's avatar Andrey Azov Committed by GitHub
Browse files

Use updated endpoint for blast form submission (#739)

parent d7f4a8fa
Pipeline #273100 failed with stages
in 12 minutes and 18 seconds
......@@ -80,7 +80,10 @@ const mockState = merge({}, initialState, {
const expectedPayload = {
species: selectedSpecies,
querySequences: sequences.map((seq) => toFasta(seq)),
sequences: sequences.map((seq, index) => ({
id: index + 1,
value: toFasta(seq)
})),
parameters: {
title: jobName,
database,
......
......@@ -42,7 +42,7 @@ import type { BlastSubmission } from 'src/content/app/tools/blast/state/blast-re
export type PayloadParams = {
species: Species[];
querySequences: string[];
sequences: { id: number; value: string }[];
parameters: Partial<Record<BlastParameterName, string>> & {
title: string;
stype: SequenceType;
......@@ -100,13 +100,16 @@ const BlastJobSubmit = () => {
export const createBlastSubmissionData = (
blastFormData: BlastFormState
): PayloadParams => {
const sequences = blastFormData.sequences.map((sequence) =>
toFasta(sequence)
);
// labelling sequences with complely artificial identifiers
// so that job ids in the response can be matched to individual combinations of sequences and genome ids
const sequences = blastFormData.sequences.map((sequence, index) => ({
id: index + 1,
value: toFasta(sequence)
}));
return {
species: blastFormData.selectedSpecies,
querySequences: sequences,
sequences,
parameters: {
title: blastFormData.settings.jobName,
database: blastFormData.settings.parameters.database,
......
......@@ -24,16 +24,25 @@ import type { BlastSubmission } from '../blast-results/blastResultsSlice';
export type BlastSubmissionPayload = {
species: Species[];
querySequences: string[];
sequences: { id: number; value: string }[];
parameters: Record<string, string>;
};
export type BlastSubmissionResponse = {
submissionId: string;
jobs: Array<{
jobId?: string;
error?: string;
}>;
submission_id: string;
jobs: Array<SubmittedJob | RejectedJob>;
};
export type SubmittedJob = {
job_id: string;
sequence_id: number;
genome_id: string;
};
export type RejectedJob = {
sequence_id: number;
genome_id: string;
error: string;
};
const blastApiSlice = restApiSlice.injectEndpoints({
......@@ -50,8 +59,8 @@ const blastApiSlice = restApiSlice.injectEndpoints({
>({
query(payload) {
const body = {
genomeIds: payload.species.map(({ genome_id }) => genome_id),
querySequences: payload.querySequences,
genome_ids: payload.species.map(({ genome_id }) => genome_id),
query_sequences: payload.sequences,
parameters: payload.parameters
};
return {
......@@ -61,20 +70,25 @@ const blastApiSlice = restApiSlice.injectEndpoints({
};
},
transformResponse(response: BlastSubmissionResponse, _, payload) {
const { submissionId, jobs } = response;
const { submission_id: submissionId, jobs } = response;
// TODO: decide what to do when a submission returns error jobs
const results = jobs.map((job) => ({
jobId: job.jobId as string,
status: 'RUNNING',
seen: false,
data: null
}));
const results = jobs
.filter((job): job is SubmittedJob => 'job_id' in job)
.map((job) => ({
jobId: job.job_id,
genomeId: job.genome_id,
sequenceId: job.sequence_id,
status: 'RUNNING',
seen: false,
data: null
}));
return {
submissionId,
submission: {
submittedData: {
species: payload.species,
sequences: payload.querySequences,
sequences: payload.sequences,
parameters: payload.parameters
},
results,
......
......@@ -37,11 +37,13 @@ export type JobStatus =
export type BlastSubmission = {
submittedData: {
species: Species[];
sequences: string[]; // Or perhaps parsed sequences?
sequences: { id: number; value: string }[]; // TODO: consider whether to have strings or parsed sequences
parameters: Partial<Record<BlastParameterName, string>>;
};
results: Array<{
jobId: string;
sequenceId: number;
genomeId: string;
status: JobStatus;
seen: boolean;
data: null; // TODO: add data type
......
......@@ -142,7 +142,7 @@ describe('blast epics', () => {
'http://tools-api-url/blast/jobs/status/:jobId',
(req, res, ctx) => {
const { jobId } = req.params;
if (jobId === firstJobInResponse.jobId) {
if (jobId === firstJobInResponse.job_id) {
firstJobPollCount++;
return firstJobPollCount >= firstJobMaxPollCount
? res(ctx.json(createFinishedJobStatusResponse()))
......@@ -176,14 +176,14 @@ describe('blast epics', () => {
// check that the job status gets updated in indexedDB
expect(blastStorageService.updateSavedBlastJob).toHaveBeenCalledWith({
submissionId: successfulSubmission.submissionId,
jobId: firstJobInResponse.jobId,
submissionId: successfulSubmission.submission_id,
jobId: firstJobInResponse.job_id,
fragment: { status: 'FINISHED' }
});
expect(blastStorageService.updateSavedBlastJob).toHaveBeenCalledWith({
submissionId: successfulSubmission.submissionId,
jobId: secondJobInResponse.jobId,
submissionId: successfulSubmission.submission_id,
jobId: secondJobInResponse.job_id,
fragment: { status: 'FAILURE' }
});
});
......@@ -199,7 +199,7 @@ describe('blast epics', () => {
const jobId = req.params.jobId as string;
if (!jobMap[jobId]) {
jobMap[jobId] = true;
if (jobId === firstJobInResponse.jobId) {
if (jobId === firstJobInResponse.job_id) {
return res(ctx.status(404));
} else {
return res.networkError('Failed to connect');
......@@ -236,7 +236,7 @@ describe('blast epics', () => {
jest
.spyOn(blastStorageService, 'getAllBlastSubmissions')
.mockImplementation(async () => ({
[successfulSubmission.submissionId]: storedBlastSubmission
[successfulSubmission.submission_id]: storedBlastSubmission
}));
it('polls status of unfinished jobs', async () => {
......@@ -273,7 +273,7 @@ describe('blast epics', () => {
// check that the job status gets updated in indexedDB
expect(blastStorageService.updateSavedBlastJob).toHaveBeenCalledWith({
submissionId: successfulSubmission.submissionId,
submissionId: successfulSubmission.submission_id,
jobId: unfinishedJob.jobId,
fragment: { status: 'FINISHED' }
});
......
......@@ -19,7 +19,8 @@ import times from 'lodash/times';
import type {
BlastSubmissionPayload,
BlastSubmissionResponse
BlastSubmissionResponse,
SubmittedJob
} from 'src/content/app/tools/blast/state/blast-api/blastApiSlice';
import type {
BlastSubmission,
......@@ -38,7 +39,7 @@ export const createBlastSubmission = (
const submission = {
species: [human],
querySequences: ['ACGT'],
sequences: [{ id: 1, value: 'ACGT' }],
parameters: {}
};
......@@ -52,7 +53,7 @@ export const createBlastSubmissionResponse = (
fragment: Partial<BlastSubmissionResponse> = {}
): BlastSubmissionResponse => {
const submission = {
submissionId: faker.datatype.uuid(),
submission_id: faker.datatype.uuid(),
jobs: times(3, createSuccessfulBlastJobInSubmissionResponse)
};
......@@ -62,11 +63,14 @@ export const createBlastSubmissionResponse = (
};
};
export const createSuccessfulBlastJobInSubmissionResponse = () => {
return {
jobId: faker.datatype.uuid()
export const createSuccessfulBlastJobInSubmissionResponse =
(): SubmittedJob => {
return {
genome_id: 'human-genome-id',
sequence_id: 1,
job_id: faker.datatype.uuid()
};
};
};
export const createRunningJobStatusResponse = (): { status: JobStatus } => ({
status: 'RUNNING'
......@@ -93,7 +97,7 @@ export const createStoredBlastSubmission = (
const submission = {
submittedData: {
species: [human],
sequences: ['ACGT'],
sequences: [{ id: 1, value: 'ACGT' }],
parameters: {}
},
results: [createStoredBlastJobResult()],
......@@ -111,6 +115,8 @@ export const createStoredBlastJobResult = (
) => {
return {
jobId: faker.datatype.uuid(),
sequenceId: 1,
genomeId: 'human-genome-id',
status: 'RUNNING' as JobStatus,
seen: false,
data: null,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment