Skip to content

React testing library #109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
4043947
add new config to jest
rady-ben Sep 3, 2021
3f2a646
configure enzyme and test the render of FileForm
rady-ben Sep 3, 2021
b7b0960
remove unused componenent
rady-ben Sep 5, 2021
75f927e
test the render of the element inside FileForm component
rady-ben Sep 6, 2021
c05a2ec
add propTypes tests
rady-ben Sep 7, 2021
dfb0c78
add default propos
rady-ben Sep 8, 2021
24846a9
add text input behaviour tests
rady-ben Sep 8, 2021
2ffcbde
refractor the Enzyme utils in separate file to not repeat the config …
rady-ben Sep 9, 2021
6390bb4
add some messing propTypes to FileCard
rady-ben Sep 9, 2021
99bf78d
replace the authentication props by is authenticated
rady-ben Sep 10, 2021
afbd3d7
add the render tests fot the FileCard
rady-ben Sep 10, 2021
b9e0e77
add prop types test for theFileCard
rady-ben Sep 10, 2021
6a0dd50
add unit test for the useState on FileCard
rady-ben Sep 10, 2021
4b3cdd4
use deferents initials states on jest tests
rady-ben Sep 13, 2021
fb37448
allow useing the destructuring import of useState without breaking tests
rady-ben Sep 14, 2021
0aadb90
return the tests removed by mistake
rady-ben Sep 14, 2021
1313723
reset useState to its initial value befor run rendering tests
rady-ben Sep 14, 2021
fe79d01
test the conditionel rendering of Pageview icon
rady-ben Sep 14, 2021
4bc8d2f
config react testing library and add input changes tests
rady-ben Sep 16, 2021
f1a6f26
check if all inputs are inside the compoenent
rady-ben Sep 17, 2021
3f3854a
add some refractoring
rady-ben Sep 17, 2021
38a50b7
add submit button tests
rady-ben Sep 17, 2021
e6a728f
bompete the submit button test
rady-ben Sep 17, 2021
d315b4f
test block editable and preview button of the fileCard componenent
rady-ben Sep 22, 2021
7bc1e4c
add the unit tests of the save button
rady-ben Sep 22, 2021
2560b2d
fix duplicated disable attribute
rady-ben Sep 22, 2021
57cb5be
test if save button is enable/disable according to the given permition
rady-ben Sep 22, 2021
d71089b
add delete button unit test
rady-ben Sep 23, 2021
ac8269d
test the closeButton
rady-ben Sep 23, 2021
9182c90
add the File.context.test
rady-ben Sep 26, 2021
becd75d
update the script of lunching react testing library
rady-ben Sep 26, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions __mocks__/File.context.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React, {useContext} from "react";
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import { AuthenticationContextProvider, FileContextProvider, RepositoryContextProvider } from "../src";
import { FileContext } from '../src/components/file/File.context';



const FileContextCustomer = () => {
const fileContextValues = useContext(FileContext);
const fileContextKeysArray = Object.keys(fileContextValues);

return(
<div
data-testid="test"
>
{
fileContextKeysArray.map((key)=>(`${key}/`))
}
</div>
)
}




describe('FileContextProvider', () => {
test('FileContextProvider renders correctly', () => {
render(
<AuthenticationContextProvider>
<RepositoryContextProvider
onRepository={()=>{}}
>
<FileContextProvider>
<FileContextCustomer text="text" data-testid="test"/>
</FileContextProvider>
</RepositoryContextProvider>
</AuthenticationContextProvider>
);
const test = screen.getByTestId('test');
expect(test).toHaveTextContent('state/stateValues/actions/component/components/config');
});
})
270 changes: 270 additions & 0 deletions __mocks__/FileCard.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
import React from "react";
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import FileCard from '../src/components/file/FileCard';
import { checkProps } from './testUtils';




jest.mock('markdown-translatable/dist/components/block-editable/BlockEditable', () =>
({markdown, onEdit, editable}) => (
<input
data-testid="blockEditable"
value={markdown}
onChange={(event) => {
if(editable){
onEdit(event.target.value)
}
}}
readOnly
/>
));




