Skip to content

Commit

Permalink
branch was updated with master
Browse files Browse the repository at this point in the history
  • Loading branch information
Gonzalo Lopez authored and Pablo Damian Berdun committed Jun 25, 2024
2 parents 3118a96 + d3d8571 commit 9e9d87e
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 11 deletions.
14 changes: 12 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
# Changelog

[Unreleased]
## [Unreleased]

## [0.0.1] - 2024-05-03
### Added

- Added notification channels

## [0.0.3] - 2024-06-13

### Added

- additional info to send in subscription

## [0.0.2] - 2024-05-03

### Added

Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ For more information about this, read https://rnfirebase.io/reference/messaging/
## Functions

<dl>
<dt><a href="#NotificationProvider">NotificationProvider(children, appName, events, environment, channelConfigs)</a> ⇒ <code>null</code> | <code>React.element</code></dt>
<dt><a href="#NotificationProvider">NotificationProvider(children, appName, events, environment, additionalInfo, channelConfigs)</a> ⇒ <code>null</code> | <code>React.element</code></dt>
<dd><p>It is the main component of the package, it is a HOC that is responsible for handling the logic of subscribing to notifications and receiving messages from the Firebase console. The HOC contains listeners to listen to notifications in the foreground and background, so (unless we cancel the subscription), we will receive notifications from the app even when it is closed.</p>
</dd>
<dt><a href="#setupBackgroundMessageHandler">setupBackgroundMessageHandler(callback)</a></dt>
Expand Down Expand Up @@ -70,6 +70,10 @@ For more information about this, read https://rnfirebase.io/reference/messaging/
<td>This util is responsible for making the request to unsubscribe from all notification events. If no arguments are received, the request will be made with the previously registered events.</td>
</tr>
<tr>
<td>updateSuscription</td>
<td>This function is responsible for updating the subscription to the notification service</td>
</tr>
<tr>
<td>addNewEvent</td>
<td>This function allows you to add a new event to receive notifications.</td>
</tr>
Expand All @@ -87,7 +91,7 @@ For more information about this, read https://rnfirebase.io/reference/messaging/

<a name="NotificationProvider"></a>

## NotificationProvider(children, appName, events, environment, channelConfigs) ⇒ <code>null</code> \| <code>React.element</code>
## NotificationProvider(children, appName, events, environment, additionalInfo, channelConfigs) ⇒ <code>null</code> \| <code>React.element</code>
It is the main component of the package, it is a HOC that is responsible for handling the logic of subscribing to notifications and receiving messages from the Firebase console. The HOC contains listeners to listen to notifications in the foreground and background, so (unless we cancel the subscription), we will receive notifications from the app even when it is closed.

**Kind**: global function
Expand All @@ -102,6 +106,7 @@ It is the main component of the package, it is a HOC that is responsible for han
| appName | <code>string</code> | name of the aplication |
| events | <code>Array.&lt;string&gt;</code> | is an array that will contain the events to which the user wants to subscribe |
| environment | <code>string</code> | The environment is necessary for the API that we are going to use to subscribe the device to notifications. |
| additionalInfo | <code>object</code> | fields to be sent as part of the body of the subscription request |
| channelConfigs | <code>Array.&lt;(string\|object)&gt;</code> | is the configuration that will be used to create new notification channels |

