Skip to content

Commit

Permalink
remove empty subjectSets array from fetchWorkflowsHelper (#6450)
Browse files Browse the repository at this point in the history
  • Loading branch information
goplayoutside3 authored Nov 12, 2024
1 parent 0859941 commit 5c66752
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 138 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import { panoptes } from '@zooniverse/panoptes-js'
import getServerSideAPIHost from '@helpers/getServerSideAPIHost'
import logToSentry from '@helpers/logger/logToSentry.js'

async function fetchWorkflowData(workflows, env) {
/* Helper function to fetch data for multiple workflows */
async function fetchWorkflowData(workflows, env, complete = false) {
const { headers, host } = getServerSideAPIHost(env)
try {
const query = {
complete: false,
complete,
env,
fields: 'completeness,configuration,display_name,grouped,prioritized',
id: workflows.join(',')
Expand All @@ -20,6 +21,7 @@ async function fetchWorkflowData(workflows, env) {
}
}

/* Helper function to fetch workflow data regardless of completion status */
async function fetchSingleWorkflow(workflowID, env) {
const { headers, host } = getServerSideAPIHost(env)
try {
Expand Down Expand Up @@ -58,7 +60,8 @@ async function fetchDisplayNames(language, workflows, env) {
return displayNames
}

async function buildWorkflow(workflow, displayName, env) {
/* Attach the displayName to a workflow object once it is fetched */
async function buildWorkflow(workflow, displayName) {
const workflowData = {
completeness: workflow.completeness || 0,
configuration: workflow.configuration,
Expand All @@ -67,12 +70,12 @@ async function buildWorkflow(workflow, displayName, env) {
id: workflow.id,
links: workflow.links,
prioritized: workflow.prioritized,
subjectSets: []
}

return workflowData
}

/* order is specified by the project owner in the lab */
function orderWorkflows(workflows, order) {
const workflowsByID = {};
workflows.forEach((workflow) => { workflowsByID[workflow.id] = workflow; });
Expand All @@ -92,36 +95,53 @@ function orderWorkflows(workflows, order) {
async function fetchWorkflowsHelper(
/* the current locale */
language = 'en',
/* an array of workflow IDs to fetch */
/* an array of workflow IDs to fetch, usually from getStaticPageProps() */
workflowIDs,
/* a specific workflow ID to fetch */
/* a specific workflow ID to fetch, usually from getStaticPageProps() */
workflowID,
/* display order of workflow IDs, specified by the project owner. */
/* display order of workflow IDs, specified by the project owner in the lab. */
workflowOrder = [],
/* API environment, production | staging. */
env
) {
const workflows = await fetchWorkflowData(workflowIDs, env)
let returnedWorkflows = []

// Fetching multiple workflows for the project pages
// When a project has active, incomplete workflows, return those so volunteers classifies them
const incompleteWorkflows = await fetchWorkflowData(workflowIDs, env, false)
if (incompleteWorkflows?.length) {
returnedWorkflows = incompleteWorkflows
}

// If `complete: false` returns zero workflows, fetch all active workflows regardless of completeness
// so volunteers can still view the Classify page for a finished project or project out of data
if (!incompleteWorkflows?.length) {
const completedWorkflows = await fetchWorkflowData(workflowIDs, env, true)
returnedWorkflows = completedWorkflows
}

// When a single workflowID is provided, this usually means the project has 1 active workflow
// or the url includes is a specific workflow id
if (workflowID) {
const activeWorkflow = workflows.find(workflow => workflow.id === workflowID)
const activeWorkflow = returnedWorkflows.find(workflow => workflow.id === workflowID)
if (!activeWorkflow) {
/*
Always fetch specified workflows, even if they're complete.
*/
const workflow = await fetchSingleWorkflow(workflowID, env)
workflows.push(workflow)
returnedWorkflows.push(workflow)
}
}
const workflowIds = workflows.map(workflow => workflow.id)
const displayNames = await fetchDisplayNames(language, workflowIds, env)

const awaitWorkflows = workflows.map(workflow => {
// Get the display names of each workflow for the WorkflowSelector UI depending on language
const workflowIds = returnedWorkflows.map(workflow => workflow.id)
const displayNames = await fetchDisplayNames(language, workflowIds, env)
const awaitWorkflows = returnedWorkflows.map(workflow => {
const displayName = displayNames[workflow.id] || workflow.display_name
return buildWorkflow(workflow, displayName, env)
return buildWorkflow(workflow, displayName)
})
const workflowStatuses = await Promise.allSettled(awaitWorkflows)
const workflowsWithSubjectSets = workflowStatuses.map(result => result.value || result.reason)
const orderedWorkflows = orderWorkflows(workflowsWithSubjectSets, workflowOrder)
const workflowsWithDisplayNames = workflowStatuses.map(promiseResult => promiseResult.value || promiseResult.reason)

// Order the workflows according to order set my project owner in the lab
const orderedWorkflows = orderWorkflows(workflowsWithDisplayNames, workflowOrder)
return orderedWorkflows
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,36 @@ describe('Helpers > fetchWorkflowsHelper', function () {
}
]

const COMPLETED_WORKFLOW = {
id: '2',
completeness: 1,
configuration: {
level: 2
const COMPLETED_WORKFLOWS = [
{
id: '1',
completeness: 1,
configuration: {
level: 1
},
grouped: false,
prioritized: false,
links: {
subject_sets: ['1', '2', '3']
}
},
grouped: true,
prioritized: true,
links: {
subject_sets: ['1', '2', '3']
{
id: '2',
completeness: 1,
configuration: {
level: 2
},
grouped: true,
prioritized: true,
links: {
subject_sets: ['1', '2', '3']
}
}
}
]

// `translated_id` is a number because of a bug in the translations API :(
// This comment ^ was added in https://github.com/zooniverse/front-end-monorepo/pull/1077
// I think it just means translated_id is type number whereas workflow.id from panotpes is a string
const TRANSLATIONS = [
{
translated_id: 1,
Expand All @@ -65,30 +81,20 @@ describe('Helpers > fetchWorkflowsHelper', function () {
.get('/translations')
.query(true)
.reply(200, {
translations: TRANSLATIONS.slice(0, 1)
translations: [ TRANSLATIONS[0] ]
})
.get('/workflows')
.query(true)
.reply(200, {
workflows: WORKFLOWS.slice(0, 1)
workflows: [ WORKFLOWS[0] ]
})

const result = await fetchWorkflowsHelper('en', ['1'])

expect(result).to.deep.equal([
{
completeness: 0.4,
configuration: {
level: 1
},
grouped: false,
prioritized: false,
id: '1',
displayName: 'Foo',
links: {
subject_sets: ['1', '2', '3']
},
subjectSets: []
...WORKFLOWS[0],
displayName: 'Foo'
}
])
})
Expand All @@ -109,32 +115,12 @@ describe('Helpers > fetchWorkflowsHelper', function () {
const result = await fetchWorkflowsHelper('en', ['1', '2'])
expect(result).to.deep.equal([
{
completeness: 0.4,
configuration: {
level: 1
},
grouped: false,
prioritized: false,
id: '1',
displayName: 'Foo',
links: {
subject_sets: ['1', '2', '3']
},
subjectSets: []
...WORKFLOWS[0],
displayName: 'Foo'
},
{
completeness: 0.7,
configuration: {
level: 2
},
grouped: true,
prioritized: true,
id: '2',
displayName: 'Bar',
links: {
subject_sets: ['1', '2', '3']
},
subjectSets: []
...WORKFLOWS[1],
displayName: 'Bar'
}
])
})
Expand All @@ -156,39 +142,19 @@ describe('Helpers > fetchWorkflowsHelper', function () {
const result = await fetchWorkflowsHelper('en', ['1', '2'], '2')
expect(result).to.deep.equal([
{
completeness: 0.4,
configuration: {
level: 1
},
grouped: false,
prioritized: false,
id: '1',
displayName: 'Foo',
links: {
subject_sets: ['1', '2', '3']
},
subjectSets: []
...WORKFLOWS[0],
displayName: 'Foo'
},
{
completeness: 0.7,
configuration: {
level: 2
},
grouped: true,
prioritized: true,
id: '2',
displayName: 'Bar',
links: {
subject_sets: ['1', '2', '3']
},
subjectSets: []
...WORKFLOWS[1],
displayName: 'Bar'
}
])
})
})

describe('when all active workflows are complete', function () {
it('should return an empty array.', async function () {
it('should return all active workflows regardless of individual completeness', async function () {
const scope = nock('https://panoptes-staging.zooniverse.org/api')
.get('/translations')
.query(true)
Expand All @@ -198,11 +164,20 @@ describe('Helpers > fetchWorkflowsHelper', function () {
.get('/workflows')
.query(true)
.reply(200, {
workflows: []
workflows: COMPLETED_WORKFLOWS
})

const result = await fetchWorkflowsHelper('en', ['1', '2'])
expect(result).to.be.empty()
expect(result).to.deep.equal([
{
...COMPLETED_WORKFLOWS[0],
displayName: 'Foo'
},
{
...COMPLETED_WORKFLOWS[1],
displayName: 'Bar'
}
])
})

it('should always return a specified workflow.', async function () {
Expand All @@ -215,29 +190,23 @@ describe('Helpers > fetchWorkflowsHelper', function () {
.get('/workflows')
.query(query => query.complete)
.reply(200, {
workflows: []
workflows: COMPLETED_WORKFLOWS
})
.get('/workflows')
.query(query => query.id == '2')
.reply(200, {
workflows: [ COMPLETED_WORKFLOW ]
workflows: COMPLETED_WORKFLOWS[1]
})

const result = await fetchWorkflowsHelper('en', ['1', '2'], '2')
expect(result).to.deep.equal([
{
completeness: 1,
configuration: {
level: 2
},
grouped: true,
prioritized: true,
id: '2',
displayName: 'Bar',
links: {
subject_sets: ['1', '2', '3']
},
subjectSets: []
...COMPLETED_WORKFLOWS[0],
displayName: 'Foo'
},
{
...COMPLETED_WORKFLOWS[1],
displayName: 'Bar'
}
])
})
Expand Down Expand Up @@ -295,32 +264,12 @@ describe('Helpers > fetchWorkflowsHelper', function () {
const workflows = await fetchWorkflowsHelper('en', ['1', '2'], undefined, ['2', '1'])
expect(workflows).to.deep.equal([
{
completeness: 0.7,
configuration: {
level: 2
},
grouped: true,
prioritized: true,
id: '2',
displayName: 'Bar',
links: {
subject_sets: ['1', '2', '3']
},
subjectSets: []
...WORKFLOWS[1],
displayName: 'Bar'
},
{
completeness: 0.4,
configuration: {
level: 1
},
grouped: false,
prioritized: false,
id: '1',
displayName: 'Foo',
links: {
subject_sets: ['1', '2', '3']
},
subjectSets: []
...WORKFLOWS[0],
displayName: 'Foo'
}
])
})
Expand Down
Loading

0 comments on commit 5c66752

Please sign in to comment.