Skip to content

Commit

Permalink
chore: add tasks permission tests
Browse files Browse the repository at this point in the history
  • Loading branch information
stepan662 committed Sep 20, 2024
1 parent fea46df commit ec4b31c
Show file tree
Hide file tree
Showing 11 changed files with 147 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@ import io.tolgee.development.testDataBuilder.builders.ProjectBuilder
import io.tolgee.development.testDataBuilder.builders.TestDataBuilder
import io.tolgee.development.testDataBuilder.builders.UserAccountBuilder
import io.tolgee.exceptions.NotFoundException
import io.tolgee.model.Language
import io.tolgee.model.Project
import io.tolgee.model.UserAccount
import io.tolgee.model.enums.OrganizationRoleType
import io.tolgee.model.enums.ProjectPermissionType
import io.tolgee.model.enums.Scope
import io.tolgee.model.enums.*
import io.tolgee.model.key.Key
import org.springframework.core.io.ClassPathResource

class PermissionsTestData {
var projectBuilder: ProjectBuilder
var organizationBuilder: OrganizationBuilder
var admin: UserAccountBuilder
lateinit var addedProject: Project
lateinit var englishLanguage: Language
lateinit var keys: List<Key>

val root: TestDataBuilder =
TestDataBuilder().apply {
Expand All @@ -40,6 +44,10 @@ class PermissionsTestData {
val de = addGerman()
val cs = addCzech()

englishLanguage = en.self

addedProject = this.self

addPermission {
this.user = member.self
this.type = ProjectPermissionType.VIEW
Expand All @@ -63,6 +71,8 @@ class PermissionsTestData {
}
}

keys = keyBuilders.map { it.self }

keyBuilders[0].apply {
val screenshotResource =
ClassPathResource("development/testScreenshot.png", this::class.java.getClassLoader())
Expand Down Expand Up @@ -127,6 +137,47 @@ class PermissionsTestData {
}
}

fun addTasks(assignees: MutableSet<UserAccount>) {
projectBuilder.apply {
val translateTask =
addTask {
number = 1
name = "Assigned translate task"
type = TaskType.TRANSLATE
state = TaskState.NEW
project = addedProject
language = englishLanguage
this.assignees = assignees
author = admin.self
}.self

keys.take(1).forEach {
addTaskKey {
task = translateTask
key = it
}
}

val reviewTask =
addTask {
number = 2
name = "Unassigned review task"
type = TaskType.REVIEW
state = TaskState.NEW
project = addedProject
language = englishLanguage
author = admin.self
}.self

keys.take(2).forEach {
addTaskKey {
task = reviewTask
key = it
}
}
}
}

private fun getLanguagesByTags(tags: List<String>?) =
tags?.map { tag ->
projectBuilder.data.languages.find { it.self.tag == tag }?.self ?: throw NotFoundException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,10 @@ interface TaskRepository : JpaRepository<Task, Long> {
from task t
join task_key tt on (t.id = tt.task_id)
left join task_assignees ta on (ta.tasks_id = t.id)
left join user_account u on ta.assignees_id = u.id
left join user_account u on ta.assignees_id = u.id and u.id = :currentUserId
left join language l on (t.language_id = l.id)
where
tt.key_id in :keyIds
and u.id = :currentUserId
and l.deleted_at is null
and (t.state = 'IN_PROGRESS' or t.state = 'NEW')
order by l.id, tt.key_id, t.type desc, t.id desc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ class PermissionsE2eDataController() : AbstractE2eDataController() {
@RequestParam translateLanguageTags: List<String>?,
@RequestParam stateChangeLanguageTags: List<String>?,
): StandardTestDataResult {
this.permissionsTestData.addUserWithPermissions(
scopes = Scope.parse(scopes).toList(),
type = type,
viewLanguageTags = viewLanguageTags,
translateLanguageTags = translateLanguageTags,
stateChangeLanguageTags = stateChangeLanguageTags,
)
val user =
this.permissionsTestData.addUserWithPermissions(
scopes = Scope.parse(scopes).toList(),
type = type,
viewLanguageTags = viewLanguageTags,
translateLanguageTags = translateLanguageTags,
stateChangeLanguageTags = stateChangeLanguageTags,
)
this.permissionsTestData.addTasks(mutableSetOf(user))
return generate()
}

Expand Down
3 changes: 2 additions & 1 deletion e2e/cypress/common/permissions/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { satisfiesLanguageAccess } from '../../../../webapp/src/fixtures/permiss
import { deleteSelected } from '../batchOperations';
import { waitForGlobalLoading } from '../loading';
import { confirmStandard, dismissMenu } from '../shared';
import { getCell } from '../state';
import { createTag } from '../tags';
import { createTranslation, editCell } from '../translations';
import { getLanguageId, getLanguages, ProjectInfo } from './shared';
Expand Down Expand Up @@ -56,7 +57,7 @@ export function testKeys(info: ProjectInfo) {
!scopes.includes('translations.edit') &&
scopes.includes('translations.view')
) {
cy.gcy('translations-table-cell-translation').first().click();
getCell('Czech text 1').click();
cy.gcy('global-editor').should('not.exist');
}

Expand Down
4 changes: 3 additions & 1 deletion e2e/cypress/common/permissions/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { testExport } from './export';
import { testIntegration } from './integration';
import { testKeys } from './keys';
import { testMembers } from './members';
import { testMyTasks } from './myTasks';
import {
getProjectInfo,
pageAcessibleWithoutErrors,
Expand Down Expand Up @@ -55,8 +56,9 @@ export function checkPermissions(projectInfo: ProjectInfo, settings: Settings) {
testDashboard(projectInfo);
break;
case 'project-menu-item-translations':
testKeys(projectInfo);
testMyTasks(projectInfo);
testTranslations(projectInfo);
testKeys(projectInfo);
testBatchOperations(projectInfo);
break;
case 'project-menu-item-members':
Expand Down
19 changes: 19 additions & 0 deletions e2e/cypress/common/permissions/myTasks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { dismissMenu } from '../shared';
import { visitTranslations } from '../translations';
import { pageAcessibleWithoutErrors, ProjectInfo } from './shared';

export function testMyTasks(projectInfo: ProjectInfo) {
cy.gcy('global-user-menu-button').click();
cy.gcy('user-menu-my-tasks').click();
cy.gcy('task-item-detail').click();
pageAcessibleWithoutErrors();

const scopes = projectInfo.project.computedPermission.scopes;
if (scopes.includes('tasks.edit')) {
cy.gcy('task-detail-field-name').get('input').should('be.enabled');
} else {
cy.gcy('task-detail-field-name').get('input').should('be.disabled');
}
dismissMenu();
visitTranslations(projectInfo.project.id);
}
36 changes: 35 additions & 1 deletion e2e/cypress/common/permissions/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,38 @@ export function testTranslations({ project, languages }: ProjectInfo) {
}

if (scopes.includes('translations.view')) {
// test task indicator
cy.waitForDom();
const english1 = getCell('English text 1');
english1
.findDcy('translations-task-indicator')
.should('be.visible')
.trigger('mouseover');
cy.gcy('task-tooltip-content')
.contains('Assigned translate task')
.should('be.visible');
getCell('English text 1')
.findDcy('translations-task-indicator')
.trigger('mouseout');

const english2 = getCell('English text 2');
english2
.findDcy('translations-task-indicator')
.should('be.visible')
.trigger('mouseover');
if (scopes.includes('tasks.view')) {
cy.gcy('task-tooltip-content')
.contains('Unassigned review task')
.should('be.visible');
} else {
cy.gcy('task-tooltip-content')
.contains('You have no access to view this task')
.should('be.visible');
}
getCell('English text 2')
.findDcy('translations-task-indicator')
.trigger('mouseout');

getRowTexts(1).forEach(([lang, text]) => {
if (languageAccess('translations.view', lang)) {
cy.gcy('translations-table-cell-translation')
Expand All @@ -46,8 +78,10 @@ export function testTranslations({ project, languages }: ProjectInfo) {

if (scopes.includes('translations.edit')) {
getRowTexts(1).forEach(([lang, text]) => {
if (languageAccess('translations.edit', lang)) {
// english translation is in task, so it's editable
if (languageAccess('translations.edit', lang) || lang === 'en') {
cy.gcy('translations-table-cell-translation').contains(text).click();
cy.waitForDom();
cy.gcy('global-editor').should('be.visible');

if (project.baseLanguage.tag !== lang) {
Expand Down
2 changes: 2 additions & 0 deletions e2e/cypress/support/dataCyType.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ declare namespace DataCy {
"task-select-item" |
"task-select-search" |
"task-state" |
"task-tooltip-content" |
"tasks-filter-menu" |
"tasks-header-add-task" |
"tasks-header-filter-select" |
Expand Down Expand Up @@ -593,6 +594,7 @@ declare namespace DataCy {
"user-delete-organization-message-item" |
"user-menu-language-switch" |
"user-menu-logout" |
"user-menu-my-tasks" |
"user-menu-organization-settings" |
"user-menu-organization-switch" |
"user-menu-server-administration" |
Expand Down
1 change: 1 addition & 0 deletions webapp/src/component/security/UserMenu/UserPresentMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ export const UserPresentMenu: React.FC = () => {
component={Link}
to={LINKS.MY_TASKS.build()}
selected={location.pathname === LINKS.MY_TASKS.build()}
data-cy="user-menu-my-tasks"
sx={{
display: 'flex',
justifyContent: 'space-between',
Expand Down
1 change: 1 addition & 0 deletions webapp/src/component/task/TaskTooltipContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const TaskTooltipContent = ({

return (
<Box
data-cy="task-tooltip-content"
sx={{ padding: 1, maxWidth: 400, minWidth: 250, position: 'relative' }}
onClick={stopAndPrevent()}
>
Expand Down
29 changes: 20 additions & 9 deletions webapp/src/views/projects/translations/cell/TranslationFlags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { stopAndPrevent } from 'tg.fixtures/eventHandler';
import { TaskTooltip } from 'tg.component/task/TaskTooltip';
import { Link } from 'react-router-dom';
import { getTaskRedirect } from 'tg.component/task/utils';
import { useProjectPermissions } from 'tg.hooks/useProjectPermissions';
import clsx from 'clsx';

type KeyWithTranslationsModel =
components['schemas']['KeyWithTranslationsModel'];
Expand Down Expand Up @@ -48,6 +50,10 @@ const StyledContainer = styled(Box)`
margin-left: -4px;
border-radius: 10px;
&.clickDisabled {
cursor: default;
}
&:hover .clearButton {
display: block;
}
Expand Down Expand Up @@ -76,6 +82,8 @@ export const TranslationFlags: React.FC<Props> = ({

const { updateTranslation } = useTranslationsActions();
const [taskDetailData, setTaskDetailData] = useState<TaskModel>();
const { satisfiesPermission } = useProjectPermissions();
const canViewTasks = satisfiesPermission('tasks.view');

const clearAutoTranslatedState = useApiMutation({
url: '/v2/projects/{projectId}/translations/{translationId}/dismiss-auto-translated-state',
Expand Down Expand Up @@ -129,18 +137,21 @@ export const TranslationFlags: React.FC<Props> = ({
return (
<StyledWrapper className={className}>
{task && (
<StyledContainer
component={Link}
data-cy="translations-task-indicator"
// @ts-ignore
to={getTaskRedirect(project, task.number)}
>
<TaskTooltip taskNumber={task.number} project={project}>
<TaskTooltip taskNumber={task.number} project={project}>
<StyledContainer
component={Link}
// @ts-ignore
to={
canViewTasks ? getTaskRedirect(project, task.number) : undefined
}
className={clsx({ clickDisabled: !canViewTasks })}
data-cy="translations-task-indicator"
>
<StyledImgWrapper>
<ClipboardCheck color={theme.palette.text.primary} />
</StyledImgWrapper>
</TaskTooltip>
</StyledContainer>
</StyledContainer>
</TaskTooltip>
)}
{translation.auto && (
<StyledContainer data-cy="translations-auto-translated-indicator">
Expand Down

0 comments on commit ec4b31c

Please sign in to comment.