Skip to content

Commit

Permalink
Fis modularization (#3638)
Browse files Browse the repository at this point in the history
* copied orginal FIS sdk into packages-expp and made unit tests passed

* migrated test app and fixed a test app bug to make it worked

* made installations-exp depend on app-exp

* Relocated public methods files into  folder

* Making installations mudularization step1, build success

* Making installations mudularization step2, unit tests pass

* update dependency version, merge master

* Apply suggestions from code review

Co-authored-by: Feiyang <[email protected]>

* update dependencies' version

* add getInstallation(app)

* correct deleteInstallations funciton name

* Place the call to registerVerion and registerInstallations at the same place

* remove dead code

* add api extractor config

* rewrite the internal interface

* fix build error

* Seperate internal interface from public interface.

* Change public methods to accept public interface

* Fixes and api extractor integration for @firebase/installations-exp (#3733)

* integrate api-extractor into installations-exp

* add release tag to APIs

* add _ prefix to the internal interface

* update api report

Co-authored-by: Feiyang <[email protected]>
  • Loading branch information
ChaoqunCHEN and Feiyang1 authored Sep 3, 2020
1 parent 1a20aef commit f506e18
Show file tree
Hide file tree
Showing 63 changed files with 5,042 additions and 1 deletion.
34 changes: 34 additions & 0 deletions common/api-review/installations-exp.api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
## API Report File for "@firebase/installations-exp"

> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts

import { FirebaseApp } from '@firebase/app-types-exp';
import { FirebaseInstallations } from '@firebase/installations-types-exp';

// @public (undocumented)
export function deleteInstallations(installations: FirebaseInstallations): Promise<void>;

// @public (undocumented)
export function getId(installations: FirebaseInstallations): Promise<string>;

// @public (undocumented)
export function getInstallations(app: FirebaseApp): FirebaseInstallations;

// @public (undocumented)
export function getToken(installations: FirebaseInstallations, forceRefresh?: boolean): Promise<string>;

// @public (undocumented)
export type IdChangeCallbackFn = (installationId: string) => void;

// @public (undocumented)
export type IdChangeUnsubscribeFn = () => void;

// @public
export function onIdChange(installations: FirebaseInstallations, callback: IdChangeCallbackFn): IdChangeUnsubscribeFn;


// (No @packageDocumentation comment for this package)

```
20 changes: 20 additions & 0 deletions common/api-review/installations-types-exp.api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## API Report File for "@firebase/installations-types-exp"

> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts

// @public (undocumented)
export interface FirebaseInstallations {}

// @internal
export interface _FirebaseInstallationsInternal {
getId(): Promise<string>;

getToken(forceRefresh?: boolean): Promise<string>;
}


// (No @packageDocumentation comment for this package)

```
26 changes: 26 additions & 0 deletions packages-exp/installations-exp/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* @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.
*/

module.exports = {
extends: '../../config/.eslintrc.js',
parserOptions: {
project: 'tsconfig.json',
// to make vscode-eslint work with monorepo
// https://github.com/typescript-eslint/typescript-eslint/issues/251#issuecomment-463943250
tsconfigRootDir: __dirname
}
};
8 changes: 8 additions & 0 deletions packages-exp/installations-exp/api-extractor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../config/api-extractor.json",
// Point it to your entry point d.ts file.
"mainEntryPointFilePath": "<projectFolder>/dist/src/index.d.ts",
"dtsRollup": {
"enabled": true
}
}
35 changes: 35 additions & 0 deletions packages-exp/installations-exp/karma.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* @license
* Copyright 2019 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.
*/

const karmaBase = require('../../config/karma.base');

const files = [`src/**/*.test.ts`];

module.exports = function (config) {
const karmaConfig = {
...karmaBase,
// files to load into karma
files,
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha']
};

config.set(karmaConfig);
};

module.exports.files = files;
64 changes: 64 additions & 0 deletions packages-exp/installations-exp/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"name": "@firebase/installations-exp",
"version": "0.0.800",
"private": true,
"author": "Firebase <[email protected]> (https://firebase.google.com/)",
"main": "dist/index.cjs.js",
"module": "dist/index.esm.js",
"browser": "dist/index.esm.js",
"esm2017": "dist/index.esm2017.js",
"typings": "dist/installations-exp.d.ts",
"license": "Apache-2.0",
"files": [
"dist"
],
"scripts": {
"lint": "eslint -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'",
"lint:fix": "eslint --fix -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'",
"build": "rollup -c && yarn api-report",
"build:deps": "lerna run --scope @firebase/installations-exp --include-dependencies build",
"dev": "rollup -c -w",
"test": "yarn type-check && yarn test:karma && yarn lint",
"test:ci": "node ../../scripts/run_tests_in_ci.js",
"test:karma": "karma start --single-run",
"test:debug": "karma start --browsers=Chrome --auto-watch",
"type-check": "tsc -p . --noEmit",
"serve": "yarn serve:build && yarn serve:host",
"serve:build": "rollup -c test-app/rollup.config.js",
"serve:host": "http-server -c-1 test-app",
"prepare": "yarn build",
"api-report": "api-extractor run --local --verbose",
"predoc": "node ../../scripts/exp/remove-exp.js temp",
"doc": "api-documenter markdown --input temp --output docs",
"build:doc": "yarn build && yarn doc"
},
"repository": {
"directory": "packages-exp/installations-exp",
"type": "git",
"url": "https://github.com/firebase/firebase-js-sdk.git"
},
"bugs": {
"url": "https://github.com/firebase/firebase-js-sdk/issues"
},
"devDependencies": {
"@firebase/app-exp": "0.0.800",
"rollup": "2.26.7",
"rollup-plugin-commonjs": "10.1.0",
"rollup-plugin-json": "4.0.0",
"rollup-plugin-node-resolve": "5.2.0",
"rollup-plugin-typescript2": "0.27.2",
"rollup-plugin-uglify": "6.0.4",
"typescript": "4.0.2"
},
"peerDependencies": {
"@firebase/app-exp": "0.x",
"@firebase/app-types-exp": "0.x"
},
"dependencies": {
"@firebase/installations-types-exp": "0.0.800",
"@firebase/util": "0.3.1",
"@firebase/component": "0.1.18",
"idb": "3.0.2",
"tslib": "^1.11.1"
}
}
70 changes: 70 additions & 0 deletions packages-exp/installations-exp/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* @license
* Copyright 2019 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 json from 'rollup-plugin-json';
import typescriptPlugin from 'rollup-plugin-typescript2';
import pkg from './package.json';
import typescript from 'typescript';

