From b634b1d160f2eb6d07e4b0339a94c24e89a9650d Mon Sep 17 00:00:00 2001
From: Manuel Friedli <manuel@fritteli.ch>
Date: Fri, 7 Sep 2018 12:21:20 +0200
Subject: [PATCH] Implement tests for ConverterSelectorComponent

---
 .../converter-selector.component.spec.ts      | 88 ++++++++++++++++---
 1 file changed, 78 insertions(+), 10 deletions(-)

diff --git a/src/app/converter-selector/converter-selector.component.spec.ts b/src/app/converter-selector/converter-selector.component.spec.ts
index 410aaa7..e37fdd0 100644
--- a/src/app/converter-selector/converter-selector.component.spec.ts
+++ b/src/app/converter-selector/converter-selector.component.spec.ts
@@ -1,25 +1,93 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
 
-import { ConverterSelectorComponent } from './converter-selector.component';
+import {ConverterSelectorComponent} from './converter-selector.component';
+import {Component, ViewChild} from '@angular/core';
+import {Step} from '../step';
+import {TextInputFieldComponent} from '../text-input-field/text-input-field.component';
+import {InputComponentManagerService} from '../input-component-manager.service';
+import {ConverterRegistryService} from '../converter-registry.service';
+import {Converter} from '../converter/converter';
+import createSpyObj = jasmine.createSpyObj;
+import SpyObj = jasmine.SpyObj;
+
+@Component({
+  template: '<app-converter-selector [step]="step" [textInput]="textInputComponent"></app-converter-selector>'
+})
+class TestHostComponent {
+  public step: Step = new Step(42);
+  public textInputComponent: TextInputFieldComponent = new TextInputFieldComponent(inputComponentManagerServiceStub);
+  @ViewChild(ConverterSelectorComponent)
+  public sutComponent: ConverterSelectorComponent;
+}
+
+const inputComponentManagerServiceStub = createSpyObj(['getNext']);
 
 describe('ConverterSelectorComponent', () => {
-  let component: ConverterSelectorComponent;
-  let fixture: ComponentFixture<ConverterSelectorComponent>;
+  let testHostComponent: TestHostComponent;
+  let testHostFixture: ComponentFixture<TestHostComponent>;
+
+  const converter1: SpyObj<Converter> = createSpyObj(['getId', 'getDisplayname', 'convert']);
+  const converter2: SpyObj<Converter> = createSpyObj(['getId', 'getDisplayname', 'convert']);
+  const converter3: SpyObj<Converter> = createSpyObj(['getId', 'getDisplayname', 'convert']);
+  // converter1.getId.and.returnValue('converter1');
+  converter1.getDisplayname.and.returnValue('Converter 1');
+  // converter2.getId.and.returnValue('converter2');
+  converter2.getDisplayname.and.returnValue('Converter 2');
+  // converter3.getId.and.returnValue('converter3');
+  converter3.getDisplayname.and.returnValue('Converter 3');
+  const converterRegistryServiceStub = createSpyObj(['getAllConverters', 'getConverter']);
+  converterRegistryServiceStub.getAllConverters.and.returnValue([converter1, converter2, converter3]);
+  converterRegistryServiceStub.getConverter.and.returnValue(undefined);
 
   beforeEach(async(() => {
     TestBed.configureTestingModule({
-      declarations: [ ConverterSelectorComponent ]
+      declarations: [
+        ConverterSelectorComponent,
+        TestHostComponent
+      ],
+      providers: [
+        {provide: InputComponentManagerService, useValue: inputComponentManagerServiceStub},
+        {provide: ConverterRegistryService, useValue: converterRegistryServiceStub}
+      ]
     })
-    .compileComponents();
+      .compileComponents();
   }));
 
   beforeEach(() => {
-    fixture = TestBed.createComponent(ConverterSelectorComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
+    testHostFixture = TestBed.createComponent(TestHostComponent);
+    testHostComponent = testHostFixture.componentInstance;
+    testHostFixture.detectChanges();
   });
 
   it('should create', () => {
-    expect(component).toBeTruthy();
+    expect(testHostComponent.sutComponent).toBeTruthy();
+  });
+
+  it('should update the conversion when the selection changes', () => {
+    // arrange
+    // set next step
+    const nextStep: Step = new Step(99);
+    inputComponentManagerServiceStub.getNext.and.returnValue(nextStep);
+    // set up converter
+    const dummyConverter = createSpyObj(['convert']);
+    dummyConverter.convert.and.returnValue('Converted value');
+    converterRegistryServiceStub.getConverter.and.returnValue(dummyConverter);
+    // create event structure
+    const event = {target: {selectedOptions: [{id: 'The testing converter id'}]}};
+
+    // act
+    testHostComponent.sutComponent.convert(event);
+
+    // assert
+    expect(converterRegistryServiceStub.getConverter).toHaveBeenCalledWith('The testing converter id');
+    expect(nextStep.content).toEqual('Converted value');
+  });
+
+  it('should load available converters upon creation', () => {
+    const converters: Converter[] = testHostComponent.sutComponent.converters;
+    expect(converters.length).toEqual(3);
+    expect(converters[0]).toEqual(converter1);
+    expect(converters[1]).toEqual(converter2);
+    expect(converters[2]).toEqual(converter3);
   });
 });