All files / app/assets/javascripts/captcha init_recaptcha_script.js

100% Statements 15/15
100% Branches 0/0
100% Functions 5/5
100% Lines 15/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49      4x 4x                             4x   4x 4x 4x 4x 4x     4x   4x     2x 2x   4x                 4x 4x    
// NOTE: This module will be used in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52044
import { memoize } from 'lodash';
 
export const RECAPTCHA_API_URL_PREFIX = window.gon.recaptcha_api_server_url;
export const RECAPTCHA_ONLOAD_CALLBACK_NAME = 'recaptchaOnloadCallback';
 
/**
 * Adds the Google reCAPTCHA script tag to the head of the document, and
 * returns a promise of the grecaptcha object
 * (https://developers.google.com/recaptcha/docs/display#js_api).
 *
 * It is memoized, so there will only be one instance of the script tag ever
 * added to the document.
 *
 * See the reCAPTCHA documentation for more details:
 *
 * https://developers.google.com/recaptcha/docs/display#explicit_render
 *
 */
export const initRecaptchaScript = memoize(() => {
  // Appends the the reCAPTCHA script tag to the head of document
  const appendRecaptchaScript = () => {
    const script = document.createElement('script');
    script.src = `${RECAPTCHA_API_URL_PREFIX}?onload=${RECAPTCHA_ONLOAD_CALLBACK_NAME}&render=explicit`;
    script.classList.add('js-recaptcha-script');
    document.head.appendChild(script);
  };
 
  return new Promise((resolve) => {
    // This global callback resolves the Promise and is passed by name to the reCAPTCHA script.
    window[RECAPTCHA_ONLOAD_CALLBACK_NAME] = () => {
      // Let's clean up after ourselves. This is also important for testing, because `window` is NOT cleared between tests.
      // https://github.com/facebook/jest/issues/1224#issuecomment-444586798.
      delete window[RECAPTCHA_ONLOAD_CALLBACK_NAME];
      resolve(window.grecaptcha);
    };
    appendRecaptchaScript();
  });
});
 
/**
 * Clears the cached memoization of the default manager.
 *
 * This is needed for determinism in tests.
 */
export const clearMemoizeCache = () => {
  initRecaptchaScript.cache.clear();
};