mocking auth2.attachClickHandler of gapi

644 views
Skip to first unread message

Kiflemariam Andom

unread,
Oct 9, 2019, 6:07:28 AM10/9/19
to Angular and AngularJS discussion
Declaration: this is part of my assignment for an online class that is already submitted for grading but it has already failed on my setup so...i will be asked to redo it until I get it but i don't have any other idea after a week.

Background: I am not supposed to change the code base. I am supposed to write a unit test only. All is in https://stackblitz.com/edit/angular-3fg4ny

To paste all the code here:

index.html:

<html>
<head>
  <script src="https://apis.google.com/js/platform.js" async defer></script>
</head>


<my-app>loading</my-app>

</html>

app.component.ts:

import { Component, OnInit } from '@angular/core';
declare let gapi: any;

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit  {
   auth2 : any;

  ngOnInit(){
    this.loadAuth();
  }
 
   loadAuth(){
    try {
      if (typeof gapi != "undefined") {
        gapi.load("auth2", () => {
          console.log(48)
          this.auth2 = gapi.auth2.init({
            cookiepolicy: "single_host_origin",
            scope: "profile email"
          });
          console.log(55);
         this.attachSignin(document.getElementById('google-login')).then(profile=>{
           console.log(48, profile)
         }).catch(error=>{
           console.log(50, error)
         }).finally(()=>{
           console.log(52, ' finally')
         })
        });
      } else {
        console.log(32, "gapi undefined");
      }
      
    } catch (err) {
      console.log(26, err);
    }
    
    console.log('step 2')
  }
  
    public attachSignin(element): Promise<any> {
    
    return new Promise((resolve, reject) => {
      if (typeof gapi == "undefined") {
   
        reject({'reason' : 'gapiUndefined'});
      } else {
        
        this.auth2.attachClickHandler(
          element,
          {},
          googleUser => {
            console.log(googleUser)
            let profile = googleUser.getBasicProfile();
         
           
              const details  = {
                name : profile.getName(),
                email : profile.getEmail(),
                token : googleUser.getAuthResponse().id_token,
                id_token : profile.getId()
              }
              
              resolve(details);
           
          },
          error => {
            // for e.g. if user closes the window
          
            reject({'reason': 'closedByUser'});
          }
        );
      }
    });
  }

}


Now in my tests, I am reaching attachSignin but I am never console logging googleUser which is : console.log(googleUser)

I can't really know how the attachClickHandler is setup or really where it is coming from because I checked platform.js from google and can't find a definition of it either. From the looks of it, I thought it is an observable but can't mock it.

Basically, in the real assignment, once googleUser is returned, there is a logic in place around the returned email and name that resolves or rejects the promise. All I wwant to do, I think correctly, is to make attachClickHandler to return a google user but I am still very fuzzy on it.

Can you take a look at my spec file and help?

Sander Elias

unread,
Oct 9, 2019, 11:47:07 PM10/9/19
to Angular and AngularJS discussion
Hi Kiflemariam,

I think you are right, and you should return a google user. Log out, and copy the result from the app, and make a moke that returns a Promise<GoogleUser>

mockedUser() {return Promise.resolve({...})}

btw, I don't think you included your spec file ;)

Regards
Sander

Kiflemariam Andom

unread,
Oct 11, 2019, 5:07:21 AM10/11/19
to Angular and AngularJS discussion
Hi Sander,

Thanks so much. I totally forgot my spec file, which I did. It had googleUser class already but I think I didn't use it right. Can you have a quick look when you are free?

Sander Elias

unread,
Oct 11, 2019, 7:43:35 AM10/11/19
to Angular and AngularJS discussion
Sure, attach it to a message ;)

Kiflemariam Andom

unread,
Oct 11, 2019, 9:45:44 AM10/11/19
to Angular and AngularJS discussion
Hey Sander, here it is. The button click is stimulated and it does enter attachSignIn method then nothing:

import { async, ComponentFixture, TestBed } from "@angular/core/testing";

import {
  AppComponent
} from "./app.component";

import { By } from "@angular/platform-browser";
import { DebugElement } from "@angular/core";
import { Observable } from 'rxjs';
import { of } from 'rxjs';

const gapiInit =
{
  client_id: '',
  cookiepolicy: "single_host_origin",
  scope: "profile email"
}


class googleUser {
  getAuthResponse(){
    return {
      id_token:'idtoken'
    }
  }
  getBasicProfile() {
    return {
      getName(){
        return 'name'
      },
      getEmail(){
        return 'em...@email.net'
      },
      getId(){
        return 'id'
      }
    }
  }
}

let compOnInit = null;

function resetCompOnInit(comp) {
  if (compOnInit == null) {
    compOnInit = comp.ngOnInit;
    comp.ngOnInit = function() {};
  } else {
    comp.ngOnInit = compOnInit;
    compOnInit = null;
  }
}

describe("Integration::Component", () => {

  it('button click should call Attach Sign In event', async(() => {
    const { comp, fixture, de, el, btn } = setup();
    resetCompOnInit(comp);


    fixture.detectChanges();

    comp.loadAuth = function(){
        return null;
     }
    comp.loadAuth();

   class auth2 {

    attachClickHandler(btn, {}, callBack){
      return callBack(of(new googleUser()))
    }

    }
  
    comp.auth2 = new auth2();

    spyOn(comp.auth2, "attachClickHandler").and.returnValue(of(new googleUser()));
    btn.addEventListener("click", ()=>{comp.attachSignin(btn)}, false);
    resetCompOnInit(comp);
    btn.click();

    fixture.whenStable().then(() => {
      comp.attachSignin(btn).then(profile=>{
        console.log(195, profile)
      }).catch(err=>{
        console.log(197, err)
      })
    });
  }));

  //

  function setup() {
    TestBed.configureTestingModule({
      providers: [],
      declarations: [
        AppComponent
      ]
    });

    const fixture = TestBed.createComponent(AppComponent);

    const comp = fixture.componentInstance;

    const de = fixture.debugElement;
    const el = de.nativeElement;
    const btn = el.querySelector("#google-login");

    window["gapi"] = {
      load(auth2, callback) {
        return null;
      },

      auth2() {
        function init(gapiInit){
          return null
        }
      },

    };

    return { comp, fixture, de, el, btn };
  }
});


On Wednesday, 9 October 2019 03:07:28 UTC-7, Kiflemariam Andom wrote:
Reply all
Reply to author
Forward
0 new messages