Skip to content

Commit 8cb3313

Browse files
Merge pull request #114 from iblai/feat/skills-route-restructuring-with-tenant-key
Feat/skills route restructuring with tenant key
2 parents 405e204 + fab7d74 commit 8cb3313

323 files changed

Lines changed: 13474 additions & 10573 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

__tests__/hooks/courses/use-course-detail.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { useCourseDetail } from '@/hooks/courses/use-course-detail';
55
// Mock dependencies
66
const mockPush = vi.fn();
77
vi.mock('next/navigation', () => ({
8+
useParams: () => ({ tenant: 'test-tenant' }),
89
useRouter: () => ({ push: mockPush }),
910
}));
1011

@@ -22,6 +23,8 @@ vi.mock('@iblai/iblai-js/web-utils', () => ({
2223
type: 'setDisplayMonetizationCheckoutModal',
2324
payload,
2425
}),
26+
isLoggedIn: vi.fn(() => true),
27+
useUserTenants: vi.fn(() => ({ userTenants: [] })),
2528
}));
2629

2730
const mockDispatch = vi.fn();

app/__tests__/error.test.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@ import { render } from '@testing-library/react';
44
const mockReplace = vi.fn();
55

66
vi.mock('next/navigation', () => ({
7+
useParams: () => ({ tenant: 'test-tenant' }),
78
useRouter: vi.fn(() => ({
89
replace: mockReplace,
910
})),
1011
}));
1112

13+
vi.mock('@/utils/helpers', () => ({
14+
getTenant: vi.fn(() => 'test-tenant'),
15+
}));
16+
1217
import ErrorBoundary from '../error';
1318

