Skip to content
Open
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
10 changes: 10 additions & 0 deletions __tests__/shared/components/challenge-detail/Header/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ describe('Challenge detail header actions', () => {
expect(collectText(output)).not.toContain('Submit a solution');
});

test('hides registration and submission actions for flattened task payloads', () => {
const output = renderHeader({
taskIsTask: true,
});

expect(collectText(output)).not.toContain('Register');
expect(collectText(output)).not.toContain('Unregister');
expect(collectText(output)).not.toContain('Submit a solution');
});

test('shows registration and submission actions for non-task challenges', () => {
const output = renderHeader();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,49 @@ test('Hides assigned task when memberId and userId do not match', () => {
expect(countElementsByType(renderer.getRenderOutput(), ChallengeCard)).toBe(0);
});

test('Hides assigned task when flattened task fields and userId do not match', () => {
const renderer = new Renderer();
renderer.render((
<Bucket
activeBucket="openForRegistration"
auth={{ user: { roles: [] } }}
bucket="openForRegistration"
challenges={[
{
id: 'task-3',
name: 'Assigned task',
status: 'ACTIVE',
type: { name: 'Task' },
tags: [],
prizes: [],
taskIsTask: true,
taskIsAssigned: true,
taskMemberId: 'owner-user',
},
]}
challengeTypes={challengeTypes}
challengesUrl="/challenges"
expand={_.noop}
expanded
expandTag={_.noop}
expandedTags={[]}
expanding={false}
filterState={{}}
isLoggedIn
needLoad={false}
prizeMode="money-usd"
selectChallengeDetailsTab={_.noop}
setFilterState={setFilterState}
setSearchText={setSearchText}
setSort={setSort}
sort=""
userId="different-user"
/>
));

expect(countElementsByType(renderer.getRenderOutput(), ChallengeCard)).toBe(0);
});

// class Wrapper extends React.Component {
// componentDidMount() {}

Expand Down
11 changes: 7 additions & 4 deletions src/shared/components/challenge-detail/Header/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
import _ from 'lodash';
import moment from 'moment';
import 'moment-duration-format';
import { isMM, getTrackName, getTypeName } from 'utils/challenge';
import {
isMM,
getTaskInfo,
getTrackName,
getTypeName,
} from 'utils/challenge';

import PT from 'prop-types';
import React, { useMemo } from 'react';
Expand Down Expand Up @@ -148,9 +153,7 @@ export default function ChallengeHeader(props) {

const trackName = getTrackName(track);
const typeName = getTypeName(type);
const isTaskChallenge = typeName === 'Task'
|| _.get(challenge, 'task.isTask') === true
|| _.get(challenge, 'legacy.pureV5Task') === true;
const { isTask: isTaskChallenge } = getTaskInfo(challenge);
const trackLower = trackName ? trackName.replace(' ', '-').toLowerCase() : 'design';

const eventNames = (events || []).map((event => (event.eventName || '').toUpperCase()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
import SortingSelectBar from 'components/SortingSelectBar';
import Waypoint from 'react-waypoint';
// import { challenge as challengeUtils } from 'topcoder-react-lib';
import { getTypeName } from 'utils/challenge';
import { getTaskInfo, getTypeName } from 'utils/challenge';
import CardPlaceholder from '../../placeholders/ChallengeCard';
import ChallengeCard from '../../ChallengeCard';
import NoRecommenderChallengeCard from '../../NoRecommenderChallengeCard';
Expand Down Expand Up @@ -86,12 +86,10 @@ export default function Bucket({

if (!_.includes(roles, 'administrator')) {
filteredChallenges = sortedChallenges.filter((ch) => {
const typeName = getTypeName(ch);
if (typeName === 'Task'
&& ch.task
&& ch.task.isTask
&& ch.task.isAssigned
&& `${ch.task.memberId}` !== `${userId}`) {
const taskInfo = getTaskInfo(ch);
if (taskInfo.isTask
&& taskInfo.isAssigned
&& `${taskInfo.memberId}` !== `${userId}`) {
return null;
}
return ch;
Expand Down
23 changes: 23 additions & 0 deletions src/shared/utils/challenge.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,28 @@ export function getTypeName(typeOrChallenge) {
return value || '';
}

/**
* Returns normalized task info for challenge payloads that may use nested
* or flattened task fields.
* @param {Object} challenge challenge object
* @returns {{isTask: boolean, isAssigned: boolean, memberId: ?string}}
*/
export function getTaskInfo(challenge = {}) {
const taskIsTask = _.get(challenge, 'task.isTask');
const taskIsAssigned = _.get(challenge, 'task.isAssigned');
const taskMemberId = _.get(challenge, 'task.memberId');

return {
isTask: getTypeName(challenge) === 'Task'
|| (_.isNil(taskIsTask) ? _.get(challenge, 'taskIsTask', false) : taskIsTask)
|| _.get(challenge, 'legacy.pureV5Task') === true,
isAssigned: _.isNil(taskIsAssigned)
? _.get(challenge, 'taskIsAssigned', false)
: taskIsAssigned,
memberId: !_.isNil(taskMemberId) ? taskMemberId : _.get(challenge, 'taskMemberId', null),
};
}

/**
* check if is marathon match challenge
* @param {Object} challenge challenge object
Expand Down Expand Up @@ -70,4 +92,5 @@ export default {
updateChallengeType,
getTrackName,
getTypeName,
getTaskInfo,
};
Loading