Angular Google Sign with Test - PullRequest
       12

Angular Google Sign with Test

0 голосов
/ 21 апреля 2020

У меня возникли проблемы с насмешливой функцией attachClickHandler gauth. Ниже мой код. Я не могу издеваться над коллбэками attachClickHander onSuccess и onFailure. Таким образом, невозможно проверить метод prepareLoginButton.

export class GoogleSignInButtonComponent implements OnInit {

  auth2: any;

  constructor(
    private socialSignInController: SocialSignInControllerService,
    private ngZone: NgZone,
    private toastr: ToastrService,
    private authenticationService: AuthenticationService) { }

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

    window['googleSDKLoaded'] = () => {
      window['gapi'].load('auth2', () => {
        this.auth2 = window['gapi'].auth2.init({
          client_id: environment.social.google.clientId,
          cookiepolicy: 'single_host_origin',
          scope: 'profile email'
        });
        this.prepareLoginButton();
      });
    }

    (function (d, s, id) {
      var js, fjs = d.getElementsByTagName(s)[0];
      if (d.getElementById(id)) { return; }
      js = d.createElement(s); js.id = id;
      js.src = "https://apis.google.com/js/platform.js?onload=googleSDKLoaded";
      fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'google-jssdk'));

  }

   prepareLoginButton() {
    this.auth2.attachClickHandler(document.getElementById('googleBtn'), {},
      (googleUser) => {
        this.ngZone.run(() => {
          const token = googleUser.getAuthResponse().id_token;
          this.socialSignInController.googleTokenSignIn(token).subscribe(res => {
            this.authenticationService.onSocialLoginSuccess(res.token);
            window.location.href = '/dashboard'
          });
        }, (error) => {
          this.toastr.error('An error occurred. Please try again', 'Could not sign you in')
          console.log(error);
        });
      })

  }

}

1 Ответ

0 голосов
/ 24 апреля 2020

Цель состояла в том, чтобы реализовать вход в Google. И код должен быть проверен на 100%. Поскольку было нелегко насмехаться над функцией успеха auth2 attachClickHandler, я удалил ее и использовал библиотеку angularx-social-login ссылку на GitHub repo

Я создал CustomHRefService, потому что router.navigate не работал, внутри обещания тогда функционируют. Позже я обнаружил, что завершение обещания стать Observable решило эту проблему.

Код и тест выглядят следующим образом:

Кнопка html

<a #googlebtn (click)="signInWithGoogle()" class="social_bt google" id="googleBtn">Login with google</a>

Кнопка Ts

import { Component, OnInit, Inject } from '@angular/core';
import { AuthService, GoogleLoginProvider } from 'angularx-social-login';
import { SocialSignInControllerService } from 'dd-core-api-sdk';
import { CustomHrefService } from 'src/app/services/custom-href.service';

@Component({
  selector: 'app-google-btn',
  templateUrl: './google-btn.component.html',
  styleUrls: ['./google-btn.component.css'],
})
export class GoogleBtnComponent implements OnInit {

  constructor(private authService: AuthService,
    private socialSignInController: SocialSignInControllerService,
    private authenticationService: AuthenticationService,
    private customeHref: CustomHrefService
  ) { }

  ngOnInit(): void {
  }

  signInWithGoogle(): void {
    this.authService.signIn(GoogleLoginProvider.PROVIDER_ID).then(googleUser => {
      this.socialSignInController.googleTokenSignIn({ token: googleUser.idToken }).subscribe(res => {
        this.authenticationService.onSocialLoginSuccess(res.token);
        this.customeHref.jumpTo('/dashboard')

      })
    })
  }

}

Проверка кнопки

import { async, ComponentFixture, TestBed, tick, fakeAsync } from '@angular/core/testing';

import { GoogleBtnComponent } from './google-btn.component';
import { provideConfig } from '../authentication.module';
import { AuthenticationServiceImpl } from 'src/app/services/authentication.service';
import { AuthService, AuthServiceConfig, SocialUser } from 'angularx-social-login';
import { of } from 'rxjs';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { ToastrModule } from 'ngx-toastr';
import { CustomHrefService } from 'src/app/services/custom-href.service';
import { WindowToken } from 'src/app/injector/window';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';

const MockWindow = {
  location: {
    _href: '',
    set href(url: string) { this._href = url },
    get href() { return this._href }
  }
};

describe('GoogleBtnComponent', () => {
  let component: GoogleBtnComponent;
  let fixture: ComponentFixture<GoogleBtnComponent>;
  let authService: AuthService;
  let socialSignInService: SocialSignInControllerService;
  let socialSignInSpy: jasmine.Spy;
  let authSpy: jasmine.Spy;
  let service: CustomHrefService;
  let setHrefSpy: jasmine.Spy;

  beforeEach(async(() => {

    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule,
        RouterTestingModule.withRoutes([{ path: 'dashboard', component: DummyComponent }]),
        ToastrModule.forRoot(),
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader,
            useValue: new FakeLoader()
          }
        }),
      ],

      declarations: [GoogleBtnComponent],
      providers: [{
        provide: AuthenticationService,
        useClass: AuthenticationServiceImpl,
      }, AuthService, { provide: AuthServiceConfig, useFactory: provideConfig },
      { provide: CustomHrefService, useClass: CustomHrefService, deps: [WindowToken]},
      { provide: WindowToken, useValue: MockWindow }]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    //mock response
    socialSignInService = TestBed.get(SocialSignInControllerService);
    service = TestBed.get(CustomHrefService);
    authService = TestBed.get(AuthService);
    socialSignInSpy = spyOn(socialSignInService, "googleTokenSignIn").and.returnValue(of({ token: '2323' } as any))
    setHrefSpy = spyOnProperty(MockWindow.location, 'href', 'set');
    const googleUser: SocialUser = {
      name: 'godwin', firstName: 'ish',
      lastName: 'dako', idToken: '1009',
      provider: 'google',
      id: '2', email: 'noone@gmail.com',
      photoUrl: 'null',
      authToken: '2323', authorizationCode: '232'
    };
    authSpy = spyOn(authService, 'signIn').and.returnValue(Promise.resolve(googleUser));
    fixture = TestBed.createComponent(GoogleBtnComponent);
    authService = TestBed.get(AuthService);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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

  it('should sign with google', fakeAsync(() => {
    component.signInWithGoogle();
    fixture.detectChanges();
    tick(3);
    expect(setHrefSpy).toHaveBeenCalledWith('/dashboard');
  }))


});

CustomHrefService

import { Injectable, Inject } from '@angular/core';
import { WindowToken } from '../injector/window';

@Injectable({
  providedIn: 'root'
})
export class CustomHrefService {

  constructor(@Inject(WindowToken) private window: Window) {}

  jumpTo(url: string) {
    this.window.location.href = url;
  }}

WindowToken

import { InjectionToken } from '@angular/core';

export const WindowToken = new InjectionToken('Window');
export function windowProvider() { return window; }

Использование InjectionToken

@NgModule({
  declarations: [
    //components],
  imports: [
    //other modules
  ],
  providers: [{
    { provide: WindowToken, useFactory: windowProvider }
  ]
})
export class AuthenticationModule { }

Тест CustomHrefService

import { TestBed } from '@angular/core/testing';

import { CustomHrefService } from './custom-href.service';
import { Injector } from '@angular/core';
import { WindowToken } from '../injector/window';
import { AuthenticationModule } from '../modules/authentication/authentication.module';

const MockWindow = {
  location: {
    _href: '',
    set href(url: string) { this._href = url },
    get href() { return this._href }
  }
};

describe('CustomHrefService', () => {
  let service: CustomHrefService;
  let setHrefSpy: jasmine.Spy;


  beforeEach(() => {
    setHrefSpy = spyOnProperty(MockWindow.location, 'href', 'set');
    const injector = Injector.create({
      providers: [
        { provide: CustomHrefService, useClass: CustomHrefService, deps: [WindowToken]},
        { provide: WindowToken, useValue: MockWindow}
      ]
    });
    service = injector.get(CustomHrefService);
  });

  it('should be registered on the AppModule', () => {
    service = TestBed.configureTestingModule({ imports: [AuthenticationModule] }).get(CustomHrefService);
    expect(service).toEqual(jasmine.any(CustomHrefService));
  });

  describe('#jumpTo', () => {
    it('should modify window.location.href', () => {
      const url = 'http://localhost:8080';
      service.jumpTo(url);
      expect(setHrefSpy).toHaveBeenCalledWith(url);
    });
  });
});
...