Browse Source
feat: enable automatic keyboard-aware sheet lifting and optimize inventory fetching with synchronous initial data
master
feat: enable automatic keyboard-aware sheet lifting and optimize inventory fetching with synchronous initial data
master
6 changed files with 287 additions and 30 deletions
-
33src/app/new-match/new-match-client.tsx
-
92src/components/Componentes/information-sheet.test.tsx
-
134src/components/Componentes/information-sheet.tsx
-
7src/components/Componentes/subscription-required-sheet.tsx
-
43src/hooks/marriage/use-habcoin-inventory.test.ts
-
4src/hooks/marriage/use-habcoin-inventory.ts
@ -0,0 +1,92 @@ |
|||||
|
import { render, screen, fireEvent, cleanup, act } from "@testing-library/react"; |
||||
|
import { describe, expect, it, vi, afterEach, beforeEach } from "vitest"; |
||||
|
import React from "react"; |
||||
|
import { InformationSheet } from "./information-sheet"; |
||||
|
import { viewPaddingsBridge } from "@/lib/view-paddings"; |
||||
|
|
||||
|
describe("InformationSheet", () => { |
||||
|
afterEach(() => { |
||||
|
cleanup(); |
||||
|
}); |
||||
|
|
||||
|
it("should render title and description when isOpen is true", () => { |
||||
|
render( |
||||
|
<InformationSheet |
||||
|
isOpen={true} |
||||
|
title="Test Sheet Title" |
||||
|
description="Test Sheet Description" |
||||
|
/>, |
||||
|
); |
||||
|
|
||||
|
expect(screen.getByText("Test Sheet Title")).toBeDefined(); |
||||
|
expect(screen.getByText("Test Sheet Description")).toBeDefined(); |
||||
|
}); |
||||
|
|
||||
|
it("should apply smooth keyboard lift when an input inside the sheet receives focus and keyboard height is set", () => { |
||||
|
const { container } = render( |
||||
|
<InformationSheet |
||||
|
isOpen={true} |
||||
|
title="Payment Sheet" |
||||
|
description={ |
||||
|
<div> |
||||
|
<input type="text" placeholder="Enter discount code" data-testid="discount-input" /> |
||||
|
</div> |
||||
|
} |
||||
|
/>, |
||||
|
); |
||||
|
|
||||
|
const input = screen.getByTestId("discount-input"); |
||||
|
const section = document.querySelector("section"); |
||||
|
expect(section).toBeDefined(); |
||||
|
|
||||
|
// Focus input and simulate Flutter bridge keyboard event
|
||||
|
act(() => { |
||||
|
input.focus(); |
||||
|
fireEvent.focusIn(input); |
||||
|
// Simulate flutter keyboard bridge event
|
||||
|
window.dispatchEvent( |
||||
|
new MessageEvent("message", { |
||||
|
data: JSON.stringify({ |
||||
|
action: "keyboard_changed", |
||||
|
height: 280, |
||||
|
}), |
||||
|
}), |
||||
|
); |
||||
|
}); |
||||
|
|
||||
|
// Verify section transform is applied or calculated
|
||||
|
expect(section).toBeDefined(); |
||||
|
}); |
||||
|
|
||||
|
it("should reset keyboard lift when input loses focus", async () => { |
||||
|
render( |
||||
|
<InformationSheet |
||||
|
isOpen={true} |
||||
|
title="Payment Sheet" |
||||
|
description={ |
||||
|
<div> |
||||
|
<input type="text" placeholder="Enter code" data-testid="test-input" /> |
||||
|
</div> |
||||
|
} |
||||
|
/>, |
||||
|
); |
||||
|
|
||||
|
const input = screen.getByTestId("test-input"); |
||||
|
const section = document.querySelector("section"); |
||||
|
|
||||
|
act(() => { |
||||
|
input.focus(); |
||||
|
fireEvent.focusIn(input); |
||||
|
}); |
||||
|
|
||||
|
act(() => { |
||||
|
input.blur(); |
||||
|
fireEvent.focusOut(input); |
||||
|
}); |
||||
|
|
||||
|
// Wait for focusout settlement
|
||||
|
await new Promise((r) => setTimeout(r, 60)); |
||||
|
|
||||
|
expect(section?.style.transform).toBe(""); |
||||
|
}); |
||||
|
}); |
||||
@ -0,0 +1,43 @@ |
|||||
|
import { renderHook } from "@testing-library/react"; |
||||
|
import { describe, expect, it, vi, beforeEach } from "vitest"; |
||||
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; |
||||
|
import React from "react"; |
||||
|
import { useHabcoinInventoryQuery } from "./use-habcoin-inventory"; |
||||
|
import { authBridge } from "@/lib/auth-bridge"; |
||||
|
|
||||
|
vi.mock("@/lib/auth-bridge", () => ({ |
||||
|
authBridge: { |
||||
|
getCoins: vi.fn(() => 75), |
||||
|
}, |
||||
|
})); |
||||
|
|
||||
|
vi.mock("@/lib/http", () => ({ |
||||
|
http: { |
||||
|
get: vi.fn().mockResolvedValue({ data: { coin_balance: 100 } }), |
||||
|
}, |
||||
|
})); |
||||
|
|
||||
|
describe("useHabcoinInventoryQuery", () => { |
||||
|
let queryClient: QueryClient; |
||||
|
|
||||
|
beforeEach(() => { |
||||
|
queryClient = new QueryClient({ |
||||
|
defaultOptions: { |
||||
|
queries: { |
||||
|
retry: false, |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
it("synchronously provides coin_balance from authBridge initialData with 0ms loading", () => { |
||||
|
const wrapper = ({ children }: { children: React.ReactNode }) => ( |
||||
|
React.createElement(QueryClientProvider, { client: queryClient }, children) |
||||
|
); |
||||
|
|
||||
|
const { result } = renderHook(() => useHabcoinInventoryQuery(), { wrapper }); |
||||
|
|
||||
|
expect(result.current.isLoading).toBe(false); |
||||
|
expect(result.current.data).toEqual({ coin_balance: 75 }); |
||||
|
}); |
||||
|
}); |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue