@rancher/shell 3.0.12-rc.2 → 3.0.12-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apis/impl/apis.ts +6 -0
- package/apis/index.ts +26 -0
- package/apis/intf/resources-api/cluster-api.ts +18 -0
- package/apis/intf/resources-api/mgmt-api.ts +15 -0
- package/apis/intf/resources-api/resource-base.ts +107 -0
- package/apis/intf/resources-api/resource-constants.ts +147 -0
- package/apis/intf/resources-api/resources-api.ts +143 -0
- package/apis/intf/resources.ts +49 -0
- package/apis/intf/{modal.ts → shell-api/modal.ts} +21 -26
- package/apis/intf/shell-api/proxy.ts +216 -0
- package/apis/intf/{slide-in.ts → shell-api/slide-in.ts} +4 -3
- package/apis/intf/{system.ts → shell-api/system.ts} +4 -1
- package/apis/intf/shell.ts +12 -6
- package/apis/resources/__tests__/resources-api-class.test.ts +550 -0
- package/apis/resources/index.ts +22 -0
- package/apis/resources/resources-api-class.ts +187 -0
- package/apis/shell/__tests__/proxy.test.ts +369 -0
- package/apis/shell/index.ts +8 -1
- package/apis/shell/modal.ts +4 -1
- package/apis/shell/notifications.ts +9 -6
- package/apis/shell/proxy.ts +256 -0
- package/apis/shell/slide-in.ts +4 -1
- package/apis/vue-shim.d.ts +2 -1
- package/assets/data/aws-regions.json +4 -0
- package/assets/fonts/lato/LatoLatin-Black.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Black.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-BlackItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-BlackItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Bold.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Bold.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-BoldItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-BoldItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Heavy.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Heavy.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-HeavyItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-HeavyItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Italic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Italic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Light.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Light.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-LightItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-LightItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Medium.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Medium.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-MediumItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-MediumItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Regular.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Regular.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Semibold.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Semibold.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff2 +0 -0
- package/assets/styles/base/_variables.scss +2 -0
- package/assets/styles/fonts/_fontstack.scss +132 -8
- package/assets/translations/en-us.yaml +22 -5
- package/chart/monitoring/index.vue +10 -1
- package/components/ActionDropdownShell.vue +2 -1
- package/components/CruResourceFooter.vue +9 -5
- package/components/ExplorerProjectsNamespaces.vue +1 -1
- package/components/InstallHelmCharts.vue +2 -2
- package/components/LandingPagePreference.vue +14 -5
- package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +15 -1
- package/components/Resource/Detail/Metadata/index.vue +6 -0
- package/components/Resource/Detail/ResourcePopover/index.vue +12 -1
- package/components/Resource/Detail/SpacedRow.vue +3 -1
- package/components/Resource/Detail/TitleBar/index.vue +10 -11
- package/components/ResourceList/Masthead.vue +12 -8
- package/components/SelectIconGrid.vue +0 -10
- package/components/SingleClusterInfo.vue +1 -0
- package/components/SortableTable/__tests__/sorting.test.ts +126 -0
- package/components/SortableTable/index.vue +6 -9
- package/components/SortableTable/selection.js +23 -5
- package/components/SortableTable/sorting.js +6 -3
- package/components/Wizard.vue +14 -13
- package/components/fleet/FleetBundles.vue +100 -12
- package/components/fleet/FleetClusterTargets/index.vue +37 -15
- package/components/fleet/__tests__/FleetClusterTargets.test.ts +149 -115
- package/components/fleet/__tests__/FleetClusters.test.ts +12 -12
- package/components/form/LabeledSelect.vue +20 -3
- package/components/form/NameNsDescription.vue +11 -0
- package/components/form/Security.vue +6 -2
- package/components/form/WorkloadPorts.vue +2 -7
- package/components/form/__tests__/Security.test.ts +76 -0
- package/components/formatter/Autoscaler.vue +4 -4
- package/components/formatter/ClusterKubeVersion.vue +27 -0
- package/components/formatter/ClusterLink.vue +1 -7
- package/components/formatter/ClusterProvider.vue +6 -10
- package/components/formatter/FleetSummaryGraph.vue +0 -3
- package/components/formatter/MachineSummaryGraph.vue +1 -1
- package/components/formatter/PodsUsage.vue +2 -2
- package/components/formatter/__tests__/Autoscaler.test.ts +19 -22
- package/components/formatter/__tests__/FleetSummaryGraph.test.ts +216 -0
- package/components/formatter/__tests__/PodsUsage.test.ts +6 -10
- package/components/nav/NamespaceFilter.vue +2 -2
- package/components/nav/TopLevelMenu.helper.ts +15 -3
- package/components/nav/TopLevelMenu.vue +16 -5
- package/components/nav/__tests__/TopLevelMenu.test.ts +145 -21
- package/components/templates/home.vue +18 -0
- package/components/templates/plain.vue +18 -0
- package/components/templates/standalone.vue +17 -0
- package/composables/useFormValidation.ts +93 -0
- package/composables/useVeeValidateField.test.ts +159 -0
- package/composables/useVeeValidateField.ts +67 -0
- package/config/pagination-table-headers.js +18 -1
- package/config/product/manager.js +82 -21
- package/config/router/routes.js +6 -0
- package/config/table-headers.js +20 -1
- package/config/types.js +2 -1
- package/core/__tests__/plugin-products.test.ts +904 -20
- package/core/plugin-products-base.ts +107 -7
- package/core/plugin-products.ts +4 -0
- package/core/plugin-types.ts +111 -1
- package/core/plugin.ts +15 -7
- package/core/productDebugger.js +9 -4
- package/core/types-provisioning.ts +43 -30
- package/core/types.ts +57 -20
- package/detail/__tests__/pod.test.ts +41 -0
- package/detail/harvesterhci.io.management.cluster.vue +6 -2
- package/detail/pod.vue +1 -1
- package/detail/provisioning.cattle.io.cluster.vue +4 -10
- package/edit/auth/__tests__/azuread.test.ts +217 -34
- package/edit/auth/azuread.vue +122 -14
- package/edit/auth/oidc.vue +2 -2
- package/edit/networking.k8s.io.ingress/DefaultBackend.vue +13 -4
- package/edit/networking.k8s.io.ingress/RulePath.vue +8 -4
- package/edit/networking.k8s.io.ingress/index.vue +75 -20
- package/edit/provisioning.cattle.io.cluster/__tests__/MachinePool.test.ts +104 -0
- package/edit/provisioning.cattle.io.cluster/index.vue +11 -7
- package/edit/provisioning.cattle.io.cluster/rke2.vue +8 -4
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +11 -0
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +37 -4
- package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +132 -7
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +2 -1
- package/edit/secret/__tests__/ssh.test.ts +5 -6
- package/edit/secret/basic.vue +31 -0
- package/edit/secret/index.vue +68 -17
- package/edit/secret/registry.vue +38 -0
- package/edit/secret/ssh.vue +29 -0
- package/edit/secret/tls.vue +30 -0
- package/edit/service.vue +4 -4
- package/edit/workload/Upgrading.vue +3 -3
- package/edit/workload/__tests__/Upgrading.test.ts +6 -9
- package/edit/workload/mixins/workload.js +2 -1
- package/list/fleet.cattle.io.bundle.vue +7 -104
- package/list/fleet.cattle.io.clusterregistrationtoken.vue +20 -0
- package/list/provisioning.cattle.io.cluster.vue +262 -180
- package/list/utils/management.cattle.io.cluster.utils.ts +128 -0
- package/mixins/__tests__/chart.test.ts +112 -0
- package/mixins/brand.js +2 -1
- package/mixins/chart.js +12 -8
- package/mixins/resource-fetch-api-pagination.js +41 -5
- package/models/__tests__/ext.cattle.io.kubeconfig.test.ts +67 -67
- package/models/__tests__/management.cattle.io.cluster.test.ts +1 -1
- package/models/__tests__/management.cattle.io.node.ts +6 -5
- package/models/__tests__/management.cattle.io.nodepool.ts +5 -4
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +32 -11
- package/models/base-cluster.x-k8s.io.js +26 -0
- package/models/cluster.js +1 -1
- package/models/cluster.x-k8s.io.machine.js +4 -22
- package/models/cluster.x-k8s.io.machinedeployment.js +2 -20
- package/models/cluster.x-k8s.io.machineset.js +2 -20
- package/models/compliance.cattle.io.clusterscan.js +130 -2
- package/models/ext.cattle.io.kubeconfig.ts +4 -7
- package/models/fleet-application.js +3 -1
- package/models/management.cattle.io.cluster.js +417 -40
- package/models/management.cattle.io.node.js +6 -4
- package/models/management.cattle.io.nodepool.js +1 -1
- package/models/networking.k8s.io.ingress.js +12 -4
- package/models/provisioning.cattle.io.cluster.js +47 -330
- package/models/rke.cattle.io.etcdsnapshot.js +1 -2
- package/package.json +11 -29
- package/pages/__tests__/readme.test.ts +49 -0
- package/pages/auth/setup.vue +2 -3
- package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +76 -0
- package/pages/c/_cluster/apps/charts/chart.vue +60 -8
- package/pages/c/_cluster/apps/charts/install.vue +10 -7
- package/pages/c/_cluster/explorer/__tests__/index.test.ts +23 -25
- package/pages/c/_cluster/explorer/index.vue +5 -49
- package/pages/c/_cluster/istio/__tests__/istio.index.test.ts +194 -0
- package/pages/c/_cluster/istio/index.vue +21 -6
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -0
- package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +719 -2
- package/pages/c/_cluster/uiplugins/index.vue +203 -197
- package/pages/diagnostic.vue +13 -17
- package/pages/fail-whale.vue +18 -0
- package/pages/home.vue +77 -260
- package/pages/readme.vue +88 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +88 -0
- package/plugins/dashboard-store/actions.js +40 -18
- package/plugins/dashboard-store/resource-class.js +5 -2
- package/plugins/steve/__tests__/subscribe.spec.ts +6 -3
- package/plugins/steve/steve-pagination-utils.ts +11 -3
- package/plugins/steve/subscribe.js +35 -5
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +10 -4
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +7 -52
- package/rancher-components/RcButton/RcButton.test.ts +37 -1
- package/rancher-components/RcButton/RcButton.vue +38 -8
- package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -8
- package/store/__tests__/catalog.test.ts +115 -1
- package/store/__tests__/type-map.test.ts +556 -1
- package/store/action-menu.js +8 -3
- package/store/auth.js +1 -1
- package/store/aws.js +27 -16
- package/store/catalog.js +27 -3
- package/store/digitalocean.js +20 -38
- package/store/index.js +2 -0
- package/store/linode.js +25 -40
- package/store/pnap.js +1 -0
- package/store/type-map.js +111 -29
- package/tsconfig.paths.json +8 -8
- package/types/kube/kube-api.ts +14 -1
- package/types/rancher/steve.api.ts +12 -12
- package/types/resources/settings.d.ts +2 -1
- package/types/shell/index.d.ts +102 -2
- package/types/store/dashboard-store.types.ts +108 -11
- package/types/store/pagination.types.ts +6 -3
- package/utils/__tests__/alertmanagerconfig.test.ts +117 -0
- package/utils/__tests__/async.test.ts +87 -0
- package/utils/__tests__/aws.test.ts +140 -0
- package/utils/__tests__/banners.test.ts +176 -0
- package/utils/__tests__/chart.test.ts +64 -1
- package/utils/__tests__/color.test.ts +226 -0
- package/utils/__tests__/duration.test.ts +140 -0
- package/utils/__tests__/fleet.test.ts +340 -0
- package/utils/__tests__/ingress.test.ts +553 -0
- package/utils/__tests__/kube.test.ts +68 -0
- package/utils/__tests__/namespace-filter.test.ts +109 -0
- package/utils/__tests__/pagination-utils.test.ts +361 -0
- package/utils/__tests__/parse-externalid.test.ts +137 -0
- package/utils/__tests__/perf-setting.utils.test.ts +98 -0
- package/utils/__tests__/poller-sequential.test.ts +177 -0
- package/utils/__tests__/poller.test.ts +170 -0
- package/utils/__tests__/promise.test.ts +346 -0
- package/utils/__tests__/settings.test.ts +140 -0
- package/utils/__tests__/sort-utils.test.ts +301 -0
- package/utils/__tests__/string-utils.test.ts +798 -0
- package/utils/__tests__/string.test.ts +23 -1
- package/utils/__tests__/style.test.ts +154 -0
- package/utils/__tests__/svg-filter.test.ts +184 -0
- package/utils/__tests__/units.test.ts +417 -0
- package/utils/__tests__/versions.test.ts +128 -0
- package/utils/__tests__/xccdf.test.ts +391 -0
- package/utils/chart.js +36 -0
- package/utils/fleet.ts +13 -3
- package/utils/gatekeeper/__tests__/util.test.ts +174 -0
- package/utils/gc/__tests__/gc-interval.test.ts +119 -0
- package/utils/gc/__tests__/gc-root-store.test.ts +225 -0
- package/utils/gc/__tests__/gc-route-changed.test.ts +96 -0
- package/utils/gc/__tests__/gc.test.ts +487 -0
- package/utils/ingress.ts +9 -1
- package/utils/pagination-utils.ts +2 -1
- package/utils/string.js +25 -2
- package/utils/uiplugins.ts +5 -5
- package/utils/validators/__tests__/cluster-name.test.ts +110 -0
- package/utils/validators/__tests__/cron-schedule.test.ts +79 -0
- package/utils/validators/__tests__/index.test.ts +481 -0
- package/utils/validators/__tests__/kubernetes-name.test.ts +163 -0
- package/utils/validators/__tests__/misc-validators.test.ts +246 -0
- package/utils/validators/__tests__/pod-affinity.test.ts +382 -0
- package/utils/validators/__tests__/prometheusrule.test.ts +211 -0
- package/utils/validators/__tests__/role-template.test.ts +149 -0
- package/utils/validators/__tests__/service.test.ts +283 -0
- package/utils/validators/__tests__/setting.test.js +32 -0
- package/utils/validators/formRules/__tests__/index.test.ts +50 -0
- package/utils/validators/formRules/index.ts +5 -5
- package/utils/validators/machine-pool.ts +1 -1
- package/utils/validators/setting.js +18 -3
- package/utils/xccdf.ts +418 -0
- package/assets/fonts/lato/lato-v17-latin-700.woff +0 -0
- package/assets/fonts/lato/lato-v17-latin-700.woff2 +0 -0
- package/assets/fonts/lato/lato-v17-latin-regular.woff +0 -0
- package/assets/fonts/lato/lato-v17-latin-regular.woff2 +0 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import perfSettingUtils from '@shell/utils/perf-setting.utils';
|
|
2
|
+
import { PerfSettings } from '@shell/config/settings';
|
|
3
|
+
|
|
4
|
+
const makePerfSettings = (incrementalLoading: boolean, manualRefresh: boolean): PerfSettings => ({
|
|
5
|
+
inactivity: { enabled: false, threshold: 0 },
|
|
6
|
+
incrementalLoading: { enabled: incrementalLoading, threshold: 0 },
|
|
7
|
+
manualRefresh: { enabled: manualRefresh, threshold: 0 },
|
|
8
|
+
disableWebsocketNotification: false,
|
|
9
|
+
garbageCollection: {} as any,
|
|
10
|
+
forceNsFilterV2: null,
|
|
11
|
+
advancedWorker: {},
|
|
12
|
+
kubeAPI: { warningHeader: { separator: '', notificationBlockList: [] } },
|
|
13
|
+
serverPagination: {} as any,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('perf-setting.utils', () => {
|
|
17
|
+
describe('incrementalLoadingUtils.isEnabled', () => {
|
|
18
|
+
it.each([
|
|
19
|
+
{
|
|
20
|
+
desc: 'SSP disabled, performance setting enabled → enabled',
|
|
21
|
+
paginationEnabled: false,
|
|
22
|
+
perfEnabled: true,
|
|
23
|
+
expected: true,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
desc: 'SSP disabled, performance setting disabled → disabled',
|
|
27
|
+
paginationEnabled: false,
|
|
28
|
+
perfEnabled: false,
|
|
29
|
+
expected: false,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
desc: 'SSP enabled takes precedence even if performance setting enabled → disabled',
|
|
33
|
+
paginationEnabled: true,
|
|
34
|
+
perfEnabled: true,
|
|
35
|
+
expected: false,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
desc: 'SSP enabled, performance setting disabled → disabled',
|
|
39
|
+
paginationEnabled: true,
|
|
40
|
+
perfEnabled: false,
|
|
41
|
+
expected: false,
|
|
42
|
+
},
|
|
43
|
+
])('$desc', ({ paginationEnabled, perfEnabled, expected }) => {
|
|
44
|
+
const settings = makePerfSettings(perfEnabled, false);
|
|
45
|
+
|
|
46
|
+
expect(perfSettingUtils.incrementalLoadingUtils.isEnabled(paginationEnabled, settings)).toStrictEqual(expected);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('manualRefreshUtils.isEnabled', () => {
|
|
51
|
+
it.each([
|
|
52
|
+
{
|
|
53
|
+
desc: 'SSP disabled, performance setting enabled → enabled',
|
|
54
|
+
paginationEnabled: false,
|
|
55
|
+
perfEnabled: true,
|
|
56
|
+
expected: true,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
desc: 'SSP disabled, performance setting disabled → disabled',
|
|
60
|
+
paginationEnabled: false,
|
|
61
|
+
perfEnabled: false,
|
|
62
|
+
expected: false,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
desc: 'SSP enabled takes precedence even if performance setting enabled → disabled',
|
|
66
|
+
paginationEnabled: true,
|
|
67
|
+
perfEnabled: true,
|
|
68
|
+
expected: false,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
desc: 'SSP enabled, performance setting disabled → disabled',
|
|
72
|
+
paginationEnabled: true,
|
|
73
|
+
perfEnabled: false,
|
|
74
|
+
expected: false,
|
|
75
|
+
},
|
|
76
|
+
])('$desc', ({ paginationEnabled, perfEnabled, expected }) => {
|
|
77
|
+
const settings = makePerfSettings(false, perfEnabled);
|
|
78
|
+
|
|
79
|
+
expect(perfSettingUtils.manualRefreshUtils.isEnabled(paginationEnabled, settings)).toStrictEqual(expected);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('incrementalLoadingUtils and manualRefreshUtils are independent instances', () => {
|
|
84
|
+
it('incrementalLoading setting does not affect manualRefreshUtils', () => {
|
|
85
|
+
const settings = makePerfSettings(true, false);
|
|
86
|
+
|
|
87
|
+
expect(perfSettingUtils.incrementalLoadingUtils.isEnabled(false, settings)).toStrictEqual(true);
|
|
88
|
+
expect(perfSettingUtils.manualRefreshUtils.isEnabled(false, settings)).toStrictEqual(false);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('manualRefresh setting does not affect incrementalLoadingUtils', () => {
|
|
92
|
+
const settings = makePerfSettings(false, true);
|
|
93
|
+
|
|
94
|
+
expect(perfSettingUtils.incrementalLoadingUtils.isEnabled(false, settings)).toStrictEqual(false);
|
|
95
|
+
expect(perfSettingUtils.manualRefreshUtils.isEnabled(false, settings)).toStrictEqual(true);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
});
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import PollerSequential from '@shell/utils/poller-sequential';
|
|
2
|
+
|
|
3
|
+
describe('pollerSequential', () => {
|
|
4
|
+
let fn: jest.Mock;
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
jest.useFakeTimers();
|
|
8
|
+
fn = jest.fn().mockResolvedValue(undefined);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
jest.useRealTimers();
|
|
13
|
+
jest.restoreAllMocks();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('constructor', () => {
|
|
17
|
+
it('should store fn, pollRateMs and maxRetries', () => {
|
|
18
|
+
const poller = new PollerSequential(fn, 1000, 5);
|
|
19
|
+
|
|
20
|
+
expect(poller.fn).toBe(fn);
|
|
21
|
+
expect(poller.pollRateMs).toBe(1000);
|
|
22
|
+
expect(poller.maxRetries).toBe(5);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should default maxRetries to POSITIVE_INFINITY', () => {
|
|
26
|
+
const poller = new PollerSequential(fn, 500);
|
|
27
|
+
|
|
28
|
+
expect(poller.maxRetries).toBe(Number.POSITIVE_INFINITY);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should substitute a no-op when fn is falsy', () => {
|
|
32
|
+
const poller = new PollerSequential(null as any, 500);
|
|
33
|
+
|
|
34
|
+
expect(typeof poller.fn).toBe('function');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should initialise tryCount to 0', () => {
|
|
38
|
+
const poller = new PollerSequential(fn, 1000);
|
|
39
|
+
|
|
40
|
+
expect(poller.tryCount).toBe(0);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should initialise timeoutId to undefined', () => {
|
|
44
|
+
const poller = new PollerSequential(fn, 1000);
|
|
45
|
+
|
|
46
|
+
expect(poller.timeoutId).toBeUndefined();
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('start', () => {
|
|
51
|
+
it('should set timeoutId after start', () => {
|
|
52
|
+
const poller = new PollerSequential(fn, 1000);
|
|
53
|
+
|
|
54
|
+
poller.start();
|
|
55
|
+
|
|
56
|
+
expect(poller.timeoutId).toBeDefined();
|
|
57
|
+
|
|
58
|
+
poller.stop();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should not call fn immediately (delayed unlike Poller)', () => {
|
|
62
|
+
const poller = new PollerSequential(fn, 1000);
|
|
63
|
+
|
|
64
|
+
poller.start();
|
|
65
|
+
|
|
66
|
+
expect(fn).not.toHaveBeenCalled();
|
|
67
|
+
|
|
68
|
+
poller.stop();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should stop and restart when start is called while already running', () => {
|
|
72
|
+
const poller = new PollerSequential(fn, 1000);
|
|
73
|
+
const stopSpy = jest.spyOn(poller, 'stop');
|
|
74
|
+
|
|
75
|
+
poller.start();
|
|
76
|
+
poller.start();
|
|
77
|
+
|
|
78
|
+
expect(stopSpy).toHaveBeenCalledWith();
|
|
79
|
+
|
|
80
|
+
poller.stop();
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe('stop', () => {
|
|
85
|
+
it('should clear timeoutId after stop', () => {
|
|
86
|
+
const poller = new PollerSequential(fn, 1000);
|
|
87
|
+
|
|
88
|
+
poller.start();
|
|
89
|
+
poller.stop();
|
|
90
|
+
|
|
91
|
+
expect(poller.timeoutId).toBeUndefined();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should not call fn after stop', async() => {
|
|
95
|
+
const poller = new PollerSequential(fn, 1000);
|
|
96
|
+
|
|
97
|
+
poller.start();
|
|
98
|
+
poller.stop();
|
|
99
|
+
jest.advanceTimersByTime(10000);
|
|
100
|
+
|
|
101
|
+
expect(fn).not.toHaveBeenCalled();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should be safe to call stop when not running', () => {
|
|
105
|
+
const poller = new PollerSequential(fn, 1000);
|
|
106
|
+
|
|
107
|
+
expect(() => poller.stop()).not.toThrow();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe('_poll', () => {
|
|
112
|
+
it('should not continue polling if timeoutId has been cleared', async() => {
|
|
113
|
+
const poller = new PollerSequential(fn, 1000);
|
|
114
|
+
|
|
115
|
+
poller.timeoutId = undefined;
|
|
116
|
+
poller._poll();
|
|
117
|
+
|
|
118
|
+
jest.advanceTimersByTime(5000);
|
|
119
|
+
|
|
120
|
+
expect(fn).not.toHaveBeenCalled();
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('should clear timeoutId and schedule next poll', () => {
|
|
124
|
+
const poller = new PollerSequential(fn, 1000);
|
|
125
|
+
|
|
126
|
+
poller.start();
|
|
127
|
+
expect(poller.timeoutId).toBeDefined();
|
|
128
|
+
|
|
129
|
+
const firstId = poller.timeoutId;
|
|
130
|
+
|
|
131
|
+
// Advance past the initial delay to trigger _poll
|
|
132
|
+
jest.advanceTimersByTime(1000);
|
|
133
|
+
|
|
134
|
+
// _poll should have set a new timeout (different from the first)
|
|
135
|
+
expect(poller.timeoutId).toBeDefined();
|
|
136
|
+
// timeoutId should have changed since _poll calls stop then sets a new one
|
|
137
|
+
expect(poller.timeoutId).not.toBe(firstId);
|
|
138
|
+
|
|
139
|
+
poller.stop();
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe('_intervalMethod', () => {
|
|
144
|
+
it('should reset tryCount to 0 after a successful call', async() => {
|
|
145
|
+
const poller = new PollerSequential(fn, 1000);
|
|
146
|
+
|
|
147
|
+
poller.tryCount = 3;
|
|
148
|
+
await poller._intervalMethod();
|
|
149
|
+
|
|
150
|
+
expect(poller.tryCount).toBe(0);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('should increment tryCount on each error', async() => {
|
|
154
|
+
fn.mockRejectedValue(new Error('fail'));
|
|
155
|
+
const poller = new PollerSequential(fn, 1000, 5);
|
|
156
|
+
|
|
157
|
+
await poller._intervalMethod();
|
|
158
|
+
expect(poller.tryCount).toBe(1);
|
|
159
|
+
|
|
160
|
+
await poller._intervalMethod();
|
|
161
|
+
expect(poller.tryCount).toBe(2);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('should stop when tryCount reaches maxRetries', async() => {
|
|
165
|
+
fn.mockRejectedValue(new Error('fail'));
|
|
166
|
+
const poller = new PollerSequential(fn, 1000, 3);
|
|
167
|
+
const stopSpy = jest.spyOn(poller, 'stop');
|
|
168
|
+
|
|
169
|
+
await poller._intervalMethod();
|
|
170
|
+
await poller._intervalMethod();
|
|
171
|
+
expect(stopSpy).not.toHaveBeenCalled();
|
|
172
|
+
|
|
173
|
+
await poller._intervalMethod();
|
|
174
|
+
expect(stopSpy).toHaveBeenCalledTimes(1);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
});
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import Poller from '@shell/utils/poller';
|
|
2
|
+
|
|
3
|
+
describe('poller', () => {
|
|
4
|
+
let fn: jest.Mock;
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
jest.useFakeTimers();
|
|
8
|
+
fn = jest.fn().mockResolvedValue(undefined);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
jest.useRealTimers();
|
|
13
|
+
jest.restoreAllMocks();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('constructor', () => {
|
|
17
|
+
it('should store fn, pollRateMs and maxRetries', () => {
|
|
18
|
+
const poller = new Poller(fn, 1000, 5);
|
|
19
|
+
|
|
20
|
+
expect(poller.fn).toBe(fn);
|
|
21
|
+
expect(poller.pollRateMs).toBe(1000);
|
|
22
|
+
expect(poller.maxRetries).toBe(5);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should default maxRetries to POSITIVE_INFINITY', () => {
|
|
26
|
+
const poller = new Poller(fn, 500);
|
|
27
|
+
|
|
28
|
+
expect(poller.maxRetries).toBe(Number.POSITIVE_INFINITY);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should substitute a no-op when fn is falsy', () => {
|
|
32
|
+
const poller = new Poller(null as any, 500);
|
|
33
|
+
|
|
34
|
+
expect(typeof poller.fn).toBe('function');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should initialise tryCount to 0', () => {
|
|
38
|
+
const poller = new Poller(fn, 1000);
|
|
39
|
+
|
|
40
|
+
expect(poller.tryCount).toBe(0);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should initialise intervalId to undefined', () => {
|
|
44
|
+
const poller = new Poller(fn, 1000);
|
|
45
|
+
|
|
46
|
+
expect(poller.intervalId).toBeUndefined();
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('start', () => {
|
|
51
|
+
it('should call fn immediately when started', () => {
|
|
52
|
+
const poller = new Poller(fn, 1000);
|
|
53
|
+
|
|
54
|
+
poller.start();
|
|
55
|
+
|
|
56
|
+
expect(fn).toHaveBeenCalledTimes(1);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should set intervalId after start', () => {
|
|
60
|
+
const poller = new Poller(fn, 1000);
|
|
61
|
+
|
|
62
|
+
poller.start();
|
|
63
|
+
|
|
64
|
+
expect(poller.intervalId).toBeDefined();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should call fn again after each poll interval', async() => {
|
|
68
|
+
const poller = new Poller(fn, 1000);
|
|
69
|
+
|
|
70
|
+
poller.start();
|
|
71
|
+
expect(fn).toHaveBeenCalledTimes(1);
|
|
72
|
+
|
|
73
|
+
jest.advanceTimersByTime(1000);
|
|
74
|
+
expect(fn).toHaveBeenCalledTimes(2);
|
|
75
|
+
|
|
76
|
+
jest.advanceTimersByTime(1000);
|
|
77
|
+
expect(fn).toHaveBeenCalledTimes(3);
|
|
78
|
+
|
|
79
|
+
poller.stop();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should stop and restart when start is called while already running', () => {
|
|
83
|
+
const poller = new Poller(fn, 1000);
|
|
84
|
+
const stopSpy = jest.spyOn(poller, 'stop');
|
|
85
|
+
|
|
86
|
+
poller.start();
|
|
87
|
+
poller.start();
|
|
88
|
+
|
|
89
|
+
expect(stopSpy).toHaveBeenCalledWith();
|
|
90
|
+
|
|
91
|
+
poller.stop();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe('stop', () => {
|
|
96
|
+
it('should clear intervalId after stop', () => {
|
|
97
|
+
const poller = new Poller(fn, 1000);
|
|
98
|
+
|
|
99
|
+
poller.start();
|
|
100
|
+
poller.stop();
|
|
101
|
+
|
|
102
|
+
expect(poller.intervalId).toBeUndefined();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should not call fn after stop', () => {
|
|
106
|
+
const poller = new Poller(fn, 1000);
|
|
107
|
+
|
|
108
|
+
poller.start();
|
|
109
|
+
expect(fn).toHaveBeenCalledTimes(1);
|
|
110
|
+
|
|
111
|
+
poller.stop();
|
|
112
|
+
jest.advanceTimersByTime(5000);
|
|
113
|
+
|
|
114
|
+
expect(fn).toHaveBeenCalledTimes(1);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('should be safe to call stop when not running', () => {
|
|
118
|
+
const poller = new Poller(fn, 1000);
|
|
119
|
+
|
|
120
|
+
expect(() => poller.stop()).not.toThrow();
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
describe('_intervalMethod', () => {
|
|
125
|
+
it('should reset tryCount to 0 after a successful call', async() => {
|
|
126
|
+
const poller = new Poller(fn, 1000);
|
|
127
|
+
|
|
128
|
+
poller.tryCount = 3;
|
|
129
|
+
await poller._intervalMethod();
|
|
130
|
+
|
|
131
|
+
expect(poller.tryCount).toBe(0);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('should increment tryCount on each error', async() => {
|
|
135
|
+
fn.mockRejectedValue(new Error('fail'));
|
|
136
|
+
const poller = new Poller(fn, 1000, 5);
|
|
137
|
+
|
|
138
|
+
await poller._intervalMethod();
|
|
139
|
+
expect(poller.tryCount).toBe(1);
|
|
140
|
+
|
|
141
|
+
await poller._intervalMethod();
|
|
142
|
+
expect(poller.tryCount).toBe(2);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should stop when tryCount reaches maxRetries', async() => {
|
|
146
|
+
fn.mockRejectedValue(new Error('fail'));
|
|
147
|
+
const poller = new Poller(fn, 1000, 3);
|
|
148
|
+
const stopSpy = jest.spyOn(poller, 'stop');
|
|
149
|
+
|
|
150
|
+
await poller._intervalMethod();
|
|
151
|
+
await poller._intervalMethod();
|
|
152
|
+
expect(stopSpy).not.toHaveBeenCalled();
|
|
153
|
+
|
|
154
|
+
await poller._intervalMethod();
|
|
155
|
+
expect(stopSpy).toHaveBeenCalledTimes(1);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('should not stop before maxRetries is reached', async() => {
|
|
159
|
+
fn.mockRejectedValue(new Error('fail'));
|
|
160
|
+
const poller = new Poller(fn, 1000, 5);
|
|
161
|
+
const stopSpy = jest.spyOn(poller, 'stop');
|
|
162
|
+
|
|
163
|
+
for (let i = 0; i < 4; i++) {
|
|
164
|
+
await poller._intervalMethod();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
expect(stopSpy).not.toHaveBeenCalled();
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
});
|