1419
describe('Error boundary', () => {
@@ -20,7 +25,7 @@ describe('Error boundary', () => {
2025
it('redirects to /error/500', () => {
2126
const error = new Error('Test error');
2227
render(<ErrorBoundary error={error} reset={() => {}} />);
23-
expect(mockReplace).toHaveBeenCalledWith('/error/500');
28+
expect(mockReplace).toHaveBeenCalledWith('/platform/test-tenant/error/500');
2429
});
2530

2631
it('logs the error to console', () => {

app/__tests__/global-error.test.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@ import { render } from '@testing-library/react';
44
const mockReplace = vi.fn();
55

66
vi.mock('next/navigation', () => ({
7+
useParams: () => ({ tenant: 'test-tenant' }),
78
useRouter: vi.fn(() => ({
89
replace: mockReplace,
910
})),
1011
}));
1112

13+
vi.mock('@/utils/helpers', () => ({
14+
getTenant: vi.fn(() => 'test-tenant'),
15+
}));
16+
1217
import GlobalError from '../global-error';
1318

1419
describe('GlobalError boundary', () => {
@@ -20,7 +25,7 @@ describe('GlobalError boundary', () => {
2025
it('redirects to /error/500', () => {
2126
const error = new Error('Root layout error');
2227
render(<GlobalError error={error} reset={() => {}} />);
23-
expect(mockReplace).toHaveBeenCalledWith('/error/500');
28+
expect(mockReplace).toHaveBeenCalledWith('/platform/test-tenant/error/500');
2429
});
2530

2631
it('logs the error to console', () => {

app/__tests__/page.test.tsx

Lines changed: 20 additions & 218 deletions
Original file line numberDiff line numberDiff line change
@@ -1,236 +1,38 @@
11
import { describe, it, expect, vi, beforeEach } from 'vitest';
2-
import { render, screen } from '@testing-library/react';
2+
import { render } from '@testing-library/react';
33
import '@testing-library/jest-dom';
44

5-
// Mock config
6-
vi.mock('@/lib/config', () => ({
7-
config: {
8-
settings: {
9-
startPageEnabled: vi.fn(() => true),
10-
},
11-
},
12-
}));
13-
14-
// Mock helpers
15-
vi.mock('@/utils/helpers', () => ({
16-
getTenant: vi.fn(() => 'test-tenant'),
17-
getUserName: vi.fn(() => 'test-user'),
18-
}));
19-
20-
// Mock useGetReportedSkillsQuery
21-
vi.mock('@iblai/iblai-js/data-layer', () => ({
22-
useGetReportedSkillsQuery: vi.fn(() => ({
23-
isLoading: false,
24-
isError: false,
25-
error: null,
26-
})),
27-
}));
5+
const mockReplace = vi.fn();
286

29-
// Mock redirect
30-
const { mockRedirect } = vi.hoisted(() => ({ mockRedirect: vi.fn() }));
317
vi.mock('next/navigation', () => ({
32-
redirect: mockRedirect,
8+
useRouter: () => ({ replace: mockReplace }),
9+
usePathname: () => '/',
3310
}));
3411

35-
// Mock useTenantMetadata
36-
vi.mock('@iblai/iblai-js/web-utils', () => ({
37-
useTenantMetadata: vi.fn(() => ({
38-
metadata: { enable_start_screen_display: true },
39-
isLoading: false,
40-
isError: false,
41-
})),
42-
}));
43-
44-
// Mock Spinner component
45-
vi.mock('@/components/spinner', () => ({
46-
Spinner: ({ className }: { className?: string }) => (
47-
<div data-testid="spinner" className={className}>
48-
Loading...
49-
</div>
50-
),
12+
vi.mock('@/utils/helpers', () => ({
13+
getTenant: vi.fn(() => 'test-tenant'),
14+
redirectToAuthSpa: vi.fn(),
5115
}));
5216

53-
import Home from '../page';
54-
import { useTenantMetadata } from '@iblai/iblai-js/web-utils';
55-
// @ts-ignore
56-
import { useGetReportedSkillsQuery } from '@iblai/iblai-js/data-layer';
57-
import { config } from '@/lib/config';
17+
import RootRedirect from '../page';
18+
import { getTenant, redirectToAuthSpa } from '@/utils/helpers';
5819

59-
describe('Home page', () => {
20+
describe('RootRedirect', () => {
6021
beforeEach(() => {
6122
vi.clearAllMocks();
62-
vi.mocked(config.settings.startPageEnabled).mockReturnValue(true);
63-
vi.mocked(useTenantMetadata).mockReturnValue({
64-
metadata: { enable_start_screen_display: true },
65-
isLoading: false,
66-
isError: false,
67-
} as any);
68-
vi.mocked(useGetReportedSkillsQuery).mockReturnValue({
69-
isLoading: false,
70-
isError: false,
71-
error: null,
72-
} as any);
73-
});
74-
75-
it('renders without crashing', () => {
76-
const { container } = render(<Home />);
77-
expect(container).toBeTruthy();
78-
});
79-
80-
it('shows Spinner when metadata is loading', () => {
81-
vi.mocked(useTenantMetadata).mockReturnValue({
82-
metadata: undefined,
83-
isLoading: true,
84-
isError: false,
85-
} as any);
86-
87-
render(<Home />);
88-
89-
expect(screen.getByTestId('spinner')).toBeInTheDocument();
90-
});
91-
92-
it('shows Spinner when reported skills are loading', () => {
93-
vi.mocked(useGetReportedSkillsQuery).mockReturnValue({
94-
isLoading: true,
95-
isError: false,
96-
error: null,
97-
} as any);
98-
99-
render(<Home />);
100-
101-
expect(screen.getByTestId('spinner')).toBeInTheDocument();
102-
});
103-
104-
it('shows Spinner when both metadata and skills are loading', () => {
105-
vi.mocked(useTenantMetadata).mockReturnValue({
106-
metadata: undefined,
107-
isLoading: true,
108-
isError: false,
109-
} as any);
110-
vi.mocked(useGetReportedSkillsQuery).mockReturnValue({
111-
isLoading: true,
112-
isError: false,
113-
error: null,
114-
} as any);
115-
116-
render(<Home />);
117-
118-
expect(screen.getByTestId('spinner')).toBeInTheDocument();
119-
});
120-
121-
it('returns null when not loading', () => {
122-
render(<Home />);
123-
124-
expect(screen.queryByTestId('spinner')).not.toBeInTheDocument();
125-
});
126-
127-
it('redirects to /home on metadata error', () => {
128-
vi.mocked(useTenantMetadata).mockReturnValue({
129-
metadata: undefined,
130-
isLoading: false,
131-
isError: true,
132-
} as any);
133-
134-
render(<Home />);
135-
136-
expect(mockRedirect).toHaveBeenCalledWith('/home');
137-
});
138-
139-
it('redirects to /home when startPageEnabled is false', () => {
140-
vi.mocked(config.settings.startPageEnabled).mockReturnValue(false);
141-
vi.mocked(useTenantMetadata).mockReturnValue({
142-
metadata: { enable_start_screen_display: true },
143-
isLoading: false,
144-
isError: false,
145-
} as any);
146-
147-
render(<Home />);
148-
149-
expect(mockRedirect).toHaveBeenCalledWith('/home');
150-
});
151-
152-
it('redirects to /home when enable_start_screen_display is false', () => {
153-
vi.mocked(useTenantMetadata).mockReturnValue({
154-
metadata: { enable_start_screen_display: false },
155-
isLoading: false,
156-
isError: false,
157-
} as any);
158-
159-
render(<Home />);
160-
161-
expect(mockRedirect).toHaveBeenCalledWith('/home');
162-
});
163-
164-
it('redirects to /home when metadata is null', () => {
165-
vi.mocked(useTenantMetadata).mockReturnValue({
166-
metadata: null,
167-
isLoading: false,
168-
isError: false,
169-
} as any);
170-
171-
render(<Home />);
172-
173-
expect(mockRedirect).toHaveBeenCalledWith('/home');
174-
});
175-
176-
it('redirects to /start when reported skills error has status 400', () => {
177-
vi.mocked(useGetReportedSkillsQuery).mockReturnValue({
178-
isLoading: false,
179-
isError: true,
180-
error: { status: 400 },
181-
} as any);
182-
183-
render(<Home />);
184-
185-
expect(mockRedirect).toHaveBeenCalledWith('/start');
18623
});
18724

188-
it('redirects to /home when reported skills error has non-400 status', () => {
189-
vi.mocked(useGetReportedSkillsQuery).mockReturnValue({
190-
isLoading: false,
191-
isError: true,
192-
error: { status: 500 },
193-
} as any);
194-
195-
render(<Home />);
196-
197-
expect(mockRedirect).toHaveBeenCalledWith('/home');
25+
it('redirects to /{tenant} when a tenant is set', () => {
26+
vi.mocked(getTenant).mockReturnValue('test-tenant');
27+
render(<RootRedirect />);
28+
expect(mockReplace).toHaveBeenCalledWith('/platform/test-tenant');
29+
expect(redirectToAuthSpa).not.toHaveBeenCalled();
19830
});
19931

200-
it('redirects to /home when no error and skills not loading', () => {
201-
vi.mocked(useGetReportedSkillsQuery).mockReturnValue({
202-
isLoading: false,
203-
isError: false,
204-
error: null,
205-
} as any);
206-
207-
render(<Home />);
208-
209-
expect(mockRedirect).toHaveBeenCalledWith('/home');
210-
});
211-
212-
it('does not redirect when metadata is loading', () => {
213-
vi.mocked(useTenantMetadata).mockReturnValue({
214-
metadata: undefined,
215-
isLoading: true,
216-
isError: false,
217-
} as any);
218-
219-
render(<Home />);
220-
221-
expect(mockRedirect).not.toHaveBeenCalled();
222-
});
223-
224-
it('renders Spinner with correct class', () => {
225-
vi.mocked(useTenantMetadata).mockReturnValue({
226-
metadata: undefined,
227-
isLoading: true,
228-
isError: false,
229-
} as any);
230-
231-
render(<Home />);
232-
233-
const spinner = screen.getByTestId('spinner');
234-
expect(spinner).toHaveClass('h-14', 'w-14');
32+
it('redirects to auth SPA when no tenant is set', () => {
33+
vi.mocked(getTenant).mockReturnValue('');
34+
render(<RootRedirect />);
35+
expect(redirectToAuthSpa).toHaveBeenCalled();
36+
expect(mockReplace).not.toHaveBeenCalled();
23537
});
23638
});

0 commit comments

Comments
 (0)