describe("Section Block Component", () => {
        const mocks = helpers.getMocks();
        let fixture: ComponentFixture<SectionBlockComponent>;
        let component: SectionBlockComponent;
        const person = mocks.person;
        let block: any;
        const blockService = mocks.blockService;

        beforeEach(async(() => {
            blockService.uploadImages = jasmine.createSpy("uploadImages").and.returnValue(Promise.resolve({}));

            TestBed.configureTestingModule({
                declarations: [SectionBlockComponent],
                providers: [
                    { provide: BlockService, useValue: blockService },
                    { provide: TranslatorService, useValue: mocks.translatorService }
                ],
                schemas: [CUSTOM_ELEMENTS_SCHEMA],
                imports: [PopoverModule.forRoot(), FormsModule, TranslateModule.forRoot()]
            });
            fixture = TestBed.createComponent(SectionBlockComponent);
            component = fixture.componentInstance;
            component.owner = person;
            component.designMode = true;

            block = {
                id: 1,
                settings: { name: 'some name', description: 'some description' },
                images: [{
                    id: 1, filename: "file1.png",
                    url: "/image_uploads/0000/0005/file1.png"
                },
                    {
                        id: 2, filename: "file2.png",
                        url: "/image_uploads/0000/0005/file2.png"
                    }
                ]
            };
            component.block = block;
            fixture.detectChanges();
            spyOn(component.popover, 'hide').and.callThrough();
        }));

        it("should hide if there is no image, name, description or title", () => {
            component.block = {
                id: 1,
                title: undefined,
                settings: { name: undefined, description: undefined },
                images: []
            };
            component.ngOnChanges();
            expect(component.block.hide).toBeTruthy();
        });

        it("should show if there is a title", () => {
            component.block = {
                id: 1,
                title: 'Section Block',
                settings: { name: undefined, description: undefined },
                images: []
            };
            component.ngOnChanges();
            expect(component.block.hide).toBeFalsy();
        });

        it("should show if there is a name", () => {
            component.block = {
                id: 1,
                title: undefined,
                settings: { name: 'mariko', description: undefined },
                images: []
            };
            component.ngOnChanges();
            expect(component.block.hide).toBeFalsy();
        });

        it("should show if there is a descriton", () => {
            component.block = {
                id: 1,
                title: undefined,
                settings: { name: undefined, description: 'nice manga' },
                images: []
            };
            component.ngOnChanges();
            expect(component.block.hide).toBeFalsy();
        });

        it("should show if there is an image", () => {
            component.block = {
                id: 1,
                title: undefined,
                settings: { name: undefined, description: undefined },
                images: [{
                    id: 1, filename: "file1.png",
                    url: "/image_uploads/0000/0005/file1.png"
                }]
            };
            component.ngOnChanges();
            expect(component.block.hide).toBeFalsy();
        });

        it("initialize modifiedLink link", fakeAsync(() => {
            component.ngOnInit();
            tick();
            expect(component.modifiedLink).toEqual(block.settings);
        }));

        it("should display section name", () => {
            expect(fixture.debugElement.nativeElement.querySelector(".section-block .name").innerHTML).toContain(block.settings.name);
        });

        it("should display section description", () => {
            expect(fixture.debugElement.nativeElement.querySelector(".section-block .description").innerHTML).toContain(block.settings.description);
        });

        it("should return the last image of component images list", () => {
            expect(component.getSectionImage()).toEqual(block.images[1]);
        });

        it("should return null if there is an empty array in component images list", () => {
            component.block.images = [];
            expect(component.getSectionImage()).toBeNull();
        });

        it("should return null if images block attribute is null", () => {
            component.block.images = null;
            expect(component.getSectionImage()).toBeNull();
        });

        it("should show the last image from block images", () => {
            expect(fixture.debugElement.nativeElement.querySelector(".section-image").src).toContain('/image_uploads/0000/0005/file2.png');
        });

        it("not show image if there is no image", () => {
            component.block.images = [];
            fixture.detectChanges();
            expect(fixture.debugElement.nativeElement.querySelector(".section-image")).toBeFalsy();
        });

        it("copyLink copy the link present in block to modifiedLink variable", () => {
            component.modifiedLink = {};
            expect(component.modifiedLink).toEqual({});
            component.block.settings = { name: 'another name', description: 'another description' };
            component.copyLink();
            expect(component.modifiedLink).toEqual(component.block.settings);
        });

        it("cancel copy the old link present in block attribute", () => {
            const newLink = { name: 'new name link', description: 'new description link' }
            component.modifiedLink = newLink;
            expect(component.modifiedLink).toEqual(newLink);
            component.block.settings = { name: 'another name', description: 'another description' };
            component.cancel();
            expect(component.modifiedLink).toEqual(component.block.settings);
        });

        it("cancel should call hide popover function", () => {
            component.cancel();
            expect(component.popover.hide).toHaveBeenCalled();
        });

        it("save should call hide popover function", () => {
            component.save();
            expect(component.popover.hide).toHaveBeenCalled();
        });

        it("save shoulld copy modifiedLink value to block attributes", () => {
            const newLink = { name: 'new name link', description: 'new description link' }
            component.modifiedLink = newLink;
            expect(component.block.settings === component.modifiedLink).toBeFalsy();
            component.save();
            expect(component.block.settings).toEqual(component.modifiedLink);
        });

        it("should uploadImages service be called by upload method", () => {
            const data = {};
            component.upload(data);
            expect(blockService.uploadImages).toHaveBeenCalledWith(component.block, [data]);
        });

        it("should upload set new information to block", fakeAsync(() => {
            const data = { data: { id: 3 } };
            component['blockService'].uploadImages = jasmine.createSpy("uploadImages").and.returnValue(Promise.resolve(data));
            component.upload(data);
            tick();
            expect(component.block).toEqual(data.data);
        }));

        it("should set background color in view", () => {
            const color = 'ff0000'
            component.backgroundColor = color;
            fixture.detectChanges();

            expect(fixture.debugElement.nativeElement.querySelector(".section-block").style.backgroundColor).toContain('rgb(255, 0, 0)');
        });

        it("should set color color in view", () => {
            const color = 'ff00ff'
            component.fontColor = color;
            fixture.detectChanges();

            expect(fixture.debugElement.nativeElement.querySelector(".section-block").style.color).toContain('rgb(255, 0, 255)');
        });

    });
  describe('template-driven forms integration tests', () => {

    beforeEach(() => { TestBed.configureTestingModule({imports: [FormsModule]}); });

    it('should support ngModel for single fields',
       fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
         const t = `<div><input type="text" [(ngModel)]="name"></div>`;

         let fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
         tick();
         fixture.debugElement.componentInstance.name = 'oldValue';
         fixture.detectChanges();

         var input = fixture.debugElement.query(By.css('input')).nativeElement;

         tick();
         expect(input.value).toEqual('oldValue');

         input.value = 'updatedValue';
         dispatchEvent(input, 'input');
         tick();

         expect(fixture.debugElement.componentInstance.name).toEqual('updatedValue');
       })));


    it('should support ngModel registration with a parent form',
       fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
         const t = `
                <form>
                  <input name="first" [(ngModel)]="name" maxlength="4">
                </form>
                `;

         let fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
         tick();
         fixture.debugElement.componentInstance.name = 'Nancy';
         fixture.detectChanges();
         var form = fixture.debugElement.children[0].injector.get(NgForm);

         tick();
         expect(form.value).toEqual({first: 'Nancy'});
         expect(form.valid).toBe(false);

       })));


    it('should add new controls and control groups',
       fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
         const t = `<form>
                         <div ngModelGroup="user">
                          <input type="text" name="login" ngModel>
                         </div>
                   </form>`;

         let fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
         tick();
         fixture.debugElement.componentInstance.name = null;
         fixture.detectChanges();

         var form = fixture.debugElement.children[0].injector.get(NgForm);
         expect(form.controls['user']).not.toBeDefined();

         tick();

         expect(form.controls['user']).toBeDefined();
         expect(form.controls['user'].controls['login']).toBeDefined();
       })));

    it('should emit ngSubmit event on submit',
       fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
         const t = `<div><form (ngSubmit)="name='updated'"></form></div>`;

         let fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
         tick();
         fixture.debugElement.componentInstance.name = 'old';
         var form = fixture.debugElement.query(By.css('form'));

         dispatchEvent(form.nativeElement, 'submit');
         tick();

         expect(fixture.debugElement.componentInstance.name).toEqual('updated');
       })));

    it('should mark NgForm as submitted on submit event',
       inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => {
                const t = `<div>
                      <form #f="ngForm" (ngSubmit)="data=f.submitted"></form>
                      <span>{{data}}</span>
                    </div>`;

                var fixture: ComponentFixture<MyComp8>;

                tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((root) => {
                  fixture = root;
                });
                tick();

                fixture.debugElement.componentInstance.data = false;

                tick();

                var form = fixture.debugElement.query(By.css('form'));
                dispatchEvent(form.nativeElement, 'submit');

                tick();
                expect(fixture.debugElement.componentInstance.data).toEqual(true);
              })));


    it('should reset the form to empty when reset button is clicked',
       fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
         const t = `
                <form>
                  <input name="name" [(ngModel)]="name">
                </form>
               `;

         const fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
         tick();
         fixture.debugElement.componentInstance.name = 'should be cleared';
         fixture.detectChanges();
         tick();

         const form = fixture.debugElement.children[0].injector.get(NgForm);
         const formEl = fixture.debugElement.query(By.css('form'));

         dispatchEvent(formEl.nativeElement, 'reset');
         fixture.detectChanges();
         tick();

         expect(fixture.debugElement.componentInstance.name).toBe(null);
         expect(form.value.name).toEqual(null);
       })));


    it('should emit valueChanges and statusChanges on init',
       fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
         const t = `<form>
                      <input type="text" name="first" [ngModel]="name" minlength="3">
                    </form>`;

         const fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
         const form = fixture.debugElement.children[0].injector.get(NgForm);
         fixture.debugElement.componentInstance.name = 'aa';
         fixture.detectChanges();

         expect(form.valid).toEqual(true);
         expect(form.value).toEqual({});

         let formValidity: string;
         let formValue: Object;

         ObservableWrapper.subscribe(
             form.statusChanges, (status: string) => { formValidity = status; });

         ObservableWrapper.subscribe(form.valueChanges, (value: string) => { formValue = value; });

         tick();

         expect(formValidity).toEqual('INVALID');
         expect(formValue).toEqual({first: 'aa'});
       })));

    it('should not create a template-driven form when ngNoForm is used',
       inject(
           [TestComponentBuilder, AsyncTestCompleter],
           (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
             const t = `<form ngNoForm>
                   </form>`;

             tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
               fixture.debugElement.componentInstance.name = null;
               fixture.detectChanges();

               expect(fixture.debugElement.children[0].providerTokens.length).toEqual(0);
               async.done();
             });
           }));

    it('should remove controls',
       fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
         const t = `<form>
                        <div *ngIf="name == 'show'">
                          <input type="text" name="login" ngModel>
                        </div>
                      </form>`;

         let fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
         tick();
         fixture.debugElement.componentInstance.name = 'show';
         fixture.detectChanges();
         tick();
         var form = fixture.debugElement.children[0].injector.get(NgForm);


         expect(form.controls['login']).toBeDefined();

         fixture.debugElement.componentInstance.name = 'hide';
         fixture.detectChanges();
         tick();

         expect(form.controls['login']).not.toBeDefined();
       })));

    it('should remove control groups',
       fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
         const t = `<form>
                         <div *ngIf="name=='show'" ngModelGroup="user">
                          <input type="text" name="login" ngModel>
                         </div>
                   </form>`;


         let fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
         tick();
         fixture.debugElement.componentInstance.name = 'show';
         fixture.detectChanges();
         tick();
         var form = fixture.debugElement.children[0].injector.get(NgForm);

         expect(form.controls['user']).toBeDefined();

         fixture.debugElement.componentInstance.name = 'hide';
         fixture.detectChanges();
         tick();

         expect(form.controls['user']).not.toBeDefined();
       })));

    it('should support ngModel for complex forms',
       fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
         const t = `<form>
                          <input type="text" name="name" [(ngModel)]="name">
                   </form>`;

         let fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
         tick();
         fixture.debugElement.componentInstance.name = 'oldValue';
         fixture.detectChanges();
         tick();

         var input = fixture.debugElement.query(By.css('input')).nativeElement;
         expect(input.value).toEqual('oldValue');

         input.value = 'updatedValue';
         dispatchEvent(input, 'input');
         tick();

         expect(fixture.debugElement.componentInstance.name).toEqual('updatedValue');
       })));


    it('should throw if ngModel has a parent form but no name attr or standalone label',
       inject(
           [TestComponentBuilder, AsyncTestCompleter],
           (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
             const t = `<form>
                      <input [(ngModel)]="name">
                    </form>`;

             tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
               expect(() => fixture.detectChanges())
                   .toThrowError(new RegExp(`name attribute must be set`));
               async.done();
             });
           }));

    it('should not throw if ngModel has a parent form, no name attr, and a standalone label',
       inject(
           [TestComponentBuilder, AsyncTestCompleter],
           (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
             const t = `<form>
                      <input [(ngModel)]="name" [ngModelOptions]="{standalone: true}">
                    </form>`;

             tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
               expect(() => fixture.detectChanges()).not.toThrow();
               async.done();
             });
           }));

    it('should override name attribute with ngModelOptions name if provided',
       fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
         const t = `
                <form>
                  <input name="one" [(ngModel)]="data" [ngModelOptions]="{name: 'two'}">
                </form>
                `;

         const fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
         tick();
         fixture.debugElement.componentInstance.data = 'some data';
         fixture.detectChanges();
         const form = fixture.debugElement.children[0].injector.get(NgForm);

         tick();
         expect(form.value).toEqual({two: 'some data'});
       })));

    it('should not register standalone ngModels with parent form',
       fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
         const t = `
                <form>
                  <input name="one" [(ngModel)]="data">
                  <input [(ngModel)]="list" [ngModelOptions]="{standalone: true}">
                </form>
                `;

         const fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
         tick();
         fixture.debugElement.componentInstance.data = 'some data';
         fixture.debugElement.componentInstance.list = 'should not show';
         fixture.detectChanges();
         const form = fixture.debugElement.children[0].injector.get(NgForm);
         const inputs = fixture.debugElement.queryAll(By.css('input'));

         tick();
         expect(form.value).toEqual({one: 'some data'});
         expect(inputs[1].nativeElement.value).toEqual('should not show');
       })));

    it('should set status classes with ngModel',
       inject(
           [TestComponentBuilder, AsyncTestCompleter],
           (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
             const t = `<div><input [(ngModel)]="name" required></div>`;

             tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
               fixture.debugElement.componentInstance.name = '';
               fixture.detectChanges();

               var input = fixture.debugElement.query(By.css('input')).nativeElement;
               expect(sortedClassList(input)).toEqual([
                 'ng-invalid', 'ng-pristine', 'ng-untouched'
               ]);

               dispatchEvent(input, 'blur');
               fixture.detectChanges();

               expect(sortedClassList(input)).toEqual(['ng-invalid', 'ng-pristine', 'ng-touched']);

               input.value = 'updatedValue';
               dispatchEvent(input, 'input');
               fixture.detectChanges();

               expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']);
               async.done();
             });
           }));

    it('should mark controls as dirty before emitting a value change event',
       fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {

         const t = `<form>
                <input type="text" name="login" ngModel>
               </form>`;

         tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
           fixture.detectChanges();

           const form = fixture.debugElement.children[0].injector.get(NgForm).form;
           fixture.detectChanges();
           tick();

           form.find('login').valueChanges.subscribe(
               () => { expect(form.find('login').dirty).toBe(true); });

           const loginEl = fixture.debugElement.query(By.css('input')).nativeElement;
           loginEl.value = 'newValue';

           dispatchEvent(loginEl, 'input');
         });
       })));

    it('should mark control as pristine before emitting a value change event when resetting ',
       fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {

         const t = `<form>
                <input type="text" name="login" ngModel>
               </form>`;

         tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
           fixture.detectChanges();

           const form = fixture.debugElement.children[0].injector.get(NgForm).form;
           const formEl = fixture.debugElement.query(By.css('form')).nativeElement;
           const loginEl = fixture.debugElement.query(By.css('input')).nativeElement;
           fixture.detectChanges();
           tick();

           loginEl.value = 'newValue';
           dispatchEvent(loginEl, 'input');

           expect(form.find('login').pristine).toBe(false);

           form.find('login').valueChanges.subscribe(
               () => { expect(form.find('login').pristine).toBe(true); });

           dispatchEvent(formEl, 'reset');
         });
       })));

    describe('radio value accessor', () => {
      it('should support <type=radio>',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<form>
                      <input type="radio" name="food" [(ngModel)]="data.food" value="chicken">
                      <input type="radio" name="food" [(ngModel)]="data.food" value="fish">
                    </form>`;

           const fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
           tick();

           fixture.debugElement.componentInstance.data = {food: 'fish'};
           fixture.detectChanges();
           tick();

           const inputs = fixture.debugElement.queryAll(By.css('input'));
           expect(inputs[0].nativeElement.checked).toEqual(false);
           expect(inputs[1].nativeElement.checked).toEqual(true);

           dispatchEvent(inputs[0].nativeElement, 'change');
           tick();

           const data = fixture.debugElement.componentInstance.data;

           expect(data.food).toEqual('chicken');
           expect(inputs[1].nativeElement.checked).toEqual(false);
         })));

      it('should support multiple named <type=radio> groups',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<form>
                      <input type="radio" name="food" [(ngModel)]="data.food" value="chicken">
                      <input type="radio" name="food"  [(ngModel)]="data.food" value="fish">
                      <input type="radio" name="drink" [(ngModel)]="data.drink" value="cola">
                      <input type="radio" name="drink" [(ngModel)]="data.drink" value="sprite">
                    </form>`;

           const fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
           tick();

           fixture.debugElement.componentInstance.data = {food: 'fish', drink: 'sprite'};
           fixture.detectChanges();
           tick();

           const inputs = fixture.debugElement.queryAll(By.css('input'));
           expect(inputs[0].nativeElement.checked).toEqual(false);
           expect(inputs[1].nativeElement.checked).toEqual(true);
           expect(inputs[2].nativeElement.checked).toEqual(false);
           expect(inputs[3].nativeElement.checked).toEqual(true);

           dispatchEvent(inputs[0].nativeElement, 'change');
           tick();

           const data = fixture.debugElement.componentInstance.data;

           expect(data.food).toEqual('chicken');
           expect(data.drink).toEqual('sprite');
           expect(inputs[1].nativeElement.checked).toEqual(false);
           expect(inputs[2].nativeElement.checked).toEqual(false);
           expect(inputs[3].nativeElement.checked).toEqual(true);

         })));
    });

    describe('select value accessor', () => {
      it('with option values that are objects',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<div>
                      <select [(ngModel)]="selectedCity">
                        <option *ngFor="let c of list" [ngValue]="c">{{c['name']}}</option>
                      </select>
                  </div>`;

           tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {

             var testComp = fixture.debugElement.componentInstance;
             testComp.list = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'Buffalo'}];
             testComp.selectedCity = testComp.list[1];
             fixture.detectChanges();

             var select = fixture.debugElement.query(By.css('select'));
             var nycOption = fixture.debugElement.queryAll(By.css('option'))[1];

             tick();
             expect(select.nativeElement.value).toEqual('1: Object');
             expect(nycOption.nativeElement.selected).toBe(true);

             select.nativeElement.value = '2: Object';
             dispatchEvent(select.nativeElement, 'change');
             fixture.detectChanges();
             tick();
             expect(testComp.selectedCity['name']).toEqual('Buffalo');
           });
         })));

      it('when new options are added (selection through the model)',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<div>
                      <select [(ngModel)]="selectedCity">
                        <option *ngFor="let c of list" [ngValue]="c">{{c['name']}}</option>
                      </select>
                  </div>`;

           tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {

             var testComp: MyComp8 = fixture.debugElement.componentInstance;
             testComp.list = [{'name': 'SF'}, {'name': 'NYC'}];
             testComp.selectedCity = testComp.list[1];
             fixture.detectChanges();

             testComp.list.push({'name': 'Buffalo'});
             testComp.selectedCity = testComp.list[2];
             fixture.detectChanges();
             tick();

             var select = fixture.debugElement.query(By.css('select'));
             var buffalo = fixture.debugElement.queryAll(By.css('option'))[2];
             expect(select.nativeElement.value).toEqual('2: Object');
             expect(buffalo.nativeElement.selected).toBe(true);
           });
         })));

      it('when new options are added (selection through the UI)',
         inject(
             [TestComponentBuilder, AsyncTestCompleter],
             (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
               const t = `<div>
                      <select [(ngModel)]="selectedCity">
                        <option *ngFor="let c of list" [ngValue]="c">{{c['name']}}</option>
                      </select>
                  </div>`;

               tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {

                 var testComp: MyComp8 = fixture.debugElement.componentInstance;
                 testComp.list = [{'name': 'SF'}, {'name': 'NYC'}];
                 testComp.selectedCity = testComp.list[0];
                 fixture.detectChanges();

                 var select = fixture.debugElement.query(By.css('select'));
                 var ny = fixture.debugElement.queryAll(By.css('option'))[1];

                 select.nativeElement.value = '1: Object';
                 dispatchEvent(select.nativeElement, 'change');
                 testComp.list.push({'name': 'Buffalo'});
                 fixture.detectChanges();

                 expect(select.nativeElement.value).toEqual('1: Object');
                 expect(ny.nativeElement.selected).toBe(true);
                 async.done();
               });
             }));


      it('when options are removed',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<div>
                      <select [(ngModel)]="selectedCity">
                        <option *ngFor="let c of list" [ngValue]="c">{{c}}</option>
                      </select>
                  </div>`;
           tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {

             var testComp: MyComp8 = fixture.debugElement.componentInstance;
             testComp.list = [{'name': 'SF'}, {'name': 'NYC'}];
             testComp.selectedCity = testComp.list[1];
             fixture.detectChanges();
             tick();

             var select = fixture.debugElement.query(By.css('select'));
             expect(select.nativeElement.value).toEqual('1: Object');

             testComp.list.pop();
             fixture.detectChanges();
             tick();

             expect(select.nativeElement.value).not.toEqual('1: Object');
           });
         })));

      it('when option values change identity while tracking by index',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<div>
                      <select [(ngModel)]="selectedCity">
                        <option *ngFor="let c of list; trackBy:customTrackBy" [ngValue]="c">{{c}}</option>
                      </select>
                  </div>`;

           tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {

             var testComp = fixture.debugElement.componentInstance;

             testComp.list = [{'name': 'SF'}, {'name': 'NYC'}];
             testComp.selectedCity = testComp.list[0];
             fixture.detectChanges();

             testComp.list[1] = 'Buffalo';
             testComp.selectedCity = testComp.list[1];
             fixture.detectChanges();
             tick();

             var select = fixture.debugElement.query(By.css('select'));
             var buffalo = fixture.debugElement.queryAll(By.css('option'))[1];

             expect(select.nativeElement.value).toEqual('1: Buffalo');
             expect(buffalo.nativeElement.selected).toBe(true);
           });
         })));

      it('with duplicate option values',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<div>
                      <select [(ngModel)]="selectedCity">
                        <option *ngFor="let c of list" [ngValue]="c">{{c.name}}</option>
                      </select>
                  </div>`;

           tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {

             var testComp = fixture.debugElement.componentInstance;

             testComp.list = [{'name': 'NYC'}, {'name': 'SF'}, {'name': 'SF'}];
             testComp.selectedCity = testComp.list[0];
             fixture.detectChanges();

             testComp.selectedCity = testComp.list[1];
             fixture.detectChanges();
             tick();

             var select = fixture.debugElement.query(By.css('select'));
             var firstSF = fixture.debugElement.queryAll(By.css('option'))[1];

             expect(select.nativeElement.value).toEqual('1: Object');
             expect(firstSF.nativeElement.selected).toBe(true);
           });
         })));

      it('when option values have same content, but different identities',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<div>
                      <select [(ngModel)]="selectedCity">
                        <option *ngFor="let c of list" [ngValue]="c">{{c['name']}}</option>
                      </select>
                  </div>`;

           tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {

             var testComp = fixture.debugElement.componentInstance;
             testComp.list = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'NYC'}];
             testComp.selectedCity = testComp.list[0];
             fixture.detectChanges();

             testComp.selectedCity = testComp.list[2];
             fixture.detectChanges();
             tick();

             var select = fixture.debugElement.query(By.css('select'));
             var secondNYC = fixture.debugElement.queryAll(By.css('option'))[2];

             expect(select.nativeElement.value).toEqual('2: Object');
             expect(secondNYC.nativeElement.selected).toBe(true);
           });
         })));
    });

    describe('ngModel corner cases', () => {
      it('should update the view when the model is set back to what used to be in the view',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<input type="text" [(ngModel)]="name">`;
           let fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
           tick();
           fixture.debugElement.componentInstance.name = '';
           fixture.detectChanges();

           // Type "aa" into the input.
           var input = fixture.debugElement.query(By.css('input')).nativeElement;
           input.value = 'aa';
           input.selectionStart = 1;
           dispatchEvent(input, 'input');

           fixture.detectChanges();
           tick();
           expect(fixture.debugElement.componentInstance.name).toEqual('aa');

           // Programmatically update the input value to be "bb".
           fixture.debugElement.componentInstance.name = 'bb';
           fixture.detectChanges();
           tick();
           expect(input.value).toEqual('bb');

           // Programatically set it back to "aa".
           fixture.debugElement.componentInstance.name = 'aa';
           fixture.detectChanges();
           tick();
           expect(input.value).toEqual('aa');
         })));

      it('should not crash when validity is checked from a binding',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           // {{x.valid}} used to crash because valid() tried to read a property
           // from form.control before it was set. This test verifies this bug is
           // fixed.
           const t = `<form><div ngModelGroup="x" #x="ngModelGroup">
                    <input type="text" name="test" ngModel></div>{{x.valid}}</form>`;
           let fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
           tick();
           fixture.detectChanges();
         })));
    });

  });
    describe('select value accessor', () => {
      it('with option values that are objects',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<div>
                      <select [(ngModel)]="selectedCity">
                        <option *ngFor="let c of list" [ngValue]="c">{{c['name']}}</option>
                      </select>
                  </div>`;

           tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {

             var testComp = fixture.debugElement.componentInstance;
             testComp.list = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'Buffalo'}];
             testComp.selectedCity = testComp.list[1];
             fixture.detectChanges();

             var select = fixture.debugElement.query(By.css('select'));
             var nycOption = fixture.debugElement.queryAll(By.css('option'))[1];

             tick();
             expect(select.nativeElement.value).toEqual('1: Object');
             expect(nycOption.nativeElement.selected).toBe(true);

             select.nativeElement.value = '2: Object';
             dispatchEvent(select.nativeElement, 'change');
             fixture.detectChanges();
             tick();
             expect(testComp.selectedCity['name']).toEqual('Buffalo');
           });
         })));

      it('when new options are added (selection through the model)',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<div>
                      <select [(ngModel)]="selectedCity">
                        <option *ngFor="let c of list" [ngValue]="c">{{c['name']}}</option>
                      </select>
                  </div>`;

           tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {

             var testComp: MyComp8 = fixture.debugElement.componentInstance;
             testComp.list = [{'name': 'SF'}, {'name': 'NYC'}];
             testComp.selectedCity = testComp.list[1];
             fixture.detectChanges();

             testComp.list.push({'name': 'Buffalo'});
             testComp.selectedCity = testComp.list[2];
             fixture.detectChanges();
             tick();

             var select = fixture.debugElement.query(By.css('select'));
             var buffalo = fixture.debugElement.queryAll(By.css('option'))[2];
             expect(select.nativeElement.value).toEqual('2: Object');
             expect(buffalo.nativeElement.selected).toBe(true);
           });
         })));

      it('when new options are added (selection through the UI)',
         inject(
             [TestComponentBuilder, AsyncTestCompleter],
             (tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
               const t = `<div>
                      <select [(ngModel)]="selectedCity">
                        <option *ngFor="let c of list" [ngValue]="c">{{c['name']}}</option>
                      </select>
                  </div>`;

               tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {

                 var testComp: MyComp8 = fixture.debugElement.componentInstance;
                 testComp.list = [{'name': 'SF'}, {'name': 'NYC'}];
                 testComp.selectedCity = testComp.list[0];
                 fixture.detectChanges();

                 var select = fixture.debugElement.query(By.css('select'));
                 var ny = fixture.debugElement.queryAll(By.css('option'))[1];

                 select.nativeElement.value = '1: Object';
                 dispatchEvent(select.nativeElement, 'change');
                 testComp.list.push({'name': 'Buffalo'});
                 fixture.detectChanges();

                 expect(select.nativeElement.value).toEqual('1: Object');
                 expect(ny.nativeElement.selected).toBe(true);
                 async.done();
               });
             }));


      it('when options are removed',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<div>
                      <select [(ngModel)]="selectedCity">
                        <option *ngFor="let c of list" [ngValue]="c">{{c}}</option>
                      </select>
                  </div>`;
           tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {

             var testComp: MyComp8 = fixture.debugElement.componentInstance;
             testComp.list = [{'name': 'SF'}, {'name': 'NYC'}];
             testComp.selectedCity = testComp.list[1];
             fixture.detectChanges();
             tick();

             var select = fixture.debugElement.query(By.css('select'));
             expect(select.nativeElement.value).toEqual('1: Object');

             testComp.list.pop();
             fixture.detectChanges();
             tick();

             expect(select.nativeElement.value).not.toEqual('1: Object');
           });
         })));

      it('when option values change identity while tracking by index',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<div>
                      <select [(ngModel)]="selectedCity">
                        <option *ngFor="let c of list; trackBy:customTrackBy" [ngValue]="c">{{c}}</option>
                      </select>
                  </div>`;

           tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {

             var testComp = fixture.debugElement.componentInstance;

             testComp.list = [{'name': 'SF'}, {'name': 'NYC'}];
             testComp.selectedCity = testComp.list[0];
             fixture.detectChanges();

             testComp.list[1] = 'Buffalo';
             testComp.selectedCity = testComp.list[1];
             fixture.detectChanges();
             tick();

             var select = fixture.debugElement.query(By.css('select'));
             var buffalo = fixture.debugElement.queryAll(By.css('option'))[1];

             expect(select.nativeElement.value).toEqual('1: Buffalo');
             expect(buffalo.nativeElement.selected).toBe(true);
           });
         })));

      it('with duplicate option values',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<div>
                      <select [(ngModel)]="selectedCity">
                        <option *ngFor="let c of list" [ngValue]="c">{{c.name}}</option>
                      </select>
                  </div>`;

           tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {

             var testComp = fixture.debugElement.componentInstance;

             testComp.list = [{'name': 'NYC'}, {'name': 'SF'}, {'name': 'SF'}];
             testComp.selectedCity = testComp.list[0];
             fixture.detectChanges();

             testComp.selectedCity = testComp.list[1];
             fixture.detectChanges();
             tick();

             var select = fixture.debugElement.query(By.css('select'));
             var firstSF = fixture.debugElement.queryAll(By.css('option'))[1];

             expect(select.nativeElement.value).toEqual('1: Object');
             expect(firstSF.nativeElement.selected).toBe(true);
           });
         })));

      it('when option values have same content, but different identities',
         fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
           const t = `<div>
                      <select [(ngModel)]="selectedCity">
                        <option *ngFor="let c of list" [ngValue]="c">{{c['name']}}</option>
                      </select>
                  </div>`;

           tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {

             var testComp = fixture.debugElement.componentInstance;
             testComp.list = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'NYC'}];
             testComp.selectedCity = testComp.list[0];
             fixture.detectChanges();

             testComp.selectedCity = testComp.list[2];
             fixture.detectChanges();
             tick();

             var select = fixture.debugElement.query(By.css('select'));
             var secondNYC = fixture.debugElement.queryAll(By.css('option'))[2];

             expect(select.nativeElement.value).toEqual('2: Object');
             expect(secondNYC.nativeElement.selected).toBe(true);
           });
         })));
    });
    describe('getReadme', () => {
        it('should not get the readme if not connected to github', fakeAsync(inject([SampleBusinessNetworkService], (service: SampleBusinessNetworkService) => {
            service['octo'] = null;

            service.getReadme('myOwner', 'myRepository', 'packages/')
                .then(() => {
                    throw('Should not get here');
                })
                .catch((error) => {
                    error.should.equal('no connection to GitHub');
                });

            tick();
        })));

        it('should get the readme', fakeAsync(inject([SampleBusinessNetworkService], (service: SampleBusinessNetworkService) => {

            let octoReadmeFileMock = {
                name: 'README.md',
                content: 'YSByZWFkbWUgZmlsZQ=='
            };

            let repoMock = {
                contents: sinon.stub()
            };

            repoMock.contents.returns({
                fetch: sinon.stub().returns(Promise.resolve(octoReadmeFileMock))
            });

            let octoMock = {
                repos: sinon.stub().returns(repoMock)
            };

            service['octo'] = octoMock;
            service.getReadme('myOwner', 'myRepository', 'packages/')
                .then((result) => {
                    result.should.deep.equal({name: 'README.md', data: 'a readme file'});
                });

            tick();
        })));

        it('should handle having no readme', fakeAsync(inject([SampleBusinessNetworkService], (service: SampleBusinessNetworkService) => {
            let repoMock = {
                contents: sinon.stub()
            };

            repoMock.contents.returns({
                fetch: sinon.stub().returns(Promise.reject({status: 404}))
            });

            let octoMock = {
                repos: sinon.stub().returns(repoMock)
            };

            service['octo'] = octoMock;
            service.getReadme('myOwner', 'myRepository', 'packages/')
                .then((result) => {
                    should.not.exist(result);
                });

            tick();
        })));

        it('should handle error', fakeAsync(inject([SampleBusinessNetworkService], (service: SampleBusinessNetworkService) => {
            let repoMock = {
                contents: sinon.stub()
            };

            repoMock.contents.returns({
                fetch: sinon.stub().returns(Promise.reject('some error'))
            });

            let octoMock = {
                repos: sinon.stub().returns(repoMock)
            };

            service['octo'] = octoMock;
            service.getReadme('myOwner', 'myRepository', 'packages/')
                .then(() => {
                    throw('should not get here');
                })
                .catch((error) => {
                    error.should.equal('some error');
                });

            tick();
        })));
    });
