mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-06-17 11:59:30 +00:00
fix: always render detailed team permissions table in sidebar (#8108)
Remove the generic write/admin description block for AccessMode 2/3 and unconditionally display the unit-level permissions table. fixes #3517 ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [ ] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [X] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [X] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [X] I want the title to show in the release notes with a link to this pull request. - [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8108 Reviewed-by: Otto <otto@codeberg.org> Co-authored-by: Julian Schlarb <julian.schlarb@denktmit.de> Co-committed-by: Julian Schlarb <julian.schlarb@denktmit.de>
This commit is contained in:
parent
bd6f3243ab
commit
e70f48bd44
7 changed files with 140 additions and 8 deletions
|
@ -239,3 +239,15 @@
|
|||
num_members: 2
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
||||
-
|
||||
id: 25
|
||||
org_id: 17
|
||||
lower_name: super-user
|
||||
name: super-user
|
||||
description: ""
|
||||
authorize: 3
|
||||
num_repos: 0
|
||||
num_members: 0
|
||||
includes_all_repositories: 0
|
||||
can_create_org_repo: 0
|
||||
|
|
|
@ -329,3 +329,10 @@
|
|||
team_id: 22
|
||||
type: 3
|
||||
access_mode: 1
|
||||
|
||||
-
|
||||
id: 84
|
||||
org_id: 17
|
||||
team_id: 25
|
||||
type: 3
|
||||
access_mode: 3
|
||||
|
|
|
@ -642,7 +642,7 @@
|
|||
num_following: 0
|
||||
num_stars: 0
|
||||
num_repos: 2
|
||||
num_teams: 3
|
||||
num_teams: 4
|
||||
num_members: 4
|
||||
visibility: 0
|
||||
repo_admin_change_team_access: false
|
||||
|
|
|
@ -2985,8 +2985,6 @@ teams.invite_team_member.list = Pending invitations
|
|||
teams.delete_team_title = Delete team
|
||||
teams.delete_team_desc = Deleting a team revokes repository access from its members. Continue?
|
||||
teams.delete_team_success = The team has been deleted.
|
||||
teams.read_permission_desc = This team grants <strong>Read</strong> access: members can view and clone team repositories.
|
||||
teams.write_permission_desc = This team grants <strong>Write</strong> access: members can read from and push to team repositories.
|
||||
teams.admin_permission_desc = This team grants <strong>Administrator</strong> access: members can read from, push to and add collaborators to team repositories.
|
||||
teams.create_repo_permission_desc = Additionally, this team grants <strong>Create repository</strong> permission: members can create new repositories in organization.
|
||||
teams.repositories = Team repositories
|
||||
|
|
|
@ -42,11 +42,8 @@
|
|||
<li>{{ctx.Locale.Tr "org.teams.can_create_org_repo"}}</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
{{if (eq .Team.AccessMode 2)}}
|
||||
<h3>{{ctx.Locale.Tr "org.settings.permission"}}</h3>
|
||||
{{ctx.Locale.Tr "org.teams.write_permission_desc"}}
|
||||
{{else if (eq .Team.AccessMode 3)}}
|
||||
<h3>{{ctx.Locale.Tr "org.settings.permission"}}</h3>
|
||||
<h3>{{ctx.Locale.Tr "org.settings.permission"}}</h3>
|
||||
{{if (eq .Team.AccessMode 3)}}
|
||||
{{ctx.Locale.Tr "org.teams.admin_permission_desc"}}
|
||||
{{else}}
|
||||
<table class="ui table">
|
||||
|
|
116
tests/e2e/org-teams-overview.test.e2e.ts
Normal file
116
tests/e2e/org-teams-overview.test.e2e.ts
Normal file
|
@ -0,0 +1,116 @@
|
|||
// @watch start
|
||||
// templates/org/team/sidebar.tmpl
|
||||
// @watch end
|
||||
/* eslint playwright/expect-expect: ["error", { "assertFunctionNames": ["assertPermissionsDetails", "assertRestrictedAccess", "assertOwnerPermissions"] }] */
|
||||
import {expect, type Page} from '@playwright/test';
|
||||
import {test} from './utils_e2e.ts';
|
||||
|
||||
type Permission = 'No access' | 'Write' | 'Read';
|
||||
|
||||
const UNIT_VALUES = [
|
||||
'Code',
|
||||
'Issues',
|
||||
'Pull requests',
|
||||
'Releases',
|
||||
'Wiki',
|
||||
'External Wiki',
|
||||
'External issues',
|
||||
'Projects',
|
||||
'Packages',
|
||||
'Actions',
|
||||
] as const;
|
||||
|
||||
type Unit = typeof UNIT_VALUES[number];
|
||||
|
||||
const assertPermission = async (page: Page, name: Unit, permission: Permission) => {
|
||||
await expect.soft(page.getByRole('row', {name}).getByRole('cell').nth(1)).toHaveText(permission);
|
||||
};
|
||||
|
||||
const testTeamUrl = '/org/org17/teams/test_team';
|
||||
const reviewTeamUrl = '/org/org17/teams/review_team';
|
||||
const ownersUrl = '/org/org17/teams/owners';
|
||||
const adminUrl = '/org/org17/teams/super-user';
|
||||
|
||||
const cases: Record<string, { read?: Unit[], write?: Unit[] }> = {
|
||||
[testTeamUrl]: {write: ['Issues']},
|
||||
[reviewTeamUrl]: {read: ['Code']},
|
||||
};
|
||||
|
||||
const assertOwnerPermissions = async (page: Page, code: number = 200) => {
|
||||
const response = await page.goto(ownersUrl);
|
||||
expect(response?.status()).toBe(code);
|
||||
|
||||
await expect(page.getByText('Owners have full access to all repositories and have administrator access to the organization.')).toBeVisible();
|
||||
};
|
||||
|
||||
const assertAdminPermissions = async (page: Page, code: number = 200) => {
|
||||
const response = await page.goto(adminUrl);
|
||||
expect(response?.status()).toBe(code);
|
||||
|
||||
await expect(page.getByText('This team grants Administrator access: members can read from, push to and add collaborators to team repositories.')).toBeVisible();
|
||||
};
|
||||
|
||||
const assertRestrictedAccess = async (page: Page, ...urls: string[]) => {
|
||||
for (const url of urls) {
|
||||
expect((await page.goto(url))?.status(), 'should not see any details').toBe(404);
|
||||
}
|
||||
};
|
||||
|
||||
const assertPermissionsDetails = async (page: Page, url: (keyof typeof cases)) => {
|
||||
const response = await page.goto(url);
|
||||
expect(response?.status()).toBe(200);
|
||||
|
||||
const per = cases[url];
|
||||
|
||||
for (const unit of UNIT_VALUES) {
|
||||
if (per.read?.includes(unit)) {
|
||||
await assertPermission(page, unit, 'Read');
|
||||
} else if (per.write?.includes(unit)) {
|
||||
await assertPermission(page, unit, 'Write');
|
||||
} else {
|
||||
await assertPermission(page, unit, 'No access');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
test.describe('Orga team overview', () => {
|
||||
test.describe('admin', () => {
|
||||
test.use({user: 'user1'});
|
||||
|
||||
test('should see all', async ({page}) => {
|
||||
await assertPermissionsDetails(page, testTeamUrl);
|
||||
await assertPermissionsDetails(page, reviewTeamUrl);
|
||||
await assertOwnerPermissions(page);
|
||||
await assertAdminPermissions(page);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('owner', () => {
|
||||
test.use({user: 'user18'});
|
||||
|
||||
test('should see all', async ({page}) => {
|
||||
await assertPermissionsDetails(page, testTeamUrl);
|
||||
await assertPermissionsDetails(page, reviewTeamUrl);
|
||||
await assertOwnerPermissions(page);
|
||||
await assertAdminPermissions(page);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('reviewer team', () => {
|
||||
test.use({user: 'user29'});
|
||||
|
||||
test('should only see permissions for `reviewer team` and restricted access to other resources', async ({page}) => {
|
||||
await assertPermissionsDetails(page, reviewTeamUrl);
|
||||
await assertRestrictedAccess(page, ownersUrl, testTeamUrl, adminUrl);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('test_team', () => {
|
||||
test.use({user: 'user2'});
|
||||
|
||||
test('should only see permissions for test_team and restricted access to other resources', async ({page}) => {
|
||||
await assertPermissionsDetails(page, testTeamUrl);
|
||||
await assertRestrictedAccess(page, ownersUrl, reviewTeamUrl, adminUrl);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -94,6 +94,8 @@ func createSessions(t testing.TB) {
|
|||
"user1",
|
||||
"user2",
|
||||
"user12",
|
||||
"user18",
|
||||
"user29",
|
||||
"user40",
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue