github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/web/src/OverviewResourcePane.test.tsx (about)

     1  import {
     2    fireEvent,
     3    render,
     4    RenderOptions,
     5    screen,
     6  } from "@testing-library/react"
     7  import { SnackbarProvider } from "notistack"
     8  import React from "react"
     9  import { MemoryRouter } from "react-router-dom"
    10  import LogStore, { LogStoreProvider } from "./LogStore"
    11  import OverviewResourcePane from "./OverviewResourcePane"
    12  import { ResourceNavProvider } from "./ResourceNav"
    13  import { SidebarContextProvider } from "./SidebarContext"
    14  import { nResourceView, oneResourceView, TestDataView } from "./testdata"
    15  import { appendLinesForManifestAndSpan, Line } from "./testlogs"
    16  import { LogLevel, UIResource } from "./types"
    17  
    18  function customRender(
    19    options: {
    20      logStore?: LogStore
    21      selectedResource?: string
    22      view: TestDataView
    23      sidebarClosed?: boolean
    24    },
    25    renderOptions?: RenderOptions
    26  ) {
    27    const { logStore, view, selectedResource } = options
    28    const routerEntry = selectedResource
    29      ? `/r/${selectedResource}/overview`
    30      : "/overview"
    31    const validateResource = (name: string) =>
    32      view.uiResources?.some((res) => res.metadata?.name == name)
    33  
    34    return render(<OverviewResourcePane view={view} isSocketConnected={true} />, {
    35      wrapper: ({ children }) => (
    36        <MemoryRouter initialEntries={[routerEntry]}>
    37          <LogStoreProvider value={logStore ?? new LogStore()}>
    38            <SnackbarProvider>
    39              <ResourceNavProvider validateResource={validateResource}>
    40                <SidebarContextProvider
    41                  sidebarClosedForTesting={options.sidebarClosed}
    42                >
    43                  {children}
    44                </SidebarContextProvider>
    45              </ResourceNavProvider>
    46            </SnackbarProvider>
    47          </LogStoreProvider>
    48        </MemoryRouter>
    49      ),
    50      ...renderOptions,
    51    })
    52  }
    53  
    54  describe("OverviewResourcePane", () => {
    55    it("renders 'not found' message when trying to view a resource that doesn't exist", () => {
    56      customRender({ selectedResource: "does-not-exist", view: nResourceView(2) })
    57  
    58      expect(screen.getByText("No resource 'does-not-exist'")).toBeInTheDocument()
    59    })
    60  
    61    it("renders 'Resource: <name>' title row for selected resource when sidebar is closed", () => {
    62      customRender({
    63        selectedResource: "_0",
    64        view: nResourceView(2),
    65        sidebarClosed: true,
    66      })
    67  
    68      expect(screen.getByText("Resource: _0")).toBeInTheDocument()
    69    })
    70  
    71    it("icon button toggles sidebar open/closed, non-selected resources should not be visible when closed", () => {
    72      customRender({ selectedResource: "_0", view: nResourceView(2) })
    73  
    74      expect(screen.getByText("_1")).toBeInTheDocument()
    75  
    76      const clickEvent = new MouseEvent("click", { bubbles: true })
    77      fireEvent(screen.getByLabelText("Collapse sidebar"), clickEvent)
    78      expect(screen.queryAllByText("_1")).toHaveLength(0)
    79  
    80      fireEvent(screen.getByLabelText("Expand sidebar"), clickEvent)
    81      expect(screen.getByText("_1")).toBeInTheDocument()
    82    })
    83  })
    84  
    85  describe("alert filtering", () => {
    86    const doTest = (
    87      expectedErrs: number,
    88      expectedWarns: number,
    89      prepare: (logStore: LogStore, r: UIResource) => any
    90    ) => {
    91      const logStore = new LogStore()
    92      const view = oneResourceView()
    93  
    94      const r = view.uiResources[0]
    95  
    96      prepare(logStore, r)
    97  
    98      customRender({ view, logStore, selectedResource: r.metadata?.name })
    99  
   100      const errorFilterButton = screen.getByRole("button", { name: /errors/i })
   101      const warningFilterButton = screen.getByRole("button", {
   102        name: /warnings/i,
   103      })
   104  
   105      expect(errorFilterButton).toHaveTextContent(`Errors (${expectedErrs})`)
   106      expect(warningFilterButton).toHaveTextContent(`Warnings (${expectedWarns})`)
   107    }
   108  
   109    it("creates no alerts if no build failures", () => {
   110      doTest(0, 0, (logStore, r) => {
   111        const latestBuild = r.status!.buildHistory![0] || {}
   112        latestBuild.spanID = "build:1"
   113        latestBuild.error = undefined
   114        latestBuild.warnings = []
   115  
   116        appendLinesForManifestAndSpan(logStore, r.metadata!.name!, "build:1", [
   117          "the build is ok!\n",
   118        ])
   119      })
   120    })
   121  
   122    it("creates alerts for build failures with existing spans", () => {
   123      doTest(1, 2, (logStore, r) => {
   124        const latestBuild = r.status!.buildHistory![0]
   125        latestBuild.spanID = "build:1"
   126        latestBuild.error = "the build failed!"
   127        latestBuild.warnings = ["warning 1!", "warning 2!"]
   128  
   129        appendLinesForManifestAndSpan(logStore, r.metadata!.name!, "build:1", [
   130          { level: LogLevel.WARN, anchor: true, text: "warning 1!\n" } as Line,
   131          { level: LogLevel.WARN, anchor: true, text: "warning 2!\n" } as Line,
   132          {
   133            level: LogLevel.ERROR,
   134            anchor: true,
   135            text: "the build failed!\n",
   136          } as Line,
   137        ])
   138      })
   139    })
   140  
   141    it("ignores alerts for removed spans", () => {
   142      doTest(0, 0, (logStore, r) => {
   143        const latestBuild = r.status!.buildHistory![0] || {}
   144        latestBuild.spanID = "build:1"
   145        latestBuild.error = "the build failed!"
   146        latestBuild.warnings = ["warning!"]
   147  
   148        appendLinesForManifestAndSpan(logStore, r.metadata!.name!, "build:2", [
   149          { level: LogLevel.WARN, anchor: true, text: "warning!\n" } as Line,
   150          {
   151            level: LogLevel.ERROR,
   152            anchor: true,
   153            text: "the build failed!\n",
   154          } as Line,
   155        ])
   156      })
   157    })
   158  })