const defaultProps = {
repository: {
owner: {
username: 'username',
avatar_url: 'avatar_url',
},
name: 'name',
avatar_url: 'avatar_url',
permissions: {
push: true,
},
full_name: 'full_name',
default_branch: 'default_branch'
},
file:{
name: 'file.name',
path: 'file.path',
sha: 'file.sha',
content: 'file.content',
branch: 'file.branch',
filepath: 'filepath',
save: () => {},
dangerouslyDelete: () => {},
close: () => {}
},
isAuthenticated: true
}


test('FileForm PropTypes', () => {
const conformingProps = {
repository: {
owner: {
username: 'username',
avatar_url: 'avatar_url',
},
name: 'name',
avatar_url: 'avatar_url',
permissions: {
push: true,
},
full_name: 'full_name',
default_branch: 'default_branch'
},
file:{
name: 'file.name',
path: 'file.path',
sha: 'file.sha',
content: 'file.content',
branch: 'file.branch',
filepath: 'filepath',
save: () => {},
dangerouslyDelete: () => {},
close: () => {}
},
isAuthenticated: true,
}
checkProps(FileCard, conformingProps);
});

describe('cardHeader',() => {
test('cardHeader is inside the document and visible', () => {
render(<FileCard {...defaultProps} />);
const cardHeader = screen.getByTestId('cardHeader');
expect(cardHeader).toBeInTheDocument();
expect(cardHeader).toBeVisible();
});
})

describe('blockEditable', () => {
test('blockEditable is inside the document', () => {
render(<FileCard {...defaultProps} />);
const blockEditable = screen.getByTestId('blockEditable');
expect(blockEditable).toBeInTheDocument();
});

test('blockEditable is editable when user is authenticated', () => {
render(<FileCard {...defaultProps} />);
const blockEditable = screen.getByTestId('blockEditable');
fireEvent.change(blockEditable, {target: {value: 'changed text'}});
expect(blockEditable.value).toBe('changed text');
});

test('blockEditable is not editable when user is not authenticated', () => {
const updatedProps = {...defaultProps, isAuthenticated: false}
render(<FileCard {...updatedProps} />);
const blockEditable = screen.getByTestId('blockEditable');
fireEvent.change(blockEditable, {target: {value: 'changed text'}});
expect(blockEditable.value).toBe(defaultProps.file.content);
});
})

describe('previewButton', () => {
test('previewButton is inside the document and visible', () => {
render(<FileCard {...defaultProps} />);
const previewButton = screen.getByTestId('previewButton');
expect(previewButton).toBeInTheDocument();
expect(previewButton).toBeVisible();
});
})

describe('previewIcon', () => {
test('Initially previewIconOutlined is inside the document and visible and previewIcon is not', () => {
render(<FileCard {...defaultProps} />);
const previewIconOutlined = screen.queryByTestId('previewIconOutlined');
expect(previewIconOutlined).toBeInTheDocument();
expect(previewIconOutlined).toBeVisible();
const previewIcon = screen.queryByTestId('previewIcon');
expect(previewIcon).toBeNull();
});

test('switch from previewIconOutlined to previewIcon and vice versa', () => {
render(<FileCard {...defaultProps} />);
const previewButton = screen.getByTestId('previewButton');
fireEvent.click(previewButton)
let previewIconOutlined = screen.queryByTestId('previewIconOutlined');
expect(previewIconOutlined).toBeNull();
let previewIcon = screen.queryByTestId('previewIcon');
expect(previewIcon).toBeInTheDocument();
expect(previewIcon).toBeVisible();
fireEvent.click(previewButton)
previewIconOutlined = screen.queryByTestId('previewIconOutlined');
expect(previewIconOutlined).toBeInTheDocument();
expect(previewIconOutlined).toBeVisible();
previewIcon = screen.queryByTestId('previewIcon');
expect(previewIcon).toBeNull();
});
})

