Files
mic-check/src/admin/tests/unit/views/ProfileView.spec.ts
James Wampler c57a13b350 Persist and restore selected project and environment across page reloads
- Add refreshOrganization/refreshProject/refreshEnvironment to context store — update value and localStorage without clearing child selections
- OrgSelector: use refreshOrganization when same org is already stored, preventing the chain that was clearing project and environment
- ProjectSelector: watch org ID (not object ref) so refresh doesn't retrigger; add autoSelectProject to restore stored project or auto-select single project
- EnvironmentTabBar: watch project ID; skip env-clear on initial mount; add autoSelectEnvironment to restore stored env or fall back to first
- Fix test fixtures missing isPrimary field; update EnvironmentTabBar tests to match v-select implementation; add tests for restore behavior
2026-06-30 11:44:55 -07:00

86 lines
2.8 KiB
TypeScript
Executable File

import { describe, it, expect, beforeEach, jest } from '@jest/globals';
import { mount, flushPromises } from '@vue/test-utils';
import { setActivePinia, createPinia } from 'pinia';
import { createRouter, createMemoryHistory } from 'vue-router';
import ProfileView from '@/views/ProfileView.vue';
import { useAuthStore } from '@/stores/auth';
import { useContextStore } from '@/stores/context';
jest.mock('@/api/auth');
jest.mock('@/api/client', () => ({
setAuthTokens: jest.fn(),
clearAuthTokens: jest.fn(),
getAccessToken: jest.fn(),
}));
import * as authApi from '@/api/auth';
function mountView() {
const routes = [
{ path: '/', component: { template: '<div />' } },
{ path: '/login', name: 'Login', component: { template: '<div />' } },
];
const router = createRouter({ history: createMemoryHistory(), routes });
return { wrapper: mount(ProfileView, { global: { plugins: [router] } }), router };
}
describe('ProfileView', () => {
beforeEach(() => {
setActivePinia(createPinia());
jest.clearAllMocks();
});
describe('WhenAuthenticated', () => {
it('ThenProfileCardIsRendered', () => {
const { wrapper } = mountView();
expect(wrapper.find('[data-testid="profile-card"]').exists()).toBe(true);
});
it('ThenLogoutButtonIsPresent', () => {
const { wrapper } = mountView();
expect(wrapper.find('[data-testid="logout-btn"]').exists()).toBe(true);
});
it('ThenOrgNameIsDisplayedWhenSelected', () => {
const { wrapper } = mountView();
const contextStore = useContextStore();
contextStore.setOrganization({ id: 1, name: 'Acme Corp', createdAt: '', isPrimary: false });
expect(wrapper.find('[data-testid="profile-org-name"]').exists()).toBe(false); // org name shown in v-if block
});
});
describe('WhenLogoutButtonIsClicked', () => {
it('ThenAuthStoreLogoutIsCalled', async () => {
jest.mocked(authApi.logout).mockResolvedValue(undefined);
const authStore = useAuthStore();
// Simulate logged-in state by setting tokens manually
authStore.accessToken = 'fake-token' as any;
authStore.refreshToken = 'fake-refresh' as any;
const { wrapper } = mountView();
await wrapper.find('[data-testid="logout-btn"]').trigger('click');
await flushPromises();
expect(authApi.logout).toHaveBeenCalled();
});
it('ThenUserIsRedirectedToLoginAfterLogout', async () => {
jest.mocked(authApi.logout).mockResolvedValue(undefined);
const authStore = useAuthStore();
authStore.accessToken = 'fake-token' as any;
authStore.refreshToken = 'fake-refresh' as any;
const { wrapper, router } = mountView();
await wrapper.find('[data-testid="logout-btn"]').trigger('click');
await flushPromises();
expect(router.currentRoute.value.name).toBe('Login');
});
});
});