TSK-519 Add user role guard and no access screen

This commit is contained in:
Martin Rojas Miguel Angel 2018-06-05 16:00:55 +02:00 committed by Holger Hagen
parent 2452057364
commit 3a01a9359d
38 changed files with 694 additions and 570 deletions

View File

@ -5,7 +5,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ViewController {
@RequestMapping({ "/administration*/**", "/workplace*/**", "/monitor*/**" })
@RequestMapping({ "/administration*/**", "/workplace*/**", "/monitor*/**" , "/no-role*/**"})
public String index() {
return "forward:/index.html";
}

View File

@ -4,7 +4,6 @@ import { Routes, RouterModule } from '@angular/router';
import { WorkbasketListComponent } from 'app/administration/workbasket/master/list/workbasket-list.component';
import { WorkbasketDetailsComponent } from 'app/administration/workbasket/details/workbasket-details.component';
import { MasterAndDetailComponent } from 'app/shared/master-and-detail/master-and-detail.component';
import { NoAccessComponent } from 'app/administration/workbasket/details/noAccess/no-access.component';
import { ClassificationListComponent } from 'app/administration/classification/master/list/classification-list.component';
import { ClassificationDetailsComponent } from 'app/administration/classification/details/classification-details.component';
import { DomainGuard } from 'app/guards/domain-guard';
@ -21,11 +20,6 @@ const routes: Routes = [
component: WorkbasketListComponent,
outlet: 'master'
},
{
path: 'noaccess',
component: NoAccessComponent,
outlet: 'detail'
},
{
path: 'new-classification/:id',
component: WorkbasketDetailsComponent,

View File

@ -19,7 +19,6 @@ import { WorkbasketInformationComponent } from './workbasket/details/information
import { DistributionTargetsComponent } from './workbasket/details/distribution-targets/distribution-targets.component';
import { DualListComponent } from './workbasket/details/distribution-targets/dual-list/dual-list.component';
import { AccessItemsComponent } from './workbasket/details/access-items/access-items.component';
import { NoAccessComponent } from './workbasket/details/noAccess/no-access.component';
import { FilterComponent } from './components/filter/filter.component';
import { IconTypeComponent } from './components/type-icon/icon-type.component';
import { PaginationComponent } from './workbasket/master/list/pagination/pagination.component';
@ -57,7 +56,6 @@ const DECLARATIONS = [
AccessItemsComponent,
WorkbasketDetailsComponent,
WorkbasketInformationComponent,
NoAccessComponent,
FilterComponent,
IconTypeComponent,
DistributionTargetsComponent,

View File

@ -27,6 +27,7 @@ import { ClassificationCategoriesService } from 'app/administration/services/cla
import { DomainServiceMock } from 'app/services/domain/domain.service.mock';
import { DomainService } from 'app/services/domain/domain.service';
import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service';
import { configureTests } from 'app/app.test.configuration';
@Component({
selector: 'taskana-dummy-detail',
@ -48,37 +49,39 @@ describe('ClassificationDetailsComponent', () => {
let classificationsService, classificationTypesService, classificationCategoriesService;
let treeService;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [FormsModule, HttpClientModule, RouterTestingModule.withRoutes(routes), AngularSvgIconModule],
declarations: [ClassificationDetailsComponent, SpinnerComponent, DummyDetailComponent],
providers: [MasterAndDetailService, RequestInProgressService, ClassificationsService, HttpClient, ErrorModalService, AlertService,
TreeService, ClassificationTypesService, ClassificationCategoriesService, {
provide: DomainService,
useClass: DomainServiceMock
},
CustomFieldsService]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ClassificationDetailsComponent);
component = fixture.componentInstance;
classificationsService = TestBed.get(ClassificationsService);
classificationTypesService = TestBed.get(ClassificationTypesService);
classificationCategoriesService = TestBed.get(ClassificationCategoriesService);
classificationsSpy = spyOn(classificationsService, 'getClassifications').and.returnValue(Observable.of(treeNodes));
classificationsTypesSpy = spyOn(classificationTypesService, 'getClassificationTypes').and.returnValue(Observable.of([]));
spyOn(classificationCategoriesService, 'getCategories').and.returnValue(Observable.of(['firstCategory', 'secondCategory']));
spyOn(classificationsService, 'deleteClassification').and.returnValue(Observable.of(true));
component.classification = new ClassificationDefinition('id1', undefined, undefined, undefined, undefined, undefined, undefined,
undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined,
undefined, undefined, undefined, new LinksClassification({ 'self': '' }));
treeService = TestBed.get(TreeService);
fixture.detectChanges();
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
imports: [FormsModule, HttpClientModule, RouterTestingModule.withRoutes(routes), AngularSvgIconModule],
declarations: [ClassificationDetailsComponent, SpinnerComponent, DummyDetailComponent],
providers: [MasterAndDetailService, RequestInProgressService, ClassificationsService, HttpClient, ErrorModalService, AlertService,
TreeService, ClassificationTypesService, ClassificationCategoriesService, {
provide: DomainService,
useClass: DomainServiceMock
},
CustomFieldsService]
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(ClassificationDetailsComponent);
component = fixture.componentInstance;
classificationsService = TestBed.get(ClassificationsService);
classificationTypesService = TestBed.get(ClassificationTypesService);
classificationCategoriesService = TestBed.get(ClassificationCategoriesService);
classificationsSpy = spyOn(classificationsService, 'getClassifications').and.returnValue(Observable.of(treeNodes));
classificationsTypesSpy = spyOn(classificationTypesService, 'getClassificationTypes').and.returnValue(Observable.of([]));
spyOn(classificationCategoriesService, 'getCategories').and.returnValue(Observable.of(['firstCategory', 'secondCategory']));
spyOn(classificationsService, 'deleteClassification').and.returnValue(Observable.of(true));
component.classification = new ClassificationDefinition('id1', undefined, undefined, undefined, undefined, undefined, undefined,
undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined,
undefined, undefined, undefined, new LinksClassification({ 'self': '' }));
treeService = TestBed.get(TreeService);
fixture.detectChanges();
done();
});
});
it('should create', () => {
expect(component).toBeTruthy();
});

View File

@ -26,6 +26,7 @@ import { DomainService } from 'app/services/domain/domain.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service';
import { ClassificationTypesService } from 'app/administration/services/classification-types/classification-types.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
import { configureTests } from 'app/app.test.configuration';
@Component({
selector: 'taskana-tree',
@ -59,29 +60,30 @@ describe('ClassificationListComponent', () => {
let classificationsSpy, classificationsTypesSpy;
let classificationsService, classificationTypesService;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ClassificationListComponent, ImportExportComponent, SpinnerComponent, ClassificationTypesSelectorComponent,
TaskanaTreeComponent, DummyDetailComponent, IconTypeComponent, MapValuesPipe],
imports: [HttpClientModule, RouterTestingModule.withRoutes(routes), FormsModule, AngularSvgIconModule, HttpModule],
providers: [
HttpClient, WorkbasketDefinitionService, AlertService, ClassificationsService, DomainService, ClassificationDefinitionService,
ErrorModalService, ClassificationTypesService, RequestInProgressService
]
})
.compileComponents();
}));
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
declarations: [ClassificationListComponent, ImportExportComponent, SpinnerComponent, ClassificationTypesSelectorComponent,
TaskanaTreeComponent, DummyDetailComponent, IconTypeComponent, MapValuesPipe],
imports: [HttpClientModule, RouterTestingModule.withRoutes(routes), FormsModule, AngularSvgIconModule, HttpModule],
providers: [
HttpClient, WorkbasketDefinitionService, AlertService, ClassificationsService, DomainService, ClassificationDefinitionService,
ErrorModalService, ClassificationTypesService, RequestInProgressService
]
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(ClassificationListComponent);
component = fixture.componentInstance;
beforeEach(() => {
fixture = TestBed.createComponent(ClassificationListComponent);
component = fixture.componentInstance;
classificationsService = TestBed.get(ClassificationsService);
classificationTypesService = TestBed.get(ClassificationTypesService);
classificationsSpy = spyOn(classificationsService, 'getClassifications').and.returnValue(Observable.of(treeNodes));
classificationsTypesSpy = spyOn(classificationTypesService, 'getClassificationTypes')
.and.returnValue(Observable.of(classificationTypes));
fixture.detectChanges();
classificationsService = TestBed.get(ClassificationsService);
classificationTypesService = TestBed.get(ClassificationTypesService);
classificationsSpy = spyOn(classificationsService, 'getClassifications').and.returnValue(Observable.of(treeNodes));
classificationsTypesSpy = spyOn(classificationTypesService, 'getClassificationTypes')
.and.returnValue(Observable.of(classificationTypes));
fixture.detectChanges();
done();
});
});
it('should create', () => {

View File

@ -8,6 +8,7 @@ import { FilterModel } from 'app/models/filter';
import { IconTypeComponent } from '../type-icon/icon-type.component';
import { FilterComponent } from './filter.component';
import { MapValuesPipe } from 'app/shared/pipes/mapValues/map-values.pipe';
import { configureTests } from 'app/app.test.configuration';
describe('FilterComponent', () => {
let component: FilterComponent,
@ -15,18 +16,21 @@ describe('FilterComponent', () => {
debugElement: any;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [FilterComponent, IconTypeComponent, MapValuesPipe],
imports: [AngularSvgIconModule, FormsModule, HttpClientModule, HttpModule]
})
.compileComponents();
fixture = TestBed.createComponent(FilterComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
fixture.detectChanges();
}));
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
declarations: [FilterComponent, IconTypeComponent, MapValuesPipe],
imports: [AngularSvgIconModule, FormsModule, HttpClientModule, HttpModule]
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(FilterComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
fixture.detectChanges();
done();
});
});
afterEach(() => {
document.body.removeChild(debugElement);

View File

@ -1,42 +1,50 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {ImportExportComponent} from './import-export.component';
import {WorkbasketService} from 'app/services/workbasket/workbasket.service';
import {ClassificationDefinitionService} from 'app/administration/services/classification-definition/classification-definition.service';
import {WorkbasketDefinitionService} from '../../services/workbasket-definition/workbasket-definition.service';
import {AlertService} from 'app/services/alert/alert.service';
import {HttpClientModule} from '@angular/common/http';
import {DomainService} from 'app/services/domain/domain.service';
import {Observable} from 'rxjs/Observable';
import {ErrorModalService} from 'app/services/errorModal/error-modal.service';
import { ImportExportComponent } from './import-export.component';
import { WorkbasketService } from 'app/services/workbasket/workbasket.service';
import { ClassificationDefinitionService } from 'app/administration/services/classification-definition/classification-definition.service';
import { WorkbasketDefinitionService } from '../../services/workbasket-definition/workbasket-definition.service';
import { AlertService } from 'app/services/alert/alert.service';
import { HttpClientModule } from '@angular/common/http';
import { DomainService } from 'app/services/domain/domain.service';
import { Observable } from 'rxjs/Observable';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service';
import { DomainServiceMock } from 'app/services/domain/domain.service.mock';
import { AngularSvgIconModule } from 'angular-svg-icon';
import { HttpModule } from '@angular/http';
import { configureTests } from 'app/app.test.configuration';
describe('ImportExportComponent', () => {
let component: ImportExportComponent;
let fixture: ComponentFixture<ImportExportComponent>;
let domainService;
let debugElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ImportExportComponent],
imports: [HttpClientModule, AngularSvgIconModule, HttpModule],
providers: [WorkbasketService, ClassificationDefinitionService, WorkbasketDefinitionService, AlertService, {
provide: DomainService,
useClass: DomainServiceMock
},
ErrorModalService]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ImportExportComponent);
component = fixture.componentInstance;
fixture.detectChanges();
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
declarations: [ImportExportComponent],
imports: [HttpClientModule, AngularSvgIconModule, HttpModule],
providers: [WorkbasketService, ClassificationDefinitionService, WorkbasketDefinitionService, AlertService, {
provide: DomainService,
useClass: DomainServiceMock
},
ErrorModalService]
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(ImportExportComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
fixture.detectChanges();
done();
});
});
afterEach(() => {
document.body.removeChild(debugElement);
});
it('should create', () => {
expect(component).toBeTruthy();
});