示例#5
0
describe('Angulartics2GoogleGlobalSiteTag', () => {
  let gtag: any;
  let ga: any;
  let fixture: ComponentFixture<any>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [TestModule],
      providers: [Angulartics2GoogleGlobalSiteTag],
    });

    window.gtag = gtag = jasmine.createSpy('gtag');
    window.ga = ga = {
      getAll: function() {
        return {
          forEach: function(callback) {
            const tracker = {
              get: function(value) {
                return 'UA-111111111-1';
              },
            };
            callback(tracker);
          },
        };
      },
    };
  });

  it('should track pages',
    fakeAsync(inject([Angulartics2, Angulartics2GoogleGlobalSiteTag],
      (angulartics2: Angulartics2, angulartics2GoogleGlobalSiteTag: Angulartics2GoogleGlobalSiteTag) => {
        fixture = createRoot(RootCmp);
        angulartics2.pageTrack.next({ path: '/abc' });
        advance(fixture);
        expect(gtag.calls.count()).toEqual(1);
        expect(gtag).toHaveBeenCalledWith('config', 'UA-111111111-1', {'page_path': '/abc'});
      },
    )),
  );

  it('should track events',
    fakeAsync(inject([Angulartics2, Angulartics2GoogleGlobalSiteTag],
      (angulartics2: Angulartics2, angulartics2GoogleGlobalSiteTag: Angulartics2GoogleGlobalSiteTag) => {
        fixture = createRoot(RootCmp);
        angulartics2.eventTrack.next({
          action: 'do',
          properties: {
            value: 1,
            label: 'abc',
            gstCustom: {
              customKey: 'customValue',
            },
          }
        });
        advance(fixture);
        expect(gtag).toHaveBeenCalledWith('event', 'do', {
          event_category: 'interaction',
          event_label: 'abc',
          value: 1,
          non_interaction: undefined,
          customKey: 'customValue',
        });
      }
    )),
  );

  it('should track exceptions',
    fakeAsync(inject([Angulartics2, Angulartics2GoogleGlobalSiteTag],
      (angulartics2: Angulartics2, angulartics2GoogleGlobalSiteTag: Angulartics2GoogleGlobalSiteTag) => {
        fixture = createRoot(RootCmp);
        angulartics2.exceptionTrack.next({ description: 'bugger', gstCustom: { appId: 'app', appName: 'Test App', appVersion: '0.1' } });
        advance(fixture);
        expect(gtag).toHaveBeenCalledWith('event', 'exception', {
          event_category: 'interaction',
          event_label: undefined,
          value: undefined,
          non_interaction: undefined,
          description: 'bugger',
          fatal: true,
          appId: 'app',
          appName: 'Test App',
          appVersion: '0.1',
        });
      }
    )),
  );

});
    describe('getSampleNetworkInfo', () => {
        it('should not get the json for the sample if not connected to github', fakeAsync(inject([SampleBusinessNetworkService], (service: SampleBusinessNetworkService) => {
            service['octo'] = null;

            service.getSampleNetworkInfo('myOwner', 'myRepository', 'packages/')
                .then(() => {
                    throw('Should not get here');
                })
                .catch((error) => {
                    error.should.equal('no connection to GitHub');
                });

            tick();
        })));

        it('should get the json for the sample', fakeAsync(inject([SampleBusinessNetworkService], (service: SampleBusinessNetworkService) => {
            let octoJsonMock = {
                content: 'eyJuYW1lIiA6ICJib2IifQ=='
            };

            let octoMock = {
                repos: sinon.stub().returns({
                    contents: sinon.stub().returns({
                        fetch: sinon.stub().returns(Promise.resolve(octoJsonMock))
                    })
                })
            };

            service['octo'] = octoMock;
            service.getSampleNetworkInfo('myOwner', 'myRepository', 'packages/')
                .then((result) => {
                    result.should.deep.equal({name: 'bob', composerPath: 'packages/'});
                });

            tick();
        })));

        it('should handle error with json', fakeAsync(inject([SampleBusinessNetworkService], (service: SampleBusinessNetworkService) => {
            // contains malformed json
            let octoJsonMock = {
                content: 'eyJuYW1lIiA6ICJib2Ii'
            };

            let octoMock = {
                repos: sinon.stub().returns({
                    contents: sinon.stub().returns({
                        fetch: sinon.stub().returns(Promise.resolve(octoJsonMock))
                    })
                })
            };

            service['octo'] = octoMock;
            service.getSampleNetworkInfo('myOwner', 'myRepository', 'packages/')
                .then(() => {
                    throw('should not get here');
                })
                .catch((error) => {
                    error.message.should.equal('Unexpected end of JSON input');
                });

            tick();

        })));

        it('should handle error', fakeAsync(inject([SampleBusinessNetworkService], (service: SampleBusinessNetworkService) => {

            let octoMock = {
                repos: sinon.stub().returns({
                    contents: sinon.stub().returns({
                        fetch: sinon.stub().returns(Promise.reject('some error'))
                    })
                })
            };

            service['octo'] = octoMock;
            service.getSampleNetworkInfo('myOwner', 'myRepository', 'packages/')
                .then(() => {
                    throw('should not get here');
                })
                .catch((error) => {
                    error.should.equal('some error');
                });

            tick();
        })));
    });
    describe('getModel', () => {
        it('should not get the model if not connected to github', fakeAsync(inject([SampleBusinessNetworkService], (service: SampleBusinessNetworkService) => {
            service['octo'] = null;

            service.getModel('myOwner', 'myRepository', 'packages/')
                .then(() => {
                    throw('Should not get here');
                })
                .catch((error) => {
                    error.should.equal('no connection to GitHub');
                });

            tick();
        })));

        it('should get the model', fakeAsync(inject([SampleBusinessNetworkService], (service: SampleBusinessNetworkService) => {
            let octoModelMock = {
                items: [{name: 'modelOne', path: 'modelOne'}]
            };

            let octoModelFileMock = {
                content: 'QSBtb2RlbCBmaWxl'
            };

            let repoMock = {
                contents: sinon.stub()
            };

            repoMock.contents.withArgs('packages/models').returns({
                fetch: sinon.stub().returns(Promise.resolve(octoModelMock))
            });

            repoMock.contents.withArgs('modelOne').returns({
                fetch: sinon.stub().returns(Promise.resolve(octoModelFileMock))
            });

            let octoMock = {
                repos: sinon.stub().returns(repoMock)
            };

            service['octo'] = octoMock;

            service.getModel('myOwner', 'myRepository', 'packages/')
                .then((result) => {
                    result.length.should.equal(1);
                    result[0].should.equal('A model file');
                });

            tick();
        })));

        it('should handle error', fakeAsync(inject([SampleBusinessNetworkService], (service: SampleBusinessNetworkService) => {
            let repoMock = {
                contents: sinon.stub()
            };

            repoMock.contents.withArgs('packages/models').returns({
                fetch: sinon.stub().returns(Promise.reject('some error'))
            });

            let octoMock = {
                repos: sinon.stub().returns(repoMock)
            };

            service['octo'] = octoMock;

            service.getModel('myOwner', 'myRepository', 'packages/')
                .then(() => {
                    throw('should not get here');
                })
                .catch((error) => {
                    error.should.equal('some error');
                });

            tick();
        })));
    });
    describe('ngOninit', () => {
        it('should initialise the footer', fakeAsync(inject([XHRBackend, ConfigService], (mockBackend, configService: ConfigService) => {
            let myConfig = new Config();
            myConfig.webonly = true;
            myConfig.title = 'My Title';
            myConfig.banner = ['My', 'Banner'];
            myConfig.docURL = 'https://doc_url';
            myConfig.links = {
                docs: 'My Docs',
                tutorial: 'My Tutorial',
                community: 'My Community',
                github: 'My Github',
                install: 'My Install',
                legal: 'My License'
            };

            configService['configLoaded'] = true;
            configService['config'] = myConfig;

            mockBackend.connections.subscribe((connection) => {
                connection.mockRespond(new Response(new ResponseOptions({
                    body: JSON.stringify(mockResponseAboutService)
                })));
            });

            fixture.detectChanges();
            tick();
            fixture.detectChanges();
            component['playgroundVersion'].should.match(/[0-9]+.[0-9]+.[0-9]+/);
            component['config'].should.deep.equal(myConfig);

            fixture.detectChanges();

            tick();

            links = fixture.debugElement.queryAll(By.css('a'));

            links.length.should.equal(5);

            links[0].nativeElement.textContent.should.equal('Legal');
            links[1].nativeElement.textContent.should.equal('GitHub');
            links[2].nativeElement.textContent.should.equal('Tutorial');
            links[3].nativeElement.textContent.should.equal('Docs');
            links[4].nativeElement.textContent.should.equal('Community');
        })));

        it('should load config if not already loaded', fakeAsync(inject([XHRBackend, ConfigService], (mockBackend, configService: ConfigService) => {
            let myConfig = new Config();
            myConfig.webonly = true;
            myConfig.title = 'My Title';
            myConfig.banner = ['My', 'Banner'];
            myConfig.docURL = 'https://doc_url';
            myConfig.links = {
                docs: 'My Docs',
                tutorial: 'My Tutorial',
                community: 'My Community',
                github: 'My Github',
                install: 'My Install',
                legal: 'My License'
            };

            mockBackend.connections.subscribe((connection) => {
                connection.mockRespond(new Response(new ResponseOptions({
                    body: JSON.stringify(mockResponseConfigService)
                })));
            });

            fixture.detectChanges();
            tick();
            fixture.detectChanges();

            component['config'].should.deep.equal(myConfig);
        })));

        it('should handle error from about service', fakeAsync(inject([ConfigService, XHRBackend], (configService, mockBackend) => {
            let myConfig = new Config();
            myConfig.webonly = true;
            myConfig.title = 'My Title';
            myConfig.banner = ['My', 'Banner'];
            myConfig.docURL = 'https://doc_url';
            myConfig.links = {
                docs: 'My Docs',
                tutorial: 'My Tutorial',
                community: 'My Community',
                github: 'My Github',
                install: 'My Install',
                legal: 'My License'
            };

            configService['configLoaded'] = true;
            configService['config'] = myConfig;

            component['alertService'].errorStatus$.subscribe(
                (message) => {
                    if (message !== null) {
                        message.should.equal('error');
                    }
                });

            mockBackend.connections.subscribe(
                (connection) => {
                    connection.mockError('error');
                }
            );

            fixture.detectChanges();
            tick();
            fixture.detectChanges();
        })));
    });
