Skip to content

Commit bbe7b0c

Browse files
authored
Merge pull request #1393 from guardian/pf/disable-delete-button-when-processing
Disable delete button when processing, and fix update after upload
2 parents 376779c + 00c5075 commit bbe7b0c

File tree

7 files changed

+276
-228
lines changed

7 files changed

+276
-228
lines changed

public/video-ui/src/components/DeleteButton.jsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import React from 'react';
21
import PropTypes from 'prop-types';
2+
import React from 'react';
33
import ReactTooltip from 'react-tooltip';
44
import Icon from './Icon';
55

66
export default class DeleteButton extends React.Component {
77
static propTypes = {
88
tooltip: PropTypes.string.isRequired,
9-
onDelete: PropTypes.func.isRequired
9+
onDelete: PropTypes.func.isRequired,
10+
disabled: PropTypes.bool,
11+
tooltipWhenDisabled: PropTypes.string
1012
};
1113

1214
state = {
@@ -28,6 +30,7 @@ export default class DeleteButton extends React.Component {
2830
onClick={this.props.onDelete}
2931
data-tip="Confirm delete. This cannot be undone."
3032
data-testid="delete-button"
33+
disabled={this.props.disabled}
3134
>
3235
<Icon icon="delete_forever">Confirm delete</Icon>
3336
</button>
@@ -39,8 +42,13 @@ export default class DeleteButton extends React.Component {
3942
<button
4043
className="btn button__secondary--remove"
4144
onClick={() => this.changeState()}
42-
data-tip={this.props.tooltip}
45+
data-tip={
46+
this.props.disabled
47+
? (this.props.tooltipWhenDisabled ?? this.props.tooltip)
48+
: this.props.tooltip
49+
}
4350
data-testid="delete-button"
51+
disabled={this.props.disabled}
4452
>
4553
<Icon icon="delete">Delete</Icon>
4654
</button>

public/video-ui/src/components/VideoUpload/VideoAsset.test.tsx

Lines changed: 88 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import React from 'react';
2-
import { render, screen } from '@testing-library/react';
31
import '@testing-library/jest-dom';
2+
import { render, screen } from '@testing-library/react';
43
import { userEvent } from '@testing-library/user-event';
5-
import { Asset } from './VideoAsset';
6-
import { setupStore } from '../../util/setupStore';
7-
import { setConfig } from '../../slices/config';
4+
import React from 'react';
85
import { Provider } from 'react-redux';
6+
import type { Video, Asset as VideoAsset } from '../../services/VideosApi';
7+
import { setConfig } from '../../slices/config';
8+
import { setVideo } from '../../slices/video';
9+
import { setupStore } from '../../util/setupStore';
910
import { setStore } from '../../util/storeAccessor';
11+
import { Asset } from './VideoAsset';
1012

1113
const defaultProps = {
1214
videoId: 'test-video-id',
@@ -19,13 +21,33 @@ const defaultProps = {
1921
activatingAssetNumber: undefined as number
2022
};
2123

24+
const defaultVideoAsset: VideoAsset = {
25+
version: 1,
26+
id: 'AAAAAAAAAAA',
27+
assetType: 'Video',
28+
mimeType: 'video/youtube',
29+
platform: 'Youtube'
30+
};
31+
2232
const store = setupStore();
2333
store.dispatch(
2434
setConfig({
2535
permissions: {},
2636
youtubeEmbedUrl: 'https://www.youtube.com/embed/'
2737
})
2838
);
39+
store.dispatch(
40+
setVideo({
41+
id: 'test-video-id',
42+
assets: [
43+
{
44+
...defaultVideoAsset,
45+
version: 1,
46+
id: 'AAAAAAAAAAA'
47+
}
48+
]
49+
} as Video)
50+
);
2951
setStore(store);
3052

3153
describe('VideoAsset', () => {
@@ -78,7 +100,9 @@ describe('VideoAsset', () => {
78100

79101
it('does not show activate button when asset is active', () => {
80102
render(
81-
<Asset {...defaultProps} upload={completedUpload} isActive={true} />
103+
<Provider store={store}>
104+
<Asset {...defaultProps} upload={completedUpload} isActive={true} />
105+
</Provider>
82106
);
83107

84108
expect(
@@ -88,7 +112,11 @@ describe('VideoAsset', () => {
88112
});
89113

90114
it('shows delete button when asset is not active', () => {
91-
render(<Asset {...defaultProps} upload={completedUpload} />);
115+
render(
116+
<Provider store={store}>
117+
<Asset {...defaultProps} upload={completedUpload} />
118+
</Provider>
119+
);
92120

93121
const deleteButton = screen.getByTestId('delete-button');
94122
expect(deleteButton).toBeInTheDocument();
@@ -112,8 +140,12 @@ describe('VideoAsset', () => {
112140
}
113141
};
114142

115-
it('renders processing asset with activate button disabled', () => {
116-
render(<Asset {...defaultProps} upload={processingUpload} />);
143+
it('renders processing asset with activate and delete buttons disabled', () => {
144+
render(
145+
<Provider store={store}>
146+
<Asset {...defaultProps} upload={processingUpload} />
147+
</Provider>
148+
);
117149

118150
// Check that progress bar is shown
119151
const progress = screen.getByRole('progressbar');
@@ -126,13 +158,24 @@ describe('VideoAsset', () => {
126158
expect(activateButton).toBeInTheDocument();
127159
expect(activateButton).toBeDisabled();
128160

161+
// Check that delete button is present but disabled
162+
const deleteButton = screen.getByRole('button', {
163+
name: 'delete Delete'
164+
});
165+
expect(deleteButton).toBeInTheDocument();
166+
expect(deleteButton).toBeDisabled();
167+
129168
// Check that processing status is displayed
130169
expect(screen.getByText('Uploading to YouTube')).toBeInTheDocument();
131170
});
132171

133172
it('does not call selectAsset when disabled activate button is clicked', async () => {
134173
const user = userEvent.setup();
135-
render(<Asset {...defaultProps} upload={processingUpload} />);
174+
render(
175+
<Provider store={store}>
176+
<Asset {...defaultProps} upload={processingUpload} />
177+
</Provider>
178+
);
136179

137180
const activateButton = screen.getByRole('button', { name: 'Activate' });
138181
await user.click(activateButton);
@@ -143,11 +186,13 @@ describe('VideoAsset', () => {
143186

144187
it('shows loading state when asset is currently being activated', () => {
145188
render(
146-
<Asset
147-
{...defaultProps}
148-
upload={processingUpload}
149-
activatingAssetNumber={2}
150-
/>
189+
<Provider store={store}>
190+
<Asset
191+
{...defaultProps}
192+
upload={processingUpload}
193+
activatingAssetNumber={2}
194+
/>
195+
</Provider>
151196
);
152197

153198
const activateButton = screen.getByRole('button', { name: 'Activate' });
@@ -163,7 +208,11 @@ describe('VideoAsset', () => {
163208
}
164209
};
165210

166-
render(<Asset {...defaultProps} upload={failedUpload} />);
211+
render(
212+
<Provider store={store}>
213+
<Asset {...defaultProps} upload={failedUpload} />
214+
</Provider>
215+
);
167216

168217
expect(screen.getByText('Upload Failed')).toBeInTheDocument();
169218

@@ -180,7 +229,11 @@ describe('VideoAsset', () => {
180229
}
181230
};
182231

183-
render(<Asset {...defaultProps} upload={unknownProgressUpload} />);
232+
render(
233+
<Provider store={store}>
234+
<Asset {...defaultProps} upload={unknownProgressUpload} />
235+
</Provider>
236+
);
184237

185238
// Should show spinner (loader class)
186239
expect(document.querySelector('.loader')).toBeInTheDocument();
@@ -195,24 +248,34 @@ describe('VideoAsset', () => {
195248
id: '2',
196249
asset: {
197250
sources: [
198-
{ src: "https://uploads.gu.com/test--264ef95d-ecb0-472e-9030-9e5ef678bf16-2.0.mp4", mimeType: "video/mp4" },
199-
{ src: "https://uploads.gu.com/test--264ef95d-ecb0-472e-9030-9e5ef678bf16-2.1.m3u8", mimeType: "application/vnd.apple.mpegurl" }
251+
{
252+
src: 'https://uploads.gu.com/test--264ef95d-ecb0-472e-9030-9e5ef678bf16-2.0.mp4',
253+
mimeType: 'video/mp4'
254+
},
255+
{
256+
src: 'https://uploads.gu.com/test--264ef95d-ecb0-472e-9030-9e5ef678bf16-2.1.m3u8',
257+
mimeType: 'application/vnd.apple.mpegurl'
258+
}
200259
]
201260
},
202261
processing: {
203-
status: "GetTranscodingProgressV2",
262+
status: 'GetTranscodingProgressV2',
204263
failed: false
205264
},
206265
metadata: {
207266
originalFilename: 'Video.mp4',
208267
startTimestamp: 1759499181730,
209-
subtitleFilename: "subtitle.srt",
268+
subtitleFilename: 'subtitle.srt',
210269
user: 'a.person@example.co.uk'
211270
}
212271
};
213272

214273
it('renders reprocessing asset with activate button disabled', () => {
215-
render(<Asset {...defaultProps} upload={reprocessingUpload} />);
274+
render(
275+
<Provider store={store}>
276+
<Asset {...defaultProps} upload={reprocessingUpload} />
277+
</Provider>
278+
);
216279

217280
// Should show spinner (loader class)
218281
expect(document.querySelector('.loader')).toBeInTheDocument();
@@ -228,7 +291,6 @@ describe('VideoAsset', () => {
228291
// Check that file name is displayed
229292
expect(screen.getByText('Asset 2 - Video.mp4')).toBeInTheDocument();
230293
});
231-
232294
});
233295

234296
it('returns null when upload has no asset or processing state', () => {
@@ -240,7 +302,9 @@ describe('VideoAsset', () => {
240302
};
241303

242304
const { container } = render(
243-
<Asset {...defaultProps} upload={emptyUpload} />
305+
<Provider store={store}>
306+
<Asset {...defaultProps} upload={emptyUpload} />
307+
</Provider>
244308
);
245309

246310
expect(container.firstChild).toBeNull();

0 commit comments

Comments
 (0)