brisket/brisket

View on GitHub
spec/server/ServerRenderingOrderSpec.js

Summary

Maintainability
B
5 hrs
Test Coverage
"use strict";

describe("Server side rendering order", function() {
    var ServerRenderingWorkflow = require("../../lib/server/ServerRenderingWorkflow");
    var View = require("../../lib/viewing/View");
    var MockExpressRequest = require("../mock/MockExpressRequest");
    var MockRouter = require("../mock/MockRouter");

    var renderingOrder;
    var expectedView;
    var originalHandler;
    var mockRouter;

    beforeEach(function() {
        expectedView = newExpectedView();
        renderingOrder = [];

        mockRouter = MockRouter.create();

        spyRenderingFor(mockRouter);

        originalHandler = function(layout) {
            renderingOrder.push("route handler runs");

            layout.customMethod();

            return expectedView;
        };

    });

    it("maintains a predictable rendering lifecycle for layout AND view on first request", function(done) {
        runRequest().finally(function() {
            expect(renderingOrder).toEqual([
                "route handler runs",
                "layout fetches data",
                "layout renders",
                "[deprecated] layout instructions from route handler run",
                "view for route renders"
            ]);

            done();
        });
    });

    function runRequest() {
        return ServerRenderingWorkflow.execute(
            mockRouter,
            originalHandler, [null],
            MockExpressRequest.basic(), {}
        );
    }

    function spyRenderingFor(router) {
        spyOn(router.layout.prototype, "fetchData").and.callFake(function() {
            renderingOrder.push("layout fetches data");
        });

        spyOn(router.layout.prototype, "render").and.callFake(function() {
            renderingOrder.push("layout renders");

            this.hasBeenRendered = true;
        });

        spyOn(router.layout.prototype, "customMethod").and.callFake(function() {
            renderingOrder.push("[deprecated] layout instructions from route handler run");
        });

        spyOn(router.layout.prototype, "backToNormal").and.callFake(function() {
            renderingOrder.push("layout back to normal");
        });

        spyOn(router.layout.prototype, "onDOM").and.callFake(function() {
            renderingOrder.push("layout enters DOM");

            this.isInDOM = true;
        });
    }

    function newExpectedView() {
        var view = new View();

        spyOn(view, "render").and.callFake(function() {
            renderingOrder.push("view for route renders");

            return this;
        });

        spyOn(view, "onDOM").and.callFake(function() {
            renderingOrder.push("view for route enters DOM");
        });

        return view;
    }

});