Fix issue where messages where not queued for non-selected apps
Summary: When determing whether to queue a message, the logic checked if the plugin is enabled on the currently selected app, rather than checking if it is enabled for the receiving app. This diff fixes that. Reviewed By: passy Differential Revision: D20000055 fbshipit-source-id: 665f0a650dcee8f7f46aa56f399a4f7d0d0aa1e0
This commit is contained in:
committed by
Facebook Github Bot
parent
adce24d343
commit
4aec81b059
@@ -417,7 +417,8 @@ export default connect<StateFromProps, DispatchFromProps, OwnProps, Store>(
|
||||
if (activePlugin && target) {
|
||||
pluginKey = getPluginKey(target.id, activePlugin.id);
|
||||
pluginIsEnabled = pluginIsStarred(
|
||||
{selectedApp, userStarredPlugins},
|
||||
userStarredPlugins,
|
||||
selectedApp,
|
||||
activePlugin.id,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ Object {
|
||||
"androidEmulators": Array [],
|
||||
"clients": Array [
|
||||
Object {
|
||||
"id": "TestApp#Android#unit_test#serial",
|
||||
"id": "TestApp#Android#MockAndroidDevice#serial",
|
||||
"query": Object {
|
||||
"app": "TestApp",
|
||||
"device": "unit_test",
|
||||
"device": "MockAndroidDevice",
|
||||
"device_id": "serial",
|
||||
"os": "Android",
|
||||
},
|
||||
@@ -25,7 +25,7 @@ Object {
|
||||
},
|
||||
],
|
||||
"errors": Array [],
|
||||
"selectedApp": "TestApp#Android#unit_test#serial",
|
||||
"selectedApp": "TestApp#Android#MockAndroidDevice#serial",
|
||||
"selectedDevice": Object {
|
||||
"deviceType": "physical",
|
||||
"logs": Array [],
|
||||
@@ -36,7 +36,7 @@ Object {
|
||||
"selectedPlugin": "TestPlugin",
|
||||
"staticView": null,
|
||||
"uninitializedClients": Array [],
|
||||
"userPreferredApp": "TestApp#Android#unit_test#serial",
|
||||
"userPreferredApp": "TestApp#Android#MockAndroidDevice#serial",
|
||||
"userPreferredDevice": "MockAndroidDevice",
|
||||
"userPreferredPlugin": "TestPlugin",
|
||||
"userStarredPlugins": Object {
|
||||
|
||||
@@ -53,7 +53,7 @@ test('can create a Fake flipper', async () => {
|
||||
sendMessage('inc', {});
|
||||
expect(store.getState().pluginStates).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"TestApp#Android#unit_test#serial#TestPlugin": Object {
|
||||
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Object {
|
||||
"count": 1,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -621,17 +621,14 @@ export function getSelectedPluginKey(state: State): string | undefined {
|
||||
}
|
||||
|
||||
export function pluginIsStarred(
|
||||
state: {
|
||||
selectedApp: string | null;
|
||||
userStarredPlugins: State['userStarredPlugins'];
|
||||
},
|
||||
userStarredPlugins: State['userStarredPlugins'],
|
||||
app: string | null,
|
||||
pluginId: string,
|
||||
): boolean {
|
||||
const {selectedApp} = state;
|
||||
if (!selectedApp) {
|
||||
if (!app) {
|
||||
return false;
|
||||
}
|
||||
const appInfo = deconstructClientId(selectedApp);
|
||||
const starred = state.userStarredPlugins[appInfo.app];
|
||||
const appInfo = deconstructClientId(app);
|
||||
const starred = userStarredPlugins[appInfo.app];
|
||||
return starred && starred.indexOf(pluginId) > -1;
|
||||
}
|
||||
|
||||
@@ -40,63 +40,72 @@ export async function createMockFlipperWithPlugin(
|
||||
device: BaseDevice;
|
||||
store: Store;
|
||||
sendMessage(method: string, params: any): void;
|
||||
createDevice(serial: string): BaseDevice;
|
||||
createClient(device: BaseDevice, name: string): Client;
|
||||
}) => Promise<void>,
|
||||
) {
|
||||
const store = createStore(reducers);
|
||||
const device = new BaseDevice(
|
||||
'serial',
|
||||
'physical',
|
||||
'MockAndroidDevice',
|
||||
'Android',
|
||||
);
|
||||
const logger = createStubLogger();
|
||||
|
||||
store.dispatch(registerPlugins([pluginClazz]));
|
||||
|
||||
store.dispatch({
|
||||
type: 'REGISTER_DEVICE',
|
||||
payload: device,
|
||||
});
|
||||
function createDevice(serial: string): BaseDevice {
|
||||
const device = new BaseDevice(
|
||||
serial,
|
||||
'physical',
|
||||
'MockAndroidDevice',
|
||||
'Android',
|
||||
);
|
||||
store.dispatch({
|
||||
type: 'REGISTER_DEVICE',
|
||||
payload: device,
|
||||
});
|
||||
return device;
|
||||
}
|
||||
|
||||
const query: ClientQuery = {
|
||||
app: 'TestApp',
|
||||
os: 'Android',
|
||||
device: 'unit_test',
|
||||
device_id: device.serial,
|
||||
};
|
||||
const id = buildClientId({
|
||||
app: query.app,
|
||||
os: query.os,
|
||||
device: query.device,
|
||||
device_id: query.device_id,
|
||||
});
|
||||
function createClient(device: BaseDevice, name: string): Client {
|
||||
const query: ClientQuery = {
|
||||
app: name,
|
||||
os: 'Android',
|
||||
device: device.title,
|
||||
device_id: device.serial,
|
||||
};
|
||||
const id = buildClientId({
|
||||
app: query.app,
|
||||
os: query.os,
|
||||
device: query.device,
|
||||
device_id: query.device_id,
|
||||
});
|
||||
|
||||
const client = new Client(
|
||||
id,
|
||||
query,
|
||||
null, // create a stub connection to avoid this plugin to be archived?
|
||||
logger,
|
||||
store,
|
||||
[pluginClazz.id],
|
||||
device,
|
||||
);
|
||||
const client = new Client(
|
||||
id,
|
||||
query,
|
||||
null, // create a stub connection to avoid this plugin to be archived?
|
||||
logger,
|
||||
store,
|
||||
[pluginClazz.id],
|
||||
device,
|
||||
);
|
||||
|
||||
// yikes
|
||||
client._deviceSet = device;
|
||||
client.device = {
|
||||
then() {
|
||||
return device;
|
||||
},
|
||||
} as any;
|
||||
// yikes
|
||||
client._deviceSet = device;
|
||||
client.device = {
|
||||
then() {
|
||||
return device;
|
||||
},
|
||||
} as any;
|
||||
|
||||
// As convenience, by default we select the new client, star the plugin, and select it
|
||||
store.dispatch({
|
||||
type: 'NEW_CLIENT',
|
||||
payload: client,
|
||||
});
|
||||
// As convenience, by default we select the new client, star the plugin, and select it
|
||||
store.dispatch({
|
||||
type: 'NEW_CLIENT',
|
||||
payload: client,
|
||||
});
|
||||
return client;
|
||||
}
|
||||
|
||||
const device = createDevice('serial');
|
||||
const client = createClient(device, 'TestApp');
|
||||
|
||||
store.dispatch(selectDevice(device));
|
||||
|
||||
store.dispatch(selectClient(client.id));
|
||||
|
||||
store.dispatch(
|
||||
@@ -131,5 +140,7 @@ export async function createMockFlipperWithPlugin(
|
||||
}),
|
||||
);
|
||||
},
|
||||
createDevice,
|
||||
createClient,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9,8 +9,13 @@
|
||||
|
||||
import {FlipperPlugin} from '../../plugin';
|
||||
import {createMockFlipperWithPlugin} from '../../test-utils/createMockFlipperWithPlugin';
|
||||
import {GK, Store, Client} from 'flipper';
|
||||
import {selectPlugin, starPlugin} from '../../reducers/connections';
|
||||
import {GK, Store, Client} from '../../';
|
||||
import {
|
||||
selectPlugin,
|
||||
starPlugin,
|
||||
selectClient,
|
||||
selectDevice,
|
||||
} from '../../reducers/connections';
|
||||
import {processMessageQueue} from '../messageQueue';
|
||||
import {getPluginKey} from '../pluginUtils';
|
||||
import {TestIdler} from '../Idler';
|
||||
@@ -87,7 +92,7 @@ test('will process event with GK disabled', async () => {
|
||||
sendMessage('inc', {});
|
||||
expect(store.getState().pluginStates).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"TestApp#Android#unit_test#serial#TestPlugin": Object {
|
||||
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Object {
|
||||
"count": 1,
|
||||
},
|
||||
}
|
||||
@@ -104,12 +109,12 @@ test('queue - events are processed immediately if plugin is selected', async ()
|
||||
expect(store.getState().connections.selectedPlugin).toBe('TestPlugin');
|
||||
sendMessage('inc', {});
|
||||
expect(store.getState().pluginStates).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"TestApp#Android#unit_test#serial#TestPlugin": Object {
|
||||
"count": 1,
|
||||
},
|
||||
}
|
||||
`);
|
||||
Object {
|
||||
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Object {
|
||||
"count": 1,
|
||||
},
|
||||
}
|
||||
`);
|
||||
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(
|
||||
`Object {}`,
|
||||
);
|
||||
@@ -135,7 +140,7 @@ test('queue - events are NOT processed immediately if plugin is NOT selected (bu
|
||||
);
|
||||
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"TestApp#Android#unit_test#serial#TestPlugin": Array [
|
||||
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
||||
Object {
|
||||
"method": "inc",
|
||||
"params": Object {},
|
||||
@@ -193,6 +198,84 @@ test('queue - events are NOT processed immediately if plugin is NOT selected (bu
|
||||
);
|
||||
});
|
||||
|
||||
test('queue - events are queued for plugins that are favorite when app is not selected', async () => {
|
||||
await createMockFlipperWithPlugin(
|
||||
TestPlugin,
|
||||
async ({device, store, sendMessage, createClient}) => {
|
||||
await GK.withWhitelistedGK('flipper_event_queue', async () => {
|
||||
selectDeviceLogs(store);
|
||||
expect(store.getState().connections.selectedPlugin).not.toBe(
|
||||
'TestPlugin',
|
||||
);
|
||||
|
||||
const client2 = createClient(device, 'TestApp2');
|
||||
store.dispatch(selectClient(client2.id));
|
||||
|
||||
// Now we send a message to the second client, it should arrive,
|
||||
// as the plugin was enabled already on the first client as well
|
||||
sendMessage('inc', {delta: 2});
|
||||
expect(store.getState().pluginStates).toMatchInlineSnapshot(
|
||||
`Object {}`,
|
||||
);
|
||||
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(
|
||||
`
|
||||
Object {
|
||||
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
||||
Object {
|
||||
"method": "inc",
|
||||
"params": Object {
|
||||
"delta": 2,
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
`,
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('queue - events are queued for plugins that are favorite when app is selected on different device', async () => {
|
||||
await createMockFlipperWithPlugin(
|
||||
TestPlugin,
|
||||
async ({client, store, sendMessage, createDevice, createClient}) => {
|
||||
await GK.withWhitelistedGK('flipper_event_queue', async () => {
|
||||
selectDeviceLogs(store);
|
||||
expect(store.getState().connections.selectedPlugin).not.toBe(
|
||||
'TestPlugin',
|
||||
);
|
||||
|
||||
const device2 = createDevice('serial2');
|
||||
const client2 = createClient(device2, client.query.app); // same app id
|
||||
store.dispatch(selectDevice(device2));
|
||||
store.dispatch(selectClient(client2.id));
|
||||
|
||||
// Now we send a message to the second client, it should arrive,
|
||||
// as the plugin was enabled already on the first client as well
|
||||
sendMessage('inc', {delta: 2});
|
||||
expect(store.getState().pluginStates).toMatchInlineSnapshot(
|
||||
`Object {}`,
|
||||
);
|
||||
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(
|
||||
`
|
||||
Object {
|
||||
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
||||
Object {
|
||||
"method": "inc",
|
||||
"params": Object {
|
||||
"delta": 2,
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
`,
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('queue - events processing will be paused', async () => {
|
||||
await createMockFlipperWithPlugin(
|
||||
TestPlugin,
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
} from '../reducers/pluginMessageQueue';
|
||||
import {Idler, BaseIdler} from './Idler';
|
||||
import {pluginIsStarred, getSelectedPluginKey} from '../reducers/connections';
|
||||
import {deconstructPluginKey} from './clientUtils';
|
||||
|
||||
const MAX_BACKGROUND_TASK_TIME = 25;
|
||||
|
||||
@@ -180,7 +181,11 @@ export function processMessageLater(
|
||||
break;
|
||||
case isSelected:
|
||||
case plugin instanceof FlipperDevicePlugin:
|
||||
case pluginIsStarred(store.getState().connections, plugin.id):
|
||||
case pluginIsStarred(
|
||||
store.getState().connections.userStarredPlugins,
|
||||
deconstructPluginKey(pluginKey).client,
|
||||
plugin.id,
|
||||
):
|
||||
store.dispatch(
|
||||
queueMessage(
|
||||
pluginKey,
|
||||
|
||||
Reference in New Issue
Block a user