mirror of
https://github.com/hanzoai/firebase-js-sdk.git
synced 2026-09-24 16:59:10 +00:00
193 lines
5.9 KiB
TypeScript
193 lines
5.9 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2020 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
import { expect } from 'chai';
|
|
|
|
import { AppCheckToken, OAuthToken, Token } from '../../../src/api/credentials';
|
|
import { User } from '../../../src/auth/user';
|
|
import { DatabaseId, DatabaseInfo } from '../../../src/core/database_info';
|
|
import { SDK_VERSION } from '../../../src/core/version';
|
|
import { ResourcePath } from '../../../src/model/path';
|
|
import { Stream } from '../../../src/remote/connection';
|
|
import { RestConnection } from '../../../src/remote/rest_connection';
|
|
import { Code, FirestoreError } from '../../../src/util/error';
|
|
import { Indexable } from '../../../src/util/misc';
|
|
import { StringMap } from '../../../src/util/types';
|
|
|
|
export class TestRestConnection extends RestConnection {
|
|
lastUrl: string = '';
|
|
lastHeaders: StringMap = {};
|
|
lastRequestBody: unknown = {};
|
|
nextResponse = Promise.resolve<unknown>({});
|
|
|
|
openStream<Req, Resp>(
|
|
rpcName: string,
|
|
authToken: Token | null,
|
|
appCheckToken: Token | null
|
|
): Stream<Req, Resp> {
|
|
throw new Error('Not Implemented');
|
|
}
|
|
|
|
protected performRPCRequest<Req, Resp>(
|
|
rpcName: string,
|
|
url: string,
|
|
headers: StringMap,
|
|
body: Req
|
|
): Promise<Resp> {
|
|
this.lastUrl = url;
|
|
this.lastRequestBody = body as unknown as Indexable;
|
|
this.lastHeaders = headers;
|
|
const response = this.nextResponse;
|
|
this.nextResponse = Promise.resolve<unknown>({});
|
|
return response as Promise<Resp>;
|
|
}
|
|
}
|
|
|
|
describe('RestConnection', () => {
|
|
const testDatabaseInfo = new DatabaseInfo(
|
|
new DatabaseId('testproject'),
|
|
'test-app-id',
|
|
'persistenceKey',
|
|
'example.com',
|
|
/*ssl=*/ false,
|
|
/*forceLongPolling=*/ false,
|
|
/*autoDetectLongPolling=*/ false,
|
|
/*longPollingOptions=*/ {},
|
|
/*useFetchStreams=*/ false,
|
|
/*isUsingEmulator=*/ false,
|
|
'rest-connection-test-api-key'
|
|
);
|
|
const connection = new TestRestConnection(testDatabaseInfo);
|
|
|
|
it('url uses from path', async () => {
|
|
await connection.invokeRPC(
|
|
'Commit',
|
|
new ResourcePath(
|
|
'projects/testproject/databases/(default)/documents'.split('/')
|
|
),
|
|
{},
|
|
null,
|
|
null
|
|
);
|
|
expect(connection.lastUrl).to.equal(
|
|
'http://example.com/v1/projects/testproject/databases/(default)/documents:commit?key=rest-connection-test-api-key'
|
|
);
|
|
});
|
|
|
|
it('merges headers', async () => {
|
|
await connection.invokeRPC(
|
|
'RunQuery',
|
|
new ResourcePath(
|
|
'projects/testproject/databases/(default)/documents/foo'.split('/')
|
|
),
|
|
{},
|
|
new OAuthToken('owner', User.UNAUTHENTICATED),
|
|
new AppCheckToken('some-app-check-token')
|
|
);
|
|
expect(connection.lastHeaders).to.deep.equal({
|
|
'Authorization': 'Bearer owner',
|
|
'Content-Type': 'text/plain',
|
|
'X-Firebase-GMPID': 'test-app-id',
|
|
'X-Goog-Api-Client': `gl-js/ fire/${SDK_VERSION}`,
|
|
'x-firebase-appcheck': 'some-app-check-token',
|
|
'x-goog-request-params': 'project_id=testproject',
|
|
'google-cloud-resource-prefix': 'projects/testproject/databases/(default)'
|
|
});
|
|
});
|
|
|
|
it('empty app check token is not added to headers', async () => {
|
|
await connection.invokeRPC(
|
|
'RunQuery',
|
|
new ResourcePath(
|
|
'projects/testproject/databases/(default)/documents/foo'.split('/')
|
|
),
|
|
{},
|
|
null,
|
|
new AppCheckToken('')
|
|
);
|
|
expect(connection.lastHeaders).to.deep.equal({
|
|
'Content-Type': 'text/plain',
|
|
'X-Firebase-GMPID': 'test-app-id',
|
|
'X-Goog-Api-Client': `gl-js/ fire/${SDK_VERSION}`,
|
|
'x-goog-request-params': 'project_id=testproject',
|
|
'google-cloud-resource-prefix': 'projects/testproject/databases/(default)'
|
|
// Note: AppCheck token should not exist here.
|
|
});
|
|
});
|
|
|
|
it('adds custom headers when _customHeaders is set', async () => {
|
|
const dbInfo = new DatabaseInfo(
|
|
new DatabaseId('testproject'),
|
|
'test-app-id',
|
|
'persistenceKey',
|
|
'example.com',
|
|
/*ssl=*/ false,
|
|
/*forceLongPolling=*/ false,
|
|
/*autoDetectLongPolling=*/ false,
|
|
/*longPollingOptions=*/ {},
|
|
/*useFetchStreams=*/ false,
|
|
/*isUsingEmulator=*/ false,
|
|
'rest-connection-test-api-key',
|
|
{ 'x-goog-firestore-api-requester': 'console', 'x-custom-header': 'val' }
|
|
);
|
|
const conn = new TestRestConnection(dbInfo);
|
|
await conn.invokeRPC(
|
|
'RunQuery',
|
|
new ResourcePath(
|
|
'projects/testproject/databases/(default)/documents/foo'.split('/')
|
|
),
|
|
{},
|
|
null,
|
|
null
|
|
);
|
|
expect(conn.lastHeaders['x-goog-firestore-api-requester']).to.equal(
|
|
'console'
|
|
);
|
|
expect(conn.lastHeaders['x-custom-header']).to.equal('val');
|
|
});
|
|
|
|
it('returns success', async () => {
|
|
connection.nextResponse = Promise.resolve({ response: true });
|
|
const response = await connection.invokeRPC(
|
|
'RunQuery',
|
|
new ResourcePath(
|
|
'projects/testproject/databases/(default)/documents/coll'.split('/')
|
|
),
|
|
{},
|
|
null,
|
|
null
|
|
);
|
|
expect(response).to.deep.equal({ response: true });
|
|
});
|
|
|
|
it('returns error', () => {
|
|
const error = new FirestoreError(Code.UNKNOWN, 'Test exception');
|
|
connection.nextResponse = Promise.reject(error);
|
|
return expect(
|
|
connection.invokeRPC(
|
|
'RunQuery',
|
|
new ResourcePath(
|
|
'projects/testproject/databases/(default)/documents/coll'.split('/')
|
|
),
|
|
{},
|
|
null,
|
|
null
|
|
)
|
|
).to.be.eventually.rejectedWith(error);
|
|
});
|
|
});
|