-
Notifications
You must be signed in to change notification settings - Fork 305
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
feat(content-sidebar): disable version modifications for archive file #3637
Changes from 9 commits
a6e56d9
9fbdfc7
ea10fee
08ab0b1
c2c76f3
07843c6
fc18385
1dcc7c6
37e767c
c0d4e86
2ac32fb
56896b1
6aa0f8f
df0645e
4e21d1c
da95adf
140a7e1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,18 +12,22 @@ import noop from 'lodash/noop'; | |
import { generatePath, withRouter } from 'react-router-dom'; | ||
import type { Match, RouterHistory } from 'react-router-dom'; | ||
import type { MessageDescriptor } from 'react-intl'; | ||
import { withFeatureConsumer, isFeatureEnabled } from '../../common/feature-checking'; | ||
import API from '../../../api'; | ||
import { FIELD_METADATA_ARCHIVE } from '../../../constants'; | ||
import messages from './messages'; | ||
import openUrlInsideIframe from '../../../utils/iframe'; | ||
import StaticVersionsSidebar from './StaticVersionSidebar'; | ||
import VersionsSidebar from './VersionsSidebar'; | ||
import VersionsSidebarAPI from './VersionsSidebarAPI'; | ||
import { withAPIContext } from '../../common/api-context'; | ||
import type { FeatureConfig } from '../../common/feature-checking'; | ||
import type { VersionActionCallback, VersionChangeCallback, SidebarLoadCallback } from './flowTypes'; | ||
import type { BoxItemVersion, BoxItem, FileVersions } from '../../../common/types/core'; | ||
|
||
type Props = { | ||
api: API, | ||
features: FeatureConfig, | ||
fileId: string, | ||
hasSidebarInitialized?: boolean, | ||
history: RouterHistory, | ||
|
@@ -43,6 +47,7 @@ type Props = { | |
type State = { | ||
error?: MessageDescriptor, | ||
isLoading: boolean, | ||
isArchiveFile: boolean, | ||
isWatermarked: boolean, | ||
versionCount: number, | ||
versionLimit: number, | ||
|
@@ -66,6 +71,7 @@ class VersionsSidebarContainer extends React.Component<Props, State> { | |
props: Props; | ||
|
||
state: State = { | ||
isArchiveFile: false, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor, but consider There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated |
||
isLoading: true, | ||
isWatermarked: false, | ||
versionCount: Infinity, | ||
|
@@ -168,16 +174,18 @@ class VersionsSidebarContainer extends React.Component<Props, State> { | |
handleFetchError = (): void => { | ||
this.setState({ | ||
error: messages.versionFetchError, | ||
isArchiveFile: false, | ||
isLoading: false, | ||
isWatermarked: false, | ||
versionCount: 0, | ||
versions: [], | ||
}); | ||
}; | ||
|
||
handleFetchSuccess = ([fileResponse, versionsResponse]): [BoxItem, FileVersions] => { | ||
handleFetchSuccess = ([fileResponse, versionsResponse]: [BoxItem, FileVersions]): [BoxItem, FileVersions] => { | ||
const { api } = this.props; | ||
const { version_limit } = fileResponse; | ||
const isArchiveFile = !!getProp(fileResponse, FIELD_METADATA_ARCHIVE); | ||
const isWatermarked = getProp(fileResponse, 'watermark_info.is_watermarked', false); | ||
const versionLimit = version_limit !== null && version_limit !== undefined ? version_limit : Infinity; | ||
const versionsWithPermissions = api.getVersionsAPI(false).addPermissions(versionsResponse, fileResponse) || {}; | ||
|
@@ -186,6 +194,7 @@ class VersionsSidebarContainer extends React.Component<Props, State> { | |
this.setState( | ||
{ | ||
error: undefined, | ||
isArchiveFile, | ||
isLoading: false, | ||
isWatermarked, | ||
versionCount, | ||
|
@@ -207,14 +216,14 @@ class VersionsSidebarContainer extends React.Component<Props, State> { | |
}; | ||
|
||
initialize = (): void => { | ||
this.api = new VersionsSidebarAPI(this.props); | ||
const { api, features, fileId }: Props = this.props; | ||
const isArchiveFeatureEnabled = isFeatureEnabled(features, 'contentSidebar.archive.enabled'); | ||
|
||
this.api = new VersionsSidebarAPI({ api, fileId, isArchiveFeatureEnabled }); | ||
}; | ||
|
||
fetchData = (): Promise<?[BoxItem, FileVersions]> => { | ||
return this.api | ||
.fetchData() | ||
.then(this.handleFetchSuccess) | ||
.catch(this.handleFetchError); | ||
return this.api.fetchData().then(this.handleFetchSuccess).catch(this.handleFetchError); | ||
}; | ||
|
||
findVersion = (versionId: ?string): ?BoxItemVersion => { | ||
|
@@ -299,4 +308,5 @@ class VersionsSidebarContainer extends React.Component<Props, State> { | |
} | ||
|
||
export type VersionsSidebarProps = Props; | ||
export default flow([withRouter, withAPIContext])(VersionsSidebarContainer); | ||
export { VersionsSidebarContainer as VersionsSidebarContainerComponent }; | ||
export default flow([withRouter, withAPIContext, withFeatureConsumer])(VersionsSidebarContainer); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -238,5 +238,111 @@ describe('elements/content-sidebar/versions/VersionsItem', () => { | |
expect(wrapper.exists(VersionsItemRetention)).toBe(true); | ||
expect(wrapper.find(VersionsItemActions).prop('isRetained')).toBe(true); | ||
}); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you please rewrite those test to use React Testing Library. Enzyme is a huge problem in EUA and we need to slowly convert existing tests instead of creating new ones. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated whole file to RTL |
||
test.each` | ||
permissions | ||
${{ can_delete: true, can_download: true, can_preview: true, can_upload: true }} | ||
${{ can_delete: true, can_download: true, can_preview: true, can_upload: false }} | ||
${{ can_delete: true, can_download: true, can_preview: false, can_upload: true }} | ||
${{ can_delete: true, can_download: false, can_preview: true, can_upload: true }} | ||
${{ can_delete: false, can_download: true, can_preview: true, can_upload: true }} | ||
${{ can_delete: true, can_download: true, can_preview: false, can_upload: false }} | ||
${{ can_delete: true, can_download: false, can_preview: true, can_upload: false }} | ||
${{ can_delete: false, can_download: true, can_preview: true, can_upload: false }} | ||
${{ can_delete: false, can_download: true, can_preview: false, can_upload: true }} | ||
${{ can_delete: false, can_download: false, can_preview: true, can_upload: true }} | ||
${{ can_delete: false, can_download: true, can_preview: false, can_upload: false }} | ||
${{ can_delete: false, can_download: false, can_preview: true, can_upload: false }} | ||
`('should disable the correct menu items based on permissions when is archive file', ({ permissions }) => { | ||
const wrapper = getWrapper({ | ||
version: getVersion({ permissions }), | ||
isArchiveFile: true, | ||
}); | ||
const actions = wrapper.find(VersionsItemActions); | ||
const button = wrapper.find(VersionsItemButton); | ||
|
||
expect(button.prop('isDisabled')).toBe(!permissions.can_preview); | ||
expect(actions.prop('showDelete')).toBe(false); | ||
expect(actions.prop('showDownload')).toBe(permissions.can_download); | ||
expect(actions.prop('showPromote')).toBe(false); | ||
expect(actions.prop('showPreview')).toBe(permissions.can_preview); | ||
expect(wrapper.find(ReadableTime)).toBeTruthy(); | ||
}); | ||
|
||
test.each` | ||
permissions | ||
${{ can_delete: true, can_download: false, can_preview: false, can_upload: true }} | ||
${{ can_delete: true, can_download: false, can_preview: false, can_upload: false }} | ||
${{ can_delete: false, can_download: false, can_preview: false, can_upload: true }} | ||
${{ can_delete: false, can_download: false, can_preview: false, can_upload: false }} | ||
`('should not render actions based on permissions when is archive file', ({ permissions }) => { | ||
const wrapper = getWrapper({ | ||
version: getVersion({ permissions }), | ||
isArchiveFile: true, | ||
}); | ||
const actions = wrapper.exists(VersionsItemActions); | ||
const button = wrapper.find(VersionsItemButton); | ||
|
||
expect(button.prop('isDisabled')).toBe(!permissions.can_preview); | ||
expect(actions).toBeFalsy(); | ||
expect(wrapper.find(ReadableTime)).toBeTruthy(); | ||
}); | ||
|
||
test.each` | ||
action | showDelete | showDownload | showPreview | showPromote | showRestore | ||
${'restore'} | ${false} | ${true} | ${true} | ${false} | ${false} | ||
${'upload'} | ${false} | ${true} | ${true} | ${false} | ${false} | ||
`( | ||
"should show actions correctly when the version's action is $action and is archive file", | ||
({ action, showDelete, showDownload, showPreview, showPromote, showRestore }) => { | ||
selectors.getVersionAction.mockReturnValueOnce(action); | ||
|
||
const wrapper = getWrapper({ | ||
version: getVersion({ | ||
permissions: { | ||
can_delete: true, | ||
can_download: true, | ||
can_preview: true, | ||
can_upload: true, | ||
}, | ||
}), | ||
isArchiveFile: true, | ||
}); | ||
const actions = wrapper.find(VersionsItemActions); | ||
const button = wrapper.find(VersionsItemButton); | ||
|
||
expect(button.prop('isDisabled')).toBe(!showPreview); | ||
expect(actions.prop('showDelete')).toBe(showDelete); | ||
expect(actions.prop('showDownload')).toBe(showDownload); | ||
expect(actions.prop('showPromote')).toBe(showPromote); | ||
expect(actions.prop('showPreview')).toBe(showPreview); | ||
expect(actions.prop('showRestore')).toBe(showRestore); | ||
expect(wrapper.find(ReadableTime)).toBeTruthy(); | ||
expect(wrapper).toMatchSnapshot(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We generally want to avoid adding new snapshot tests, especially for larger components. Let's rely on explicit assertions, instead. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've moved all the tests for this component to react-testing-library, so I removed snapshots completely there |
||
}, | ||
); | ||
|
||
test("should not show actions when the version's action is delete and unchangeableVersions feature is enabled", () => { | ||
selectors.getVersionAction.mockReturnValueOnce('delete'); | ||
|
||
const wrapper = getWrapper({ | ||
version: getVersion({ | ||
permissions: { | ||
can_delete: true, | ||
can_download: true, | ||
can_preview: true, | ||
can_upload: true, | ||
}, | ||
}), | ||
isArchiveFile: true, | ||
}); | ||
const actions = wrapper.exists(VersionsItemActions); | ||
const button = wrapper.find(VersionsItemButton); | ||
|
||
expect(button.prop('isDisabled')).toBe(true); | ||
expect(actions).toBeFalsy(); | ||
expect(wrapper.find(ReadableTime)).toBeTruthy(); | ||
expect(wrapper).toMatchSnapshot(); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ import * as React from 'react'; | |
import { shallow } from 'enzyme/build'; | ||
import messages from '../messages'; | ||
import openUrlInsideIframe from '../../../../utils/iframe'; | ||
import VersionsSidebar from '../VersionsSidebarContainer'; | ||
import { VersionsSidebarContainerComponent } from '../VersionsSidebarContainer'; | ||
|
||
jest.mock('react-router-dom', () => ({ | ||
...jest.requireActual('react-router-dom'), | ||
|
@@ -32,7 +32,8 @@ describe('elements/content-sidebar/versions/VersionsSidebarContainer', () => { | |
const api = { | ||
getVersionsAPI: () => versionsAPI, | ||
}; | ||
const getWrapper = ({ ...props } = {}) => shallow(<VersionsSidebar api={api} fileId="12345" {...props} />); | ||
const getWrapper = ({ ...props } = {}) => | ||
shallow(<VersionsSidebarContainerComponent api={api} fileId="12345" {...props} />); | ||
|
||
describe('componentDidUpdate', () => { | ||
let onVersionChange; | ||
|
@@ -245,6 +246,7 @@ describe('elements/content-sidebar/versions/VersionsSidebarContainer', () => { | |
expect(instance.sortVersions).toBeCalledWith(versionsWithCurrent.entries); | ||
expect(wrapper.state()).toMatchObject({ | ||
error: undefined, | ||
isArchiveFile: false, | ||
isLoading: false, | ||
isWatermarked: false, | ||
versionCount: 2, | ||
|
@@ -263,6 +265,17 @@ describe('elements/content-sidebar/versions/VersionsSidebarContainer', () => { | |
|
||
expect(wrapper.state('isWatermarked')).toBe(true); | ||
}); | ||
|
||
test('should set state with isArchiveFile if file is archive file', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel this file is too complicated to switch whole of it from enzyme to RTL in scope of this PR. I have RTL implementation for new tests (added to tests this PR code changes), but I'm working on putting it alongside enzyme in this file. I'm having trouble, because some module mocks needed for RTL are breaking enzyme tests and vice versa There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved this test case to new file using RTL |
||
const wrapper = getWrapper(); | ||
const instance = wrapper.instance(); | ||
const testFile = { ...file, metadata: { global: { archivedItemTemplate: { archiveDate: '1726832355' } } } }; | ||
|
||
instance.verifyVersion = jest.fn(); | ||
instance.handleFetchSuccess([testFile, versionsWithCurrent]); | ||
|
||
expect(wrapper.state('isArchiveFile')).toBe(true); | ||
}); | ||
}); | ||
|
||
describe('findVersion', () => { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor, but we should alphabetize props and object properties when possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated