在 firebase 函数中添加 auth0

Stubbing auth0 in firebase functions

我有以下使用 Auth0 获取用户配置文件的 Firebase 函数。

'use strict';

const {
    dialogflow,
    Image,
  } = require('actions-on-google')

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp(functions.config().firebase);

const db = admin.firestore();

// database collection and key names
const DB_BANK_COLLECTION_KEY = 'bank'
// the action name from all Dialogflow intents
const INTENT_WELCOME_USER = 'Default Welcome Intent';

// Initialize the Auth0 client
var AuthenticationClient = require('auth0').AuthenticationClient;
var auth0 = new AuthenticationClient({
    domain: functions.config().familybank.auth0.domain,
    clientID: functions.config().familybank.auth0.clientid
});

const app = dialogflow();

app.intent(INTENT_WELCOME_USER, async (conv) => {
    console.log('Request: ' + JSON.stringify(conv.request));

    const userInfo = await auth0.getProfile(conv.user.access.token)
    .catch( function(err) {
        console.error('Error getting userProfile from Auth0: ' + err);
        conv.close("Something went wrong. Please try again in a few minutes. " + err)
    });
    console.log('userInfo: ' + JSON.stringify(userInfo));

    // check for existing bank, if not present, create it
    var bankRef = db.collection(DB_BANK_COLLECTION_KEY).doc(userInfo.email);
    const bankSnapshot = await bankRef.get()

})

exports.accessAccount = functions.https.onRequest(app);

我尝试使用以下代码(和几个排列)在我的测试中模拟 auth0,但实际函数总是被调用而不是模拟。

const chai = require('chai');
const assert = chai.assert;

const sinon = require('sinon');

// Require firebase-admin so we can stub out some of its methods.
const admin = require('firebase-admin');
const test = require('firebase-functions-test')();

var AuthenticationClient = require('auth0').AuthenticationClient;
var auth0 = new AuthenticationClient({
  domain: "mock",
  clientID: "mock"
});

describe('Cloud Functions', () => {
  let myFunctions, adminInitStub;

  before(() => {
    test.mockConfig({"familybank": {"auth0": {"domain": "mockdomain", "clientid": "mockid"}}});
    adminInitStub = sinon.stub(admin, 'initializeApp');
    sinon.stub(admin, 'firestore')
   .get(function() { 
       return function() { 
           return "data";
       }
    });
    sinon.stub(auth0, 'getProfile').callsFake( function fakeGetProfile(accessToken) {
      return Promise.resolve({"email": "daniel.watrous@gmail.com", "accessToken": accessToken});
    });
    myFunctions = require('../index');
  });

  after(() => {
    adminInitStub.restore();
    test.cleanup();
  });

  describe('accessAccount', () => {

    it('should return a 200', (done) => {
      const req = {REQUESTDATA};
      const res = {
        redirect: (code, url) => {
          assert.equal(code, 200);
          done();
        }
      };

      myFunctions.accessAccount(req, res);
    });
  });
})

有什么方法可以为我的离线测试模拟 auth0 吗?

我发现与其初始化 Auth0 AuthenticationClient,不如先请求 UsersManager,其中定义了 getProfile(包装 getInfo)。

var UsersManager = require('auth0/src/auth/UsersManager');

在我的 before() 方法中,我可以为 getInfo 创建一个存根,就像这样

sinon.stub(UsersManager.prototype, 'getInfo').callsFake( function fakeGetProfile() {
  return Promise.resolve({"email": "some.user@company.com"});
});

所有对 auth0.getProfile 的调用然后 return 解析为我的存根伪函数中显示的文档的 Promise。