View File

@ -3,24 +3,30 @@ import { MapValuesPipe } from 'app/shared/pipes/mapValues/map-values.pipe';
import { SortComponent } from './sort.component';
import { Direction } from 'app/models/sorting';
import { configureTests } from 'app/app.test.configuration';
describe('SortComponent', () => {
let component: SortComponent;
let fixture: ComponentFixture<SortComponent>;
let debugElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [SortComponent, MapValuesPipe]
})
.compileComponents();
}));
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
declarations: [SortComponent, MapValuesPipe]
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(SortComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
fixture.detectChanges();
done();
});
});
beforeEach(() => {
fixture = TestBed.createComponent(SortComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
fixture.detectChanges();
afterEach(() => {
document.body.removeChild(debugElement);
});
it('should create', () => {

View File

@ -3,23 +3,31 @@ import { AngularSvgIconModule } from 'angular-svg-icon';
import { HttpClientModule } from '@angular/common/http';
import { HttpModule } from '@angular/http';
import { IconTypeComponent } from './icon-type.component';
import { configureTests } from 'app/app.test.configuration';
describe('IconTypeComponent', () => {
let component: IconTypeComponent;
let fixture: ComponentFixture<IconTypeComponent>;
let debugElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [AngularSvgIconModule, HttpClientModule, HttpModule],
declarations: [IconTypeComponent]
})
.compileComponents();
}));
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
imports: [AngularSvgIconModule, HttpClientModule, HttpModule],
declarations: [IconTypeComponent]
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(IconTypeComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
fixture.detectChanges();
done();
});
});
beforeEach(() => {
fixture = TestBed.createComponent(IconTypeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
afterEach(() => {
document.body.removeChild(debugElement);
});
it('should create', () => {

View File

@ -25,6 +25,7 @@ import { RequestInProgressService } from 'app/services/requestInProgress/request
import { DomainService } from 'app/services/domain/domain.service';
import { DomainServiceMock } from 'app/services/domain/domain.service.mock';
import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service';
import { configureTests } from 'app/app.test.configuration';
@Component({
@ -62,43 +63,45 @@ describe('AccessItemsComponent', () => {
let fixture: ComponentFixture<AccessItemsComponent>;
let workbasketService, debugElement, alertService;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [SpinnerComponent, AccessItemsComponent, GeneralMessageModalComponent, TaskanaTypeAheadComponent],
imports: [FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule, ReactiveFormsModule],
providers: [WorkbasketService, AlertService, ErrorModalService, SavingWorkbasketService, RequestInProgressService,
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
declarations: [SpinnerComponent, AccessItemsComponent, GeneralMessageModalComponent, TaskanaTypeAheadComponent],
imports: [FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule, ReactiveFormsModule],
providers: [WorkbasketService, AlertService, ErrorModalService, SavingWorkbasketService, RequestInProgressService,
{
provide: DomainService,
useClass: DomainServiceMock
},
CustomFieldsService]
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(AccessItemsComponent);
component = fixture.componentInstance;
component.workbasket = new Workbasket('1', '', '', '', ICONTYPES.TOPIC, '', '', '', '', '', '', '', '', '', '', '', '',
new Links(undefined, undefined, { 'href': 'someurl' }));
workbasketService = TestBed.get(WorkbasketService);
alertService = TestBed.get(AlertService);
spyOn(workbasketService, 'getWorkBasketAccessItems').and.returnValue(Observable.of(new WorkbasketAccessItemsResource(
{
provide: DomainService,
useClass: DomainServiceMock
},
CustomFieldsService]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AccessItemsComponent);
component = fixture.componentInstance;
component.workbasket = new Workbasket('1', '', '', '', ICONTYPES.TOPIC, '', '', '', '', '', '', '', '', '', '', '', '',
new Links(undefined, undefined, { 'href': 'someurl' }));
workbasketService = TestBed.get(WorkbasketService);
alertService = TestBed.get(AlertService);
spyOn(workbasketService, 'getWorkBasketAccessItems').and.returnValue(Observable.of(new WorkbasketAccessItemsResource(
{
'accessItems': new Array<WorkbasketAccessItems>(
new WorkbasketAccessItems('id1', '1', 'accessID1', false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false),
new WorkbasketAccessItems('id2', '1', 'accessID2'))
}, new Links({ 'href': 'someurl' })
)));
spyOn(workbasketService, 'updateWorkBasketAccessItem').and.returnValue(Observable.of(true)),
spyOn(alertService, 'triggerAlert').and.returnValue(Observable.of(true)),
debugElement = fixture.debugElement.nativeElement;
component.ngOnChanges({
active: new SimpleChange(undefined, 'accessItems', true)
'accessItems': new Array<WorkbasketAccessItems>(
new WorkbasketAccessItems('id1', '1', 'accessID1', false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false),
new WorkbasketAccessItems('id2', '1', 'accessID2'))
}, new Links({ 'href': 'someurl' })
)));
spyOn(workbasketService, 'updateWorkBasketAccessItem').and.returnValue(Observable.of(true)),
spyOn(alertService, 'triggerAlert').and.returnValue(Observable.of(true)),
debugElement = fixture.debugElement.nativeElement;
component.ngOnChanges({
active: new SimpleChange(undefined, 'accessItems', true)
});
fixture.detectChanges();
done();
});
fixture.detectChanges();
});
afterEach(() => {

View File

@ -28,6 +28,7 @@ import { SelectWorkBasketPipe } from 'app/shared/pipes/selectedWorkbasket/selete
import { LinksWorkbasketSummary } from 'app/models/links-workbasket-summary';
import { DomainService } from 'app/services/domain/domain.service';
import { DomainServiceMock } from 'app/services/domain/domain.service.mock';
import { configureTests } from 'app/app.test.configuration';
const workbasketSummaryResource: WorkbasketSummaryResource = new WorkbasketSummaryResource({
@ -54,45 +55,46 @@ describe('DistributionTargetsComponent', () => {
const workbasket = new Workbasket('1', '', '', '', ICONTYPES.TOPIC, '', '', '', '', '', '', '', '', '', '', '', '',
new Links({ 'href': 'someurl' }, { 'href': 'someurl' }, { 'href': 'someurl' }));
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [AngularSvgIconModule, HttpClientModule, HttpModule, JsonpModule],
declarations: [DistributionTargetsComponent, SpinnerComponent, GeneralMessageModalComponent,
FilterComponent, SelectWorkBasketPipe, IconTypeComponent, DualListComponent],
providers: [WorkbasketService, AlertService, SavingWorkbasketService, ErrorModalService, RequestInProgressService,
{
provide: DomainService,
useClass: DomainServiceMock
}]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DistributionTargetsComponent);
component = fixture.componentInstance;
component.workbasket = workbasket;
workbasketService = TestBed.get(WorkbasketService);
spyOn(workbasketService, 'getWorkBasketsSummary').and.callFake(() => {
return Observable.of(new WorkbasketSummaryResource(
{
'workbaskets': new Array<WorkbasketSummary>(
new WorkbasketSummary('id1', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })),
new WorkbasketSummary('id2', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })),
new WorkbasketSummary('id3', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })))
}, new LinksWorkbasketSummary({ 'href': 'someurl' })))
})
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() => {
return Observable.of(new WorkbasketDistributionTargetsResource(
{
'distributionTargets': new Array<WorkbasketSummary>(
new WorkbasketSummary('id2', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })))
}, new LinksWorkbasketSummary({ 'href': 'someurl' })))
})
component.ngOnChanges({
active: new SimpleChange(undefined, 'distributionTargets', true)
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
imports: [AngularSvgIconModule, HttpClientModule, HttpModule, JsonpModule],
declarations: [DistributionTargetsComponent, SpinnerComponent, GeneralMessageModalComponent,
FilterComponent, SelectWorkBasketPipe, IconTypeComponent, DualListComponent],
providers: [WorkbasketService, AlertService, SavingWorkbasketService, ErrorModalService, RequestInProgressService,
{
provide: DomainService,
useClass: DomainServiceMock
}]
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(DistributionTargetsComponent);
component = fixture.componentInstance;
component.workbasket = workbasket;
workbasketService = TestBed.get(WorkbasketService);
spyOn(workbasketService, 'getWorkBasketsSummary').and.callFake(() => {
return Observable.of(new WorkbasketSummaryResource(
{
'workbaskets': new Array<WorkbasketSummary>(
new WorkbasketSummary('id1', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })),
new WorkbasketSummary('id2', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })),
new WorkbasketSummary('id3', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })))
}, new LinksWorkbasketSummary({ 'href': 'someurl' })))
})
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() => {
return Observable.of(new WorkbasketDistributionTargetsResource(
{
'distributionTargets': new Array<WorkbasketSummary>(
new WorkbasketSummary('id2', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })))
}, new LinksWorkbasketSummary({ 'href': 'someurl' })))
})
component.ngOnChanges({
active: new SimpleChange(undefined, 'distributionTargets', true)
});
fixture.detectChanges();
done();
});
fixture.detectChanges();
});
it('should create', () => {

View File

@ -29,6 +29,7 @@ import { RequestInProgressService } from 'app/services/requestInProgress/request
import { DomainService } from 'app/services/domain/domain.service';
import { DomainServiceMock } from 'app/services/domain/domain.service.mock';
import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service';
import { configureTests } from 'app/app.test.configuration';
@Component({
selector: 'taskana-dummy-detail',
@ -77,35 +78,40 @@ describe('InformationComponent', () => {
let fixture: ComponentFixture<WorkbasketInformationComponent>;
let debugElement, workbasketService, alertService, savingWorkbasketService, requestInProgressService;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [WorkbasketInformationComponent, IconTypeComponent, MapValuesPipe,
RemoveNoneTypePipe, SpinnerComponent, GeneralMessageModalComponent, DummyDetailComponent,
TaskanaTypeAheadComponent],
imports: [FormsModule,
AngularSvgIconModule,
HttpClientModule,
HttpModule,
RouterTestingModule.withRoutes(routes)],
providers: [WorkbasketService, AlertService, SavingWorkbasketService, ErrorModalService, RequestInProgressService,
{
provide: DomainService,
useClass: DomainServiceMock
},
CustomFieldsService]
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
declarations: [WorkbasketInformationComponent, IconTypeComponent, MapValuesPipe,
RemoveNoneTypePipe, SpinnerComponent, GeneralMessageModalComponent, DummyDetailComponent,
TaskanaTypeAheadComponent],
imports: [FormsModule,
AngularSvgIconModule,
HttpClientModule,
HttpModule,
RouterTestingModule.withRoutes(routes)],
providers: [WorkbasketService, AlertService, SavingWorkbasketService, ErrorModalService, RequestInProgressService,
{
provide: DomainService,
useClass: DomainServiceMock
},
CustomFieldsService]
})
.compileComponents();
fixture = TestBed.createComponent(WorkbasketInformationComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
workbasketService = TestBed.get(WorkbasketService);
alertService = TestBed.get(AlertService);
savingWorkbasketService = TestBed.get(SavingWorkbasketService);
requestInProgressService = TestBed.get(RequestInProgressService);
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(WorkbasketInformationComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
workbasketService = TestBed.get(WorkbasketService);
alertService = TestBed.get(AlertService);
savingWorkbasketService = TestBed.get(SavingWorkbasketService);
requestInProgressService = TestBed.get(RequestInProgressService);
spyOn(alertService, 'triggerAlert');
}));
spyOn(alertService, 'triggerAlert');
fixture.detectChanges();
done();
});
});
afterEach(() => {
document.body.removeChild(debugElement);

View File

@ -1,11 +0,0 @@
<button class = "btn btn-default back-button pull-left visible-xs visible-sm hidden blue" (click) = "backClicked()">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>Back
</button>
<div class="col-xs-12 container-no-access">
<div class="center-block no-access">
<h3 class="grey">You do not have access to edit this workbasket</h3>
<svg-icon class="img-responsive no-access-icon" src="./assets/icons/noaccess.svg"></svg-icon>
</div>
</div>

View File

@ -1,47 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NoAccessComponent } from './no-access.component';
import { Router, Routes, ActivatedRoute, NavigationStart, RouterEvent } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { AngularSvgIconModule } from 'angular-svg-icon';
import { HttpModule } from '@angular/http';
import { HttpClientModule } from '@angular/common/http';
describe('NoAccessComponent', () => {
let component: NoAccessComponent;
let fixture: ComponentFixture<NoAccessComponent>;
let debugElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule, AngularSvgIconModule, HttpModule, HttpClientModule],
declarations: [NoAccessComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NoAccessComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
});
afterEach(() => {
document.body.removeChild(debugElement);
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should have a back button with the following classes "btn btn-default back-button' +
'pull-left visible-xs visible-sm hidden blue"', () => {
expect(debugElement.querySelector('button').attributes.class.value)
.toBe('btn btn-default back-button pull-left visible-xs visible-sm hidden blue');
});
it('should have a div with title and svg', () => {
expect(debugElement.querySelector('div.center-block.no-access > h3').textContent).toBeDefined();
expect(debugElement.querySelector('div.center-block.no-access > svg-icon').attributes.src.value).toBe('./assets/icons/noaccess.svg');
});
});

View File

@ -1,20 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
@Component({
selector: 'taskana-no-access',
templateUrl: './no-access.component.html',
styleUrls: ['./no-access.component.scss']
})
export class NoAccessComponent implements OnInit {
constructor(private router: Router, private route: ActivatedRoute) { }
ngOnInit() {
}
backClicked(): void {
this.router.navigate(['./'], { relativeTo: this.route.parent });
}
}

View File

@ -1,16 +1,15 @@
<div class="container-scrollable">
<taskana-spinner [isRunning]="requestInProgress" ></taskana-spinner>
<taskana-no-access *ngIf="!requestInProgress && (!workbasket || !workbasket && selectedId)"></taskana-no-access>
<taskana-spinner [isRunning]="requestInProgress"></taskana-spinner>
<div id="workbasket-details" *ngIf="workbasket && !requestInProgress">
<ul class="nav nav-tabs" role="tablist">
<li *ngIf="showDetail" class="visible-xs visible-sm hidden">
<a (click)="backClicked()">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>Back</a>
</li>
<li role="presentation" class="active" (click)="tabSelected = 'information'" >
<li role="presentation" class="active" (click)="tabSelected = 'information'">
<a href="#work-baskets" aria-controls="work baskets" role="tab" data-toggle="tab" aria-expanded="true">Information</a>
</li>
<li role="presentation" [ngClass]="{'disabled': !workbasket._links?.accessItems}" (click)="tabSelected = 'accessItems'">
<li role="presentation" [ngClass]="{'disabled': !workbasket._links?.accessItems}" (click)="tabSelected = 'accessItems'">
<a href="#access-items" aria-controls="Acccess" role="tab" data-toggle="tab" aria-expanded="true">Access</a>
</li>
<li role="presentation" [ngClass]="{'disabled': !workbasket._links?.distributionTargets}" (click)="tabSelected = 'distributionTargets'">
@ -18,14 +17,14 @@
</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane fade in active"id="work-baskets">
<taskana-workbasket-information [workbasket]="workbasket" [action]="action" ></taskana-workbasket-information>
<div role="tabpanel" class="tab-pane fade in active" id="work-baskets">
<taskana-workbasket-information [workbasket]="workbasket" [action]="action"></taskana-workbasket-information>
</div>
<div role="tabpanel" class="tab-pane fade" id="access-items">
<taskana-workbasket-access-items [workbasket]="workbasket" [action]="action" [active] ="tabSelected"></taskana-workbasket-access-items>
<taskana-workbasket-access-items [workbasket]="workbasket" [action]="action" [active]="tabSelected"></taskana-workbasket-access-items>
</div>
<div role="tabpanel" class="tab-pane fade" id="distribution-targets">
<taskana-workbaskets-distribution-targets [workbasket]="workbasket" [action]="action" [active] ="tabSelected"></taskana-workbaskets-distribution-targets>
<taskana-workbaskets-distribution-targets [workbasket]="workbasket" [action]="action" [active]="tabSelected"></taskana-workbaskets-distribution-targets>
</div>
</div>
</div>

View File

@ -24,7 +24,6 @@ import { AlertService } from 'app/services/alert/alert.service';
import { SavingWorkbasketService } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service';
import { WorkbasketDetailsComponent } from './workbasket-details.component';
import { NoAccessComponent } from './noAccess/no-access.component';
import { WorkbasketInformationComponent } from './information/workbasket-information.component';
import { AccessItemsComponent } from './access-items/access-items.component';
import { DistributionTargetsComponent } from './distribution-targets/distribution-targets.component';
@ -41,6 +40,7 @@ import { RequestInProgressService } from 'app/services/requestInProgress/request
import { DomainService } from 'app/services/domain/domain.service';
import { DomainServiceMock } from 'app/services/domain/domain.service.mock';
import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service';
import { configureTests } from 'app/app.test.configuration';
@Component({
selector: 'taskana-filter',
template: ''
@ -103,52 +103,52 @@ describe('WorkbasketDetailsComponent', () => {
{ path: '*', component: DummyDetailComponent }
];
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes(routes), FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule],
declarations: [WorkbasketDetailsComponent, NoAccessComponent, WorkbasketInformationComponent, SpinnerComponent,
IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe, AlertComponent, GeneralMessageModalComponent, AccessItemsComponent,
DistributionTargetsComponent, FilterComponent, DualListComponent, DummyDetailComponent,
TaskanaTypeAheadComponent, SelectWorkBasketPipe],
providers: [WorkbasketService, MasterAndDetailService, ErrorModalService, RequestInProgressService,
AlertService, SavingWorkbasketService, {
provide: DomainService,
useClass: DomainServiceMock
},
CustomFieldsService]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(WorkbasketDetailsComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
router = TestBed.get(Router)
fixture.detectChanges();
masterAndDetailService = TestBed.get(MasterAndDetailService);
workbasketService = TestBed.get(WorkbasketService);
spyOn(masterAndDetailService, 'getShowDetail').and.callFake(() => { return Observable.of(true) })
spyOn(workbasketService, 'getSelectedWorkBasket').and.callFake(() => { return Observable.of('id1') })
spyOn(workbasketService, 'getWorkBasketsSummary').and.callFake(() => {
return Observable.of(new WorkbasketSummaryResource(
{
'workbaskets': new Array<WorkbasketSummary>(
new WorkbasketSummary('id1', '', '', '', '', '', '', '', '', '', '', '',
new Links({ 'href': 'someurl' })))
}, new LinksWorkbasketSummary({ 'href': 'someurl' })))
})
spyOn(workbasketService, 'getWorkBasket').and.callFake(() => { return Observable.of(workbasket) })
spyOn(workbasketService, 'getWorkBasketAccessItems').and.callFake(() => {
return Observable.of(new WorkbasketAccessItemsResource(
{ 'accessItems': new Array<WorkbasketAccessItems>() }, new Links({ 'href': 'url' })))
})
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() => {
return Observable.of(new WorkbasketSummaryResource(
{ 'workbaskets': new Array<WorkbasketSummary>() }, new LinksWorkbasketSummary({ 'href': 'url' })))
})
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes(routes), FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule],
declarations: [WorkbasketDetailsComponent, WorkbasketInformationComponent, SpinnerComponent,
IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe, AlertComponent, GeneralMessageModalComponent, AccessItemsComponent,
DistributionTargetsComponent, FilterComponent, DualListComponent, DummyDetailComponent,
TaskanaTypeAheadComponent, SelectWorkBasketPipe],
providers: [WorkbasketService, MasterAndDetailService, ErrorModalService, RequestInProgressService,
AlertService, SavingWorkbasketService, {
provide: DomainService,
useClass: DomainServiceMock
},
CustomFieldsService]
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(WorkbasketDetailsComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
router = TestBed.get(Router)
fixture.detectChanges();
masterAndDetailService = TestBed.get(MasterAndDetailService);
workbasketService = TestBed.get(WorkbasketService);
spyOn(masterAndDetailService, 'getShowDetail').and.callFake(() => { return Observable.of(true) })
spyOn(workbasketService, 'getSelectedWorkBasket').and.callFake(() => { return Observable.of('id1') })
spyOn(workbasketService, 'getWorkBasketsSummary').and.callFake(() => {
return Observable.of(new WorkbasketSummaryResource(
{
'workbaskets': new Array<WorkbasketSummary>(
new WorkbasketSummary('id1', '', '', '', '', '', '', '', '', '', '', '',
new Links({ 'href': 'someurl' })))
}, new LinksWorkbasketSummary({ 'href': 'someurl' })))
})
spyOn(workbasketService, 'getWorkBasket').and.callFake(() => { return Observable.of(workbasket) })
spyOn(workbasketService, 'getWorkBasketAccessItems').and.callFake(() => {
return Observable.of(new WorkbasketAccessItemsResource(
{ 'accessItems': new Array<WorkbasketAccessItems>() }, new Links({ 'href': 'url' })))
})
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() => {
return Observable.of(new WorkbasketSummaryResource(
{ 'workbaskets': new Array<WorkbasketSummary>() }, new LinksWorkbasketSummary({ 'href': 'url' })))
})
done();
});
});
afterEach(() => {
@ -159,19 +159,4 @@ describe('WorkbasketDetailsComponent', () => {
expect(component).toBeTruthy();
});
it('should has created taskana-workbasket-details if workbasket is defined and taskana-no-access should dissapear', () => {
expect(component.workbasket).toBeUndefined();
fixture.detectChanges();
expect(debugElement.querySelector('taskana-no-access')).toBeTruthy();
component.workbasket = workbasket;
fixture.detectChanges();
expect(debugElement.querySelector('taskana-no-access')).toBeFalsy();
expect(debugElement.querySelector('taskana-workbasket-information')).toBeTruthy();
});
});

