cvat/tests/cypress/e2e/actions_projects_models/markdown_base_pipeline.js

217 lines
8.4 KiB
JavaScript
Raw Normal View History

2025-09-16 01:19:40 +00:00
// Copyright (C) CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT
/// <reference types="cypress" />
context('Basic markdown pipeline', () => {
const projectName = 'A project with markdown';
const projectLabels = [{ name: 'label', attributes: [], type: 'any' }];
const taskName = 'A task with markdown';
const serverFiles = ['images/image_1.jpg', 'images/image_2.jpg', 'images/image_3.jpg'];
const additionalUsers = {
jobAssignee: {
username: 'md_job_assignee',
firstName: 'Firstname',
lastName: 'Lastname',
email: 'md_job_assignee@local.local',
password: 'Fv5Df3#f55g',
},
taskAssignee: {
username: 'md_task_assignee',
firstName: 'Firstname',
lastName: 'Lastname',
email: 'md_task_assignee@local.local',
password: 'UfdU21!dds',
},
notAssignee: {
username: 'md_not_assignee',
firstName: 'Firstname',
lastName: 'Lastname',
email: 'md_not_assignee@local.local',
password: 'UfdU21!dds',
},
};
let projectID = null;
let taskID = null;
let jobID = null;
let guideID = null;
let assetID = null;
before(() => {
cy.headlessLogout();
cy.visit('/auth/login');
for (const user of Object.values(additionalUsers)) {
cy.headlessCreateUser(user);
}
cy.login();
cy.get('.cvat-tasks-page').should('exist').and('be.visible');
cy.headlessCreateProject({
labels: projectLabels,
name: projectName,
}).then((response) => {
projectID = response.projectID;
cy.headlessCreateTask({
labels: [],
name: taskName,
project_id: projectID,
source_storage: { location: 'local' },
target_storage: { location: 'local' },
}, {
server_files: serverFiles,
image_quality: 70,
use_zip_chunks: true,
use_cache: true,
sorting_method: 'lexicographical',
}).then((taskResponse) => {
taskID = taskResponse.taskID;
[jobID] = taskResponse.jobIDs;
cy.openTaskById(taskID);
cy.assignTaskToUser(additionalUsers.taskAssignee.username);
cy.assignJobToUser(jobID, additionalUsers.jobAssignee.username);
});
});
});
after(() => {
cy.getAuthKey().then((authKey) => {
cy.deleteUsers(authKey, [
additionalUsers.jobAssignee.username,
additionalUsers.taskAssignee.username,
additionalUsers.notAssignee.username,
]);
cy.deleteTasks(authKey, [taskName]);
cy.deleteProjects(authKey, [projectName]);
});
});
describe('Markdown text can be bounded to the project', () => {
function openGuide() {
cy.get('.cvat-md-guide-control-wrapper button').click();
cy.url().should('to.match', /\/projects\/\d+\/guide/);
cy.get('.cvat-guide-page-editor-wrapper').should('exist').and('be.visible');
cy.get('.cvat-spinner-container').should('not.exist').then(() => {
if (guideID === null) {
cy.intercept('GET', '/api/projects/**').as('getProjects');
cy.window().then(async ($win) => {
$win.cvat.projects.get({ id: projectID }).then(([project]) => {
guideID = project.guideId;
});
});
cy.wait('@getProjects').its('response.statusCode').should('equal', 200);
}
});
}
function updatePlainText(value) {
cy.get('.cvat-guide-page-editor-wrapper textarea').clear();
cy.get('.cvat-guide-page-editor-wrapper textarea').type(value);
cy.intercept('PATCH', '/api/guides/**').as('patchGuide');
cy.get('.cvat-guide-page-bottom button').should('exist').and('be.visible').and('not.be.disabled').click();
cy.get('.cvat-spinner-container').should('not.exist');
cy.wait('@patchGuide').its('response.statusCode').should('equal', 200);
}
function setupGuide(value) {
cy.openProjectById(projectID);
openGuide();
updatePlainText(value);
}
it('Plain text', () => {
setupGuide('A plain markdown text');
});
it('Plain text with 3rdparty picture', () => {
const url = 'https://github.com/cvat-ai/cvat/raw/develop/site/content/en/images/cvat_poster_with_name.png';
const value = `Plain text with 3rdparty picture\n![image](${url})`;
cy.intercept('GET', url).as('getPicture');
setupGuide(value);
cy.wait('@getPicture');
});
it('Text and an uploaded picture', () => {
cy.window().then(($win) => {
cy.readFile('mounted_file_share/images/image_1.jpg', 'base64').should('exist').then((image) => {
const base64 = `data:image/jpg;base64,${image}`;
return fetch(base64);
}).then((res) => res.blob()).then((blob) => (
$win.cvat.assets.create(
new $win.File([blob], 'file.jpg', { type: 'image/jpeg' }), guideID,
)
)).then(({ uuid }) => {
assetID = uuid;
setupGuide(`Plain text with a picture\n![image](/api/assets/${uuid})`);
});
});
});
after(() => {
cy.logout();
});
});
describe('Staff can see markdown', () => {
function checkGuideAndAssetAvailableOnAnnotationView() {
// when open job for the first time, guide is opened automatically
cy.visit(`/tasks/${taskID}/jobs/${jobID}`);
cy.intercept('GET', `/api/assets/${assetID}**`).as('assetGet');
cy.get('.cvat-annotation-view-markdown-guide-modal button').contains('OK').click();
cy.wait('@assetGet');
// when reopen the job, guide is not opened automatically, but can be opened manually
cy.reload();
cy.get('.cvat-annotation-header-guide-button').should('not.exist');
cy.get('.cvat-annotation-header-guide-button').should('exist').and('be.visible').click();
cy.get('.cvat-annotation-view-markdown-guide-modal').should('exist').and('be.visible');
cy.get('.cvat-annotation-view-markdown-guide-modal button').contains('OK').click();
// when there is a request to open in a link, the guide is opened automatically
cy.visit(`/tasks/${taskID}/jobs/${jobID}?openGuide`);
cy.get('.cvat-annotation-header-guide-button').should('not.exist');
cy.get('.cvat-annotation-view-markdown-guide-modal button').contains('OK').click();
}
beforeEach(() => {
cy.clearLocalStorage('seenGuides');
});
afterEach(() => {
cy.logout();
});
it('Project owner can see markdown on annotation view', () => {
cy.login();
checkGuideAndAssetAvailableOnAnnotationView();
});
it('Job assignee can see markdown on annotation view', () => {
cy.login(additionalUsers.jobAssignee.username, additionalUsers.jobAssignee.password);
checkGuideAndAssetAvailableOnAnnotationView();
});
it('Task assignee can see markdown on annotation view', () => {
cy.login(additionalUsers.taskAssignee.username, additionalUsers.taskAssignee.password);
checkGuideAndAssetAvailableOnAnnotationView();
});
it('Not assignee can not access the guide and the asset', () => {
cy.login(additionalUsers.notAssignee.username, additionalUsers.notAssignee.password);
cy.request({
method: 'GET',
url: `/api/guides/${guideID}`,
failOnStatusCode: false,
}).its('status').should('equal', 403);
cy.request({
method: 'GET',
url: `/api/assets/${assetID}`,
failOnStatusCode: false,
}).its('status').should('equal', 403);
});
});
});