Viewing File: /usr/local/cpanel/base/frontend/jupiter/site-monitor/services/sites.spec.js

/*
# site-moniotor/services/sites.spec.js             Copyright 2021 cPanel, L.L.C.
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
*/

/* eslint-env amd, jasmine */
/* global define, PAGE, module, inject */

define([
    "angular",
    "app/models/site",
    "app/models/domain-type.enum",
    "cjt/core",
    "cjt/util/test",
    "ngMocks",
    "cjt/services/APIFailures",
    "cjt/services/onBeforeUnload",
    "cjt/services/APIFailures",
    "cjt/services/APICatcher",
    "site-monitor/services/sites",
], function(angular, Site, DomainType) {
    "use strict";

    var service, q, $scope, $rootScope, apiHandler, PAGE;

    var _mainDomain = {
        domain: "this.is.the.main.domain",
        homedir: "/homedir",
    };

    var recentApiCalls = [];

    // Structured as
    //   {
    //      <namespace>: {
    //          <function1>: <return1>
    //          <function2>: <return2>
    //      }
    //   }
    var mockApiReturns = {
        Monitoring: {
            get_all_site_monitors: {
                response: {
                    monitors: [ {
                        downtime_seconds: 0,
                        first_update: 1639000295,
                        id: "9916258a-01f0-4a3e-88b1-0083d13c81a1",
                        ip_address: "127.0.0.1",
                        last_check: 1639000312,
                        last_update: 1639000321,
                        monitor: {
                            name: "USA/Houston",
                            ip_address_v6: "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
                            ip_address: "244.44.44.44",
                        },
                        name: 'Main Site',
                        ssl_expiration_timestamp: 1639000352,
                        status: 200,
                        status_message: 'ok',
                        type: 'https',
                        uptime_percentage: 99.9,
                        url: 'domain.com/index.html?check=1',
                    } ]
                }
            },
        },
        DomainInfo: {
            domains_data: {
                main_domain: {
                    domain: "domain.com",
                    documentroot: "/home/ssltest/public_html",
                    homedir: "/home/ssltest",
                    type: "main_domain",
                },
                sub_domains: [
                    {
                        domain: "sub.domain.com",
                        type: "sub_domain",
                        servername: "sub.domain.com",
                        homedir: "/homebase2",
                        documentroot: "/homebase2/sub_domain_com",
                    },
                ],
                parked_domains: [
                    "parked.domain.com",
                    "second.parked.domain.com"
                ],
                addon_domains: [
                    {
                        domain: "addon.domain.com",
                        type: "addon_domain",
                        servername: "sub.domain.com",
                        homedir: "/homebase",
                        documentroot: "/homebase/addon_domain_com",
                    },
                    {
                        domain: "second.addon.domain.com",
                        type: "addon_domain",
                        servername: "sub.domain.com",
                        homedir: "/homebase",
                        documentroot: "/homebase/second_addon_domain_com",
                    },
                ],
            },
        },
    };

    beforeEach(function() {
        module("cpanel.siteMonitor.sitesService");
        module("cjt2.services.api");
        module("cjt2.services.onBeforeUnload");
        module("cjt2.services.apifailures");
        module("cjt2.services.apicatcher");

        inject(function($injector) {
            service = $injector.get("sites");
            apiHandler = $injector.get("APICatcher");
            PAGE = $injector.get("PAGE");

            PAGE.requirePublicHTMLSubs = "1";
            PAGE.mainDomain = "domain.com";

            q = $injector.get("$q");
            $rootScope = $injector.get("$rootScope");
            $scope = $rootScope.$new();
        });

        $scope.$digest();
    });

    /**
     * Mock the api successes.
     *
     * @param {Object} mocks
     */
    function mockAPISuccess(mocks) {

        recentApiCalls = [];
        var spy = spyOn(apiHandler, "promise");
        spy.and.callFake(function(apiCall) {
            recentApiCalls.push(apiCall.module + "::" + apiCall.func);
            return q.resolve({ data: mocks[apiCall.module][apiCall.func] });
        });
    }

    /**
     * Mock the api failures.
     *
     * @param {string} message
     */
    function mockApiFailure(message) {

        var spy = spyOn(apiHandler, "promise");
        spy.and.callFake(function(apiCall) {
            return q.reject({
                errors: [ message ],
            });
        });
    }

    describe("parseDomain", function() {
        it("should throw an error if no domain passed", function() {
            expect(function() { service.parseDomain() }).toThrow();
        });

        it("should throw an error if empty object passed", function() {
            expect(function() { service.parseDomain({}) }).toThrow();
        });

        it("should throw an error if missing required fields", function() {
            expect(function() {
                service.parseDomain({
                    homedir: "/home/muppets",
                })
            }).toThrow();
        });

        it("should throw an error if missing required one of the alternative fields", function() {
            expect(function() {
                service.parseDomain({
                    domain: "muppets.com",
                    homedir: "/home/muppets",
                    type: DomainType.MAIN,
                })
            }).toThrow();
        });

        it("should return a parsed Site object when passed a valid DomainInfo response", function() {
            var gotDomain = service.parseDomain({
                domain: "muppets.com",
                homedir: "/home/muppets",
                documentroot: "/home/mupperts/public_html",
                servername: "muppets.com",
                is_https_redirecting: 0,
                all_aliases_valid: 1,
                can_https_redirect: 1,
                status: "not redirected",
                type: DomainType.MAIN,
            });

            var expectedSite = new Site({
                domain: "muppets.com",
                homedir: "/home/muppets",
                type: DomainType.MAIN,
            });

            expect(gotDomain).toEqual(jasmine.objectContaining(expectedSite));
        });
    });

    // Test code goes here
    describe("get", function() {
        it("should call the expected UAPI calls", function(done) {

            // Mockes
            mockAPISuccess(mockApiReturns);
            PAGE.hasWebServerRole = true;

            // Run the code
            var promise = service.get()
                .then(function(data) {

                    expect(recentApiCalls).toEqual([
                        "DomainInfo::domains_data",
                        "Monitoring::get_all_site_monitors",
                    ]);
                    done();
                })
                .catch(function(error) {
                    done(error);
                });

            // Yeild to angular
            $rootScope.$apply();
        });

        it("should call not call the api again if the Site is in the cache", function(done) {

            // Mockes
            mockAPISuccess(mockApiReturns);
            PAGE.hasWebServerRole = true;

            // Run the code
            var promise = service.get()
                .then(function(data) {
                    expect(recentApiCalls).toEqual([
                        "DomainInfo::domains_data",
                        "Monitoring::get_all_site_monitors",
                    ]);
                })
                .catch(function(error) {
                    done(error);
                })
                .finally(function(){

                    // Clear the previous api calls
                    recentApiCalls = [];
                    var promise2 = service.get()
                        .then(function(data) {
                            expect(recentApiCalls).toEqual([]);
                            done();
                        })
                        .catch(function(error){
                            done(error);
                        });

                    // Yeild to angular
                    $rootScope.$apply();
                });


            // Yeild to angular
            $rootScope.$apply();

        });

        it("should properly build a Site object when the cache is empty.", function(done) {

            // Mockes
            mockAPISuccess(mockApiReturns);
            PAGE.hasWebServerRole = true;

            // Run the code
            var promise = service.get()
                .then(function(data) {
                    data.forEach(function(site) {
                        if (site.type === "main_domain") {
                            expect(site).toEqual(jasmine.objectContaining({
                                homedir: jasmine.anything(),
                                documentRoot: jasmine.anything(),
                                type: jasmine.stringMatching(/main_domain/),
                                domain: jasmine.anything(),
                                monitors: [
                                    jasmine.objectContaining({}),
                                ],
                            }));
                        } else if (site.type === "addon") {
                            expect(site).toEqual(jasmine.objectContaining({
                                homedir: jasmine.anything(),
                                documentRoot: jasmine.anything(),
                                type: jasmine.stringMatching(/addon/),
                                domain: jasmine.anything(),
                                subdomain: jasmine.anything(),
                                monitors: [],
                            }));
                        } else if (site.type === "subdomain") {
                            expect(site).toEqual(jasmine.objectContaining({
                                homedir: jasmine.anything(),
                                documentRoot: jasmine.anything(),
                                type: jasmine.stringMatching(/subdomain/),
                                domain: jasmine.anything(),
                                subdomain: jasmine.anything(),
                                monitors: [],
                            }));
                        } else if (site.type === "alias") {
                            expect(site).toEqual(jasmine.objectContaining({
                                homedir: jasmine.anything(),
                                documentRoot: jasmine.anything(),
                                type: jasmine.stringMatching(/alias/),
                                domain: jasmine.anything(),
                                monitors: [],
                            }));
                        }
                    });
                    done();
                })
                .catch(function(error) {
                    done(error);
                });

            // Yeild to angular
            $rootScope.$apply();
        });

        it("should set the main domain for the account when get() is called", function(done) {

            mockAPISuccess(mockApiReturns);
            PAGE.hasWebServerRole = true;

            // Run the code
            var promise = service.get()
                .then(function(data) {
                    expect(service.getMainDomain()).toBeDefined();
                    done();
                })
                .catch(function(error) {
                    done(error);
                });

            // Yeild to angular
            $rootScope.$apply();
        });

        it("should be able to find the domain in the cache", function(done) {

            mockAPISuccess(mockApiReturns);
            PAGE.hasWebServerRole = true;

            // Run the code
            var promise = service.get()
                .then(function(data) {
                    var got = service.findByDomainName("domain.com")
                    expect(got).toEqual(jasmine.objectContaining({
                        domain: "domain.com",
                        type: DomainType.MAIN,
                    }));

                    got = service.findByDomainName("sub.domain.com")
                    expect(got).toEqual(jasmine.objectContaining({
                        domain: "sub.domain.com",
                        type: DomainType.SUBDOMAIN,
                    }));

                    got = service.findByDomainName("parked.domain.com")
                    expect(got).toEqual(jasmine.objectContaining({
                        domain: "parked.domain.com",
                        type: DomainType.ALIAS,
                    }));

                    got = service.findByDomainName("addon.domain.com")
                    expect(got).toEqual(jasmine.objectContaining({
                        domain: "addon.domain.com",
                        type: DomainType.ADDON,
                    }));
                    done();
                })
                .catch(function(error) {
                    done(error);
                });

            // Yeild to angular
            $rootScope.$apply();
        });

        it("should fail when one or more of the UAPI calls fails", function(done) {

            // Mocks
            mockApiFailure('Uhoh!');

            // Run the code
            var promise = service.get()
                .then(function() {
                    done('Test Failed');
                })
                .catch(function(error) {
                    expect(error).toEqual({
                        errors: [ 'Uhoh!' ]
                    });
                    done();
                });

            // Yeild to angular
            $rootScope.$apply();
        });

    });

});
Back to Directory File Manager