繁体   English   中英

如何绕过auth0登录以进行Angular测试?

[英]How do I bypass auth0 login for Angular testing?

我正在尝试为Angular / Auth0应用程序编写测试。 当localStorage中没有任何内容或它们的令牌已过期时,它将把用户定向到auth0域进行登录。 但是,我很难模拟用户绕过auth0登录屏幕。

app.component.ts:

export class AppComponent {
  constructor( public auth: AuthService) { auth.handleAuthentication() }
}

auth.service.ts:

export class AuthService {
  authConfig = {
    clientID: //omitted for privacy,
    domain: //omitted for privacy,
    callbackURL: window.location.origin + '/home',
    apiUrl: //omitted for privacy
  }

  auth0 = new auth0.WebAuth({
    clientID: this.authConfig.clientID,
    domain: this.authConfig.domain,
    responseType: 'token id_token',
    audience: this.authConfig.apiUrl,
    redirectUri: this.authConfig.callbackURL,
    scope: 'openid profile email',
  })

  constructor() { }

  public login(): void {
    this.auth0.authorize()
  }

  public logout(): void {
    localStorage.removeItem('access_token')
    localStorage.removeItem('id_token')
    localStorage.removeItem('expires_at')
    this.login()
  }

  public handleAuthentication(): void {
    if( this.isAuthenticated() ) return

    // if the token is old, logout
    if(localStorage.getItem('expires_at') && !this.isAuthenticated()) { 
      this.logout()
    } else {
      this.auth0.parseHash((err, authResult) => {

        // if we didn't just log in, and we don't have an expiration token, login
        if(authResult === null && !localStorage.getItem('expires_at')) {
          this.login()
        }

        if(authResult && authResult.accessToken && authResult.idToken) {
          this.setSession(authResult)
        }
      })
    }
  }

  private setSession(authResult: any): void {
    // Set the time that the Access Token will expire at
    const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime())
    localStorage.setItem('sub', authResult.idTokenPayload.sub)
    localStorage.setItem('email', authResult.idTokenPayload.sub.split('|')[2])
    localStorage.setItem('access_token', authResult.accessToken)
    localStorage.setItem('id_token', authResult.idToken)
    localStorage.setItem('expires_at', expiresAt)
  }

  // Check whether the current time is past the access token's expiration time
  public isAuthenticated(): boolean {
    const expiresAt = JSON.parse(localStorage.getItem('expires_at'))
    return new Date().getTime() < expiresAt
  }
}

app.component.spec.ts:

import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import { MaterialModule } from './material.module';

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ 
        RouterTestingModule,
        MaterialModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    console.log('inside create app in app spec');
    expect(app).toBeTruthy();
  });
});

auth.service.spec.ts:

import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AuthService } from './auth.service';
import { DebugElement } from '@angular/core';

describe('AuthService', () => {
  let service: AuthService;
  let authSpy;
  let fixture: ComponentFixture<AuthService>;
  let debugElement: DebugElement;

  beforeAll( () => {
    const expiry = JSON.stringify(new Date().setHours(5));
    localStorage.setItem('sub', 'sub')
    localStorage.setItem('email', 'test@test.com')
    localStorage.setItem('access_token', '1234')
    localStorage.setItem('id_token', '1234')
    localStorage.setItem('expires_at', expiry);
  })

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

    service = new AuthService();
    authSpy = spyOn(service, 'isAuthenticated').and.returnValue(true);
  });

  afterAll( () => {
    service = null;
  })

  it('should be created', () => {
    const service: AuthService = TestBed.get(AuthService);
    console.log('inside auth service spec');
    expect(service).toBeTruthy();
  });

  it ('should return true when all localStorage set', () => {
    //this is not returning true even if it gets to run, which 70% of the time it doesn't
    expect( service.isAuthenticated() ).toBeTruthy();
  });
});

现在,如果我只是在浏览器中运行此程序而不进行测试,那么它将运行良好。 登录用户,将他们路由到/ home。 但是测试使我进入auth0登录屏幕(之前可能运行了2-6个测试),如果我使用登录名,它会显示404:/ home。

我似乎找不到关于auth0,Angular和路由的任何良好的测试文档...非常感谢任何帮助

而不是在constructor中运行auth.handleAuthentication() ,而应在ngOnInit方法中运行它。 这使您可以创建组件实例并测试其功能,而无需发送登录信息。

我阅读过的大多数Angular文档都推荐这种方法,并限制在任何服务或组件的构造函数中完成的代码量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM