diff --git a/src/app/search/components/criteria/criteria-by-family.component.spec.ts b/src/app/search/components/criteria/criteria-by-family.component.spec.ts
index d61a1ed6ed652ca4907302747d4dab71db3188d0..2ecf0066aad34d587266f7630ee6d73bc6459d17 100644
--- a/src/app/search/components/criteria/criteria-by-family.component.spec.ts
+++ b/src/app/search/components/criteria/criteria-by-family.component.spec.ts
@@ -196,7 +196,7 @@ describe('[Search][Criteria] Component: CriteriaByFamilyComponent', () => {
     it('#getCriterion(criterionId) should return correct crition', () => {
         const criterionId = 1;
         const criterion = testedComponent.getCriterion(criterionId) as FieldCriterion;
-        expect(criterion.value).toBe('field_criterion_1');
+        expect(criterion.value).toBe('fd_crit_1');
     });
 
     it('raises the add criterion event when clicked', () => {
diff --git a/src/app/search/components/index.ts b/src/app/search/components/index.ts
index d21caf97458298d8b615c9e6df07431c29a694ee..853128c083537dd007d3624927557fdaee0689f8 100644
--- a/src/app/search/components/index.ts
+++ b/src/app/search/components/index.ts
@@ -1,4 +1,4 @@
-import { ProgressComponent } from './progress.component';
+import { ProgressBarComponent } from './progress-bar.component';
 import { DatasetTabsComponent } from './dataset/dataset-tabs.component';
 import { DatasetCardComponent } from './dataset/dataset-card.component';
 import { CriteriaTabsComponent } from './criteria/criteria-tabs.component';
@@ -13,7 +13,7 @@ import { DatatableComponent } from './result/datatable.component';
 import { RendererComponents } from './result/renderer';
 
 export const dummiesComponents = [
-    ProgressComponent,
+    ProgressBarComponent,
     DatasetTabsComponent,
     DatasetCardComponent,
     CriteriaTabsComponent,
diff --git a/src/app/search/components/progress.component.css b/src/app/search/components/progress-bar.component.css
similarity index 100%
rename from src/app/search/components/progress.component.css
rename to src/app/search/components/progress-bar.component.css
diff --git a/src/app/search/components/progress.component.html b/src/app/search/components/progress-bar.component.html
similarity index 95%
rename from src/app/search/components/progress.component.html
rename to src/app/search/components/progress-bar.component.html
index eeb2662d665728e3af2f947e2fe7bcfc0918084f..4ccdbe2489cc42a6b19749fdb6cc7af1e0e2ad0b 100644
--- a/src/app/search/components/progress.component.html
+++ b/src/app/search/components/progress-bar.component.html
@@ -18,7 +18,7 @@
                 Dataset
             </a>
         </li>
-        <li class="nav-item" [ngClass]="{'active': currentStep === 'criteria', 'checked': criteriaStepChecked}">
+        <li id="criteriaStep" class="nav-item" [ngClass]="{'active': currentStep === 'criteria', 'checked': criteriaStepChecked}">
             <a *ngIf="datasetName" class="nav-link" [ngClass]="{'disabled': !datasetName}"
                 routerLink="/search/criteria/{{datasetName}}" [queryParams]="queryParams" data-toggle="tab">
                 <div class="icon-circle">
diff --git a/src/app/search/components/progress-bar.component.spec.ts b/src/app/search/components/progress-bar.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a264f5cacbb2e9abc46d439f47eb7320f1c2c1b3
--- /dev/null
+++ b/src/app/search/components/progress-bar.component.spec.ts
@@ -0,0 +1,64 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+import { By } from '@angular/platform-browser';
+
+import { ProgressBarComponent } from './progress-bar.component';
+
+describe('[Search] Component: ProgressBarComponent', () => {
+    let component: ProgressBarComponent;
+    let fixture: ComponentFixture<ProgressBarComponent>;
+
+    beforeEach(async(() => {
+        TestBed.configureTestingModule({
+            declarations: [ProgressBarComponent],
+            imports: [RouterTestingModule]
+        }).compileComponents();
+    }));
+
+    beforeEach(() => {
+        fixture = TestBed.createComponent(ProgressBarComponent);
+        component = fixture.componentInstance;
+        fixture.detectChanges();
+    });
+
+    it('should create the component', () => {
+        expect(component).toBeTruthy();
+    });
+
+    it('#getStepClass() should return correct step class', () => {
+        let style = component.getStepClass();
+        expect(style).toBe('datasetStep');
+        component.currentStep = 'dataset';
+        style = component.getStepClass();
+        expect(style).toBe('datasetStep');
+        component.currentStep = 'criteria';
+        style = component.getStepClass();
+        expect(style).toBe('criteriaStep');
+        component.currentStep = 'output';
+        style = component.getStepClass();
+        expect(style).toBe('outputStep');
+        component.currentStep = 'result';
+        style = component.getStepClass();
+        expect(style).toBe('resultStep');
+    });
+
+    // TODO: Make test working
+    // it('should apply the correct class', () => {
+    //     component.currentStep = 'dataset';
+    //     fixture.detectChanges();
+    //     let style = fixture.debugElement.query(By.css('#criteriaStep')).nativeElement.getAttribute('class');
+    //     expect(style).not.toContain('active');
+    //     component.currentStep = 'criteria';
+    //     fixture.detectChanges();
+    //     style = fixture.debugElement.query(By.css('#criteriaStep')).nativeElement.getAttribute('class');
+    //     console.log(style);
+    //     expect(style).toContain('active');
+    //     component.criteriaStepChecked = true;
+    //     fixture.detectChanges();
+    //     style = fixture.debugElement.query(By.css('#criteriaStep')).nativeElement.getAttribute('class');
+    //     expect(style).toContain('checked');
+    //     const template = fixture.nativeElement;
+    //     expect(template.querySelector('#criteriaStep')).toBeTruthy();
+    // });
+});
+
diff --git a/src/app/search/components/progress.component.ts b/src/app/search/components/progress-bar.component.ts
similarity index 82%
rename from src/app/search/components/progress.component.ts
rename to src/app/search/components/progress-bar.component.ts
index 5e0e3f1a9840aad97251e6039066c90e2411e975..6e21d2b37b57345391a2e5f90d8ab89b7ddc91a8 100644
--- a/src/app/search/components/progress.component.ts
+++ b/src/app/search/components/progress-bar.component.ts
@@ -1,12 +1,12 @@
 import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
 
 @Component({
-    selector: 'app-progress',
-    templateUrl: 'progress.component.html',
-    styleUrls: ['progress.component.css'],
+    selector: 'app-progress-bar',
+    templateUrl: 'progress-bar.component.html',
+    styleUrls: ['progress-bar.component.css'],
     changeDetection: ChangeDetectionStrategy.OnPush
 })
-export class ProgressComponent {
+export class ProgressBarComponent {
     @Input() currentStep: string;
     @Input() datasetName: string;
     @Input() criteriaStepChecked: boolean;
diff --git a/src/app/search/components/result/datatable.component.html b/src/app/search/components/result/datatable.component.html
index 5188f8230f0fa68575b18d9c3e96d32d700493a1..490653917341460f5f1326554cce31cf1bd557b7 100644
--- a/src/app/search/components/result/datatable.component.html
+++ b/src/app/search/components/result/datatable.component.html
@@ -14,7 +14,7 @@
         </div>
         <div *ngIf="searchMeta">
             <div *ngIf="getDataset().selectable_row" class="mb-2">
-                <button [disabled]="noSelectedData() || processWip" (click)="fireProcess('csv')"
+                <button [disabled]="noSelectedData() || processWip" (click)="emitProcess('csv')"
                     class="btn btn-sm btn-outline-primary">
                     To CSV
                 </button>
@@ -73,16 +73,18 @@
                                         </app-btn>
                                     </div>
                                     <div *ngSwitchCase="'detail-link'">
-                                        <app-detail-link 
-                                            [datasetName]="datasetName" 
+                                        <app-detail
+                                            [style]="'link'"
+                                            [datasetName]="datasetName"
                                             [data]="datum[attribute.label]">
-                                        </app-detail-link>
+                                        </app-detail>
                                     </div>
                                     <div *ngSwitchCase="'detail-btn'">
-                                        <app-detail-btn 
-                                            [datasetName]="datasetName" 
+                                        <app-detail 
+                                            [style]="'btn'"
+                                            [datasetName]="datasetName"
                                             [data]="datum[attribute.label]">
-                                        </app-detail-btn>
+                                        </app-detail>
                                     </div>
                                     <div *ngSwitchCase="'download'">
                                         <app-download
@@ -108,8 +110,13 @@
                 <p>Total items {{ searchMeta.total_items }}</p>
             </div>
             <div class="mt-3">
-                <pagination [totalItems]="searchMeta.total_items" [boundaryLinks]="true" [rotate]="true" [maxSize]="5"
-                    (pageChanged)="getSearchData.emit($event.page)"></pagination>
+                <pagination
+                    [totalItems]="searchMeta.total_items" 
+                    [boundaryLinks]="true" 
+                    [rotate]="true" 
+                    [maxSize]="5"
+                    (pageChanged)="getSearchData.emit($event.page)">
+                </pagination>
             </div>
         </div>
     </accordion-group>
diff --git a/src/app/search/components/result/datatable.component.spec.ts b/src/app/search/components/result/datatable.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3d81096e0512257005ea2e1d53a43f1bbecc76a4
--- /dev/null
+++ b/src/app/search/components/result/datatable.component.spec.ts
@@ -0,0 +1,154 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { Component, Input } from '@angular/core';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+import { AccordionModule } from 'ngx-bootstrap';
+import { DatatableComponent } from './datatable.component';
+import { Dataset } from '../../../metamodel/model';
+import { ATTRIBUTE_LIST, DATASET_LIST } from '../../../../settings/test-data';
+
+describe('[Search][Result] Component: DatatableComponent', () => {
+    @Component({ selector: 'app-img', template: '' })
+    class ImgStubComponent {
+        @Input() src: string;
+    }
+
+    @Component({ selector: 'app-thumbnail', template: '' })
+    class ThumbnailStubComponent {
+        @Input() src: string;
+        @Input() attributeName: string;
+    }
+
+    @Component({ selector: 'app-link', template: '' })
+    class LinkStubComponent {
+        @Input() href: string;
+    }
+
+    @Component({ selector: 'app-btn', template: '' })
+    class BtnStubComponent {
+        @Input() href: string;
+    }
+
+    @Component({ selector: 'app-detail', template: '' })
+    class DetailStubComponent {
+        @Input() style: string;
+        @Input() datasetName: string;
+        @Input() data: string | number;
+    }
+
+    @Component({ selector: 'app-download', template: '' })
+    class DownloadStubComponent {
+        @Input() href: string;
+    }
+
+    @Component({ selector: 'app-json-renderer', template: '' })
+    class JsonStubComponent {
+        @Input() attributeName: string;
+        @Input() json: string;
+    }
+
+    @Component({ selector: 'pagination', template: '' })
+    class PaginationStubComponent {
+        @Input() totalItems: number;
+        @Input() boundaryLinks: boolean;
+        @Input() rotate: boolean;
+        @Input() maxSize: number;
+    }
+
+    let component: DatatableComponent;
+    let fixture: ComponentFixture<DatatableComponent>;
+
+    beforeEach(() => {
+        TestBed.configureTestingModule({
+            declarations: [
+                DatatableComponent,
+                ImgStubComponent,
+                ThumbnailStubComponent,
+                LinkStubComponent,
+                BtnStubComponent,
+                DetailStubComponent,
+                DownloadStubComponent,
+                JsonStubComponent,
+                PaginationStubComponent
+            ],
+            imports: [AccordionModule.forRoot(), BrowserAnimationsModule]
+        });
+        fixture = TestBed.createComponent(DatatableComponent);
+        component = fixture.componentInstance;
+    });
+
+    it('should create the component', () => {
+        expect(component).toBeTruthy();
+    });
+
+    it('#initDatatable() should raise initSearchMeta and getSearchData events', () => {
+        component.initSearchMeta.subscribe((event: {}) => expect(event).toBeUndefined());
+        component.getSearchData.subscribe((event: number) => expect(event).toBe(1));
+        component.initDatatable();
+    });
+
+    it('#getDataset() should return dataset object', () => {
+        component.datasetList = DATASET_LIST;
+        component.datasetName = 'cat_1';
+        const dataset: Dataset = component.getDataset();
+        expect(dataset.name).toBe('cat_1');
+        expect(dataset.label).toBe('Cat 1');
+    });
+
+    it('#getAttributeId(attributeName) should return id of attributeName', () => {
+        component.datasetAttributeList = ATTRIBUTE_LIST;
+        expect(component.getAttributeId('name_one')).toBe(1);
+    });
+
+    it('#getAttributeRenderer(attributeName) should return renderer type of attributeName', () => {
+        component.datasetAttributeList = ATTRIBUTE_LIST;
+        expect(component.getAttributeRenderer('name_one')).toBe('btn');
+    });
+
+    it('#getAttributeUriAction(attributeName, datum) should return uri action of attributeName', () => {
+        component.datasetAttributeList = ATTRIBUTE_LIST;
+        expect(component.getAttributeUriAction('name_one', 'test')).toBe('test');
+        expect(component.getAttributeUriAction('name_two', 'test')).toBe('http://test.com/test');
+    });
+
+    it('#toggleSelection(datum) should return add datum to selectedData', () => {
+        const datum = { label_one: 123456 };
+        component.datasetAttributeList = ATTRIBUTE_LIST;
+        component.selectedData = [];
+        component.addSelectedData.subscribe((event: any) => expect(event).toBe(123456));
+        component.toggleSelection(datum);
+    });
+
+    it('#toggleSelection(datum) should return remove datum to selectedData', () => {
+        const datum = { label_one: 123456 };
+        component.selectedData = [123456];
+        component.datasetAttributeList = ATTRIBUTE_LIST;
+        component.deleteSelectedData.subscribe((event: any) => expect(event).toBe(123456));
+        component.toggleSelection(datum);
+    });
+
+    it('#isSelected(datum) should return true datum is selected', () => {
+        const datum = { label_one: 123456 };
+        component.datasetAttributeList = ATTRIBUTE_LIST;
+        component.selectedData = [123456];
+        expect(component.isSelected(datum)).toBeTruthy();
+    });
+
+    it('#isSelected(datum) should return false datum is not selected', () => {
+        const datum = { label_one: 123456 };
+        component.datasetAttributeList = ATTRIBUTE_LIST;
+        component.selectedData = [];
+        expect(component.isSelected(datum)).toBeFalsy();
+    });
+
+    it('#noSelectedData() should return true if no selectedData', () => {
+        component.selectedData = [];
+        expect(component.noSelectedData()).toBeTruthy();
+    });
+
+    it('#noSelectedData() should return false if there are selectedData', () => {
+        component.selectedData = [123456];
+        expect(component.noSelectedData()).toBeFalsy();
+    });
+});
+
diff --git a/src/app/search/components/result/datatable.component.ts b/src/app/search/components/result/datatable.component.ts
index 61e2890f014b9198bc98165e8c607f4e71514330..78e1c7df3820c63b997181a4ec3027fe4b59e036 100644
--- a/src/app/search/components/result/datatable.component.ts
+++ b/src/app/search/components/result/datatable.component.ts
@@ -78,7 +78,7 @@ export class DatatableComponent {
         return this.selectedData.length < 1;
     }
 
-    fireProcess(typeProcess: string): void {
+    emitProcess(typeProcess: string): void {
         this.executeProcess.emit(typeProcess);
     }
 }
diff --git a/src/app/search/components/result/renderer/btn.component.spec.ts b/src/app/search/components/result/renderer/btn.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..246de811e1606c379928121b76d9db997929c58d
--- /dev/null
+++ b/src/app/search/components/result/renderer/btn.component.spec.ts
@@ -0,0 +1,28 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+
+import { BtnComponent } from './btn.component';
+
+describe('[Search][Result][Renderer] Component: BtnComponent', () => {
+    let component: BtnComponent;
+    let fixture: ComponentFixture<BtnComponent>;
+
+    beforeEach(() => {
+        TestBed.configureTestingModule({
+            declarations: [BtnComponent]
+        });
+        fixture = TestBed.createComponent(BtnComponent);
+        component = fixture.componentInstance;
+    });
+
+    it('should create the component', () => {
+        expect(component).toBeTruthy();
+    });
+
+    it('should fill href tag with href input', () => {
+        component.href = 'https://test.com';
+        fixture.detectChanges();
+        const href = fixture.debugElement.query(By.css('a')).nativeElement.getAttribute('href');
+        expect(href).toBe('https://test.com');
+    });
+});
diff --git a/src/app/search/components/result/renderer/detail-btn.component.html b/src/app/search/components/result/renderer/detail-btn.component.html
deleted file mode 100644
index 4410bd9a6fd1662c3cc359ea0069c6c21e51b5d2..0000000000000000000000000000000000000000
--- a/src/app/search/components/result/renderer/detail-btn.component.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<a routerLink="/detail/{{ datasetName }}/{{ data }}" class="btn btn-outline-primary btn-sm">
-    {{ data }}
-</a>
\ No newline at end of file
diff --git a/src/app/search/components/result/renderer/detail-btn.component.ts b/src/app/search/components/result/renderer/detail-btn.component.ts
deleted file mode 100644
index 4dbe5a58a203cedd52688d0d0225dbc1430729ab..0000000000000000000000000000000000000000
--- a/src/app/search/components/result/renderer/detail-btn.component.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
-
-@Component({
-    selector: 'app-detail-btn',
-    templateUrl: 'detail-btn.component.html',
-    changeDetection: ChangeDetectionStrategy.OnPush
-})
-export class DetailBtnComponent {
-    @Input() datasetName: string;
-    @Input() data: string | number;
-}
diff --git a/src/app/search/components/result/renderer/detail-link.component.html b/src/app/search/components/result/renderer/detail-link.component.html
deleted file mode 100644
index 701009cf769c767ebbafc91f8f36f19db3246cf1..0000000000000000000000000000000000000000
--- a/src/app/search/components/result/renderer/detail-link.component.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<a routerLink="/detail/{{ datasetName }}/{{ data }}">
-    {{ data }}
-</a>
\ No newline at end of file
diff --git a/src/app/search/components/result/renderer/detail.component.html b/src/app/search/components/result/renderer/detail.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..03e4fb0a4727d7081fb561a729d3ddff50dff1ea
--- /dev/null
+++ b/src/app/search/components/result/renderer/detail.component.html
@@ -0,0 +1,3 @@
+<a routerLink="/detail/{{ datasetName }}/{{ data }}" [ngClass]="style === 'btn' ? ' btn btn-outline-primary btn-sm' : ''">
+    {{ data }}
+</a>
\ No newline at end of file
diff --git a/src/app/search/components/result/renderer/detail.component.spec.ts b/src/app/search/components/result/renderer/detail.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..de9932abfb21b5d587ec86ee725a3a8880054e25
--- /dev/null
+++ b/src/app/search/components/result/renderer/detail.component.spec.ts
@@ -0,0 +1,47 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+import { By } from '@angular/platform-browser';
+
+import { DetailComponent } from './detail.component';
+
+describe('[Search][Result][Renderer] Component: DetailComponent', () => {
+    let component: DetailComponent;
+    let fixture: ComponentFixture<DetailComponent>;
+
+    beforeEach(() => {
+        TestBed.configureTestingModule({
+            declarations: [DetailComponent],
+            imports: [RouterTestingModule]
+        });
+        fixture = TestBed.createComponent(DetailComponent);
+        component = fixture.componentInstance;
+    });
+
+    it('should create the component', () => {
+        expect(component).toBeTruthy();
+    });
+
+    it('should apply link style if link style', () => {
+        component.style = 'link';
+        fixture.detectChanges();
+        const style = fixture.debugElement.query(By.css('a')).nativeElement.getAttribute('class');
+        expect(style).toBeNull();
+    });
+
+    it('should add button classes if btn style', () => {
+        component.style = 'btn';
+        fixture.detectChanges();
+        const style = fixture.debugElement.query(By.css('a')).nativeElement.getAttribute('class');
+        expect(style).toContain('btn');
+        expect(style).toContain('btn-outline-primary');
+        expect(style).toContain('btn-sm');
+    });
+
+    it('should fill routerLink param correctly', () => {
+        component.datasetName = 'cat_1';
+        component.data = 'id_test';
+        fixture.detectChanges();
+        const href = fixture.debugElement.query(By.css('a')).nativeElement.getAttribute('href');
+        expect(href).toEqual('/detail/' + component.datasetName + '/' + component.data);
+    });
+});
diff --git a/src/app/search/components/result/renderer/detail-link.component.ts b/src/app/search/components/result/renderer/detail.component.ts
similarity index 62%
rename from src/app/search/components/result/renderer/detail-link.component.ts
rename to src/app/search/components/result/renderer/detail.component.ts
index 8418682adbd4a86dd8bd2aa1849f1d913ad6cf9d..fef72d9bc1a08aae7150d43c561f82c6f4ab1897 100644
--- a/src/app/search/components/result/renderer/detail-link.component.ts
+++ b/src/app/search/components/result/renderer/detail.component.ts
@@ -1,11 +1,12 @@
 import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
 
 @Component({
-    selector: 'app-detail-link',
-    templateUrl: 'detail-link.component.html',
+    selector: 'app-detail',
+    templateUrl: 'detail.component.html',
     changeDetection: ChangeDetectionStrategy.OnPush
 })
-export class DetailLinkComponent {
+export class DetailComponent {
+    @Input() style: string;
     @Input() datasetName: string;
     @Input() data: string | number;
 }
diff --git a/src/app/search/components/result/renderer/download.component.spec.ts b/src/app/search/components/result/renderer/download.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8519538ccee81d638c3b58e7321115bb76636ba0
--- /dev/null
+++ b/src/app/search/components/result/renderer/download.component.spec.ts
@@ -0,0 +1,28 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+
+import { DownloadComponent } from './download.component';
+
+describe('[Search][Result][Renderer] Component: DownloadComponent', () => {
+    let component: DownloadComponent;
+    let fixture: ComponentFixture<DownloadComponent>;
+
+    beforeEach(() => {
+        TestBed.configureTestingModule({
+            declarations: [DownloadComponent]
+        });
+        fixture = TestBed.createComponent(DownloadComponent);
+        component = fixture.componentInstance;
+    });
+
+    it('should create the component', () => {
+        expect(component).toBeTruthy();
+    });
+
+    it('should fill href tag with href input', () => {
+        component.href = 'https://test.com';
+        fixture.detectChanges();
+        const href = fixture.debugElement.query(By.css('a')).nativeElement.getAttribute('href');
+        expect(href).toBe('https://test.com');
+    });
+});
diff --git a/src/app/search/components/result/renderer/img.component.spec.ts b/src/app/search/components/result/renderer/img.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d46ebcf5069518febf5e96f5cbb9bee76cf94d69
--- /dev/null
+++ b/src/app/search/components/result/renderer/img.component.spec.ts
@@ -0,0 +1,30 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+
+import { ImgComponent } from './img.component';
+
+describe('[Search][Result][Renderer] Component: ImgComponent', () => {
+    let component: ImgComponent;
+    let fixture: ComponentFixture<ImgComponent>;
+
+    beforeEach(() => {
+        TestBed.configureTestingModule({
+            declarations: [ImgComponent]
+        });
+        fixture = TestBed.createComponent(ImgComponent);
+        component = fixture.componentInstance;
+    });
+
+    it('should create the component', () => {
+        expect(component).toBeTruthy();
+    });
+
+    it('should fill src and alt tags with src input', () => {
+        component.src = 'url_image';
+        fixture.detectChanges();
+        const src = fixture.debugElement.query(By.css('img')).nativeElement.getAttribute('src');
+        expect(src).toBe('url_image');
+        const alt = fixture.debugElement.query(By.css('img')).nativeElement.getAttribute('alt');
+        expect(alt).toBe('url_image');
+    });
+});
diff --git a/src/app/search/components/result/renderer/index.ts b/src/app/search/components/result/renderer/index.ts
index 78d423370b35746b6ce7cbe9b8d57e0f4533bad4..e1e04ba6bd995ff3920035e25581039ded3864ea 100644
--- a/src/app/search/components/result/renderer/index.ts
+++ b/src/app/search/components/result/renderer/index.ts
@@ -2,8 +2,7 @@ import { ImgComponent } from './img.component';
 import { ThumbnailComponent } from './thumbnail.component';
 import { LinkComponent } from './link.component';
 import { BtnComponent } from './btn.component';
-import { DetailLinkComponent } from './detail-link.component';
-import { DetailBtnComponent } from './detail-btn.component';
+import { DetailComponent } from './detail.component';
 import { DownloadComponent } from './download.component';
 import { JsonComponent } from './json.component';
 
@@ -12,8 +11,7 @@ export const RendererComponents = [
     ThumbnailComponent,
     LinkComponent,
     BtnComponent,
-    DetailLinkComponent,
-    DetailBtnComponent,
+    DetailComponent,
     DownloadComponent,
     JsonComponent
 ];
diff --git a/src/app/search/components/result/renderer/json.component.spec.ts b/src/app/search/components/result/renderer/json.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d83fbb16bc82965e0ebf8b01265dee084ef02c0c
--- /dev/null
+++ b/src/app/search/components/result/renderer/json.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { NgxJsonViewerModule } from 'ngx-json-viewer';
+import { ModalModule } from 'ngx-bootstrap';
+import { BsModalService } from 'ngx-bootstrap/modal';
+
+import { JsonComponent } from './json.component';
+
+describe('[Search][Result][Renderer] Component: JsonComponent', () => {
+    let component: JsonComponent;
+    let fixture: ComponentFixture<JsonComponent>;
+
+    beforeEach(() => {
+        TestBed.configureTestingModule({
+            declarations: [JsonComponent],
+            imports: [NgxJsonViewerModule, ModalModule.forRoot()],
+            providers: [BsModalService]
+        });
+        fixture = TestBed.createComponent(JsonComponent);
+        component = fixture.componentInstance;
+    });
+
+    it('should create the component', () => {
+        expect(component).toBeTruthy();
+    });
+});
diff --git a/src/app/search/components/result/renderer/link.component.spec.ts b/src/app/search/components/result/renderer/link.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..be84b4e12e1619abcbd7cf888b2a5773f6ff774a
--- /dev/null
+++ b/src/app/search/components/result/renderer/link.component.spec.ts
@@ -0,0 +1,28 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+
+import { LinkComponent } from './link.component';
+
+describe('[Search][Result][Renderer] Component: LinkComponent', () => {
+    let component: LinkComponent;
+    let fixture: ComponentFixture<LinkComponent>;
+
+    beforeEach(() => {
+        TestBed.configureTestingModule({
+            declarations: [LinkComponent]
+        });
+        fixture = TestBed.createComponent(LinkComponent);
+        component = fixture.componentInstance;
+    });
+
+    it('should create the component', () => {
+        expect(component).toBeTruthy();
+    });
+
+    it('should fill href tags with href input', () => {
+        component.href = 'https://test.com';
+        fixture.detectChanges();
+        const href = fixture.debugElement.query(By.css('a')).nativeElement.getAttribute('href');
+        expect(href).toBe('https://test.com');
+    });
+});
diff --git a/src/app/search/components/result/renderer/link.component.ts b/src/app/search/components/result/renderer/link.component.ts
index 455bb35a1c8f5e9fcfa74a48839a25d12848bebf..966244c25718f3eb668e4053434d7812171a4cad 100644
--- a/src/app/search/components/result/renderer/link.component.ts
+++ b/src/app/search/components/result/renderer/link.component.ts
@@ -5,6 +5,6 @@ import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
     templateUrl: 'link.component.html',
     changeDetection: ChangeDetectionStrategy.OnPush
 })
-export class LinkComponent{
+export class LinkComponent {
     @Input() href: string;
 }
diff --git a/src/app/search/components/result/renderer/thumbnail.component.spec.ts b/src/app/search/components/result/renderer/thumbnail.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a7b3863358b05e215f7e34ddbca1e2e0360439c9
--- /dev/null
+++ b/src/app/search/components/result/renderer/thumbnail.component.spec.ts
@@ -0,0 +1,34 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+
+import { ModalModule } from 'ngx-bootstrap';
+import { BsModalService } from 'ngx-bootstrap/modal';
+import { ThumbnailComponent } from './thumbnail.component';
+
+describe('[Search][Result][Renderer] Component: ThumbnailComponent', () => {
+    let component: ThumbnailComponent;
+    let fixture: ComponentFixture<ThumbnailComponent>;
+
+    beforeEach(() => {
+        TestBed.configureTestingModule({
+            declarations: [ThumbnailComponent],
+            imports: [ModalModule.forRoot()],
+            providers: [BsModalService]
+        });
+        fixture = TestBed.createComponent(ThumbnailComponent);
+        component = fixture.componentInstance;
+    });
+
+    it('should create the component', () => {
+        expect(component).toBeTruthy();
+    });
+
+    it('should fill src and alt tags with src input', () => {
+        component.src = 'url_image';
+        fixture.detectChanges();
+        const src = fixture.debugElement.query(By.css('img')).nativeElement.getAttribute('src');
+        expect(src).toBe('url_image');
+        const alt = fixture.debugElement.query(By.css('img')).nativeElement.getAttribute('alt');
+        expect(alt).toBe('url_image');
+    });
+});
diff --git a/src/app/search/components/result/url-display.component.spec.ts b/src/app/search/components/result/url-display.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..95ab48dfde50f8fce7d4150374e9581b405aea52
--- /dev/null
+++ b/src/app/search/components/result/url-display.component.spec.ts
@@ -0,0 +1,41 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+import { AccordionModule } from 'ngx-bootstrap';
+import { ToastrModule } from 'ngx-toastr';
+import { ToastrService } from 'ngx-toastr';
+import { UrlDisplayComponent } from './url-display.component';
+import { CRITERIA_LIST } from '../../../../settings/test-data';
+
+describe('[Search][Result] Component: UrlDisplayComponent', () => {
+    let component: UrlDisplayComponent;
+    let fixture: ComponentFixture<UrlDisplayComponent>;
+
+    beforeEach(() => {
+        TestBed.configureTestingModule({
+            declarations: [UrlDisplayComponent],
+            imports: [AccordionModule.forRoot(), BrowserAnimationsModule, ToastrModule.forRoot()],
+            providers: [ToastrService]
+        });
+        fixture = TestBed.createComponent(UrlDisplayComponent);
+        component = fixture.componentInstance;
+    });
+
+    it('should create the component', () => {
+        expect(component).toBeTruthy();
+    });
+
+    it('#getUrl() should construct url', () => {
+        component.apiPath = 'http://test.com';
+        component.instanceName = 'instance';
+        component.datasetName = 'dataset';
+        component.outputList = [1, 2, 3];
+        component.criteriaList = [];
+        let url = component.getUrl();
+        expect(url).toBe('http://test.com/instance/data/dataset?a=1;2;3');
+        component.criteriaList = CRITERIA_LIST;
+        url = component.getUrl();
+        expect(url).toBe('http://test.com/instance/data/dataset?a=1;2;3&c=1::eq::fd_crit_1;2::eq::fd_crit_2');
+    });
+});
+
diff --git a/src/app/search/containers/search.component.html b/src/app/search/containers/search.component.html
index 57b43f8658d2084bf1a00dcc9c547dbf24edbe44..f14df6ea0fe67813fac064a3963c210739682325 100644
--- a/src/app/search/containers/search.component.html
+++ b/src/app/search/containers/search.component.html
@@ -1,11 +1,11 @@
 <div class="mx-5 px-5">
-    <app-progress
+    <app-progress-bar
         [currentStep]="currentStep | async"
         [datasetName]="datasetName | async"
         [criteriaStepChecked]="criteriaStepChecked | async"
         [outputStepChecked]="outputStepChecked | async"
         [resultStepChecked]="resultStepChecked | async"
         [queryParams]="queryParams | async">
-    </app-progress>
+    </app-progress-bar>
     <router-outlet></router-outlet>
 </div>
\ No newline at end of file
diff --git a/src/settings/test-data/attribute-list.ts b/src/settings/test-data/attribute-list.ts
index 9f9a46af9e3ad925b0b02e02ba3a8feb0ad6db6b..a816c68eedfb1479388685f8a313e0b2e4600963 100644
--- a/src/settings/test-data/attribute-list.ts
+++ b/src/settings/test-data/attribute-list.ts
@@ -19,7 +19,7 @@ export const ATTRIBUTE_LIST: Attribute[] = [
         placeholder_min: '1',
         placeholder_max: '10',
         uri_action: '',
-        renderer: '',
+        renderer: 'btn',
         display_detail: 2,
         selected: true,
         order_by: true,
@@ -57,7 +57,7 @@ export const ATTRIBUTE_LIST: Attribute[] = [
         max: null,
         placeholder_min: '',
         placeholder_max: '',
-        uri_action: '',
+        uri_action: 'http://test.com/',
         renderer: '',
         display_detail: 1,
         selected: true,
diff --git a/src/settings/test-data/criteria-list.ts b/src/settings/test-data/criteria-list.ts
index 621a17780e4ff3074ee88c22240839765e088d0b..efc831956dd0827fe45a3ef703929eb3eebe651f 100644
--- a/src/settings/test-data/criteria-list.ts
+++ b/src/settings/test-data/criteria-list.ts
@@ -1,6 +1,6 @@
 import { Criterion, FieldCriterion } from 'src/app/search/store/model';
 
 export const CRITERIA_LIST: Criterion[] = [
-    new FieldCriterion(1, 'eq', 'field_criterion_1'),
-    new FieldCriterion(2, 'eq', 'field_criterion_1')
+    new FieldCriterion(1, 'eq', 'fd_crit_1'),
+    new FieldCriterion(2, 'eq', 'fd_crit_2')
 ];