mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-04 05:28:59 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			183 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import * as utils from "../src/utils";
 | 
						|
import * as ParseRangeHeaderExports from "../src/parseRangeHeader";
 | 
						|
import { ContentDoesNotExistError } from "../src/ContentDoesNotExistError";
 | 
						|
import { SinonSandbox, createSandbox, SinonStub, SinonSpy } from "sinon";
 | 
						|
import { createPartialContentHandler } from "../src/createPartialContentHandler";
 | 
						|
import { ContentProvider } from "../src/ContentProvider";
 | 
						|
import { Logger } from "../src/Logger";
 | 
						|
import { expect } from "chai";
 | 
						|
import { Request, Response } from "express";
 | 
						|
import { Content } from "../src/Content";
 | 
						|
import { Stream } from "stream";
 | 
						|
import { Range } from "../src/Range";
 | 
						|
 | 
						|
describe("createPartialContentHandler tests", () => {
 | 
						|
  let sandbox: SinonSandbox;
 | 
						|
  let logger: Logger;
 | 
						|
  beforeEach(() => {
 | 
						|
    sandbox = createSandbox();
 | 
						|
    logger = {
 | 
						|
      debug: sandbox.stub() as (message: string, extra?: any) => void
 | 
						|
    };
 | 
						|
  });
 | 
						|
  afterEach(() => {
 | 
						|
    sandbox.restore();
 | 
						|
  });
 | 
						|
  it("returns a handler", () => {
 | 
						|
    const contentProvider = sandbox.stub().resolves({}) as ContentProvider;
 | 
						|
    const handler = createPartialContentHandler(contentProvider, logger);
 | 
						|
    expect(typeof handler === "function");
 | 
						|
  });
 | 
						|
 | 
						|
  describe("handler tests", () => {
 | 
						|
    let req: Request;
 | 
						|
    let res: Response;
 | 
						|
    let statusSpy: SinonSpy;
 | 
						|
    let sendSpy: SinonSpy;
 | 
						|
    let sendStatusSpy: SinonSpy;
 | 
						|
    beforeEach(() => {
 | 
						|
      req = {} as Request;
 | 
						|
      res = {
 | 
						|
        status: (code: number) => res,
 | 
						|
        send: (message: string) => res,
 | 
						|
        sendStatus: (code: number) => res,
 | 
						|
        setHeader: sandbox.stub() as (name: string, value: string) => void
 | 
						|
      } as Response;
 | 
						|
      statusSpy = sandbox.spy(res, "status");
 | 
						|
      sendSpy = sandbox.spy(res, "send");
 | 
						|
      sendStatusSpy = sandbox.spy(res, "sendStatus");
 | 
						|
    });
 | 
						|
    it("invokes contentProvider with the specified request", async () => {
 | 
						|
      const contentProvider = sandbox.stub().resolves({}) as ContentProvider;
 | 
						|
      const handler = createPartialContentHandler(contentProvider, logger);
 | 
						|
      try {
 | 
						|
        await handler(req, res);
 | 
						|
      } catch {}
 | 
						|
      expect((contentProvider as SinonStub).calledOnceWith(req));
 | 
						|
    });
 | 
						|
    it("returns 404 if contentProvider throws ContentDoesNotExistError error", async () => {
 | 
						|
      const error = new ContentDoesNotExistError("404-File not found!");
 | 
						|
      const contentProvider = sandbox.stub().rejects(error) as ContentProvider;
 | 
						|
      const handler = createPartialContentHandler(contentProvider, logger);
 | 
						|
      try {
 | 
						|
        await handler(req, res);
 | 
						|
        expect(statusSpy.calledOnceWith(404));
 | 
						|
        expect(sendSpy.calledOnceWith(error.message));
 | 
						|
      } catch {
 | 
						|
        expect(false);
 | 
						|
      }
 | 
						|
    });
 | 
						|
    it("returns 500 if contentProvider throws any other error", async () => {
 | 
						|
      const error = new Error("Something went wrong!");
 | 
						|
      const contentProvider = sandbox.stub().rejects(error) as ContentProvider;
 | 
						|
      const handler = createPartialContentHandler(contentProvider, logger);
 | 
						|
      try {
 | 
						|
        await handler(req, res);
 | 
						|
        expect(sendStatusSpy.calledOnceWith(500));
 | 
						|
      } catch {
 | 
						|
        expect(false);
 | 
						|
      }
 | 
						|
    });
 | 
						|
    it("returns 416 if parseRangeHeader throws RangeParserError error", async () => {
 | 
						|
      const contentProvider = sandbox.stub().resolves({}) as ContentProvider;
 | 
						|
      const handler = createPartialContentHandler(contentProvider, logger);
 | 
						|
      req.headers = { range: "bytes=30-10" };
 | 
						|
      try {
 | 
						|
        await handler(req, res);
 | 
						|
        expect(statusSpy.calledOnceWith(416));
 | 
						|
      } catch {
 | 
						|
        expect(false);
 | 
						|
      }
 | 
						|
    });
 | 
						|
    it("returns 500 if parseRangeHeader throws other errors", async () => {
 | 
						|
      const parseRangeHeaderStub = sandbox
 | 
						|
        .stub(ParseRangeHeaderExports, "parseRangeHeader")
 | 
						|
        .throws(new Error("Something went wrong!"));
 | 
						|
      const contentProvider = sandbox.stub().resolves({}) as ContentProvider;
 | 
						|
      const handler = createPartialContentHandler(contentProvider, logger);
 | 
						|
      try {
 | 
						|
        await handler(req, res);
 | 
						|
        expect(sendStatusSpy.calledOnceWith(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 = sandbox.spy(result, "pipe");
 | 
						|
      const getStreamSpy = sandbox.spy(content, "getStream");
 | 
						|
      const contentProvider = sandbox.stub().resolves(content) as ContentProvider;
 | 
						|
      const handler = createPartialContentHandler(contentProvider, logger);
 | 
						|
      const setContentTypeHeaderSpy = sandbox.spy(utils, "setContentTypeHeader");
 | 
						|
      const setContentDispositionHeaderSpy = sandbox.spy(utils, "setContentDispositionHeader");
 | 
						|
      const setAcceptRangesHeaderSpy = sandbox.spy(utils, "setAcceptRangesHeader");
 | 
						|
      const setContentLengthHeaderSpy = sandbox.spy(utils, "setContentLengthHeader");
 | 
						|
      const setContentRangeHeaderSpy = sandbox.spy(utils, "setContentRangeHeader");
 | 
						|
      try {
 | 
						|
        await handler(req, res);
 | 
						|
        expect(setContentTypeHeaderSpy.calledOnceWith(content.mimeType, res));
 | 
						|
        expect(setContentDispositionHeaderSpy.calledOnceWith(content.fileName, res));
 | 
						|
        expect(setAcceptRangesHeaderSpy.calledOnceWith(res));
 | 
						|
        expect(setContentLengthHeaderSpy.calledOnceWith(content.totalSize, res));
 | 
						|
        expect(getStreamSpy.calledOnceWith());
 | 
						|
        expect(pipeSpy.calledOnceWith(res));
 | 
						|
        expect(setContentRangeHeaderSpy.notCalled);
 | 
						|
      } 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 = sandbox.spy(result, "pipe");
 | 
						|
      const getStreamSpy = sandbox.spy(content, "getStream");
 | 
						|
      const contentProvider = sandbox.stub().resolves(content) as ContentProvider;
 | 
						|
      const handler = createPartialContentHandler(contentProvider, logger);
 | 
						|
      const setContentTypeHeaderSpy = sandbox.spy(utils, "setContentTypeHeader");
 | 
						|
      const setContentDispositionHeaderSpy = sandbox.spy(utils, "setContentDispositionHeader");
 | 
						|
      const setAcceptRangesHeaderSpy = sandbox.spy(utils, "setAcceptRangesHeader");
 | 
						|
      const setContentLengthHeaderSpy = sandbox.spy(utils, "setContentLengthHeader");
 | 
						|
      const setContentRangeHeaderSpy = sandbox.spy(utils, "setContentRangeHeader");
 | 
						|
      try {
 | 
						|
        await handler(req, res);
 | 
						|
        expect(setContentTypeHeaderSpy.calledOnceWith(content.mimeType, res));
 | 
						|
        expect(setContentDispositionHeaderSpy.calledOnceWith(content.fileName, res));
 | 
						|
        expect(setAcceptRangesHeaderSpy.calledOnceWith(res));
 | 
						|
        expect(setContentRangeHeaderSpy.calledOnceWith(range, content.totalSize, res));
 | 
						|
        expect(setContentLengthHeaderSpy.calledOnceWith(6, res));
 | 
						|
        expect(getStreamSpy.calledOnceWith(range));
 | 
						|
        expect(pipeSpy.calledOnceWith(res));
 | 
						|
      } catch {
 | 
						|
        expect(false);
 | 
						|
      }
 | 
						|
    });
 | 
						|
  });
 | 
						|
});
 |