go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/build/pages/builder_group_page/builder_group_page.test.tsx (about)

     1  // Copyright 2024 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  import { act, render } from '@testing-library/react';
    16  
    17  import { FilterableBuilderTable } from '@/build/components/filterable_builder_table';
    18  import {
    19    BuilderID,
    20    BuilderItem,
    21  } from '@/proto/go.chromium.org/luci/buildbucket/proto/builder_common.pb';
    22  import {
    23    ListBuildersResponse,
    24    MiloInternalClientImpl,
    25  } from '@/proto/go.chromium.org/luci/milo/proto/v1/rpc.pb';
    26  import { FakeContextProvider } from '@/testing_tools/fakes/fake_context_provider';
    27  
    28  import { BuilderGroupPage } from './builder_group_page';
    29  
    30  jest.mock('@/build/components/filterable_builder_table', () =>
    31    self.createSelectiveMockFromModule<
    32      typeof import('@/build/components/filterable_builder_table')
    33    >('@/build/components/filterable_builder_table', ['FilterableBuilderTable']),
    34  );
    35  
    36  const builders = Array(25)
    37    .fill(0)
    38    .map((_, i) =>
    39      BuilderID.fromPartial({
    40        project: 'proj',
    41        bucket: `bucket${i}`,
    42        builder: `builder${i}`,
    43      }),
    44    );
    45  
    46  const builderItems = builders.map((id) => BuilderItem.fromPartial({ id }));
    47  
    48  const pages: { [key: string]: ListBuildersResponse } = {
    49    '': ListBuildersResponse.fromPartial({
    50      builders: Object.freeze(builderItems.slice(0, 10)),
    51      nextPageToken: 'page2',
    52    }),
    53    page2: ListBuildersResponse.fromPartial({
    54      builders: Object.freeze(builderItems.slice(10, 20)),
    55      nextPageToken: 'page3',
    56    }),
    57    page3: ListBuildersResponse.fromPartial({
    58      builders: Object.freeze(builderItems.slice(20, 25)),
    59      nextPageToken: '',
    60    }),
    61  };
    62  
    63  describe('<BuilderGroupPage />', () => {
    64    let listBuildersSpy: jest.SpiedFunction<
    65      MiloInternalClientImpl['ListBuilders']
    66    >;
    67    let builderTableMock: jest.MockedFunction<typeof FilterableBuilderTable>;
    68  
    69    beforeEach(() => {
    70      jest.useFakeTimers();
    71      builderTableMock = jest.mocked(FilterableBuilderTable);
    72      listBuildersSpy = jest
    73        .spyOn(MiloInternalClientImpl.prototype, 'ListBuilders')
    74        .mockImplementation(async (req) => pages[req.pageToken]);
    75    });
    76  
    77    afterEach(() => {
    78      jest.useRealTimers();
    79      listBuildersSpy.mockReset();
    80      builderTableMock.mockReset();
    81    });
    82  
    83    it('should render correctly', async () => {
    84      render(
    85        <FakeContextProvider
    86          mountedPath="/p/:project/g/:group/builders"
    87          routerOptions={{
    88            initialEntries: ['/p/proj/g/a_group/builders'],
    89          }}
    90        >
    91          <BuilderGroupPage />
    92        </FakeContextProvider>,
    93      );
    94  
    95      // Load all pages automatically.
    96      await act(() => jest.runAllTimersAsync());
    97      await act(() => jest.runAllTimersAsync());
    98      expect(listBuildersSpy).toHaveBeenCalledTimes(3);
    99  
   100      // No more page loading.
   101      await act(() => jest.runAllTimersAsync());
   102      expect(listBuildersSpy).toHaveBeenCalledTimes(3);
   103  
   104      expect(builderTableMock).toHaveBeenCalledWith(
   105        {
   106          builders,
   107          maxBatchSize: expect.anything(),
   108        },
   109        expect.anything(),
   110      );
   111    });
   112  });