Skip to content

Commit

Permalink
Add poor connection simulation
Browse files Browse the repository at this point in the history
  • Loading branch information
VickyStash committed Dec 6, 2024
1 parent e25e3fa commit 86c486b
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 1 deletion.
10 changes: 10 additions & 0 deletions src/components/TestToolMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ function TestToolMenu({network}: TestToolMenuProps) {
accessibilityLabel="Force offline"
isOn={!!network?.shouldForceOffline}
onToggle={() => Network.setShouldForceOffline(!network?.shouldForceOffline)}
disabled={isUsingImportedState || network?.shouldSimulatePoorConnection}

Check failure on line 77 in src/components/TestToolMenu.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator
/>
</TestToolRow>

{/* When toggled the app will randomly change internet connection every 2-5 seconds */}
<TestToolRow title={translate('initialSettingsPage.troubleshoot.simulatePoorConnection')}>
<Switch
accessibilityLabel="Simulate poor internet connection"
isOn={!!network?.shouldSimulatePoorConnection}
onToggle={() => Network.simulatePoorConnection(!network?.shouldSimulatePoorConnection, network?.poorConnectionTimeoutID)}
disabled={isUsingImportedState}
/>
</TestToolRow>
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,7 @@ const translations = {
testingPreferences: 'Testing preferences',
useStagingServer: 'Use Staging Server',
forceOffline: 'Force offline',
simulatePoorConnection: 'Simulate poor internet connection',
simulatFailingNetworkRequests: 'Simulate failing network requests',
authenticationStatus: 'Authentication status',
deviceCredentials: 'Device credentials',
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,7 @@ const translations = {
testingPreferences: 'Preferencias para Tests',
useStagingServer: 'Usar servidor “staging”',
forceOffline: 'Forzar desconexión',
simulatePoorConnection: 'Simular una conexión a internet deficiente',
simulatFailingNetworkRequests: 'Simular fallos en solicitudes de red',
authenticationStatus: 'Estado de autenticación',
deviceCredentials: 'Credenciales del dispositivo',
Expand Down
55 changes: 54 additions & 1 deletion src/libs/actions/Network.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
import Onyx from 'react-native-onyx';
import Log from '@libs/Log';
import type {NetworkStatus} from '@libs/NetworkConnection';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';

let isPoorConnectionSimulated: boolean | undefined;
Onyx.connect({
key: ONYXKEYS.NETWORK,
callback: (value) => {
if (!value) {
return;
}

// Starts random network status change when shouldSimulatePoorConnection is turned into true
// or after app restart if shouldSimulatePoorConnection is true already
if (!isPoorConnectionSimulated && !!value.shouldSimulatePoorConnection) {
clearTimeout(value.poorConnectionTimeoutID);
setRandomNetworkStatus(true);
}

isPoorConnectionSimulated = !!value.shouldSimulatePoorConnection;
},
});

function setIsOffline(isOffline: boolean, reason = '') {
if (reason) {
let textToLog = '[Network] Client is';
Expand Down Expand Up @@ -32,4 +52,37 @@ function setShouldFailAllRequests(shouldFailAllRequests: boolean) {
Onyx.merge(ONYXKEYS.NETWORK, {shouldFailAllRequests});
}

export {setIsOffline, setShouldForceOffline, setShouldFailAllRequests, setTimeSkew, setNetWorkStatus};
function setPoorConnectionTimeoutID(poorConnectionTimeoutID: NodeJS.Timeout | undefined) {
Onyx.merge(ONYXKEYS.NETWORK, {poorConnectionTimeoutID});
}

function setRandomNetworkStatus(initialCall = false) {
// The check to ensure no new timeouts are scheduled after poor connection simulation is stopped
if (!isPoorConnectionSimulated && !initialCall) {
setShouldForceOffline(false);
return;
}

const statuses = [CONST.NETWORK.NETWORK_STATUS.OFFLINE, CONST.NETWORK.NETWORK_STATUS.ONLINE];
const randomStatus = statuses[Math.floor(Math.random() * statuses.length)];
const randomInterval = Math.random() * (5000 - 2000) + 2000; // random interval between 2-5 seconds
Log.info(`[NetworkConnection] Set connection status "${randomStatus}" for ${randomInterval} sec`);

setShouldForceOffline(randomStatus === CONST.NETWORK.NETWORK_STATUS.OFFLINE);

const timeoutID = setTimeout(setRandomNetworkStatus, randomInterval);

setPoorConnectionTimeoutID(timeoutID);
}

function simulatePoorConnection(shouldSimulatePoorConnection: boolean, poorConnectionTimeoutID: NodeJS.Timeout | undefined) {
if (!shouldSimulatePoorConnection) {
clearTimeout(poorConnectionTimeoutID);
setPoorConnectionTimeoutID(undefined);
setShouldForceOffline(false);
}

Onyx.merge(ONYXKEYS.NETWORK, {shouldSimulatePoorConnection});
}

export {setIsOffline, setShouldForceOffline, setShouldFailAllRequests, setTimeSkew, setNetWorkStatus, simulatePoorConnection};
6 changes: 6 additions & 0 deletions src/types/onyx/Network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ type Network = {
/** Should the network be forced offline */
shouldForceOffline?: boolean;

/** Whether we should simulate poor connection */
shouldSimulatePoorConnection?: boolean;

/** Poor connection timeout id */
poorConnectionTimeoutID?: NodeJS.Timeout;

/** Whether we should fail all network requests */
shouldFailAllRequests?: boolean;

Expand Down

0 comments on commit 86c486b

Please sign in to comment.