Search code examples
reactjsgoogle-apijestjsenzymegoogle-api-js-client

How to mock window.gapi.load() React + Jest


There's a question that answers this for Angular, and a question without any answers for Vuejs. I'm trying to find a way to mock the window.gapi.load() function in my tests. I'm new to React testing and this is what I have so far:

it('should render the App component without crashing', function () {
  const component = renderer.create(
    shallow(
      <Root>
        <App/>
      </Root>
    )
  )

  let tree = component.toJSON()
  expect(tree).toMatchSnapshot()
})

I have tried a basic beforeEach call to try and load it or something but that didn't work either. Here is the code in the component:

const App = () => {
  const { isSignedIn } = useSelector(state => state.auth)

  const renderApp = () => {
    if (isSignedIn) {
      return <Home/>
    } else {
      return (
          <div className='app'>
            <h1 id='logo'>netTube</h1>
            <GoogleAuth/>
          </div>
      )
    }
  }

  return (
      <>
        { renderApp() }
      </>
  )
}

And the call in the GoogleAuth component:

// GoogleAuth.jsx

componentDidMount() {
    window.gapi.load('client:auth2', () => {
      window.gapi.client.init({
        clientId: process.env.REACT_APP_GOOGLE_CLIENT_ID,
        scope: 'email'
      }).then(() => {
        this.auth = window.gapi.auth2.getAuthInstance()
        this.onAuthChange(this.auth.isSignedIn.get())
        this.auth.isSignedIn.listen(this.onAuthChange)
      })
    })
  }

If there is anything else you'd like me to add, please ask. Sorry if there is not enough information, as I said, I am super new to React testing. Thank you!


Solution

  • Expanding a little on the answers from Tom & Hector, I added a JWT token and it seems to work in Jest for mocking the basics of signing in & out of gapi.auth2:

    window.gapi = {auth2: {}, client: {}};
    window.gapi.auth2.getAuthInstance = () => {return new function() {
      this.isSignedIn = new function() {
        this.signedIn = false;
        this.get = () => this.signedIn;
        this.listen = (f) => f();
      };
      this.signIn = () => Promise.resolve(this.isSignedIn.signedIn = true);
      this.signOut = () => Promise.resolve(this.isSignedIn.signedIn = false);
      this.currentUser = new function() {
        this.get = () => new function() {
          this.getId = () => "XYZ";
          this.getAuthResponse = () => new function() {
            this.id_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
          };
          this.getBasicProfile = () => new function() {
            this.getName = () => "Mr Test";
            this.getEmail = () => "test@email.com";
            this.getImageUrl = () => "http://email.com/image";
          };
        };
      };
    };}
    window.gapi.auth2.init = () => {return Promise.resolve({});}
    window.gapi.client.init = (v) => true;
    window.gapi.load = (a, f) => f();