feat: test push notification (#5329)
* feat: test push notification * restApi and definition * push.info and change properly the troubleshootingNotification * use the finally at try/catch * minor tweak
This commit is contained in:
parent
5ab5d9c945
commit
85ec50a9ee
|
@ -96,8 +96,4 @@ export const VIDEO_CONF = createRequestTypes('VIDEO_CONF', [
|
|||
'ACCEPT_CALL',
|
||||
'SET_CALLING'
|
||||
]);
|
||||
export const TROUBLESHOOTING_NOTIFICATION = createRequestTypes('TROUBLESHOOTING_NOTIFICATION', [
|
||||
'REQUEST',
|
||||
'SET',
|
||||
'SET_IN_ALERT'
|
||||
]);
|
||||
export const TROUBLESHOOTING_NOTIFICATION = createRequestTypes('TROUBLESHOOTING_NOTIFICATION', ['REQUEST', 'SET']);
|
||||
|
|
|
@ -23,12 +23,3 @@ export function setTroubleshootingNotification(payload: Partial<ITroubleshooting
|
|||
payload
|
||||
};
|
||||
}
|
||||
|
||||
export function setInAlertTroubleshootingNotification(
|
||||
payload: Pick<ITroubleshootingNotification, 'inAlertNotification'>
|
||||
): TSetInAlertTroubleshootingNotification {
|
||||
return {
|
||||
type: TROUBLESHOOTING_NOTIFICATION.SET_IN_ALERT,
|
||||
payload
|
||||
};
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import { E2eEndpoints } from './e2e';
|
|||
import { SubscriptionsEndpoints } from './subscriptions';
|
||||
import { VideoConferenceEndpoints } from './videoConference';
|
||||
import { CommandsEndpoints } from './commands';
|
||||
import { PushTokenEndpoints } from './pushToken';
|
||||
import { PushEndpoints } from './push';
|
||||
import { DirectoryEndpoint } from './directory';
|
||||
import { AutoTranslateEndpoints } from './autotranslate';
|
||||
|
||||
|
@ -40,6 +40,6 @@ export type Endpoints = ChannelsEndpoints &
|
|||
SubscriptionsEndpoints &
|
||||
VideoConferenceEndpoints &
|
||||
CommandsEndpoints &
|
||||
PushTokenEndpoints &
|
||||
PushEndpoints &
|
||||
DirectoryEndpoint &
|
||||
AutoTranslateEndpoints;
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
export type PushTokenEndpoints = {
|
||||
type TPushInfo = {
|
||||
pushGatewayEnabled: boolean;
|
||||
defaultPushGateway: boolean;
|
||||
success: boolean;
|
||||
};
|
||||
|
||||
export type PushEndpoints = {
|
||||
'push.token': {
|
||||
POST: (params: { value: string; type: string; appName: string }) => {
|
||||
result: {
|
||||
|
@ -9,4 +15,7 @@ export type PushTokenEndpoints = {
|
|||
};
|
||||
};
|
||||
};
|
||||
'push.info': {
|
||||
GET: () => TPushInfo;
|
||||
};
|
||||
};
|
|
@ -770,5 +770,6 @@
|
|||
"Jitsi_authentication_before_making_calls": "Jitsi may require authentication before making calls. To learn more about their policies, visit the Jitsi website.",
|
||||
"Jitsi_authentication_before_making_calls_ask_admin": "If you believe there are problems with Jitsi and its authentication, ask a workspace administrator for help.",
|
||||
"Continue": "Continue",
|
||||
"Troubleshooting": "Troubleshooting"
|
||||
"Troubleshooting": "Troubleshooting",
|
||||
"Your_push_was_sent_to_s_devices": "Your push was sent to {{s}} devices"
|
||||
}
|
||||
|
|
|
@ -756,5 +756,6 @@
|
|||
"decline": "Recusar",
|
||||
"accept": "Aceitar",
|
||||
"Incoming_call_from": "Chamada recebida de",
|
||||
"Call_started": "Chamada Iniciada"
|
||||
"Call_started": "Chamada Iniciada",
|
||||
"Your_push_was_sent_to_s_devices": "A sua notificação foi enviada para {{s}} dispositivos"
|
||||
}
|
|
@ -60,7 +60,8 @@ export const SUPPORTED_PERMISSIONS = [
|
|||
'view-canned-responses',
|
||||
'mobile-upload-file',
|
||||
'delete-own-message',
|
||||
'call-management'
|
||||
'call-management',
|
||||
'test-push-notifications'
|
||||
] as const;
|
||||
|
||||
export async function setPermissions(): Promise<void> {
|
||||
|
|
|
@ -901,6 +901,11 @@ export const removePushToken = (): Promise<boolean | void> => {
|
|||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const pushTest = (): Promise<{ message: string; params: number[] }> => sdk.methodCallWrapper('push_test');
|
||||
|
||||
// RC 6.5.0
|
||||
export const pushInfo = () => sdk.get('push.info');
|
||||
|
||||
export const sendEmailCode = () => {
|
||||
const { username } = reduxStore.getState().login.user as IUser;
|
||||
// RC 3.1.0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { setInAlertTroubleshootingNotification, setTroubleshootingNotification } from '../actions/troubleshootingNotification';
|
||||
import { setTroubleshootingNotification, requestTroubleshootingNotification } from '../actions/troubleshootingNotification';
|
||||
import { mockedStore } from './mockedStore';
|
||||
import { ITroubleshootingNotification, initialState } from './troubleshootingNotification';
|
||||
|
||||
|
@ -8,26 +8,21 @@ describe('test troubleshootingNotification reducer', () => {
|
|||
expect(state).toEqual(initialState);
|
||||
});
|
||||
|
||||
it('should return correctly the value after call requestTroubleshootingNotification action', () => {
|
||||
mockedStore.dispatch(requestTroubleshootingNotification());
|
||||
const state = mockedStore.getState().troubleshootingNotification;
|
||||
expect(state).toEqual(initialState);
|
||||
});
|
||||
|
||||
it('should return correctly value after call troubleshootingNotification action', () => {
|
||||
const payload: ITroubleshootingNotification = {
|
||||
consumptionPercentage: 50,
|
||||
deviceNotificationEnabled: true,
|
||||
inAlertNotification: false,
|
||||
isCommunityEdition: true,
|
||||
isCustomPushGateway: true,
|
||||
isPushGatewayConnected: true
|
||||
defaultPushGateway: true,
|
||||
pushGatewayEnabled: true
|
||||
};
|
||||
mockedStore.dispatch(setTroubleshootingNotification(payload));
|
||||
const state = mockedStore.getState().troubleshootingNotification;
|
||||
expect(state).toEqual(payload);
|
||||
});
|
||||
it('should return correctly the inAlert value after call setInAlert action', () => {
|
||||
const previousInAlertState = mockedStore.getState().troubleshootingNotification.inAlertNotification;
|
||||
const payload: Pick<ITroubleshootingNotification, 'inAlertNotification'> = {
|
||||
inAlertNotification: !previousInAlertState
|
||||
};
|
||||
mockedStore.dispatch(setInAlertTroubleshootingNotification(payload));
|
||||
const newInAlertState = mockedStore.getState().troubleshootingNotification.inAlertNotification;
|
||||
expect(newInAlertState).toEqual(payload.inAlertNotification);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,20 +3,19 @@ import { TActionTroubleshootingNotification } from '../actions/troubleshootingNo
|
|||
|
||||
export interface ITroubleshootingNotification {
|
||||
deviceNotificationEnabled: boolean;
|
||||
isCommunityEdition: boolean;
|
||||
isPushGatewayConnected: boolean;
|
||||
isCustomPushGateway: boolean;
|
||||
consumptionPercentage: number;
|
||||
pushGatewayEnabled: boolean;
|
||||
defaultPushGateway: boolean;
|
||||
inAlertNotification: boolean;
|
||||
}
|
||||
|
||||
export const initialState: ITroubleshootingNotification = {
|
||||
consumptionPercentage: 0,
|
||||
deviceNotificationEnabled: false,
|
||||
isCommunityEdition: false,
|
||||
isPushGatewayConnected: false,
|
||||
isCustomPushGateway: false,
|
||||
pushGatewayEnabled: false,
|
||||
defaultPushGateway: false,
|
||||
inAlertNotification: false
|
||||
// TODO: This will be used in the near future when the consumption percentage is implemented on the server.
|
||||
// consumptionPercentage: 0,
|
||||
// isCommunityEdition: false,
|
||||
};
|
||||
|
||||
export default (state = initialState, action: TActionTroubleshootingNotification): ITroubleshootingNotification => {
|
||||
|
@ -26,11 +25,6 @@ export default (state = initialState, action: TActionTroubleshootingNotification
|
|||
...state,
|
||||
...action.payload
|
||||
};
|
||||
case TROUBLESHOOTING_NOTIFICATION.SET_IN_ALERT:
|
||||
return {
|
||||
...state,
|
||||
...action.payload
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import { inviteLinksRequest } from '../actions/inviteLinks';
|
|||
import { showErrorAlert } from '../lib/methods/helpers/info';
|
||||
import { localAuthenticate } from '../lib/methods/helpers/localAuthentication';
|
||||
import { encryptionInit, encryptionStop } from '../actions/encryption';
|
||||
import { requestTroubleshootingNotification } from '../actions/troubleshootingNotification';
|
||||
import UserPreferences from '../lib/methods/userPreferences';
|
||||
import { inquiryRequest, inquiryReset } from '../ee/omnichannel/actions/inquiry';
|
||||
import { isOmnichannelStatusAvailable } from '../ee/omnichannel/lib';
|
||||
|
@ -209,6 +210,7 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
|
|||
if (inviteLinkToken) {
|
||||
yield put(inviteLinksRequest(inviteLinkToken));
|
||||
}
|
||||
yield put(requestTroubleshootingNotification());
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
|
|
|
@ -3,34 +3,39 @@ import { put, takeEvery } from 'redux-saga/effects';
|
|||
import { call } from 'typed-redux-saga';
|
||||
import notifee from '@notifee/react-native';
|
||||
|
||||
import { ITroubleshootingNotification } from '../reducers/troubleshootingNotification';
|
||||
import { TROUBLESHOOTING_NOTIFICATION } from '../actions/actionsTypes';
|
||||
import { setInAlertTroubleshootingNotification, setTroubleshootingNotification } from '../actions/troubleshootingNotification';
|
||||
import { appSelector } from '../lib/hooks';
|
||||
import { setTroubleshootingNotification } from '../actions/troubleshootingNotification';
|
||||
import { pushInfo } from '../lib/services/restApi';
|
||||
import log from '../lib/methods/helpers/log';
|
||||
|
||||
interface IGenericAction extends Action {
|
||||
type: string;
|
||||
}
|
||||
|
||||
type TSetGeneric = IGenericAction & {
|
||||
payload: ITroubleshootingNotification;
|
||||
};
|
||||
|
||||
function* request() {
|
||||
const settings = yield* call(notifee.getNotificationSettings);
|
||||
yield put(setTroubleshootingNotification({ deviceNotificationEnabled: !!settings.authorizationStatus }));
|
||||
}
|
||||
|
||||
function* setNotification({ payload }: { payload: ITroubleshootingNotification }) {
|
||||
const troubleshootingNotification = yield* appSelector(state => state.troubleshootingNotification);
|
||||
const newState = { ...troubleshootingNotification, ...payload };
|
||||
// TODO: add properly the conditions to set inAlertNotification bias on each expected settings
|
||||
// For now there is only the deviceNotificationEnabled properly, waiting for the next settings to fix
|
||||
const inAlertNotification = !newState.deviceNotificationEnabled;
|
||||
yield put(setInAlertTroubleshootingNotification({ inAlertNotification }));
|
||||
let deviceNotificationEnabled = false;
|
||||
let defaultPushGateway = false;
|
||||
let pushGatewayEnabled = false;
|
||||
try {
|
||||
const { authorizationStatus } = yield* call(notifee.getNotificationSettings);
|
||||
deviceNotificationEnabled = authorizationStatus > 0;
|
||||
const pushInfoResult = yield* call(pushInfo);
|
||||
if (pushInfoResult.success) {
|
||||
pushGatewayEnabled = pushInfoResult.pushGatewayEnabled;
|
||||
defaultPushGateway = pushInfoResult.defaultPushGateway;
|
||||
}
|
||||
} catch (e) {
|
||||
log(e);
|
||||
} finally {
|
||||
// If Any of the items that can have red values: notification settings, CE quota, or gateway connection; the red icon should show.
|
||||
// Then inAlertNotification has to be true
|
||||
const inAlertNotification = !deviceNotificationEnabled || !pushGatewayEnabled;
|
||||
yield put(
|
||||
setTroubleshootingNotification({ deviceNotificationEnabled, defaultPushGateway, pushGatewayEnabled, inAlertNotification })
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default function* root(): Generator {
|
||||
yield takeEvery<IGenericAction>(TROUBLESHOOTING_NOTIFICATION.REQUEST, request);
|
||||
yield takeEvery<TSetGeneric>(TROUBLESHOOTING_NOTIFICATION.SET, setNotification);
|
||||
}
|
||||
|
|
|
@ -11,10 +11,12 @@ import I18n from '../../i18n';
|
|||
import { SettingsStackParamList } from '../../stacks/types';
|
||||
import { useTheme } from '../../theme';
|
||||
import CustomListSection from './components/CustomListSection';
|
||||
import ListPercentage from './components/ListPercentage';
|
||||
import { isIOS, showErrorAlert } from '../../lib/methods/helpers';
|
||||
import { compareServerVersion, isIOS, showErrorAlert } from '../../lib/methods/helpers';
|
||||
import { requestTroubleshootingNotification } from '../../actions/troubleshootingNotification';
|
||||
import { useAppSelector } from '../../lib/hooks';
|
||||
import { useAppSelector, usePermissions } from '../../lib/hooks';
|
||||
import { Services } from '../../lib/services';
|
||||
// TODO: This will be used in the near future when the consumption percentage is implemented on the server.
|
||||
// import ListPercentage from './components/ListPercentage';
|
||||
|
||||
interface IPushTroubleshootViewProps {
|
||||
navigation: StackNavigationProp<SettingsStackParamList, 'PushTroubleshootView'>;
|
||||
|
@ -24,21 +26,20 @@ const PushTroubleshootView = ({ navigation }: IPushTroubleshootViewProps): JSX.E
|
|||
const { colors } = useTheme();
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const {
|
||||
consumptionPercentage,
|
||||
deviceNotificationEnabled,
|
||||
isCommunityEdition,
|
||||
isCustomPushGateway,
|
||||
isPushGatewayConnected,
|
||||
foreground
|
||||
} = useAppSelector(state => ({
|
||||
deviceNotificationEnabled: state.troubleshootingNotification.deviceNotificationEnabled,
|
||||
isCommunityEdition: state.troubleshootingNotification.isCommunityEdition,
|
||||
isPushGatewayConnected: state.troubleshootingNotification.isPushGatewayConnected,
|
||||
isCustomPushGateway: state.troubleshootingNotification.isCustomPushGateway,
|
||||
consumptionPercentage: state.troubleshootingNotification.consumptionPercentage,
|
||||
foreground: state.app.foreground
|
||||
}));
|
||||
const { deviceNotificationEnabled, defaultPushGateway, pushGatewayEnabled, foreground, serverVersion } = useAppSelector(
|
||||
state => ({
|
||||
deviceNotificationEnabled: state.troubleshootingNotification.deviceNotificationEnabled,
|
||||
pushGatewayEnabled: state.troubleshootingNotification.pushGatewayEnabled,
|
||||
defaultPushGateway: state.troubleshootingNotification.defaultPushGateway,
|
||||
foreground: state.app.foreground,
|
||||
serverVersion: state.server.version
|
||||
// TODO: This will be used in the near future when the consumption percentage is implemented on the server.
|
||||
// isCommunityEdition: state.troubleshootingNotification.isCommunityEdition,
|
||||
// consumptionPercentage: state.troubleshootingNotification.consumptionPercentage,
|
||||
})
|
||||
);
|
||||
|
||||
const [testPushNotificationsPermission] = usePermissions(['test-push-notifications']);
|
||||
|
||||
useEffect(() => {
|
||||
if (foreground) {
|
||||
|
@ -64,9 +65,10 @@ const PushTroubleshootView = ({ navigation }: IPushTroubleshootViewProps): JSX.E
|
|||
);
|
||||
};
|
||||
|
||||
const alertWorkspaceConsumption = () => {
|
||||
Alert.alert(I18n.t('Push_consumption_alert_title'), I18n.t('Push_consumption_alert_description'));
|
||||
};
|
||||
// TODO: This will be used in the near future when the consumption percentage is implemented on the server.
|
||||
// const alertWorkspaceConsumption = () => {
|
||||
// Alert.alert(I18n.t('Push_consumption_alert_title'), I18n.t('Push_consumption_alert_description'));
|
||||
// };
|
||||
|
||||
const goToNotificationSettings = () => {
|
||||
if (isIOS) {
|
||||
|
@ -76,17 +78,25 @@ const PushTroubleshootView = ({ navigation }: IPushTroubleshootViewProps): JSX.E
|
|||
}
|
||||
};
|
||||
|
||||
const handleTestPushNotification = () => {
|
||||
// do nothing
|
||||
const handleTestPushNotification = async () => {
|
||||
let message = '';
|
||||
try {
|
||||
const result = await Services.pushTest();
|
||||
message = I18n.t('Your_push_was_sent_to_s_devices', { s: result.params[0] });
|
||||
} catch (error: any) {
|
||||
message = I18n.isTranslated(error?.error) ? I18n.t(error?.error) : error?.message;
|
||||
} finally {
|
||||
Alert.alert(I18n.t('Test_push_notification'), message);
|
||||
}
|
||||
};
|
||||
|
||||
let pushGatewayInfoDescription = 'Push_gateway_not_connected_description';
|
||||
let pushGatewayStatusColor = colors.userPresenceBusy;
|
||||
if (isPushGatewayConnected) {
|
||||
if (pushGatewayEnabled) {
|
||||
pushGatewayStatusColor = colors.userPresenceOnline;
|
||||
pushGatewayInfoDescription = 'Push_gateway_connected_description';
|
||||
}
|
||||
if (isPushGatewayConnected && isCustomPushGateway) {
|
||||
if (pushGatewayEnabled && !defaultPushGateway) {
|
||||
pushGatewayStatusColor = colors.badgeBackgroundLevel3;
|
||||
pushGatewayInfoDescription = 'Custom_push_gateway_connected_description';
|
||||
}
|
||||
|
@ -108,6 +118,7 @@ const PushTroubleshootView = ({ navigation }: IPushTroubleshootViewProps): JSX.E
|
|||
<List.Separator />
|
||||
</CustomListSection>
|
||||
|
||||
{/* TODO: This will be used in the near future when the consumption percentage is implemented on the server.
|
||||
{isCommunityEdition ? (
|
||||
<List.Section title='Community_edition_push_quota'>
|
||||
<List.Separator />
|
||||
|
@ -120,22 +131,24 @@ const PushTroubleshootView = ({ navigation }: IPushTroubleshootViewProps): JSX.E
|
|||
<List.Separator />
|
||||
<List.Info info='Workspace_consumption_description' />
|
||||
</List.Section>
|
||||
) : null}
|
||||
) : null} */}
|
||||
|
||||
<CustomListSection
|
||||
title={isCustomPushGateway ? 'Custom_push_gateway_connection' : 'Push_gateway_connection'}
|
||||
statusColor={pushGatewayStatusColor}
|
||||
>
|
||||
<List.Separator />
|
||||
<List.Item
|
||||
title='Test_push_notification'
|
||||
disabled={!isPushGatewayConnected}
|
||||
onPress={handleTestPushNotification}
|
||||
testID='push-troubleshoot-view-push-gateway-connection'
|
||||
/>
|
||||
<List.Separator />
|
||||
<List.Info info={pushGatewayInfoDescription} />
|
||||
</CustomListSection>
|
||||
{compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '6.5.0') ? (
|
||||
<CustomListSection
|
||||
title={!defaultPushGateway ? 'Custom_push_gateway_connection' : 'Push_gateway_connection'}
|
||||
statusColor={pushGatewayStatusColor}
|
||||
>
|
||||
<List.Separator />
|
||||
<List.Item
|
||||
title='Test_push_notification'
|
||||
disabled={!pushGatewayEnabled || !testPushNotificationsPermission}
|
||||
onPress={handleTestPushNotification}
|
||||
testID='push-troubleshoot-view-push-gateway-connection'
|
||||
/>
|
||||
<List.Separator />
|
||||
<List.Info info={pushGatewayInfoDescription} />
|
||||
</CustomListSection>
|
||||
) : null}
|
||||
|
||||
<List.Section title='Notification_delay'>
|
||||
<List.Separator />
|
||||
|
|
|
@ -15,7 +15,6 @@ import RoomItem, { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from '../../containers/Roo
|
|||
import log, { logEvent, events } from '../../lib/methods/helpers/log';
|
||||
import I18n from '../../i18n';
|
||||
import { closeSearchHeader, closeServerDropdown, openSearchHeader, roomsRequest } from '../../actions/rooms';
|
||||
import { requestTroubleshootingNotification } from '../../actions/troubleshootingNotification';
|
||||
import * as HeaderButton from '../../containers/HeaderButton';
|
||||
import StatusBar from '../../containers/StatusBar';
|
||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||
|
@ -200,8 +199,6 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
|||
const { navigation, dispatch } = this.props;
|
||||
this.handleHasPermission();
|
||||
this.mounted = true;
|
||||
|
||||
dispatch(requestTroubleshootingNotification());
|
||||
this.unsubscribeFocus = navigation.addListener('focus', () => {
|
||||
this.animated = true;
|
||||
// Check if there were changes with sort preference, then call getSubscription to remount the list
|
||||
|
|
Loading…
Reference in New Issue