diff --git a/__tests__/components/waves/drop/SingleWaveDropVoteInput.test.tsx b/__tests__/components/waves/drop/SingleWaveDropVoteInput.test.tsx
index 16ac0efce8..1d3b5177ac 100644
--- a/__tests__/components/waves/drop/SingleWaveDropVoteInput.test.tsx
+++ b/__tests__/components/waves/drop/SingleWaveDropVoteInput.test.tsx
@@ -2,7 +2,6 @@ import React from 'react';
import { render, screen, fireEvent, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { SingleWaveDropVoteInput } from '@/components/waves/drop/SingleWaveDropVoteInput';
-import { ApiWaveCreditType } from '@/generated/models/ObjectSerializer';
// Mock timers for testing interval behavior
jest.useFakeTimers();
@@ -12,7 +11,7 @@ describe('SingleWaveDropVoteInput', () => {
voteValue: 0,
minValue: -1000,
maxValue: 1000,
- creditType: ApiWaveCreditType.Rep,
+ label: "Rep",
setVoteValue: jest.fn(),
onSubmit: jest.fn(),
};
@@ -37,8 +36,8 @@ describe('SingleWaveDropVoteInput', () => {
});
it('displays credit type in input field', () => {
- render();
-
+ render();
+
expect(screen.getByText('TDH')).toBeInTheDocument();
});
diff --git a/__tests__/components/waves/drop/SingleWaveDropVoteSlider.test.tsx b/__tests__/components/waves/drop/SingleWaveDropVoteSlider.test.tsx
index 0cfbf99057..3577d9095f 100644
--- a/__tests__/components/waves/drop/SingleWaveDropVoteSlider.test.tsx
+++ b/__tests__/components/waves/drop/SingleWaveDropVoteSlider.test.tsx
@@ -1,6 +1,5 @@
import { render, screen, fireEvent } from '@testing-library/react';
import SingleWaveDropVoteSlider from '@/components/waves/drop/SingleWaveDropVoteSlider';
-import { ApiWaveCreditType } from '@/generated/models/ApiWaveCreditType';
// Mock framer-motion
jest.mock('framer-motion', () => ({
@@ -35,7 +34,7 @@ describe('SingleWaveDropVoteSlider', () => {
minValue: -100,
maxValue: 100,
setVoteValue: jest.fn(),
- creditType: ApiWaveCreditType.Rep,
+ label: "Rep",
};
beforeEach(() => {
@@ -44,29 +43,29 @@ describe('SingleWaveDropVoteSlider', () => {
it('renders slider with basic elements', () => {
render();
-
+
const sliders = screen.getAllByRole('slider');
expect(sliders.length).toBeGreaterThan(0);
const tooltips = screen.getAllByText((content, element) => {
- return element?.textContent === '50 REP';
+ return element?.textContent === '50 Rep';
});
expect(tooltips.length).toBeGreaterThan(0); // Vote value in tooltip
});
it('displays vote value in tooltip', () => {
render();
-
+
const tooltips = screen.getAllByText((content, element) => {
- return element?.textContent === '75 REP';
+ return element?.textContent === '75 Rep';
});
expect(tooltips.length).toBeGreaterThan(0);
});
it('handles string vote value by defaulting to 0', () => {
render();
-
+
const tooltips = screen.getAllByText((content, element) => {
- return element?.textContent === '0 REP';
+ return element?.textContent === '0 Rep';
});
expect(tooltips.length).toBeGreaterThan(0);
});
@@ -111,18 +110,18 @@ describe('SingleWaveDropVoteSlider', () => {
it('handles zero range case', () => {
render();
-
+
const tooltips = screen.getAllByText((content, element) => {
- return element?.textContent === '0 REP';
+ return element?.textContent === '0 Rep';
});
expect(tooltips.length).toBeGreaterThan(0);
});
it('handles negative vote values', () => {
render();
-
+
const tooltips = screen.getAllByText((content, element) => {
- return element?.textContent === '-25 REP';
+ return element?.textContent === '-25 Rep';
});
expect(tooltips.length).toBeGreaterThan(0);
});
@@ -161,20 +160,20 @@ describe('SingleWaveDropVoteSlider', () => {
});
it('displays correct credit type in tooltip', () => {
- render();
-
+ render();
+
const tooltips = screen.getAllByText((content, element) => {
- return element?.textContent === '50 REP';
+ return element?.textContent === '50 Rep';
});
expect(tooltips.length).toBeGreaterThan(0);
});
it('handles edge case where all values are zero', () => {
render();
-
+
// Should render without crashing and show 0 value
const tooltips = screen.getAllByText((content, element) => {
- return element?.textContent === '0 REP';
+ return element?.textContent === '0 Rep';
});
expect(tooltips.length).toBeGreaterThan(0);
});
diff --git a/__tests__/components/waves/drop/SingleWaveDropVoteSubmit.test.tsx b/__tests__/components/waves/drop/SingleWaveDropVoteSubmit.test.tsx
index e98492d639..2e964a5894 100644
--- a/__tests__/components/waves/drop/SingleWaveDropVoteSubmit.test.tsx
+++ b/__tests__/components/waves/drop/SingleWaveDropVoteSubmit.test.tsx
@@ -142,9 +142,9 @@ describe('SingleWaveDropVoteSubmit', () => {
it('renders vote button with correct initial text', () => {
renderComponent();
-
+
expect(screen.getByRole('button')).toBeInTheDocument();
- expect(screen.getByText('Vote!')).toBeInTheDocument();
+ expect(screen.getByText('Vote')).toBeInTheDocument();
});
it('applies correct styling based on drop rank', () => {
@@ -159,13 +159,13 @@ describe('SingleWaveDropVoteSubmit', () => {
mockCommonApiPost.mockResolvedValue(mockDrop);
renderComponent();
-
+
const button = screen.getByRole('button');
fireEvent.click(button);
// Should show loading spinner
await waitFor(() => {
- expect(screen.getByText('Vote!')).toBeInTheDocument();
+ expect(screen.getByText('Vote')).toBeInTheDocument();
});
});
@@ -234,12 +234,12 @@ describe('SingleWaveDropVoteSubmit', () => {
mockCommonApiPost.mockRejectedValue(mockError);
renderComponent();
-
+
const button = screen.getByRole('button');
fireEvent.click(button);
// Button should show initial text
- expect(screen.getByText('Vote!')).toBeInTheDocument();
+ expect(screen.getByText('Vote')).toBeInTheDocument();
});
it('accepts onVoteSuccess callback prop', () => {
@@ -273,10 +273,10 @@ describe('SingleWaveDropVoteSubmit', () => {
it('renders button with initial vote text', () => {
renderComponent();
-
+
const button = screen.getByRole('button');
expect(button).toBeInTheDocument();
- expect(screen.getByText('Vote!')).toBeInTheDocument();
+ expect(screen.getByText('Vote')).toBeInTheDocument();
});
it('exposes handleClick method through ref', () => {
diff --git a/__tests__/components/waves/leaderboard/sidebar/WaveLeaderboardRightSidebarActivityLog.test.tsx b/__tests__/components/waves/leaderboard/sidebar/WaveLeaderboardRightSidebarActivityLog.test.tsx
index f4ec7c2bdb..314f8e8656 100644
--- a/__tests__/components/waves/leaderboard/sidebar/WaveLeaderboardRightSidebarActivityLog.test.tsx
+++ b/__tests__/components/waves/leaderboard/sidebar/WaveLeaderboardRightSidebarActivityLog.test.tsx
@@ -112,13 +112,14 @@ describe('WaveLeaderboardRightSidebarActivityLog', () => {
it('displays voter information with profile picture', () => {
renderComponent();
-
+
const voterLink = screen.getByTitle('Voter: voter_user');
expect(voterLink).toHaveAttribute('href', '/voter_user');
expect(screen.getByText('voter_user')).toBeInTheDocument();
-
+
const voterPfp = voterLink.querySelector('img');
- expect(voterPfp).toHaveAttribute('src', 'https://example.com/voter.jpg');
+ expect(voterPfp).toBeInTheDocument();
+ expect(voterPfp).toHaveAttribute('src', expect.stringContaining('voter.jpg'));
expect(voterPfp).toHaveClass('tw-size-5', 'tw-rounded-md');
});
@@ -138,13 +139,14 @@ describe('WaveLeaderboardRightSidebarActivityLog', () => {
it('displays drop author information with profile picture', () => {
renderComponent();
-
+
const authorLink = screen.getByTitle('Drop creator: author_user');
expect(authorLink).toHaveAttribute('href', '/author_user');
expect(screen.getByText('author_user')).toBeInTheDocument();
-
+
const authorPfp = authorLink.querySelector('img');
- expect(authorPfp).toHaveAttribute('src', 'https://example.com/author.jpg');
+ expect(authorPfp).toBeInTheDocument();
+ expect(authorPfp).toHaveAttribute('src', expect.stringContaining('author.jpg'));
});
it('displays drop author information without profile picture', () => {
diff --git a/__tests__/helpers/Helpers.test.ts b/__tests__/helpers/Helpers.test.ts
index 3482593e90..3f3cdd518a 100644
--- a/__tests__/helpers/Helpers.test.ts
+++ b/__tests__/helpers/Helpers.test.ts
@@ -74,7 +74,7 @@ describe("additional helper functions", () => {
test("parseNftDescriptionToHtml replaces newlines and links", () => {
const input = "line1\nhttps://example.com";
expect(parseNftDescriptionToHtml(input)).toBe(
- 'line1
https://example.com'
+ 'line1
https://example.com'
);
});
diff --git a/contexts/wave/hooks/useWaveMessagesStore.ts b/contexts/wave/hooks/useWaveMessagesStore.ts
index 692c94c6b4..0782d7a345 100644
--- a/contexts/wave/hooks/useWaveMessagesStore.ts
+++ b/contexts/wave/hooks/useWaveMessagesStore.ts
@@ -83,12 +83,9 @@ function useWaveMessagesStore() {
}, [waveMessages]);
// Stable function to get data for a key
- const getData = useCallback(
- (key: string): WaveMessages | undefined => {
- return waveMessages[key];
- },
- [waveMessages]
- ); // Dependency on store is fine here
+ const getData = useCallback((key: string): WaveMessages | undefined => {
+ return waveMessagesRef.current[key];
+ }, []);
// Stable function to subscribe a listener for a specific key
const subscribe = useCallback(
diff --git a/hooks/useDeviceInfo.ts b/hooks/useDeviceInfo.ts
index f63cafd8e6..b07e5cf730 100644
--- a/hooks/useDeviceInfo.ts
+++ b/hooks/useDeviceInfo.ts
@@ -71,7 +71,19 @@ export default function useDeviceInfo(): DeviceInfo {
useEffect(() => {
const mq = window.matchMedia("(pointer: coarse)");
- const update = () => setInfo(getInfo());
+ const update = () =>
+ setInfo((prev) => {
+ const next = getInfo();
+ if (
+ prev.isMobileDevice === next.isMobileDevice &&
+ prev.hasTouchScreen === next.hasTouchScreen &&
+ prev.isApp === next.isApp &&
+ prev.isAppleMobile === next.isAppleMobile
+ ) {
+ return prev;
+ }
+ return next;
+ });
mq.addEventListener("change", update);
window.addEventListener("resize", update);