src/app/lib/cron-jobs/cron-jobs.component.spec.ts
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { CronJobsComponent } from './cron-jobs.component';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import * as fixtures from '../fixture.spec';
import { Component, DebugElement } from '@angular/core';
import { PosixService } from '../services/posix.service';
import { QuartzService } from '../services/quartz.service';
import { DataService } from '../services/data.service';
import { cold } from 'jasmine-marbles';
import { CronJobsConfig, CronJobsValidationConfig } from '../contracts/contracts';
import { By } from '@angular/platform-browser';
import createSpy = jasmine.createSpy;
@Component({
template:
`
<cron-jobs [formControl]="freqControl" [config]="cronConfig" [validate]="cronValidate"></cron-jobs>
<cron-jobs [config]="cronConfig" [validate]="cronValidate"></cron-jobs>
`
})
class TestReactiveComponent {
freqControl: FormControl;
freqSec = '';
freqToSet = '';
cronConfig: CronJobsConfig = {
multiple: false,
quartz: false,
bootstrap: true
};
cronValidate: CronJobsValidationConfig = {
validate: true
};
constructor() {
this.freqControl = new FormControl();
this.freqControl.valueChanges
.subscribe(value => {
this.freqSec = value;
});
}
set(value: string) {
this.freqToSet = value;
this.setControl();
}
setControl() {
this.freqControl.setValue(this.freqToSet);
}
}
function getFormControlNames(list: Array<DebugElement>): Array<string> {
return list.map((ele: DebugElement) => {
return ele.attributes['formControlName'];
});
}
describe('CronJobsComponent', () => {
let testComponent: TestReactiveComponent;
let testFixture: ComponentFixture<TestReactiveComponent>;
let component: CronJobsComponent;
let posixService: PosixService;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ReactiveFormsModule],
declarations: [TestReactiveComponent, CronJobsComponent],
providers: [DataService, PosixService, QuartzService]
})
.compileComponents();
}));
beforeEach(() => {
testFixture = TestBed.createComponent(TestReactiveComponent);
posixService = TestBed.get(PosixService);
testComponent = testFixture.componentInstance;
component = testFixture.debugElement.query(By.css('cron-jobs')).componentInstance;
});
afterEach(() => {
testComponent.cronConfig = {
multiple: false,
quartz: false,
bootstrap: true
};
testComponent.cronValidate = {
validate: true
};
});
it('should create', () => {
testFixture.detectChanges();
expect(testComponent).toBeTruthy();
expect(component).toBeTruthy();
});
it('should create from group on creation', () => {
const expected = ['baseFrequency', 'daysOfWeek', 'daysOfMonth', 'months', 'hours', 'minutes'];
testFixture.detectChanges();
expect(Object.keys(component.cronJobsForm.controls)).toEqual(expected);
});
it('should set config on creation', () => {
testFixture.detectChanges();
expect(component.config).toEqual(testComponent.cronConfig);
});
it('should set default config on creation when no config is passed', () => {
testFixture.detectChanges();
testComponent.cronConfig = undefined;
testFixture.detectChanges();
expect(component.config).toEqual(fixtures.defaultConfig);
});
it('should set validation config on creation', () => {
testFixture.detectChanges();
expect(component.validate).toEqual(testComponent.cronValidate);
});
it('should set default validation config on creation when no config is passed', () => {
testFixture.detectChanges();
testComponent.cronValidate = undefined;
testFixture.detectChanges();
expect(component.validate).toEqual(fixtures.defaultValidateConfig);
});
it('should set service on service change', () => {
testFixture.detectChanges();
const spy = spyOn(component, 'setService').and.callThrough();
testComponent.cronConfig = {
...testComponent.cronConfig,
quartz: true,
};
testFixture.detectChanges();
expect(spy).toHaveBeenCalledTimes(1);
});
it('should create config on config change', () => {
testFixture.detectChanges();
const expected = {
multiple: true,
quartz: true,
bootstrap: false
};
testComponent.cronConfig = {
...expected
};
testFixture.detectChanges();
expect(component.config).toEqual(expected);
});
it('should create validation config on config change', () => {
testFixture.detectChanges();
const expected = {
validate: false
};
testComponent.cronValidate = {
...expected
};
testFixture.detectChanges();
expect(component.validate).toEqual(expected);
});
it('should set Posix service on setService call when config.quartz is false', fakeAsync(() => {
testFixture.detectChanges();
tick();
component.cronJobsForm.get('baseFrequency').setValue('1');
tick();
testFixture.detectChanges();
expect(testComponent.freqSec).toEqual('* * * * *');
}));
it('should set Quartz service on setService call when config.quartz is true', fakeAsync(() => {
testComponent.cronConfig = {
...testComponent.cronConfig,
quartz: true,
};
testFixture.detectChanges();
tick();
component.cronJobsForm.get('baseFrequency').setValue('1');
tick();
testFixture.detectChanges();
expect(testComponent.freqSec).toEqual('0 * * * * ?');
}));
it('should set baseFrequency$ on init with value 0 ', fakeAsync(() => {
const expected = cold('a', { a: 0 });
testFixture.detectChanges();
tick();
expect(component.baseFrequency$).toBeObservable(expected);
}));
it('should change baseFrequency$ on baseFrequency form control change', fakeAsync(() => {
testFixture.detectChanges();
const expected = cold('a', { a: 2 });
tick();
component.cronJobsForm.get('baseFrequency').setValue('2');
tick();
testFixture.detectChanges();
expect(component.baseFrequency$).toBeObservable(expected);
}));
it('should call onChange if cronJobsForm was changed and baseFrequency is different then 0', fakeAsync(() => {
testFixture.detectChanges();
const spy = spyOn(component, 'onChange').and.callThrough();
tick();
spy.calls.reset();
component.cronJobsForm.get('baseFrequency').setValue('2');
component.cronJobsForm.get('minutes').setValue(['5']);
testFixture.detectChanges();
expect(spy).toHaveBeenCalledTimes(2);
}));
it('should call onChange and call getDefaultFrequency and set cronJobsForm value to default one ' +
'if cronJobsForm was changed and baseFrequency is set to 0', fakeAsync(() => {
testFixture.detectChanges();
const spy = spyOn(component, 'onChange').and.callThrough();
const spyDefaultFreq = spyOn(posixService, 'getDefaultFrequenceWithDefault').and.callThrough();
const expected = {
baseFrequency: 0, daysOfWeek: [0], daysOfMonth: [1], months: [1], hours: [0], minutes: [0]
};
tick();
component.cronJobsForm.get('baseFrequency').setValue('2');
component.cronJobsForm.get('minutes').setValue(['5']);
spy.calls.reset();
spyDefaultFreq.calls.reset();
component.cronJobsForm.get('baseFrequency').setValue('0');
testFixture.detectChanges();
tick();
expect(spy).toHaveBeenCalledTimes(1);
// expect(spyDefaultFreq).toHaveBeenCalledTimes(1);
expect(component.cronJobsForm.value).toEqual(expected);
}));
it('should not call onChange if component values are patched', fakeAsync(() => {
testFixture.detectChanges();
const spy = spyOn(component, 'onChange').and.callThrough();
tick();
spy.calls.reset();
component.writeValue('* * * * *');
tick();
testFixture.detectChanges();
expect(spy).not.toHaveBeenCalled();
}));
it('should set corect data for select options', fakeAsync(() => {
testFixture.detectChanges();
tick();
expect(component.baseFrequencyData.length).toBeTruthy();
expect(component.daysOfMonthData.length).toBeTruthy();
expect(component.daysOfWeekData.length).toBeTruthy();
expect(component.daysOfWeekData.length).toBeTruthy();
expect(component.monthsData.length).toBeTruthy();
expect(component.hoursData.length).toBeTruthy();
expect(component.minutesData.length).toBeTruthy();
}));
it('should on init patch cronJobsFrom with default value', fakeAsync(() => {
testFixture.detectChanges();
const spy = spyOn(component.cronJobsForm, 'patchValue').and.callThrough();
const expected = posixService.getDefaultFrequenceWithDefault();
tick();
expect(spy).toHaveBeenCalledWith(expected);
}));
it('should call cronService.fromCron and patchValue on writeValue call with correct data', fakeAsync(() => {
testFixture.detectChanges();
const spy = spyOn(component.cronJobsForm, 'patchValue').and.callThrough();
const expected = posixService.getDefaultFrequenceWithDefault();
tick();
spy.calls.reset();
component.writeValue('* * * * *');
tick();
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).not.toHaveBeenCalledWith(expected);
}));
it('should not call cronService.fromCron and call patchValue with default data on writeValue call with empty data', fakeAsync(() => {
testFixture.detectChanges();
const spy = spyOn(component.cronJobsForm, 'patchValue').and.callThrough();
const expected = posixService.getDefaultFrequenceWithDefault();
tick();
component.writeValue('* * * * *');
tick();
spy.calls.reset();
component.writeValue('');
tick();
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledWith(expected);
}));
it('should register onChange callback', fakeAsync(() => {
testFixture.detectChanges();
tick();
expect(component.onChange).not.toBeUndefined();
}));
it('should set disable state on cronJobsForm on setDisabledState call', fakeAsync(() => {
testFixture.detectChanges();
tick();
component.setDisabledState(true);
tick();
expect(component.cronJobsForm.disabled).toBeTruthy();
expect(component.isDisabled).toBeTruthy();
component.setDisabledState(false);
tick();
expect(component.cronJobsForm.disabled).toBeFalsy();
expect(component.isDisabled).toBeFalsy();
}));
it('should return default frequency object on getDefaultFrequency call', fakeAsync(() => {
testFixture.detectChanges();
tick();
const expected = {
baseFrequency: 0, daysOfWeek: [0], daysOfMonth: [1], months: [1], hours: [0], minutes: [0]
};
const result = posixService.getDefaultFrequenceWithDefault();
expect(result).toEqual(expected);
}));
it('should return if validation state on getIsValid call and call getValid if validate.validate is set to true', fakeAsync(() => {
testFixture.detectChanges();
const spy = spyOn(component, 'getValid').and.callThrough();
tick();
spy.calls.reset();
const result = component.getIsValid();
expect(spy).toHaveBeenCalledTimes(1);
expect(result).toBeTruthy();
}));
it('should return if validation state on getIsInvalid call and call getValid if validate.validate is set to true', fakeAsync(() => {
testFixture.detectChanges();
const spy = spyOn(component, 'getValid').and.callThrough();
tick();
spy.calls.reset();
const result = component.getIsInvalid();
expect(spy).toHaveBeenCalledTimes(1);
expect(result).toBeFalsy();
}));
it('should return false if validation state equals to false on getIsValid call ' +
'and no call getValid if validate.validate is false', fakeAsync(() => {
testComponent.cronValidate = {
validate: false
};
testFixture.detectChanges();
const spy = spyOn(component, 'getValid').and.callThrough();
tick();
spy.calls.reset();
const result = component.getIsValid();
expect(spy).not.toHaveBeenCalled();
expect(result).toBeFalsy();
}));
it('should return false if validation state equals to false on getIsInvalid call ' +
'and no call getIsInvalid if validate.validate is false', fakeAsync(() => {
testComponent.cronValidate = {
validate: false
};
testFixture.detectChanges();
const spy = spyOn(component, 'getValid').and.callThrough();
tick();
spy.calls.reset();
const result = component.getIsInvalid();
expect(spy).not.toHaveBeenCalled();
expect(result).toBeFalsy();
}));
it('should return formControl.valid if formControl is defined', fakeAsync(() => {
testFixture.detectChanges();
tick();
expect(component.getValid()).toBeTruthy();
}));
it('should return isValid if formControl is not defined', fakeAsync(() => {
const secComponent = testFixture.debugElement.queryAll(By.css('cron-jobs'))[1].componentInstance;
testFixture.detectChanges();
tick();
expect(secComponent.getValid()).toBeTruthy();
}));
it('should on registerOnTouched set onTouched', () => {
const spy = createSpy('spy');
component.registerOnTouched(spy);
expect(component.onTouched).toBeDefined();
});
it('should on registerOnChange set onChange', () => {
const spy = createSpy('spy');
component.registerOnChange(spy);
expect(component.onChange).toBeDefined();
});
it('should on onBlur() call onTouched', () => {
const spy = createSpy('spy');
component.registerOnTouched(spy);
component.onBlur();
expect(spy).toHaveBeenCalled();
});
describe('integration', () => {
let fixture: ComponentFixture<CronJobsComponent>;
let orgComponent: CronJobsComponent;
let de: DebugElement;
const spyOnChange = createSpy('spyOnChange');
const spyOnTouched = createSpy('spyOnTouched');
beforeEach(() => {
fixture = TestBed.createComponent(CronJobsComponent);
orgComponent = fixture.componentInstance;
spyOnChange.calls.reset();
orgComponent.registerOnChange(spyOnChange);
orgComponent.registerOnTouched(spyOnTouched);
de = fixture.debugElement;
fixture.detectChanges();
});
it('should on start render baseFrequency select', fakeAsync(() => {
tick();
const result = de.queryAll(By.css('select'));
expect(result.length).toEqual(1);
expect(result[0].attributes.formControlName).toEqual('baseFrequency');
}));
it('should render correct selects on baseFrequency set to 1', fakeAsync(() => {
tick();
orgComponent.cronJobsForm.get('baseFrequency').setValue('1');
fixture.detectChanges();
const result = de.queryAll(By.css('select'));
expect(result.length).toEqual(1);
expect(result[0].attributes.formControlName).toEqual('baseFrequency');
}));
it('should render correct selects on baseFrequency set to 2', fakeAsync(() => {
tick();
orgComponent.cronJobsForm.get('baseFrequency').setValue('2');
fixture.detectChanges();
const result = getFormControlNames(de.queryAll(By.css('select')));
const expected = ['baseFrequency', 'minutes'];
expect(result.length).toEqual(2);
expect(result).toEqual(expected);
}));
it('should render correct selects on baseFrequency set to 3', fakeAsync(() => {
tick();
orgComponent.cronJobsForm.get('baseFrequency').setValue('3');
fixture.detectChanges();
const result = getFormControlNames(de.queryAll(By.css('select')));
const expected = ['baseFrequency', 'hours', 'minutes'];
expect(result.length).toEqual(3);
expect(result).toEqual(expected);
}));
it('should render correct selects on baseFrequency set to 4', fakeAsync(() => {
tick();
orgComponent.cronJobsForm.get('baseFrequency').setValue('4');
fixture.detectChanges();
const result = getFormControlNames(de.queryAll(By.css('select')));
const expected = ['baseFrequency', 'daysOfWeek', 'hours', 'minutes'];
expect(result.length).toEqual(4);
expect(result).toEqual(expected);
}));
it('should render correct selects on baseFrequency set to 5', fakeAsync(() => {
tick();
orgComponent.cronJobsForm.get('baseFrequency').setValue('5');
fixture.detectChanges();
const result = getFormControlNames(de.queryAll(By.css('select')));
const expected = ['baseFrequency', 'daysOfMonth', 'hours', 'minutes'];
expect(result.length).toEqual(4);
expect(result).toEqual(expected);
}));
it('should render correct selects on baseFrequency set to 6', fakeAsync(() => {
tick();
orgComponent.cronJobsForm.get('baseFrequency').setValue('6');
fixture.detectChanges();
const result = getFormControlNames(de.queryAll(By.css('select')));
const expected = ['baseFrequency', 'daysOfMonth', 'months', 'hours', 'minutes'];
expect(result.length).toEqual(5);
expect(result).toEqual(expected);
}));
it('should render no bootstrap them on config.bootstrap set to false', fakeAsync(() => {
tick();
orgComponent.config = {
...orgComponent.config,
bootstrap: false
};
tick();
fixture.detectChanges();
const result = de.query(By.css('.cron-wrap')).nativeElement;
expect(result).toBeTruthy();
}));
});
});