Skip to content

Commit

Permalink
Display whitelisted members for closed proposal discussions (#2480) (#…
Browse files Browse the repository at this point in the history
…3756)

* Display whitelisted members for closed proposal discussions (#2480)

* fixup

* fix ProposalDiscussion.test.tsx

* change wording, fix test

Co-authored-by: Joystream Stats <dev@joystreamstats.live>
  • Loading branch information
traumschule and Joystream Stats authored Dec 12, 2022
1 parent 6afd081 commit 3272196
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 56 deletions.
27 changes: 16 additions & 11 deletions packages/ui/src/proposals/components/ProposalDiscussions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,21 @@ interface Props {
proposalId: string
}

const hints = {
open: 'This is an unmoderated discussioon, everyone can comment.',
closed: 'This discussion is closed. Only selected members and the council can comment.',
}

export const ProposalDiscussions = ({ thread, proposalId }: Props) => {
const query = useRouteQuery()
const { api } = useApi()
const { active, members } = useMyMemberships()

const initialPost = query.get('post')
const isAbleToPost =
thread.mode === 'open' ||
(thread.mode === 'closed' && active && (thread.whitelistIds?.includes(active.id) || active.isCouncilMember))
const isInWhitelist = thread.mode === 'closed' && members.find((member) => thread.whitelistIds?.includes(member.id))
const hasCouncilMembership = thread.mode === 'closed' && members.find((member) => member.isCouncilMember)
const isClosed = thread.mode === 'closed'
const isAbleToPost = !isClosed || (active && (thread.whitelistIds?.includes(active.id) || active.isCouncilMember))
const whitelistedMember = isClosed ? members.find((member) => thread.whitelistIds?.includes(member.id)) : null
const hasCouncilMembership = isClosed && members.find((member) => member.isCouncilMember)

const newPostRef = useRef<HTMLDivElement>(null)
const postsRefs: AnyKeys = {}
Expand Down Expand Up @@ -66,14 +70,15 @@ export const ProposalDiscussions = ({ thread, proposalId }: Props) => {
return <TextBig>Please select your council membership to post in this thread.</TextBig>
}

if (isInWhitelist) {
return <TextBig>Please select a whitelisted membership to post in this thread.</TextBig>
if (whitelistedMember) {
return <TextBig>Please select your other membership to post in this thread: {whitelistedMember.handle}</TextBig>
}

return (
<TextBig>
The discussion of this proposal is closed; only members whitelisted by the proposer can comment on it.
</TextBig>
<>
<TextBig>The discussion is limited to following whitelisted members:</TextBig>
{thread.whitelistIds?.join(' ') ?? ''}
</>
)
}

Expand All @@ -83,7 +88,7 @@ export const ProposalDiscussions = ({ thread, proposalId }: Props) => {
<h4>Discussion</h4>
<Badge>
{`${thread.mode} `}
<Tooltip tooltipText="Dolore magna anim eu nisi qui.">
<Tooltip tooltipText={hints[thread.mode]}>
<TooltipDefault />
</Tooltip>
</Badge>
Expand Down
71 changes: 26 additions & 45 deletions packages/ui/test/proposals/components/ProposalDiscussion.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,17 @@ import { getMember } from '../../_mocks/members'
import { MockKeyringProvider } from '../../_mocks/providers'
import { stubApi, stubTransaction } from '../../_mocks/transactions'

jest.mock('@/common/components/CKEditor', () => ({
BaseCKEditor: (props: CKEditorProps) => mockCKEditor(props),
}))
jest.mock('@/common/components/CKEditor', () => {
return {
BaseCKEditor: (props: CKEditorProps) => mockCKEditor(props),
}
})

const strings = {
isClosed: 'The discussion is limited to following whitelisted members:',
selectCouncilor: 'Please select your council membership to post in this thread.',
selectWhitelisted: 'Please select your other membership to post in this thread:',
}

describe('UI: Proposal discussion', () => {
const api = stubApi()
Expand Down Expand Up @@ -52,84 +60,61 @@ describe('UI: Proposal discussion', () => {
it('Non-whitelisted member', async () => {
useMyMemberships.setActive(alice)
renderComponent({ ...baseThread, mode: 'closed', whitelistIds: ['111', '13'] })
expect(
await screen.findByText(
'The discussion of this proposal is closed; only members whitelisted by the proposer can comment on it.'
)
).toBeDefined()
expect(await screen.queryByText(/${strings.isClosed}/i)).toBeDefined()
})

it('Whitelisted member', async () => {
useMyMemberships.setActive(alice)
renderComponent({ ...baseThread, mode: 'closed', whitelistIds: ['111', '13', '0'] })
expect(
screen.queryByText(
'The discussion of this proposal is closed; only members whitelisted by the proposer can comment on it.'
)
).toBeNull()
expect(screen.queryByText('Please select your council membership to post in this thread.')).toBeNull()
expect(await screen.queryByText(/${strings.isClosed}/i)).toBeNull()
expect(await screen.queryByText(strings.selectCouncilor)).toBeNull()
expect(await getButton('Create post')).toBeDefined()
})

it('Whitelisted member not selected', async () => {
renderComponent({ ...baseThread, mode: 'closed', whitelistIds: ['111', '13', '0'] })
expect(await screen.findByText('Please select a whitelisted membership to post in this thread.')).toBeDefined()
expect(await screen.queryByText(/${strings.isClosed}/i)).toBeNull()
expect(await screen.queryByText(/${strings.selectWhitelisted}/i)).toBeDefined()
})

it('Council member', async () => {
useMyMemberships.setActive(councillor)
renderComponent({ ...baseThread, mode: 'closed', whitelistIds: ['111'] })
expect(
screen.queryByText(
'The discussion of this proposal is closed; only members whitelisted by the proposer can comment on it.'
)
).toBeNull()
expect(screen.queryByText('Please select your council membership to post in this thread.')).toBeNull()
expect(screen.queryByText(/${strings.isClosed}/i)).toBeNull()
expect(screen.queryByText(strings.selectCouncilor)).toBeNull()
expect(await getButton('Create post')).toBeDefined()
})

it('Council member not selected', async () => {
useMyMemberships.members = [councillor]
renderComponent({ ...baseThread, mode: 'closed', whitelistIds: ['111'] })
expect(await screen.findByText('Please select your council membership to post in this thread.')).toBeDefined()
expect(await screen.findByText(strings.selectCouncilor)).toBeDefined()
})

describe('User has both a council and a whitelisted membership', () => {
it('Council member selected', async () => {
useMyMemberships.members = [alice, councillor]
useMyMemberships.setActive(councillor)
renderComponent({ ...baseThread, mode: 'closed', whitelistIds: ['0'] })
expect(
screen.queryByText(
'The discussion of this proposal is closed; only members whitelisted by the proposer can comment on it.'
)
).toBeNull()
expect(screen.queryByText('Please select your council membership to post in this thread.')).toBeNull()
expect(screen.queryByText(/${strings.isClosed}/i)).toBeNull()
expect(screen.queryByText(strings.selectCouncilor)).toBeNull()
expect(await getButton('Create post')).toBeDefined()
})

it('Whitelisted member selected', async () => {
useMyMemberships.members = [alice, councillor]
useMyMemberships.setActive(alice)
renderComponent({ ...baseThread, mode: 'closed', whitelistIds: ['0'] })
expect(
screen.queryByText(
'The discussion of this proposal is closed; only members whitelisted by the proposer can comment on it.'
)
).toBeNull()
expect(screen.queryByText('Please select your council membership to post in this thread.')).toBeNull()
expect(screen.queryByText(strings.isClosed)).toBeNull()
expect(screen.queryByText(strings.selectCouncilor)).toBeNull()
expect(await getButton('Create post')).toBeDefined()
})

it('Neither member selected', async () => {
useMyMemberships.members = [alice, councillor]
renderComponent({ ...baseThread, mode: 'closed', whitelistIds: ['0'] })
expect(
screen.queryByText(
'The discussion of this proposal is closed; only members whitelisted by the proposer can comment on it.'
)
).toBeNull()
expect(await screen.findByText('Please select your council membership to post in this thread.')).toBeDefined()
expect(screen.queryByText(/${strings.isClosed}/i)).toBeNull()
expect(await screen.findByText(strings.selectCouncilor)).toBeDefined()
expect(screen.queryByText('Create post')).toBeNull()
})
})
Expand All @@ -139,11 +124,7 @@ describe('UI: Proposal discussion', () => {
it('Member selected', async () => {
useMyMemberships.setActive(alice)
renderComponent({ ...baseThread })
expect(
screen.queryByText(
'The discussion of this proposal is closed; only members whitelisted by the proposer can comment on it.'
)
).toBeNull()
expect(screen.queryByText(/${strings.isClosed}/i)).toBeNull()
expect(await getButton('Create post')).toBeDefined()
})

Expand Down

2 comments on commit 3272196

@vercel
Copy link

@vercel vercel bot commented on 3272196 Dec 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 3272196 Dec 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

pioneer-2 – ./

pioneer-2-git-dev-joystream.vercel.app
pioneer-2-joystream.vercel.app
pioneer-2.vercel.app

Please sign in to comment.