describe('saveButton', () => {
test('saveButton is inside the document and visible and disabled initialy', () => {
render(<FileCard {...defaultProps} />);
const saveButton = screen.getByTestId('saveButton');
expect(saveButton).toBeInTheDocument();
expect(saveButton).toBeVisible();
expect(saveButton).toBeDisabled();
});

test('switch saveButton from enable to disable and vice versa', () => {
render(<FileCard {...defaultProps} />);
const blockEditable = screen.getByTestId('blockEditable');
fireEvent.change(blockEditable, {target: {value: 'changed text'}});
let saveButton = screen.getByTestId('saveButton');
expect(saveButton).toBeEnabled();
fireEvent.change(blockEditable, {target: {value: defaultProps.file.content}});
saveButton = screen.getByTestId('saveButton');
expect(saveButton).toBeDisabled();
});

test('saveButton is enabled when the text change and the push permission is granted', () => {
render(<FileCard {...defaultProps} />);
const blockEditable = screen.getByTestId('blockEditable');
fireEvent.change(blockEditable, {target: {value: 'changed text'}});
const saveButton = screen.getByTestId('saveButton');
expect(saveButton).toBeEnabled();
});

test('saveButton is disabled whenpush permission is not granted event it the text change or not', () => {
const updatedProps = {
...defaultProps,
repository: {...defaultProps.repository,
permissions: {
...defaultProps.repository.permissions, push: false
}
}
}
render(<FileCard {...updatedProps} />);
const saveButton = screen.getByTestId('saveButton');
expect(saveButton).toBeDisabled();
const blockEditable = screen.getByTestId('blockEditable');
fireEvent.change(blockEditable, {target: {value: 'changed text'}});
expect(saveButton).toBeDisabled();
});


})

describe('saveIcon', () => {
test('Initially saveIconOutlined is inside the document and visible and saveIcon is not', () => {
render(<FileCard {...defaultProps} />);
const saveIconOutlined = screen.queryByTestId('saveIconOutlined');
expect(saveIconOutlined).toBeInTheDocument();
expect(saveIconOutlined).toBeVisible();
const saveIcon = screen.queryByTestId('saveIcon');
expect(saveIcon).toBeNull();
});

test('switch from saveIconOutlined to saveIcon and vice versa', () => {
render(<FileCard {...defaultProps} />);
const blockEditable = screen.getByTestId('blockEditable');
fireEvent.change(blockEditable, {target: {value: 'changed text'}});
let saveIconOutlined = screen.queryByTestId('saveIconOutlined');
expect(saveIconOutlined).toBeNull();
let saveIcon = screen.queryByTestId('saveIcon');
expect(saveIcon).toBeInTheDocument();
expect(saveIcon).toBeVisible();
fireEvent.change(blockEditable, {target: {value: defaultProps.file.content}});
saveIconOutlined = screen.queryByTestId('saveIconOutlined');
expect(saveIconOutlined).toBeInTheDocument();
expect(saveIconOutlined).toBeVisible();
saveIcon = screen.queryByTestId('saveIcon');
expect(saveIcon).toBeNull();
});
})


describe('Delete button', () => {
test('Delete button is inside the document and visible', () => {
render(<FileCard {...defaultProps} />);
const deleteButton = screen.queryByTestId('deleteButton');
expect(deleteButton).toBeInTheDocument();
expect(deleteButton).toBeVisible();
});

test('Delete button is enabled when push permissions is granted', () => {
render(<FileCard {...defaultProps} />);
const deleteButton = screen.queryByTestId('deleteButton');
expect(deleteButton).toBeEnabled();
});

test('Delete button is disabled when push permissions is not granted', () => {
const updatedProps = {
...defaultProps,
repository: {...defaultProps.repository,
permissions: {
...defaultProps.repository.permissions, push: false
}
}
}
render(<FileCard {...updatedProps} />);
const deleteButton = screen.queryByTestId('deleteButton');
expect(deleteButton).toBeDisabled();
});
})

describe('closeButton', () => {
test('closeButton is inside the document and visible and enabled', () => {
render(<FileCard {...defaultProps} />);
const closeButton = screen.queryByTestId('closeButton');
expect(closeButton).toBeInTheDocument();
expect(closeButton).toBeVisible();
expect(closeButton).toBeEnabled();
});
})
93 changes: 93 additions & 0 deletions __mocks__/FileForm.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React from "react";
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import FileForm from '../src/components/file/FileForm';
import { checkProps } from './testUtils';