const deps = Object.keys({ ...pkg.peerDependencies, ...pkg.dependencies });

/**
* ES5 Builds
*/
const es5BuildPlugins = [typescriptPlugin({ typescript }), json()];

const es5Builds = [
{
input: 'src/index.ts',
output: [
{ file: pkg.main, format: 'cjs', sourcemap: true },
{ file: pkg.module, format: 'es', sourcemap: true }
],
plugins: es5BuildPlugins,
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`))
}
];

/**
* ES2017 Builds
*/
const es2017BuildPlugins = [
typescriptPlugin({
typescript,
tsconfigOverride: {
compilerOptions: {
target: 'es2017'
}
}
}),
json({ preferConst: true })
];

const es2017Builds = [
{
input: 'src/index.ts',
output: {
file: pkg.esm2017,
format: 'es',
sourcemap: true
},
plugins: es2017BuildPlugins,
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`))
}
];

export default [...es5Builds, ...es2017Builds];
131 changes: 131 additions & 0 deletions packages-exp/installations-exp/src/api/delete-installations.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/**
* @license
* Copyright 2019 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 { SinonStub, stub } from 'sinon';
import * as deleteInstallationRequestModule from '../functions/delete-installation-request';
import { get, set } from '../helpers/idb-manager';
import {
InProgressInstallationEntry,
RegisteredInstallationEntry,
RequestStatus,
UnregisteredInstallationEntry
} from '../interfaces/installation-entry';
import { getFakeInstallations } from '../testing/fake-generators';
import '../testing/setup';
import { ErrorCode } from '../util/errors';
import { sleep } from '../util/sleep';
import { deleteInstallations } from './delete-installations';
import {
FirebaseInstallationsImpl,
AppConfig
} from '../interfaces/installation-impl';

const FID = 'children-of-the-damned';

describe('deleteInstallation', () => {
let installations: FirebaseInstallationsImpl;
let deleteInstallationRequestSpy: SinonStub<
[AppConfig, RegisteredInstallationEntry],
Promise<void>
>;

beforeEach(() => {
installations = getFakeInstallations();

deleteInstallationRequestSpy = stub(
deleteInstallationRequestModule,
'deleteInstallationRequest'
).callsFake(
() => sleep(100) // Request would take some time
);
});

it('resolves without calling server API if there is no installation', async () => {
await expect(deleteInstallations(installations)).to.be.fulfilled;
expect(deleteInstallationRequestSpy).not.to.have.been.called;
});

it('deletes and resolves without calling server API if the installation is unregistered', async () => {
const entry: UnregisteredInstallationEntry = {
registrationStatus: RequestStatus.NOT_STARTED,
fid: FID
};
await set(installations.appConfig, entry);

await expect(deleteInstallations(installations)).to.be.fulfilled;
expect(deleteInstallationRequestSpy).not.to.have.been.called;
await expect(get(installations.appConfig)).to.eventually.be.undefined;
});

it('rejects without calling server API if the installation is pending', async () => {
const entry: InProgressInstallationEntry = {
fid: FID,
registrationStatus: RequestStatus.IN_PROGRESS,
registrationTime: Date.now() - 3 * 1000
};
await set(installations.appConfig, entry);

await expect(deleteInstallations(installations)).to.be.rejectedWith(
ErrorCode.DELETE_PENDING_REGISTRATION
);
expect(deleteInstallationRequestSpy).not.to.have.been.called;
});

it('rejects without calling server API if the installation is registered and app is offline', async () => {
const entry: RegisteredInstallationEntry = {
fid: FID,
registrationStatus: RequestStatus.COMPLETED,
refreshToken: 'refreshToken',
authToken: {
token: 'authToken',
expiresIn: 123456,
requestStatus: RequestStatus.COMPLETED,
creationTime: Date.now()
}
};
await set(installations.appConfig, entry);
stub(navigator, 'onLine').value(false);

await expect(deleteInstallations(installations)).to.be.rejectedWith(
ErrorCode.APP_OFFLINE
);
expect(deleteInstallationRequestSpy).not.to.have.been.called;
});

it('deletes and resolves after calling server API if the installation is registered', async () => {
const entry: RegisteredInstallationEntry = {
fid: FID,
registrationStatus: RequestStatus.COMPLETED,
refreshToken: 'refreshToken',
authToken: {
token: 'authToken',
expiresIn: 123456,
requestStatus: RequestStatus.COMPLETED,
creationTime: Date.now()
}
};
await set(installations.appConfig, entry);

await expect(deleteInstallations(installations)).to.be.fulfilled;
expect(deleteInstallationRequestSpy).to.have.been.calledOnceWith(
installations.appConfig,
entry
);
await expect(get(installations.appConfig)).to.eventually.be.undefined;
});
});
Loading

0 comments on commit f506e18

Please sign in to comment.