diff --git a/.idea/runConfigurations/System_Test.xml b/.idea/runConfigurations/System_Test.xml index 9dad0feea..6be057102 100644 --- a/.idea/runConfigurations/System_Test.xml +++ b/.idea/runConfigurations/System_Test.xml @@ -7,6 +7,9 @@ true + + + bdd --require ts-node/register/type-check --no-cache --timeout 60000 diff --git a/dev/system-test/firestore.ts b/dev/system-test/firestore.ts index 2ceca9626..eda7e3316 100644 --- a/dev/system-test/firestore.ts +++ b/dev/system-test/firestore.ts @@ -3447,7 +3447,7 @@ describe.skipEnterprise('Query class - Standard DB', () => { // TODO Enterprise - wait for implicit sort order decision // Skip this test if running against standard production because it results in a 'missing index' error. - it.skipClassic('supports OR queries with composite indexes', async () => { + it.skipStandard('supports OR queries with composite indexes', async () => { const collection = await testCollectionWithDocs({ doc1: {a: 1, b: 0}, doc2: {a: 2, b: 1}, @@ -3547,7 +3547,7 @@ describe.skipEnterprise('Query class - Standard DB', () => { // Skip this test if running against production standard DB because it results in a 'missing index' error. // The Firestore Emulator and Enterprise-editions, however, do serve these queries. - it.skipClassic( + it.skipStandard( 'supports OR queries on documents with missing fields', async () => { const collection = await testCollectionWithDocs({ @@ -3645,7 +3645,7 @@ describe.skipEnterprise('Query class - Standard DB', () => { }); // Skip this test if running against production because it results in a 'missing index' error. - it.skipClassic('supports OR queries with not-in', async () => { + it.skipStandard('supports OR queries with not-in', async () => { const collection = await testCollectionWithDocs({ doc1: {a: 1, b: 0}, doc2: {b: 1}, @@ -7503,7 +7503,7 @@ describe('Client initialization', () => { 'CollectionReference.listDocuments()', randomColl => { - if (process.env.RUN_ENTERPRISE_TESTS) return Promise.resolve(); + if (isEnterprise()) return Promise.resolve(); return randomColl.listDocuments(); }, ], @@ -7563,7 +7563,7 @@ describe('Client initialization', () => { 'CollectionGroup.getPartitions()', async randomColl => { // Requires PartitionQuery support - if (process.env.RUN_ENTERPRISE_TESTS) return; + if (isEnterprise()) return; const partitions = randomColl.firestore .collectionGroup('id') diff --git a/dev/system-test/pipeline.ts b/dev/system-test/pipeline.ts index d2a565d83..79553abcf 100644 --- a/dev/system-test/pipeline.ts +++ b/dev/system-test/pipeline.ts @@ -136,7 +136,7 @@ import * as chaiAsPromised from 'chai-as-promised'; import {afterEach, describe, it} from 'mocha'; import '../test/util/mocha_extensions'; -import {verifyInstance} from '../test/util/helpers'; +import {isPreferRest, verifyInstance} from '../test/util/helpers'; import {getTestDb, getTestRoot} from './firestore'; import {Firestore as InternalFirestore} from '../src'; @@ -146,7 +146,7 @@ use(chaiAsPromised); const timestampDeltaMS = 3000; -describe.skipClassic('Pipeline class', () => { +describe.skipStandard('Pipeline class', () => { let firestore: Firestore; let randomCol: CollectionReference; let beginDocCreation = 0; @@ -458,7 +458,7 @@ describe.skipClassic('Pipeline class', () => { }); describe('pipeline explain', () => { - it('mode: analyze, format: text', async () => { + it.skipRestConnection('mode: analyze, format: text', async () => { const ppl = firestore .pipeline() .collection(randomCol.path) @@ -498,7 +498,7 @@ describe.skipClassic('Pipeline class', () => { ); }); - it('mode: analyze, format: unspecified', async () => { + it.skipRestConnection('mode: analyze, format: unspecified', async () => { const ppl = firestore .pipeline() .collection(randomCol.path) @@ -1636,17 +1636,24 @@ describe.skipClassic('Pipeline class', () => { expect.fail('expected pipeline.execute() to throw'); } catch (e: unknown) { - expect(e instanceof Error).to.be.true; - const err = e as ServiceError; - expect(err['code']).to.equal(3); - expect(typeof err['message']).to.equal('string'); - expect(typeof err['details']).to.equal('string'); - expect(typeof err['stack']).to.equal('string'); - expect(err['metadata'] instanceof Object).to.be.true; - - expect(err['message']).to.equal( - `${err.code} INVALID_ARGUMENT: ${err.details}`, - ); + if (isPreferRest()) { + expect(e instanceof Error).to.be.true; + const err = e as ServiceError; + expect(err['code']).to.equal(400); + } else { + // grpc + expect(e instanceof Error).to.be.true; + const err = e as ServiceError; + expect(err['code']).to.equal(3); + expect(typeof err['message']).to.equal('string'); + expect(typeof err['details']).to.equal('string'); + expect(typeof err['stack']).to.equal('string'); + expect(err['metadata'] instanceof Object).to.be.true; + + expect(err['message']).to.equal( + `${err.code} INVALID_ARGUMENT: ${err.details}`, + ); + } } }); @@ -1667,32 +1674,39 @@ describe.skipClassic('Pipeline class', () => { expect.fail('expected pipeline.execute() to throw'); } catch (e: unknown) { - const err = e as {[k: string]: unknown}; - expect(err instanceof Error).to.be.true; - - expect(err['code']).to.equal(8); - expect(typeof err['message']).to.equal('string'); - expect(typeof err['details']).to.equal('string'); - expect(typeof err['stack']).to.equal('string'); - expect(err['metadata'] instanceof Object).to.be.true; - - expect(err['message']).to.equal( - `${err.code} RESOURCE_EXHAUSTED: ${err.details}`, - ); + if (isPreferRest()) { + const err = e as {[k: string]: unknown}; + expect(err instanceof Error).to.be.true; + expect(err['code']).to.equal(429); + } else { + // grpc + const err = e as {[k: string]: unknown}; + expect(err instanceof Error).to.be.true; + + expect(err['code']).to.equal(8); + expect(typeof err['message']).to.equal('string'); + expect(typeof err['details']).to.equal('string'); + expect(typeof err['stack']).to.equal('string'); + expect(err['metadata'] instanceof Object).to.be.true; + + expect(err['message']).to.equal( + `${err.code} RESOURCE_EXHAUSTED: ${err.details}`, + ); - expect('statusDetails' in err).to.be.true; - expect(Array.isArray(err['statusDetails'])).to.be.true; + expect('statusDetails' in err).to.be.true; + expect(Array.isArray(err['statusDetails'])).to.be.true; - const statusDetails = err['statusDetails'] as Array; + const statusDetails = err['statusDetails'] as Array; - const foundExplainStats = statusDetails.find(x => { - return ( - 'type_url' in x && - x['type_url'] === - 'type.googleapis.com/google.firestore.v1.ExplainStats' - ); - }); - expect(foundExplainStats).to.not.be.undefined; + const foundExplainStats = statusDetails.find(x => { + return ( + 'type_url' in x && + x['type_url'] === + 'type.googleapis.com/google.firestore.v1.ExplainStats' + ); + }); + expect(foundExplainStats).to.not.be.undefined; + } } }); }); @@ -4449,7 +4463,7 @@ describe.skipClassic('Pipeline class', () => { // This is the Query integration tests from the lite API (no cache support) // with some additional test cases added for more complete coverage. // eslint-disable-next-line no-restricted-properties -describe.skipClassic('Query to Pipeline', () => { +describe.skipStandard('Query to Pipeline', () => { async function execute(ppl: Pipeline): Promise { return ppl.execute(); } diff --git a/dev/system-test/query.ts b/dev/system-test/query.ts index 14acbe69b..52c19fbf3 100644 --- a/dev/system-test/query.ts +++ b/dev/system-test/query.ts @@ -39,7 +39,7 @@ import {verifyInstance} from '../test/util/helpers'; import {DeferredPromise, getTestRoot} from './firestore'; import {IndexTestHelper} from './index_test_helper'; -describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { +describe.skipStandard('Query and Pipeline Compare - Enterprise DB', () => { interface PaginatedResults { pages: number; docs: QueryDocumentSnapshot[]; @@ -544,8 +544,7 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { ).to.deep.equal(embeddingVector); }); - // TODO waiting on implicit sort order decision - it.skipEnterprise('supports !=', async () => { + it('supports !=', async () => { await addDocs( {zip: NaN}, {zip: 91102}, @@ -558,10 +557,11 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { ); let res = await compareQueryAndPipeline( - randomCol.where('zip', '!=', 98101), + randomCol.where('zip', '!=', 98101).orderBy('zip'), ); expectDocs( res, + {zip: null}, {zip: NaN}, {zip: 91102}, {zip: 98103}, @@ -570,9 +570,12 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { {zip: {zip: 98101}}, ); - res = await compareQueryAndPipeline(randomCol.where('zip', '!=', NaN)); + res = await compareQueryAndPipeline( + randomCol.where('zip', '!=', NaN).orderBy('zip'), + ); expectDocs( res, + {zip: null}, {zip: 91102}, {zip: 98101}, {zip: 98103}, @@ -581,7 +584,9 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { {zip: {zip: 98101}}, ); - res = await compareQueryAndPipeline(randomCol.where('zip', '!=', null)); + res = await compareQueryAndPipeline( + randomCol.where('zip', '!=', null).orderBy('zip'), + ); expectDocs( res, {zip: NaN}, @@ -594,11 +599,12 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { ); }); - // TODO waiting on implicit sort order decision - it.skipEnterprise('supports != with document ID', async () => { + it('supports != with document ID', async () => { const refs = await addDocs({count: 1}, {count: 2}, {count: 3}); const res = await compareQueryAndPipeline( - randomCol.where(FieldPath.documentId(), '!=', refs[0].id), + randomCol + .where(FieldPath.documentId(), '!=', refs[0].id) + .orderBy(FieldPath.documentId()), ); expectDocs(res, {count: 2}, {count: 3}); }); @@ -663,8 +669,7 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { expectDocs(res, {count: 3}); }); - // TODO waiting on implicit sort order decision - it.skipEnterprise('supports "in"', async () => { + it('supports "in"', async () => { await addDocs( {zip: 98101}, {zip: 91102}, @@ -674,7 +679,7 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { {zip: {zip: 98101}}, ); const res = await compareQueryAndPipeline( - randomCol.where('zip', 'in', [98101, 98103]), + randomCol.where('zip', 'in', [98101, 98103]).orderBy('zip'), ); expectDocs(res, {zip: 98101}, {zip: 98103}); }); @@ -1005,8 +1010,7 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { expect(received).to.equal(2); }); - // TODO (enterprise) waiting on implicit sor order decision - it.skipEnterprise('can query collection groups', async () => { + it('can query collection groups', async () => { // Use `randomCol` to get a random collection group name to use but ensure // it starts with 'b' for predictable ordering. const collectionGroup = 'b' + randomCol.id; @@ -1031,7 +1035,9 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { await batch.commit(); const querySnapshot = await compareQueryAndPipeline( - firestore.collectionGroup(collectionGroup), + firestore + .collectionGroup(collectionGroup) + .orderBy(FieldPath.documentId()), ); expect(querySnapshot.docs.map(d => d.id)).to.deep.equal([ 'cg-doc1', @@ -1042,95 +1048,89 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { ]); }); - // TODO (enterprise) wait for implicit sort order support - it.skipEnterprise( - 'can query collection groups with startAt / endAt by arbitrary documentId', - async () => { - // Use `randomCol` to get a random collection group name to use but - // ensure it starts with 'b' for predictable ordering. - const collectionGroup = 'b' + randomCol.id; - - const docPaths = [ - `a/a/${collectionGroup}/cg-doc1`, - `a/b/a/b/${collectionGroup}/cg-doc2`, - `a/b/${collectionGroup}/cg-doc3`, - `a/b/c/d/${collectionGroup}/cg-doc4`, - `a/c/${collectionGroup}/cg-doc5`, - `${collectionGroup}/cg-doc6`, - 'a/b/nope/nope', - ]; - const batch = firestore.batch(); - for (const docPath of docPaths) { - batch.set(firestore.doc(docPath), {x: 1}); - } - await batch.commit(); + it('can query collection groups with startAt / endAt by arbitrary documentId', async () => { + // Use `randomCol` to get a random collection group name to use but + // ensure it starts with 'b' for predictable ordering. + const collectionGroup = 'b' + randomCol.id; - let querySnapshot = await firestore - .collectionGroup(collectionGroup) - .orderBy(FieldPath.documentId()) - .startAt('a/b') - .endAt('a/b0') - .get(); - expect(querySnapshot.docs.map(d => d.id)).to.deep.equal([ - 'cg-doc2', - 'cg-doc3', - 'cg-doc4', - ]); + const docPaths = [ + `a/a/${collectionGroup}/cg-doc1`, + `a/b/a/b/${collectionGroup}/cg-doc2`, + `a/b/${collectionGroup}/cg-doc3`, + `a/b/c/d/${collectionGroup}/cg-doc4`, + `a/c/${collectionGroup}/cg-doc5`, + `${collectionGroup}/cg-doc6`, + 'a/b/nope/nope', + ]; + const batch = firestore.batch(); + for (const docPath of docPaths) { + batch.set(firestore.doc(docPath), {x: 1}); + } + await batch.commit(); - querySnapshot = await firestore - .collectionGroup(collectionGroup) - .orderBy(FieldPath.documentId()) - .startAfter('a/b') - .endBefore(`a/b/${collectionGroup}/cg-doc3`) - .get(); - expect(querySnapshot.docs.map(d => d.id)).to.deep.equal(['cg-doc2']); - }, - ); + let querySnapshot = await firestore + .collectionGroup(collectionGroup) + .orderBy(FieldPath.documentId()) + .startAt('a/b') + .endAt('a/b0') + .get(); + expect(querySnapshot.docs.map(d => d.id)).to.deep.equal([ + 'cg-doc2', + 'cg-doc3', + 'cg-doc4', + ]); - // TODO (enterprise) wait for implicit sort order support - it.skipEnterprise( - 'can query collection groups with where filters on arbitrary documentId', - async () => { - // Use `randomCol` to get a random collection group name to use but - // ensure it starts with 'b' for predictable ordering. - const collectionGroup = 'b' + randomCol.id; - - const docPaths = [ - `a/a/${collectionGroup}/cg-doc1`, - `a/b/a/b/${collectionGroup}/cg-doc2`, - `a/b/${collectionGroup}/cg-doc3`, - `a/b/c/d/${collectionGroup}/cg-doc4`, - `a/c/${collectionGroup}/cg-doc5`, - `${collectionGroup}/cg-doc6`, - 'a/b/nope/nope', - ]; - const batch = firestore.batch(); - for (const docPath of docPaths) { - batch.set(firestore.doc(docPath), {x: 1}); - } - await batch.commit(); + querySnapshot = await firestore + .collectionGroup(collectionGroup) + .orderBy(FieldPath.documentId()) + .startAfter('a/b') + .endBefore(`a/b/${collectionGroup}/cg-doc3`) + .get(); + expect(querySnapshot.docs.map(d => d.id)).to.deep.equal(['cg-doc2']); + }); - let querySnapshot = await compareQueryAndPipeline( - firestore - .collectionGroup(collectionGroup) - .where(FieldPath.documentId(), '>=', 'a/b') - .where(FieldPath.documentId(), '<=', 'a/b0'), - ); - expect(querySnapshot.docs.map(d => d.id)).to.deep.equal([ - 'cg-doc2', - 'cg-doc3', - 'cg-doc4', - ]); - - querySnapshot = await compareQueryAndPipeline( - firestore - .collectionGroup(collectionGroup) - .where(FieldPath.documentId(), '>', 'a/b') - .where(FieldPath.documentId(), '<', `a/b/${collectionGroup}/cg-doc3`), - ); - expect(querySnapshot.docs.map(d => d.id)).to.deep.equal(['cg-doc2']); - }, - ); + it('can query collection groups with where filters on arbitrary documentId', async () => { + // Use `randomCol` to get a random collection group name to use but + // ensure it starts with 'b' for predictable ordering. + const collectionGroup = 'b' + randomCol.id; + + const docPaths = [ + `a/a/${collectionGroup}/cg-doc1`, + `a/b/a/b/${collectionGroup}/cg-doc2`, + `a/b/${collectionGroup}/cg-doc3`, + `a/b/c/d/${collectionGroup}/cg-doc4`, + `a/c/${collectionGroup}/cg-doc5`, + `${collectionGroup}/cg-doc6`, + 'a/b/nope/nope', + ]; + const batch = firestore.batch(); + for (const docPath of docPaths) { + batch.set(firestore.doc(docPath), {x: 1}); + } + await batch.commit(); + + let querySnapshot = await compareQueryAndPipeline( + firestore + .collectionGroup(collectionGroup) + .where(FieldPath.documentId(), '>=', 'a/b') + .where(FieldPath.documentId(), '<=', 'a/b0') + .orderBy(FieldPath.documentId()), + ); + expect(querySnapshot.docs.map(d => d.id)).to.deep.equal([ + 'cg-doc2', + 'cg-doc3', + 'cg-doc4', + ]); + + querySnapshot = await compareQueryAndPipeline( + firestore + .collectionGroup(collectionGroup) + .where(FieldPath.documentId(), '>', 'a/b') + .where(FieldPath.documentId(), '<', `a/b/${collectionGroup}/cg-doc3`) + .orderBy(FieldPath.documentId()), + ); + expect(querySnapshot.docs.map(d => d.id)).to.deep.equal(['cg-doc2']); + }); it('can query large collections', async () => { // @grpc/grpc-js v0.4.1 failed to deliver the full set of query results for @@ -1145,8 +1145,7 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { expect(snapshot.size).to.equal(100); }); - // TODO (enterprise) wait for implicit sort order support - it.skipEnterprise('supports OR queries', async () => { + it('supports OR queries', async () => { const collection = await testCollectionWithDocs({ doc1: {a: 1, b: 0}, doc2: {a: 2, b: 1}, @@ -1158,9 +1157,11 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { // Two equalities: a==1 || b==1. expectDocs( await compareQueryAndPipeline( - collection.where( - Filter.or(Filter.where('a', '==', 1), Filter.where('b', '==', 1)), - ), + collection + .where( + Filter.or(Filter.where('a', '==', 1), Filter.where('b', '==', 1)), + ) + .orderBy(FieldPath.documentId()), ), 'doc1', 'doc2', @@ -1171,12 +1172,20 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { // (a==1 && b==0) || (a==3 && b==2) expectDocs( await compareQueryAndPipeline( - collection.where( - Filter.or( - Filter.and(Filter.where('a', '==', 1), Filter.where('b', '==', 0)), - Filter.and(Filter.where('a', '==', 3), Filter.where('b', '==', 2)), - ), - ), + collection + .where( + Filter.or( + Filter.and( + Filter.where('a', '==', 1), + Filter.where('b', '==', 0), + ), + Filter.and( + Filter.where('a', '==', 3), + Filter.where('b', '==', 2), + ), + ), + ) + .orderBy(FieldPath.documentId()), ), 'doc1', 'doc3', @@ -1185,12 +1194,14 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { // a==1 && (b==0 || b==3). expectDocs( await compareQueryAndPipeline( - collection.where( - Filter.and( - Filter.where('a', '==', 1), - Filter.or(Filter.where('b', '==', 0), Filter.where('b', '==', 3)), - ), - ), + collection + .where( + Filter.and( + Filter.where('a', '==', 1), + Filter.or(Filter.where('b', '==', 0), Filter.where('b', '==', 3)), + ), + ) + .orderBy(FieldPath.documentId()), ), 'doc1', 'doc4', @@ -1199,12 +1210,14 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { // (a==2 || b==2) && (a==3 || b==3) expectDocs( await compareQueryAndPipeline( - collection.where( - Filter.and( - Filter.or(Filter.where('a', '==', 2), Filter.where('b', '==', 2)), - Filter.or(Filter.where('a', '==', 3), Filter.where('b', '==', 3)), - ), - ), + collection + .where( + Filter.and( + Filter.or(Filter.where('a', '==', 2), Filter.where('b', '==', 2)), + Filter.or(Filter.where('a', '==', 3), Filter.where('b', '==', 3)), + ), + ) + .orderBy(FieldPath.documentId()), ), 'doc3', ); @@ -1216,6 +1229,7 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { .where( Filter.or(Filter.where('a', '==', 2), Filter.where('b', '==', 1)), ) + .orderBy(FieldPath.documentId()) .limit(1), ), 'doc2', @@ -1224,8 +1238,7 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { // Skip this test if running against production because it results in a 'missing index' error. // The Firestore Emulator, however, does serve these queries. - // TODO (enterprise) wait for implicit sort order support - it.skipEnterprise('supports OR queries with composite indexes', async () => { + it('supports OR queries with composite indexes', async () => { const collection = await testCollectionWithDocs({ doc1: {a: 1, b: 0}, doc2: {a: 2, b: 1}, @@ -1237,9 +1250,11 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { // with one inequality: a>2 || b==1. expectDocs( await compareQueryAndPipeline( - collection.where( - Filter.or(Filter.where('a', '>', 2), Filter.where('b', '==', 1)), - ), + collection + .where( + Filter.or(Filter.where('a', '>', 2), Filter.where('b', '==', 1)), + ) + .orderBy('a'), ), 'doc5', 'doc2', @@ -1253,6 +1268,7 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { .where( Filter.or(Filter.where('a', '==', 1), Filter.where('b', '>', 0)), ) + .orderBy(FieldPath.documentId()) .limit(2), ), 'doc1', @@ -1459,8 +1475,7 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { ); }); - // TODO (enterprise) wait for implicit sort order support - it.skipEnterprise('supports OR queries with array membership', async () => { + it('supports OR queries with array membership', async () => { const collection = await testCollectionWithDocs({ doc1: {a: 1, b: [0]}, doc2: {b: [1]}, @@ -1473,12 +1488,14 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { // Query: a==2 || b array-contains 7 expectDocs( await compareQueryAndPipeline( - collection.where( - Filter.or( - Filter.where('a', '==', 2), - Filter.where('b', 'array-contains', 7), - ), - ), + collection + .where( + Filter.or( + Filter.where('a', '==', 2), + Filter.where('b', 'array-contains', 7), + ), + ) + .orderBy(FieldPath.documentId()), ), 'doc3', 'doc4', @@ -1489,12 +1506,14 @@ describe.skipClassic('Query and Pipeline Compare - Enterprise DB', () => { // Has implicit "orderBy b" expectDocs( await compareQueryAndPipeline( - collection.where( - Filter.or( - Filter.where('a', '==', 2), - Filter.where('b', 'array-contains-any', [0, 3]), - ), - ), + collection + .where( + Filter.or( + Filter.where('a', '==', 2), + Filter.where('b', 'array-contains-any', [0, 3]), + ), + ) + .orderBy(FieldPath.documentId()), ), 'doc1', 'doc4', diff --git a/dev/test/util/helpers.ts b/dev/test/util/helpers.ts index b10c81c5d..02e30852b 100644 --- a/dev/test/util/helpers.ts +++ b/dev/test/util/helpers.ts @@ -468,9 +468,19 @@ export function isPreferRest(): boolean { ); } +export type FirestoreEdition = 'STANDARD' | 'ENTERPRISE'; + +export function getFirestoreEdition(): FirestoreEdition { + const edition = process.env.FIRESTORE_EDITION; + if (edition && edition.toUpperCase() === 'ENTERPRISE') { + return 'ENTERPRISE'; + } + return 'STANDARD'; +} + /** * Returns a value indicating whether the tests are running against an Enterprise edition DB */ export function isEnterprise(): boolean { - return !!process.env.RUN_ENTERPRISE_TESTS; + return getFirestoreEdition() === 'ENTERPRISE'; } diff --git a/dev/test/util/mocha_extensions.ts b/dev/test/util/mocha_extensions.ts index 4acd09f4d..be89277a5 100644 --- a/dev/test/util/mocha_extensions.ts +++ b/dev/test/util/mocha_extensions.ts @@ -27,25 +27,29 @@ declare module 'mocha' { interface TestFunction { skipEnterprise: tOrSkipT; skipEmulator: tOrSkipT; - skipClassic: tOrSkipT; + skipStandard: tOrSkipT; + skipRestConnection: tOrSkipT; } interface PendingTestFunction { skipEnterprise: tOrSkipT; skipEmulator: tOrSkipT; - skipClassic: tOrSkipT; + skipStandard: tOrSkipT; + skipRestConnection: tOrSkipT; } interface SuiteFunction { skipEnterprise: tOrSkipT; skipEmulator: tOrSkipT; - skipClassic: tOrSkipT; + skipStandard: tOrSkipT; + skipRestConnection: tOrSkipT; } interface PendingSuiteFunction { skipEnterprise: tOrSkipT; skipEmulator: tOrSkipT; - skipClassic: tOrSkipT; + skipStandard: tOrSkipT; + skipRestConnection: tOrSkipT; } } @@ -59,7 +63,7 @@ export function mixinSkipImplementations(obj: unknown): void { if (this === describe.skip) { return this; } - if (process.env.RUN_ENTERPRISE_TESTS) { + if (process.env.FIRESTORE_EDITION?.toUpperCase() === 'ENTERPRISE') { return this.skip; } return this; @@ -81,7 +85,7 @@ export function mixinSkipImplementations(obj: unknown): void { }, }); - Object.defineProperty(obj, 'skipClassic', { + Object.defineProperty(obj, 'skipStandard', { get(): unknown { if (this === it.skip) { return this; @@ -89,7 +93,25 @@ export function mixinSkipImplementations(obj: unknown): void { if (this === describe.skip) { return this; } - if (!process.env.RUN_ENTERPRISE_TESTS) { + if (process.env.FIRESTORE_EDITION?.toUpperCase() !== 'ENTERPRISE') { + return this.skip; + } + return this; + }, + }); + + Object.defineProperty(obj, 'skipRestConnection', { + get(): unknown { + if (this === it.skip) { + return this; + } + if (this === describe.skip) { + return this; + } + if ( + process.env.FIRESTORE_PREFER_REST === '1' || + process.env.FIRESTORE_PREFER_REST === 'true' + ) { return this.skip; } return this; diff --git a/package.json b/package.json index c473c47c0..fcb20b5be 100644 --- a/package.json +++ b/package.json @@ -36,14 +36,14 @@ "predocs": "npm run compile", "docs": "jsdoc -c .jsdoc.js", "system-test:rest": "FIRESTORE_PREFER_REST=true mocha build/system-test --timeout 1200000", - "system-test:named-db:rest": "FIRESTORE_NAMED_DATABASE=test-db FIRESTORE_PREFER_REST=true mocha build/system-test --timeout 1200000", + "system-test:enterprise:rest": "FIRESTORE_NAMED_DATABASE=enterprise FIRESTORE_EDITION=ENTERPRISE FIRESTORE_PREFER_REST=true mocha build/system-test --timeout 1200000", "system-test:grpc": "mocha build/system-test --timeout 1200000", - "system-test:named-db:grpc": "FIRESTORE_NAMED_DATABASE=test-db mocha build/system-test --timeout 1200000", + "system-test:enterprise:grpc": "FIRESTORE_NAMED_DATABASE=enterprise FIRESTORE_EDITION=ENTERPRISE mocha build/system-test --timeout 1200000", "system-test:emulator:rest": "FIRESTORE_EMULATOR_HOST=localhost:8080 FIRESTORE_PREFER_REST=true mocha build/system-test --timeout 1200000", "system-test:named-db:emulator:rest": "FIRESTORE_NAMED_DATABASE=test-db FIRESTORE_EMULATOR_HOST=localhost:8080 FIRESTORE_PREFER_REST=true mocha build/system-test --timeout 1200000", "system-test:emulator:grpc": "FIRESTORE_EMULATOR_HOST=localhost:8080 mocha build/system-test --timeout 1200000", "system-test:named-db:emulator:grpc": "FIRESTORE_NAMED_DATABASE=test-db FIRESTORE_EMULATOR_HOST=localhost:8080 mocha build/system-test --timeout 1200000", - "system-test": "npm run system-test:grpc && npm run system-test:rest && npm run system-test:named-db:grpc && npm run system-test:named-db:rest", + "system-test": "npm run system-test:grpc && npm run system-test:rest && npm run system-test:enterprise:grpc && npm run system-test:enterprise:rest", "system-test:emulator": "npm run system-test:emulator:grpc && npm run system-test:emulator:rest && npm run system-test:named-db:emulator:grpc && npm run system-test:named-db:emulator:rest", "presystem-test": "npm run compile", "samples-test": "npm link && cd samples/ && npm link ../ && npm test && cd ../",