mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-02-14 00:09:35 -06:00
Guard against stale ws events for version uploads
This commit is contained in:
@@ -1842,6 +1842,43 @@ describe('DocumentDetailComponent', () => {
|
|||||||
expect(errorSpy).toHaveBeenCalled()
|
expect(errorSpy).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should clear and isolate version upload state on document change', () => {
|
||||||
|
initNormally()
|
||||||
|
httpTestingController.expectOne(component.previewUrl).flush('preview')
|
||||||
|
|
||||||
|
component.versionUploadState = UploadState.Failed
|
||||||
|
component.versionUploadError = 'boom'
|
||||||
|
component.docChangeNotifier.next(999)
|
||||||
|
expect(component.versionUploadState).toBe(UploadState.Idle)
|
||||||
|
expect(component.versionUploadError).toBeNull()
|
||||||
|
|
||||||
|
const uploadSpy = jest.spyOn(documentService, 'uploadVersion')
|
||||||
|
const versionsSpy = jest.spyOn(documentService, 'getVersions')
|
||||||
|
const finished$ = new Subject<any>()
|
||||||
|
const failed$ = new Subject<any>()
|
||||||
|
jest
|
||||||
|
.spyOn(websocketStatusService, 'onDocumentConsumptionFinished')
|
||||||
|
.mockReturnValueOnce(finished$ as any)
|
||||||
|
jest
|
||||||
|
.spyOn(websocketStatusService, 'onDocumentConsumptionFailed')
|
||||||
|
.mockReturnValueOnce(failed$ as any)
|
||||||
|
|
||||||
|
uploadSpy.mockReturnValueOnce(of('task-stale'))
|
||||||
|
component.onVersionFileSelected({
|
||||||
|
target: createFileInput(
|
||||||
|
new File(['data'], 'version.pdf', { type: 'application/pdf' })
|
||||||
|
),
|
||||||
|
} as any)
|
||||||
|
expect(component.versionUploadState).toBe(UploadState.Processing)
|
||||||
|
|
||||||
|
component.docChangeNotifier.next(1000)
|
||||||
|
failed$.next({ taskId: 'task-stale', message: 'stale-error' })
|
||||||
|
|
||||||
|
expect(component.versionUploadState).toBe(UploadState.Idle)
|
||||||
|
expect(component.versionUploadError).toBeNull()
|
||||||
|
expect(versionsSpy).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
it('createDisabled should return true if the user does not have permission to add the specified data type', () => {
|
it('createDisabled should return true if the user does not have permission to add the specified data type', () => {
|
||||||
currentUserCan = false
|
currentUserCan = false
|
||||||
expect(component.createDisabled(DataType.Correspondent)).toBeTruthy()
|
expect(component.createDisabled(DataType.Correspondent)).toBeTruthy()
|
||||||
|
|||||||
@@ -674,6 +674,10 @@ export class DocumentDetailComponent
|
|||||||
this.loadDocument(documentId)
|
this.loadDocument(documentId)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.docChangeNotifier
|
||||||
|
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||||
|
.subscribe(() => this.clearVersionUploadStatus())
|
||||||
|
|
||||||
this.route.paramMap
|
this.route.paramMap
|
||||||
.pipe(takeUntil(this.unsubscribeNotifier))
|
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||||
.subscribe((paramMap) => {
|
.subscribe((paramMap) => {
|
||||||
@@ -1311,6 +1315,7 @@ export class DocumentDetailComponent
|
|||||||
onVersionFileSelected(event: Event) {
|
onVersionFileSelected(event: Event) {
|
||||||
const input = event.target as HTMLInputElement
|
const input = event.target as HTMLInputElement
|
||||||
if (!input?.files || input.files.length === 0) return
|
if (!input?.files || input.files.length === 0) return
|
||||||
|
const uploadDocumentId = this.documentId
|
||||||
const file = input.files[0]
|
const file = input.files[0]
|
||||||
// Reset input to allow re-selection of the same file later
|
// Reset input to allow re-selection of the same file later
|
||||||
input.value = ''
|
input.value = ''
|
||||||
@@ -1318,7 +1323,7 @@ export class DocumentDetailComponent
|
|||||||
this.versionUploadState = UploadState.Uploading
|
this.versionUploadState = UploadState.Uploading
|
||||||
this.versionUploadError = null
|
this.versionUploadError = null
|
||||||
this.documentsService
|
this.documentsService
|
||||||
.uploadVersion(this.documentId, file, label)
|
.uploadVersion(uploadDocumentId, file, label)
|
||||||
.pipe(
|
.pipe(
|
||||||
first(),
|
first(),
|
||||||
tap(() => {
|
tap(() => {
|
||||||
@@ -1351,7 +1356,10 @@ export class DocumentDetailComponent
|
|||||||
message: status.message,
|
message: status.message,
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
).pipe(take(1))
|
).pipe(
|
||||||
|
takeUntil(merge(this.unsubscribeNotifier, this.docChangeNotifier)),
|
||||||
|
take(1)
|
||||||
|
)
|
||||||
}),
|
}),
|
||||||
switchMap((result) => {
|
switchMap((result) => {
|
||||||
if (result?.state !== 'success') {
|
if (result?.state !== 'success') {
|
||||||
@@ -1362,13 +1370,14 @@ export class DocumentDetailComponent
|
|||||||
}
|
}
|
||||||
return of(null)
|
return of(null)
|
||||||
}
|
}
|
||||||
return this.documentsService.getVersions(this.documentId)
|
return this.documentsService.getVersions(uploadDocumentId)
|
||||||
}),
|
}),
|
||||||
takeUntil(this.unsubscribeNotifier),
|
takeUntil(this.unsubscribeNotifier),
|
||||||
takeUntil(this.docChangeNotifier)
|
takeUntil(this.docChangeNotifier)
|
||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (doc) => {
|
next: (doc) => {
|
||||||
|
if (uploadDocumentId !== this.documentId) return
|
||||||
if (doc?.versions) {
|
if (doc?.versions) {
|
||||||
this.document.versions = doc.versions
|
this.document.versions = doc.versions
|
||||||
const openDoc = this.openDocumentService.getOpenDocument(
|
const openDoc = this.openDocumentService.getOpenDocument(
|
||||||
@@ -1385,6 +1394,7 @@ export class DocumentDetailComponent
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
|
if (uploadDocumentId !== this.documentId) return
|
||||||
this.versionUploadState = UploadState.Failed
|
this.versionUploadState = UploadState.Failed
|
||||||
this.versionUploadError = error?.message || $localize`Upload failed.`
|
this.versionUploadError = error?.message || $localize`Upload failed.`
|
||||||
this.toastService.showError(
|
this.toastService.showError(
|
||||||
|
|||||||
Reference in New Issue
Block a user