Skip to content

Commit 01de80b

Browse files
authored
Specific interface for provider enhancement (1/3) (#1021)
* adding in app distro changes * removing comments & addings package refs * jsdoc comments * fix comments * adding periods to doc strings * fix wording
1 parent 8f92e1f commit 01de80b

File tree

5 files changed

+266
-1
lines changed

5 files changed

+266
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
- Parallelizes network calls that occur when validating authorization for onCall handlers.
22
- Adds new regions to V2 API
3+
- Adds new provider for alerts

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@
5555
"./v2/params": "./lib/v2/params/index.js",
5656
"./v2/pubsub": "./lib/v2/providers/pubsub.js",
5757
"./v2/storage": "./lib/v2/providers/storage.js",
58-
"./v2/alerts": "./lib/v2/providers/alerts/index.js"
58+
"./v2/alerts": "./lib/v2/providers/alerts/index.js",
59+
"./v2/alerts/appDistribution": "./lib/v2/providers/alerts/appDistribution.js"
5960
},
6061
"typesVersions": {
6162
"*": {
@@ -118,6 +119,9 @@
118119
],
119120
"v2/alerts": [
120121
"lib/v2/providers/alerts"
122+
],
123+
"v2/alerts/appDistribution": [
124+
"lib/v2/providers/alerts/appDistribution"
121125
]
122126
}
123127
},
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { expect } from 'chai';
2+
import * as alerts from '../../../../src/v2/providers/alerts';
3+
import * as appDistribution from '../../../../src/v2/providers/alerts/appDistribution';
4+
import { FULL_ENDPOINT, FULL_OPTIONS } from '../helpers';
5+
6+
const APPID = '123456789';
7+
const myHandler = () => 42;
8+
9+
describe('appDistribution', () => {
10+
describe('onNewTesterIosDevicePublished', () => {
11+
it('should create a function with alertType & appId', () => {
12+
const func = appDistribution.onNewTesterIosDevicePublished(
13+
APPID,
14+
myHandler
15+
);
16+
17+
expect(func.__endpoint).to.deep.equal({
18+
platform: 'gcfv2',
19+
labels: {},
20+
eventTrigger: {
21+
eventType: alerts.eventType,
22+
eventFilters: {
23+
alertType: appDistribution.newTesterIosDeviceAlert,
24+
appId: APPID,
25+
},
26+
retry: false,
27+
},
28+
});
29+
});
30+
31+
it('should create a function with opts', () => {
32+
const func = appDistribution.onNewTesterIosDevicePublished(
33+
{ ...FULL_OPTIONS },
34+
myHandler
35+
);
36+
37+
expect(func.__endpoint).to.deep.equal({
38+
...FULL_ENDPOINT,
39+
eventTrigger: {
40+
eventType: alerts.eventType,
41+
eventFilters: {
42+
alertType: appDistribution.newTesterIosDeviceAlert,
43+
},
44+
retry: false,
45+
},
46+
});
47+
});
48+
49+
it('should create a function with appid in opts', () => {
50+
const func = appDistribution.onNewTesterIosDevicePublished(
51+
{ ...FULL_OPTIONS, appId: APPID },
52+
myHandler
53+
);
54+
55+
expect(func.__endpoint).to.deep.equal({
56+
...FULL_ENDPOINT,
57+
eventTrigger: {
58+
eventType: alerts.eventType,
59+
eventFilters: {
60+
alertType: appDistribution.newTesterIosDeviceAlert,
61+
appId: APPID,
62+
},
63+
retry: false,
64+
},
65+
});
66+
});
67+
68+
it('should create a function without opts or appId', () => {
69+
const func = appDistribution.onNewTesterIosDevicePublished(myHandler);
70+
71+
expect(func.__endpoint).to.deep.equal({
72+
platform: 'gcfv2',
73+
labels: {},
74+
eventTrigger: {
75+
eventType: alerts.eventType,
76+
eventFilters: {
77+
alertType: appDistribution.newTesterIosDeviceAlert,
78+
},
79+
retry: false,
80+
},
81+
});
82+
});
83+
84+
it('should create a function with a run method', () => {
85+
const func = appDistribution.onNewTesterIosDevicePublished(
86+
APPID,
87+
(event) => event
88+
);
89+
90+
const res = func.run('input' as any);
91+
92+
expect(res).to.equal('input');
93+
});
94+
});
95+
96+
describe('getOptsAndApp', () => {
97+
it('should parse a string', () => {
98+
const [opts, appId] = appDistribution.getOptsAndApp(APPID);
99+
100+
expect(opts).to.deep.equal({});
101+
expect(appId).to.equal(APPID);
102+
});
103+
104+
it('should parse an options object without appId', () => {
105+
const myOpts: appDistribution.AppDistributionOptions = {
106+
region: 'us-west1',
107+
};
108+
109+
const [opts, appId] = appDistribution.getOptsAndApp(myOpts);
110+
111+
expect(opts).to.deep.equal({ region: 'us-west1' });
112+
expect(appId).to.be.undefined;
113+
});
114+
115+
it('should parse an options object with appId', () => {
116+
const myOpts: appDistribution.AppDistributionOptions = {
117+
appId: APPID,
118+
region: 'us-west1',
119+
};
120+
121+
const [opts, appId] = appDistribution.getOptsAndApp(myOpts);
122+
123+
expect(opts).to.deep.equal({ region: 'us-west1' });
124+
expect(appId).to.equal(APPID);
125+
});
126+
});
127+
});
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { getEndpointAnnotation, FirebaseAlertData } from './alerts';
2+
import { CloudEvent, CloudFunction } from '../../core';
3+
import * as options from '../../options';
4+
5+
/**
6+
* The internal payload object for adding a new tester device to app distribution.
7+
* Payload is wrapped inside a FirebaseAlertData object.
8+
*/
9+
export interface NewTesterDevicePayload {
10+
['@type']: 'com.google.firebase.firebasealerts.NewTesterDevicePayload';
11+
testerName: string;
12+
testerEmail: string;
13+
testerDeviceModelName: string;
14+
testerDeviceIdentifier: string;
15+
}
16+
17+
interface WithAlertTypeAndApp {
18+
alertType: string;
19+
appId: string;
20+
}
21+
/**
22+
* A custom CloudEvent for Firebase Alerts (with custom extension attributes).
23+
*/
24+
export type AppDistributionEvent<T> = CloudEvent<
25+
FirebaseAlertData<T>,
26+
WithAlertTypeAndApp
27+
>;
28+
29+
/** @internal */
30+
export const newTesterIosDeviceAlert = 'appDistribution.newTesterIosDevice';
31+
32+
/**
33+
* Configuration for app distribution functions.
34+
*/
35+
export interface AppDistributionOptions extends options.EventHandlerOptions {
36+
appId?: string;
37+
}
38+
39+
/**
40+
* Declares a function that can handle adding a new tester iOS device.
41+
*/
42+
export function onNewTesterIosDevicePublished(
43+
handler: (
44+
event: AppDistributionEvent<NewTesterDevicePayload>
45+
) => any | Promise<any>
46+
): CloudFunction<FirebaseAlertData<NewTesterDevicePayload>>;
47+
export function onNewTesterIosDevicePublished(
48+
appId: string,
49+
handler: (
50+
event: AppDistributionEvent<NewTesterDevicePayload>
51+
) => any | Promise<any>
52+
): CloudFunction<FirebaseAlertData<NewTesterDevicePayload>>;
53+
export function onNewTesterIosDevicePublished(
54+
opts: AppDistributionOptions,
55+
handler: (
56+
event: AppDistributionEvent<NewTesterDevicePayload>
57+
) => any | Promise<any>
58+
): CloudFunction<FirebaseAlertData<NewTesterDevicePayload>>;
59+
export function onNewTesterIosDevicePublished(
60+
appIdOrOptsOrHandler:
61+
| string
62+
| AppDistributionOptions
63+
| ((
64+
event: AppDistributionEvent<NewTesterDevicePayload>
65+
) => any | Promise<any>),
66+
handler?: (
67+
event: AppDistributionEvent<NewTesterDevicePayload>
68+
) => any | Promise<any>
69+
): CloudFunction<FirebaseAlertData<NewTesterDevicePayload>> {
70+
if (typeof appIdOrOptsOrHandler === 'function') {
71+
handler = appIdOrOptsOrHandler as (
72+
event: AppDistributionEvent<NewTesterDevicePayload>
73+
) => any | Promise<any>;
74+
appIdOrOptsOrHandler = {};
75+
}
76+
77+
const [opts, appId] = getOptsAndApp(appIdOrOptsOrHandler);
78+
79+
const func = (raw: CloudEvent<unknown>) => {
80+
return handler(raw as AppDistributionEvent<NewTesterDevicePayload>);
81+
};
82+
83+
func.run = handler;
84+
func.__endpoint = getEndpointAnnotation(opts, newTesterIosDeviceAlert, appId);
85+
86+
return func;
87+
}
88+
89+
/**
90+
* @internal
91+
* Helper function to parse the function opts and appId.
92+
*/
93+
export function getOptsAndApp(
94+
appIdOrOpts: string | AppDistributionOptions
95+
): [options.EventHandlerOptions, string | undefined] {
96+
let opts: options.EventHandlerOptions;
97+
let appId: string | undefined;
98+
if (typeof appIdOrOpts === 'string') {
99+
opts = {};
100+
appId = appIdOrOpts;
101+
} else {
102+
appId = appIdOrOpts.appId;
103+
opts = { ...appIdOrOpts };
104+
delete (opts as any).appId;
105+
}
106+
return [opts, appId];
107+
}

v2/alerts/appDistribution.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2021 Firebase
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in all
13+
// copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
// SOFTWARE.
22+
23+
// This file is not part of the firebase-functions SDK. It is used to silence the
24+
// imports eslint plugin until it can understand import paths defined by node
25+
// package exports.
26+
// For more information, see github.com/import-js/eslint-plugin-import/issues/1810

0 commit comments

Comments
 (0)