[no-issue] error image resolver mimetype should not be part of datatable (#3415)

* move error image custom logic form datatable to documentlist

* change travis

* [fix-test-log] added optional function to data row interface

* [no-issue] fixed datatable tests

* [no-issue] fixing tests
This commit is contained in:
Eugenio Romano
2018-06-08 00:27:01 +02:00
committed by GitHub
parent 346dff436d
commit 08fd49c4e3
16 changed files with 131 additions and 99 deletions

View File

@@ -71,11 +71,20 @@ jobs:
- # Test expors
script: npm run test-export
- stage: Update Apps dependencies
- # Test Update generator-ng2-alfresco-app
if: tag =~ .*beta.*
script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n generator-ng2-alfresco-app
- # Test Update alfresco-content-app
if: tag =~ .*beta.*
script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n alfresco-content-app
- # Test Update adf-app-manager-ui
if: tag =~ .*beta.*
script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n adf-app-manager-ui
- # Test Update aalfresco-ng2-components
if: tag =~ .*beta.*
script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n alfresco-ng2-components
- # Test Update alfresco-modeler-app
if: tag =~ .*beta.*
script: ./scripts/update-project.sh -gnu -t $GITHUB_TOKEN -n alfresco-modeler-app
- stage: Deploy PR
script: node ./scripts/pr-deploy.js -n $TRAVIS_BUILD_NUMBER -u $RANCHER_TOKEN -p $RANCHER_SECRET -s $REPO_RANCHER --image "docker:$REPO_DOCKER/adf/demo-shell:$TRAVIS_BUILD_NUMBER" --env $ENVIRONMENT_NAME -r $ENVIRONMENT_URL || exit 1

View File

@@ -95,6 +95,7 @@
"CUSTOM_FILTER" :"Custom extensions filter",
"MAX_SIZE" : "Max size filter",
"ENABLE_VERSIONING" :"Enable versioning",
"THUMBNAILS" :"Enable Thumbnails",
"DESCRIPTION_UPLOAD" : "Enable upload",
"ENABLE_INFINITE_SCROLL":"Enable Infinite Scrolling",
"MULTISELECT_DESCRIPTION" : "Use Cmd (Mac) or Ctrl (Windows) to toggle selection of multiple items",

View File

@@ -199,6 +199,7 @@
[sorting]="sorting"
[sortingMode]="sortingMode"
[showHeader]="showHeader"
[thumbnails]="thumbnails"
(error)="onNavigationError($event)"
(success)="resetError()"
(ready)="emitReadyEvent($event)"
@@ -477,6 +478,12 @@
</mat-slide-toggle>
</section>
<section>
<mat-slide-toggle [color]="'primary'" (click)="toggleThumbnails()" >{{'DOCUMENT_LIST.THUMBNAILS' |
translate}}
</mat-slide-toggle>
</section>
<section>
<mat-slide-toggle [color]="'primary'" [(ngModel)]="versioning">
{{'DOCUMENT_LIST.ENABLE_VERSIONING' | translate}}

View File

@@ -178,6 +178,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
supportedPages: number[];
currentSiteid = '';
warnOnMultipleUploads = false;
thumbnails = false;
private onCreateFolder: Subscription;
private onEditFolder: Subscription;
@@ -213,6 +214,11 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
return this.folderUpload;
}
toggleThumbnails() {
this.thumbnails = !this.thumbnails;
this.documentList.reload();
}
ngOnInit() {
if (!this.pagination) {
this.pagination = <Pagination>{

View File

@@ -23,7 +23,7 @@ import {
import {
ContentService, DataCellEvent, DataColumn, DataRowActionEvent, DataSorting, DataTableComponent,
DisplayMode, ObjectDataColumn, PaginatedComponent, AppConfigService, DataColumnListComponent,
UserPreferencesService, PaginationModel
UserPreferencesService, PaginationModel, ThumbnailService
} from '@alfresco/adf-core';
import { MinimalNodeEntity, MinimalNodeEntryEntity, NodePaging } from 'alfresco-js-api';
@@ -243,7 +243,8 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
private appConfig: AppConfigService,
private preferences: UserPreferencesService,
private customResourcesService: CustomResourcesService,
private contentService: ContentService) {
private contentService: ContentService,
private thumbnailService: ThumbnailService) {
}
getContextActions(node: MinimalNodeEntity) {
@@ -333,7 +334,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
ngOnInit() {
this.loadLayoutPresets();
this.data = new ShareDataTableAdapter(this.documentListService, null, this.getDefaultSorting(), this.sortingMode);
this.data = new ShareDataTableAdapter(this.documentListService, this.thumbnailService, null, this.getDefaultSorting(), this.sortingMode);
this.data.thumbnails = this.thumbnails;
this.data.permissionsStyle = this.permissionsStyle;
@@ -371,7 +372,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
}
if (!this.data) {
this.data = new ShareDataTableAdapter(this.documentListService, schema, this.getDefaultSorting(), this.sortingMode);
this.data = new ShareDataTableAdapter(this.documentListService, this.thumbnailService, schema, this.getDefaultSorting(), this.sortingMode);
} else if (schema && schema.length > 0) {
this.data.setColumns(schema);
}
@@ -384,7 +385,10 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
ngOnChanges(changes: SimpleChanges) {
this.resetSelection();
if (this.data) {
this.data.thumbnails = this.thumbnails;
}
if (changes.sortingMode && !changes.sortingMode.firstChange && this.data) {
this.data.sortingMode = changes.sortingMode.currentValue;
}

View File

@@ -15,8 +15,7 @@
* limitations under the License.
*/
import { DataRow } from '@alfresco/adf-core';
import { ObjectUtils } from '@alfresco/adf-core';
import { DataRow, ObjectUtils, ThumbnailService } from '@alfresco/adf-core';
import { MinimalNode, MinimalNodeEntity } from 'alfresco-js-api';
import { PermissionStyleModel } from './../models/permissions-style.model';
import { DocumentListService } from './../services/document-list.service';
@@ -34,7 +33,10 @@ export class ShareDataRow implements DataRow {
return this.obj;
}
constructor(private obj: MinimalNodeEntity, private documentListService: DocumentListService, private permissionsStyle: PermissionStyleModel[]) {
constructor(private obj: MinimalNodeEntity,
private documentListService: DocumentListService,
private permissionsStyle: PermissionStyleModel[],
private thumbnailService?: ThumbnailService) {
if (!obj) {
throw new Error(ShareDataRow.ERR_OBJECT_NOT_FOUND);
}
@@ -91,6 +93,10 @@ export class ShareDataRow implements DataRow {
return ObjectUtils.getValue(this.obj.entry, key);
}
imageErrorResolver(event: Event): any {
return this.thumbnailService.getMimeTypeIcon(this.obj.entry.content.mimeType);
}
hasValue(key: string): boolean {
return this.getValue(key) !== undefined;
}

View File

@@ -33,12 +33,12 @@ describe('ShareDataTableAdapter', () => {
});
it('should use client sorting by default', () => {
const adapter = new ShareDataTableAdapter(documentListService, []);
const adapter = new ShareDataTableAdapter(documentListService, null, []);
expect(adapter.sortingMode).toBe('client');
});
it('should not be case sensitive for sorting mode value', () => {
const adapter = new ShareDataTableAdapter(documentListService, []);
const adapter = new ShareDataTableAdapter(documentListService, null, []);
adapter.sortingMode = 'CLIENT';
expect(adapter.sortingMode).toBe('client');
@@ -48,7 +48,7 @@ describe('ShareDataTableAdapter', () => {
});
it('should fallback to client sorting for unknown values', () => {
const adapter = new ShareDataTableAdapter(documentListService, []);
const adapter = new ShareDataTableAdapter(documentListService, null, []);
adapter.sortingMode = 'SeRvEr';
expect(adapter.sortingMode).toBe('server');
@@ -59,28 +59,27 @@ describe('ShareDataTableAdapter', () => {
it('should setup rows and columns with constructor', () => {
let schema = [<DataColumn> {}];
let adapter = new ShareDataTableAdapter(documentListService, schema);
let adapter = new ShareDataTableAdapter(documentListService, null, schema);
expect(adapter.getRows()).toEqual([]);
expect(adapter.getColumns()).toEqual(schema);
});
it('should setup columns when constructor is missing schema', () => {
let adapter = new ShareDataTableAdapter(documentListService, null);
const adapter = new ShareDataTableAdapter(documentListService, null, null);
expect(adapter.getColumns()).toEqual([]);
});
it('should set new columns', () => {
let columns = [<DataColumn> {}, <DataColumn> {}];
let adapter = new ShareDataTableAdapter(documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null, null);
adapter.setColumns(columns);
expect(adapter.getColumns()).toEqual(columns);
});
it('should reset columns', () => {
let columns = [<DataColumn> {}, <DataColumn> {}];
let adapter = new ShareDataTableAdapter(documentListService, columns);
let adapter = new ShareDataTableAdapter(documentListService, null, columns);
expect(adapter.getColumns()).toEqual(columns);
adapter.setColumns(null);
@@ -89,7 +88,7 @@ describe('ShareDataTableAdapter', () => {
it('should set new rows', () => {
let rows = [<DataRow> {}, <DataRow> {}];
let adapter = new ShareDataTableAdapter(documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null, null);
expect(adapter.getRows()).toEqual([]);
adapter.setRows(rows);
@@ -98,7 +97,7 @@ describe('ShareDataTableAdapter', () => {
it('should reset rows', () => {
let rows = [<DataRow> {}, <DataRow> {}];
let adapter = new ShareDataTableAdapter(documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null, null);
adapter.setRows(rows);
expect(adapter.getRows()).toEqual(rows);
@@ -108,7 +107,7 @@ describe('ShareDataTableAdapter', () => {
});
it('should sort new rows', () => {
let adapter = new ShareDataTableAdapter(documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null, null);
spyOn(adapter, 'sort').and.callThrough();
let rows = [<DataRow> {}];
@@ -118,7 +117,7 @@ describe('ShareDataTableAdapter', () => {
});
it('should fail when getting value for missing row', () => {
let adapter = new ShareDataTableAdapter(documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null, null);
let check = () => {
return adapter.getValue(null, <DataColumn> {});
};
@@ -126,7 +125,7 @@ describe('ShareDataTableAdapter', () => {
});
it('should fail when getting value for missing column', () => {
let adapter = new ShareDataTableAdapter(documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null, null);
let check = () => {
return adapter.getValue(<DataRow> {}, null);
};
@@ -145,7 +144,7 @@ describe('ShareDataTableAdapter', () => {
};
let row = new ShareDataRow(file, documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null, null);
let value = adapter.getValue(row, col);
expect(value).toBe(rawValue);
@@ -154,7 +153,7 @@ describe('ShareDataTableAdapter', () => {
it('should generate fallback icon for a file thumbnail with missing mime type', () => {
spyOn(documentListService, 'getDefaultMimeTypeIcon').and.returnValue(`assets/images/ft_ic_miscellaneouse.svg`);
let adapter = new ShareDataTableAdapter(documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null, null);
let file = new FileNode();
file.entry.content.mimeType = null;
@@ -170,7 +169,7 @@ describe('ShareDataTableAdapter', () => {
it('should generate fallback icon for a file with no content entry', () => {
spyOn(documentListService, 'getDefaultMimeTypeIcon').and.returnValue(`assets/images/ft_ic_miscellaneouse.svg`);
let adapter = new ShareDataTableAdapter(documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null, null);
let file = new FileNode();
file.entry.content = null;
@@ -189,7 +188,7 @@ describe('ShareDataTableAdapter', () => {
let file = new FileNode();
file.entry['icon'] = imageUrl;
let adapter = new ShareDataTableAdapter(documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null, null);
let row = new ShareDataRow(file, documentListService, null);
let col = <DataColumn> { type: 'image', key: 'icon' };
@@ -200,7 +199,7 @@ describe('ShareDataTableAdapter', () => {
it('should resolve folder icon', () => {
spyOn(documentListService, 'getMimeTypeIcon').and.returnValue(`assets/images/ft_ic_folder.svg`);
let adapter = new ShareDataTableAdapter(documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null, null);
let row = new ShareDataRow(new FolderNode(), documentListService, null);
let col = <DataColumn> { type: 'image', key: '$thumbnail' };
@@ -212,7 +211,7 @@ describe('ShareDataTableAdapter', () => {
it('should resolve file thumbnail', () => {
let imageUrl = 'http://<addresss>';
let adapter = new ShareDataTableAdapter(documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null, null);
adapter.thumbnails = true;
let file = new FileNode();
@@ -227,7 +226,7 @@ describe('ShareDataTableAdapter', () => {
it('should resolve fallback file icon for unknown node', () => {
spyOn(documentListService, 'getDefaultMimeTypeIcon').and.returnValue(`assets/images/ft_ic_miscellaneous.svg`);
let adapter = new ShareDataTableAdapter(documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null, null);
let file = new FileNode();
file.entry.isFile = false;
@@ -244,7 +243,7 @@ describe('ShareDataTableAdapter', () => {
it('should resolve file icon for content type', () => {
spyOn(documentListService, 'getMimeTypeIcon').and.returnValue(`assets/images/ft_ic_raster_image.svg`);
let adapter = new ShareDataTableAdapter(documentListService, null);
let adapter = new ShareDataTableAdapter(documentListService, null, null);
let file = new FileNode();
file.entry.isFile = false;
@@ -265,7 +264,7 @@ describe('ShareDataTableAdapter', () => {
let folder = new FolderNode();
let col = <DataColumn> { key: 'name' };
let adapter = new ShareDataTableAdapter(documentListService, [col]);
let adapter = new ShareDataTableAdapter(documentListService, null, [col]);
adapter.setSorting(new DataSorting('name', 'asc'));
adapter.setRows([
@@ -288,7 +287,7 @@ describe('ShareDataTableAdapter', () => {
file2.entry['dateProp'] = new Date(2016, 6, 30, 13, 14, 2);
let col = <DataColumn> { key: 'dateProp' };
let adapter = new ShareDataTableAdapter(documentListService, [col]);
let adapter = new ShareDataTableAdapter(documentListService, null, [col]);
adapter.setRows([
new ShareDataRow(file2, documentListService, null),
@@ -318,7 +317,7 @@ describe('ShareDataTableAdapter', () => {
file4.entry.content.sizeInBytes = 2852791665; // 2.66 GB
let col = <DataColumn> { key: 'content.sizeInBytes' };
let adapter = new ShareDataTableAdapter(documentListService, [col]);
let adapter = new ShareDataTableAdapter(documentListService, null, [col]);
adapter.setRows([
new ShareDataRow(file3, documentListService, null),
@@ -351,7 +350,7 @@ describe('ShareDataTableAdapter', () => {
let file6 = new FileNode('b');
let col = <DataColumn> { key: 'name' };
let adapter = new ShareDataTableAdapter(documentListService, [col]);
let adapter = new ShareDataTableAdapter(documentListService, null, [col]);
adapter.setRows([
new ShareDataRow(file4, documentListService, null),

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { DataColumn, DataRow, DataSorting, DataTableAdapter } from '@alfresco/adf-core';
import { DataColumn, DataRow, DataSorting, DataTableAdapter, ThumbnailService } from '@alfresco/adf-core';
import { NodePaging } from 'alfresco-js-api';
import { PermissionStyleModel } from './../models/permissions-style.model';
import { DocumentListService } from './../services/document-list.service';
@@ -51,6 +51,7 @@ export class ShareDataTableAdapter implements DataTableAdapter {
}
constructor(private documentListService: DocumentListService,
private thumbnailService: ThumbnailService,
schema: DataColumn[] = [],
sorting?: DataSorting,
sortingMode: string = 'client') {
@@ -207,7 +208,7 @@ export class ShareDataTableAdapter implements DataTableAdapter {
if (page && page.list) {
let data = page.list.entries;
if (data && data.length > 0) {
rows = data.map(item => new ShareDataRow(item, this.documentListService, this.permissionsStyle));
rows = data.map(item => new ShareDataRow(item, this.documentListService, this.permissionsStyle, this.thumbnailService));
if (this.filter) {
rows = rows.filter(this.filter);

View File

@@ -93,7 +93,8 @@
<div *ngIf="!col.template" class="cell-container">
<ng-container [ngSwitch]="col.type">
<div *ngSwitchCase="'image'" class="cell-value">
<mat-icon *ngIf="isIconValue(row, col); else no_iconvalue">{{ asIconValue(row, col) }}</mat-icon>
<mat-icon *ngIf="isIconValue(row, col); else no_iconvalue">{{ asIconValue(row, col) }}
</mat-icon>
<ng-template #no_iconvalue>
<mat-icon class="adf-datatable-selected"
*ngIf="row.isSelected; else no_selected_row" svgIcon="selected">
@@ -102,7 +103,7 @@
<img
alt="{{ iconAltTextKey(data.getValue(row, col)) | translate }}"
src="{{ data.getValue(row, col) }}"
(error)="onImageLoadingError($event, row.obj.entry.content.mimeType)">
(error)="onImageLoadingError($event, row)">
</ng-template>
</ng-template>
</div>

View File

@@ -29,7 +29,22 @@ import { CoreTestingModule } from '../../../testing/core.testing.module';
import { DataColumnListComponent } from '../../../data-column/data-column-list.component';
import { DataColumnComponent } from '../../../data-column/data-column.component';
describe('DataTable', () => {
class FakeDataRow implements DataRow {
isDropTarget = false;
isSelected = true;
hasValue(key: any) {
return true;
}
getValue() {
return '1';
}
imageErrorResolver() {
return './assets/images/ft_ic_miscellaneous.svg';
}
}
/*tslint:disable:ban*/
fdescribe('DataTable', () => {
let fixture: ComponentFixture<DataTableComponent>;
let dataTable: DataTableComponent;
@@ -881,9 +896,9 @@ describe('DataTable', () => {
src: 'missing-image'
}
};
const row = new FakeDataRow();
dataTable.fallbackThumbnail = '<fallback>';
dataTable.onImageLoadingError(event);
dataTable.onImageLoadingError(event, row);
expect(event.target.src).toBe(dataTable.fallbackThumbnail);
});
@@ -894,23 +909,12 @@ describe('DataTable', () => {
src: originalSrc
}
};
const row = new FakeDataRow();
dataTable.fallbackThumbnail = null;
dataTable.onImageLoadingError(event);
dataTable.onImageLoadingError(event, row);
expect(event.target.src).toBe('./assets/images/ft_ic_miscellaneous.svg' );
});
it('should replace image source with icon if fallback is not available and mimeType is provided', () => {
let event = <any> {
target: {
src: 'missing-image'
}
};
dataTable.onImageLoadingError(event, 'image/png');
expect(event.target.src).toBe('./assets/images/ft_ic_raster_image.svg');
});
it('should not get cell tooltip when row is not provided', () => {
const col = <DataColumn> { key: 'name', type: 'text' };
expect(dataTable.getCellTooltip(null, col)).toBeNull();

View File

@@ -27,7 +27,6 @@ import { DataRowEvent } from '../../data/data-row-event.model';
import { DataRow } from '../../data/data-row.model';
import { DataSorting } from '../../data/data-sorting.model';
import { DataTableAdapter } from '../../data/datatable-adapter';
import { ThumbnailService } from '../../../services/thumbnail.service';
import { ObjectDataRow } from '../../data/object-datarow.model';
import { ObjectDataTableAdapter } from '../../data/object-datatable-adapter';
@@ -175,8 +174,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
private dataRowsChanged: Subscription;
constructor(private elementRef: ElementRef,
differs: IterableDiffers,
private thumbnailService?: ThumbnailService) {
differs: IterableDiffers) {
if (differs) {
this.differ = differs.find([]).create(null);
}
@@ -511,15 +509,14 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
this.emitRowSelectionEvent(domEventName, row);
}
onImageLoadingError(event: Event, mimeType?: string) {
onImageLoadingError(event: Event, row: DataRow) {
if (event) {
let element = <any> event.target;
if (this.fallbackThumbnail) {
element.src = this.fallbackThumbnail;
} else {
element.src = this.thumbnailService.getMimeTypeIcon(mimeType);
element.src = row.imageErrorResolver(event);
}
}
}

View File

@@ -19,6 +19,10 @@ export interface DataRow {
isSelected: boolean;
isDropTarget?: boolean;
cssClass?: string;
hasValue(key: string): boolean;
getValue(key: string): any;
imageErrorResolver?(event: Event): any;
}

View File

@@ -35,4 +35,8 @@ export class ObjectDataRow implements DataRow {
hasValue(key: string): boolean {
return this.getValue(key) !== undefined;
}
imageErrorResolver(event: Event): string {
return '';
}
}

View File

@@ -31,8 +31,7 @@ describe('ProcessFiltersComponent', () => {
let mockErrorFilterPromise;
beforeEach(() => {
fakeGlobalFilterPromise = new Promise(function (resolve, reject) {
resolve([
fakeGlobalFilterPromise = Promise.resolve([
new FilterProcessRepresentationModel({
name: 'FakeInvolvedTasks',
filter: { state: 'open', assignment: 'fake-involved' }
@@ -46,13 +45,10 @@ describe('ProcessFiltersComponent', () => {
filter: { state: 'open', assignment: 'fake-running' }
})
]);
});
mockErrorFilterPromise = new Promise(function (resolve, reject) {
reject({
mockErrorFilterPromise = Promise.reject({
error: 'wrong request'
});
});
processFilterService = new ProcessFilterService(null);
appsProcessService = new AppsProcessService(null, null);
@@ -96,12 +92,7 @@ describe('ProcessFiltersComponent', () => {
});
it('should return the filter task list, filtered By Name', (done) => {
let fakeDeployedApplicationsPromise = new Promise(function (resolve, reject) {
resolve({ id: 1 });
});
spyOn(appsProcessService, 'getDeployedApplicationsByName').and.returnValue(Observable.fromPromise(fakeDeployedApplicationsPromise));
spyOn(appsProcessService, 'getDeployedApplicationsByName').and.returnValue(Observable.fromPromise(Promise.resolve({ id: 1 })));
spyOn(processFilterService, 'getProcessFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
let change = new SimpleChange(null, 'test', true);

View File

@@ -64,9 +64,7 @@ describe('TaskFiltersComponent', () => {
error: 'wrong request'
};
let mockErrorFilterPromise = new Promise(function (resolve, reject) {
reject(mockErrorFilterList);
});
let mockErrorFilterPromise = new Promise.reject(mockErrorFilterList);
let component: TaskFiltersComponent;
let fixture: ComponentFixture<TaskFiltersComponent>;

View File

@@ -241,7 +241,7 @@ describe('TaskHeaderComponent', () => {
}));
it('should call the service\'s unclaim method on unclaiming', async(() => {
spyOn(service, 'unclaimTask');
spyOn(service, 'unclaimTask').and.returnValue(Observable.of(true));
component.taskDetails = new TaskDetailsModel(claimedTaskDetailsMock);
component.refreshData();
fixture.detectChanges();