Skip to content

Commit

Permalink
chore: Add test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
jessieweiyi committed Feb 24, 2023
1 parent b4863dd commit 180da22
Show file tree
Hide file tree
Showing 11 changed files with 208 additions and 18 deletions.
2 changes: 1 addition & 1 deletion packages/ui/.storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const decorators = [

return (
<StrictMode>
<NorthStarThemeProvider colorMode={colorMode}>
<NorthStarThemeProvider theme={colorMode}>
<Story />
</NorthStarThemeProvider>
</StrictMode>
Expand Down
8 changes: 4 additions & 4 deletions packages/ui/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ module.exports = merge.recursive(tsPreset, cloudscapePreset, {
maxWorkers: '50%',
coverageThreshold: {
global: {
branches: 60,
functions: 70,
lines: 85,
statements: 85,
branches: 68,
functions: 75,
lines: 88,
statements: 87,
},
},
coveragePathIgnorePatterns: ['/node_modules/', '/components/index.ts', '.*/.*.stories.tsx'],
Expand Down
17 changes: 15 additions & 2 deletions packages/ui/src/components/AppLayout/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
See the License for the specific language governing permissions and
limitations under the License. *
******************************************************************************************************************** */
import React from 'react';
import { withRouter } from 'storybook-addon-react-router-v6';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import Badge from '@cloudscape-design/components/badge';
import SpaceBetween from '@cloudscape-design/components/space-between';
import { composeStory } from '@storybook/testing-react';
import AppLayout from '.';
import KeyValuePairsStoryMeta, { Default as KeyValuePairsStory } from '../KeyValuePairs/index.stories';
import TableMeta, { LongData as TableStory } from '../Table/index.stories';

export default {
component: AppLayout,
Expand All @@ -28,8 +31,18 @@ export default {
},
} as ComponentMeta<typeof AppLayout>;

const KeyValuePairs = composeStory(KeyValuePairsStory, KeyValuePairsStoryMeta);
const Table = composeStory(TableStory, TableMeta);

const Template: ComponentStory<typeof AppLayout> = (args) => {
return <AppLayout {...args} />;
return (
<AppLayout {...args}>
<SpaceBetween size="l">
<KeyValuePairs />
<Table />
</SpaceBetween>
</AppLayout>
);
};

export const Default = Template.bind({});
Expand Down
6 changes: 5 additions & 1 deletion packages/ui/src/components/AppLayout/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ import { render } from '@testing-library/react';
import { composeStories } from '@storybook/testing-react';
import * as stories from './index.stories';

const { Default } = composeStories(stories);
const { Default, WithUser } = composeStories(stories);

describe('AppLayout', () => {
it('should render default AppLayout', async () => {
render(<Default />);
});

it('should render AppLayout with user', async () => {
render(<WithUser />);
});
});
20 changes: 19 additions & 1 deletion packages/ui/src/components/AppLayout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { FC, useState, useCallback, createContext, PropsWithChildren, ReactEleme
import { useNavigate } from 'react-router-dom';
import BreadcrumbGroup, { BreadcrumbGroupProps } from '@cloudscape-design/components/breadcrumb-group';
import SideNavigation, { SideNavigationProps } from '@cloudscape-design/components/side-navigation';
import Box from '@cloudscape-design/components/box';
import AppLayoutComponent, {
AppLayoutProps as AppLayoutComponentProps,
} from '@cloudscape-design/components/app-layout';
Expand Down Expand Up @@ -138,7 +139,24 @@ const AppLayout: FC<PropsWithChildren<AppLayoutProps>> = ({
setAppLayoutProps: setAppLayoutPropsSafe,
}}
>
{children}
{!props.contentType || props.contentType === 'default' ? (
<div
style={{
display: 'flex',
}}
>
<div
style={{
flex: '1 0 auto',
overflowY: 'scroll',
}}
>
<Box margin="l">{children}</Box>
</div>
</div>
) : (
children
)}
</AppLayoutContext.Provider>
}
{...props}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ const FileTokenLabel: FunctionComponent<FileMetadata> = ({ name, size, lastModif
<StatusIndicator type="success" />
<TextContent>
<Spacebetween direction="vertical" size="xxxs">
<b>{name}</b>
{getDisplaySize(size)}
{lastModified && getDisplayLastModified(lastModified)}
<div key="name">
<b>{name}</b>
</div>
<div key="size">{getDisplaySize(size)}</div>
<div key="lastModified">{lastModified && getDisplayLastModified(lastModified)}</div>
</Spacebetween>
</TextContent>
</Spacebetween>
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/components/FileUpload/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ MultiWithValue.args = {
{
name: 'file_name2.file_type2',
size: 1022222,
lastModified: 1611275279000,
lastModified: 1622275279000,
},
{
name: 'file_name3.file_type3',
size: 103333333,
lastModified: 1611275279000,
lastModified: 1641231243243,
},
],
};
105 changes: 102 additions & 3 deletions packages/ui/src/components/FileUpload/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,113 @@
See the License for the specific language governing permissions and
limitations under the License. *
******************************************************************************************************************** */
import { render } from '@testing-library/react';
import { render, screen, act } from '@testing-library/react';
import { composeStories } from '@storybook/testing-react';
import userEvent from '@testing-library/user-event';
import wrapper from '@cloudscape-design/components/test-utils/dom';
import * as stories from './index.stories';
import getDisplayLastModified from './utils/getDisplayLastModified';

const { Default } = composeStories(stories);
const { Default, WithValue, Error, Multi, MultiWithValue } = composeStories(stories);

describe('FileUpload', () => {
it('should render file upload widget', async () => {
it('should render file upload control', async () => {
render(<Default />);
expect(screen.getByText('Form field label')).toBeVisible();
expect(screen.getByText('Description')).toBeVisible();
expect(screen.getByText('Hint text for file requirements')).toBeVisible();

const content = 'hello world';
const lastModified = new Date(2022, 1, 1).getTime();

await act(() => {
userEvent.upload(
screen.getByLabelText('Form field label'),
new File([new Blob([content])], 'test.png', {
type: 'image/png',
lastModified,
})
);
});

expect(screen.getByText('test.png')).toBeVisible();
expect(screen.getByText(`Size: ${content.length} bytes`)).toBeVisible();
expect(screen.getByText(getDisplayLastModified(lastModified))).toBeVisible();
});

it('should render file upload control with initial value', async () => {
render(<WithValue />);

expect(screen.getByText('file_name.file_type')).toBeVisible();
expect(screen.getByText('Size: 1 KB')).toBeVisible();
expect(screen.getByText('Last modified: 1/22/2021, 12:27:59 AM')).toBeVisible();
});

it('should render error message', async () => {
render(<Error />);

expect(screen.getByText('Error message')).toBeVisible();
});

it('should render file upload control for uploading multiple files', async () => {
render(<Multi />);

const fileName1 = 'test1.png';
const content1 = 'hello world';
const lastModified1 = new Date(2022, 1, 1).getTime();

await act(() => {
userEvent.upload(
screen.getByLabelText('Form field label'),
new File([new Blob([content1])], fileName1, {
type: 'image/png',
lastModified: lastModified1,
})
);
});

const fileName2 = 'test2.png';
const content2 = 'some randome content';
const lastModified2 = new Date(2022, 2, 1).getTime();

await act(() => {
userEvent.upload(
screen.getByLabelText('Form field label'),
new File([new Blob([content2])], fileName2, {
type: 'image/png',
lastModified: lastModified2,
})
);
});

expect(screen.getByText(fileName1)).toBeVisible();
expect(screen.getByText(`Size: ${content1.length} bytes`)).toBeVisible();
expect(screen.getByText(getDisplayLastModified(lastModified1))).toBeVisible();

expect(screen.getByText(fileName2)).toBeVisible();
expect(screen.getByText(`Size: ${content2.length} bytes`)).toBeVisible();
expect(screen.getByText(getDisplayLastModified(lastModified2))).toBeVisible();
});

it('should render file upload control for uploading multiple files with initial values', async () => {
const { container } = render(<MultiWithValue />);

const tokenGroup = wrapper(container).findTokenGroup();

const tokens = tokenGroup?.findTokens();
expect(tokens).toHaveLength(3);

expect(tokens![0].findLabel().getElement()).toHaveTextContent(
'very_long_long_long_long_long_long_long_long_long_file_name1.file_type1'
);
expect(tokens![1].findLabel().getElement()).toHaveTextContent('file_name2.file_type2');
expect(tokens![2].findLabel().getElement()).toHaveTextContent('file_name3.file_type3');

await act(async () => {
await userEvent.click(tokens![1].findDismiss().getElement());
});

expect(tokenGroup?.findTokens()).toHaveLength(2);
expect(screen.queryByText('file_name2.file_type2')).toBeNull();
});
});
3 changes: 2 additions & 1 deletion packages/ui/src/components/FileUpload/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export interface FileUploadProps extends FormFieldProps {
/**
* The list of choosen files.
*/
files?: FileMetadata[];
files?: (File | FileMetadata)[];
/**
* Event handler for the file selection change event.
*/
Expand Down Expand Up @@ -157,6 +157,7 @@ const FileUpload: FC<FileUploadProps> = ({
<SpaceBetween direction="vertical" size="m">
<FormField
{...props}
controlId={id}
label={label}
info={info}
description={description}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/** *******************************************************************************************************************
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. *
******************************************************************************************************************** */
import getDisplayLastModified from '.';

describe('getDisplayLastModified', () => {
it('should return the displayed last modified date text of the date object', () => {
const date = new Date(2022, 0, 1, 1, 1);
expect(getDisplayLastModified(date)).toBe('Last modified: 1/1/2022, 1:01:00 AM');
});

it('should return the displayed last modified date text of the date number', () => {
const date = new Date(2022, 0, 1, 1, 1).getTime();
expect(getDisplayLastModified(date)).toBe('Last modified: 1/1/2022, 1:01:00 AM');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/** *******************************************************************************************************************
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. *
******************************************************************************************************************** */
import getDisplaySie from '.';

describe('getDisplaySie', () => {
it('should return the displayed file size', () => {
expect(getDisplaySie(11)).toBe('Size: 11 bytes');
expect(getDisplaySie(1011)).toBe('Size: 1.01 KB');
expect(getDisplaySie(1011000)).toBe('Size: 1.01 MB');
expect(getDisplaySie(1011000000)).toBe('Size: 1.01 GB');
});
});

0 comments on commit 180da22

Please sign in to comment.