Add onboarding integration test
cgen-6f556f4b240242eda148c08428d795c3
This commit is contained in:
parent
0956ddb03b
commit
bc3b8f9d20
1 changed files with 148 additions and 0 deletions
148
client/lib/onboarding.integration.spec.ts
Normal file
148
client/lib/onboarding.integration.spec.ts
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
import { describe, it, expect, beforeEach, vi } from "vitest";
|
||||
|
||||
const createStorage = () => {
|
||||
const store = new Map<string, string>();
|
||||
const storage: Storage = {
|
||||
get length() {
|
||||
return store.size;
|
||||
},
|
||||
clear: () => {
|
||||
store.clear();
|
||||
},
|
||||
getItem: (key: string) => store.get(key) ?? null,
|
||||
key: (index: number) => Array.from(store.keys())[index] ?? null,
|
||||
removeItem: (key: string) => {
|
||||
store.delete(key);
|
||||
},
|
||||
setItem: (key: string, value: string) => {
|
||||
store.set(key, value);
|
||||
},
|
||||
} as Storage;
|
||||
return storage;
|
||||
};
|
||||
|
||||
vi.stubGlobal("localStorage", createStorage());
|
||||
vi.stubGlobal(
|
||||
"fetch",
|
||||
vi.fn().mockResolvedValue({
|
||||
ok: false,
|
||||
status: 404,
|
||||
text: async () => "",
|
||||
json: async () => ({}),
|
||||
}),
|
||||
);
|
||||
|
||||
vi.mock("@/lib/supabase", () => {
|
||||
const chain = () => ({
|
||||
select: () => chain(),
|
||||
insert: () => ({ data: null, error: null }),
|
||||
update: () => ({ data: null, error: null }),
|
||||
delete: () => ({ error: null }),
|
||||
eq: () => chain(),
|
||||
order: () => chain(),
|
||||
limit: () => chain(),
|
||||
single: () => ({ data: null, error: null }),
|
||||
});
|
||||
|
||||
return {
|
||||
supabase: {
|
||||
auth: {
|
||||
signInWithPassword: vi.fn(),
|
||||
signInWithOAuth: vi.fn(),
|
||||
linkIdentity: vi.fn(),
|
||||
unlinkIdentity: vi.fn(),
|
||||
signOut: vi.fn(),
|
||||
getUser: async () => ({ data: { user: null }, error: null }),
|
||||
getSession: async () => ({ data: { session: null }, error: null }),
|
||||
onAuthStateChange: () => ({
|
||||
data: {
|
||||
subscription: {
|
||||
unsubscribe: () => {},
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
from: () => chain(),
|
||||
channel: () => ({
|
||||
on: () => ({}),
|
||||
subscribe: () => ({ unsubscribe: () => {} }),
|
||||
unsubscribe: () => {},
|
||||
}),
|
||||
storage: {
|
||||
from: () => ({
|
||||
upload: async () => ({ data: null, error: null }),
|
||||
getPublicUrl: () => ({ data: { publicUrl: "" } }),
|
||||
}),
|
||||
},
|
||||
},
|
||||
isSupabaseConfigured: false,
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("@/lib/aethex-toast", () => ({
|
||||
aethexToast: {
|
||||
success: vi.fn(),
|
||||
error: vi.fn(),
|
||||
warning: vi.fn(),
|
||||
info: vi.fn(),
|
||||
aethex: vi.fn(),
|
||||
system: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
import { mockAuth } from "@/lib/mock-auth";
|
||||
import {
|
||||
aethexUserService,
|
||||
aethexAchievementService,
|
||||
checkProfileComplete,
|
||||
type AethexUserProfile,
|
||||
} from "@/lib/aethex-database-adapter";
|
||||
|
||||
const wait = (ms = 50) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
describe("onboarding passport flow", () => {
|
||||
beforeEach(async () => {
|
||||
localStorage.clear();
|
||||
await mockAuth.signOut();
|
||||
(fetch as unknown as vi.Mock).mockReset();
|
||||
(fetch as unknown as vi.Mock).mockResolvedValue({
|
||||
ok: false,
|
||||
status: 404,
|
||||
text: async () => "",
|
||||
json: async () => ({}),
|
||||
});
|
||||
});
|
||||
|
||||
it("persists profile setup, links providers, and awards welcome badge", async () => {
|
||||
const email = `tester+${Date.now()}@example.com`;
|
||||
const password = "Secret123!";
|
||||
|
||||
const authResult = await mockAuth.signInWithPassword(email, password);
|
||||
expect(authResult.error).toBeNull();
|
||||
await wait();
|
||||
|
||||
const user = authResult.data.user;
|
||||
expect(user).toBeTruthy();
|
||||
|
||||
await aethexUserService.updateProfile(user.id, {
|
||||
id: user.id,
|
||||
username: "tester",
|
||||
full_name: "Tester One",
|
||||
user_type: "community_member" as AethexUserProfile["user_type"],
|
||||
experience_level: "intermediate" as AethexUserProfile["experience_level"],
|
||||
bio: "Building awesome experiences",
|
||||
});
|
||||
|
||||
const hydratedProfile = await aethexUserService.getCurrentUser();
|
||||
expect(checkProfileComplete(hydratedProfile)).toBe(true);
|
||||
|
||||
await mockAuth.linkIdentity({ provider: "github" });
|
||||
const refreshedUser = (await mockAuth.getUser()).data.user;
|
||||
expect(refreshedUser?.identities?.some((id: any) => id.provider === "github")).toBe(true);
|
||||
|
||||
await aethexAchievementService.checkAndAwardOnboardingAchievement(user.id);
|
||||
const achievements = await aethexAchievementService.getUserAchievements(user.id);
|
||||
const welcomeBadge = achievements.find((item) => item.name === "Welcome to AeThex");
|
||||
expect(welcomeBadge).toBeTruthy();
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue