mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-18 09:35:20 +02:00
142 lines
4.6 KiB
TypeScript
142 lines
4.6 KiB
TypeScript
import * as React from 'react';
|
|
import RepositoryApi from '@joplin/lib/services/plugins/RepositoryApi';
|
|
import { afterAllCleanUp, afterEachCleanUp, createTempDir, mockMobilePlatform, setupDatabaseAndSynchronizer, supportDir, switchClient } from '@joplin/lib/testing/test-utils';
|
|
|
|
import { render, screen, waitFor } from '@testing-library/react-native';
|
|
import '@testing-library/react-native/extend-expect';
|
|
|
|
import Setting from '@joplin/lib/models/Setting';
|
|
import PluginService, { PluginSettings, defaultPluginSetting } from '@joplin/lib/services/plugins/PluginService';
|
|
import { useCallback, useState } from 'react';
|
|
import pluginServiceSetup from './testUtils/pluginServiceSetup';
|
|
import PluginStates from './PluginStates';
|
|
import configScreenStyles from '../configScreenStyles';
|
|
import { remove, writeFile } from 'fs-extra';
|
|
import { join } from 'path';
|
|
import shim from '@joplin/lib/shim';
|
|
import { resetRepoApi } from './utils/useRepoApi';
|
|
|
|
interface WrapperProps {
|
|
initialPluginSettings: PluginSettings;
|
|
}
|
|
|
|
const shouldShowBasedOnSettingSearchQuery = ()=>true;
|
|
const PluginStatesWrapper = (props: WrapperProps) => {
|
|
const styles = configScreenStyles(Setting.THEME_LIGHT);
|
|
|
|
const [pluginStates, setPluginStates] = useState(() => {
|
|
return PluginService.instance().serializePluginSettings(props.initialPluginSettings ?? {});
|
|
});
|
|
|
|
const updatePluginStates = useCallback((newStates: PluginSettings) => {
|
|
const serialized = PluginService.instance().serializePluginSettings(newStates);
|
|
setPluginStates(serialized);
|
|
}, []);
|
|
|
|
return (
|
|
<PluginStates
|
|
themeId={Setting.THEME_LIGHT}
|
|
styles={styles}
|
|
updatePluginStates={updatePluginStates}
|
|
pluginSettings={pluginStates}
|
|
shouldShowBasedOnSearchQuery={shouldShowBasedOnSettingSearchQuery}
|
|
/>
|
|
);
|
|
};
|
|
|
|
let repoTempDir: string|null = null;
|
|
const mockRepositoryApiConstructor = async () => {
|
|
if (repoTempDir) {
|
|
await remove(repoTempDir);
|
|
}
|
|
repoTempDir = await createTempDir();
|
|
|
|
RepositoryApi.ofDefaultJoplinRepo = jest.fn((_tempDirPath: string, installMode) => {
|
|
return new RepositoryApi(`${supportDir}/pluginRepo`, repoTempDir, installMode);
|
|
});
|
|
};
|
|
|
|
const loadMockPlugin = async (id: string, name: string, version: string, pluginSettings: PluginSettings) => {
|
|
const service = PluginService.instance();
|
|
const pluginSource = `
|
|
/* joplin-manifest:
|
|
${JSON.stringify({
|
|
id,
|
|
manifest_version: 1,
|
|
app_min_version: '1.4',
|
|
name,
|
|
description: 'Test plugin',
|
|
version,
|
|
homepage_url: 'https://joplinapp.org',
|
|
})}
|
|
*/
|
|
|
|
joplin.plugins.register({
|
|
onStart: async function() { },
|
|
});
|
|
`;
|
|
const pluginPath = join(await createTempDir(), 'plugin.js');
|
|
await writeFile(pluginPath, pluginSource, 'utf-8');
|
|
await service.loadAndRunPlugins([pluginPath], pluginSettings);
|
|
};
|
|
|
|
describe('PluginStates', () => {
|
|
beforeEach(async () => {
|
|
await setupDatabaseAndSynchronizer(0);
|
|
await switchClient(0);
|
|
pluginServiceSetup();
|
|
resetRepoApi();
|
|
});
|
|
afterEach(async () => {
|
|
for (const pluginId of PluginService.instance().pluginIds) {
|
|
await PluginService.instance().unloadPlugin(pluginId);
|
|
}
|
|
await afterEachCleanUp();
|
|
});
|
|
afterAll(() => afterAllCleanUp());
|
|
|
|
it.each([
|
|
'android',
|
|
'ios',
|
|
])('should not allow updating a plugin that is not recommended on iOS, but should on Android (on %s)', async (platform) => {
|
|
await mockMobilePlatform(platform);
|
|
expect(shim.mobilePlatform()).toBe(platform);
|
|
await mockRepositoryApiConstructor();
|
|
|
|
const abcPluginId = 'org.joplinapp.plugins.AbcSheetMusic';
|
|
const backlinksPluginId = 'joplin.plugin.ambrt.backlinksToNote';
|
|
|
|
const defaultPluginSettings: PluginSettings = {
|
|
[abcPluginId]: defaultPluginSetting(),
|
|
[backlinksPluginId]: defaultPluginSetting(),
|
|
};
|
|
|
|
// Load an outdated recommended plugin
|
|
await loadMockPlugin(abcPluginId, 'ABC Sheet Music', '0.0.1', defaultPluginSettings);
|
|
expect(PluginService.instance().plugins[abcPluginId]).toBeTruthy();
|
|
|
|
// Load a plugin not marked as recommended
|
|
await loadMockPlugin(backlinksPluginId, 'Backlinks to note', '0.0.1', defaultPluginSettings);
|
|
expect(PluginService.instance().plugins[backlinksPluginId]).toBeTruthy();
|
|
|
|
render(
|
|
<PluginStatesWrapper
|
|
initialPluginSettings={defaultPluginSettings}
|
|
/>,
|
|
);
|
|
expect(await screen.findByText('ABC Sheet Music')).not.toBeNull();
|
|
expect(await screen.findByText('Backlinks to note')).not.toBeNull();
|
|
|
|
const shouldBothBeUpdatable = platform === 'android';
|
|
await waitFor(async () => {
|
|
const updateButtons = await screen.findAllByText('Update');
|
|
expect(updateButtons).toHaveLength(shouldBothBeUpdatable ? 2 : 1);
|
|
});
|
|
|
|
const updateButtons = await screen.findAllByText('Update');
|
|
for (const button of updateButtons) {
|
|
expect(button).not.toBeDisabled();
|
|
}
|
|
});
|
|
});
|