Skip to content

Commit

Permalink
Merge pull request #583 from fractal-analytics-platform/align-server-2.7
Browse files Browse the repository at this point in the history
Alignment with fractal-server 2.7
  • Loading branch information
zonia3000 authored Oct 11, 2024
2 parents d02e6ea + 7a9a827 commit 3151f5e
Show file tree
Hide file tree
Showing 52 changed files with 1,050 additions and 842 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/end_to_end_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,9 @@ jobs:
env:
TEST_VERSION: v2
FRACTAL_RUNNER_BACKEND: local_experimental

- name: Archive test results
uses: actions/upload-artifact@v4
with:
name: test-results-folder
path: test-results
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
*Note: Numbers like (\#123) point to closed Pull Requests on the fractal-web repository.*

# Unreleased

* Alignment with fractal-server 2.7 (\#583):
* Removed owner from v2 tasks;
* Displayed workflow task warning message;
* Implemented selection of group in task creation;
* First implementation of new workflow task modal;
* Used new group_ids_names field;
* Changed "new version available" icon;
* Renamed source to label in custom python env task creation;
* Removed kind from admin tasks page;

# 1.8.0

* Drop Node 16 support (\#574);
Expand Down
94 changes: 94 additions & 0 deletions __tests__/v2/AddSingleTask.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { describe, it, beforeEach, expect, vi } from 'vitest';
import { render, screen } from '@testing-library/svelte';
import userEvent from '@testing-library/user-event';

// Mocking fetch
global.fetch = vi.fn();

const mockedUser = {
group_ids_names: [
[1, 'All'],
[2, 'Group2']
]
};

// The component to be tested must be imported after the mock setup
import AddSingleTask from '../../src/lib/components/v2/tasks/AddSingleTask.svelte';

describe('AddSingleTask', () => {
beforeEach(() => {
fetch.mockClear();
});

it('Add single task associated with specific group', async () => {
const user = userEvent.setup();

fetch.mockResolvedValue({
ok: true,
status: 200,
json: async () => ({})
});

render(AddSingleTask, {
props: {
user: mockedUser,
addNewTasks: vi.fn()
}
});

await user.type(screen.getByRole('textbox', { name: 'Task name' }), 'test-task');
await user.type(screen.getByRole('textbox', { name: 'Command non parallel' }), 'command');
await user.type(screen.getByRole('textbox', { name: 'Source' }), 'task-source');
await user.selectOptions(screen.getByRole('combobox', { name: 'Group' }), 'Group2');
await user.click(screen.getByRole('button', { name: 'Create' }));

expect(fetch).toHaveBeenCalledWith(
'/api/v2/task?private=false&user_group_id=2',
expect.objectContaining({
body: JSON.stringify({
name: 'test-task',
command_non_parallel: 'command',
source: 'task-source',
input_types: {},
output_types: {}
})
})
);
});

it('Add private task', async () => {
const user = userEvent.setup();

fetch.mockResolvedValue({
ok: true,
status: 200,
json: async () => ({})
});

render(AddSingleTask, {
props: {
user: mockedUser,
addNewTasks: vi.fn()
}
});

await user.type(screen.getByRole('textbox', { name: 'Task name' }), 'test-task');
await user.type(screen.getByRole('textbox', { name: 'Command non parallel' }), 'command');
await user.type(screen.getByRole('textbox', { name: 'Source' }), 'task-source');
await user.click(screen.getByText('Private task'));
await user.click(screen.getByRole('button', { name: 'Create' }));

expect(fetch).toHaveBeenCalledWith(
'/api/v2/task?private=true',
expect.objectContaining({
body: JSON.stringify({
name: 'test-task',
command_non_parallel: 'command',
source: 'task-source',
input_types: {},
output_types: {}
})
})
);
});
});
166 changes: 166 additions & 0 deletions __tests__/v2/AddWorkflowTaskModal.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import { describe, it, beforeEach, expect, vi } from 'vitest';
import { render, screen, waitFor } from '@testing-library/svelte';

// Mocking fetch
global.fetch = vi.fn();

// Mocking bootstrap.Modal
class MockModal {
constructor() {
this.show = vi.fn();
this.hide = vi.fn();
}
}
MockModal.getInstance = vi.fn();

global.window.bootstrap = {
Modal: MockModal
};

const mockedWorkflow = {
id: 20,
name: 'test',
project_id: 24,
task_list: []
};

// The component to be tested must be imported after the mock setup
import AddWorkflowTaskModal from '../../src/lib/components/v2/workflow/AddWorkflowTaskModal.svelte';

describe('AddWorkflowTaskModal', () => {
beforeEach(() => {
fetch.mockClear();
});

it('Display task with loosely valid version', async () => {
fetch.mockResolvedValue({
ok: true,
status: 200,
json: async () => [
{
id: 1,
task_list: [
{
id: 1,
name: 'test_task',
taskgroupv2_id: 1,
category: null,
modality: null,
authors: null,
tags: []
}
],
user_id: 1,
user_group_id: 1,
pkg_name: 'test_task_package',
version: '0.0.1',
active: true
},
{
id: 2,
task_list: [
{
id: 2,
name: 'test_task',
taskgroupv2_id: 2,
category: null,
modality: null,
authors: null,
tags: []
}
],
user_id: 1,
user_group_id: 1,
pkg_name: 'test_task_package',
version: '0.7.10.dev4+g4c8ebe3',
active: true
}
]
});

const result = render(AddWorkflowTaskModal, {
props: {
workflow: mockedWorkflow,
onWorkflowTaskAdded: vi.fn()
}
});

result.component.show();

await waitFor(() => screen.getByText(/Add new workflow task/));
expect(fetch).toHaveBeenCalledWith('/api/v2/task-group', expect.anything());
await waitFor(() => screen.getAllByText(/test_task/));

const dropdown = screen.getByRole('combobox');
expect(dropdown.options.length).eq(2);
expect(dropdown.options[0].text).eq('0.7.10.dev4+g4c8ebe3');
expect(dropdown.options[1].text).eq('0.0.1');
expect(dropdown.value).eq('0.7.10.dev4+g4c8ebe3');
});

it('Display task with invalid version', async () => {
fetch.mockResolvedValue({
ok: true,
status: 200,
json: async () => [
{
id: 1,
task_list: [
{
id: 1,
name: 'test_task',
taskgroupv2_id: 1,
category: null,
modality: null,
authors: null,
tags: []
}
],
user_id: 1,
user_group_id: 1,
pkg_name: 'test_task_package',
version: '0.0.1',
active: true
},
{
id: 2,
task_list: [
{
id: 2,
name: 'test_task',
taskgroupv2_id: 2,
category: null,
modality: null,
authors: null,
tags: []
}
],
user_id: 1,
user_group_id: 1,
pkg_name: 'test_task_package',
version: 'INVALID',
active: true
}
]
});

const result = render(AddWorkflowTaskModal, {
props: {
workflow: mockedWorkflow,
onWorkflowTaskAdded: vi.fn()
}
});

result.component.show();

await waitFor(() => screen.getByText(/Add new workflow task/));
expect(fetch).toHaveBeenCalledWith('/api/v2/task-group', expect.anything());
await waitFor(() => screen.getAllByText(/test_task/));

const dropdown = screen.getByRole('combobox');
expect(dropdown.options.length).eq(2);
expect(dropdown.options[0].text).eq('0.0.1');
expect(dropdown.options[1].text).eq('INVALID');
expect(dropdown.value).eq('0.0.1');
});
});
83 changes: 83 additions & 0 deletions __tests__/v2/TaskCollection.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { describe, it, beforeEach, expect, vi } from 'vitest';
import { render, screen } from '@testing-library/svelte';
import userEvent from '@testing-library/user-event';

// Mocking fetch
global.fetch = vi.fn();

// Mocking public variables
vi.mock('$env/dynamic/public', () => {
return { env: {} };
});

const mockedUser = {
group_ids_names: [
[1, 'All'],
[2, 'Group2']
]
};

// The component to be tested must be imported after the mock setup
import TaskCollection from '../../src/lib/components/v2/tasks/TaskCollection.svelte';

describe('TaskCollection', () => {
beforeEach(() => {
fetch.mockClear();
});

it('Add single task associated with specific group', async () => {
const user = userEvent.setup();

fetch.mockResolvedValue({
ok: true,
status: 200,
json: async () => ({ data: {} })
});

render(TaskCollection, {
props: {
user: mockedUser,
reloadTaskList: vi.fn()
}
});

await user.type(screen.getByRole('textbox', { name: 'Package' }), 'test-task');
await user.selectOptions(screen.getByRole('combobox', { name: 'Group' }), 'Group2');
await user.click(screen.getByRole('button', { name: 'Collect' }));

expect(fetch).toHaveBeenCalledWith(
'/api/v2/task/collect/pip?private=false&user_group_id=2',
expect.objectContaining({
body: JSON.stringify({ package: 'test-task' })
})
);
});

it('Add private task', async () => {
const user = userEvent.setup();

fetch.mockResolvedValue({
ok: true,
status: 200,
json: async () => ({ data: {} })
});

render(TaskCollection, {
props: {
user: mockedUser,
reloadTaskList: vi.fn()
}
});

await user.type(screen.getByRole('textbox', { name: 'Package' }), 'test-task');
await user.click(screen.getByText('Private task'));
await user.click(screen.getByRole('button', { name: 'Collect' }));

expect(fetch).toHaveBeenCalledWith(
'/api/v2/task/collect/pip?private=true',
expect.objectContaining({
body: JSON.stringify({ package: 'test-task' })
})
);
});
});
2 changes: 1 addition & 1 deletion __tests__/v2/UserEditor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe('UserEditor', () => {

const selectedUser = {
id: 1,
group_ids: []
group_ids_names: []
};

const initialSettings = {
Expand Down
5 changes: 0 additions & 5 deletions __tests__/v2/VersionUpdate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,6 @@ describe('VersionUpdate', () => {
expect(screen.getByText('Invalid JSON')).toBeDefined();
});

it('no new versions available for null owner', async () => {
const task = getTask('My Other Task', '1.2.3');
await checkVersions(task, 0);
});

it('no new versions available for admin owner', async () => {
const task = getTask('My Other Task', '1.3.0');
await checkVersions(task, 0);
Expand Down
Loading

0 comments on commit 3151f5e

Please sign in to comment.