Firebase-функция для диалогового потока не возвращается - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть следующая облачная функция 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();

const config = require('config');

// 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(config.get('dialogflow.intents.welcome_user'), async (conv) => {
    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)
    });

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

    if (bankSnapshot.exists) {
        conv.ask("Welcome back to Family Bank. I just opened the bank I found for " + userInfo.name + ". How can I help you?");
    } else {
        // create new account
        conv.ask("Welcome to Family Bank. I just created a new bank for " + userInfo.name + ". I can help you create and manage accounts. What would you like to do?");
    }
})

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

Я также написал следующий тестовый модуль, который успешно заглушает Auth0, Firestore и т. Д., Но он не может получить возвращаемое значение,Вот тест

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

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

const config = require('config');

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

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

  before(() => {
    test.mockConfig({"familybank": {"auth0": {"domain": "mockdomain", "clientid": "mockid"}}});
    adminInitStub = sinon.stub(admin, 'initializeApp');

    oldFirestore = admin.firestore;
    firestoreStub = sinon.stub();
    Object.defineProperty(admin, 'firestore', { get: () => firestoreStub });
    collectionStub = sinon.stub();
    firestoreStub.returns({ collection: collectionStub });

    sinon.stub(UsersManager.prototype, 'getInfo').callsFake( function fakeGetProfile() {
      return Promise.resolve({"email": "someuser@domain.com", "name": "Joe Banks"});
    });
    myFunctions = require('../index');
  });

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

  describe('accessAccount', () => {
    it('should return a 200', (done) => {
      const bankOwnerParam = 'someuser@domain.com';
      const bankStub = sinon.stub();

      collectionStub.withArgs(config.get('firestore.bank_collection_key')).returns({ doc: bankStub });
      bankStub.withArgs(bankOwnerParam).returns({ get: () => Promise.resolve({ mykey: 'mydata', exists: true })});

      const req = {"responseId":"RESPONSEID","queryResult":{"queryText":"GOOGLE_ASSISTANT_WELCOME","action":"input.welcome","parameters":{},"allRequiredParamsPresent":true,"fulfillmentMessages":[{"text":{"text":[""]}}],"outputContexts":[{"name":"projects/familybank/agent/sessions/SESSIONID/contexts/google_assistant_welcome"},{"name":"projects/familybank/agent/sessions/SESSIONID/contexts/actions_capability_audio_output"},{"name":"projects/familybank/agent/sessions/SESSIONID/contexts/google_assistant_input_type_voice"},{"name":"projects/familybank/agent/sessions/SESSIONID/contexts/actions_capability_media_response_audio"}],"intent":{"name":"projects/familybank/agent/intents/65b6c584-be5d-456b-ad77-341abdb4dcb4","displayName":"Default Welcome Intent"},"intentDetectionConfidence":1.0,"languageCode":"en-us"},"originalDetectIntentRequest":{"source":"google","version":"2","payload":{"isInSandbox":true,"surface":{"capabilities":[{"name":"actions.capability.AUDIO_OUTPUT"},{"name":"actions.capability.MEDIA_RESPONSE_AUDIO"}]},"requestType":"SIMULATOR","inputs":[{"rawInputs":[{"query":"Talk to Family Bank","inputType":"VOICE"}],"intent":"actions.intent.MAIN"}],"user":{"lastSeen":"2018-11-15T14:41:36Z","accessToken":"TOKEN","locale":"en-US","userId":"USERID"},"conversation":{"conversationId":"SESSIONID","type":"NEW"},"availableSurfaces":[{"capabilities":[{"name":"actions.capability.AUDIO_OUTPUT"},{"name":"actions.capability.SCREEN_OUTPUT"},{"name":"actions.capability.WEB_BROWSER"}]}]}},"session":"projects/familybank/agent/sessions/SESSIONID"};
      const res = {
        response: (code) => {
          assert.equal(code, 200);
          done();
        }
      };

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

Когда я запускаю тест, я получаю следующую ошибку

root@fc19e6bca144:/appfiles/functions# npm test

> familybank@0.0.1 test /appfiles/functions
> mocha --reporter spec



  Cloud Functions
    accessAccount
      1) should return a 200


  0 passing (3s)
  1 failing

  1) Cloud Functions
       accessAccount
         should return a 200:
     Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (/appfiles/functions/test/index.test.js)




npm ERR! Test failed.  See above for more details.

Я не могу понять, почему это не возвращает значение.Я следовал за https://firebase.google.com/docs/functions/unit-testing#testing_http_functions, и переходил по ссылкам на некоторые связанные файлы.

1 Ответ

0 голосов
/ 27 ноября 2018

Благодаря подсказке в комментарии выше, я смог получить рабочее решение со следующим изменением

it('should return a 200', async () => {
  const bankOwnerParam = 'someuser@domain.com';
  const bankStub = sinon.stub();

  collectionStub.withArgs(config.get('firestore.bank_collection_key')).returns({ doc: bankStub });
  bankStub.withArgs(bankOwnerParam).returns({ get: () => Promise.resolve({ mykey: 'mydata', exists: true })});

  const req = {"responseId":"RESPONSEID","queryResult":{"queryText":"GOOGLE_ASSISTANT_WELCOME","action":"input.welcome","parameters":{},"allRequiredParamsPresent":true,"fulfillmentMessages":[{"text":{"text":[""]}}],"outputContexts":[{"name":"projects/familybank/agent/sessions/SESSIONID/contexts/google_assistant_welcome"},{"name":"projects/familybank/agent/sessions/SESSIONID/contexts/actions_capability_audio_output"},{"name":"projects/familybank/agent/sessions/SESSIONID/contexts/google_assistant_input_type_voice"},{"name":"projects/familybank/agent/sessions/SESSIONID/contexts/actions_capability_media_response_audio"}],"intent":{"name":"projects/familybank/agent/intents/65b6c584-be5d-456b-ad77-341abdb4dcb4","displayName":"Default Welcome Intent"},"intentDetectionConfidence":1.0,"languageCode":"en-us"},"originalDetectIntentRequest":{"source":"google","version":"2","payload":{"isInSandbox":true,"surface":{"capabilities":[{"name":"actions.capability.AUDIO_OUTPUT"},{"name":"actions.capability.MEDIA_RESPONSE_AUDIO"}]},"requestType":"SIMULATOR","inputs":[{"rawInputs":[{"query":"Talk to Family Bank","inputType":"VOICE"}],"intent":"actions.intent.MAIN"}],"user":{"lastSeen":"2018-11-15T14:41:36Z","accessToken":"TOKEN","locale":"en-US","userId":"USERID"},"conversation":{"conversationId":"SESSIONID","type":"NEW"},"availableSurfaces":[{"capabilities":[{"name":"actions.capability.AUDIO_OUTPUT"},{"name":"actions.capability.SCREEN_OUTPUT"},{"name":"actions.capability.WEB_BROWSER"}]}]}},"session":"projects/familybank/agent/sessions/SESSIONID"};
  const res = {
    response: (code) => {
      assert.equal(code, 200);
    }
  };

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