Adding Organiztion, environment and project. Segment fix, tag fix

This commit is contained in:
2026-04-14 14:10:37 -07:00
parent 4195d384d0
commit b75f5f602e
20 changed files with 3370 additions and 61 deletions

View File

@@ -15,6 +15,8 @@ jest.mock('@/api/client', () => ({
import * as projectsApi from '@/api/projects';
const dialogStub = { template: '<div><slot /></div>' };
const mockOrg: OrganizationResponse = { id: 1, name: 'Acme', createdAt: '2026-01-01T00:00:00Z' };
const mockProjects: ProjectResponse[] = [
{ id: 10, name: 'Website', organizationId: 1, hideDisabledFlags: false, createdAt: '2026-01-01T00:00:00Z' },
@@ -27,7 +29,10 @@ function mountComponent() {
routes: [{ path: '/', component: { template: '<div />' } }],
});
return mount(ProjectSelector, {
global: { plugins: [router] },
global: {
plugins: [router],
stubs: { 'v-dialog': dialogStub },
},
});
}
@@ -45,6 +50,15 @@ describe('ProjectSelector', () => {
expect(projectsApi.listProjects).not.toHaveBeenCalled();
expect(wrapper.find('[data-testid="project-selector"]').exists()).toBe(true);
});
it('ThenCreateProjectButtonIsDisabled', async () => {
const wrapper = mountComponent();
await flushPromises();
const btn = wrapper.find('[data-testid="create-project-btn"]');
expect(btn.exists()).toBe(true);
expect(btn.attributes('disabled')).toBeDefined();
});
});
describe('WhenOrganizationIsSetInContextStore', () => {
@@ -59,6 +73,19 @@ describe('ProjectSelector', () => {
expect(projectsApi.listProjects).toHaveBeenCalledWith(mockOrg.id);
});
it('ThenCreateProjectButtonIsEnabled', async () => {
jest.mocked(projectsApi.listProjects).mockResolvedValue(mockProjects);
const contextStore = useContextStore();
contextStore.setOrganization(mockOrg);
const wrapper = mountComponent();
await flushPromises();
const btn = wrapper.find('[data-testid="create-project-btn"]');
expect(btn.attributes('disabled')).toBeUndefined();
});
});
describe('WhenProjectIsSelected', () => {
@@ -95,4 +122,149 @@ describe('ProjectSelector', () => {
expect(projectsApi.listProjects).toHaveBeenLastCalledWith(newOrg.id);
});
});
describe('WhenCreateProjectButtonIsClicked', () => {
it('ThenCreateDialogIsShown', async () => {
jest.mocked(projectsApi.listProjects).mockResolvedValue([]);
const contextStore = useContextStore();
contextStore.setOrganization(mockOrg);
const wrapper = mountComponent();
await flushPromises();
await wrapper.find('[data-testid="create-project-btn"]').trigger('click');
expect(wrapper.find('[data-testid="create-project-dialog"]').exists()).toBe(true);
});
it('ThenNameInputIsPresentInDialog', async () => {
jest.mocked(projectsApi.listProjects).mockResolvedValue([]);
const contextStore = useContextStore();
contextStore.setOrganization(mockOrg);
const wrapper = mountComponent();
await flushPromises();
await wrapper.find('[data-testid="create-project-btn"]').trigger('click');
expect(wrapper.find('[data-testid="project-name-input"]').exists()).toBe(true);
});
});
describe('WhenCreateProjectIsConfirmed', () => {
const newProject: ProjectResponse = {
id: 99, name: 'New Project', organizationId: 1, hideDisabledFlags: false, createdAt: '2026-04-13T00:00:00Z',
};
it('ThenCreateProjectApiIsCalled', async () => {
jest.mocked(projectsApi.listProjects).mockResolvedValue([]);
jest.mocked(projectsApi.createProject).mockResolvedValue(newProject);
const contextStore = useContextStore();
contextStore.setOrganization(mockOrg);
const wrapper = mountComponent();
await flushPromises();
await wrapper.find('[data-testid="create-project-btn"]').trigger('click');
(wrapper.vm as any).newProjectName = 'New Project';
await (wrapper.vm as any).onCreateConfirm();
await flushPromises();
expect(projectsApi.createProject).toHaveBeenCalledWith({ name: 'New Project', organizationId: mockOrg.id });
});
it('ThenNewProjectIsAutoSelectedInContextStore', async () => {
jest.mocked(projectsApi.listProjects).mockResolvedValue([]);
jest.mocked(projectsApi.createProject).mockResolvedValue(newProject);
const contextStore = useContextStore();
contextStore.setOrganization(mockOrg);
const wrapper = mountComponent();
await flushPromises();
await wrapper.find('[data-testid="create-project-btn"]').trigger('click');
(wrapper.vm as any).newProjectName = 'New Project';
await (wrapper.vm as any).onCreateConfirm();
await flushPromises();
expect(contextStore.currentProject).toEqual(newProject);
});
it('ThenDialogIsClosedAfterSuccessfulCreate', async () => {
jest.mocked(projectsApi.listProjects).mockResolvedValue([]);
jest.mocked(projectsApi.createProject).mockResolvedValue(newProject);
const contextStore = useContextStore();
contextStore.setOrganization(mockOrg);
const wrapper = mountComponent();
await flushPromises();
await wrapper.find('[data-testid="create-project-btn"]').trigger('click');
(wrapper.vm as any).newProjectName = 'New Project';
await (wrapper.vm as any).onCreateConfirm();
await flushPromises();
expect((wrapper.vm as any).showDialog).toBe(false);
});
});
describe('WhenCreateProjectFails', () => {
it('ThenErrorMessageIsDisplayed', async () => {
jest.mocked(projectsApi.listProjects).mockResolvedValue([]);
jest.mocked(projectsApi.createProject).mockRejectedValue(new Error('Server error'));
const contextStore = useContextStore();
contextStore.setOrganization(mockOrg);
const wrapper = mountComponent();
await flushPromises();
await wrapper.find('[data-testid="create-project-btn"]').trigger('click');
(wrapper.vm as any).newProjectName = 'Bad Project';
await (wrapper.vm as any).onCreateConfirm();
await flushPromises();
expect((wrapper.vm as any).createError).toBeTruthy();
});
it('ThenDialogRemainsOpen', async () => {
jest.mocked(projectsApi.listProjects).mockResolvedValue([]);
jest.mocked(projectsApi.createProject).mockRejectedValue(new Error('Server error'));
const contextStore = useContextStore();
contextStore.setOrganization(mockOrg);
const wrapper = mountComponent();
await flushPromises();
await wrapper.find('[data-testid="create-project-btn"]').trigger('click');
(wrapper.vm as any).newProjectName = 'Bad Project';
await (wrapper.vm as any).onCreateConfirm();
await flushPromises();
expect((wrapper.vm as any).showDialog).toBe(true);
});
});
describe('WhenCancelIsClicked', () => {
it('ThenDialogIsClosed', async () => {
jest.mocked(projectsApi.listProjects).mockResolvedValue([]);
const contextStore = useContextStore();
contextStore.setOrganization(mockOrg);
const wrapper = mountComponent();
await flushPromises();
await wrapper.find('[data-testid="create-project-btn"]').trigger('click');
await wrapper.find('[data-testid="create-project-cancel-btn"]').trigger('click');
expect((wrapper.vm as any).showDialog).toBe(false);
});
});
});