feat: implement dynamic redirection after login based on location state

This commit is contained in:
ramvignesh-b
2026-04-24 18:43:13 +05:30
parent db31be4ec8
commit 42493a950c
5 changed files with 89 additions and 29 deletions
+50 -15
View File
@@ -1,9 +1,10 @@
import { render, screen, waitFor } from "@testing-library/react";
import { HttpResponse, http } from "msw";
import { MemoryRouter, Route, Routes } from "react-router-dom";
import { MemoryRouter, Route, Routes, useLocation } from "react-router-dom";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { server } from "../../test/mocks/server";
import { endpoints } from "../config/endpoints";
import { useKeyStore } from "../store/useKeyStore";
import { CryptoUtils } from "../utils/crypto";
import Reader from "./Reader";
@@ -19,6 +20,15 @@ describe("Reader Page", () => {
let masterKey: CryptoKey;
let utils: CryptoUtils;
const LocationTest = () => {
const location = useLocation();
return (
<div data-testid="location-state">
{JSON.stringify(location.state || {})}
</div>
);
};
beforeEach(async () => {
vi.clearAllMocks();
@@ -26,6 +36,8 @@ describe("Reader Page", () => {
await utils.initialize();
const bundle = await CryptoUtils.deriveKeyBundle("password", "salt");
masterKey = bundle.masterKey;
// User is logged in by default
useKeyStore.setState({ masterKey });
// Clear the URL hash
vi.stubGlobal("location", {
@@ -34,24 +46,12 @@ describe("Reader Page", () => {
});
});
it("should notify the user if the sharing key is missing from the URL", async () => {
render(
<MemoryRouter initialEntries={["/read/123"]}>
<Routes>
<Route path="/read/:public_id" element={<Reader />} />
</Routes>
</MemoryRouter>,
);
expect(
await screen.findByText(/No sharing key provided/i),
).toBeInTheDocument();
});
it("should load and decrypt the letter when a valid key is provided and display the envelope", async () => {
const mockPublicId = "test-uuid";
const letterContent = JSON.stringify({ objects: [] });
const metadata = { recipient: "Guest" };
// simulate guest
useKeyStore.setState({ masterKey: null });
const encryptedLetter = await utils.encryptLetter(letterContent, masterKey);
const encryptedMetadata = await utils.encryptMetadata(metadata, masterKey);
@@ -103,4 +103,39 @@ describe("Reader Page", () => {
await screen.findByText(/Failed to load letter/i),
).toBeInTheDocument();
});
it("should navigate to the login page with redirect url when the letter has no sharing key and the user is not logged in", async () => {
const mockPublicId = "4ef9f25f-4f37-477a-891a-4b10541e350c";
const letterContent = JSON.stringify({ objects: [] });
const metadata = { recipient: "Guest" };
useKeyStore.setState({ masterKey: null });
const encryptedLetter = await utils.encryptLetter(letterContent, masterKey);
const encryptedMetadata = await utils.encryptMetadata(metadata, masterKey);
server.use(
http.get(`${API_URL}${endpoints.LETTERS}${mockPublicId}/`, () => {
return HttpResponse.json({
encrypted_content: encryptedLetter.encrypted_content,
encrypted_metadata: encryptedMetadata.encrypted_content,
encrypted_dek: encryptedLetter.encrypted_dek,
images: [],
});
}),
);
render(
<MemoryRouter initialEntries={[`/read/${mockPublicId}`]}>
<Routes>
<Route path="/read/:public_id" element={<Reader />} />
<Route path="/login" element={<LocationTest />} />
</Routes>
</MemoryRouter>,
);
const stateComponent = screen.getByTestId("location-state");
expect(stateComponent).toHaveTextContent(
`"redirectUrl":"/read/${mockPublicId}"`,
);
});
});