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
34 changes: 17 additions & 17 deletions app/components/UI/Bridge/hooks/useRewards/useRewards.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,10 @@ describe('useRewards', () => {
mockUnsubscribe.mockClear();
});

describe('when rewards feature is disabled', () => {
it('should return default state when rewards feature is disabled', async () => {
describe('when there is no active season', () => {
it('should return default state when there is no active season', async () => {
mockCall.mockImplementation((method) => {
if (method === 'RewardsController:isRewardsFeatureEnabled') {
if (method === 'RewardsController:hasActiveSeason') {
return Promise.resolve(false);
}
return Promise.resolve(null);
Expand Down Expand Up @@ -235,15 +235,15 @@ describe('useRewards', () => {
});

expect(mockCall).toHaveBeenCalledWith(
'RewardsController:isRewardsFeatureEnabled',
'RewardsController:hasActiveSeason',
);
});
});

describe('when user has not opted in', () => {
it('should return default state when user has not opted in and opt-in is not supported', async () => {
mockCall.mockImplementation((method) => {
if (method === 'RewardsController:isRewardsFeatureEnabled') {
if (method === 'RewardsController:hasActiveSeason') {
return Promise.resolve(true);
}
if (method === 'RewardsController:getCandidateSubscriptionId') {
Expand Down Expand Up @@ -301,7 +301,7 @@ describe('useRewards', () => {

it('should show rewards row when user has not opted in but opt-in is supported', async () => {
mockCall.mockImplementation((method) => {
if (method === 'RewardsController:isRewardsFeatureEnabled') {
if (method === 'RewardsController:hasActiveSeason') {
return Promise.resolve(true);
}
if (method === 'RewardsController:getCandidateSubscriptionId') {
Expand Down Expand Up @@ -361,7 +361,7 @@ describe('useRewards', () => {
describe('when rewards estimation is successful', () => {
it('should return estimated points when all conditions are met', async () => {
mockCall.mockImplementation((method) => {
if (method === 'RewardsController:isRewardsFeatureEnabled') {
if (method === 'RewardsController:hasActiveSeason') {
return Promise.resolve(true);
}
if (method === 'RewardsController:getCandidateSubscriptionId') {
Expand Down Expand Up @@ -432,7 +432,7 @@ describe('useRewards', () => {

it('should handle source token without exchange rate', async () => {
mockCall.mockImplementation((method) => {
if (method === 'RewardsController:isRewardsFeatureEnabled') {
if (method === 'RewardsController:hasActiveSeason') {
return Promise.resolve(true);
}
if (method === 'RewardsController:getCandidateSubscriptionId') {
Expand Down Expand Up @@ -603,7 +603,7 @@ describe('useRewards', () => {
describe('when subscription ID is missing', () => {
it('should return default state when there is no subscription', async () => {
mockCall.mockImplementation((method) => {
if (method === 'RewardsController:isRewardsFeatureEnabled') {
if (method === 'RewardsController:hasActiveSeason') {
return Promise.resolve(true);
}
if (method === 'RewardsController:getCandidateSubscriptionId') {
Expand Down Expand Up @@ -641,7 +641,7 @@ describe('useRewards', () => {
});

expect(mockCall).toHaveBeenCalledWith(
'RewardsController:isRewardsFeatureEnabled',
'RewardsController:hasActiveSeason',
);
expect(mockCall).toHaveBeenCalledWith(
'RewardsController:getCandidateSubscriptionId',
Expand All @@ -656,7 +656,7 @@ describe('useRewards', () => {
describe('error handling', () => {
it('should handle rewards estimation error gracefully', async () => {
mockCall.mockImplementation((method) => {
if (method === 'RewardsController:isRewardsFeatureEnabled') {
if (method === 'RewardsController:hasActiveSeason') {
return Promise.resolve(true);
}
if (method === 'RewardsController:getCandidateSubscriptionId') {
Expand Down Expand Up @@ -700,10 +700,10 @@ describe('useRewards', () => {
});
});

it('should set hasError to true when isRewardsFeatureEnabled throws an error', async () => {
it('should set hasError to true when hasActiveSeason throws an error', async () => {
mockCall.mockImplementation((method) => {
if (method === 'RewardsController:isRewardsFeatureEnabled') {
throw new Error('Feature check failed');
if (method === 'RewardsController:hasActiveSeason') {
throw new Error('Active season check failed');
}
return Promise.resolve(null);
});
Expand Down Expand Up @@ -739,7 +739,7 @@ describe('useRewards', () => {

it('should set hasError to true when getHasAccountOptedIn throws an error', async () => {
mockCall.mockImplementation((method) => {
if (method === 'RewardsController:isRewardsFeatureEnabled') {
if (method === 'RewardsController:hasActiveSeason') {
return Promise.resolve(true);
}
if (method === 'RewardsController:getCandidateSubscriptionId') {
Expand Down Expand Up @@ -783,7 +783,7 @@ describe('useRewards', () => {
it('should reset hasError to false when estimation succeeds after previous error', async () => {
// First mock returns error
mockCall.mockImplementationOnce((method) => {
if (method === 'RewardsController:isRewardsFeatureEnabled') {
if (method === 'RewardsController:hasActiveSeason') {
return Promise.resolve(true);
}
if (method === 'RewardsController:getCandidateSubscriptionId') {
Expand Down Expand Up @@ -822,7 +822,7 @@ describe('useRewards', () => {

// Now mock successful response
mockCall.mockImplementation((method) => {
if (method === 'RewardsController:isRewardsFeatureEnabled') {
if (method === 'RewardsController:hasActiveSeason') {
return Promise.resolve(true);
}
if (method === 'RewardsController:getCandidateSubscriptionId') {
Expand Down
8 changes: 4 additions & 4 deletions app/components/UI/Bridge/hooks/useRewards/useRewards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,12 @@ export const useRewards = ({
setHasError(false);

try {
// Check if rewards feature is enabled
const isRewardsEnabled = await Engine.controllerMessenger.call(
'RewardsController:isRewardsFeatureEnabled',
// Check if there is an active season
const hasActiveSeason = await Engine.controllerMessenger.call(
'RewardsController:hasActiveSeason',
);

if (!isRewardsEnabled) {
if (!hasActiveSeason) {
setEstimatedPoints(null);
setShouldShowRewardsRow(false);
setAccountOptedIn(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,8 @@ import { formatDateSection } from '../../utils/formatUtils';
import { styleSheet } from './PerpsTransactionsView.styles';
import { usePerpsMeasurement } from '../../hooks/usePerpsMeasurement';
import { TraceName } from '../../../../../util/trace';
import Button, {
ButtonSize,
ButtonVariants,
} from '../../../../../component-library/components/Buttons/Button';
import ButtonFilter from '../../../../../component-library/components-temp/ButtonFilter';
import { ButtonSize } from '@metamask/design-system-react-native';

const PerpsTransactionsView: React.FC<PerpsTransactionsViewProps> = () => {
const { styles } = useStyles(styleSheet, {});
Expand Down Expand Up @@ -225,14 +223,15 @@ const PerpsTransactionsView: React.FC<PerpsTransactionsViewProps> = () => {
};

return (
<Button
<ButtonFilter
key={tab}
variant={isActive ? ButtonVariants.Primary : ButtonVariants.Secondary}
size={ButtonSize.Sm}
isActive={isActive}
size={ButtonSize.Md}
onPress={handleTabPress}
accessibilityRole="button"
label={strings(`perps.transactions.tabs.${i18nKey}`)}
/>
>
{strings(`perps.transactions.tabs.${i18nKey}`)}
</ButtonFilter>
);
},
[activeFilter],
Expand Down
50 changes: 26 additions & 24 deletions app/components/UI/Perps/hooks/usePerpsRewardAccountOptedIn.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ describe('usePerpsRewardAccountOptedIn', () => {
});

it('returns selected account when available', async () => {
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockResolvedValueOnce('subscription-id'); // getCandidateSubscriptionId
mockEngineCall.mockResolvedValueOnce(true); // getHasAccountOptedIn

Expand All @@ -150,9 +150,9 @@ describe('usePerpsRewardAccountOptedIn', () => {
});
});

describe('Rewards feature enabled check', () => {
it('returns null when rewards feature is disabled', async () => {
mockEngineCall.mockResolvedValueOnce(false); // isRewardsFeatureEnabled
describe('Active season check', () => {
it('returns null when there is no active season', async () => {
mockEngineCall.mockResolvedValueOnce(false); // hasActiveSeason

const { result } = renderHook(() => usePerpsRewardAccountOptedIn());

Expand All @@ -161,23 +161,23 @@ describe('usePerpsRewardAccountOptedIn', () => {
});

expect(mockEngineCall).toHaveBeenCalledWith(
'RewardsController:isRewardsFeatureEnabled',
'RewardsController:hasActiveSeason',
);
expect(mockEngineCall).not.toHaveBeenCalledWith(
'RewardsController:getCandidateSubscriptionId',
);
});

it('proceeds to check subscription when rewards feature is enabled', async () => {
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
it('proceeds to check subscription when there is an active season', async () => {
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockResolvedValueOnce('subscription-id'); // getCandidateSubscriptionId
mockEngineCall.mockResolvedValueOnce(true); // getHasAccountOptedIn

renderHook(() => usePerpsRewardAccountOptedIn());

await waitFor(() => {
expect(mockEngineCall).toHaveBeenCalledWith(
'RewardsController:isRewardsFeatureEnabled',
'RewardsController:hasActiveSeason',
);
expect(mockEngineCall).toHaveBeenCalledWith(
'RewardsController:getCandidateSubscriptionId',
Expand All @@ -188,7 +188,7 @@ describe('usePerpsRewardAccountOptedIn', () => {

describe('Subscription check', () => {
it('returns null when no subscription exists', async () => {
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockResolvedValueOnce(null); // getCandidateSubscriptionId

const { result } = renderHook(() => usePerpsRewardAccountOptedIn());
Expand All @@ -206,7 +206,7 @@ describe('usePerpsRewardAccountOptedIn', () => {
});

it('proceeds to check opt-in when subscription exists', async () => {
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockResolvedValueOnce('subscription-id'); // getCandidateSubscriptionId
mockEngineCall.mockResolvedValueOnce(true); // getHasAccountOptedIn

Expand All @@ -226,7 +226,7 @@ describe('usePerpsRewardAccountOptedIn', () => {

describe('CAIP account formatting', () => {
it('returns null when CAIP formatting fails', async () => {
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockResolvedValueOnce('subscription-id'); // getCandidateSubscriptionId
mockFormatAccountToCaipAccountId.mockReturnValue(null);

Expand All @@ -248,7 +248,7 @@ describe('usePerpsRewardAccountOptedIn', () => {

it('uses formatted CAIP account for opt-in check', async () => {
const customCaipAccount = 'eip155:1:0xCustomAddress';
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockResolvedValueOnce('subscription-id'); // getCandidateSubscriptionId
mockFormatAccountToCaipAccountId.mockReturnValue(customCaipAccount);
mockEngineCall.mockResolvedValueOnce(true); // getHasAccountOptedIn
Expand All @@ -266,7 +266,7 @@ describe('usePerpsRewardAccountOptedIn', () => {

describe('Account opt-in status', () => {
it('returns true when account has opted in', async () => {
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockResolvedValueOnce('subscription-id'); // getCandidateSubscriptionId
mockEngineCall.mockResolvedValueOnce(true); // getHasAccountOptedIn

Expand All @@ -278,7 +278,7 @@ describe('usePerpsRewardAccountOptedIn', () => {
});

it('returns false when account has not opted in and opt-in is supported', async () => {
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockResolvedValueOnce('subscription-id'); // getCandidateSubscriptionId
mockEngineCall.mockResolvedValueOnce(false); // getHasAccountOptedIn
mockEngineCall.mockResolvedValueOnce(true); // isOptInSupported
Expand All @@ -296,7 +296,7 @@ describe('usePerpsRewardAccountOptedIn', () => {
});

it('returns null when account has not opted in and opt-in is not supported', async () => {
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockResolvedValueOnce('subscription-id'); // getCandidateSubscriptionId
mockEngineCall.mockResolvedValueOnce(false); // getHasAccountOptedIn
mockEngineCall.mockResolvedValueOnce(false); // isOptInSupported
Expand All @@ -315,8 +315,10 @@ describe('usePerpsRewardAccountOptedIn', () => {
});

describe('Error handling', () => {
it('returns null when isRewardsFeatureEnabled throws error', async () => {
mockEngineCall.mockRejectedValueOnce(new Error('Feature check failed'));
it('returns null when hasActiveSeason throws error', async () => {
mockEngineCall.mockRejectedValueOnce(
new Error('Active season check failed'),
);

const { result } = renderHook(() => usePerpsRewardAccountOptedIn());

Expand All @@ -326,7 +328,7 @@ describe('usePerpsRewardAccountOptedIn', () => {
});

it('returns null when getCandidateSubscriptionId throws error', async () => {
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockRejectedValueOnce(
new Error('Subscription check failed'),
);
Expand All @@ -339,7 +341,7 @@ describe('usePerpsRewardAccountOptedIn', () => {
});

it('returns null when getHasAccountOptedIn throws error', async () => {
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockResolvedValueOnce('subscription-id'); // getCandidateSubscriptionId
mockEngineCall.mockRejectedValueOnce(new Error('Opt-in check failed'));

Expand All @@ -351,7 +353,7 @@ describe('usePerpsRewardAccountOptedIn', () => {
});

it('returns null when isOptInSupported throws error', async () => {
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockResolvedValueOnce('subscription-id'); // getCandidateSubscriptionId
mockEngineCall.mockResolvedValueOnce(false); // getHasAccountOptedIn
mockEngineCall.mockRejectedValueOnce(
Expand All @@ -368,7 +370,7 @@ describe('usePerpsRewardAccountOptedIn', () => {

describe('Account linked event subscription', () => {
it('subscribes to account linked event on mount', () => {
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockResolvedValueOnce('subscription-id'); // getCandidateSubscriptionId
mockEngineCall.mockResolvedValueOnce(true); // getHasAccountOptedIn

Expand All @@ -381,7 +383,7 @@ describe('usePerpsRewardAccountOptedIn', () => {
});

it('unsubscribes from account linked event on unmount', () => {
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockResolvedValueOnce('subscription-id'); // getCandidateSubscriptionId
mockEngineCall.mockResolvedValueOnce(true); // getHasAccountOptedIn

Expand Down Expand Up @@ -467,7 +469,7 @@ describe('usePerpsRewardAccountOptedIn', () => {

describe('Integration scenarios', () => {
it('handles complete flow from account selection to opt-in check', async () => {
mockEngineCall.mockResolvedValueOnce(true); // isRewardsFeatureEnabled
mockEngineCall.mockResolvedValueOnce(true); // hasActiveSeason
mockEngineCall.mockResolvedValueOnce('subscription-123'); // getCandidateSubscriptionId
mockEngineCall.mockResolvedValueOnce(true); // getHasAccountOptedIn

Expand All @@ -479,7 +481,7 @@ describe('usePerpsRewardAccountOptedIn', () => {
});

expect(mockEngineCall).toHaveBeenCalledWith(
'RewardsController:isRewardsFeatureEnabled',
'RewardsController:hasActiveSeason',
);
expect(mockEngineCall).toHaveBeenCalledWith(
'RewardsController:getCandidateSubscriptionId',
Expand Down
8 changes: 4 additions & 4 deletions app/components/UI/Perps/hooks/usePerpsRewardAccountOptedIn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ export const usePerpsRewardAccountOptedIn = (
}

try {
// Check if rewards feature is enabled
const isRewardsEnabled = await Engine.controllerMessenger.call(
'RewardsController:isRewardsFeatureEnabled',
// Check if there is an active season
const hasActiveSeason = await Engine.controllerMessenger.call(
'RewardsController:hasActiveSeason',
);

if (!isRewardsEnabled) {
if (!hasActiveSeason) {
setAccountOptedIn(null);
return;
}
Expand Down
Loading
Loading