使用 CORS 测试 firebase HTTPS 调用

Posted

技术标签:

【中文标题】使用 CORS 测试 firebase HTTPS 调用【英文标题】:Testing firebase HTTPS call with CORS 【发布时间】:2017-10-28 19:07:20 【问题描述】:

我正在尝试为我的 firebase 云功能设置本地测试环境。但是,当我尝试对我的一个 HTTP 函数进行虚假调用时遇到了问题。

我的错误原因似乎是我使用了 CORS (npm)。当我删除 cors 并仅使用 response.status(200) 运行下面看到的函数“test”时,一切正常。但是当使用 cors(req,res) 包装时,我的测试失败并出现 TypeError: Cannot read property 'origin' of undefined。

我在这里做错了什么?

在 index.js 中 -->

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

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

在我的 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]


            )
        )



)

【问题讨论】:

【参考方案1】:

试试这个: 而不是使用const req = ; 使用:

const req = 
   headers:  origin: true ,
;

【讨论】:

【参考方案2】:

最后,带有 firebase 功能和 cors 的单元测试正在运行

你必须在响应中设置Header和GetHeader

 setHeader: (key, value) => ,
 getHeader: (value) => ,

测试

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

let myFunctions

beforeAll(() => 
  myFunctions = require('../src/index')
)

afterAll(() => 
  test.cleanup()
)

it('get', async () => 
  let request =  headers:  origins: true  

  const response = 
    setHeader: (key, value) => 
    ,
    getHeader: (value) => 
    ,
    status: (code) => 
      expect(code).toBe(200)
      return  send: (body) => 
        expect(body).toBe('ok')
      
      
    

  
  myFunctions.addLink(request, response)
)

索引

const functions = require('firebase-functions')
const cors = require('cors')(
  origin: true
)

exports.addLink = functions.https.onRequest((req, res) => 
  return cors(req, res, () => 
    res.status(200).send('ok')
  )
)

【讨论】:

origin: true,出错了【参考方案3】:

这是我使用 sinon 解决 cors 错误的方法

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());
);

然后,在您的测试中,您可以测试您的回答:

    cloudFunctions.testFunction( query:  text: 'foo'  , res);
    response = res.json.lastCall.args[0];

【讨论】:

【参考方案4】:

在您的请求中添加标头: origin: '*' ,并将 setHeader () 添加到响应中

const req = 
    origin: '*' 
;

const res = 
  status: (status) => 
      assert.equal(status, 200);
      done();
  
;

【讨论】:

origin: '*' 不起作用,因为 cors 在 firebase 云功能上需要 origin: true

以上是关于使用 CORS 测试 firebase HTTPS 调用的主要内容,如果未能解决你的问题,请参考以下文章