mirror of
https://github.com/zadam/trilium.git
synced 2025-11-06 05:15:59 +01:00
chore(express-partial-content): integrate tests and convert to vitest
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
import * as utils from "./utils.js";
|
||||
import * as ParseRangeHeaderExports from "./parseRangeHeader.js";
|
||||
import { ContentDoesNotExistError } from "./ContentDoesNotExistError.js";
|
||||
import { createPartialContentHandler } from "./createPartialContentHandler.js";
|
||||
import type { ContentProvider } from "./ContentProvider.js";
|
||||
import type { Logger } from "./Logger.js";
|
||||
import type { Request, Response } from "express";
|
||||
import type { Content } from "./Content.js";
|
||||
import { Stream } from "stream";
|
||||
import type { Range } from "./Range.js";
|
||||
import type { MockInstance } from "vitest";
|
||||
|
||||
describe("createPartialContentHandler tests", () => {
|
||||
let logger: Logger;
|
||||
beforeEach(() => {
|
||||
logger = {
|
||||
debug: vi.fn() as (message: string, extra?: any) => void
|
||||
};
|
||||
});
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
it("returns a handler", () => {
|
||||
const contentProvider = vi.fn().mockResolvedValue({}) as ContentProvider;
|
||||
const handler = createPartialContentHandler(contentProvider, logger);
|
||||
expect(typeof handler === "function");
|
||||
});
|
||||
|
||||
describe("handler tests", () => {
|
||||
let req: Request;
|
||||
let res: Response;
|
||||
let statusSpy: MockInstance;
|
||||
let sendSpy: MockInstance;
|
||||
let sendStatusSpy: MockInstance;
|
||||
beforeEach(() => {
|
||||
req = {} as Request;
|
||||
res = {
|
||||
status: (code: number) => res,
|
||||
send: (message: string) => res,
|
||||
sendStatus: (code: number) => res,
|
||||
setHeader: vi.fn() as (name: string, value: string) => void
|
||||
} as Response;
|
||||
statusSpy = vi.spyOn(res, "status");
|
||||
sendSpy = vi.spyOn(res, "send");
|
||||
sendStatusSpy = vi.spyOn(res, "sendStatus");
|
||||
});
|
||||
it("invokes contentProvider with the specified request", async () => {
|
||||
const contentProvider = vi.fn().mockResolvedValue({}) as ContentProvider;
|
||||
const handler = createPartialContentHandler(contentProvider, logger);
|
||||
try {
|
||||
await handler(req, res);
|
||||
} catch {}
|
||||
expect(contentProvider).toHaveBeenCalledExactlyOnceWith(req);
|
||||
});
|
||||
it("returns 404 if contentProvider throws ContentDoesNotExistError error", async () => {
|
||||
const error = new ContentDoesNotExistError("404-File not found!");
|
||||
const contentProvider = vi.fn().mockRejectedValue(error) as ContentProvider;
|
||||
const handler = createPartialContentHandler(contentProvider, logger);
|
||||
try {
|
||||
await handler(req, res);
|
||||
expect(statusSpy).toHaveBeenCalledExactlyOnceWith(404);
|
||||
expect(sendSpy).toHaveBeenCalledExactlyOnceWith(error.message);
|
||||
} catch {
|
||||
expect(false);
|
||||
}
|
||||
});
|
||||
it("returns 500 if contentProvider throws any other error", async () => {
|
||||
const error = new Error("Something went wrong!");
|
||||
const contentProvider = vi.fn().mockRejectedValue(error) as ContentProvider;
|
||||
const handler = createPartialContentHandler(contentProvider, logger);
|
||||
try {
|
||||
await handler(req, res);
|
||||
expect(sendStatusSpy).toHaveBeenCalledExactlyOnceWith(500);
|
||||
} catch {
|
||||
expect(false);
|
||||
}
|
||||
});
|
||||
it("returns 416 if parseRangeHeader throws RangeParserError error", async () => {
|
||||
const contentProvider = vi.fn().mockResolvedValue({}) as ContentProvider;
|
||||
const handler = createPartialContentHandler(contentProvider, logger);
|
||||
req.headers = { range: "bytes=30-10" };
|
||||
try {
|
||||
await handler(req, res);
|
||||
expect(statusSpy).toHaveBeenCalledExactlyOnceWith(416);
|
||||
} catch {
|
||||
expect(false);
|
||||
}
|
||||
});
|
||||
it("returns 500 if parseRangeHeader throws other errors", async () => {
|
||||
const parseRangeHeaderStub = vi
|
||||
.spyOn(ParseRangeHeaderExports, "parseRangeHeader")
|
||||
.mockImplementation(() => {
|
||||
throw new Error("Something went wrong!")
|
||||
});
|
||||
const contentProvider = vi.fn().mockResolvedValue({}) as ContentProvider;
|
||||
const handler = createPartialContentHandler(contentProvider, logger);
|
||||
try {
|
||||
await handler(req, res);
|
||||
expect(sendStatusSpy).toHaveBeenCalledExactlyOnceWith(500);
|
||||
} catch {
|
||||
expect(false);
|
||||
}
|
||||
});
|
||||
it("returns correct response if range is not specified", async () => {
|
||||
const result = ({
|
||||
pipe() {
|
||||
return result;
|
||||
}
|
||||
} as any) as Stream;
|
||||
const content: Content = {
|
||||
fileName: "file.txt",
|
||||
totalSize: 10,
|
||||
mimeType: "text/plain",
|
||||
getStream(range?: Range) {
|
||||
return result;
|
||||
}
|
||||
};
|
||||
const pipeSpy = vi.spyOn(result, "pipe");
|
||||
const getStreamSpy = vi.spyOn(content, "getStream");
|
||||
const contentProvider = vi.fn().mockResolvedValue(content) as ContentProvider;
|
||||
const handler = createPartialContentHandler(contentProvider, logger);
|
||||
const setContentTypeHeaderSpy = vi.spyOn(utils, "setContentTypeHeader");
|
||||
const setContentDispositionHeaderSpy = vi.spyOn(utils, "setContentDispositionHeader");
|
||||
const setAcceptRangesHeaderSpy = vi.spyOn(utils, "setAcceptRangesHeader");
|
||||
const setContentLengthHeaderSpy = vi.spyOn(utils, "setContentLengthHeader");
|
||||
const setContentRangeHeaderSpy = vi.spyOn(utils, "setContentRangeHeader");
|
||||
try {
|
||||
await handler(req, res);
|
||||
expect(setContentTypeHeaderSpy).toHaveBeenCalledExactlyOnceWith(content.mimeType, res);
|
||||
expect(setContentDispositionHeaderSpy).toHaveBeenCalledExactlyOnceWith(content.fileName, res);
|
||||
expect(setAcceptRangesHeaderSpy).toHaveBeenCalledExactlyOnceWith(res);
|
||||
expect(setContentLengthHeaderSpy).toHaveBeenCalledExactlyOnceWith(content.totalSize, res);
|
||||
expect(getStreamSpy).toHaveBeenCalledExactlyOnceWith();
|
||||
expect(pipeSpy).toHaveBeenCalledExactlyOnceWith(res);
|
||||
expect(setContentRangeHeaderSpy).not.toHaveBeenCalled();
|
||||
} catch {
|
||||
expect(false);
|
||||
}
|
||||
});
|
||||
it("returns correct partial response if range is specified", async () => {
|
||||
req.headers = {
|
||||
range: "bytes=0-5"
|
||||
};
|
||||
const result = ({
|
||||
pipe() {
|
||||
return result;
|
||||
}
|
||||
} as any) as Stream;
|
||||
const content: Content = {
|
||||
fileName: "file.txt",
|
||||
totalSize: 10,
|
||||
mimeType: "text/plain",
|
||||
getStream(range?: Range) {
|
||||
return result;
|
||||
}
|
||||
};
|
||||
const range = { start: 0, end: 5 };
|
||||
const pipeSpy = vi.spyOn(result, "pipe");
|
||||
const getStreamSpy = vi.spyOn(content, "getStream");
|
||||
const contentProvider = vi.fn().mockResolvedValue(content) as ContentProvider;
|
||||
const handler = createPartialContentHandler(contentProvider, logger);
|
||||
const setContentTypeHeaderSpy = vi.spyOn(utils, "setContentTypeHeader");
|
||||
const setContentDispositionHeaderSpy = vi.spyOn(utils, "setContentDispositionHeader");
|
||||
const setAcceptRangesHeaderSpy = vi.spyOn(utils, "setAcceptRangesHeader");
|
||||
const setContentLengthHeaderSpy = vi.spyOn(utils, "setContentLengthHeader");
|
||||
const setContentRangeHeaderSpy = vi.spyOn(utils, "setContentRangeHeader");
|
||||
try {
|
||||
await handler(req, res);
|
||||
expect(setContentTypeHeaderSpy).toHaveBeenCalledExactlyOnceWith(content.mimeType, res);
|
||||
expect(setContentDispositionHeaderSpy).toHaveBeenCalledExactlyOnceWith(content.fileName, res);
|
||||
expect(setAcceptRangesHeaderSpy).toHaveBeenCalledExactlyOnceWith(res);
|
||||
expect(setContentRangeHeaderSpy).toHaveBeenCalledExactlyOnceWith(range, content.totalSize, res);
|
||||
expect(setContentLengthHeaderSpy).toHaveBeenCalledExactlyOnceWith(6, res);
|
||||
expect(getStreamSpy).toHaveBeenCalledExactlyOnceWith(range);
|
||||
expect(pipeSpy).toHaveBeenCalledExactlyOnceWith(res);
|
||||
} catch {
|
||||
expect(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user