fix(auth): return to guest session on logout
This commit is contained in:
@@ -49,8 +49,9 @@ function createTestAuthMachine(
|
||||
LoginStatus,
|
||||
{ accessToken: string }
|
||||
>(async () => "facebook"),
|
||||
logout: fromPromise<void>(async () => {
|
||||
logout: fromPromise<LoginStatus>(async () => {
|
||||
logoutSpy();
|
||||
return "guest";
|
||||
}),
|
||||
},
|
||||
});
|
||||
@@ -125,7 +126,7 @@ describe("authMachine", () => {
|
||||
actor.stop();
|
||||
});
|
||||
|
||||
it("logout resets auth state and keeps initialization completed", async () => {
|
||||
it("logout transitions authenticated users back to guest", async () => {
|
||||
const logoutSpy = vi.fn<() => void>();
|
||||
const actor = createActor(createTestAuthMachine({ logoutSpy })).start();
|
||||
|
||||
@@ -141,7 +142,7 @@ describe("authMachine", () => {
|
||||
|
||||
const context = actor.getSnapshot().context;
|
||||
expect(logoutSpy).toHaveBeenCalledOnce();
|
||||
expect(context.loginStatus).toBe("notLoggedIn");
|
||||
expect(context.loginStatus).toBe("guest");
|
||||
expect(context.hasInitialized).toBe(true);
|
||||
|
||||
actor.stop();
|
||||
|
||||
@@ -94,10 +94,12 @@ export const oauthSignInActor = fromPromise<void, AuthProvider>(async ({ input }
|
||||
}
|
||||
});
|
||||
|
||||
export const logoutActor = fromPromise<void>(async () => {
|
||||
export const logoutActor = fromPromise<LoginStatus>(async () => {
|
||||
const authRepo = getAuthRepository();
|
||||
const result = await authRepo.logout();
|
||||
const deviceId = await deviceIdentifier.getDeviceId();
|
||||
const result = await authRepo.logoutToGuest(deviceId);
|
||||
if (Result.isErr(result)) throw result.error;
|
||||
return "guest" as LoginStatus;
|
||||
});
|
||||
|
||||
// ========== OAuth token → 后端业务 token sync actors ==========
|
||||
|
||||
@@ -241,15 +241,16 @@ export const authMachine = setup({
|
||||
src: "logout",
|
||||
onDone: {
|
||||
target: "idle",
|
||||
actions: assign(() => ({
|
||||
...initialState,
|
||||
actions: assign({
|
||||
loginStatus: ({ event }) => event.output,
|
||||
hasInitialized: true,
|
||||
})),
|
||||
errorMessage: null,
|
||||
}),
|
||||
},
|
||||
onError: {
|
||||
target: "idle",
|
||||
actions: assign(({ event }) => ({
|
||||
...initialState,
|
||||
loginStatus: "guest",
|
||||
hasInitialized: true,
|
||||
errorMessage: toAuthErrorMessage(event.error),
|
||||
})),
|
||||
|
||||
@@ -164,7 +164,7 @@ function createLoadHistoryCallback(
|
||||
}
|
||||
|
||||
describe("chatMachine transitions", () => {
|
||||
it("keeps guest logout disabled while allowing upgrade to user login", async () => {
|
||||
it("keeps guest logout disabled and supports user to guest transition", async () => {
|
||||
const actor = createActor(createTestChatMachine()).start();
|
||||
|
||||
actor.send({ type: "ChatGuestLogin" });
|
||||
@@ -180,6 +180,22 @@ describe("chatMachine transitions", () => {
|
||||
snapshot.matches({ userSession: "ready" }),
|
||||
);
|
||||
|
||||
actor.send({ type: "ChatGuestLogin" });
|
||||
await waitFor(actor, (snapshot) =>
|
||||
snapshot.matches({ guestSession: "ready" }),
|
||||
);
|
||||
|
||||
actor.stop();
|
||||
});
|
||||
|
||||
it("allows explicit logout from user session", async () => {
|
||||
const actor = createActor(createTestChatMachine()).start();
|
||||
|
||||
actor.send({ type: "ChatUserLogin", token: "token" });
|
||||
await waitFor(actor, (snapshot) =>
|
||||
snapshot.matches({ userSession: "ready" }),
|
||||
);
|
||||
|
||||
actor.send({ type: "ChatLogout" });
|
||||
expect(actor.getSnapshot().matches("idle")).toBe(true);
|
||||
|
||||
@@ -270,7 +286,7 @@ describe("chatMachine transitions", () => {
|
||||
actor.stop();
|
||||
});
|
||||
|
||||
it("ignores guest login while an authenticated user session is active", async () => {
|
||||
it("switches to guest session when guest login arrives during user session", async () => {
|
||||
const actor = createActor(createTestChatMachine()).start();
|
||||
|
||||
actor.send({ type: "ChatUserLogin", token: "token" });
|
||||
@@ -279,7 +295,9 @@ describe("chatMachine transitions", () => {
|
||||
);
|
||||
|
||||
actor.send({ type: "ChatGuestLogin" });
|
||||
expect(actor.getSnapshot().matches({ userSession: "ready" })).toBe(true);
|
||||
await waitFor(actor, (snapshot) =>
|
||||
snapshot.matches({ guestSession: "ready" }),
|
||||
);
|
||||
|
||||
actor.stop();
|
||||
});
|
||||
|
||||
@@ -235,6 +235,10 @@ export const chatMachine = setup({
|
||||
},
|
||||
],
|
||||
on: {
|
||||
ChatGuestLogin: {
|
||||
target: "#chat.guestSession",
|
||||
actions: "startGuestSession",
|
||||
},
|
||||
ChatLogout: {
|
||||
target: "#chat.idle",
|
||||
actions: "clearChatSession",
|
||||
|
||||
Reference in New Issue
Block a user