**Example**
Expand Down Expand Up @@ -140,6 +145,7 @@ is a hook, which returns the elements contained within the notifications context
| backgroundNotification | An object containing all data received when a background push notification is triggered. |
| subscribeError | An object containing all data received from a notification service subscription failure. |
| cancelNotifications | This util is responsible for making the request to unsubscribe from all notification events. If no arguments are received, the request will be made with the previously registered events. |
| updateSuscription | This function is responsible for updating the subscription to the notification service |
| addNewEvent | This function allows you to add a new event to receive notifications. |
| deleteReceivedNotification | An util that clears the foreground or background notification state to the depending on the type it receives by parameter
| getSubscribedEvents | This function returns an array with the events to which the user is subscribed. |
Expand Down
1 change: 1 addition & 0 deletions lib/NotificationContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const NotificationContext = React.createContext(null);
* | backgroundNotification | An object containing all data received when a background push notification is triggered. |
* | subscribeError | An object containing all data received from a notification service subscription failure. |
* | cancelNotifications | This util is responsible for making the request to unsubscribe from all notification events. If no arguments are received, the request will be made with the previously registered events. |
* | updateSuscription | This function is responsible for updating the subscription to the notification service |
* | addNewEvent | This function allows you to add a new event to receive notifications. |
* | deleteReceivedNotification | An util that clears the foreground or background notification state to the depending on the type it receives by parameter
* | getSubscribedEvents | This function returns an array with the events to which the user is subscribed. |
Expand Down
3 changes: 3 additions & 0 deletions lib/NotificationProvider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
* @param {string} appName name of the aplication
* @param {Array<string>} events is an array that will contain the events to which the user wants to subscribe
* @param {string} environment The environment is necessary for the API that we are going to use to subscribe the device to notifications.
* @param {object} additionalInfo fields to be sent as part of the body of the subscription request
* @param {Array<string | object>} channelConfigs is the configuration that will be used to create new notification channels
* @throws null when not receive a children argument
* @returns {null | React.element}
Expand All @@ -45,6 +46,7 @@ const NotificationProvider = ({
appName,
events,
environment,
additionalInfo,
channelConfigs = [],
}) => {
if (!children) return null;
Expand All @@ -67,6 +69,7 @@ const NotificationProvider = ({
validEvents,
validAppName,
isRegistered,
additionalInfo,
);

// @function handlerForegroundData
Expand Down
35 changes: 34 additions & 1 deletion lib/usePushNotification.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import {getFCMToken, isArray, isString} from './utils';
import SubscribeNotifications from './utils/api/SubscribeNotifications';
import UnSubscribeNotifications from './utils/api/UnSubscribeNotifications';

const usePushNotification = (environment, events, appName, isRegistered) => {
const usePushNotification = (
environment,
events,
appName,
isRegistered,
additionalInfo,
) => {
const [notificationState, setNotificationState] = useState({
deviceToken: null,
foregroundNotification: {},
Expand Down Expand Up @@ -54,6 +60,7 @@ const usePushNotification = (environment, events, appName, isRegistered) => {
events: pushEvents,
deviceToken: token,
request: Request,
additionalInfo,
});

isRegistered.current = true;
Expand All @@ -63,6 +70,31 @@ const usePushNotification = (environment, events, appName, isRegistered) => {
}
}, [pushEvents]);

/**
* @function updateSuscription
* @description This function is responsible for updating the subscription to the notification service
* @param {object} props all properties that will be sent as additional data in the subscription
* @returns {Promise}
*/

const updateSuscription = async (props = {}) => {
try {
const token = await getDeviceToken();

const response = await SubscribeNotifications({
appName,
events: pushEvents,
deviceToken: token,
request: Request,
additionalInfo: props,
});

return response;
} catch (error) {
return Promise.reject(error);
}
};

/**
* @function cancelNotifications
* @description This util is responsible for making the request to unsubscribe from all notification events. If no arguments are received, the request will be made with the previously registered events.
Expand Down Expand Up @@ -161,6 +193,7 @@ const usePushNotification = (environment, events, appName, isRegistered) => {
updateNotificationState,
getSubscribedEvents,
deleteReceivedNotification,
updateSuscription,
};
};

Expand Down
10 changes: 8 additions & 2 deletions lib/utils/api/SubscribeNotifications/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {isString, isArray} from '../../index';
import {isString, isArray, isObject} from '../../index';

const SubscribeNotifications = async (params = {}) => {
try {
if (!params || !Object.keys(params).length)
throw new Error('params is not a valid object');

const {deviceToken, events, appName, request} = params;
const {deviceToken, events, appName, request, additionalInfo} = params;

if (!deviceToken || !isString(deviceToken))
throw new Error('device token is invalid or null');
Expand All @@ -19,10 +19,16 @@ const SubscribeNotifications = async (params = {}) => {
if (!parsedEvents.length)
throw new Error('events to be suscribed are invalids');

const validAdditionalInfo =
isObject(additionalInfo) && !!Object.keys(additionalInfo).length;

const body = {
token: deviceToken,
events: parsedEvents,
platformApplicationName: appName,
...(validAdditionalInfo && {
additionalInfo,
}),
};

const response = await request.post({
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@janiscommerce/app-push-notification",
"version": "0.0.2",
"version": "0.0.3",
"type": "commonjs",
"description": "This package will take care of performing the main actions for registration to receive notifications in the foreground and background.",
"main": "lib/index.js",
Expand Down
61 changes: 61 additions & 0 deletions test/usePushNotification.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {useState} from 'react';
import {renderHook} from '@testing-library/react-native';
import usePushNotification from '../lib/usePushNotification';
import * as UnSubscribeNotifications from '../lib/utils/api/UnSubscribeNotifications';
import * as SubscribeNotifications from '../lib/utils/api/SubscribeNotifications';
import {promiseWrapper} from '../lib/utils';

describe('usePushNotification hook', () => {
Expand All @@ -10,6 +11,11 @@ describe('usePushNotification hook', () => {
'default',
);

const spySubscribeNotifications = jest.spyOn(
SubscribeNotifications,
'default',
);

const initialState = {
deviceToken: null,
foregroundNotification: {},
Expand Down Expand Up @@ -37,6 +43,61 @@ describe('usePushNotification hook', () => {
});

describe('the object contains:', () => {
describe('updateSuscription util', () => {
it('this util call the api to suscribe to notifications service', async () => {
spySubscribeNotifications.mockResolvedValueOnce({result: {}});
useState.mockReturnValueOnce([
{
...initialState,
deviceToken: 'fcmToken',
pushEvents: ['picking:session:created'],
},
mockSetState,
]);

const {result} = renderHook(() =>
usePushNotification(
'local',
['picking:session:created'],
'PickingApp',
{current: false},
),
);
const {updateSuscription} = result.current;

const [response] = await promiseWrapper(
updateSuscription({language: 'en-US'}),
);

await expect(response).toStrictEqual({result: {}});
});

it('this util returns an error when the suscription has an error', async () => {
spySubscribeNotifications.mockRejectedValueOnce({message: 'error'});
useState.mockReturnValueOnce([
{
...initialState,
deviceToken: 'fcmToken',
pushEvents: ['picking:session:created'],
},
mockSetState,
]);

const {result} = renderHook(() =>
usePushNotification(
'local',
['picking:session:created'],
'PickingApp',
{current: false},
),
);
const {updateSuscription} = result.current;

const [, response] = await promiseWrapper(updateSuscription());

await expect(response).toStrictEqual({message: 'error'});
});
});
describe('cancelNotifications util', () => {
it('this utils call the api and cancel the subscription to event passed an arguments or all events', async () => {
spyUnSubscribeNotifications.mockResolvedValueOnce({result: {}});
Expand Down
7 changes: 6 additions & 1 deletion test/utils/api/subscribeNotifications/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ describe('SubscribeNotifications', () => {

nock(server).post('/subscribe/push').reply(200, {});

const response = await SubscribeNotifications(validParams);
const response = await SubscribeNotifications({
...validParams,
additionalInfo: {
language: 'en-US',
},
});

expect(response).toStrictEqual({result: {}});
});
Expand Down

0 comments on commit 9e9d87e

Please sign in to comment.