Commit 6c99242e authored by yogevbd's avatar yogevbd

Splits requestPermissionsWithCategories to two functions

parent 8099dbfc
#import "RCTConvert+RNNotifications.h"
@implementation RCTConvert (UIUserNotificationActivationMode)
RCT_ENUM_CONVERTER(UIUserNotificationActivationMode, (@{
@"foreground": @(UIUserNotificationActivationModeForeground),
@"background": @(UIUserNotificationActivationModeBackground)
}), UIUserNotificationActivationModeForeground, integerValue)
@end
@implementation RCTConvert (UNNotificationActionOptions)
+ (UNNotificationActionOptions)UNUserNotificationActionOptions:(id)json {
......
......@@ -32,8 +32,12 @@ RCT_EXPORT_MODULE();
#pragma mark - JS interface
RCT_EXPORT_METHOD(requestPermissionsWithCategories:(NSArray *)json) {
[_commandsHandler requestPermissionsWithCategories:json];
RCT_EXPORT_METHOD(requestPermissions) {
[_commandsHandler requestPermissions];
}
RCT_EXPORT_METHOD(setCategories:(NSArray *)categories) {
[_commandsHandler setCategories:categories];
}
RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
......
......@@ -5,7 +5,9 @@
- (instancetype)init;
- (void)requestPermissionsWithCategories:(NSArray *)json;
- (void)requestPermissions;
- (void)setCategories:(NSArray *)categories;
- (void)getInitialNotification:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject;
......
......@@ -13,8 +13,12 @@
return self;
}
- (void)requestPermissionsWithCategories:(NSArray *)json {
[_notificationCenter requestPermissionsWithCategories:json];
- (void)requestPermissions {
[_notificationCenter requestPermissions];
}
- (void)setCategories:(NSArray *)categories {
[_notificationCenter setCategories:categories];
}
- (void)getInitialNotification:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
......
......@@ -10,7 +10,9 @@ typedef void (^RCTPromiseRejectBlock)(NSString *code, NSString *message, NSError
- (void)isRegisteredForRemoteNotifications:(RCTPromiseResolveBlock)resolve;
- (void)requestPermissionsWithCategories:(NSArray *)json;
- (void)requestPermissions;
- (void)setCategories:(NSArray *)json;
- (void)checkPermissions:(RCTPromiseResolveBlock)resolve;
......
......@@ -3,16 +3,7 @@
@implementation RNNotificationCenter
- (void)requestPermissionsWithCategories:(NSArray *)json {
NSMutableSet<UNNotificationCategory *>* categories = nil;
if ([json count] > 0) {
categories = [NSMutableSet new];
for (NSDictionary* categoryJson in json) {
[categories addObject:[RCTConvert UNMutableUserNotificationCategory:categoryJson]];
}
}
[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:categories];
- (void)requestPermissions {
UNAuthorizationOptions authOptions = (UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert);
[UNUserNotificationCenter.currentNotificationCenter requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error && granted) {
......@@ -27,6 +18,18 @@
}];
}
- (void)setCategories:(NSArray *)json {
NSMutableSet<UNNotificationCategory *>* categories = nil;
if ([json count] > 0) {
categories = [NSMutableSet new];
for (NSDictionary* categoryJson in json) {
[categories addObject:[RCTConvert UNMutableUserNotificationCategory:categoryJson]];
}
}
[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:categories];
}
- (void)sendLocalNotification:(NSDictionary *)notification withId:(NSString *)notificationId {
UNNotificationRequest* localNotification = [RCTConvert UNNotificationRequest:notification withId:notificationId];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:localNotification withCompletionHandler:nil];
......
......@@ -25,33 +25,43 @@
_notificationCenter = [UNUserNotificationCenter currentNotificationCenter];
}
- (void)testRequestPermissionsWithCategories_userAuthorizedPermissions {
NSArray* json = @[@{@"identifier": @"identifier"}];
- (void)testRequestPermissions_userAuthorizedPermissions {
UNAuthorizationOptions authOptions = (UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert);
UNNotificationSettings* settings = [UNNotificationSettings new];
[settings setValue:@(UNAuthorizationStatusAuthorized) forKey:@"authorizationStatus"];
[[_notificationCenter expect] setNotificationCategories:[OCMArg any]];
[[_notificationCenter expect] requestAuthorizationWithOptions:authOptions completionHandler:[OCMArg invokeBlockWithArgs:@(YES), [NSNull null], nil]];
[[_notificationCenter expect] getNotificationSettingsWithCompletionHandler:[OCMArg invokeBlockWithArgs:settings, nil]];
[[(id)[UIApplication sharedApplication] expect] registerForRemoteNotifications];
[_uut requestPermissionsWithCategories:json];
[_uut requestPermissions];
[_notificationCenter verify];
}
- (void)testRequestPermissionsWithCategories_userDeniedPermissions {
NSArray* json = @[@{@"identifier": @"identifier"}];
- (void)testRequestPermissions_userDeniedPermissions {
UNAuthorizationOptions authOptions = (UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert);
UNNotificationSettings* settings = [UNNotificationSettings new];
[settings setValue:@(UNAuthorizationStatusDenied) forKey:@"authorizationStatus"];
[[_notificationCenter expect] setNotificationCategories:[OCMArg any]];
[[_notificationCenter expect] requestAuthorizationWithOptions:authOptions completionHandler:[OCMArg invokeBlockWithArgs:@(YES), [NSNull null], nil]];
[[_notificationCenter expect] getNotificationSettingsWithCompletionHandler:[OCMArg invokeBlockWithArgs:settings, nil]];
[[(id)[UIApplication sharedApplication] reject] registerForRemoteNotifications];
[_uut requestPermissionsWithCategories:json];
[_uut requestPermissions];
[_notificationCenter verify];
}
- (void)testSetCategories_shouldSetCategories {
NSArray* json = @[@{@"identifier": @"categoryId", @"actions": @[@{@"identifier" : @"actionId", @"activationMode": @"foreground"}]}];
[[_notificationCenter expect] setNotificationCategories:[OCMArg checkWithBlock:^BOOL(NSMutableSet<UNNotificationCategory *>* categories) {
UNNotificationCategory* category = categories.allObjects.firstObject;
UNNotificationAction* action = category.actions.firstObject;
return ([category.identifier isEqualToString:@"categoryId"] &&
[action.identifier isEqualToString:@"actionId"] &&
action.options == UNNotificationActionOptionForeground);
}]];
[_uut setCategories:json];
[_notificationCenter verify];
}
......
......@@ -2,7 +2,7 @@ import { NativeCommandsSender } from './adapters/NativeCommandsSender';
import { NativeEventsReceiver } from './adapters/NativeEventsReceiver';
import { Commands } from './commands/Commands';
import { EventsRegistry } from './events/EventsRegistry';
import { Notification } from './interfaces/Notification';
import { Notification, NotificationCategory } from './interfaces/Notification';
export class NotificationsRoot {
private readonly nativeEventsReceiver: NativeEventsReceiver;
......@@ -22,14 +22,21 @@ export class NotificationsRoot {
/**
* Request permissions to send remote notifications - iOS only
*/
public requestPermissions(): Promise<any> {
public requestPermissions() {
return this.commands.requestPermissions();
}
/**
* registerPushKit
*/
public registerPushKit() {
return this.commands.registerPushKit();
}
/**
* Reset the app to a new layout
*/
public localNotification(notification: Notification): Promise<any> {
public localNotification(notification: Notification) {
return this.commands.sendLocalNotification(notification);
}
......@@ -40,6 +47,71 @@ export class NotificationsRoot {
return this.commands.getInitialNotification();
}
/**
* setCategories
*/
public setCategories(categories: [NotificationCategory?]) {
this.commands.setCategories(categories);
}
/**
* getBadgesCount
*/
public getBadgeCount(): Promise<number> {
return this.commands.getBadgeCount();
}
/**
* setBadgeCount
* @param count number of the new badge count
*/
public setBadgeCount(count: number) {
return this.commands.setBadgeCount(count);
}
/**
* cancelLocalNotification
*/
public cancelLocalNotification(notificationId: string) {
return this.commands.cancelLocalNotification(notificationId);
}
/**
* cancelAllLocalNotifications
*/
public cancelAllLocalNotifications() {
this.commands.cancelAllLocalNotifications();
}
/**
* isRegisteredForRemoteNotifications
*/
public isRegisteredForRemoteNotifications(): Promise<any> {
this.commands.isRegisteredForRemoteNotifications();
}
/**
* checkPermissions
*/
public checkPermissions() {
return this.commands.checkPermissions();
}
/**
* removeAllDeliveredNotifications
*/
public removeAllDeliveredNotifications() {
return this.commands.removeAllDeliveredNotifications();
}
/**
* removeDeliveredNotifications
* @param identifiers Array of notification identifiers
*/
public removeDeliveredNotifications(identifiers: Array<string>) {
return this.commands.removeDeliveredNotifications(identifiers);
}
/**
* Obtain the events registry instance
*/
......
import { NativeModules } from 'react-native';
import { Notification } from '../interfaces/Notification';
import { Notification, NotificationCategory, NotificationPermissions } from '../interfaces/Notification';
interface NativeCommandsModule {
getInitialNotification(): Promise<any>;
localNotification(notification: Notification, id: string): Promise<Notification>;
requestPermissionsWithCategories(categories: any): Promise<any>;
abandonPermissions(): Promise<any>;
getInitialNotification(): Promise<Notification>;
localNotification(notification: Notification, id: string): void;
requestPermissions(): void;
abandonPermissions(): void;
registerPushKit(): void;
getBadgeCount(): Promise<number>;
setBadgeCount(count: number): void;
cancelLocalNotification(notificationId: string): void;
cancelAllLocalNotifications(): void;
isRegisteredForRemoteNotifications(): Promise<boolean>;
checkPermissions(): Promise<NotificationPermissions>;
removeDeliveredNotifications(identifiers: Array<string>): void;
removeAllDeliveredNotifications(): void;
setCategories(categories: [NotificationCategory?]): void;
}
export class NativeCommandsSender {
......@@ -23,10 +33,50 @@ export class NativeCommandsSender {
}
requestPermissions() {
return this.nativeCommandsModule.requestPermissionsWithCategories([]);
return this.nativeCommandsModule.requestPermissions();
}
abandonPermissions() {
return this.nativeCommandsModule.abandonPermissions();
}
registerPushKit() {
return this.nativeCommandsModule.registerPushKit();
}
setCategories(categories: [NotificationCategory?]) {
this.nativeCommandsModule.setCategories(categories);
}
getBadgeCount(): Promise<number> {
return this.nativeCommandsModule.getBadgeCount();
}
setBadgeCount(count: number) {
this.nativeCommandsModule.setBadgeCount(count);
}
cancelLocalNotification(notificationId: string) {
this.nativeCommandsModule.cancelLocalNotification(notificationId);
}
cancelAllLocalNotifications() {
this.nativeCommandsModule.cancelAllLocalNotifications();
}
isRegisteredForRemoteNotifications(): Promise<any> {
return this.nativeCommandsModule.isRegisteredForRemoteNotifications();
}
checkPermissions() {
return this.nativeCommandsModule.checkPermissions();
}
removeAllDeliveredNotifications() {
return this.nativeCommandsModule.removeAllDeliveredNotifications();
}
removeDeliveredNotifications(identifiers: Array<string>) {
return this.nativeCommandsModule.removeDeliveredNotifications(identifiers);
}
}
......@@ -3,7 +3,7 @@ import { mock, verify, instance, deepEqual, when, anything, anyString } from 'ts
import { Commands } from './Commands';
import { NativeCommandsSender } from '../adapters/NativeCommandsSender';
import { Notification } from '../interfaces/Notification';
import { Notification, NotificationCategory, NotificationPermissions } from '../interfaces/Notification';
describe('Commands', () => {
let uut: Commands;
......@@ -18,7 +18,7 @@ describe('Commands', () => {
});
describe('getInitialNotification', () => {
it('sends getInitialNotification to native', () => {
it('sends to native', () => {
uut.getInitialNotification();
verify(mockedNativeCommandsSender.getInitialNotification()).called();
});
......@@ -33,24 +33,129 @@ describe('Commands', () => {
});
describe('requestPermissions', () => {
it('sends requestPermissions to native', () => {
it('sends to native', () => {
uut.requestPermissions();
verify(mockedNativeCommandsSender.requestPermissions()).called();
});
});
describe('registerPushKit', () => {
it('sends to native', () => {
uut.registerPushKit();
verify(mockedNativeCommandsSender.registerPushKit()).called();
});
});
describe('setCategories', () => {
it('sends to native', () => {
const emptyCategoriesArray: [NotificationCategory?] = [];
uut.setCategories(emptyCategoriesArray);
verify(mockedNativeCommandsSender.setCategories(emptyCategoriesArray)).called();
});
it('sends to native with categories', () => {
const category: NotificationCategory = {identifier: 'id', actions: []};
const categoriesArray: [NotificationCategory] = [category];
uut.setCategories(categoriesArray);
verify(mockedNativeCommandsSender.setCategories(categoriesArray)).called();
});
});
describe('abandonPermissions', () => {
it('sends abandonPermissions to native', () => {
it('sends to native', () => {
uut.abandonPermissions();
verify(mockedNativeCommandsSender.abandonPermissions()).called();
});
});
describe('sendLocalNotification', () => {
it('sends sendLocalNotification to native', () => {
it('sends to native', () => {
const notification: Notification = {data: {}, alert: 'alert'};
uut.sendLocalNotification(notification);
verify(mockedNativeCommandsSender.sendLocalNotification(notification, 'id')).called();
});
});
describe('getBadgeCount', () => {
it('sends to native', () => {
uut.getBadgeCount();
verify(mockedNativeCommandsSender.getBadgeCount()).called();
});
});
describe('setBadgeCount', () => {
it('sends to native', () => {
uut.setBadgeCount(10);
verify(mockedNativeCommandsSender.setBadgeCount(10)).called();
});
});
describe('cancelLocalNotification', () => {
it('sends to native', () => {
uut.cancelLocalNotification("notificationId");
verify(mockedNativeCommandsSender.cancelLocalNotification("notificationId")).called();
});
});
describe('cancelAllLocalNotifications', () => {
it('sends to native', () => {
uut.cancelAllLocalNotifications();
verify(mockedNativeCommandsSender.cancelAllLocalNotifications()).called();
});
});
describe('isRegisteredForRemoteNotifications', () => {
it('sends to native', () => {
uut.isRegisteredForRemoteNotifications();
verify(mockedNativeCommandsSender.isRegisteredForRemoteNotifications()).called();
});
it('return positive response from native', async () => {
when(mockedNativeCommandsSender.isRegisteredForRemoteNotifications()).thenResolve(
true
);
const isRegistered = await uut.isRegisteredForRemoteNotifications();
verify(mockedNativeCommandsSender.isRegisteredForRemoteNotifications()).called();
expect(isRegistered).toEqual(true);
});
it('return negative response from native', async () => {
when(mockedNativeCommandsSender.isRegisteredForRemoteNotifications()).thenResolve(
false
);
const isRegistered = await uut.isRegisteredForRemoteNotifications();
expect(isRegistered).toEqual(false);
});
});
describe('checkPermissions', () => {
it('sends to native', () => {
uut.checkPermissions();
verify(mockedNativeCommandsSender.checkPermissions()).called();
});
it('return negative response from native', async () => {
const expectedPermissions: NotificationPermissions = {badge: false, alert: true, sound: false};
when(mockedNativeCommandsSender.checkPermissions()).thenResolve(
expectedPermissions
);
const permissions = await uut.checkPermissions();
expect(permissions).toEqual(expectedPermissions);
});
});
describe('removeAllDeliveredNotifications', () => {
it('sends to native', () => {
uut.removeAllDeliveredNotifications();
verify(mockedNativeCommandsSender.removeAllDeliveredNotifications()).called();
});
});
describe('removeDeliveredNotifications', async () => {
it('sends to native', () => {
const identifiers: Array<string> = ["id1", "id2"];
uut.removeDeliveredNotifications(identifiers);
verify(mockedNativeCommandsSender.removeDeliveredNotifications(identifiers)).called();
});
});
});
import * as _ from 'lodash';
import { NativeCommandsSender } from '../adapters/NativeCommandsSender';
import { Notification } from '../interfaces/Notification';
import { Notification, NotificationCategory, NotificationPermissions } from '../interfaces/Notification';
export class Commands {
constructor(
......@@ -27,4 +27,44 @@ export class Commands {
const result = this.nativeCommandsSender.abandonPermissions();
return result;
}
public registerPushKit() {
this.nativeCommandsSender.registerPushKit();
}
public setCategories(categories: [NotificationCategory?]) {
this.nativeCommandsSender.setCategories(categories);
}
public getBadgeCount(): Promise<number> {
return this.nativeCommandsSender.getBadgeCount();
}
public setBadgeCount(count: number) {
this.nativeCommandsSender.setBadgeCount(count);
}
public cancelLocalNotification(notificationId: string) {
this.nativeCommandsSender.cancelLocalNotification(notificationId);
}
public cancelAllLocalNotifications() {
this.nativeCommandsSender.cancelAllLocalNotifications();
}
public isRegisteredForRemoteNotifications(): Promise<boolean> {
return this.nativeCommandsSender.isRegisteredForRemoteNotifications();
}
public checkPermissions(): Promise<NotificationPermissions> {
return this.nativeCommandsSender.checkPermissions();
}
public removeAllDeliveredNotifications() {
this.nativeCommandsSender.removeAllDeliveredNotifications();
}
public removeDeliveredNotifications(identifiers: Array<string>) {
return this.nativeCommandsSender.removeDeliveredNotifications(identifiers);
}
}
......@@ -6,3 +6,28 @@ export interface Notification {
type?: string;
thread?: string;
}
export interface NotificationPermissions {
badge: boolean;
alert: boolean;
sound: boolean;
}
export interface NotificationCategory {
identifier: string
actions: [NotificationAction?];
}
export interface NotificationTextInput {
buttonTitle: string;
placeholder: string;
}
export interface NotificationAction {
identifier: string;
activationMode: 'foreground' | 'authenticationRequired' | 'destructive';
title: string;
authenticationRequired: boolean;
textInput: NotificationTextInput
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment