Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update simple HTTP testing to explain emulator interactions #97

Open
samtstern opened this issue Feb 8, 2021 · 4 comments
Open

Update simple HTTP testing to explain emulator interactions #97

samtstern opened this issue Feb 8, 2021 · 4 comments

Comments

@samtstern
Copy link
Contributor

See:
firebase/firebase-tools#3098 (comment)

@markgoho
Copy link

@samtstern maybe you could help me out here -- I've accomplished setting up http testing:

const { expect } = require('chai');
const axios = require('axios');
const qs = require('qs');
const admin = require('firebase-admin');
const test = require('firebase-functions-test')({
  projectId: process.env.GCLOUD_PROJECT,
});

const axiosConfig = (functionName, data) => {
  return {
    method: 'post',
    url: `http://localhost:5001/${process.env.GCLOUD_PROJECT}/us-central1/${functionName}`,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    data,
  };
};

describe('Unit tests', () => {
  after(() => {
    test.cleanup();
  });

  it('tests a new deployment', async () => {
    const data = qs.stringify({
      payload:
        '{"status": "started", "branch": "feature-fix", "env": "hotfix-2", "app": "enroll", "user_name": "kvootla", "org": "maine", "repo": "enroll", "commit_sha": "abc1234" }',
    });

    const config = axiosConfig('branchDeployment', data);

    let responsePayload;
    try {
      // Make the http request
      responsePayload = await axios(config);
    } catch (e) {
      console.log('ERROR:', e);
    }

    // Wait for the promise to be resolved and then check the sent text
    expect(responsePayload.data).to.deep.eq({
      status: 'started',
      branch: 'feature-fix',
      env: 'hotfix-2',
      app: 'enroll',
      user_name: 'kvootla',
      org: 'maine',
      repo: 'enroll',
      commit_sha: 'abc1234',
    });
  }).timeout(5000);
});

This works when run with firebase emulators:exec --project=fakeproject \"npm run test\"

However, as soon as I also try to check that a value was set in Firestore, e.g. adding this just below the payload assertion:

const envSnap = await admin
      .firestore()
      .collection('orgs')
      .doc('maine')
      .collection('environments')
      .doc('hotfix-2')
      .get();

    expect(envSnap.data()).to.eql({
      status: 'started',
      branch: 'feature-fix',
      env: 'hotfix-2',
      app: 'enroll',
      user_name: 'kvootla',
      org: 'maine',
      repo: 'enroll',
      commit_sha: 'abc1234',
    });

I get the following error:

 Error: The default Firebase app does not exist. Make sure you call initializeApp() before using any of the Firebase services.
      at FirebaseAppError.FirebaseError [as constructor] (node_modules\firebase-admin\lib\utils\error.js:44:28)
      at FirebaseAppError.PrefixedFirebaseError [as constructor] (node_modules\firebase-admin\lib\utils\error.js:90:28)
      at new FirebaseAppError (node_modules\firebase-admin\lib\utils\error.js:125:28)
      at FirebaseNamespaceInternals.app (node_modules\firebase-admin\lib\firebase-namespace.js:101:19)
      at FirebaseNamespace.app (node_modules\firebase-admin\lib\firebase-namespace.js:430:30)
      at FirebaseNamespace.ensureApp (node_modules\firebase-admin\lib\firebase-namespace.js:444:24)
      at FirebaseNamespace.fn (node_modules\firebase-admin\lib\firebase-namespace.js:304:30)
      at Context.<anonymous> (test\functions.spec.js:54:8)
      at processTicksAndRejections (internal/process/task_queues.js:97:5)

@samtstern
Copy link
Contributor Author

@markgoho that error message is correct, you have not called admin.initializeApp() anywhere so you can't use admin.firestore() to perform actions.

Also make sure you have FIRESTORE_EMULATOR_HOST set correctly in your environment or the Admin SDK will attempt to talk to prod. If you're running your tests through firebase emulators:exec this is handled for you.

@markgoho
Copy link

thank you so much @samtstern that did solve this issue!

does your functions.spec.js file in this repo get the intializeApp() call from https://github.com/firebase/quickstart-testing/blob/master/unit-test-cloud-functions/functions/test/functions.spec.js#L15 where you require the index.js file?

it seems like I'll need two separate spec files:

  • one where I'm manually calling initializeApp because I'm not importing my functions index
  • one where I'm importing my functions index and letting it call initializeApp

@samtstern
Copy link
Contributor Author

@markgoho that's a great point and I hadn't thought about it! Yes we're somewhat accidentally inheriting the app initialization from the wrapped functions themselves since they're running inside the same process rather than being accessed over the network.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants