Skip to content

Commit eb7e457

Browse files
authored
feat(predict): add NBA support to sports predictions (#24955)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** - Add 'nba' to PredictSportsLeague type union - Add NBA slug pattern for game parsing (nba-{away}-{home}-{date}) - Include 'nba' in SUPPORTED_SPORTS_LEAGUES constant - Generalize PredictMarket to render sport cards for any game with a league - Remove NFL-specific getNflTeam method in favor of generic getTeam - Update TeamsCache tests to reflect removed method <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Expands sports support and simplifies league-specific logic. > > - Adds `nba` to `PredictSportsLeague` and `SUPPORTED_SPORTS_LEAGUES`; introduces `NBA_SLUG_PATTERN` and updates `LEAGUE_SLUG_PATTERNS` in `utils/gameParser.ts` > - Generalizes `PredictMarket` to render `PredictMarketSportCard` for any `market.game` (not just `nfl`) > - Removes `getNflTeam` from `TeamsCache` in favor of generic `getTeam`; updates `TeamsCache.test.ts` accordingly > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 6f465aa. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 7cb245e commit eb7e457

6 files changed

Lines changed: 5 additions & 33 deletions

File tree

app/components/UI/Predict/components/PredictMarket/PredictMarket.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const PredictMarket: React.FC<PredictMarketProps> = ({
1919
entryPoint = PredictEventValues.ENTRY_POINT.PREDICT_FEED,
2020
isCarousel = false,
2121
}) => {
22-
if (market.game?.league === 'nfl') {
22+
if (market.game) {
2323
return (
2424
<PredictMarketSportCard
2525
market={market}

app/components/UI/Predict/constants/sports.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { PredictSportsLeague } from '../types';
99
* 3. Add the league to this array
1010
* 4. Add tests for the new league's slug parsing
1111
*/
12-
export const SUPPORTED_SPORTS_LEAGUES: PredictSportsLeague[] = ['nfl'];
12+
export const SUPPORTED_SPORTS_LEAGUES: PredictSportsLeague[] = ['nfl', 'nba'];
1313

1414
export const filterSupportedLeagues = (
1515
leagues: string[],

app/components/UI/Predict/providers/polymarket/TeamsCache.test.ts

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -276,32 +276,6 @@ describe('TeamsCache', () => {
276276
});
277277
});
278278

279-
describe('getNflTeam', () => {
280-
beforeEach(async () => {
281-
mockFetch.mockResolvedValueOnce({
282-
ok: true,
283-
json: async () => mockNflTeams,
284-
});
285-
await TeamsCache.getInstance().ensureLeagueLoaded('nfl');
286-
});
287-
288-
it('returns NFL team by abbreviation', () => {
289-
const cache = TeamsCache.getInstance();
290-
291-
const team = cache.getNflTeam('den');
292-
293-
expect(team?.name).toBe('Denver Broncos');
294-
});
295-
296-
it('returns undefined for unknown NFL team', () => {
297-
const cache = TeamsCache.getInstance();
298-
299-
const team = cache.getNflTeam('unknown');
300-
301-
expect(team).toBeUndefined();
302-
});
303-
});
304-
305279
describe('isLeagueLoaded', () => {
306280
it('returns false for unloaded league', () => {
307281
const cache = TeamsCache.getInstance();

app/components/UI/Predict/providers/polymarket/TeamsCache.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,6 @@ export class TeamsCache {
6060
return leagueCache.get(abbreviation.toLowerCase());
6161
}
6262

63-
getNflTeam(abbreviation: string): PolymarketApiTeam | undefined {
64-
return this.getTeam('nfl', abbreviation);
65-
}
66-
6763
isLeagueLoaded(league: PredictSportsLeague): boolean {
6864
return this.cache.has(league);
6965
}

app/components/UI/Predict/types/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export type PredictCategory =
113113
| 'politics';
114114

115115
// Sports league types
116-
export type PredictSportsLeague = 'nfl';
116+
export type PredictSportsLeague = 'nfl' | 'nba';
117117

118118
// Game status
119119
export type PredictGameStatus = 'scheduled' | 'ongoing' | 'ended';

app/components/UI/Predict/utils/gameParser.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ import {
1111
} from '../providers/polymarket/types';
1212

1313
const NFL_SLUG_PATTERN = /^nfl-([a-z]+)-([a-z]+)-(\d{4}-\d{2}-\d{2})$/;
14+
const NBA_SLUG_PATTERN = /^nba-([a-z]+)-([a-z]+)-(\d{4}-\d{2}-\d{2})$/;
1415

1516
const LEAGUE_SLUG_PATTERNS: Record<PredictSportsLeague, RegExp> = {
1617
nfl: NFL_SLUG_PATTERN,
18+
nba: NBA_SLUG_PATTERN,
1719
};
1820

1921
export type TeamLookup = (

0 commit comments

Comments
 (0)