Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing firebase HTTPS call with CORS

I am trying to setup a local testing environment for my firebase cloud functions. However I run into problems when trying to do a fake call to one of my HTTP functions.

The reason for my error seems to be that I am using CORS (npm). When I remove cors and run the function "test" seen below with just a response.status(200) everything works. But when wrapping with cors(req,res) my test fails with TypeError: Cannot read property 'origin' of undefined.

What am I doing wrong here?

In index.js -->

exports.test = functions.https.onRequest((request, response) => {

cors(request, response, () => {
    response.status(200);
    response.send("test ok");
})

In my test.js

describe('Cloud Functions', () => {
    // [START stubConfig]
    var myFunctions, configStub, adminInitStub, functions, admin, cors;

    before(() => {
        // Since index.js makes calls to functions.config and admin.initializeApp at the top of the file,
        // we need to stub both of these functions before requiring index.js. This is because the
        // functions will be executed as a part of the require process.
        // Here we stub admin.initializeApp to be a dummy function that doesn't do anything.
        admin = require('firebase-admin');
        cors = require('cors')({
            origin: true
        });
        adminInitStub = sinon.stub(admin, 'initializeApp');
        // Next we stub functions.config(). Normally config values are loaded from Cloud Runtime Config;
        // here we'll just provide some fake values for firebase.databaseURL and firebase.storageBucket
        // so that an error is not thrown during admin.initializeApp's parameter check
        functions = require('firebase-functions');
        configStub = sinon.stub(functions, 'config').returns({
            firebase: {
                databaseURL: 'https://not-a-project.firebaseio.com',
                storageBucket: 'not-a-project.appspot.com',
            }
            // You can stub any other config values needed by your functions here, for example:
            // foo: 'bar'
        });
        // Now we can require index.js and save the exports inside a namespace called myFunctions.
        // This includes our cloud functions, which can now be accessed at myFunctions.makeUppercase
        // and myFunctions.addMessage
        myFunctions = require('../index');
    });

    after(() => {
        // Restoring our stubs to the original methods.
        configStub.restore();
        adminInitStub.restore();
    });
    // [END stubConfig]


        describe('test', () => {
            it('should return status code 200', (done) => {

                // [START invokeHTTPS]
                // A fake request object, with req.query.text set to 'input'
                const req = {};
                // A fake response object, with a stubbed redirect function which asserts that it is called
                // with parameters 303, 'new_ref'.
                const res = {
                    status: (status) => {
                        assert.equal(status, 200);
                        done();
                    }
                };

                // Invoke addMessage with our fake request and response objects. This will cause the
                // assertions in the response object to be evaluated.
                myFunctions.test(req, res);
                // [END invokeHTTPS]


            })
        })



})
like image 608
A.kurt Avatar asked Oct 18 '22 11:10

A.kurt


2 Answers

Try this: Instead of using const req = {}; use:

const req = {
   headers: { origin: true },
};
like image 158
Santiago Mejia Avatar answered Nov 04 '22 20:11

Santiago Mejia


Here's how I got around the cors errors, with sinon

const res = {};

Object.assign(res, {
  status: sinon.stub().returns(res),
  end: sinon.stub().returns(res),
  json: sinon.stub().returns(res),
  setHeader: sinon.stub(),
  getHeader: sinon.stub(),
});

beforeEach(() => {
  Object.values(res).forEach(stub => stub.resetHistory());
});

Then, in your test, you can test your responses:

    cloudFunctions.testFunction({ query: { text: 'foo' } }, res);
    response = res.json.lastCall.args[0];
like image 27
Mihai Alexandru Bîrsan Avatar answered Nov 04 '22 20:11

Mihai Alexandru Bîrsan