Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(user-scopes): control who can see organisation views #8012

Merged
merged 9 commits into from
Dec 9, 2024
24 changes: 24 additions & 0 deletions packages/client/graphql.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,18 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "eventLocationLevel6",
"description": null,
"args": [],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "fatherDoB",
"description": null,
Expand Down Expand Up @@ -1713,6 +1725,18 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "eventLocationLevel6",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "fatherDoB",
"description": null,
Expand Down
236 changes: 101 additions & 135 deletions packages/client/src/components/interface/Navigation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -483,178 +483,144 @@ describe('Given a user with scopes views Navigation', () => {
})
})

describe('and user has organisation scopes', async () => {
const orgScopes = [
describe('Organisation', async () => {
const id = `#navigation_${WORKQUEUE_TABS.organisation}`

const requiredScopes = [
SCOPES.ORGANISATION_READ_LOCATIONS,
SCOPES.ORGANISATION_READ_LOCATIONS_MY_OFFICE,
SCOPES.ORGANISATION_READ_LOCATIONS_MY_JURISDICTION
] as Scope[]

describe('Performance', async () => {
const id = `#navigation_${WORKQUEUE_TABS.performance}`

const requiredScopes = ([SCOPES.PERFORMANCE_READ] as Scope[]).concat(
orgScopes
)

const allOtherScopes = allScopes.filter(
(scope) => !requiredScopes.includes(scope)
)

const withoutOrgScopes = allScopes.filter(
(scope) => !orgScopes.includes(scope)
)

const tests = [
[requiredScopes, true],
[allOtherScopes, false],
[withoutOrgScopes, false]
]

tests.forEach(async ([scopes, exists]) => {
it(`should render when user has correct scopes ${scopes}`, async () => {
setScopes(scopes as Scope[], store)
testComponent = await build()
expect(testComponent.exists(id)).toBe(exists)
})
})
})

describe('Organisation', async () => {
const id = `#navigation_${WORKQUEUE_TABS.organisation}`

const requiredScopes = [SCOPES.ORGANISATION_READ_LOCATIONS] as Scope[]

const allOtherScopes = allScopes.filter(
(scope) => !requiredScopes.includes(scope)
)
const allOtherScopes = allScopes.filter(
(scope) => !requiredScopes.includes(scope)
)

const tests = [
[requiredScopes, true],
[allOtherScopes, false]
]
const tests = [
[requiredScopes, true],
[allOtherScopes, false]
]

tests.forEach(async ([scopes, exists]) => {
it(`should render when user has correct scopes ${scopes}`, async () => {
setScopes(scopes as Scope[], store)
testComponent = await build()
expect(testComponent.exists(id)).toBe(exists)
})
tests.forEach(async ([scopes, exists]) => {
it(`should render when user has correct scopes ${scopes}`, async () => {
setScopes(scopes as Scope[], store)
testComponent = await build()
expect(testComponent.exists(id)).toBe(exists)
})
})
})

describe('Team', async () => {
const id = `#navigation_${WORKQUEUE_TABS.team}`
describe('Team', async () => {
const id = `#navigation_${WORKQUEUE_TABS.team}`

const requiredScopes = [
SCOPES.ORGANISATION_READ_LOCATIONS,
SCOPES.ORGANISATION_READ_LOCATIONS_MY_OFFICE
] as Scope[]
const requiredScopes = [
SCOPES.ORGANISATION_READ_LOCATIONS,
SCOPES.ORGANISATION_READ_LOCATIONS_MY_OFFICE,
SCOPES.ORGANISATION_READ_LOCATIONS_MY_JURISDICTION
] as Scope[]

const allOtherScopes = allScopes.filter(
(scope) => !requiredScopes.includes(scope)
)
const allOtherScopes = allScopes.filter(
(scope) => !requiredScopes.includes(scope)
)

const tests = [
[[requiredScopes[0]], true],
[[requiredScopes[1]], true],
[allOtherScopes, false]
]
const tests = [
[requiredScopes, true],
[allOtherScopes, false]
]

tests.forEach(async ([scopes, exists]) => {
it(`should render when user has correct scopes ${scopes}`, async () => {
setScopes(scopes as Scope[], store)
testComponent = await build()
expect(testComponent.exists(id)).toBe(exists)
})
tests.forEach(async ([scopes, exists]) => {
it(`should render when user has correct scopes ${scopes}`, async () => {
setScopes(scopes as Scope[], store)
testComponent = await build()
expect(testComponent.exists(id)).toBe(exists)
})
})
})

describe('Config', async () => {
const id = `#navigation_${WORKQUEUE_TABS.config}_main`
describe('Config', async () => {
const id = `#navigation_${WORKQUEUE_TABS.config}_main`

const requiredScopes = [...orgScopes, SCOPES.CONFIG_UPDATE_ALL] as Scope[]
const requiredScopes = [SCOPES.CONFIG_UPDATE_ALL] as Scope[]

const allOtherScopes = allScopes.filter(
(scope) => !requiredScopes.includes(scope)
)
const allOtherScopes = allScopes.filter(
(scope) => !requiredScopes.includes(scope)
)

const tests = [
[requiredScopes, true],
[allOtherScopes, false]
]
const tests = [
[requiredScopes, true],
[allOtherScopes, false]
]

tests.forEach(async ([scopes, exists]) => {
it(`should render when user has correct scopes ${scopes}`, async () => {
setScopes(scopes as Scope[], store)
testComponent = await build()
expect(testComponent.exists(id)).toBe(exists)
})
tests.forEach(async ([scopes, exists]) => {
it(`should render when user has correct scopes ${scopes}`, async () => {
setScopes(scopes as Scope[], store)
testComponent = await build()
expect(testComponent.exists(id)).toBe(exists)
})
})
})

describe('Systems', async () => {
const id = `#navigation_${WORKQUEUE_TABS.systems}`
describe('Systems', async () => {
const id = `#navigation_${WORKQUEUE_TABS.systems}`

const requiredScopes = [...orgScopes, SCOPES.CONFIG_UPDATE_ALL] as Scope[]
const requiredScopes = [SCOPES.CONFIG_UPDATE_ALL] as Scope[]

const tests = [[requiredScopes, true]]
const tests = [[requiredScopes, true]]

tests.forEach(async ([scopes, exists]) => {
it(`should render when user has correct scopes ${scopes} and clicks config expander`, async () => {
setScopes(scopes as Scope[], store)
testComponent = await build()
testComponent
.find(`#navigation_${WORKQUEUE_TABS.config}_main`)
.hostNodes()
.simulate('click')
tests.forEach(async ([scopes, exists]) => {
it(`should render when user has correct scopes ${scopes} and clicks config expander`, async () => {
setScopes(scopes as Scope[], store)
testComponent = await build()
testComponent
.find(`#navigation_${WORKQUEUE_TABS.config}_main`)
.hostNodes()
.simulate('click')

expect(testComponent.exists(id)).toBe(exists)
})
expect(testComponent.exists(id)).toBe(exists)
})
})
})

describe('Communications', async () => {
const id = `#navigation_${WORKQUEUE_TABS.communications}_main`
describe('Communications', async () => {
const id = `#navigation_${WORKQUEUE_TABS.communications}_main`

const requiredScopes = [...orgScopes, SCOPES.CONFIG_UPDATE_ALL] as Scope[]
const requiredScopes = [SCOPES.CONFIG_UPDATE_ALL] as Scope[]

const allOtherScopes = allScopes.filter(
(scope) => !requiredScopes.includes(scope)
)
const allOtherScopes = allScopes.filter(
(scope) => !requiredScopes.includes(scope)
)

const tests = [
[requiredScopes, true],
[allOtherScopes, false]
]
const tests = [
[requiredScopes, true],
[allOtherScopes, false]
]

tests.forEach(async ([scopes, exists]) => {
it(`should render when user has correct scopes ${scopes}`, async () => {
setScopes(scopes as Scope[], store)
testComponent = await build()
expect(testComponent.exists(id)).toBe(exists)
})
tests.forEach(async ([scopes, exists]) => {
it(`should render when user has correct scopes ${scopes}`, async () => {
setScopes(scopes as Scope[], store)
testComponent = await build()
expect(testComponent.exists(id)).toBe(exists)
})
})
})

describe('Email all users', async () => {
const id = `#navigation_${WORKQUEUE_TABS.emailAllUsers}`
describe('Email all users', async () => {
const id = `#navigation_${WORKQUEUE_TABS.emailAllUsers}`

const requiredScopes = [...orgScopes, SCOPES.CONFIG_UPDATE_ALL] as Scope[]
const requiredScopes = [SCOPES.CONFIG_UPDATE_ALL] as Scope[]

const tests = [[requiredScopes, true]]
const tests = [[requiredScopes, true]]

tests.forEach(async ([scopes, exists]) => {
it(`should render when user has correct scopes ${scopes} and clicks communciation expander`, async () => {
setScopes(scopes as Scope[], store)
testComponent = await build()
testComponent
.find(`#navigation_${WORKQUEUE_TABS.communications}_main`)
.hostNodes()
.simulate('click')
tests.forEach(async ([scopes, exists]) => {
it(`should render when user has correct scopes ${scopes} and clicks communciation expander`, async () => {
setScopes(scopes as Scope[], store)
testComponent = await build()
testComponent
.find(`#navigation_${WORKQUEUE_TABS.communications}_main`)
.hostNodes()
.simulate('click')

expect(testComponent.exists(id)).toBe(exists)
})
expect(testComponent.exists(id)).toBe(exists)
})
})
})
Expand Down Expand Up @@ -682,8 +648,8 @@ describe('Given a user with scopes views Navigation', () => {
})
})

describe('Statistics', async () => {
const id = `#navigation_${WORKQUEUE_TABS.statistics}`
describe('Performance', async () => {
const id = `#navigation_${WORKQUEUE_TABS.performance}`

const requiredScopes = [SCOPES.PERFORMANCE_READ] as Scope[]

Expand Down Expand Up @@ -729,7 +695,7 @@ describe('Given a user with scopes views Navigation', () => {
})

describe('Statistics', async () => {
const id = `#navigation_${WORKQUEUE_TABS.leaderboards}`
const id = `#navigation_${WORKQUEUE_TABS.statistics}`

const requiredScopes = [SCOPES.PERFORMANCE_READ] as Scope[]

Expand All @@ -751,8 +717,8 @@ describe('Given a user with scopes views Navigation', () => {
})
})

describe('Report', async () => {
const id = `#navigation_${WORKQUEUE_TABS.report}`
describe('Statistics', async () => {
const id = `#navigation_${WORKQUEUE_TABS.leaderboards}`

const requiredScopes = [SCOPES.PERFORMANCE_READ] as Scope[]

Expand Down
21 changes: 2 additions & 19 deletions packages/client/src/components/interface/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -440,23 +440,6 @@ const NavigationView = (props: IFullProps) => {
<NavigationGroup>
{userDetails && (
<>
{hasAccess(WORKQUEUE_TABS.performance) && (
<NavigationItem
icon={() => <Icon name="Activity" size="medium" />}
id={`navigation_${WORKQUEUE_TABS.performance}`}
label={intl.formatMessage(
navigationMessages[WORKQUEUE_TABS.performance]
)}
onClick={() => {
props.goToPerformanceViewAction()
}}
isSelected={
enableMenuSelection &&
activeMenuItem === WORKQUEUE_TABS.performance
}
/>
)}

{hasAccess(WORKQUEUE_TABS.organisation) && (
<NavigationItem
icon={() => <Icon name="Buildings" size="medium" />}
Expand Down Expand Up @@ -602,12 +585,12 @@ const NavigationView = (props: IFullProps) => {
}
/>
)}
{userDetails && hasAccess(WORKQUEUE_TABS.report) && (
{userDetails && hasAccess(WORKQUEUE_TABS.performance) && (
<NavigationItem
icon={() => <Icon name="ChartBar" size="medium" />}
label={intl.formatMessage(navigationMessages['performance'])}
onClick={() => props.goToPerformanceViewAction()}
id={`navigation_${WORKQUEUE_TABS.report}`}
id={`navigation_${WORKQUEUE_TABS.performance}`}
isSelected={
enableMenuSelection &&
activeMenuItem === WORKQUEUE_TABS.performance
Expand Down
3 changes: 1 addition & 2 deletions packages/client/src/components/interface/WorkQueueTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ export const WORKQUEUE_TABS = {
readyToIssue: 'readyToIssue',
dashboard: 'dashboard',
statistics: 'statistics',
leaderboards: 'leaderboards',
report: 'report'
leaderboards: 'leaderboards'
} as const

export const TAB_GROUPS = {
Expand Down
Loading
Loading