View File

@ -6,26 +6,30 @@ import { SharedModule } from 'app/shared/shared.module';
import { PaginationComponent } from './pagination.component';
import { WorkbasketSummaryResource } from 'app/models/workbasket-summary-resource';
import { Page } from 'app/models/page';
import { configureTests } from 'app/app.test.configuration';
describe('PaginationComponent', () => {
let component: PaginationComponent;
let fixture: ComponentFixture<PaginationComponent>;
let debugElement;
beforeEach(async(() => {
return TestBed.configureTestingModule({
declarations: [
PaginationComponent
],
imports: [FormsModule, SharedModule]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PaginationComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
fixture.detectChanges();
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
declarations: [
PaginationComponent
],
imports: [FormsModule, SharedModule]
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(PaginationComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
fixture.detectChanges();
done();
});
});
afterEach(() => {

View File

@ -25,6 +25,7 @@ import { ImportExportComponent } from 'app/administration/components/import-expo
import { WorkbasketService } from 'app/services/workbasket/workbasket.service';
import { ClassificationDefinitionService } from 'app/administration/services/classification-definition/classification-definition.service';
import { WorkbasketDefinitionService } from 'app/administration/services/workbasket-definition/workbasket-definition.service';
import { configureTests } from 'app/app.test.configuration';
@Component({
selector: 'taskana-dummy-detail',
@ -43,35 +44,36 @@ describe('WorkbasketListToolbarComponent', () => {
{ path: ':id', component: DummyDetailComponent, outlet: 'detail' }
];
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [FormsModule, ReactiveFormsModule, AngularSvgIconModule, HttpModule,
HttpClientModule, RouterTestingModule.withRoutes(routes), SharedModule, AppModule],
declarations: [WorkbasketListToolbarComponent, SortComponent,
FilterComponent, IconTypeComponent, DummyDetailComponent, ImportExportComponent],
providers: [
WorkbasketService,
ClassificationDefinitionService,
WorkbasketDefinitionService,
]
})
.compileComponents();
}));
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
imports: [FormsModule, ReactiveFormsModule, AngularSvgIconModule, HttpModule,
HttpClientModule, RouterTestingModule.withRoutes(routes), SharedModule, AppModule],
declarations: [WorkbasketListToolbarComponent, SortComponent,
FilterComponent, IconTypeComponent, DummyDetailComponent, ImportExportComponent],
providers: [
WorkbasketService,
ClassificationDefinitionService,
WorkbasketDefinitionService,
]
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(WorkbasketListToolbarComponent);
workbasketService = TestBed.get(WorkbasketService);
router = TestBed.get(Router);
spyOn(workbasketService, 'deleteWorkbasket').and.returnValue(Observable.of(''));
spyOn(workbasketService, 'triggerWorkBasketSaved');
beforeEach(() => {
fixture = TestBed.createComponent(WorkbasketListToolbarComponent);
workbasketService = TestBed.get(WorkbasketService);
router = TestBed.get(Router);
spyOn(workbasketService, 'deleteWorkbasket').and.returnValue(Observable.of(''));
spyOn(workbasketService, 'triggerWorkBasketSaved');
debugElement = fixture.debugElement.nativeElement;
component = fixture.componentInstance;
component.workbaskets = new Array<WorkbasketSummary>(
new WorkbasketSummary('1', 'key1', 'NAME1', 'description 1', 'owner 1',
undefined, undefined, undefined, undefined, undefined, undefined, undefined, new Links({ 'href': 'selfLink' })));
debugElement = fixture.debugElement.nativeElement;
component = fixture.componentInstance;
component.workbaskets = new Array<WorkbasketSummary>(
new WorkbasketSummary('1', 'key1', 'NAME1', 'description 1', 'owner 1',
undefined, undefined, undefined, undefined, undefined, undefined, undefined, new Links({ 'href': 'selfLink' })));
fixture.detectChanges();
fixture.detectChanges();
done();
});
});
afterEach(() => {

View File

@ -25,6 +25,9 @@ import { ImportExportComponent } from 'app/administration/components/import-expo
import { WorkbasketDefinitionService } from 'app/administration/services/workbasket-definition/workbasket-definition.service';
import { ClassificationDefinitionService } from 'app/administration/services/classification-definition/classification-definition.service';
import { WorkbasketService } from 'app/services/workbasket/workbasket.service';
import { OrientationService } from 'app/services/orientation/orientation.service';
import { Orientation } from '../../../../models/orientation';
import { configureTests } from 'app/app.test.configuration';
@Component({
selector: 'taskana-dummy-detail',
@ -73,37 +76,42 @@ describe('WorkbasketListComponent', () => {
];
beforeEach(async(() => {
TestBed.configureTestingModule({
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
declarations: [WorkbasketListComponent, DummyDetailComponent, FilterComponent, WorkbasketListToolbarComponent,
IconTypeComponent, SortComponent, PaginationComponent, ImportExportComponent],
imports: [
AngularSvgIconModule,
HttpModule,
HttpClientModule,
RouterTestingModule.withRoutes(routes),
SharedModule,
AppModule
],
providers: [
WorkbasketService,
WorkbasketDefinitionService,
ClassificationDefinitionService,
OrientationService
]
});
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(WorkbasketListComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
workbasketService = TestBed.get(WorkbasketService);
const orientationService = TestBed.get(OrientationService);
workbasketSummarySpy = spyOn(workbasketService, 'getWorkBasketsSummary').and.returnValue(Observable.of(workbasketSummaryResource));
spyOn(workbasketService, 'getSelectedWorkBasket').and.returnValue(Observable.of('2'));
spyOn(orientationService, 'getOrientation').and.returnValue(Observable.of(undefined));
declarations: [WorkbasketListComponent, DummyDetailComponent, FilterComponent, WorkbasketListToolbarComponent,
IconTypeComponent, SortComponent, PaginationComponent, ImportExportComponent],
imports: [
AngularSvgIconModule,
HttpModule,
HttpClientModule,
RouterTestingModule.withRoutes(routes),
SharedModule,
AppModule
],
providers: [
WorkbasketService,
WorkbasketDefinitionService,
ClassificationDefinitionService
]
})
.compileComponents();
fixture.detectChanges();
done();
});
fixture = TestBed.createComponent(WorkbasketListComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
workbasketService = TestBed.get(WorkbasketService);
workbasketSummarySpy = spyOn(workbasketService, 'getWorkBasketsSummary').and.returnValue(Observable.of(workbasketSummaryResource));
spyOn(workbasketService, 'getSelectedWorkBasket').and.returnValue(Observable.of('2'));
fixture.detectChanges();
}));
});
afterEach(() => {
fixture.detectChanges()

View File

@ -2,8 +2,11 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { BusinessAdminGuard } from 'app/guards/business-admin-guard';
import { MonitorGuard } from 'app/guards/monitor-guard';
import { UserGuard } from 'app/guards/user-guard';
import { NoAccessComponent } from './components/no-access/no-access.component';
const appRoutes: Routes = [
{
@ -17,9 +20,14 @@ const appRoutes: Routes = [
loadChildren: './monitor/monitor.module#MonitorModule',
},
{
canActivate: [UserGuard],
path: 'workplace',
loadChildren: './workplace/workplace.module#WorkplaceModule'
},
{
path: 'no-role',
component: NoAccessComponent
},
{
path: '',
redirectTo: 'workplace',

View File

@ -39,6 +39,7 @@ import { TaskanaEngineService } from 'app/services/taskana-engine/taskana-engine
import { AppComponent } from './app.component';
import { NavBarComponent } from 'app/components/nav-bar/nav-bar.component';
import { UserInformationComponent } from 'app/components/user-information/user-information.component';
import { NoAccessComponent } from 'app/components/no-access/no-access.component';
/**
* Guards
@ -46,6 +47,7 @@ import { UserInformationComponent } from 'app/components/user-information/user-i
import { DomainGuard } from './guards/domain-guard';
import { BusinessAdminGuard } from './guards/business-admin-guard';
import { MonitorGuard } from './guards/monitor-guard';
import { UserGuard } from './guards/user-guard';
import { APP_BASE_HREF } from '@angular/common';
@ -67,6 +69,7 @@ const DECLARATIONS = [
AppComponent,
NavBarComponent,
UserInformationComponent,
NoAccessComponent,
];
export function startupServiceFactory(startupService: StartupService): () => Promise<any> {
@ -90,6 +93,7 @@ export function startupServiceFactory(startupService: StartupService): () => Pro
DomainGuard,
BusinessAdminGuard,
MonitorGuard,
UserGuard,
StartupService,
{
provide: APP_INITIALIZER,

View File

@ -0,0 +1,28 @@
import {
getTestBed,
ComponentFixtureAutoDetect,
TestBed,
} from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting,
} from '@angular/platform-browser-dynamic/testing';
import { TaskanaEngineServiceMock } from './services/taskana-engine/taskana-engine.mock.service';
import { TaskanaEngineService } from './services/taskana-engine/taskana-engine.service';
export const configureTests = (configure: (testBed: TestBed) => void) => {
const testBed = getTestBed();
if (testBed.platform == null) {
testBed.initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting());
}
configure(testBed);
testBed.configureTestingModule({ providers: [{ provide: TaskanaEngineService, useClass: TaskanaEngineServiceMock }] });
return testBed.compileComponents().then(() => testBed);
};

View File

@ -57,7 +57,7 @@
<div *ngIf="monitorAccess" class="row menu" [ngClass]="{'selected': selectedRoute.indexOf('monitor') !== -1}">
<span (click)="toogleNavBar()" routerLink="{{monitorUrl}}" aria-controls="Monitor" routerLinkActive="active">Monitor</span>
</div>
<div class="row menu" [ngClass]="{'selected': selectedRoute.indexOf('workplace') !== -1 || selectedRoute === ''}">
<div *ngIf="workplaceAccess" class="row menu" [ngClass]="{'selected': selectedRoute.indexOf('workplace') !== -1 || selectedRoute === ''}">
<span (click)="toogleNavBar()" routerLink="{{workplaceUrl}}" aria-controls="Workplace" routerLinkActive="active">Workplace</span>
</div>
</div>

View File

@ -14,53 +14,52 @@ import { DomainService } from 'app/services/domain/domain.service';
import { DomainServiceMock } from 'app/services/domain/domain.service.mock';
import { BusinessAdminGuard } from 'app/guards/business-admin-guard';
import { MonitorGuard } from 'app/guards/monitor-guard';
import { TaskanaEngineService } from 'app/services/taskana-engine/taskana-engine.service';
import { WindowRefService } from 'app/services/window/window.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
import { UserInfoModel } from 'app/models/user-info';
import { configureTests } from 'app/app.test.configuration';
describe('NavBarComponent', () => {
let component: NavBarComponent;
let fixture: ComponentFixture<NavBarComponent>;
let debugElement, navBar, taskanaEngineService;
let debugElement, navBar;
const routes: Routes = [
{ path: 'classifications', component: NavBarComponent }
];
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [NavBarComponent, UserInformationComponent],
imports: [
AngularSvgIconModule,
HttpClientModule,
RouterTestingModule.withRoutes(routes),
SharedModule
],
providers: [SelectedRouteService, {
provide: DomainService,
useClass: DomainServiceMock
},
BusinessAdminGuard,
MonitorGuard,
TaskanaEngineService,
WindowRefService,
ErrorModalService,
RequestInProgressService]
})
.compileComponents();
}));
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
declarations: [NavBarComponent, UserInformationComponent],
imports: [
AngularSvgIconModule,
HttpClientModule,
RouterTestingModule.withRoutes(routes),
SharedModule
],
providers: [SelectedRouteService, {
provide: DomainService,
useClass: DomainServiceMock
},
BusinessAdminGuard,
MonitorGuard,
WindowRefService,
ErrorModalService,
RequestInProgressService]
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(NavBarComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
navBar = fixture.debugElement.componentInstance;
fixture.detectChanges();
done();
});
beforeEach(() => {
fixture = TestBed.createComponent(NavBarComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
navBar = fixture.debugElement.componentInstance;
taskanaEngineService = TestBed.get(TaskanaEngineService);
spyOn(taskanaEngineService, 'getUserInformation').and.returnValue(Observable.of(new UserInfoModel));
fixture.detectChanges();
});
afterEach(() => {

View File

@ -7,6 +7,8 @@ import { DomainService } from 'app/services/domain/domain.service';
import { BusinessAdminGuard } from 'app/guards/business-admin-guard';
import { MonitorGuard } from 'app/guards/monitor-guard';
import { WindowRefService } from 'app/services/window/window.service';
import { UserGuard } from 'app/guards/user-guard';
import { TaskanaEngineService } from '../../services/taskana-engine/taskana-engine.service';
@Component({
selector: 'taskana-nav-bar',
templateUrl: './nav-bar.component.html',
@ -45,14 +47,14 @@ export class NavBarComponent implements OnInit, OnDestroy {
administrationAccess = false;
monitorAccess = false;
workplaceAccess = false;
selectedRouteSubscription: Subscription;
constructor(
private selectedRouteService: SelectedRouteService,
private domainService: DomainService,
private businessAdminGuard: BusinessAdminGuard,
private monitorGuard: MonitorGuard,
private taskanaEngineService: TaskanaEngineService,
private window: WindowRefService) { }
ngOnInit() {
@ -68,12 +70,9 @@ export class NavBarComponent implements OnInit, OnDestroy {
this.selectedDomain = domain;
});
this.businessAdminGuard.canActivate().subscribe(hasAccess => {
this.administrationAccess = hasAccess
});
this.monitorGuard.canActivate().subscribe(hasAccess => {
this.monitorAccess = hasAccess
});
this.administrationAccess = this.taskanaEngineService.hasRole(BusinessAdminGuard.roles);
this.monitorAccess = this.taskanaEngineService.hasRole(MonitorGuard.roles);
this.workplaceAccess = this.taskanaEngineService.hasRole(UserGuard.roles);
}
switchDomain(domain) {

View File

@ -0,0 +1,6 @@
<div *ngIf ="showNoAccess" class="col-xs-12 container-no-access">
<div class="center-block no-access">
<h3 class="grey">You do not have access to taskana application</h3>
<svg-icon class="img-responsive no-access-icon" src="./assets/icons/noaccess.svg"></svg-icon>
</div>
</div>

View File

@ -8,13 +8,7 @@
}
.container-no-access{
top:30vh;
top:20vh;
height: 100vh;
}
.center-block.no-access {
text-align: center;
}
.back-button {
margin:0px;
border:none;
}

View File

@ -0,0 +1,40 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NoAccessComponent } from './no-access.component';
import { Router, Routes, ActivatedRoute, NavigationStart, RouterEvent } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { AngularSvgIconModule } from 'angular-svg-icon';
import { HttpModule } from '@angular/http';
import { HttpClientModule } from '@angular/common/http';
import { configureTests } from 'app/app.test.configuration';
describe('NoAccessComponent', () => {
let component: NoAccessComponent;
let fixture: ComponentFixture<NoAccessComponent>;
let debugElement;
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
imports: [RouterTestingModule, AngularSvgIconModule, HttpModule, HttpClientModule],
declarations: [NoAccessComponent]
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(NoAccessComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
done();
});
});
afterEach(() => {
document.body.removeChild(debugElement);
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,29 @@
import { Component, OnInit } from '@angular/core';
import { TaskanaEngineService } from '../../services/taskana-engine/taskana-engine.service';
import { BusinessAdminGuard } from 'app/guards/business-admin-guard';
import { MonitorGuard } from 'app/guards/monitor-guard';
import { UserGuard } from 'app/guards/user-guard';
import { Router } from '@angular/router';
@Component({
selector: 'taskana-no-access',
templateUrl: './no-access.component.html',
styleUrls: ['./no-access.component.scss']
})
export class NoAccessComponent implements OnInit {
showNoAccess = false;
constructor(private taskanaEngineService: TaskanaEngineService, public router: Router) { }
ngOnInit() {
if (this.taskanaEngineService.hasRole(BusinessAdminGuard.roles)) {
this.router.navigate(['administration']);
} else if (this.taskanaEngineService.hasRole(MonitorGuard.roles)) {
this.router.navigate(['monitor']);
} else if (this.taskanaEngineService.hasRole(UserGuard.roles)) {
this.router.navigate(['workplace']);
} else {
this.showNoAccess = true;
}
}
}

View File

@ -6,29 +6,35 @@ import { HttpModule } from '@angular/http';
import { UserInformationComponent } from './user-information.component';
import { TaskanaEngineService } from 'app/services/taskana-engine/taskana-engine.service';
import { UserInfoModel } from 'app/models/user-info';
import { configureTests } from 'app/app.test.configuration';
describe('UserInformationComponent', () => {
let component: UserInformationComponent;
let fixture: ComponentFixture<UserInformationComponent>;
let taskanaEngineService;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [AngularSvgIconModule,
HttpClientModule, HttpModule],
declarations: [UserInformationComponent],
providers: [TaskanaEngineService]
})
.compileComponents();
}));
let debugElement;
beforeEach(() => {
fixture = TestBed.createComponent(UserInformationComponent);
component = fixture.componentInstance;
taskanaEngineService = TestBed.get(TaskanaEngineService);
spyOn(taskanaEngineService, 'getUserInformation').and.returnValue(Observable.of(new UserInfoModel));
fixture.detectChanges();
beforeEach(done => {
const configure = (testBed: TestBed) => {
testBed.configureTestingModule({
imports: [AngularSvgIconModule,
HttpClientModule, HttpModule],
declarations: [UserInformationComponent],
})
};
configureTests(configure).then(testBed => {
fixture = TestBed.createComponent(UserInformationComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
fixture.detectChanges();
done();
});
});
afterEach(() => {
document.body.removeChild(debugElement);
});
it('should create', () => {

View File

@ -28,10 +28,8 @@ export class UserInformationComponent implements OnInit {
constructor(private taskanaEngineService: TaskanaEngineService) { }
ngOnInit() {
this.taskanaEngineService.getUserInformation().subscribe(userInfo => {
this.userInformation = userInfo;
this.roles = '[' + userInfo.roles.join(',') + ']';
})
this.userInformation = this.taskanaEngineService.currentUserInfo;
this.roles = '[' + this.taskanaEngineService.currentUserInfo.roles.join(',') + ']';
}
toogleRoles() {

View File

@ -6,37 +6,23 @@ import { DomainService } from 'app/services/domain/domain.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service';
import { ErrorModel } from 'app/models/modal-error';
import { TaskanaEngineService } from 'app/services/taskana-engine/taskana-engine.service';
import { WindowRefService } from 'app/services/window/window.service';
@Injectable()
export class BusinessAdminGuard implements CanActivate {
constructor(private taskanaEngineService: TaskanaEngineService, public router: Router,
private window: WindowRefService) { }
static roles = ['ADMIN', 'BUSINESS_ADMIN'];
constructor(private taskanaEngineService: TaskanaEngineService, public router: Router) { }
canActivate() {
return this.taskanaEngineService.getUserInformation().map(userInfo => {
if (userInfo.roles.length === 0) {
return this.navigateToWorplace();
}
const adminRole = userInfo.roles.find(role => {
if (role === 'BUSINESS_ADMIN' || role === 'ADMIN') {
return true;
}
});
if (adminRole) {
return true;
}
return this.navigateToWorplace();
}).catch(() => {
return Observable.of(this.navigateToWorplace())
});
if (this.taskanaEngineService.hasRole(BusinessAdminGuard.roles)) {
return true;
}
return this.navigateToWorkplace();
}
navigateToWorplace(): boolean {
if (this.window.nativeWindow.location.href.indexOf('administration') !== -1) {
this.router.navigate(['workplace']);
}
navigateToWorkplace(): boolean {
this.router.navigate(['workplace']);
return false
}
}

View File

@ -10,33 +10,18 @@ import { WindowRefService } from 'app/services/window/window.service';
@Injectable()
export class MonitorGuard implements CanActivate {
constructor(private taskanaEngineService: TaskanaEngineService, public router: Router,
private window: WindowRefService) { }
static roles = ['ADMIN', 'MONITOR'];
constructor(private taskanaEngineService: TaskanaEngineService, public router: Router) { }
canActivate() {
return this.taskanaEngineService.getUserInformation().map(userInfo => {
if (userInfo.roles.length === 0) {
return this.navigateToWorplace();
}
const adminRole = userInfo.roles.find(role => {
if (role === 'MONITOR' || role === 'ADMIN') {
return true;
}
});
if (adminRole) {
return true;
}
return this.navigateToWorplace();
}).catch(() => {
return Observable.of(this.navigateToWorplace())
});
if (this.taskanaEngineService.hasRole(MonitorGuard.roles)) {
return true;
}
return this.navigateToWorkplace();
}
navigateToWorplace(): boolean {
if (this.window.nativeWindow.location.href.indexOf('monitor') !== -1) {
this.router.navigate(['workplace']);
}
return false
navigateToWorkplace(): boolean {
this.router.navigate(['workplace']);
return false;
}
}

View File

@ -0,0 +1,26 @@
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '@angular/common/http';
import { CanActivate, Router } from '@angular/router';
import { Injectable } from '@angular/core';
import { DomainService } from 'app/services/domain/domain.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service';
import { ErrorModel } from 'app/models/modal-error';
import { TaskanaEngineService } from 'app/services/taskana-engine/taskana-engine.service';
import { WindowRefService } from 'app/services/window/window.service';
@Injectable()
export class UserGuard implements CanActivate {
static roles = ['ADMIN', 'USER'];
constructor(private taskanaEngineService: TaskanaEngineService, public router: Router) { }
canActivate() {
if (this.taskanaEngineService.hasRole(UserGuard.roles)) {
return true;
}
return this.navigateToNoRole();
}
navigateToNoRole(): boolean {
this.router.navigate(['no-role']);
return false;
}
}

View File

@ -5,6 +5,7 @@ import { environment } from 'app/../environments/environment';
import { Injectable, Inject } from '@angular/core';
import { TitlesService } from 'app/services/titles/titles.service';
import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service';
import { TaskanaEngineService } from 'app/services/taskana-engine/taskana-engine.service';
@Injectable()
export class StartupService {
@ -12,7 +13,8 @@ export class StartupService {
constructor(
private httpClient: HttpClient,
private titlesService: TitlesService,
private customFieldsService: CustomFieldsService) { }
private customFieldsService: CustomFieldsService,
private taskanaEngineService: TaskanaEngineService) { }
load(): Promise<any> {
return this.loadEnvironment();
@ -21,7 +23,9 @@ export class StartupService {
private loadEnvironment() {
return this.getEnvironmentFilePromise().then(
() => this.geCustomizedFieldsFilePromise()
);
).then(
() => this.taskanaEngineService.getUserInformation()
)
}
getEnvironmentFilePromise() {

View File

@ -0,0 +1,44 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { environment } from 'environments/environment';
import { UserInfoModel } from 'app/models/user-info';
import { ReplaySubject } from 'rxjs/ReplaySubject';
@Injectable()
export class TaskanaEngineServiceMock {
currentUserInfo: UserInfoModel;
constructor(
) {
this.getUserInformation();
}
// GET
getUserInformation(): Promise<any> {
this.currentUserInfo = new UserInfoModel('userid', [''], ['admin']);
return Observable.of().toPromise();
}
hasRole(roles2Find: Array<string>): boolean {
if (!this.currentUserInfo || this.currentUserInfo.roles.length < 1) {
return false;
}
if (this.findRole(roles2Find)) {
return true;
}
return false;
}
private findRole(roles2Find: Array<string>) {
return this.currentUserInfo.roles.find(role => {
return roles2Find.some(roleLookingFor => {
if (role === roleLookingFor) {
return true;
}
});
});
}
}

View File

@ -9,24 +9,38 @@ import { ReplaySubject } from 'rxjs/ReplaySubject';
@Injectable()
export class TaskanaEngineService {
private dataObs$ = new ReplaySubject<UserInfoModel>(1);
currentUserInfo: UserInfoModel;
constructor(
private httpClient: HttpClient
) { }
// GET
getUserInformation(forceRefresh = false): Observable<UserInfoModel> {
if (!this.dataObs$.observers.length || forceRefresh) {
this.httpClient.get<UserInfoModel>(`${environment.taskanaRestUrl}/v1/current-user-info`).subscribe(
data => this.dataObs$.next(data),
error => {
this.dataObs$.error(error);
this.dataObs$ = new ReplaySubject(1);
}
);
}
return this.dataObs$;
getUserInformation(): Promise<any> {
return this.httpClient.get<any>(`${environment.taskanaRestUrl}/v1/current-user-info`).map(
data => {
this.currentUserInfo = data
}
).toPromise();
}
hasRole(roles2Find: Array<string>): boolean {
if (!this.currentUserInfo || this.currentUserInfo.roles.length < 1) {
return false;
}
if (this.findRole(roles2Find)) {
return true;
}
return false;
}
private findRole(roles2Find: Array<string>) {
return this.currentUserInfo.roles.find(role => {
return roles2Find.some(roleLookingFor => {
if (role === roleLookingFor) {
return true;
}
});
});
}
}