|
|
@@ -26,6 +26,7 @@ import {
|
|
|
pageLoadingAtom,
|
|
|
pageNotFoundAtom,
|
|
|
remoteRevisionBodyAtom,
|
|
|
+ shareLinkIdAtom,
|
|
|
} from '~/states/page/internal-atoms';
|
|
|
import { useSWRxPageInfo } from '~/stores/page';
|
|
|
|
|
|
@@ -1045,4 +1046,78 @@ describe('useFetchCurrentPage - Integration Test', () => {
|
|
|
expect(store.get(currentPageEntityIdAtom)).toBe('pageId123');
|
|
|
});
|
|
|
});
|
|
|
+
|
|
|
+ it('should use currentPageId when shareLinkId is present instead of path from router', async () => {
|
|
|
+ // Arrange: Simulate share link page where SSR is skipped and CSR fetch is triggered
|
|
|
+ // shareLinkIdAtom is hydrated from SSR props, currentPageEntityIdAtom is also hydrated
|
|
|
+ const shareLinkId = '65d4e0a0f7b7b2e5a8652e86';
|
|
|
+ const pageId = '58a4569921a8424d00a1aa0e';
|
|
|
+ store.set(shareLinkIdAtom, shareLinkId);
|
|
|
+ store.set(currentPageEntityIdAtom, pageId);
|
|
|
+
|
|
|
+ const pageData = createPageDataMock(
|
|
|
+ pageId,
|
|
|
+ '/actual/wiki/path',
|
|
|
+ 'share link page content that is very long',
|
|
|
+ );
|
|
|
+ mockedApiv3Get.mockResolvedValue(mockApiResponse(pageData));
|
|
|
+
|
|
|
+ // Act: fetchCurrentPage is called with router.asPath = /share/<shareLinkId>
|
|
|
+ // This simulates what useInitialCsrFetch does when SSR is skipped
|
|
|
+ const { result } = renderHookWithProvider();
|
|
|
+ await act(async () => {
|
|
|
+ await result.current.fetchCurrentPage({
|
|
|
+ path: `/share/${shareLinkId}`,
|
|
|
+ force: true,
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ // Assert: API should be called with pageId (not path=/share/...) and shareLinkId
|
|
|
+ await waitFor(() => {
|
|
|
+ expect(mockedApiv3Get).toHaveBeenCalledWith(
|
|
|
+ '/page',
|
|
|
+ expect.objectContaining({
|
|
|
+ pageId,
|
|
|
+ shareLinkId,
|
|
|
+ }),
|
|
|
+ );
|
|
|
+ // path should NOT be sent
|
|
|
+ expect(mockedApiv3Get).toHaveBeenCalledWith(
|
|
|
+ '/page',
|
|
|
+ expect.not.objectContaining({ path: expect.anything() }),
|
|
|
+ );
|
|
|
+ expect(store.get(currentPageEntityIdAtom)).toBe(pageId);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should fall through to existing logic when shareLinkId is present but currentPageId is null', async () => {
|
|
|
+ // Arrange: shareLinkId is set but currentPageEntityIdAtom is not
|
|
|
+ const shareLinkId = '65d4e0a0f7b7b2e5a8652e86';
|
|
|
+ store.set(shareLinkIdAtom, shareLinkId);
|
|
|
+ // currentPageEntityIdAtom is NOT set (undefined)
|
|
|
+
|
|
|
+ const pageData = createPageDataMock(
|
|
|
+ 'somePageId',
|
|
|
+ '/share/some-path',
|
|
|
+ 'content',
|
|
|
+ );
|
|
|
+ mockedApiv3Get.mockResolvedValue(mockApiResponse(pageData));
|
|
|
+
|
|
|
+ // Act: fetchCurrentPage called with a path
|
|
|
+ const { result } = renderHookWithProvider();
|
|
|
+ await act(async () => {
|
|
|
+ await result.current.fetchCurrentPage({ path: '/some/path' });
|
|
|
+ });
|
|
|
+
|
|
|
+ // Assert: Falls through to path-based logic since currentPageId is null
|
|
|
+ await waitFor(() => {
|
|
|
+ expect(mockedApiv3Get).toHaveBeenCalledWith(
|
|
|
+ '/page',
|
|
|
+ expect.objectContaining({
|
|
|
+ path: '/some/path',
|
|
|
+ shareLinkId,
|
|
|
+ }),
|
|
|
+ );
|
|
|
+ });
|
|
|
+ });
|
|
|
});
|