Added test cases for flipper import and export
Summary: Adds tests for flipper import and export. Also fixed few edge cases which was discovered through tests. The edge case was that it didn't export device plugin states. Reviewed By: danielbuechele Differential Revision: D13828357 fbshipit-source-id: ddc4352b729ca7f05c5875f2f3fbdd2c7f4e2186
This commit is contained in:
committed by
Facebook Github Bot
parent
5ef970e5b5
commit
cbd70f573c
@@ -4,6 +4,15 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
* @format
|
||||
*/
|
||||
import type {Store} from '../reducers';
|
||||
import type {DeviceExport} from '../devices/BaseDevice';
|
||||
import type {State as PluginStates} from '../reducers/pluginStates';
|
||||
import type {PluginNotification} from '../reducers/notifications.js';
|
||||
import type {ClientExport} from '../Client.js';
|
||||
import type {State as PluginStatesState} from '../reducers/pluginStates';
|
||||
import {FlipperDevicePlugin} from '../plugin.js';
|
||||
import {default as BaseDevice} from '../devices/BaseDevice';
|
||||
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
@@ -14,54 +23,117 @@ const exportFilePath = path.join(
|
||||
'FlipperExport.json',
|
||||
);
|
||||
|
||||
export const exportStoreToFile = (data: Store): Promise<void> => {
|
||||
const state = data.getState();
|
||||
const json = {
|
||||
fileVersion: '1.0.0',
|
||||
device: {},
|
||||
clients: [],
|
||||
store: {
|
||||
pluginStates: {},
|
||||
activeNotifications: [],
|
||||
},
|
||||
};
|
||||
export type ExportType = {|
|
||||
fileVersion: '1.0.0',
|
||||
clients: Array<ClientExport>,
|
||||
device: ?DeviceExport,
|
||||
store: {
|
||||
pluginStates: PluginStates,
|
||||
activeNotifications: Array<PluginNotification>,
|
||||
},
|
||||
|};
|
||||
|
||||
const device = state.connections.selectedDevice;
|
||||
export function processClients(
|
||||
clients: Array<ClientExport>,
|
||||
serial: string,
|
||||
): Array<ClientExport> {
|
||||
return clients.filter(client => client.query.device_id === serial);
|
||||
}
|
||||
|
||||
export function processPluginStates(
|
||||
clients: Array<ClientExport>,
|
||||
serial: string,
|
||||
allPluginStates: PluginStatesState,
|
||||
devicePlugins: Map<string, Class<FlipperDevicePlugin<>>>,
|
||||
): PluginStatesState {
|
||||
let pluginStates = {};
|
||||
for (let key in allPluginStates) {
|
||||
let keyArray = key.split('#');
|
||||
const pluginName = keyArray.pop();
|
||||
const filteredClients = clients.filter(client => {
|
||||
// Remove the last entry related to plugin
|
||||
return client.id.includes(keyArray.join('#'));
|
||||
});
|
||||
if (
|
||||
filteredClients.length > 0 ||
|
||||
(devicePlugins.has(pluginName) && serial === keyArray[0])
|
||||
) {
|
||||
// There need not be any client for device Plugins
|
||||
pluginStates = {...pluginStates, [key]: allPluginStates[key]};
|
||||
}
|
||||
}
|
||||
return pluginStates;
|
||||
}
|
||||
|
||||
export function processNotificationStates(
|
||||
clients: Array<ClientExport>,
|
||||
serial: string,
|
||||
allActiveNotifications: Array<PluginNotification>,
|
||||
devicePlugins: Map<string, Class<FlipperDevicePlugin<>>>,
|
||||
): Array<PluginNotification> {
|
||||
let activeNotifications = allActiveNotifications.filter(notif => {
|
||||
const filteredClients = clients.filter(
|
||||
client => (notif.client ? client.id.includes(notif.client) : false),
|
||||
);
|
||||
return (
|
||||
filteredClients.length > 0 ||
|
||||
(devicePlugins.has(notif.pluginId) && serial === notif.client)
|
||||
); // There need not be any client for device Plugins
|
||||
});
|
||||
return activeNotifications;
|
||||
}
|
||||
|
||||
export const processStore = (
|
||||
activeNotifications: Array<PluginNotification>,
|
||||
device: ?BaseDevice,
|
||||
pluginStates: PluginStatesState,
|
||||
clients: Array<ClientExport>,
|
||||
devicePlugins: Map<string, Class<FlipperDevicePlugin<>>>,
|
||||
): ?ExportType => {
|
||||
if (device) {
|
||||
const {serial} = device;
|
||||
json.device = device.toJSON();
|
||||
const clients = state.connections.clients
|
||||
.filter(client => {
|
||||
return client.query.device_id === serial;
|
||||
})
|
||||
.map(client => {
|
||||
return client.toJSON();
|
||||
});
|
||||
const processedClients = processClients(clients, serial);
|
||||
let processedPluginStates = processPluginStates(
|
||||
processedClients,
|
||||
serial,
|
||||
pluginStates,
|
||||
devicePlugins,
|
||||
);
|
||||
const processedActiveNotifications = processNotificationStates(
|
||||
processedClients,
|
||||
serial,
|
||||
activeNotifications,
|
||||
devicePlugins,
|
||||
);
|
||||
return {
|
||||
fileVersion: '1.0.0',
|
||||
clients: processedClients,
|
||||
device: device.toJSON(),
|
||||
store: {
|
||||
pluginStates: processedPluginStates,
|
||||
activeNotifications: processedActiveNotifications,
|
||||
},
|
||||
};
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
json.clients = clients;
|
||||
|
||||
const allPluginStates = state.pluginStates;
|
||||
let pluginStates = {};
|
||||
for (let key in allPluginStates) {
|
||||
const filteredClients = clients.filter(client => {
|
||||
let keyArray = key.split('#');
|
||||
keyArray.pop(); // Remove the last entry related to plugin
|
||||
return client.id.includes(keyArray.join('#'));
|
||||
});
|
||||
if (filteredClients.length > 0) {
|
||||
pluginStates = {...pluginStates, [key]: allPluginStates[key]};
|
||||
json.store.pluginStates = pluginStates;
|
||||
}
|
||||
}
|
||||
|
||||
const allActiveNotifications = state.notifications.activeNotifications;
|
||||
let activeNotifications = allActiveNotifications.filter(notif => {
|
||||
const filteredClients = clients.filter(client =>
|
||||
client.id.includes(notif.client),
|
||||
);
|
||||
return filteredClients.length > 0;
|
||||
});
|
||||
json.store.activeNotifications = activeNotifications;
|
||||
export const exportStoreToFile = (data: Store): Promise<void> => {
|
||||
const state = data.getState();
|
||||
const {activeNotifications} = state.notifications;
|
||||
const {selectedDevice, clients} = state.connections;
|
||||
const {pluginStates} = state;
|
||||
const {devicePlugins} = state.plugins;
|
||||
// TODO: T39612653 Make Client mockable. Currently rsocket logic is tightly coupled.
|
||||
// Not passing the entire state as currently Client is not mockable.
|
||||
const json = processStore(
|
||||
activeNotifications,
|
||||
selectedDevice,
|
||||
pluginStates,
|
||||
clients.map(client => client.toJSON()),
|
||||
devicePlugins,
|
||||
);
|
||||
if (json) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.writeFile(exportFilePath, JSON.stringify(json), err => {
|
||||
if (err) {
|
||||
|
||||
Reference in New Issue
Block a user