2017-01-12 6 views
3

私は一定期間後にユーザを自動ログアウトするのにng2-idleを使用しています。私は私のappComponentコンストラクタでそれを初期化:私はthis.idle.watch()使用して私のLoginComponentでそれを起動するログインに成功すると分度器テストのためのng2-idleを停止する

import {Idle, DEFAULT_INTERRUPTSOURCES} from '@ng-idle/core'; 

export class AppComponent { 

    constructor(
     private idle:Idle) { 

     idle.setIdle(21600); 
     idle.setTimeout(1); 
     idle.setInterrupts(DEFAULT_INTERRUPTSOURCES); 

     idle.onTimeout.subscribe(() => { this.logout(); }); 
    }; 

(アイドルがコンストラクタ内に注入されます)。

これはすべて問題なく動作しますが、私の分度器テストを実行すると時間切れになるので、分断器がタイムアウトを待っているため、ng2-idleを6時間に設定してからしばらく時間がかかります。私はIdle.watch()を使用して初期化しない場合

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. 

その後、テストが実行されます。私が何をしたいか

は私の分度器の設定ファイルにonPrepareブロックにIdle.stop();を設定し、テストが私のonCompleteブロック内に完了した後にIdle.watch();にそれをリセットすることです。

私は分度器のconfファイル内var idle = require('@ng-idle/core');を試してみましたが、それは次のように私をバックスロー:

ReferenceError: document is not defined

それでは、どのように私は分度器の設定ファイルにNG2-アイドル・モジュールを必要とすることができますか?

+0

のためのオープン欠陥がある見つけました。 idle + timeoutの値がDEFAULT_TIMEOUT_INTERVALより小さい場合、テストは実行中であるように見えます。 – santon

答えて

2

質問した質問に対する解決策はありません。しかし、私はあなたにこの問題を解決するための別のアプローチを提供します。チームの分度器をセットアップしているときに、ng-idleを使ってセッションタイムアウト戦略を実装した後も同じ問題が発生しました。これを解決する方法について少し胸を痛めた後、Angular zone APIを使ってこれを解決することができました。ここに私のappcomponentがあります。 ゾーン内でrunOutsideAngularおよびrunメソッドを参照してください。

すべての状態の変更は、runメソッド内でラップされていることに注意してください。そうでない場合、変更検出は機能せず、カウントダウンタイマーを含む状態フィールドのどれもUIを更新しません。

この解決策には、現在の理解の中で、分裂器ではできないため、ng-idleを使用するアプリケーションを変更する必要があります。

this.ngZone.runOutsideAngular

@Component({ 
selector : 'app-root', 
templateUrl: './app.component.html', 
styleUrls : [ './app.component.scss' ] 
}) 

export class AppComponent implements OnInit, OnDestroy{ 

idleState = 'Not started.'; 
idleStateTitle = ''; 
idleStateBtnText = ''; 
timedOut = false; 

@ViewChild(DialogComponent) dialog: DialogComponent; 

constructor(private idle: Idle, 
      private locationStrategy: LocationStrategy, 
      private authUtils: AuthUtils, 
      private ngZone: NgZone){ 

    this.ngZone.runOutsideAngular(() => { 
     //Idle timer is set to 28 minutes and timeout count down timer will run for 2 minutes. 
     idle.setIdle(28 * 60); 
     idle.setTimeout(120); 
    }); 


    //When idling starts display the dialog with count down timer 
    idle.onIdleStart.subscribe(() =>{ 
     this.idleState = ''; 
     this.idleStateTitle = 'Your session is about to expire.'; 
     this.idleStateBtnText = 'Stay Logged In'; 
     this.ngZone.run(() => this.dialog.show()); 
    }); 

    //User stopped idling 
    idle.onIdleEnd.subscribe(() =>{ 
     this.idleState = 'No longer idle.'; 
    }); 

    //Show timeout warning two minutes before expiry 
    idle.onTimeoutWarning.subscribe((countdown) =>{ 
     this.ngZone.run(() => { this.idleState = 'Your session will time out in ' + countdown + ' seconds! '}); 
    }); 

    //Session Timed out 
    idle.onTimeout.subscribe(() =>{ 
     this.ngZone.run(() =>{ 
      this.idleStateTitle = "Your session has expired."; 
      this.idleState = 'To Continue, log back in'; 
      this.timedOut = true; 
      this.idleStateBtnText = 'Log in Again'; 
     }); 
    }); 
} 

reset(){ 
    this.ngZone.runOutsideAngular(() => { 
     this.idle.watch(); 
    }); 
    this.ngZone.run(() =>{ 
     this.idleState = 'Started.'; 
     this.idleStateTitle = ""; 
     this.idleStateBtnText = ''; 
     this.timedOut = false; 
    }); 
} 

title = 'Projects'; 

/** 
* <p>Refresh Token by getting user token from the user service. Also reset the idle state timer here.</p> 
*/ 
refreshToken(){ 
    this.authUtils.refreshToken(); 
    this.reset(); 
} 

/** 
* Handle timeout 
*/ 
processTimeout(){ 
    this.dialog.hide(null); 
    if(this.timedOut){ 
     AuthUtils.invalidateSession(); 
     let origin = window.location.origin; 
     window.location.href = origin + this.locationStrategy.getBaseHref() + "?_="+ (Math.floor(Math.random() * 10000)); 
    } 
    else{ 
     this.refreshToken(); 
    } 
} 

ngOnInit(): void{ 
    this.reset(); 
} 

ngOnDestroy(): void{ 
    this.ngZone.runOutsideAngular(() =>{ 
     this.idle.stop(); 
    }); 
} 
} 

私はbrowser.waitForAngularEnabled(false)を使用して、いくつかの部分的な成功を持っていたし、無効とbeforeEachafterEachジャスミン・ルーチン内でそれらを有効にします。彼らは薄れていて、すべてのテストでうまく機能しませんでした。

編集:私は、NG2-アイドル課題追跡をチェックし、私が把握しようと、同じ問題を打っています。このhere

関連する問題