Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions application/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export { createEnvironment } from './environment/create-environment.use-case';
export { deleteEnvironment } from './environment/delete-environment.use-case';
export { updateEnvironment, type UpdateEnvironmentPatch } from './environment/update-environment.use-case';
export { Insomnia, type InsomniaDependencies } from './insomnia';
export { deleteRequest } from './request/delete-request.use-case';
export { createWorkspace } from './workspace/create-workspace.use-case';
export { deleteWorkspace } from './workspace/delete-workspace.use-case';
export { moveWorkspace } from './workspace/move-workspace.use-case';
Expand Down
24 changes: 22 additions & 2 deletions application/src/insomnia.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@ import { describe, expect, it } from 'vitest';

import { buildEnvironment, createFakeEnvironmentRepository } from './environment/testing/fake-environment-repository';
import { Insomnia } from './insomnia';
import { buildRequest, createFakeRequestRepository } from './request/testing/fake-request-repository';
import { buildWorkspace, createFakeWorkspaceRepository } from './workspace/testing/fake-workspace-repository';

function buildDependencies(overrides: Partial<ConstructorParameters<typeof Insomnia>[0]> = {}) {
return {
workspaceRepository: createFakeWorkspaceRepository(),
environmentRepository: createFakeEnvironmentRepository(),
requestRepository: createFakeRequestRepository(),
...overrides,
};
}

