Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,47 @@ describe('TicketDetailPage reply access', () => {
.toBeUndefined()
})

it('identifies support team replies without labelling the ticket owner', () => {
mockUseSWR.mockReturnValue({
data: {
...closedTicket,
responseCount: 2,
responses: [{
createdAt: '2026-08-07T01:30:00.000Z',
id: 'response-owner',
markdown: 'Member follow-up.',
readBy: [],
userHandle: 'ticket-owner',
userId: '12345',
}, {
createdAt: '2026-08-07T01:45:00.000Z',
id: 'response-support',
markdown: 'Support follow-up.',
readBy: [],
userHandle: 'support-agent',
userId: '67890',
}],
},
error: undefined,
isValidating: false,
mutate: mockMutate,
})

render(<TicketDetailPage />)

const ownerReply = screen.getByText('Member follow-up.')
.closest('article')
const supportReply = screen.getByText('Support follow-up.')
.closest('article')

expect(ownerReply?.textContent)
.toContain('ticket-owner')
expect(ownerReply?.textContent)
.not.toContain('(Support Team)')
expect(supportReply?.textContent)
.toContain('support-agent (Support Team)')
})

it('requires non-owner support staff to assign an open ticket before replying or closing it', () => {
mockProfile = {
roles: ['Topcoder Support Team'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import {
import styles from './TicketDetailPage.module.scss'

/**
* Renders the original request followed by ascending replies and authorized actions.
* Renders the original request followed by ascending, role-labelled replies and authorized actions.
*
* @returns support ticket detail page.
* @throws Does not throw; request failures are shown with recovery actions.
Expand Down Expand Up @@ -316,6 +316,7 @@ export const TicketDetailPage: FC = () => {
color={response.userHandleColor}
handle={response.userHandle}
/>
{response.userId !== data.memberUserId && ' (Support Team)'}
</span>
<time dateTime={response.createdAt}>{formatSupportDate(response.createdAt)}</time>
</header>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3107,7 +3107,7 @@ describe('ChallengeEditorForm', () => {
render(
<MemoryRouter>
<WorkAppContext.Provider value={copilotContextValue}>
<ChallengeEditorForm challenge={designChallengeWithDeferredScreener} />
<ChallengeEditorForm challenge={designChallengeWithDeferredScreeners} />
</WorkAppContext.Provider>
</MemoryRouter>,
)
Expand All @@ -3131,7 +3131,7 @@ describe('ChallengeEditorForm', () => {
<WorkAppContext.Provider value={copilotContextValue}>
<ChallengeEditorForm
challenge={{
...designChallengeWithDeferredScreener,
...designChallengeWithDeferredScreeners,
track: {
abbreviation: 'DESIGN',
name: 'Design',
Expand Down Expand Up @@ -3172,7 +3172,7 @@ describe('ChallengeEditorForm', () => {
render(
<MemoryRouter>
<WorkAppContext.Provider value={adminContextValue}>
<ChallengeEditorForm challenge={designChallengeWithDeferredScreener} />
<ChallengeEditorForm challenge={designChallengeWithDeferredScreeners} />
</WorkAppContext.Provider>
</MemoryRouter>,
)
Expand Down Expand Up @@ -4443,7 +4443,7 @@ describe('ChallengeEditorForm', () => {
isLoading: false,
})
mockedPatchChallenge.mockResolvedValue({
...designChallengeWithDeferredScreener,
...designChallengeWithDeferredScreeners,
metadata: [],
status: 'DRAFT',
})
Expand All @@ -4452,7 +4452,7 @@ describe('ChallengeEditorForm', () => {
<MemoryRouter initialEntries={['/projects/100578/challenges/new']}>
<ChallengeEditorForm
challenge={{
...designChallengeWithDeferredScreener,
...designChallengeWithDeferredScreeners,
metadata: submissionLimitMetadata,
status: 'NEW',
}}
Expand Down
Loading