TSK-1349: Added unit test for access items management (#1218)
* TSK-1349: added unit test for access items management * TSK-1349: updated test * TSK-1349: clean up test code * TSK-1349: fixed fixture not working correctly in test * TSK-1349: added shared sort stub * TSK-1349: added new tests and fixed html attr * TSK-1349: updated test desc and matcher * TSK-1349: fixed stub not working correctly
This commit is contained in:
parent
72d4c3150a
commit
8a6e68d0b9
|
@ -1,13 +0,0 @@
|
||||||
var SeedReporter = function (baseReporterDecorator) {
|
|
||||||
baseReporterDecorator(this);
|
|
||||||
|
|
||||||
this.onBrowserComplete = function (browser, result) {
|
|
||||||
if (result.order && result.order.random && result.order.seed) {
|
|
||||||
this.write('%s: Randomized with seed %s\n', browser, result.order.seed);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
'reporter:jasmine-seed': ['type', SeedReporter]
|
|
||||||
};
|
|
|
@ -3,7 +3,9 @@ const { compilerOptions } = require('./tsconfig');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
preset: 'jest-preset-angular',
|
preset: 'jest-preset-angular',
|
||||||
roots: ['<rootDir>/src/'],
|
roots: ['<rootDir>/src'],
|
||||||
|
modulePaths: ['<rootDir>'],
|
||||||
|
moduleDirectories: ['node_modules', 'src'],
|
||||||
testMatch: ['**/+(*.)+(spec).+(ts)'],
|
testMatch: ['**/+(*.)+(spec).+(ts)'],
|
||||||
setupFilesAfterEnv: ['<rootDir>/src/test.ts'],
|
setupFilesAfterEnv: ['<rootDir>/src/test.ts'],
|
||||||
collectCoverage: true,
|
collectCoverage: true,
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="col-md-6 col-md-offset-3 margin">
|
<div class="col-md-6 col-md-offset-3 margin">
|
||||||
<taskana-shared-type-ahead #accesId="ngModel" name="accessIdSelected" [(ngModel)]="accessIdSelected"
|
<taskana-shared-type-ahead name="accessIdSelected" [(ngModel)]="accessIdSelected"
|
||||||
placeHolderMessage="Search for access id..."
|
placeHolderMessage="Search for access id..."
|
||||||
(selectedItem)="onSelectAccessId($event)"
|
(selectedItem)="onSelectAccessId($event)"
|
||||||
displayError=true>
|
displayError=true>
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
<!-- CONTENT -->
|
<!-- CONTENT -->
|
||||||
<div *ngIf="accessItemsForm" class="row col-xs-12">
|
<div *ngIf="accessItemsForm" class="row col-xs-12">
|
||||||
<form [formGroup]="accessItemsForm">
|
<ng-form [formGroup]="accessItemsForm">
|
||||||
<!-- TABLE WITH ACCESS ID -->
|
<!-- TABLE WITH ACCESS ID -->
|
||||||
<table id="table-access-items" class="table table-striped table-center">
|
<table id="table-access-items" class="table table-striped table-center">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -153,7 +153,7 @@
|
||||||
<span class="material-icons md-20 red">clear</span>
|
<span class="material-icons md-20 red">clear</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</ng-form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||||
|
import { AccessItemsManagementComponent } from './access-items-management.component';
|
||||||
|
import { FormsValidatorService } from '../../../shared/services/forms-validator/forms-validator.service';
|
||||||
|
import { Actions, NgxsModule, ofActionDispatched, Store } from '@ngxs/store';
|
||||||
|
import { Component, DebugElement, EventEmitter, Input, Output } from '@angular/core';
|
||||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { AngularSvgIconModule } from 'angular-svg-icon';
|
||||||
|
import { RequestInProgressService } from '../../../shared/services/request-in-progress/request-in-progress.service';
|
||||||
|
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
||||||
|
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||||
|
import { EngineConfigurationState } from '../../../shared/store/engine-configuration-store/engine-configuration.state';
|
||||||
|
import { ClassificationCategoriesService } from '../../../shared/services/classification-categories/classification-categories.service';
|
||||||
|
import { AccessItemsManagementState } from '../../../shared/store/access-items-management-store/access-items-management.state';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { GetAccessItems } from '../../../shared/store/access-items-management-store/access-items-management.actions';
|
||||||
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||||
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
|
import { TypeAheadComponent } from '../../../shared/components/type-ahead/type-ahead.component';
|
||||||
|
import { TypeaheadModule } from 'ngx-bootstrap';
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { Direction, Sorting } from '../../../shared/models/sorting';
|
||||||
|
|
||||||
|
const isFieldValidFn = jest.fn().mockReturnValue(true);
|
||||||
|
const formValidatorServiceSpy = jest.fn().mockImplementation(
|
||||||
|
(): Partial<FormsValidatorService> => ({
|
||||||
|
isFieldValid: isFieldValidFn
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const showDialogFn = jest.fn().mockReturnValue(true);
|
||||||
|
const notificationServiceSpy = jest.fn().mockImplementation(
|
||||||
|
(): Partial<NotificationService> => ({
|
||||||
|
showDialog: showDialogFn
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
export const engineConfigInitState = {
|
||||||
|
customisation: {
|
||||||
|
EN: {
|
||||||
|
workbaskets: {
|
||||||
|
'access-items': {
|
||||||
|
accessId: {
|
||||||
|
lookupField: true
|
||||||
|
},
|
||||||
|
custom3: {
|
||||||
|
field: '',
|
||||||
|
visible: false
|
||||||
|
},
|
||||||
|
custom9: {
|
||||||
|
field: 'Some custom field',
|
||||||
|
visible: true
|
||||||
|
},
|
||||||
|
custom10: {
|
||||||
|
field: '',
|
||||||
|
visible: false
|
||||||
|
},
|
||||||
|
custom11: {
|
||||||
|
field: '',
|
||||||
|
visible: false
|
||||||
|
},
|
||||||
|
custom12: {
|
||||||
|
field: '',
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('AccessItemsManagementComponent', () => {
|
||||||
|
let fixture: ComponentFixture<AccessItemsManagementComponent>;
|
||||||
|
let debugElement: DebugElement;
|
||||||
|
let app: AccessItemsManagementComponent;
|
||||||
|
let store: Store;
|
||||||
|
let actions$: Observable<any>;
|
||||||
|
|
||||||
|
@Component({ selector: 'taskana-shared-spinner', template: '' })
|
||||||
|
class TaskanaSharedSpinnerStub {
|
||||||
|
@Input() isRunning: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({ selector: 'taskana-shared-sort', template: '' })
|
||||||
|
class TaskanaSharedSortStub {
|
||||||
|
@Input() sortingFields: Map<string, string>;
|
||||||
|
@Output() performSorting = new EventEmitter<Sorting>();
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
HttpClientTestingModule,
|
||||||
|
NgxsModule.forRoot([EngineConfigurationState, AccessItemsManagementState]),
|
||||||
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
AngularSvgIconModule,
|
||||||
|
MatSnackBarModule,
|
||||||
|
MatDialogModule,
|
||||||
|
TypeaheadModule.forRoot(),
|
||||||
|
BrowserAnimationsModule
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
AccessItemsManagementComponent,
|
||||||
|
TypeAheadComponent,
|
||||||
|
TaskanaSharedSortStub,
|
||||||
|
TaskanaSharedSpinnerStub
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: FormsValidatorService, useClass: formValidatorServiceSpy },
|
||||||
|
{ provide: NotificationService, useClass: notificationServiceSpy },
|
||||||
|
RequestInProgressService,
|
||||||
|
ClassificationCategoriesService
|
||||||
|
]
|
||||||
|
}).compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(AccessItemsManagementComponent);
|
||||||
|
debugElement = fixture.debugElement;
|
||||||
|
app = fixture.debugElement.componentInstance;
|
||||||
|
store = TestBed.inject(Store);
|
||||||
|
actions$ = TestBed.inject(Actions);
|
||||||
|
store.reset({
|
||||||
|
...store.snapshot(),
|
||||||
|
engineConfiguration: engineConfigInitState
|
||||||
|
});
|
||||||
|
app.accessIdSelected = '1';
|
||||||
|
fixture.detectChanges();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should create the app', () => {
|
||||||
|
expect(app).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display header correctly as Access items management', () => {
|
||||||
|
const panelHeader = () => debugElement.nativeElement.querySelector('h4.panel-header').textContent;
|
||||||
|
expect(panelHeader()).toBe('Access items management');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render search type ahead', () => {
|
||||||
|
const typeAhead = () => debugElement.nativeElement.querySelector('taskana-shared-type-ahead');
|
||||||
|
expect(typeAhead()).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not display result table when search bar is empty', () => {
|
||||||
|
const form = () => debugElement.nativeElement.querySelector('ng-form');
|
||||||
|
expect(form()).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should initialize app with ngxs store', () => {
|
||||||
|
const engineConfigs = store.selectSnapshot((state) => {
|
||||||
|
return state.engineConfiguration.customisation.EN.workbaskets['access-items'];
|
||||||
|
});
|
||||||
|
expect(engineConfigs).toBeDefined();
|
||||||
|
expect(engineConfigs).not.toEqual([]);
|
||||||
|
|
||||||
|
const groups = store.selectSnapshot((state) => state.accessItemsManagement);
|
||||||
|
expect(groups).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to get groups if selected access ID is not null in onSelectAccessId', () => {
|
||||||
|
const selectedAccessId = { accessId: '1', name: '' };
|
||||||
|
app.onSelectAccessId(selectedAccessId);
|
||||||
|
const groups = store.selectSnapshot((state) => state.accessItemsManagement);
|
||||||
|
expect(selectedAccessId).not.toBeNull();
|
||||||
|
expect(groups).not.toBeNull();
|
||||||
|
expect(app.accessItemsForm).not.toBeNull();
|
||||||
|
|
||||||
|
app.onSelectAccessId(null);
|
||||||
|
expect(app.accessItemsForm).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should dispatch GetAccessItems action in searchForAccessItemsWorkbaskets', async((done) => {
|
||||||
|
app.accessId = { accessId: '1', name: 'max' };
|
||||||
|
app.groups = [
|
||||||
|
{ accessId: '1', name: 'users' },
|
||||||
|
{ accessId: '2', name: 'users' }
|
||||||
|
];
|
||||||
|
app.sortModel = { sortBy: 'access-id', sortDirection: 'desc' };
|
||||||
|
app.searchForAccessItemsWorkbaskets();
|
||||||
|
fixture.detectChanges();
|
||||||
|
let actionDispatched = false;
|
||||||
|
actions$.pipe(ofActionDispatched(GetAccessItems)).subscribe(() => {
|
||||||
|
actionDispatched = true;
|
||||||
|
expect(actionDispatched).toBe(true);
|
||||||
|
expect(app.setAccessItemsGroups).toHaveBeenCalled();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should display a dialog in when access is revoked', async(() => {
|
||||||
|
app.accessIdSelected = '';
|
||||||
|
const notificationService = TestBed.inject(NotificationService);
|
||||||
|
const showDialogSpy = jest.spyOn(notificationService, 'showDialog').mockImplementation();
|
||||||
|
app.revokeAccess();
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(showDialogSpy).toHaveBeenCalled();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should create accessItemsForm in setAccessItemsGroups', () => {
|
||||||
|
app.setAccessItemsGroups([]);
|
||||||
|
expect(app.accessItemsForm).toBeDefined();
|
||||||
|
expect(app.accessItemsForm).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should invoke sorting function correctly', () => {
|
||||||
|
const newSort = new Sorting('access-id', Direction.DESC);
|
||||||
|
app.accessId = { accessId: '1', name: 'max' };
|
||||||
|
app.groups = [{ accessId: '1', name: 'users' }];
|
||||||
|
app.sorting(newSort);
|
||||||
|
expect(app.sortModel).toMatchObject(newSort);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not return accessItemsGroups when accessItemsForm is null', () => {
|
||||||
|
app.accessItemsForm = null;
|
||||||
|
expect(app.accessItemsGroups).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
|
@ -3,13 +3,11 @@ import { Select, Store } from '@ngxs/store';
|
||||||
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
|
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
import { Observable, Subject } from 'rxjs';
|
import { Observable, Subject } from 'rxjs';
|
||||||
import { FormsValidatorService } from 'app/shared/services/forms-validator/forms-validator.service';
|
import { FormsValidatorService } from 'app/shared/services/forms-validator/forms-validator.service';
|
||||||
import { AccessItemWorkbasketResource } from 'app/shared/models/access-item-workbasket-resource';
|
|
||||||
import { AccessItemWorkbasket } from 'app/shared/models/access-item-workbasket';
|
import { AccessItemWorkbasket } from 'app/shared/models/access-item-workbasket';
|
||||||
import { Direction, Sorting } from 'app/shared/models/sorting';
|
import { Direction, Sorting } from 'app/shared/models/sorting';
|
||||||
import { EngineConfigurationSelectors } from 'app/shared/store/engine-configuration-store/engine-configuration.selectors';
|
import { EngineConfigurationSelectors } from 'app/shared/store/engine-configuration-store/engine-configuration.selectors';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
import { RequestInProgressService } from '../../../shared/services/request-in-progress/request-in-progress.service';
|
import { RequestInProgressService } from '../../../shared/services/request-in-progress/request-in-progress.service';
|
||||||
import { AccessIdsService } from '../../../shared/services/access-ids/access-ids.service';
|
|
||||||
import { AccessIdDefinition } from '../../../shared/models/access-id';
|
import { AccessIdDefinition } from '../../../shared/models/access-id';
|
||||||
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
||||||
import { AccessItemsCustomisation, CustomField, getCustomFields } from '../../../shared/models/customisation';
|
import { AccessItemsCustomisation, CustomField, getCustomFields } from '../../../shared/models/customisation';
|
||||||
|
@ -50,7 +48,6 @@ export class AccessItemsManagementComponent implements OnInit {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private accessIdsService: AccessIdsService,
|
|
||||||
private formsValidatorService: FormsValidatorService,
|
private formsValidatorService: FormsValidatorService,
|
||||||
private requestInProgressService: RequestInProgressService,
|
private requestInProgressService: RequestInProgressService,
|
||||||
private notificationService: NotificationService,
|
private notificationService: NotificationService,
|
||||||
|
|
Loading…
Reference in New Issue