go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/common/store/build_page/build_page.test.ts (about)

     1  // Copyright 2021 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 { autorun } from 'mobx';
    16  import { addDisposer, destroy } from 'mobx-state-tree';
    17  
    18  import { ANONYMOUS_IDENTITY } from '@/common/api/auth_state';
    19  import { Build, GetBuildRequest } from '@/common/services/buildbucket';
    20  import { Store, StoreInstance } from '@/common/store';
    21  import { CacheOption } from '@/generic_libs/tools/cached_fn';
    22  
    23  describe('BuildPage', () => {
    24    describe('cache', () => {
    25      let store: StoreInstance;
    26      let getBuildStub: jest.SpiedFunction<
    27        (req: GetBuildRequest, cacheOpt?: CacheOption) => Promise<Build>
    28      >;
    29  
    30      beforeEach(() => {
    31        const builderId = {
    32          project: 'proj',
    33          bucket: 'bucket',
    34          builder: 'builder',
    35        };
    36        jest.useFakeTimers();
    37        store = Store.create({
    38          authState: { value: { identity: ANONYMOUS_IDENTITY } },
    39          refreshTime: { value: jest.now() },
    40        });
    41        store.buildPage.setParams(builderId, '1');
    42  
    43        getBuildStub = jest.spyOn(store.services.builds!, 'getBuild');
    44        getBuildStub.mockResolvedValueOnce({
    45          number: 1,
    46          id: '2',
    47          builder: builderId,
    48        } as Build);
    49        getBuildStub.mockResolvedValueOnce({
    50          number: 1,
    51          id: '2',
    52          builder: builderId,
    53        } as Build);
    54      });
    55  
    56      afterEach(() => {
    57        destroy(store);
    58        jest.useRealTimers();
    59      });
    60  
    61      test('should accept cache when first querying build', async () => {
    62        store.buildPage.build;
    63        await jest.runAllTimersAsync();
    64        expect(getBuildStub.mock.calls[0][1]?.acceptCache).not.toBeFalsy();
    65      });
    66  
    67      test('should not accept cache after calling refresh', async () => {
    68        store.buildPage.build;
    69        await jest.runAllTimersAsync();
    70  
    71        await jest.advanceTimersByTimeAsync(10);
    72        store.refreshTime.refresh();
    73        store.buildPage.build;
    74        await jest.runAllTimersAsync();
    75  
    76        expect(getBuildStub.mock.calls[0][1]?.acceptCache).not.toBeFalsy();
    77        expect(getBuildStub.mock.calls[1][1]?.acceptCache).toBeFalsy();
    78      });
    79    });
    80  
    81    describe('params', () => {
    82      let store: StoreInstance;
    83      beforeEach(() => {
    84        jest.useFakeTimers();
    85        store = Store.create({
    86          authState: { value: { identity: ANONYMOUS_IDENTITY } },
    87          refreshTime: { value: jest.now() },
    88        });
    89      });
    90  
    91      afterEach(() => {
    92        destroy(store);
    93        jest.useRealTimers();
    94      });
    95  
    96      test('ignore builderIdParam when buildNumOrIdParam is a buildId', async () => {
    97        store.buildPage.setParams(
    98          {
    99            project: 'wrong_proj',
   100            bucket: 'wrong_bucket',
   101            builder: 'wrong_builder',
   102          },
   103          'b123',
   104        );
   105  
   106        const getBuildStub = jest.spyOn(store.services.builds!, 'getBuild');
   107        const batchCheckPermissionsStub = jest.spyOn(
   108          store.services.milo!,
   109          'batchCheckPermissions',
   110        );
   111  
   112        const builderId = {
   113          project: 'proj',
   114          bucket: 'bucket',
   115          builder: 'builder',
   116        };
   117        getBuildStub.mockResolvedValueOnce({
   118          number: 1,
   119          id: '123',
   120          builder: builderId,
   121        } as Build);
   122        batchCheckPermissionsStub.mockResolvedValueOnce({ results: {} });
   123  
   124        addDisposer(
   125          store,
   126          autorun(() => {
   127            store.buildPage.build;
   128            store.buildPage.canRetry;
   129          }),
   130        );
   131        await jest.runAllTimersAsync();
   132  
   133        expect(getBuildStub.mock.calls[0][0].builder).toBeUndefined();
   134        expect(batchCheckPermissionsStub.mock.calls[0][0].realm).toStrictEqual(
   135          `${builderId.project}:${builderId.bucket}`,
   136        );
   137      });
   138    });
   139  });