const defaultProps = { onSubmit: () => {} }

// render tests
describe('TextFields',() => {
test('TextFields are inside the document', () => {
render(<FileForm {...defaultProps} />);
const branchTextField = screen.getByTestId('branch-textField');
expect(branchTextField).toBeInTheDocument();

const filepathTextField = screen.getByTestId('filepath-textField');
expect(filepathTextField).toBeInTheDocument();

const defaultContentTextField = screen.getByTestId('defaultContent-textField');
expect(defaultContentTextField).toBeInTheDocument();
});

test('TextFields are visible', () => {
render(<FileForm {...defaultProps} />);
const branchTextField = screen.getByTestId('branch-textField');
expect(branchTextField).toBeVisible();

const filepathTextField = screen.getByTestId('filepath-textField');
expect(filepathTextField).toBeVisible();

const defaultContentTextField = screen.getByTestId('defaultContent-textField');
expect(defaultContentTextField).toBeVisible();
});

test('TextFields handle input change correctly', () => {
render(<FileForm {...defaultProps} />);
const branchTextField = screen.getByTestId('branch-textField');
fireEvent.change(branchTextField, {target: {value: 'branch'}});
expect(branchTextField.value).toBe('branch');

const filepathTextField = screen.getByTestId('filepath-textField');
fireEvent.change(filepathTextField, {target: {value: 'filepath'}});
expect(filepathTextField.value).toBe('filepath');

const defaultContentTextField = screen.getByTestId('defaultContent-textField');
fireEvent.change(defaultContentTextField, {target: {value: 'defaultContent'}});
expect(defaultContentTextField.value).toBe('defaultContent');
});
});

describe('submit button',() => {
test('submit button is inside the document', () => {
render(<FileForm {...defaultProps} />);
const button = screen.getByTestId('button');
expect(button).toBeInTheDocument();
});
test('submit button is visible', () => {
render(<FileForm {...defaultProps} />);
const button = screen.getByTestId('button');
expect(button).toBeVisible();
});
test('submit button is disabled initially ', () => {
render(<FileForm {...defaultProps} />);
const button = screen.getByTestId('button');
expect(button).toBeDisabled();
});
test('submit button enabled/disable according to the input value of the branch and the filePath', () => {
render(<FileForm {...defaultProps} />);
const button = screen.getByTestId('button');
const branchTextField = screen.getByTestId('branch-textField');
const filepathTextField = screen.getByTestId('filepath-textField');
fireEvent.change(filepathTextField, {target: {value: 'filepath'}});
fireEvent.change(branchTextField, {target: {value: 'branch'}});
expect(button).toBeEnabled();
fireEvent.change(filepathTextField, {target: {value: ''}});
expect(button).toBeDisabled();
fireEvent.change(branchTextField, {target: {value: 'branch'}});
fireEvent.change(filepathTextField, {target: {value: ''}});
expect(button).toBeDisabled();
});
});

// PropTypes tests
test('FileForm PropTypes', () => {
const conformingProps = {
submitText: "text",
onSubmit: () => {},
branch: 'branch',
filepath: 'filepath',
defaultContent: 'defaultContent',
}
checkProps(FileForm, conformingProps)
});
2 changes: 2 additions & 0 deletions __mocks__/fileMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module.exports = 'test-file-stub';
import '@testing-library/jest-dom'
12 changes: 12 additions & 0 deletions __mocks__/testUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import checkPropTypes from 'check-prop-types';

export const findByAttribute = (wrapper, attribute) => wrapper.find(`[data-test='${attribute}']`)

