github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ui/src/views/shared/components/loading/loading.spec.tsx (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  import _ from "lodash";
    12  import React from "react";
    13  import { assert } from "chai";
    14  
    15  import "src/enzymeInit";
    16  import Loading from "src/views/shared/components/loading";
    17  import { ReactWrapper, mount } from "enzyme";
    18  
    19  const LOADING_CLASS_NAME = "loading-class-name";
    20  const RENDER_CLASS_NAME = "render-class-name";
    21  const ERROR_CLASS_NAME = "loading-error";
    22  const ALL_CLASS_NAMES = [LOADING_CLASS_NAME, ERROR_CLASS_NAME, RENDER_CLASS_NAME];
    23  
    24  interface MakeLoadingProps {
    25    loading: boolean;
    26    error?: Error | Error[] | null;
    27    renderClassName?: string;
    28  }
    29  
    30  interface AssertExpectedProps {
    31    onlyVisibleClass: string;
    32    errorCount?: number;
    33  }
    34  
    35  const makeLoadingComponent = (props: MakeLoadingProps) => mount(
    36    <Loading
    37      loading={props.loading}
    38      error={props.error}
    39      className={LOADING_CLASS_NAME}
    40      render={() => (<div className={props.renderClassName || RENDER_CLASS_NAME}>Hello, world!</div>)}
    41    />,
    42  );
    43  
    44  describe("<Loading>", () => {
    45  
    46    describe("when error is null", () => {
    47      describe("when loading=false", () => {
    48        it("renders content.", () => {
    49          const wrapper = makeLoadingComponent({
    50            loading: false, error: null,
    51            renderClassName: "my-rendered-content",
    52          });
    53          assertExpectedState(wrapper, {
    54            onlyVisibleClass: "my-rendered-content",
    55          });
    56        });
    57      });
    58  
    59      describe("when loading=true", () => {
    60        it("renders loading spinner.", () => {
    61          const wrapper = makeLoadingComponent({
    62            loading: true, error: null,
    63          });
    64          assertExpectedState(wrapper, {
    65            onlyVisibleClass: LOADING_CLASS_NAME,
    66          });
    67        });
    68      });
    69    });
    70  
    71    describe("when error is a single error", () => {
    72      describe("when loading=false", () => {
    73        it("renders error, regardless of loading value.", () => {
    74          const wrapper = makeLoadingComponent({
    75            loading: false,
    76            error: Error("some error message"),
    77          });
    78          assertExpectedState(wrapper, {
    79            onlyVisibleClass: ERROR_CLASS_NAME,
    80            errorCount: 1,
    81          });
    82        });
    83      });
    84  
    85      describe("when loading=true", () => {
    86        it("renders error, regardless of loading value.", () => {
    87          const wrapper = makeLoadingComponent({
    88            loading: true,
    89            error: Error("some error message"),
    90          });
    91          assertExpectedState(wrapper, {
    92            onlyVisibleClass: ERROR_CLASS_NAME,
    93            errorCount: 1,
    94          });
    95        });
    96      });
    97    });
    98  
    99    describe("when error is a list of errors", () => {
   100      describe("when no errors are null", () => {
   101        it("renders all errors in list", () => {
   102          const wrapper = makeLoadingComponent({
   103            loading: false,
   104            error: [
   105              Error("error1"),
   106              Error("error2"),
   107              Error("error3"),
   108            ],
   109          });
   110          assertExpectedState(wrapper, {
   111            onlyVisibleClass: ERROR_CLASS_NAME,
   112            errorCount: 3,
   113          });
   114        });
   115      });
   116  
   117      describe("when some errors are null", () => {
   118        it("ignores null list values, rending only valid errors.", () => {
   119          const wrapper = makeLoadingComponent({
   120            loading: false,
   121            error: [
   122              null,
   123              Error("error1"),
   124              Error("error2"),
   125              null,
   126              Error("error3"),
   127              null,
   128            ],
   129          });
   130          assertExpectedState(wrapper, {
   131            onlyVisibleClass: ERROR_CLASS_NAME,
   132            errorCount: 3,
   133          });
   134        });
   135      });
   136  
   137      describe("when all errors are null", () => {
   138        it("renders content, since there are no errors.", () => {
   139          const wrapper = makeLoadingComponent({
   140            loading: false,
   141            error: [
   142              null,
   143              null,
   144              null,
   145            ],
   146            renderClassName: "no-errors-so-should-render-me",
   147          });
   148          assertExpectedState(wrapper, {
   149            onlyVisibleClass: "no-errors-so-should-render-me",
   150          });
   151        });
   152      });
   153    });
   154  });
   155  
   156  function assertExpectedState(
   157    wrapper: ReactWrapper,
   158    props: AssertExpectedProps,
   159  ) {
   160    // Assert that onlyVisibleClass is rendered, and that all classes are not.
   161    _.map(ALL_CLASS_NAMES, (className) => {
   162      const expectedVisibility = props.onlyVisibleClass === className;
   163      const expectedLength = expectedVisibility ? 1 : 0;
   164      const element = "div." + className;
   165      assert.lengthOf(
   166        wrapper.find(element),
   167        expectedLength, "expected " + element +
   168        (expectedVisibility ? " to be visible" : " to not be rendered"));
   169    });
   170  
   171    if (props.errorCount) {
   172      assert.lengthOf(
   173        wrapper.find("div." + ERROR_CLASS_NAME).find("li"),
   174        props.errorCount,
   175      );
   176    }
   177  }