diff --git a/e2e/components/dialog/share-dialog.ts b/e2e/components/dialog/share-dialog.ts index 824dd5c83..75ea20b28 100755 --- a/e2e/components/dialog/share-dialog.ts +++ b/e2e/components/dialog/share-dialog.ts @@ -116,7 +116,7 @@ export class ShareDialog extends Component { return toggleClass.includes('checked'); } - async isShareToggleEnabled() { + async isShareToggleDisabled() { const toggleClass = await this.getShareToggle().getAttribute('class'); return toggleClass.includes('mat-disabled'); } diff --git a/e2e/suites/actions/unshare-file.test.ts b/e2e/suites/actions/unshare-file.test.ts index ed9aaa370..16591a9f9 100755 --- a/e2e/suites/actions/unshare-file.test.ts +++ b/e2e/suites/actions/unshare-file.test.ts @@ -738,8 +738,7 @@ describe('Unshare a file', () => { done(); }); - // TODO: ACA-1911 - xit('on File Libraries - file shared by other user - [C286682]', async () => { + it('on File Libraries - file shared by other user - [C286682]', async () => { await page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES); await dataTable.waitForHeader(); await dataTable.doubleClickOnRowByName(sitePrivate); @@ -749,7 +748,7 @@ describe('Unshare a file', () => { await toolbar.menu.clickMenuItem('Shared link settings'); await shareDialog.waitForDialogToOpen(); - expect(await shareDialog.isShareToggleEnabled()).toBe(false, 'Share toggle enabled for consumer'); + expect(await shareDialog.isShareToggleDisabled()).toBe(false, 'Share toggle enabled for consumer'); }); it('on File Libraries - file shared by the user - [C286701]', async () => { @@ -762,11 +761,10 @@ describe('Unshare a file', () => { await toolbar.menu.clickMenuItem('Shared link settings'); await shareDialog.waitForDialogToOpen(); - expect(await shareDialog.isShareToggleEnabled()).toBe(true, 'Share toggle disabled for consumer'); + expect(await shareDialog.isShareToggleDisabled()).toBe(false, 'Share toggle enabled for consumer'); }); - // TODO: ACA-1911 - xit('on Shared Files - file shared by other user - [C286687]', async () => { + it('on Shared Files - file shared by other user - [C286687]', async () => { await page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES); await dataTable.waitForHeader(); await dataTable.selectItem(file1); @@ -774,7 +772,7 @@ describe('Unshare a file', () => { await toolbar.menu.clickMenuItem('Shared link settings'); await shareDialog.waitForDialogToOpen(); - expect(await shareDialog.isShareToggleEnabled()).toBe(false, 'Share toggle enabled for consumer'); + expect(await shareDialog.isShareToggleDisabled()).toBe(false, 'Share toggle enabled for consumer'); }); it('on Shared Files - file shared by the user - [C286702]', async () => { @@ -785,11 +783,10 @@ describe('Unshare a file', () => { await toolbar.menu.clickMenuItem('Shared link settings'); await shareDialog.waitForDialogToOpen(); - expect(await shareDialog.isShareToggleEnabled()).toBe(true, 'Share toggle disabled for consumer'); + expect(await shareDialog.isShareToggleDisabled()).toBe(false, 'Share toggle enabled for consumer'); }); - // TODO: ACA-1911 - xit('on Favorites - file shared by other user - [C286697]', async () => { + it('on Favorites - file shared by other user - [C286697]', async () => { await page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES); await dataTable.waitForHeader(); await dataTable.selectItem(file1); @@ -797,7 +794,7 @@ describe('Unshare a file', () => { await toolbar.menu.clickMenuItem('Share'); await shareDialog.waitForDialogToOpen(); - expect(await shareDialog.isShareToggleEnabled()).toBe(false, 'Share toggle enabled for consumer'); + expect(await shareDialog.isShareToggleDisabled()).toBe(false, 'Share toggle enabled for consumer'); }); it('on Favorites - file shared by the user - [C286703]', async () => { @@ -808,7 +805,7 @@ describe('Unshare a file', () => { await toolbar.menu.clickMenuItem('Share'); await shareDialog.waitForDialogToOpen(); - expect(await shareDialog.isShareToggleEnabled()).toBe(true, 'Share toggle disabled for consumer'); + expect(await shareDialog.isShareToggleDisabled()).toBe(false, 'Share toggle enabled for consumer'); }); }); diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.html b/src/app/components/shared/content-node-share/content-node-share.dialog.html index 5fc3903ec..a922dc8be 100644 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.html +++ b/src/app/components/shared/content-node-share/content-node-share.dialog.html @@ -14,7 +14,7 @@ color="primary" data-automation-id="adf-share-toggle" [checked]="isFileShared" - [disabled]="!canUpdate || isDisabled" + [disabled]="isDisabled" (change)="onSlideShareChange()"> diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts b/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts index 7f497c433..2db6f161c 100644 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts +++ b/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts @@ -29,6 +29,7 @@ import { import { ContentNodeShareModule } from './content-node-share.module'; import { ShareDialogComponent } from './content-node-share.dialog'; import moment from 'moment-es6'; +import { Store } from '@ngrx/store'; describe('ShareDialogComponent', () => { let node; @@ -40,6 +41,9 @@ describe('ShareDialogComponent', () => { let nodesApiService: NodesApiService; let fixture; let component; + const storeMock = { + dispatch: jasmine.createSpy('dispatch') + }; setupTestBed({ imports: [ @@ -50,6 +54,7 @@ describe('ShareDialogComponent', () => { providers: [ NodesApiService, SharedLinksApiService, + { provide: Store, useValue: storeMock }, { provide: NotificationService, useValue: notificationServiceMock }, { provide: MatDialogRef, useValue: {} }, { provide: MAT_DIALOG_DATA, useValue: {} } @@ -266,7 +271,7 @@ describe('ShareDialogComponent', () => { ).toBe(''); }); - it('should not allow unshare when node has no update permission', () => { + it('should not allow expiration date action when node has no update permission', () => { node.entry.properties['qshare:sharedId'] = 'sharedId'; component.data = { @@ -277,11 +282,6 @@ describe('ShareDialogComponent', () => { fixture.detectChanges(); - expect( - fixture.nativeElement.querySelector( - '.mat-slide-toggle[data-automation-id="adf-share-toggle"' - ).classList - ).toContain('mat-disabled'); expect( fixture.nativeElement.querySelector('input[formcontrolname="time"]') .disabled @@ -293,6 +293,29 @@ describe('ShareDialogComponent', () => { ).toContain('mat-disabled'); }); + it('should show permission error notification on un-share action', () => { + node.entry.properties['qshare:sharedId'] = 'sharedId'; + spyOn(matDialog, 'open').and.returnValue({ beforeClose: () => of(true) }); + spyOn(sharedLinksApiService, 'deleteSharedLink').and.returnValue( + of(new Error('{"error": { "statusCode": 403 } }')) + ); + component.data = { + node, + permission: false, + baseShareUrl: 'some-url/' + }; + + fixture.detectChanges(); + + fixture.nativeElement + .querySelector( + '.mat-slide-toggle[data-automation-id="adf-share-toggle"] label' + ) + .dispatchEvent(new MouseEvent('click')); + + expect(storeMock.dispatch).toHaveBeenCalled(); + }); + it('should update node expiration date with selected date and time', () => { const date = moment(); node.entry.properties['qshare:sharedId'] = 'sharedId'; diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.ts b/src/app/components/shared/content-node-share/content-node-share.dialog.ts index 826d5890f..c737a495e 100644 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.ts +++ b/src/app/components/shared/content-node-share/content-node-share.dialog.ts @@ -26,6 +26,9 @@ import { import { MAT_DIALOG_DATA, MatDialogRef, MatDialog } from '@angular/material'; import { FormGroup, FormControl } from '@angular/forms'; import { Subscription, Observable, throwError } from 'rxjs'; +import { SnackbarErrorAction } from '../../../store/actions'; +import { AppStore } from '../../../store/states/app.state'; +import { Store } from '@ngrx/store'; import { skip, mergeMap, @@ -72,6 +75,7 @@ export class ShareDialogComponent implements OnInit, OnDestroy { private dialogRef: MatDialogRef, private dialog: MatDialog, private nodesApiService: NodesApiService, + private store: Store, @Inject(MAT_DIALOG_DATA) public data: any ) {} @@ -197,17 +201,19 @@ export class ShareDialogComponent implements OnInit, OnDestroy { private deleteSharedLink(sharedId: string) { this.isDisabled = true; - this.sharedLinksApiService.deleteSharedLink(sharedId).subscribe( - () => { - this.data.node.entry.properties['qshare:sharedId'] = null; - this.data.node.entry.properties['qshare:expiryDate'] = null; - this.dialogRef.close(this.data.node); - }, - () => { - this.isDisabled = false; - this.isFileShared = false; - } - ); + this.sharedLinksApiService + .deleteSharedLink(sharedId) + .subscribe((response: any) => { + if (response instanceof Error) { + this.isDisabled = false; + this.isFileShared = true; + this.showError(response); + } else { + this.data.node.entry.properties['qshare:sharedId'] = null; + this.data.node.entry.properties['qshare:expiryDate'] = null; + this.dialogRef.close(this.data.node); + } + }); } private updateForm() { @@ -233,4 +239,14 @@ export class ShareDialogComponent implements OnInit, OnDestroy { properties['qshare:expiryDate'] = date ? date.toDate() : null; } + + private showError(response) { + let message; + const statusCode = JSON.parse(response.message).error.statusCode; + if (statusCode === 403) { + message = 'SHARED_LINK.UNSHARE_PERMISSION_ERROR'; + } + + this.store.dispatch(new SnackbarErrorAction(message)); + } } diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index b0d91d966..cdc2fc30c 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -265,6 +265,9 @@ "INHERITED_PERMISSIONS_BUTTON": "Permission Inherited" } }, + "SHARED_LINK": { + "UNSHARE_PERMISSION_ERROR": "You don't have permission to unshare this file" + }, "VERSION": { "DIALOG": { "TITLE": "Manage Versions",