export const checkProps = (component, conformingProps) => {
const propError = checkPropTypes(
component.propTypes,
conformingProps,
'prop',
component.name);
expect(propError).toBeUndefined();
}
10 changes: 10 additions & 0 deletions jest.enzyme.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
'roots': [
'<rootDir>/__mocks__',
],
'moduleNameMapper': {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less)$": "identity-obj-proxy"
},
setupFilesAfterEnv: ['<rootDir>/__mocks__/fileMock']
};
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@
"test:e2e": "NODE_ENV=test start-test 6060 cypress:run && nyc report --reporter=json-summary",
"test:unit": "NODE_ENV=test jest ./src/core --coverage && cat ./coverage/lcov.info | coveralls",
"test": "nyc --exclude-after-remap=false npm run test:e2e",
"testJestReactTestingLibrary": "jest --watch -c ./jest.enzyme.config.js --verbose",
"create-coverage-badge": "bash scripts/create-badge-json.sh"
},
"browserslist": [
@@ -55,6 +56,10 @@
"@istanbuljs/nyc-config-typescript": "0.1.3",
"@material-ui/core": "^4.7.0",
"@material-ui/icons": "^4.9.1",
"@testing-library/dom": "^8.5.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.1.0",
"@testing-library/user-event": "^13.2.1",
"@types/base-64": "0.1.3",
"@types/cypress": "1.1.3",
"@types/jest": "^25.2.1",
@@ -66,14 +71,18 @@
"babel-jest": "24.9.0",
"babel-loader": "^8.0.6",
"babel-plugin-istanbul": "6.0.0",
"check-prop-types": "^1.1.2",
"coveralls": "3.0.7",
"cypress": "^6.8.0",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.6",
"eslint": "6.6.0",
"eslint-config-prettier": "6.5.0",
"eslint-plugin-chai-friendly": "0.5.0",
"eslint-plugin-cypress": "^2.11.1",
"eslint-plugin-mdx": "1.0.1",
"eslint-plugin-react": "7.19.0",
"identity-obj-proxy": "^3.0.0",
"istanbul-lib-coverage": "2.0.5",
"jest": "24.9.0",
"lorem-ipsum": "2.0.1",
53 changes: 38 additions & 15 deletions src/components/file/FileCard.js
Original file line number Diff line number Diff line change
@@ -22,54 +22,71 @@ const useStyles = makeStyles(theme => ({
}));

function FileCard({
authentication,
isAuthenticated,
repository,
file,
}) {
const classes = useStyles();
const [preview, setPreview] = useState(true);
const [markdown, setMarkdown] = useState(file ? file.content : '');
const [markdown, setMarkdown] = useState('');
const changed = (markdown !== (file && file.content));
const avatarUrl = repository.avatar_url || repository.owner.avatar_url;
const access = repository.permissions.push;

useEffect(() => {
setMarkdown(file && file.content);
setMarkdown(file && file.content ? file.content : '');
}, [file]);

const branch = (file && file.branch) ? file.branch : repository.default_branch;

return (
<Card>
<Card
data-testid="component-fileCard"
>
<CardHeader
avatar={<Avatar src={avatarUrl} />}
title={<strong>{file && file.path}</strong>}
subheader={repository.full_name + '/' + branch}
data-testid="cardHeader"
/>
<CardContent>
<Paper>
<Paper data-testid="BlockEditable">
<BlockEditable
preview={preview}
markdown={markdown}
onEdit={setMarkdown}
editable={!!authentication}
editable={isAuthenticated}
/>
</Paper>
</CardContent>
<CardActions>
<div className={classes.actions}>
<IconButton className={classes.action} aria-label="Preview" onClick={() => setPreview(!preview)}>
{!preview ? <Pageview /> : <PageviewOutlined />}
<IconButton
className={classes.action}
aria-label="Preview"
onClick={() => setPreview(!preview)}
data-testid="previewButton"
>
{
!preview ?
<Pageview data-testid="previewIcon"/> :
<PageviewOutlined data-testid="previewIconOutlined"/>
}
</IconButton>
<IconButton
className={classes.action}
aria-label="Save"
disabled={!access}
disabled={!access || !changed}
onClick={() => {
if (changed) file.save(markdown);
}}
data-testid="saveButton"
>
{changed ? <Save /> : <SaveOutlined />}
{
changed ?
<Save data-testid="saveIcon" /> :
<SaveOutlined data-testid="saveIconOutlined" />
}
</IconButton>
<IconButton
className={classes.action}
@@ -82,12 +99,14 @@ function FileCard({

if (confirmation) file.dangerouslyDelete();
}}
data-testid="deleteButton"
>
<DeleteSweepOutlined />
</IconButton>
<IconButton
title="Close Repository"
onClick={file.close}
data-testid="closeButton"
>
<CancelOutlined />
</IconButton>
@@ -106,6 +125,11 @@ FileCard.propTypes = {
}),
name: PropTypes.string.isRequired,
avatar_url: PropTypes.string,
permissions: PropTypes.shape({
push: PropTypes.bool,
}).isRequired,
full_name: PropTypes.string.isRequired,
default_branch: PropTypes.string.isRequired,
}).isRequired,
/** Pass a previously returned file object to bypass the selection. */
file: PropTypes.shape({
@@ -115,13 +139,12 @@ FileCard.propTypes = {
content: PropTypes.string,
branch: PropTypes.string,
filepath: PropTypes.string,
save: PropTypes.func.isRequired,
dangerouslyDelete: PropTypes.func.isRequired,
close: PropTypes.func.isRequired
}),
/** Pass a previously returned authentication object to bypass login. */
authentication: PropTypes.shape({
user: PropTypes.object.isRequired,
token: PropTypes.object.isRequired,
config: PropTypes.object.isRequired,
}),
isAuthenticated: PropTypes.bool,
};

