Skip to content

Commit e268d7e

Browse files
committed
Merge branch 'main' into dev-1.17
2 parents 0d66d2c + e5ce681 commit e268d7e

File tree

7 files changed

+169
-23
lines changed

7 files changed

+169
-23
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
*Note: Numbers like (\#123) point to closed Pull Requests on the fractal-web repository.*
22

3+
# 1.16.1
4+
5+
* Improved handling of new default values in task version update (\#731);
6+
37
# 1.16.0
48

59
* Used `FRACTAL_BACKEND_RUNNER=local` instead of `local_experimental` (\#713);

__tests__/v2/VersionUpdate.test.js

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, it, expect, vi } from 'vitest';
1+
import { beforeEach, describe, it, expect, vi } from 'vitest';
22
import { fireEvent, render, screen } from '@testing-library/svelte';
33
import { readable } from 'svelte/store';
44

@@ -169,6 +169,66 @@ const taskGroups = /** @type {import('fractal-components/types/api').TaskGroupV2
169169
}
170170
],
171171
active: true
172+
},
173+
{
174+
id: 9,
175+
pkg_name: 'default_values',
176+
version: '0.0.1',
177+
task_list: [
178+
{
179+
id: 9,
180+
name: 'task_default_values',
181+
type: 'non_parallel',
182+
args_schema_non_parallel: {
183+
title: 'task_default_values',
184+
type: 'object',
185+
properties: {
186+
default_boolean1: {
187+
type: 'boolean',
188+
default: false
189+
}
190+
},
191+
additionalProperties: false
192+
},
193+
args_schema_parallel: null,
194+
taskgroupv2_id: 9
195+
}
196+
],
197+
active: true
198+
},
199+
{
200+
id: 10,
201+
pkg_name: 'default_values',
202+
version: '0.0.2',
203+
task_list: [
204+
{
205+
id: 10,
206+
name: 'task_default_values',
207+
type: 'non_parallel',
208+
args_schema_non_parallel: {
209+
title: 'task_default_values',
210+
type: 'object',
211+
properties: {
212+
default_boolean1: {
213+
type: 'boolean',
214+
default: false
215+
},
216+
default_boolean2: {
217+
type: 'boolean',
218+
default: true
219+
},
220+
default_string: {
221+
type: 'string',
222+
default: 'foo'
223+
}
224+
},
225+
additionalProperties: false
226+
},
227+
args_schema_parallel: null,
228+
taskgroupv2_id: 10
229+
}
230+
],
231+
active: true
172232
}
173233
]);
174234

@@ -202,6 +262,10 @@ function getMockedWorkflowTask() {
202262
}
203263

204264
describe('VersionUpdate', () => {
265+
beforeEach(() => {
266+
fetch.mockClear();
267+
});
268+
205269
it('update task without changing the arguments', async () => {
206270
const task = getTask('My Task', '1.2.3');
207271
const versions = /** @type {string[]} */ (
@@ -340,6 +404,64 @@ describe('VersionUpdate', () => {
340404
)
341405
).toBeDefined();
342406
});
407+
408+
it('update task with default parameters and no previous values', async () => {
409+
const task = getTask('task_default_values', '0.0.1');
410+
const versions = await checkVersions(task, 1);
411+
expect(versions[0]).toBe('0.0.2');
412+
413+
await fireEvent.change(screen.getByRole('combobox'), { target: { value: '0.0.2' } });
414+
415+
const btn = screen.getByRole('button', { name: 'Update' });
416+
expect(btn.disabled).eq(false);
417+
await fireEvent.click(btn);
418+
419+
expect(fetch).toHaveBeenNthCalledWith(
420+
2,
421+
expect.stringContaining('/wftask/replace-task'),
422+
expect.objectContaining({
423+
body: JSON.stringify({
424+
args_non_parallel: {
425+
default_boolean1: false,
426+
default_boolean2: true,
427+
default_string: 'foo',
428+
},
429+
args_parallel: null
430+
})
431+
})
432+
);
433+
});
434+
435+
it('update task with default parameters and previous values', async () => {
436+
const task = getTask('task_default_values', '0.0.1');
437+
const versions = await checkVersions(task, 1, {
438+
args_non_parallel: {
439+
default_boolean1: true,
440+
}, args_parallel: null
441+
});
442+
expect(versions[0]).toBe('0.0.2');
443+
444+
await fireEvent.change(screen.getByRole('combobox'), { target: { value: '0.0.2' } });
445+
446+
const btn = screen.getByRole('button', { name: 'Update' });
447+
expect(btn.disabled).eq(false);
448+
await fireEvent.click(btn);
449+
450+
expect(fetch).toHaveBeenNthCalledWith(
451+
2,
452+
expect.stringContaining('/wftask/replace-task'),
453+
expect.objectContaining({
454+
body: JSON.stringify({
455+
args_non_parallel: {
456+
default_boolean1: true,
457+
default_boolean2: true,
458+
default_string: 'foo',
459+
},
460+
args_parallel: null
461+
})
462+
})
463+
);
464+
});
343465
});
344466

