-
Notifications
You must be signed in to change notification settings - Fork 210
March 2026 prod release #7192
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
March 2026 prod release #7192
Changes from all commits
5117f3f
75054cb
6bc2a33
1a61a13
891312b
79210e9
5c71125
c37c38a
5674e80
b4784f4
56c9101
f230dd8
85beb76
1ada131
266f455
921844e
1ad6472
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| import React from 'react'; | ||
| import renderer from 'react-test-renderer'; | ||
|
|
||
| import ChallengesFeed from 'components/Dashboard/Challenges'; | ||
|
|
||
| function renderChallenge(challenge) { | ||
| return renderer.create(( | ||
| <ChallengesFeed | ||
| challenges={[challenge]} | ||
| loading={false} | ||
| /> | ||
| )).toJSON(); | ||
| } | ||
|
|
||
| describe('Dashboard Challenges feed', () => { | ||
| test('shows Fun label for fun challenges', () => { | ||
| const view = renderChallenge({ | ||
| id: 'challenge-fun', | ||
| name: 'Challenge one', | ||
| funChallenge: true, | ||
| prizeSets: [ | ||
| { | ||
| type: 'PLACEMENT', | ||
| prizes: [{ type: 'USD', value: 0 }], | ||
| }, | ||
| ], | ||
| }); | ||
|
|
||
| const text = JSON.stringify(view); | ||
| expect(text).toContain('Fun'); | ||
| expect(text).not.toContain('$0'); | ||
| }); | ||
|
|
||
| test('shows calculated prize amount for regular challenges', () => { | ||
| const view = renderChallenge({ | ||
| id: 'challenge-regular', | ||
| name: 'Challenge two', | ||
| funChallenge: false, | ||
| prizeSets: [ | ||
| { | ||
| type: 'PLACEMENT', | ||
| prizes: [{ type: 'USD', value: 44 }], | ||
| }, | ||
| ], | ||
| }); | ||
|
|
||
| expect(JSON.stringify(view)).toContain('$44'); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [ |
||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import React from 'react'; | ||
| import Renderer from 'react-test-renderer/shallow'; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [ |
||
|
|
||
| import Prizes from 'components/challenge-detail/Header/Prizes'; | ||
|
|
||
| describe('Challenge detail header prizes', () => { | ||
| test('renders leaderboard-scoring label for fun challenges', () => { | ||
| const renderer = new Renderer(); | ||
| renderer.render(( | ||
| <Prizes | ||
| isFunChallenge | ||
| pointPrizes={[]} | ||
| prizes={[{ type: 'USD', value: 1 }]} | ||
| /> | ||
| )); | ||
| expect(renderer.getRenderOutput()).toMatchSnapshot(); | ||
| }); | ||
|
|
||
| test('renders normal placement prizes when fun challenge is false', () => { | ||
| const renderer = new Renderer(); | ||
| renderer.render(( | ||
| <Prizes | ||
| isFunChallenge={false} | ||
| pointPrizes={[]} | ||
| prizes={[{ type: 'USD', value: 1000 }]} | ||
| /> | ||
| )); | ||
| expect(renderer.getRenderOutput()).toMatchSnapshot(); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| // Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
|
||
| exports[`Challenge detail header prizes renders leaderboard-scoring label for fun challenges 1`] = ` | ||
| <div | ||
| className="src-shared-components-challenge-detail-Header-___style__prizes-container___3iYoT" | ||
| > | ||
| <p | ||
| className="src-shared-components-challenge-detail-Header-___style__fun-challenge-prize___3T3KZ" | ||
| > | ||
| No individual prize - leaderboard scoring | ||
| </p> | ||
| </div> | ||
| `; | ||
|
|
||
| exports[`Challenge detail header prizes renders normal placement prizes when fun challenge is false 1`] = ` | ||
| <div | ||
| className="src-shared-components-challenge-detail-Header-___style__prizes-container___3iYoT" | ||
| > | ||
| <div | ||
| className="src-shared-components-challenge-detail-Header-___style__prize-fill___2MJPB" | ||
| > | ||
| <div | ||
| aria-label="1st prize is $$1,000" | ||
| className="src-shared-components-challenge-detail-Header-___style__prize-card___24y2m" | ||
| id="rank1" | ||
| tabIndex={0} | ||
| > | ||
| <p | ||
| aria-hidden="true" | ||
| className="src-shared-components-challenge-detail-Header-___style__prize-rank___3hC_J" | ||
| > | ||
| 1 | ||
| <span | ||
| className="src-shared-components-challenge-detail-Header-___style__rank-ordinal___1K53t" | ||
| > | ||
| st | ||
| </span> | ||
| </p> | ||
| </div> | ||
| <p | ||
| aria-hidden="true" | ||
| className="src-shared-components-challenge-detail-Header-___style__prize-money___3raXa" | ||
| > | ||
| $1,000 | ||
| </p> | ||
| </div> | ||
| </div> | ||
| `; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ import _ from 'lodash'; | |
| import Renderer from 'react-test-renderer/shallow'; | ||
| // import TU from 'react-dom/test-utils'; | ||
| import Bucket from 'components/challenge-listing/Listing/Bucket'; | ||
| import ChallengeCard from 'components/challenge-listing/ChallengeCard'; | ||
| import reduxStoreFactory from 'redux-mock-store'; | ||
| import { Provider } from 'react-redux'; | ||
| import { StaticRouter } from 'react-router-dom'; | ||
|
|
@@ -15,6 +16,23 @@ const expand = jest.fn(); | |
| const loadMore = jest.fn(); | ||
| const setFilterState = jest.fn(); | ||
| const setSort = jest.fn(); | ||
| const setSearchText = jest.fn(); | ||
|
|
||
| const challengeTypes = [ | ||
| { | ||
| name: 'Challenge', | ||
| abbreviation: 'CH', | ||
| }, { | ||
| name: 'First2Finish', | ||
| abbreviation: 'F2F', | ||
| }, { | ||
| name: 'Task', | ||
| abbreviation: 'TSK', | ||
| }, { | ||
| name: 'Marathon Match', | ||
| abbreviation: 'MM', | ||
| }, | ||
| ]; | ||
|
|
||
| const mockDatas = [{ | ||
| bucket: 'all', | ||
|
|
@@ -47,21 +65,7 @@ const mockDatas = [{ | |
| totalPrize: 1800, | ||
| users: {}, | ||
| }], | ||
| challengeTypes: [ | ||
| { | ||
| name: 'Challenge', | ||
| abbreviation: 'CH', | ||
| }, { | ||
| name: 'First2Finish', | ||
| abbreviation: 'F2F', | ||
| }, { | ||
| name: 'Task', | ||
| abbreviation: 'TSK', | ||
| }, { | ||
| name: 'Marathon Match', | ||
| abbreviation: 'MM', | ||
| }, | ||
| ], | ||
| challengeTypes, | ||
| loading: false, | ||
| loadMore, | ||
| setFilterState, | ||
|
|
@@ -84,6 +88,109 @@ test('Matches shallow shapshot', () => { | |
| }); | ||
| }); | ||
|
|
||
| function countElementsByType(element, type) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [ |
||
| if (!React.isValidElement(element)) { | ||
| return 0; | ||
| } | ||
|
|
||
| let count = element.type === type ? 1 : 0; | ||
| React.Children.forEach(element.props.children, (child) => { | ||
| count += countElementsByType(child, type); | ||
| }); | ||
|
|
||
| return count; | ||
| } | ||
|
|
||
| test('Shows assigned task when memberId and userId are matching strings', () => { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [ |
||
| const renderer = new Renderer(); | ||
| renderer.render(( | ||
| <Bucket | ||
| activeBucket="openForRegistration" | ||
| auth={{ user: { roles: [] } }} | ||
| bucket="openForRegistration" | ||
| challenges={[ | ||
| { | ||
| id: 'task-1', | ||
| name: 'Assigned task', | ||
| status: 'ACTIVE', | ||
| type: { name: 'Task' }, | ||
| tags: [], | ||
| prizes: [], | ||
| task: { | ||
| isTask: true, | ||
| isAssigned: true, | ||
| memberId: 'c0ffee-123', | ||
| }, | ||
| }, | ||
| ]} | ||
| 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="c0ffee-123" | ||
| /> | ||
| )); | ||
|
|
||
| expect(countElementsByType(renderer.getRenderOutput(), ChallengeCard)).toBe(1); | ||
| }); | ||
|
|
||
| test('Hides assigned task when memberId and userId do not match', () => { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [ |
||
| const renderer = new Renderer(); | ||
| renderer.render(( | ||
| <Bucket | ||
| activeBucket="openForRegistration" | ||
| auth={{ user: { roles: [] } }} | ||
| bucket="openForRegistration" | ||
| challenges={[ | ||
| { | ||
| id: 'task-2', | ||
| name: 'Assigned task', | ||
| status: 'ACTIVE', | ||
| type: { name: 'Task' }, | ||
| tags: [], | ||
| prizes: [], | ||
| task: { | ||
| isTask: true, | ||
| isAssigned: true, | ||
| memberId: '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() {} | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| import { getDisplayWinners, isWiproRegistrationBlocked } from 'containers/challenge-detail'; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [ |
||
|
|
||
| describe('Challenge detail Wipro registration guard', () => { | ||
| test('blocks Wipro members when challenge disallows Wipro participation', () => { | ||
| expect(isWiproRegistrationBlocked('member@wipro.com', false)).toBe(true); | ||
| }); | ||
|
|
||
| test('does not block Wipro members when challenge allows Wipro participation', () => { | ||
| expect(isWiproRegistrationBlocked('member@wipro.com', true)).toBe(false); | ||
| }); | ||
|
|
||
| test('does not block non-Wipro members when challenge disallows Wipro participation', () => { | ||
| expect(isWiproRegistrationBlocked('member@example.com', false)).toBe(false); | ||
| }); | ||
|
|
||
| test('matches Wipro domain case-insensitively and ignores surrounding spaces', () => { | ||
| expect(isWiproRegistrationBlocked(' MEMBER@WIPRO.COM ', false)).toBe(true); | ||
| }); | ||
| }); | ||
|
|
||
| describe('Challenge detail winners filter', () => { | ||
| test('includes legacy winners with "Final" type for non-task challenges', () => { | ||
| const winners = getDisplayWinners({ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [ |
||
| type: 'Challenge', | ||
| winners: [ | ||
| { handle: 'legacyFinal', type: 'Final' }, | ||
| { handle: 'newFinal', type: 'final' }, | ||
| { handle: 'provisionalWinner', type: 'provisional' }, | ||
| ], | ||
| }); | ||
|
|
||
| expect(winners).toEqual([ | ||
| { handle: 'legacyFinal', type: 'Final' }, | ||
| { handle: 'newFinal', type: 'final' }, | ||
| ]); | ||
| }); | ||
|
|
||
| test('does not filter winners for task challenges', () => { | ||
| const winners = getDisplayWinners({ | ||
| type: 'Task', | ||
| winners: [ | ||
| { handle: 'taskWinner', type: 'provisional' }, | ||
| ], | ||
| }); | ||
|
|
||
| expect(winners).toEqual([ | ||
| { handle: 'taskWinner', type: 'provisional' }, | ||
| ]); | ||
| }); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[⚠️
maintainability]Using
JSON.stringifyto convert the component's output to a string for assertions may lead to brittle tests. Consider using a more robust method to inspect the rendered output, such as querying the rendered component tree for specific elements or text.