示例#9
0
    describe('asyncValidator', () => {
      it('should run validator with the initial value', fakeAsync(() => {
           const c = new FormControl('value', null, asyncValidator('expected'));
           tick();

           expect(c.valid).toEqual(false);
           expect(c.errors).toEqual({'async': true});
         }));

      it('should support validators returning observables', fakeAsync(() => {
           const c = new FormControl('value', null, asyncValidatorReturningObservable);
           tick();

           expect(c.valid).toEqual(false);
           expect(c.errors).toEqual({'async': true});
         }));

      it('should rerun the validator when the value changes', fakeAsync(() => {
           const c = new FormControl('value', null, asyncValidator('expected'));

           c.setValue('expected');
           tick();

           expect(c.valid).toEqual(true);
         }));

      it('should run the async validator only when the sync validator passes', fakeAsync(() => {
           const c = new FormControl('', Validators.required, asyncValidator('expected'));
           tick();

           expect(c.errors).toEqual({'required': true});

           c.setValue('some value');
           tick();

           expect(c.errors).toEqual({'async': true});
         }));

      it('should mark the control as pending while running the async validation', fakeAsync(() => {
           const c = new FormControl('', null, asyncValidator('expected'));

           expect(c.pending).toEqual(true);

           tick();

           expect(c.pending).toEqual(false);
         }));

      it('should only use the latest async validation run', fakeAsync(() => {
           const c = new FormControl(
               '', null, asyncValidator('expected', {'long': 200, 'expected': 100}));

           c.setValue('long');
           c.setValue('expected');

           tick(300);

           expect(c.valid).toEqual(true);
         }));

      it('should support arrays of async validator functions if passed', fakeAsync(() => {
           const c =
               new FormControl('value', null, [asyncValidator('expected'), otherAsyncValidator]);
           tick();

           expect(c.errors).toEqual({'async': true, 'other': true});
         }));

      it('should add single async validator', fakeAsync(() => {
           const c = new FormControl('value', null);

           c.setAsyncValidators(asyncValidator('expected'));
           expect(c.asyncValidator).not.toEqual(null);

           c.setValue('expected');
           tick();

           expect(c.valid).toEqual(true);
         }));

      it('should add async validator from array', fakeAsync(() => {
           const c = new FormControl('value', null);

           c.setAsyncValidators([asyncValidator('expected')]);
           expect(c.asyncValidator).not.toEqual(null);

           c.setValue('expected');
           tick();

           expect(c.valid).toEqual(true);
         }));

      it('should clear async validators', fakeAsync(() => {
           const c = new FormControl('value', [asyncValidator('expected'), otherAsyncValidator]);

           c.clearValidators();

           expect(c.asyncValidator).toEqual(null);
         }));

      it('should not change validity state if control is disabled while async validating',
         fakeAsync(() => {
           const c = new FormControl('value', [asyncValidator('expected')]);
           c.disable();
           tick();
           expect(c.status).toEqual('DISABLED');
         }));
    });
  describe('RuntimeCompiler', () => {
    let compiler: Compiler;
    let resourceLoader: SpyResourceLoader;
    let dirResolver: MockDirectiveResolver;
    let injector: Injector;

    beforeEach(() => { TestBed.configureCompiler({providers: [SpyResourceLoader.PROVIDE]}); });

    beforeEach(fakeAsync(inject(
        [Compiler, ResourceLoader, DirectiveResolver, Injector],
        (_compiler: Compiler, _resourceLoader: SpyResourceLoader,
         _dirResolver: MockDirectiveResolver, _injector: Injector) => {
          compiler = _compiler;
          resourceLoader = _resourceLoader;
          dirResolver = _dirResolver;
          injector = _injector;
        })));

    describe('compileModuleAsync', () => {
      it('should allow to use templateUrl components', fakeAsync(() => {
           @NgModule({
             declarations: [SomeCompWithUrlTemplate],
             entryComponents: [SomeCompWithUrlTemplate]
           })
           class SomeModule {
           }

           resourceLoader.spy('get').and.callFake(() => Promise.resolve('hello'));
           let ngModuleFactory: NgModuleFactory<any> = undefined !;
           compiler.compileModuleAsync(SomeModule).then((f) => ngModuleFactory = f);
           tick();
           expect(ngModuleFactory.moduleType).toBe(SomeModule);
         }));
    });

    describe('compileModuleSync', () => {
      it('should throw when using a templateUrl that has not been compiled before', () => {
        @NgModule(
            {declarations: [SomeCompWithUrlTemplate], entryComponents: [SomeCompWithUrlTemplate]})
        class SomeModule {
        }

        resourceLoader.spy('get').and.callFake(() => Promise.resolve(''));
        expect(() => compiler.compileModuleSync(SomeModule))
            .toThrowError(
                `Can't compile synchronously as ${stringify(SomeCompWithUrlTemplate)} is still being loaded!`);
      });

      it('should throw when using a templateUrl in a nested component that has not been compiled before',
         () => {
           @NgModule({declarations: [SomeComp, ChildComp], entryComponents: [SomeComp]})
           class SomeModule {
           }

           resourceLoader.spy('get').and.callFake(() => Promise.resolve(''));
           dirResolver.setView(SomeComp, new ViewMetadata({template: ''}));
           dirResolver.setView(ChildComp, new ViewMetadata({templateUrl: '/someTpl.html'}));
           expect(() => compiler.compileModuleSync(SomeModule))
               .toThrowError(
                   `Can't compile synchronously as ${stringify(ChildComp)} is still being loaded!`);
         });

      it('should allow to use templateUrl components that have been loaded before',
         fakeAsync(() => {
           @NgModule({
             declarations: [SomeCompWithUrlTemplate],
             entryComponents: [SomeCompWithUrlTemplate]
           })
           class SomeModule {
           }

           resourceLoader.spy('get').and.callFake(() => Promise.resolve('hello'));
           compiler.compileModuleAsync(SomeModule);
           tick();

           const ngModuleFactory = compiler.compileModuleSync(SomeModule);
           expect(ngModuleFactory).toBeTruthy();
         }));
    });
  });