345467
/**

docs/version-compatibility.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ The following table shows which `fractal-server` versions are compatible with wh
44

55
| fractal-web | fractal-server |
66
|-------------|----------------|
7+
| 1.16.1 | 2.13.1 |
78
| 1.16.0 | 2.13.1 |
89
| 1.15.0 | 2.11.0 |
910
| 1.14.0 | 2.10.1 |

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "fractal-web",
3-
"version": "1.16.0",
3+
"version": "1.16.1",
44
"private": true,
55
"scripts": {
66
"dev": "vite dev",

src/lib/components/v2/workflow/VersionUpdate.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@
159159
headers.set('Content-Type', 'application/json');
160160
161161
const response = await fetch(
162-
`/api/v2/project/${$page.params.projectId}/workflow/${workflowTask.workflow_id}/wftask/replace-task/?workflow_task_id=${workflowTask.id}&task_id=${newTaskId}`,
162+
`/api/v2/project/${$page.params.projectId}/workflow/${workflowTask.workflow_id}/wftask/replace-task?workflow_task_id=${workflowTask.id}&task_id=${newTaskId}`,
163163
{
164164
method: 'POST',
165165
credentials: 'include',

src/lib/components/v2/workflow/VersionUpdateFixArgs.svelte

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
<script>
22
import { deepCopy } from '$lib/common/component_utilities';
33
import { AlertError } from '$lib/common/errors';
4-
import { stripIgnoredProperties, getPropertiesToIgnore, SchemaValidator } from 'fractal-components';
4+
import {
5+
stripIgnoredProperties,
6+
getPropertiesToIgnore,
7+
SchemaValidator,
8+
stripNullAndEmptyObjectsAndArrays
9+
} from 'fractal-components';
10+
import { getJsonSchemaData } from 'fractal-components/jschema/jschema_initial_data';
511
612
/** @type {import('fractal-components/types/api').WorkflowTaskV2} */
713
export let workflowTask;
@@ -53,34 +59,32 @@
5359
export function checkArgumentsWithNewSchema() {
5460
const oldArgs = (parallel ? workflowTask.args_parallel : workflowTask.args_non_parallel) || {};
5561
originalArgs = JSON.stringify(oldArgs, null, 2);
56-
validateArguments(oldArgs);
62+
const newArgs = { ...getDefaultValues(), ...oldArgs };
63+
validateArguments(newArgs);
5764
return displayTextarea;
5865
}
5966
6067
export function getNewArgs() {
61-
argsToBeFixed !== ''
62-
? JSON.parse(argsToBeFixed)
63-
: (parallel ? workflowTask.args_parallel : workflowTask.args_non_parallel) || {};
68+
if (argsToBeFixed !== '') {
69+
return JSON.parse(argsToBeFixed);
70+
}
71+
const args = (parallel ? workflowTask.args_parallel : workflowTask.args_non_parallel) || {};
72+
return { ...getDefaultValues(), ...args };
73+
}
74+
75+
function getDefaultValues() {
76+
const newSchema = getNewSchema();
77+
const schemaDefaultData = getJsonSchemaData(newSchema, updateCandidate.args_schema_version);
78+
return stripNullAndEmptyObjectsAndArrays(schemaDefaultData || {});
6479
}
6580
6681
/**
6782
* @param {object} args
6883
*/
6984
function validateArguments(args) {
70-
let newSchema =
71-
/** @type {import('fractal-components/types/jschema').JSONSchemaObjectProperty} */ (
72-
'args_schema' in updateCandidate
73-
? updateCandidate.args_schema
74-
: parallel
75-
? updateCandidate.args_schema_parallel
76-
: updateCandidate.args_schema_non_parallel
77-
);
85+
const newSchema = getNewSchema();
7886
const validator = new SchemaValidator(updateCandidate.args_schema_version, true);
79-
if ('properties' in newSchema) {
80-
newSchema = stripIgnoredProperties(newSchema, getPropertiesToIgnore(false));
81-
}
82-
const parsedSchema = deepCopy(newSchema);
83-
const isSchemaValid = validator.loadSchema(parsedSchema);
87+
const isSchemaValid = validator.loadSchema(newSchema);
8488
if (!isSchemaValid) {
8589
throw new AlertError('Invalid JSON schema');
8690
}
@@ -94,6 +98,21 @@
9498
}
9599
}
96100
101+
function getNewSchema() {
102+
let newSchema =
103+
/** @type {import('fractal-components/types/jschema').JSONSchemaObjectProperty} */ (
104+
'args_schema' in updateCandidate
105+
? updateCandidate.args_schema
106+
: parallel
107+
? updateCandidate.args_schema_parallel
108+
: updateCandidate.args_schema_non_parallel
109+
);
110+
if ('properties' in newSchema) {
111+
newSchema = stripIgnoredProperties(newSchema, getPropertiesToIgnore(false));
112+
}
113+
return deepCopy(newSchema);
114+
}
115+
97116
export function hasValidationErrors() {
98117
return (validationErrors?.length || 0) > 0;
99118
}

0 commit comments

Comments
 (0)