Skip to content

Commit

Permalink
* Added tests to ScopeEditor
Browse files Browse the repository at this point in the history
*Updated button for updating fragments
  • Loading branch information
Vas9ka committed Aug 6, 2024
1 parent 28d0c89 commit 7ec4b8d
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/auth/Session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export default class MemorySession implements Session {
return false
}

private hasApplicationScope(applicationScope: string): boolean {
hasApplicationScope(applicationScope: string): boolean {
const scope = applicationScopes[applicationScope]
return this.scopes.has(scope)
}
Expand Down
3 changes: 2 additions & 1 deletion src/auth/applicationScopes.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@
"readCAICFragments": "read:CAIC-fragments",
"readItalianNinevehFragments": "read:ITALIANNINEVEH-fragments",
"readSipparLibraryFragments": "read:SIPPARLIBRARY-fragments",
"readUrukLBUFragments": "read:URUKLBU-fragments"
"readUrukLBUFragments": "read:URUKLBU-fragments",
"readSipparIstanbulFragments": "read:SIPPARISTANBUL-fragments"
}
4 changes: 2 additions & 2 deletions src/fragmentarium/application/FragmentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export interface FragmentRepository {
fetchPeriods(): Bluebird<string[]>
fetchColophonNames(query: string): Bluebird<string[]>
updateGenres(number: string, genres: Genres): Bluebird<Fragment>
updateScopes(number: string, scopes: string): Bluebird<Fragment>
updateScopes(number: string, scopes: string[]): Bluebird<Fragment>
updateScript(number: string, script: Script): Bluebird<Fragment>
updateDate(number: string, date: MesopotamianDate): Bluebird<Fragment>
updateDatesInText(
Expand Down Expand Up @@ -169,7 +169,7 @@ export class FragmentService {
.updateScript(number, script)
.then((fragment: Fragment) => this.injectReferences(fragment))
}
updateScopes(number: string, scopes: string): Bluebird<Fragment> {
updateScopes(number: string, scopes: string[]): Bluebird<Fragment> {
return this.fragmentRepository
.updateScopes(number, scopes)
.then((fragment: Fragment) => this.injectReferences(fragment))
Expand Down
3 changes: 2 additions & 1 deletion src/fragmentarium/domain/fragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ export class Fragment {
props.date,
props.datesInText,
props.archaeology,
props.colophon
props.colophon,
props.authorizedScopes
)
}

Expand Down
11 changes: 7 additions & 4 deletions src/fragmentarium/infrastructure/FragmentRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,14 @@ class ApiFragmentRepository
})
.then(createFragment)
}
updateScopes(number: string, scopes: string): Promise<Fragment> {
updateScopes(number: string, scopes: string[]): Promise<Fragment> {
const path = createFragmentPath(number, 'scopes')
return this.apiClient
.postJson(path, { scopes: scopes })
.then(createFragment)
return (
this.apiClient
// eslint-disable-next-line camelcase
.postJson(path, { authorized_scopes: scopes })
.then(createFragment)
)
}
updateScript(number: string, script: Script): Promise<Fragment> {
const path = createFragmentPath(number, 'script')
Expand Down
13 changes: 7 additions & 6 deletions src/fragmentarium/ui/fragment/CuneiformFragmentEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type TabName =
| 'references'
| 'archaeology'
| 'colophon'
| 'scope'
| 'permissions'

const tabNames: TabName[] = [
'display',
Expand All @@ -57,7 +57,7 @@ const tabNames: TabName[] = [
'references',
'archaeology',
'colophon',
'scope',
'permissions',
]

function EditorTab({
Expand Down Expand Up @@ -97,7 +97,7 @@ function TabContentsMatcher({
references: () => ReferencesContents(props),
archaeology: () => ArchaeologyContents(props),
colophon: () => ColophonContents(props),
scope: () => ScopeContents(props, session),
permissions: () => ScopeContents(props, session),
}[name]()
}

Expand Down Expand Up @@ -245,9 +245,10 @@ function ColophonContents(props: TabsProps): JSX.Element {
}

function ScopeContents(props: TabsProps, session: Session): JSX.Element {
const updateScopes = async (scopes: string) => {
await props.fragmentService.updateScopes(props.fragment.number, scopes)
props.onSave()
const updateScopes = async (scopes: string[]) => {
props.onSave(
props.fragmentService.updateScopes(props.fragment.number, scopes)
)
}

return (
Expand Down
73 changes: 73 additions & 0 deletions src/fragmentarium/ui/fragment/ScopeEditor.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from 'react'
import { render, screen, fireEvent } from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'
import ScopeEditor from './ScopeEditor'
import { Fragment } from 'fragmentarium/domain/fragment'
import MemorySession from 'auth/Session'

describe('ScopeEditor', () => {
const fragment: Fragment = {
authorizedScopes: ['read:CAIC-fragments'],
} as Fragment

const session = new MemorySession([
'read:CAIC-fragments',
'read:ITALIANNINEVEH-fragments',
])

const updateScopes = jest.fn().mockResolvedValue(undefined)

test('renders the component correctly', () => {
render(
<ScopeEditor
fragment={fragment}
session={session}
updateScopes={updateScopes}
/>
)

expect(screen.getByText('Permissions')).toBeInTheDocument()
expect(
screen.getByText(
'Records with added permissions are visible only to users who have those permissions.'
)
).toBeInTheDocument()
})

test('toggles scopes', () => {
render(
<ScopeEditor
fragment={fragment}
session={session}
updateScopes={updateScopes}
/>
)

const checkboxes = screen.getAllByRole('checkbox')
expect(checkboxes).toHaveLength(2)

expect(checkboxes[0]).toBeChecked()

fireEvent.click(checkboxes[0])
expect(checkboxes[0]).not.toBeChecked()

fireEvent.click(checkboxes[0])
expect(checkboxes[0]).toBeChecked()
})

test('submits selected scopes', async () => {
render(
<ScopeEditor
fragment={fragment}
session={session}
updateScopes={updateScopes}
/>
)

const button = screen.getByText('Update Permissions')

fireEvent.click(button)

expect(updateScopes).toHaveBeenCalledWith(['read:CAIC-fragments'])
})
})
68 changes: 61 additions & 7 deletions src/fragmentarium/ui/fragment/ScopeEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,79 @@
import React from 'react'
import React, { useState, useEffect } from 'react'
import { Fragment } from 'fragmentarium/domain/fragment'
import { Session } from 'auth/Session'

import MemorySession, { Session } from 'auth/Session'
import { Button } from 'react-bootstrap'
interface ScopeEditorProps {
fragment: Fragment
session: Session
updateScopes: (scopes: string) => void
updateScopes: (scopes: string[]) => Promise<void>
}

function isMemorySession(session: Session): session is MemorySession {
return !session.isGuestSession()
}

const ScopeEditor: React.FC<ScopeEditorProps> = ({
fragment,
session,
updateScopes,
}) => {
const SCOPES = [
'CAIC',
'ItalianNineveh',
'SipparLibrary',
'UrukLBU',
'SipparIstanbul',
]
const [selectedScopes, setSelectedScopes] = useState<string[]>(
fragment.authorizedScopes || []
)
const [fragmentScopes, setFragmentScopes] = useState<string[]>([])
useEffect(() => {
if (isMemorySession(session)) {
const scopes = SCOPES.filter((scope) =>
session.hasApplicationScope('read' + scope + 'Fragments')
)
const upperCaseScopes = scopes.map((scope) => scope.toUpperCase())
const reformattedScopes = upperCaseScopes.map(
(scope) => 'read:' + scope + '-fragments'
)
setFragmentScopes(reformattedScopes)
}
}, [session])
const handleScopeChange = (scope: string) => {
setSelectedScopes((prevScopes) =>
prevScopes.includes(scope)
? prevScopes.filter((s) => s !== scope)
: [...prevScopes, scope]
)
}

const handleSubmit = async () => {
await updateScopes(selectedScopes)
}

return (
<div>
<h3>Authorized Scopes</h3>
<h3>Permissions</h3>
<p>
Records with added permissions are visible only to users who have those
permissions.
</p>
<ul>
{fragment.authorizedScopes?.map((scope) => (
<li key={scope}>{scope}</li>
{fragmentScopes.map((scope) => (
<li key={scope}>
<label>
<input
type="checkbox"
checked={selectedScopes.includes(scope)}
onChange={() => handleScopeChange(scope)}
/>
{scope}
</label>
</li>
))}
</ul>
<Button onClick={handleSubmit}>Update Permissions</Button>
</div>
)
}
Expand Down

0 comments on commit 7ec4b8d

Please sign in to comment.