github.com/tilt-dev/tilt@v0.36.0/web/src/ResourceGroupsContext.test.tsx (about) 1 import { act, render } from "@testing-library/react" 2 import userEvent from "@testing-library/user-event" 3 import React from "react" 4 import { 5 DEFAULT_GROUP_STATE, 6 ResourceGroupsContextProvider, 7 useResourceGroups, 8 } from "./ResourceGroupsContext" 9 10 const GROUP_STATE_ID = "test-group-state" 11 const LABEL_STATE_ID = "test-label-state" 12 13 // This is a very basic test component that prints out the state 14 // from the ResourceGroups context and provides buttons to trigger 15 // methods returned by the context, so they can be tested 16 const TestConsumer = (props: { labelName?: string }) => { 17 const { groups, getGroup, toggleGroupExpanded } = useResourceGroups() 18 19 return ( 20 <> 21 <p id={GROUP_STATE_ID}>{JSON.stringify(groups)}</p> 22 {/* Display the label state if a specific label is present */} 23 {props.labelName && ( 24 <p id={LABEL_STATE_ID}>{JSON.stringify(getGroup(props.labelName))}</p> 25 )} 26 {/* Display a button to toggle the label state if a specific label is present */} 27 {props.labelName && ( 28 <button onClick={() => toggleGroupExpanded(props.labelName || "")} /> 29 )} 30 </> 31 ) 32 } 33 34 describe("ResourceGroupsContext", () => { 35 let wrapper: HTMLElement 36 37 // Helpers 38 const groupState = () => 39 wrapper.querySelector(`#${GROUP_STATE_ID}`)!.innerHTML 40 const labelState = () => 41 wrapper.querySelector(`#${LABEL_STATE_ID}`)!.innerHTML 42 const clickButton = () => { 43 userEvent.click(wrapper.querySelector("button")!) 44 } 45 46 beforeEach(() => { 47 localStorage.clear() 48 }) 49 50 afterEach(() => { 51 localStorage.clear() 52 }) 53 54 it("defaults to an empty state with no groups", () => { 55 wrapper = renderContainer( 56 <ResourceGroupsContextProvider> 57 <TestConsumer /> 58 </ResourceGroupsContextProvider> 59 ) 60 61 expect(groupState()).toBe(JSON.stringify({})) 62 }) 63 64 describe("toggleGroupExpanded", () => { 65 it("sets expanded to `true` when group is collapsed", () => { 66 const testValues = { test: { expanded: false } } 67 wrapper = renderContainer( 68 <ResourceGroupsContextProvider initialValuesForTesting={testValues}> 69 <TestConsumer labelName="test" /> 70 </ResourceGroupsContextProvider> 71 ) 72 clickButton() 73 74 expect(labelState()).toBe(JSON.stringify({ expanded: true })) 75 }) 76 77 it("sets expanded to `false` when group is expanded", () => { 78 const testValues = { test: { expanded: true } } 79 wrapper = renderContainer( 80 <ResourceGroupsContextProvider initialValuesForTesting={testValues}> 81 <TestConsumer labelName="test" /> 82 </ResourceGroupsContextProvider> 83 ) 84 clickButton() 85 86 expect(labelState()).toBe(JSON.stringify({ expanded: false })) 87 }) 88 89 it("sets expanded to `false` if a group isn't saved yet and is toggled", () => { 90 wrapper = renderContainer( 91 <ResourceGroupsContextProvider> 92 <TestConsumer labelName="a-non-existent-group" /> 93 </ResourceGroupsContextProvider> 94 ) 95 clickButton() 96 97 expect(labelState()).toBe(JSON.stringify({ expanded: false })) 98 }) 99 }) 100 101 describe("getGroup", () => { 102 it("returns the correct state of a resource group", () => { 103 const testValues = { frontend: { expanded: false } } 104 wrapper = renderContainer( 105 <ResourceGroupsContextProvider initialValuesForTesting={testValues}> 106 <TestConsumer labelName="frontend" /> 107 </ResourceGroupsContextProvider> 108 ) 109 110 expect(labelState()).toBe(JSON.stringify({ expanded: false })) 111 }) 112 113 it("returns a default state of a resource group if a group isn't saved yet", () => { 114 const testValues = { frontend: { expanded: false } } 115 wrapper = renderContainer( 116 <ResourceGroupsContextProvider initialValuesForTesting={testValues}> 117 <TestConsumer labelName="backend" /> 118 </ResourceGroupsContextProvider> 119 ) 120 121 expect(labelState()).toBe(JSON.stringify(DEFAULT_GROUP_STATE)) 122 }) 123 }) 124 125 it("memoizes renders", () => { 126 let renderCount = 0 127 let toggleGroupExpanded: any 128 let FakeEl = React.memo(() => { 129 let context = useResourceGroups() 130 toggleGroupExpanded = context.toggleGroupExpanded 131 renderCount++ 132 return <div></div> 133 }) 134 135 let tree = () => { 136 const init = { frontend: { expanded: false } } 137 return ( 138 <ResourceGroupsContextProvider initialValuesForTesting={init}> 139 <FakeEl /> 140 </ResourceGroupsContextProvider> 141 ) 142 } 143 144 let { rerender } = render(tree()) 145 expect(renderCount).toEqual(1) 146 147 // Make sure we don't re-render 148 rerender(tree()) 149 expect(renderCount).toEqual(1) 150 151 act(() => toggleGroupExpanded("frontend")) 152 expect(renderCount).toEqual(2) 153 }) 154 }) 155 156 function renderContainer(x: any) { 157 let { container } = render(x) 158 return container 159 }