export default FileCard;
13 changes: 11 additions & 2 deletions src/components/file/FileForm.js
Original file line number Diff line number Diff line change
@@ -17,28 +17,34 @@ function FileForm({
const disabled = !(filepath);

return (
<Paper style={{ marginBottom: '1em', padding: '1.3em' }}>
<Paper
style={{ marginBottom: '1em', padding: '1.3em' }}
>
<form>
<button type="submit" disabled style={{ display: 'none' }} aria-hidden="true"></button>
<TextField
name='branch' label='branch' type='text' autoComplete={null}
variant="outlined" margin="normal" fullWidth defaultValue={branch}
variant="outlined" margin="normal" fullWidth defaultValue={'branch'}
onChange={(e) => setBranch(e.target.value)}
inputProps={{ "data-testid": "branch-textField" }}
/>
<TextField
name='filepath' label='filepath' type='text' autoComplete={null}
variant="outlined" margin="normal" fullWidth defaultValue={filepath}
onChange={(e) => setFilepath(e.target.value)}
inputProps={{ "data-testid": "filepath-textField" }}
/>
<TextField
name='defaultContent' label='defaultContent' type='text' multiline={true} autoComplete={null}
variant="outlined" margin="normal" fullWidth defaultValue={defaultContent}
onChange={(e) => setDefaultContent(e.target.value)}
inputProps={{ "data-testid": "defaultContent-textField" }}
/>
<Button type="button" disabled={disabled} fullWidth variant="contained" color="primary"
onClick={() => onSubmit({
branch, filepath, defaultContent,
})}
data-testid="button"
>
{submitText}
</Button>
@@ -52,6 +58,9 @@ FileForm.propTypes = {
submitText: PropTypes.string,
/** Function run when submit button is clicked */
onSubmit: PropTypes.func.isRequired,
branch: PropTypes.string,
filepath: PropTypes.string,
defaultContent: PropTypes.string,
};

FileForm.defaultProps = { submitText: 'Submit' };
4 changes: 2 additions & 2 deletions src/components/file/useFile.js
Original file line number Diff line number Diff line change
@@ -60,7 +60,7 @@ function useFile({

useEffect(() => {
setIsChanged(false);
}, [file, deleted, closed]);
}, [file, deleted]);

const read = useCallback(async (_filepath) => {
if (onFilepath) {
@@ -187,7 +187,7 @@ function useFile({
browse: repository && blobComponents.browse,
fileCard: repository && file && (
<FileCard
authentication={authentication}
authentication={Object.keys(authentication).length === 0}
repository={repository}
file={{ ...file, ...actions }}
/>
632 changes: 625 additions & 7 deletions yarn.lock

Large diffs are not rendered by default.