Skip to content

Commit 5a9a144

Browse files
authored
Set up docgen for rules-unit-testing (#5419)
1 parent 703ef77 commit 5a9a144

File tree

8 files changed

+188
-31
lines changed

8 files changed

+188
-31
lines changed

.gitignore

+5-1
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,8 @@ temp
8989
packages/**/docs
9090

9191
# files generated by api-extractor that should not be tracked
92-
tsdoc-metadata.json
92+
tsdoc-metadata.json
93+
94+
# generated html docs
95+
docs-*/
96+
docs/
+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
## API Report File for "@firebase/rules-unit-testing"
2+
3+
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
4+
5+
```ts
6+
7+
import { default as firebase_2 } from 'firebase/compat/app';
8+
import { FirebaseSignInProvider } from '@firebase/util';
9+
10+
// @public
11+
export function assertFails(pr: Promise<any>): Promise<any>;
12+
13+
// @public
14+
export function assertSucceeds<T>(pr: Promise<T>): Promise<T>;
15+
16+
// @public
17+
export type EmulatorConfig = {
18+
rules?: string;
19+
} & (HostAndPort | {});
20+
21+
// @public
22+
export interface HostAndPort {
23+
host: string;
24+
port: number;
25+
}
26+
27+
// @public
28+
export function initializeTestEnvironment(config: TestEnvironmentConfig): Promise<RulesTestEnvironment>;
29+
30+
// @public
31+
export interface RulesTestContext {
32+
database(databaseURL?: string): firebase_2.database.Database;
33+
firestore(settings?: firebase_2.firestore.Settings): firebase_2.firestore.Firestore;
34+
storage(bucketUrl?: string): firebase_2.storage.Storage;
35+
}
36+
37+
// @public
38+
export interface RulesTestEnvironment {
39+
authenticatedContext(user_id: string, tokenOptions?: TokenOptions): RulesTestContext;
40+
cleanup(): Promise<void>;
41+
clearDatabase(): Promise<void>;
42+
clearFirestore(): Promise<void>;
43+
clearStorage(): Promise<void>;
44+
readonly emulators: {
45+
database?: HostAndPort;
46+
firestore?: HostAndPort;
47+
storage?: HostAndPort;
48+
};
49+
readonly projectId: string;
50+
unauthenticatedContext(): RulesTestContext;
51+
// (undocumented)
52+
withSecurityRulesDisabled(callback: (context: RulesTestContext) => Promise<void>): Promise<void>;
53+
}
54+
55+
// @public
56+
export interface TestEnvironmentConfig {
57+
database?: EmulatorConfig;
58+
firestore?: EmulatorConfig;
59+
hub?: HostAndPort;
60+
projectId?: string;
61+
storage?: EmulatorConfig;
62+
}
63+
64+
// @public
65+
export type TokenOptions = {
66+
iat?: number;
67+
exp?: number;
68+
auth_time?: number;
69+
provider_id?: 'anonymous';
70+
email?: string;
71+
email_verified?: boolean;
72+
phone_number?: string;
73+
name?: string;
74+
picture?: string;
75+
firebase?: {
76+
sign_in_provider: FirebaseSignInProvider;
77+
identities?: {
78+
[provider in FirebaseSignInProvider]?: string[];
79+
};
80+
};
81+
aud?: string;
82+
iss?: string;
83+
[claim: string]: unknown;
84+
uid?: never;
85+
sub?: never;
86+
user_id?: never;
87+
};
88+
89+
// @public
90+
export function withFunctionTriggersDisabled<TResult>(fn: () => TResult | Promise<TResult>): Promise<TResult>;
91+
92+
// @public
93+
export function withFunctionTriggersDisabled<TResult>(hub: {
94+
host: string;
95+
port: number;
96+
}, fn: () => TResult | Promise<TResult>): Promise<TResult>;
97+
98+
99+
// (No @packageDocumentation comment for this package)
100+
101+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"extends": "../../config/api-extractor.json",
3+
// Point it to your entry point d.ts file.
4+
"mainEntryPointFilePath": "<projectFolder>/dist/index.d.ts"
5+
}

packages/rules-unit-testing/package.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@
1111
"dist"
1212
],
1313
"scripts": {
14-
"build": "rollup -c",
14+
"build": "rollup -c && yarn api-report",
1515
"build:deps": "lerna run --scope @firebase/rules-unit-testing --include-dependencies build",
1616
"dev": "rollup -c -w",
1717
"test:nyc": "TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha 'test/{,!(browser)/**/}*.test.ts' --config ./mocharc.node.js",
1818
"test": "(cd functions && yarn) && firebase --project=demo-foo --debug emulators:exec 'yarn test:nyc'",
19-
"test:ci": "node ../../scripts/run_tests_in_ci.js -s test"
19+
"test:ci": "node ../../scripts/run_tests_in_ci.js -s test",
20+
"api-report": "api-extractor run --local --verbose",
21+
"doc": "api-documenter markdown --input temp --output docs",
22+
"build:doc": "yarn build && yarn doc"
2023
},
2124
"license": "Apache-2.0",
2225
"devDependencies": {

packages/rules-unit-testing/src/initialize.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import {
3838
* variables or through the Firebase Emulator hub if hosts and ports are unspecified. It is strongly
3939
* recommended to specify security rules for emulators used for testing. See minimal example below.
4040
*
41-
* @param config the configuration for emulators. most fields are optional if they can be discovered
41+
* @param config - the configuration for emulators. Most fields are optional if they can be discovered
4242
* @returns a promise that resolves with an environment ready for testing, or rejects on error.
4343
* @public
4444
* @example

packages/rules-unit-testing/src/public_types/index.ts

+22-22
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,13 @@ export interface TestEnvironmentConfig {
131131
export interface HostAndPort {
132132
/**
133133
* The host of the emulator. Can be omitted if discovered automatically through the hub or
134-
* specified via environment variables. See {@code TestEnvironmentConfig} for details.
134+
* specified via environment variables. See `TestEnvironmentConfig` for details.
135135
*/
136136
host: string;
137137

138138
/**
139139
* The port of the emulator. Can be omitted if discovered automatically through the hub or
140-
* specified via environment variables. See {@code TestEnvironmentConfig} for details.
140+
* specified via environment variables. See `TestEnvironmentConfig` for details.
141141
*/
142142
port: number;
143143
}
@@ -170,12 +170,12 @@ export interface RulesTestEnvironment {
170170
};
171171

172172
/**
173-
* Create a {@code RulesTestContext} which behaves like an authenticated Firebase Auth user.
173+
* Create a `RulesTestContext` which behaves like an authenticated Firebase Auth user.
174174
*
175175
* Requests created via the returned context will have a mock Firebase Auth token attached.
176176
*
177-
* @param user_id the User ID of the user. Specifies the value of "user_id" and "sub" on the token
178-
* @param tokenOptions custom claims or overrides for Firebase Auth token payloads
177+
* @param user_id - the User ID of the user. Specifies the value of "user_id" and "sub" on the token
178+
* @param tokenOptions - custom claims or overrides for Firebase Auth token payloads
179179
*
180180
* @example
181181
* ```javascript
@@ -189,7 +189,7 @@ export interface RulesTestEnvironment {
189189
): RulesTestContext;
190190

191191
/**
192-
* Create a {@code RulesTestContext} which behaves like client that is NOT logged in via Firebase
192+
* Create a `RulesTestContext` which behaves like client that is NOT logged in via Firebase
193193
* Auth.
194194
*
195195
* Requests created via the returned context will not have Firebase Auth tokens attached.
@@ -222,7 +222,7 @@ export interface RulesTestEnvironment {
222222
clearDatabase(): Promise<void>;
223223

224224
/**
225-
* Clear data in the Firestore that belongs to the {@code projectId} in the Firestore emulator.
225+
* Clear data in the Firestore that belongs to the `projectId` in the Firestore emulator.
226226
*/
227227
clearFirestore(): Promise<void>;
228228

@@ -236,7 +236,7 @@ export interface RulesTestEnvironment {
236236
* created in test environment and clean up the underlying resources, allowing a clean exit.
237237
*
238238
* This method does not change the state in emulators in any way. To reset data between tests,
239-
* see {@code clearDatabase()}, {@code clearFirestore()} and {@code clearStorage()}.
239+
* see `clearDatabase()`, `clearFirestore()` and `clearStorage()`.
240240
*/
241241
cleanup(): Promise<void>;
242242
}
@@ -247,38 +247,38 @@ export interface RulesTestEnvironment {
247247
*/
248248
export interface RulesTestContext {
249249
/**
250-
* Get a Firestore instance for this test context. The returned Firebase JS Client SDK instance
250+
* Get a {@link @firebase/firestore#Firestore} instance for this test context. The returned Firebase JS Client SDK instance
251251
* can be used with the client SDK APIs (v9 modular or v9 compat).
252252
*
253-
* See: https://firebase.google.com/docs/reference/js/v9/firestore_
254-
* @param settings a settings object to configure the {@code Firestore} instance
255-
* @returns a Firestore instance configured to connect to the emulator
253+
* See: {@link @firebase/firestore#Firestore}
254+
* @param settings - a settings object to configure the {@link @firebase/firestore#Firestore} instance
255+
* @returns a `Firestore` instance configured to connect to the emulator
256256
* @public
257257
*/
258258
firestore(
259259
settings?: firebase.firestore.Settings
260260
): firebase.firestore.Firestore;
261261

262262
/**
263-
* Get a Firestore instance for this test context. The returned Firebase JS Client SDK instance
263+
* Get a {@link @firebase/database#Database} instance for this test context. The returned Firebase JS Client SDK instance
264264
* can be used with the client SDK APIs (v9 modular or v9 compat).
265265
*
266-
* See: https://firebase.google.com/docs/reference/js/v9/firestore_
267-
* @param databaseURL the URL of the Realtime Database instance. If specified, returns an instance
266+
* See: {@link @firebase/database#Database}
267+
* @param databaseURL - the URL of the Realtime Database instance. If specified, returns an instance
268268
* for an emulated version of the namespace with parameters extracted from URL
269-
* @returns a Database instance configured to connect to the emulator. It never connects to
270-
* production even if a production databaseURL is specified
269+
* @returns a `Database` instance configured to connect to the emulator. It never connects to
270+
* production even if a production `databaseURL` is specified
271271
*/
272272
database(databaseURL?: string): firebase.database.Database;
273273

274274
/**
275-
* Get a Storage instance for this test context. The returned Firebase JS Client SDK instance
275+
* Get a {@link @firebase/storage#FirebaseStorage} instance for this test context. The returned Firebase JS Client SDK instance
276276
* can be used with the client SDK APIs (v9 modular or v9 compat).
277277
*
278-
* See: https://firebase.google.com/docs/reference/js/v9/firestore_
279-
* @param settings the gs:// url to the Firebase Storage Bucket for testing. If specified,
280-
* returns a Storage instance for an emulated version of the bucket name
281-
* @returns a Storage instance configured to connect to the emulator
278+
* See: {@link @firebase/storage#FirebaseStorage}
279+
* @param settings - the gs:// url to the Firebase Storage Bucket for testing. If specified,
280+
* returns a `Storage` instance for an emulated version of the bucket name
281+
* @returns a `Storage` instance configured to connect to the emulator
282282
*/
283283
storage(bucketUrl?: string): firebase.storage.Storage;
284284
}

packages/rules-unit-testing/src/util.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import fetch from 'node-fetch';
3131
* This method only works with Firebase CLI version 8.13.0 or higher. This overload works only if
3232
* the Emulator hub host:port is specified by the environment variable FIREBASE_EMULATOR_HUB.
3333
*
34-
* @param fn an function which may be sync or async (returns a promise)
34+
* @param fn - a function which may be sync or async (returns a promise)
3535
* @public
3636
*/
3737
export async function withFunctionTriggersDisabled<TResult>(
@@ -46,8 +46,8 @@ export async function withFunctionTriggersDisabled<TResult>(
4646
* This method only works with Firebase CLI version 8.13.0 or higher. The Emulator hub must be
4747
* running, which host and port are specified in this overload.
4848
*
49-
* @param fn an function which may be sync or async (returns a promise)
50-
* @param hub the host and port of the Emulator Hub (ex: `{host: 'localhost', port: 4400}`)
49+
* @param fn - a function which may be sync or async (returns a promise)
50+
* @param hub - the host and port of the Emulator Hub (ex: `{host: 'localhost', port: 4400}`)
5151
* @public
5252
*/
5353
export async function withFunctionTriggersDisabled<TResult>(
@@ -121,7 +121,7 @@ export async function withFunctionTriggersDisabled<TResult>(
121121
* Useful to assert a certain request to be denied by Security Rules. See example below.
122122
* This function recognizes permission-denied errors from Database, Firestore, and Storage JS SDKs.
123123
*
124-
* @param pr the promise to be asserted
124+
* @param pr - the promise to be asserted
125125
* @returns a Promise that is fulfilled if pr is rejected with "permission denied". If pr is
126126
* rejected with any other error or resolved, the returned promise rejects.
127127
* @public

scripts/docgen/docgen.ts

+45-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import fs from 'fs';
2222
import glob from 'glob';
2323
import * as yargs from 'yargs';
2424

25+
const tmpDir = `${projectRoot}/temp`;
26+
2527
yargs
2628
.command('$0', 'generate standard reference docs', {}, _argv =>
2729
generateDocs(/* forDevsite */ false)
@@ -32,7 +34,6 @@ yargs
3234
.demandCommand()
3335
.help().argv;
3436

35-
const tmpDir = `${projectRoot}/temp`;
3637
// create *.api.json files
3738
async function generateDocs(forDevsite: boolean = false) {
3839
const outputFolder = forDevsite ? 'docs-devsite' : 'docs';
@@ -99,4 +100,47 @@ async function generateDocs(forDevsite: boolean = false) {
99100
[command, 'markdown', '--input', 'temp', '--output', outputFolder],
100101
{ stdio: 'inherit' }
101102
);
103+
104+
moveRulesUnitTestingDocs(outputFolder, command);
105+
}
106+
107+
// Create a docs-rut folder and move rules-unit-testing docs into it.
108+
async function moveRulesUnitTestingDocs(
109+
mainDocsFolder: string,
110+
command: string
111+
) {
112+
const rulesOutputFolder = `${projectRoot}/docs-rut`;
113+
114+
if (!fs.existsSync(rulesOutputFolder)) {
115+
fs.mkdirSync(rulesOutputFolder);
116+
}
117+
118+
const rulesDocPaths = await new Promise<string[]>(resolve =>
119+
glob(`${mainDocsFolder}/rules-unit-testing.*`, (err, paths) => {
120+
if (err) throw err;
121+
resolve(paths);
122+
})
123+
);
124+
// Move rules-unit-testing docs into the new folder.
125+
// These paths also need to be adjusted to point to a sibling directory.
126+
for (const sourcePath of rulesDocPaths) {
127+
let destinationPath = sourcePath.replace(mainDocsFolder, rulesOutputFolder);
128+
129+
const originalText = fs.readFileSync(sourcePath, 'utf-8');
130+
const jsReferencePath = '/docs/reference/js';
131+
let alteredPathText = originalText.replace(
132+
/\.\/database/g,
133+
`${jsReferencePath}/database`
134+
);
135+
alteredPathText = alteredPathText.replace(
136+
/\.\/storage/g,
137+
`${jsReferencePath}/storage`
138+
);
139+
alteredPathText = alteredPathText.replace(
140+
/\.\/firestore/g,
141+
`${jsReferencePath}/firestore`
142+
);
143+
fs.writeFileSync(destinationPath, alteredPathText);
144+
fs.unlinkSync(sourcePath);
145+
}
102146
}

0 commit comments

Comments
 (0)