Skip to content

Commit

Permalink
[ui] Add tests for recently visited assets (#20321)
Browse files Browse the repository at this point in the history
Adds tests to preserve logic in
#20266 that stores the N most
recently-viewed assets:
- Assert that when an asset is viewed, its asset key is stored in local
storage
- Assert that if a user tries to view a nonexistent asset, nothing is
added to local storage

Let me know if more detailed tests are needed, i.e. tests asserting LRU
cache behavior.
  • Loading branch information
clairelin135 authored and PedramNavid committed Mar 28, 2024
1 parent 8ddf051 commit d691937
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export const AssetsCatalogRoot = () => {
// eslint-disable-next-line import/no-default-export
export default AssetsCatalogRoot;

const ASSETS_CATALOG_ROOT_QUERY = gql`
export const ASSETS_CATALOG_ROOT_QUERY = gql`
query AssetsCatalogRootQuery($assetKey: AssetKeyInput!) {
assetOrError(assetKey: $assetKey) {
... on Asset {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import {MockedProvider} from '@apollo/client/testing';
import {render, screen, waitFor} from '@testing-library/react';
import Router, {MemoryRouter} from 'react-router-dom';

import {AnalyticsContext} from '../../app/analytics';
import {AssetLiveDataProvider} from '../../asset-data/AssetLiveDataProvider';
import {buildAsset, buildAssetKey} from '../../graphql/types';
import {buildQueryMock} from '../../testing/mocking';
import AssetsCatalogRoot, {ASSETS_CATALOG_ROOT_QUERY} from '../AssetsCatalogRoot';
import {fetchRecentlyVisitedAssetsFromLocalStorage} from '../RecentlyVisitedAssetsStorage';
import {
AssetsCatalogRootQuery,
AssetsCatalogRootQueryVariables,
} from '../types/AssetsCatalogRoot.types';

// Mock the `useParams` hook to override the asset key in the URL.
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useParams: jest.fn(),
}));

describe('RecentlyVisitedAssetsStorage', () => {
beforeEach(() => {
window.localStorage.clear();
});

it('Store visited asset in local storage', async () => {
// Set the asset key in the URL
jest.spyOn(Router, 'useParams').mockReturnValue({0: 'sda_asset'});

const assetKey = {path: ['sda_asset']};
const TestAssetView = (
<MockedProvider
mocks={[
buildQueryMock<AssetsCatalogRootQuery, AssetsCatalogRootQueryVariables>({
query: ASSETS_CATALOG_ROOT_QUERY,
variables: {
assetKey,
},
data: {
assetOrError: buildAsset({
key: buildAssetKey(assetKey),
}),
},
}),
]}
>
<AnalyticsContext.Provider value={{page: () => {}} as any}>
<AssetLiveDataProvider>
<MemoryRouter initialEntries={['/assets/sda_asset']}>
<AssetsCatalogRoot />
</MemoryRouter>
</AssetLiveDataProvider>
</AnalyticsContext.Provider>
</MockedProvider>
);

// First render displays the page in a loading state
const {rerender} = render(TestAssetView);
// Assert that the asset is not stored if the page is still loading
expect(fetchRecentlyVisitedAssetsFromLocalStorage()).toEqual([]);
// Wait for the page to load
await waitFor(() => {
expect(screen.queryByText('Loading assets…')).toBeNull();
});
// Second render displays the page in a loaded state
// Effect called to store asset in local storage
rerender(TestAssetView);

expect(fetchRecentlyVisitedAssetsFromLocalStorage()).toEqual([assetKey]);
});

it('Do not store nonexistent asset in local storage', async () => {
// Set the asset key in the URL
jest.spyOn(Router, 'useParams').mockReturnValue({0: 'nonexistent_asset'});

const assetKey = {path: ['nonexistent_asset']};
const TestAssetView = (
<MockedProvider
mocks={[
buildQueryMock<AssetsCatalogRootQuery, AssetsCatalogRootQueryVariables>({
query: ASSETS_CATALOG_ROOT_QUERY,
variables: {
assetKey,
},
data: {
assetOrError: {
__typename: 'AssetNotFoundError',
},
},
}),
]}
>
<AnalyticsContext.Provider value={{page: () => {}} as any}>
<AssetLiveDataProvider>
<MemoryRouter initialEntries={['/assets/nonexistent_asset']}>
<AssetsCatalogRoot />
</MemoryRouter>
</AssetLiveDataProvider>
</AnalyticsContext.Provider>
</MockedProvider>
);

// First render displays the page in a loading state
const {rerender} = render(TestAssetView);
// Assert that the asset is not stored if the page is still loading
expect(fetchRecentlyVisitedAssetsFromLocalStorage()).toEqual([]);
// Wait for the page to load
await waitFor(() => {
expect(screen.queryByText('Loading assets…')).toBeNull();
});
// Second render displays the page in a loaded state
// Effect called to store asset in local storage
rerender(TestAssetView);

expect(fetchRecentlyVisitedAssetsFromLocalStorage()).toEqual([]);
});
});

0 comments on commit d691937

Please sign in to comment.