diff --git a/models/fixtures/team.yml b/models/fixtures/team.yml index 149fe90888..a863f1203a 100644 --- a/models/fixtures/team.yml +++ b/models/fixtures/team.yml @@ -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 diff --git a/models/fixtures/team_unit.yml b/models/fixtures/team_unit.yml index e8f8d0e422..4d282a7eb5 100644 --- a/models/fixtures/team_unit.yml +++ b/models/fixtures/team_unit.yml @@ -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 diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml index 1a03185cf1..00aa182540 100644 --- a/models/fixtures/user.yml +++ b/models/fixtures/user.yml @@ -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 diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index e43276a122..7479ab80af 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -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 Read access: members can view and clone team repositories. -teams.write_permission_desc = This team grants Write access: members can read from and push to team repositories. teams.admin_permission_desc = This team grants Administrator access: members can read from, push to and add collaborators to team repositories. teams.create_repo_permission_desc = Additionally, this team grants Create repository permission: members can create new repositories in organization. teams.repositories = Team repositories diff --git a/templates/org/team/sidebar.tmpl b/templates/org/team/sidebar.tmpl index c9f80259e2..faf0c336a0 100644 --- a/templates/org/team/sidebar.tmpl +++ b/templates/org/team/sidebar.tmpl @@ -42,11 +42,8 @@
  • {{ctx.Locale.Tr "org.teams.can_create_org_repo"}}
  • {{end}} - {{if (eq .Team.AccessMode 2)}} -

    {{ctx.Locale.Tr "org.settings.permission"}}

    - {{ctx.Locale.Tr "org.teams.write_permission_desc"}} - {{else if (eq .Team.AccessMode 3)}} -

    {{ctx.Locale.Tr "org.settings.permission"}}

    +

    {{ctx.Locale.Tr "org.settings.permission"}}

    + {{if (eq .Team.AccessMode 3)}} {{ctx.Locale.Tr "org.teams.admin_permission_desc"}} {{else}} diff --git a/tests/e2e/org-teams-overview.test.e2e.ts b/tests/e2e/org-teams-overview.test.e2e.ts new file mode 100644 index 0000000000..d968b1e6df --- /dev/null +++ b/tests/e2e/org-teams-overview.test.e2e.ts @@ -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 = { + [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); + }); + }); +}); diff --git a/tests/e2e/utils_e2e_test.go b/tests/e2e/utils_e2e_test.go index f892d6c518..e121c604c3 100644 --- a/tests/e2e/utils_e2e_test.go +++ b/tests/e2e/utils_e2e_test.go @@ -94,6 +94,8 @@ func createSessions(t testing.TB) { "user1", "user2", "user12", + "user18", + "user29", "user40", }