Search code examples
angulartypescriptunit-testingkarma-jasmineistanbul

How to unit testing OidcSecurityService.checkAuth function with Jasmine?


I am using Jasmine for unit testing in Angular. And I am using the OidcSecurityService service for security. Now I want to unit test this piece for the automatic login:

export class AppComponent implements OnInit {
  title = 'cityflows-client';
  constructor(public oidcSecurityService: OidcSecurityService, private router: Router, public platform: Platform) {}

  ngOnInit() {
    this.oidcSecurityService
      .checkAuth()

      .subscribe(isAuthenticated => {
        if (!isAuthenticated) {
          if ('/autologin' !== window.location.pathname) {
            this.write('redirect', window.location.pathname);
            this.router.navigate(['/autologin']);
          }
        }
        if (isAuthenticated) {
          this.navigateToStoredEndpoint();
        }
      });
  }

and so the unit test looks like this:

describe('AppComponent', () => {
  let component: AppComponent;
  let fixture: ComponentFixture<AppComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      providers:    [ {provide: OidcSecurityService, useClass: OidcSecurityServiceStub} ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));
  beforeEach(() => {
    fixture = TestBed.createComponent(AppComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create the app', () => {
    expect(component).toBeTruthy();
  }); 
});

And the stub looks like this:

export class OidcSecurityServiceStub {
  getToken() {
    return 'some_token_eVbnasdQ324';
  }

  checkAuth(url: string) {
    return of(url);
  }

  authorize(authOptions?: AuthOptions) {
    if (authOptions) {
      return authOptions.urlHandler('http://localhost');
    } else {
      return null;
    }
  }
}

But i see in the coverage report this:

by the if that the else part is not taken.

So what I have to change? Thank you

  it('should redirect user to login page if user is not logged in', () => {
    
    expect(component).toBeTruthy();
  });

Solution

    1. You need to correct mockfile
    export class OidcSecurityServiceStub {
      getToken() {
        return 'some_token_eVbnasdQ324';
      }
    
      checkAuth() {
        return of(true); // <-------- make it return true
      }
    
      authorize(authOptions?: AuthOptions) {
        if (authOptions) {
          return authOptions.urlHandler('http://localhost');
        } else {
          return null;
        }
      }
    }
    

    this would cover below code:

     if (isAuthenticated) {
              this.navigateToStoredEndpoint();
            }
    

    now for false, use jasmine

      it('Navigate if not authenticated', () => {
        spyOn(component.oidcSecurityService,'checkAuth').and.returnValue(of(false));
        // also spy on write and router.navigate
        component.ngOnInit()
        expect(component.router.navigate).not.toHaveBeenCalledWith(['/autologin']); // because the url will not be /authLogin (I am assuming, please correct accordingly)
        // similarly check for component.write()
      }); 
    
    
    1. To check if ('/autologin' !== window.location.pathname) you need to override the window object to set the value accordingly in pathName

    You can refer this question where I mocked one of the window method. in You case you need to set pathName and test it