/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { MdDialogRef } from '@angular/material';
import { AbstractMockObservableService } from '../../common/abstract-mock-observable.service';
import { LogoutComponent } from './logout.component';
import { MessageService } from '../../services/message.service';
import { Router } from '@angular/router';
import { AuthenticationService } from '../../services/authentication.service';
import { Observable } from 'rxjs/Observable';

class FakeRouter {
  navigate(commands: any[]) {
    return commands[0];
  }
}

class MockAuthService extends AbstractMockObservableService {

  logout() {
    return this;
  }
}

class MockDialogRef extends AbstractMockObservableService {
  config: MdDialogConfigMock;
  close() { }
}

class MdDialogConfigMock {
  data: any;
}

class MockMainNavigation {
  logout() { }
}

describe('LogoutComponent', () => {
  let component: LogoutComponent;
  let fixture: ComponentFixture<LogoutComponent>;
  let routerStub: FakeRouter;
  let messageService;
  let router: Router;
  let mockAuthService;  
  let mockDialog: MockDialogRef;

  routerStub = {
    navigate: jasmine.createSpy('navigate').and.callThrough()
  };


  beforeEach(async(() => {
    mockAuthService = new MockAuthService();
    mockDialog = new MockDialogRef();
    messageService = new MessageService();    
    router = new FakeRouter() as any as Router;    

    TestBed.configureTestingModule({
      declarations: [LogoutComponent],
      providers: [            
        { provide: AuthenticationService, useValue: mockAuthService },
        { provide: MdDialogRef, useValue: mockDialog },
        { provide: Router, useValue: routerStub },
        { provide: MessageService, useValue: messageService }
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {    
    fixture = TestBed.createComponent(LogoutComponent);
    component = fixture.componentInstance;    
  });

  it('should navigate to logout page on abmelden click', async(() => {          
    const configMock: MdDialogConfigMock  = new MdDialogConfigMock();
    const mockMainNav: MockMainNavigation  = new MockMainNavigation();
    configMock.data = mockMainNav;    
    mockDialog.config = configMock;

    mockAuthService.content = Observable.of('');    
    fixture.detectChanges();

    component.logout();
    fixture.detectChanges();
    expect(routerStub.navigate).toHaveBeenCalledWith(['/logout']);
  }));

  it('shouldnt navigate to logout page on error', async(() => {          
    const configMock: MdDialogConfigMock  = new MdDialogConfigMock();
    const mockMainNav: MockMainNavigation  = new MockMainNavigation();
    configMock.data = mockMainNav;    
    mockDialog.config = configMock;

    mockAuthService.error = 'MOCKERROR';
    fixture.detectChanges();

    component.logout();
    fixture.detectChanges();
    expect(routerStub.navigate).toHaveBeenCalledWith(['/logout']);
  }));  

});