describe('Insomnia', () => {
it('workspace.renameById() delegates to the injected WorkspaceRepository', async () => {
const workspace = buildWorkspace();
const workspaceRepository = createFakeWorkspaceRepository([workspace]);
const insomnia = new Insomnia({ workspaceRepository, environmentRepository: createFakeEnvironmentRepository() });
const insomnia = new Insomnia(buildDependencies({ workspaceRepository }));

const renamed = await insomnia.workspace.renameById(workspace._id, 'Renamed');

Expand All @@ -19,11 +29,21 @@ describe('Insomnia', () => {
it('environment.updateById() delegates to the injected EnvironmentRepository', async () => {
const environment = buildEnvironment();
const environmentRepository = createFakeEnvironmentRepository([environment]);
const insomnia = new Insomnia({ workspaceRepository: createFakeWorkspaceRepository(), environmentRepository });
const insomnia = new Insomnia(buildDependencies({ environmentRepository }));

const updated = await insomnia.environment.updateById(environment._id, { name: 'Renamed' });

expect(updated.name).toBe('Renamed');
expect((await environmentRepository.findById(environment._id))?.name).toBe('Renamed');
});

it('request.deleteById() delegates to the injected RequestRepository', async () => {
const request = buildRequest();
const requestRepository = createFakeRequestRepository([request]);
const insomnia = new Insomnia(buildDependencies({ requestRepository }));

await insomnia.request.deleteById(request._id);

expect(await requestRepository.findById(request._id)).toBeNull();
});
});
6 changes: 5 additions & 1 deletion application/src/insomnia.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { EnvironmentRepository, WorkspaceRepository } from 'insomnia-domain';
import type { EnvironmentRepository, RequestRepository, WorkspaceRepository } from 'insomnia-domain';

import { EnvironmentModule } from './environment/environment.module';
import { RequestModule } from './request/request.module';
import { WorkspaceModule } from './workspace/workspace.module';

/**
Expand All @@ -12,6 +13,7 @@ import { WorkspaceModule } from './workspace/workspace.module';
export interface InsomniaDependencies {
workspaceRepository: WorkspaceRepository;
environmentRepository: EnvironmentRepository;
requestRepository: RequestRepository;
}

/**
Expand All @@ -23,9 +25,11 @@ export interface InsomniaDependencies {
export class Insomnia {
workspace: WorkspaceModule;
environment: EnvironmentModule;
request: RequestModule;

constructor(dependencies: InsomniaDependencies) {
this.workspace = new WorkspaceModule(dependencies.workspaceRepository);
this.environment = new EnvironmentModule(dependencies.environmentRepository);
this.request = new RequestModule(dependencies.requestRepository);
}
}
21 changes: 21 additions & 0 deletions application/src/request/delete-request.use-case.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { describe, expect, it } from 'vitest';

import { deleteRequest } from './delete-request.use-case';
import { buildRequest, createFakeRequestRepository } from './testing/fake-request-repository';

describe('deleteRequest', () => {
it('deletes an existing request', async () => {
const request = buildRequest();
const repository = createFakeRequestRepository([request]);

await deleteRequest(repository, request._id);

expect(await repository.findById(request._id)).toBeNull();
});

it('throws when the request does not exist', async () => {
const repository = createFakeRequestRepository([]);

await expect(deleteRequest(repository, 'req_missing')).rejects.toThrow('Request not found');
});
});
9 changes: 9 additions & 0 deletions application/src/request/delete-request.use-case.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { RequestRepository } from 'insomnia-domain';

export async function deleteRequest(requestRepository: RequestRepository, requestId: string): Promise<void> {
const request = await requestRepository.findById(requestId);
if (!request) {
throw new Error(`Request not found: ${requestId}`);
}
await requestRepository.delete(requestId);
}
16 changes: 16 additions & 0 deletions application/src/request/request.module.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { describe, expect, it } from 'vitest';

import { RequestModule } from './request.module';
import { buildRequest, createFakeRequestRepository } from './testing/fake-request-repository';

describe('RequestModule', () => {
it('deleteById() delegates to deleteRequest', async () => {
const request = buildRequest();
const repository = createFakeRequestRepository([request]);
const module = new RequestModule(repository);

await module.deleteById(request._id);

expect(await repository.findById(request._id)).toBeNull();
});
});
11 changes: 11 additions & 0 deletions application/src/request/request.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { RequestRepository } from 'insomnia-domain';

import { deleteRequest } from './delete-request.use-case';

export class RequestModule {
constructor(private readonly requestRepository: RequestRepository) {}

deleteById(id: string) {
return deleteRequest(this.requestRepository, id);
}
}
44 changes: 44 additions & 0 deletions application/src/request/testing/fake-request-repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { AnyRequest, Request, RequestRepository } from 'insomnia-domain';

export function createFakeRequestRepository(seed: AnyRequest[] = []): RequestRepository {
const store = new Map(seed.map(r => [r._id, r]));
return {
async findById(id) {
return store.get(id) ?? null;
},
async findByParentId(parentId) {
return [...store.values()].filter(r => r.parentId === parentId);
},
async save(request) {
store.set(request._id, request);
},
async delete(id) {
store.delete(id);
},
};
}

export const buildRequest = (overrides: Partial<Request> = {}): Request => ({
_id: 'req_1',
type: 'Request',
parentId: 'wrk_1',
created: 0,
modified: 0,
isPrivate: false,
name: 'Original',
description: '',
url: '',
method: 'GET',
body: {},
parameters: [],
headers: [],
authentication: {},
metaSortKey: 0,
settingStoreCookies: true,
settingSendCookies: true,
settingDisableRenderRequestBody: false,
settingEncodeUrl: true,
settingRebuildPath: true,
settingFollowRedirects: 'global',
...overrides,
});
3 changes: 2 additions & 1 deletion apps/desktop/src/common/application-bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
// react-router is a desktop-specific framework dependency, and `application` must stay usable by
// any app (apps/cli, future MCP/web apps) - only the Insomnia class itself belongs there.
import { Insomnia } from 'application';
import { nedbEnvironmentRepository, nedbWorkspaceRepository } from 'infrastructure';
import { nedbEnvironmentRepository, nedbRequestRepository, nedbWorkspaceRepository } from 'infrastructure';
import { createContext } from 'react-router';

export const insomnia = new Insomnia({
workspaceRepository: nedbWorkspaceRepository,
environmentRepository: nedbEnvironmentRepository,
requestRepository: nedbRequestRepository,
});

export const InsomniaContext = createContext<Insomnia>();
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import { services } from 'insomnia-data';
import { href, redirect } from 'react-router';

import { InsomniaContext } from '~/common/application-bootstrap';
import { invariant } from '~/common/utils/invariant';
import { AnalyticsEvent } from '~/ui/analytics';
import { createFetcherSubmitHook } from '~/ui/utils/router';

import type { Route } from './+types/organization.$organizationId.project.$projectId.workspace.$workspaceId.debug.request.delete';

export async function clientAction({ params, request }: Route.ClientActionArgs) {
export async function clientAction({ params, request, context }: Route.ClientActionArgs) {
const { organizationId, projectId, workspaceId } = params;

const formData = await request.formData();
const id = formData.get('id') as string;
const req = await services.helpers.getRequestById(id);
invariant(req, 'Request not found');
await context.get(InsomniaContext).request.deleteById(id);
services.stats.incrementDeletedRequests();
await services.helpers.removeRequest(req);
const workspaceMeta = await services.workspaceMeta.getByParentId(workspaceId);
invariant(workspaceMeta, 'Workspace meta not found');

Expand Down
Loading