@cccsaurora/howler-ui 2.19.0-cases.863 → 2.19.0-dev.1000
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/api/index.d.ts +0 -4
- package/api/index.js +2 -10
- package/api/search/facet/hit.d.ts +3 -1
- package/api/search/facet/index.d.ts +1 -3
- package/api/search/index.d.ts +1 -2
- package/api/search/index.js +1 -2
- package/commons/components/leftnav/LeftNavDrawer.js +1 -1
- package/components/app/App.d.ts +1 -0
- package/components/app/App.js +20 -42
- package/components/app/hooks/useMatchers.d.ts +1 -1
- package/components/app/hooks/useMatchers.js +11 -23
- package/components/app/hooks/useMatchers.test.js +22 -22
- package/components/app/hooks/useTitle.js +5 -5
- package/components/app/providers/FavouritesProvider.js +2 -6
- package/components/app/providers/HitProvider.d.ts +22 -0
- package/components/app/providers/{RecordProvider.js → HitProvider.js} +42 -42
- package/components/app/providers/{RecordSearchProvider.d.ts → HitSearchProvider.d.ts} +6 -6
- package/components/app/providers/{RecordSearchProvider.js → HitSearchProvider.js} +17 -12
- package/components/app/providers/{RecordSearchProvider.test.js → HitSearchProvider.test.js} +71 -52
- package/components/app/providers/ModalProvider.d.ts +1 -1
- package/components/app/providers/ModalProvider.js +5 -1
- package/components/app/providers/ParameterProvider.d.ts +2 -9
- package/components/app/providers/ParameterProvider.js +240 -165
- package/components/app/providers/ParameterProvider.test.js +94 -346
- package/components/app/providers/SocketProvider.d.ts +2 -11
- package/components/app/providers/SocketProvider.js +5 -18
- package/components/app/providers/UserListProvider.js +8 -28
- package/components/elements/PluginTypography.d.ts +1 -2
- package/components/elements/PluginTypography.js +2 -3
- package/components/elements/UserList.d.ts +2 -5
- package/components/elements/UserList.js +8 -18
- package/components/elements/addons/buttons/CustomButton.test.js +106 -0
- package/components/elements/addons/layout/FlexOne.test.js +30 -0
- package/components/elements/addons/lists/TuiListBase.js +4 -0
- package/components/elements/addons/lists/TuiListElement.js +6 -3
- package/components/elements/addons/lists/index.d.ts +1 -0
- package/components/elements/addons/search/SearchPagination.test.js +80 -0
- package/components/elements/addons/search/SearchTotal.test.js +45 -0
- package/components/elements/addons/search/phrase/Phrase.js +1 -1
- package/components/elements/display/ChipPopper.d.ts +1 -1
- package/components/elements/display/ChipPopper.js +5 -5
- package/components/elements/display/DocumentationButton.test.js +84 -0
- package/components/elements/display/DynamicTabs.test.js +93 -0
- package/components/elements/display/HowlerAvatar.js +2 -1
- package/components/elements/display/HowlerCard.js +1 -1
- package/components/elements/display/HowlerCard.test.js +55 -0
- package/components/elements/display/Image.test.js +79 -0
- package/components/elements/display/Markdown.js +9 -2
- package/components/elements/display/Modal.js +0 -2
- package/components/elements/display/QueryResultText.test.js +48 -0
- package/components/elements/display/TextDivider.test.js +43 -0
- package/components/elements/display/TypingIndicator.test.js +33 -0
- package/components/elements/display/icons/BundleButton.d.ts +6 -0
- package/components/elements/display/icons/BundleButton.js +32 -0
- package/components/elements/display/modals/ConfirmDeleteModal.d.ts +4 -0
- package/components/elements/display/modals/ConfirmDeleteModal.js +4 -2
- package/components/elements/hit/HitActions.js +4 -4
- package/components/elements/hit/HitBanner.d.ts +0 -1
- package/components/elements/hit/HitBanner.js +49 -31
- package/components/elements/hit/HitCard.d.ts +0 -2
- package/components/elements/hit/HitCard.js +7 -7
- package/components/elements/{record/RecordComments.d.ts → hit/HitComments.d.ts} +4 -5
- package/components/elements/{record/RecordComments.js → hit/HitComments.js} +28 -29
- package/components/elements/{ObjectDetails.js → hit/HitDetails.js} +17 -17
- package/components/elements/hit/HitLabels.js +2 -2
- package/components/elements/hit/HitOutline.d.ts +0 -1
- package/components/elements/hit/HitOutline.js +3 -3
- package/components/elements/hit/{HitPreview.d.ts → HitQuickSearch.d.ts} +3 -3
- package/components/elements/hit/{HitPreview.js → HitQuickSearch.js} +4 -10
- package/components/elements/hit/HitRelated.d.ts +6 -0
- package/components/elements/hit/HitRelated.js +7 -0
- package/components/elements/hit/HitSummary.d.ts +1 -2
- package/components/elements/hit/HitSummary.js +8 -8
- package/components/elements/{record/RecordWorklog.d.ts → hit/HitWorklog.d.ts} +3 -4
- package/components/elements/{record/RecordWorklog.js → hit/HitWorklog.js} +13 -15
- package/components/elements/hit/aggregate/HitGraph.js +8 -8
- package/components/elements/hit/elements/{Assigned.d.ts → HitUsers.d.ts} +5 -2
- package/components/elements/hit/elements/HitUsers.js +33 -0
- package/components/elements/hit/outlines/DefaultOutline.js +1 -1
- package/components/elements/view/ViewTitle.d.ts +0 -1
- package/components/elements/view/ViewTitle.js +2 -9
- package/components/hooks/useHitActions.d.ts +1 -1
- package/components/hooks/useHitActions.js +4 -4
- package/components/hooks/{useRecordSelection.d.ts → useHitSelection.d.ts} +2 -2
- package/components/hooks/{useRecordSelection.js → useHitSelection.js} +33 -12
- package/components/hooks/useMyPreferences.js +3 -11
- package/components/hooks/useMySearch.js +2 -2
- package/components/hooks/useMySitemap.js +1 -4
- package/components/hooks/useMyTheme.js +2 -9
- package/components/routes/403.test.js +27 -0
- package/components/routes/404.test.js +26 -0
- package/components/routes/ErrorBoundary.test.js +43 -0
- package/components/routes/ErrorOccured.test.js +35 -0
- package/components/routes/Logout.test.js +59 -0
- package/components/routes/action/edit/ActionEditor.js +2 -2
- package/components/routes/action/view/ActionDetails.js +4 -2
- package/components/routes/action/view/ActionSearch.js +12 -7
- package/components/routes/advanced/QueryBuilder.js +1 -1
- package/components/routes/advanced/QueryEditor.js +3 -3
- package/components/routes/advanced/historyCompletionProvider.js +3 -3
- package/components/routes/analytics/AnalyticDetails.js +12 -8
- package/components/routes/analytics/AnalyticSearch.js +1 -1
- package/components/routes/dossiers/DossierEditor.js +2 -2
- package/components/routes/dossiers/DossierEditor.test.js +1 -1
- package/components/routes/dossiers/Dossiers.js +15 -11
- package/components/routes/help/ApiDocumentation.js +1 -1
- package/components/routes/help/BundleDocumentation.d.ts +3 -0
- package/components/routes/help/BundleDocumentation.js +12 -0
- package/components/routes/help/HitBannerDocumentation.js +0 -1
- package/components/routes/help/HitDocumentation.js +3 -1
- package/components/routes/help/markdown/en/bundles.md.js +1 -0
- package/components/routes/help/markdown/en/client.md.js +1 -1
- package/components/routes/help/markdown/fr/bundles.md.js +1 -0
- package/components/routes/help/markdown/fr/client.md.js +1 -1
- package/components/routes/hits/search/BundleParentMenu.d.ts +6 -0
- package/components/routes/hits/search/BundleParentMenu.js +32 -0
- package/components/routes/hits/search/BundleScroller.d.ts +2 -0
- package/components/routes/hits/search/BundleScroller.js +6 -0
- package/components/routes/hits/search/{RecordBrowser.js → HitBrowser.js} +9 -9
- package/components/{elements/record/RecordContextMenu.d.ts → routes/hits/search/HitContextMenu.d.ts} +3 -3
- package/components/routes/hits/search/HitContextMenu.js +239 -0
- package/components/{elements/record/RecordContextMenu.test.js → routes/hits/search/HitContextMenu.test.js} +43 -98
- package/components/routes/hits/search/{RecordQuery.d.ts → HitQuery.d.ts} +2 -2
- package/components/routes/hits/search/{RecordQuery.js → HitQuery.js} +6 -6
- package/components/routes/hits/search/InformationPane.d.ts +0 -1
- package/components/routes/hits/search/InformationPane.js +63 -50
- package/components/routes/hits/search/LayoutSettings.js +3 -3
- package/components/routes/hits/search/QuerySettings.js +1 -2
- package/components/routes/hits/search/QuerySettings.test.js +9 -14
- package/components/routes/hits/search/SearchPane.js +49 -26
- package/components/routes/hits/search/ViewLink.js +3 -3
- package/components/routes/hits/search/ViewLink.test.js +8 -8
- package/components/routes/hits/search/grid/AddColumnModal.js +4 -5
- package/components/routes/hits/search/grid/EnhancedCell.d.ts +1 -2
- package/components/routes/hits/search/grid/EnhancedCell.js +2 -2
- package/components/routes/hits/search/grid/HitGrid.js +18 -20
- package/components/routes/hits/search/grid/{RecordRow.d.ts → HitRow.d.ts} +2 -3
- package/components/routes/hits/search/grid/{RecordRow.js → HitRow.js} +9 -11
- package/components/routes/hits/search/shared/CustomSpan.js +7 -7
- package/components/routes/hits/search/shared/CustomSpan.test.js +170 -0
- package/components/routes/hits/view/HitViewer.js +13 -12
- package/components/routes/home/AddNewCard.test.js +68 -0
- package/components/routes/home/ViewCard.js +41 -47
- package/components/routes/home/ViewRefresh.test.js +79 -0
- package/components/routes/overviews/OverviewCard.test.js +108 -0
- package/components/{elements/MarkdownEditor.js → routes/overviews/OverviewEditor.js} +3 -3
- package/components/routes/overviews/OverviewViewer.js +14 -10
- package/components/routes/overviews/Overviews.js +15 -11
- package/components/routes/settings/LocalSection.js +2 -1
- package/components/routes/settings/SettingsSection.test.js +19 -0
- package/components/routes/templates/TemplateCard.d.ts +3 -1
- package/components/routes/templates/TemplateCard.js +8 -4
- package/components/routes/templates/TemplateCard.test.d.ts +1 -0
- package/components/routes/templates/TemplateCard.test.js +115 -0
- package/components/routes/templates/TemplateViewer.js +57 -16
- package/components/routes/templates/Templates.js +23 -6
- package/components/routes/views/ViewComposer.js +19 -46
- package/components/routes/views/Views.js +8 -4
- package/locales/en/translation.json +17 -117
- package/locales/fr/translation.json +19 -119
- package/models/WithMetadata.d.ts +1 -2
- package/models/entities/generated/{ThreatEnrichment.d.ts → Enrichment.d.ts} +1 -1
- package/models/entities/generated/Hit.d.ts +1 -1
- package/models/entities/generated/Howler.d.ts +6 -0
- package/models/entities/generated/Rule.d.ts +9 -6
- package/models/entities/generated/Threat.d.ts +2 -2
- package/models/entities/generated/UserUser.d.ts +2 -0
- package/models/entities/generated/View.d.ts +0 -1
- package/package.json +112 -132
- package/plugins/clue/components/ClueTypography.js +2 -2
- package/plugins/clue/utils.d.ts +1 -2
- package/rest/FetchClient.test.d.ts +1 -0
- package/rest/FetchClient.test.js +81 -0
- package/setupTests.js +5 -0
- package/tests/mocks.d.ts +1 -11
- package/tests/mocks.js +7 -12
- package/tests/server-handlers.js +1 -6
- package/tests/utils.d.ts +0 -4
- package/tests/utils.js +0 -20
- package/utils/Throttler.test.d.ts +1 -0
- package/utils/Throttler.test.js +135 -0
- package/utils/actionUtils.test.d.ts +1 -0
- package/utils/actionUtils.test.js +140 -0
- package/utils/constants.d.ts +4 -4
- package/utils/constants.js +1 -6
- package/utils/hitFunctions.d.ts +1 -2
- package/utils/hitFunctions.js +4 -4
- package/utils/hitFunctions.test.d.ts +1 -0
- package/utils/hitFunctions.test.js +52 -0
- package/utils/localStorage.test.d.ts +1 -0
- package/utils/localStorage.test.js +96 -0
- package/utils/menuUtils.test.d.ts +1 -0
- package/utils/menuUtils.test.js +198 -0
- package/utils/sessionStorage.test.d.ts +1 -0
- package/utils/sessionStorage.test.js +81 -0
- package/utils/socketUtils.d.ts +0 -14
- package/utils/socketUtils.js +1 -17
- package/utils/socketUtils.test.js +16 -49
- package/utils/stringUtils.test.d.ts +1 -0
- package/utils/stringUtils.test.js +159 -0
- package/utils/utils.test.d.ts +1 -0
- package/utils/utils.test.js +292 -0
- package/utils/viewUtils.js +0 -3
- package/utils/viewUtils.test.d.ts +1 -0
- package/utils/viewUtils.test.js +45 -0
- package/utils/xsrf.test.d.ts +1 -0
- package/utils/xsrf.test.js +41 -0
- package/api/search/case.d.ts +0 -4
- package/api/search/case.js +0 -8
- package/api/socket/index.d.ts +0 -3
- package/api/socket/index.js +0 -6
- package/api/socket/viewers.d.ts +0 -2
- package/api/socket/viewers.js +0 -8
- package/api/socket/viewers.test.js +0 -44
- package/api/v2/case/index.d.ts +0 -9
- package/api/v2/case/index.js +0 -21
- package/api/v2/case/items.d.ts +0 -6
- package/api/v2/case/items.js +0 -18
- package/api/v2/case/rules.d.ts +0 -6
- package/api/v2/case/rules.js +0 -18
- package/api/v2/index.d.ts +0 -4
- package/api/v2/index.js +0 -6
- package/api/v2/search/facet.d.ts +0 -3
- package/api/v2/search/facet.js +0 -12
- package/api/v2/search/index.d.ts +0 -5
- package/api/v2/search/index.js +0 -24
- package/components/app/providers/RecordProvider.d.ts +0 -23
- package/components/elements/ContextMenu.d.ts +0 -56
- package/components/elements/ContextMenu.js +0 -109
- package/components/elements/ContextMenu.test.js +0 -215
- package/components/elements/ObjectDetails.d.ts +0 -6
- package/components/elements/case/CaseCard.d.ts +0 -12
- package/components/elements/case/CaseCard.js +0 -42
- package/components/elements/case/CasePreview.d.ts +0 -6
- package/components/elements/case/CasePreview.js +0 -17
- package/components/elements/case/StatusIcon.d.ts +0 -5
- package/components/elements/case/StatusIcon.js +0 -13
- package/components/elements/hit/elements/AnalyticLink.d.ts +0 -9
- package/components/elements/hit/elements/AnalyticLink.js +0 -22
- package/components/elements/hit/elements/Assigned.js +0 -34
- package/components/elements/hit/elements/Assigned.test.js +0 -65
- package/components/elements/hit/related/RelatedRecords.js +0 -63
- package/components/elements/observable/ObservableCard.d.ts +0 -6
- package/components/elements/observable/ObservableCard.js +0 -22
- package/components/elements/observable/ObservablePreview.d.ts +0 -6
- package/components/elements/observable/ObservablePreview.js +0 -12
- package/components/elements/record/RecordContextMenu.js +0 -268
- package/components/elements/record/RecordRelated.d.ts +0 -7
- package/components/elements/record/RecordRelated.js +0 -34
- package/components/hooks/useRelatedRecords.d.ts +0 -13
- package/components/hooks/useRelatedRecords.js +0 -32
- package/components/routes/cases/CaseViewer.d.ts +0 -2
- package/components/routes/cases/CaseViewer.js +0 -44
- package/components/routes/cases/CaseViewer.test.js +0 -133
- package/components/routes/cases/Cases.d.ts +0 -2
- package/components/routes/cases/Cases.js +0 -148
- package/components/routes/cases/constants.d.ts +0 -6
- package/components/routes/cases/constants.js +0 -6
- package/components/routes/cases/detail/AlertPanel.d.ts +0 -6
- package/components/routes/cases/detail/AlertPanel.js +0 -33
- package/components/routes/cases/detail/CaseAssets.d.ts +0 -11
- package/components/routes/cases/detail/CaseAssets.js +0 -104
- package/components/routes/cases/detail/CaseAssets.test.js +0 -167
- package/components/routes/cases/detail/CaseDashboard.d.ts +0 -7
- package/components/routes/cases/detail/CaseDashboard.js +0 -66
- package/components/routes/cases/detail/CaseDetails.d.ts +0 -6
- package/components/routes/cases/detail/CaseDetails.js +0 -70
- package/components/routes/cases/detail/CaseOverview.d.ts +0 -7
- package/components/routes/cases/detail/CaseOverview.js +0 -43
- package/components/routes/cases/detail/CaseRules.d.ts +0 -7
- package/components/routes/cases/detail/CaseRules.js +0 -57
- package/components/routes/cases/detail/CaseRules.test.js +0 -221
- package/components/routes/cases/detail/CaseSidebar.d.ts +0 -8
- package/components/routes/cases/detail/CaseSidebar.js +0 -107
- package/components/routes/cases/detail/CaseSidebar.test.js +0 -266
- package/components/routes/cases/detail/CaseTask.d.ts +0 -11
- package/components/routes/cases/detail/CaseTask.js +0 -66
- package/components/routes/cases/detail/CaseTimeline.d.ts +0 -12
- package/components/routes/cases/detail/CaseTimeline.js +0 -106
- package/components/routes/cases/detail/CaseTimeline.test.js +0 -320
- package/components/routes/cases/detail/CreateRuleDialog.d.ts +0 -9
- package/components/routes/cases/detail/CreateRuleDialog.js +0 -163
- package/components/routes/cases/detail/CreateRuleDialog.test.js +0 -259
- package/components/routes/cases/detail/ItemPage.d.ts +0 -6
- package/components/routes/cases/detail/ItemPage.js +0 -95
- package/components/routes/cases/detail/RelatedCasePanel.d.ts +0 -6
- package/components/routes/cases/detail/RelatedCasePanel.js +0 -34
- package/components/routes/cases/detail/TaskPanel.d.ts +0 -7
- package/components/routes/cases/detail/TaskPanel.js +0 -52
- package/components/routes/cases/detail/aggregates/CaseAggregate.d.ts +0 -11
- package/components/routes/cases/detail/aggregates/CaseAggregate.js +0 -24
- package/components/routes/cases/detail/aggregates/SourceAggregate.d.ts +0 -6
- package/components/routes/cases/detail/aggregates/SourceAggregate.js +0 -26
- package/components/routes/cases/detail/assets/Asset.d.ts +0 -14
- package/components/routes/cases/detail/assets/Asset.js +0 -12
- package/components/routes/cases/detail/assets/Asset.test.js +0 -72
- package/components/routes/cases/detail/sidebar/CaseFolder.d.ts +0 -20
- package/components/routes/cases/detail/sidebar/CaseFolder.js +0 -83
- package/components/routes/cases/detail/sidebar/CaseFolder.test.js +0 -295
- package/components/routes/cases/detail/sidebar/CaseFolderContextMenu.d.ts +0 -34
- package/components/routes/cases/detail/sidebar/CaseFolderContextMenu.js +0 -103
- package/components/routes/cases/detail/sidebar/CaseFolderContextMenu.test.js +0 -363
- package/components/routes/cases/detail/sidebar/FolderEntry.d.ts +0 -25
- package/components/routes/cases/detail/sidebar/FolderEntry.js +0 -88
- package/components/routes/cases/detail/sidebar/FolderEntry.test.js +0 -206
- package/components/routes/cases/detail/sidebar/RootDropZone.d.ts +0 -5
- package/components/routes/cases/detail/sidebar/RootDropZone.js +0 -33
- package/components/routes/cases/detail/sidebar/types.d.ts +0 -9
- package/components/routes/cases/detail/sidebar/utils.d.ts +0 -3
- package/components/routes/cases/detail/sidebar/utils.js +0 -29
- package/components/routes/cases/detail/sidebar/utils.test.js +0 -82
- package/components/routes/cases/hooks/useCase.d.ts +0 -13
- package/components/routes/cases/hooks/useCase.js +0 -69
- package/components/routes/cases/hooks/useCase.test.js +0 -141
- package/components/routes/cases/modals/AddToCaseModal.d.ts +0 -7
- package/components/routes/cases/modals/AddToCaseModal.js +0 -59
- package/components/routes/cases/modals/AddToCaseModal.test.js +0 -313
- package/components/routes/cases/modals/CaseRecordRow.d.ts +0 -9
- package/components/routes/cases/modals/CaseRecordRow.js +0 -15
- package/components/routes/cases/modals/CreateCaseModal.d.ts +0 -7
- package/components/routes/cases/modals/CreateCaseModal.js +0 -55
- package/components/routes/cases/modals/CreateCaseModal.test.js +0 -358
- package/components/routes/cases/modals/RenameItemModal.d.ts +0 -9
- package/components/routes/cases/modals/RenameItemModal.js +0 -48
- package/components/routes/cases/modals/ResolveModal.d.ts +0 -7
- package/components/routes/cases/modals/ResolveModal.js +0 -115
- package/components/routes/cases/modals/ResolveModal.test.js +0 -394
- package/components/routes/cases/modals/hooks.d.ts +0 -7
- package/components/routes/cases/modals/hooks.js +0 -44
- package/components/routes/cases/modals/types.d.ts +0 -5
- package/components/routes/cases/search/CaseAssigneeFilter.d.ts +0 -6
- package/components/routes/cases/search/CaseAssigneeFilter.js +0 -33
- package/components/routes/cases/search/CaseAssigneeFilter.test.js +0 -127
- package/components/routes/cases/search/CaseDateFilter.d.ts +0 -13
- package/components/routes/cases/search/CaseDateFilter.js +0 -26
- package/components/routes/cases/search/CaseDateFilter.test.js +0 -115
- package/components/routes/cases/search/CaseStatusFilter.d.ts +0 -6
- package/components/routes/cases/search/CaseStatusFilter.js +0 -13
- package/components/routes/cases/search/CaseStatusFilter.test.js +0 -86
- package/components/routes/hits/search/shared/IndexPicker.d.ts +0 -2
- package/components/routes/hits/search/shared/IndexPicker.js +0 -20
- package/components/routes/observables/ObservableViewer.d.ts +0 -7
- package/components/routes/observables/ObservableViewer.js +0 -27
- package/models/entities/generated/AttachmentsFile.d.ts +0 -12
- package/models/entities/generated/Case.d.ts +0 -28
- package/models/entities/generated/DestinationOriginal.d.ts +0 -19
- package/models/entities/generated/EmailAttachment.d.ts +0 -8
- package/models/entities/generated/EmailParent.d.ts +0 -19
- package/models/entities/generated/Enrichments.d.ts +0 -7
- package/models/entities/generated/EnrichmentsIndicator.d.ts +0 -21
- package/models/entities/generated/HttpResponse.d.ts +0 -11
- package/models/entities/generated/Item.d.ts +0 -9
- package/models/entities/generated/Observable.d.ts +0 -85
- package/models/entities/generated/ObservableCloud.d.ts +0 -20
- package/models/entities/generated/ObservableDestination.d.ts +0 -23
- package/models/entities/generated/ObservableEmail.d.ts +0 -30
- package/models/entities/generated/ObservableFile.d.ts +0 -36
- package/models/entities/generated/ObservableHowler.d.ts +0 -42
- package/models/entities/generated/ObservableHttp.d.ts +0 -11
- package/models/entities/generated/ObservableObserver.d.ts +0 -21
- package/models/entities/generated/ObservableOrganization.d.ts +0 -7
- package/models/entities/generated/ObservableProcess.d.ts +0 -34
- package/models/entities/generated/ObservableSource.d.ts +0 -23
- package/models/entities/generated/ObservableThreat.d.ts +0 -21
- package/models/entities/generated/ObservableTls.d.ts +0 -12
- package/models/entities/generated/ObserverIngress.d.ts +0 -9
- package/models/entities/generated/Task.d.ts +0 -10
- package/models/socket/CaseUpdate.d.ts +0 -5
- package/models/socket/ViewersUpdate.d.ts +0 -4
- package/utils/typeUtils.d.ts +0 -7
- package/utils/typeUtils.js +0 -27
- /package/{api/socket/viewers.test.d.ts → components/app/providers/HitSearchProvider.test.d.ts} +0 -0
- /package/components/{app/providers/RecordSearchProvider.test.d.ts → elements/addons/buttons/CustomButton.test.d.ts} +0 -0
- /package/components/elements/{ContextMenu.test.d.ts → addons/layout/FlexOne.test.d.ts} +0 -0
- /package/components/elements/{hit/elements/Assigned.test.d.ts → addons/search/SearchPagination.test.d.ts} +0 -0
- /package/components/elements/{record/RecordContextMenu.test.d.ts → addons/search/SearchTotal.test.d.ts} +0 -0
- /package/components/{routes/cases/CaseViewer.test.d.ts → elements/display/DocumentationButton.test.d.ts} +0 -0
- /package/components/{routes/cases/detail/CaseAssets.test.d.ts → elements/display/DynamicTabs.test.d.ts} +0 -0
- /package/components/{routes/cases/detail/CaseRules.test.d.ts → elements/display/HowlerCard.test.d.ts} +0 -0
- /package/components/{routes/cases/detail/CaseSidebar.test.d.ts → elements/display/Image.test.d.ts} +0 -0
- /package/components/{routes/cases/detail/CaseTimeline.test.d.ts → elements/display/QueryResultText.test.d.ts} +0 -0
- /package/components/{routes/cases/detail/CreateRuleDialog.test.d.ts → elements/display/TextDivider.test.d.ts} +0 -0
- /package/components/{routes/cases/detail/assets/Asset.test.d.ts → elements/display/TypingIndicator.test.d.ts} +0 -0
- /package/components/elements/hit/{related/RelatedRecords.d.ts → HitDetails.d.ts} +0 -0
- /package/components/routes/{cases/detail/sidebar/CaseFolder.test.d.ts → 403.test.d.ts} +0 -0
- /package/components/routes/{cases/detail/sidebar/CaseFolderContextMenu.test.d.ts → 404.test.d.ts} +0 -0
- /package/components/routes/{cases/detail/sidebar/FolderEntry.test.d.ts → ErrorBoundary.test.d.ts} +0 -0
- /package/components/routes/{cases/detail/sidebar/utils.test.d.ts → ErrorOccured.test.d.ts} +0 -0
- /package/components/routes/{cases/hooks/useCase.test.d.ts → Logout.test.d.ts} +0 -0
- /package/components/routes/hits/search/{RecordBrowser.d.ts → HitBrowser.d.ts} +0 -0
- /package/components/routes/{cases/modals/AddToCaseModal.test.d.ts → hits/search/HitContextMenu.test.d.ts} +0 -0
- /package/components/routes/{cases/modals/CreateCaseModal.test.d.ts → hits/search/shared/CustomSpan.test.d.ts} +0 -0
- /package/components/routes/{cases/modals/ResolveModal.test.d.ts → home/AddNewCard.test.d.ts} +0 -0
- /package/components/routes/{cases/search/CaseAssigneeFilter.test.d.ts → home/ViewRefresh.test.d.ts} +0 -0
- /package/components/routes/{cases/search/CaseDateFilter.test.d.ts → overviews/OverviewCard.test.d.ts} +0 -0
- /package/components/{elements/MarkdownEditor.d.ts → routes/overviews/OverviewEditor.d.ts} +0 -0
- /package/components/routes/{cases/search/CaseStatusFilter.test.d.ts → settings/SettingsSection.test.d.ts} +0 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/// <reference types="vitest" />
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { bytesToSize, compareTimestamp, convertCustomDateRangeToLucene, convertDateToLucene, convertLuceneToDate, flattenDeep, formatDate, getTimeRange, hashCode, humanReadableNumber, removeEmpty, searchObject, sortByTimestamp, tryParse, twitterShort } from './utils';
|
|
4
|
+
describe('bytesToSize', () => {
|
|
5
|
+
it('returns "0 B" for 0', () => {
|
|
6
|
+
expect(bytesToSize(0)).toBe('0 B');
|
|
7
|
+
});
|
|
8
|
+
it('returns "0 B" for null', () => {
|
|
9
|
+
expect(bytesToSize(null)).toBe('0 B');
|
|
10
|
+
});
|
|
11
|
+
it('formats bytes', () => {
|
|
12
|
+
expect(bytesToSize(512)).toBe('512 B');
|
|
13
|
+
});
|
|
14
|
+
it('formats kilobytes', () => {
|
|
15
|
+
expect(bytesToSize(1024)).toBe('1 KB');
|
|
16
|
+
});
|
|
17
|
+
it('formats megabytes', () => {
|
|
18
|
+
expect(bytesToSize(1024 * 1024)).toBe('1 MB');
|
|
19
|
+
});
|
|
20
|
+
it('formats gigabytes', () => {
|
|
21
|
+
expect(bytesToSize(1024 * 1024 * 1024)).toBe('1 GB');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe('humanReadableNumber', () => {
|
|
25
|
+
it('returns "0 " for 0', () => {
|
|
26
|
+
expect(humanReadableNumber(0)).toBe('0 ');
|
|
27
|
+
});
|
|
28
|
+
it('returns "0 " for null', () => {
|
|
29
|
+
expect(humanReadableNumber(null)).toBe('0 ');
|
|
30
|
+
});
|
|
31
|
+
it('returns the number with a trailing space for values below 1000', () => {
|
|
32
|
+
expect(humanReadableNumber(500)).toBe('500 ');
|
|
33
|
+
});
|
|
34
|
+
it('formats thousands with "k"', () => {
|
|
35
|
+
expect(humanReadableNumber(1000)).toBe('1k ');
|
|
36
|
+
});
|
|
37
|
+
it('formats millions with "m"', () => {
|
|
38
|
+
expect(humanReadableNumber(1_000_000)).toBe('1m ');
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe('compareTimestamp', () => {
|
|
42
|
+
it('returns a negative number when a is earlier than b', () => {
|
|
43
|
+
expect(compareTimestamp('2021-01-01T00:00:00Z', '2021-01-02T00:00:00Z')).toBeLessThan(0);
|
|
44
|
+
});
|
|
45
|
+
it('returns a positive number when a is later than b', () => {
|
|
46
|
+
expect(compareTimestamp('2021-01-02T00:00:00Z', '2021-01-01T00:00:00Z')).toBeGreaterThan(0);
|
|
47
|
+
});
|
|
48
|
+
it('returns 0 for identical timestamps', () => {
|
|
49
|
+
expect(compareTimestamp('2021-01-01T00:00:00Z', '2021-01-01T00:00:00Z')).toBe(0);
|
|
50
|
+
});
|
|
51
|
+
it('returns a difference in seconds', () => {
|
|
52
|
+
// 86400 seconds = 1 day
|
|
53
|
+
expect(compareTimestamp('2021-01-02T00:00:00Z', '2021-01-01T00:00:00Z')).toBe(86400);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
describe('hashCode', () => {
|
|
57
|
+
it('returns a number', () => {
|
|
58
|
+
expect(typeof hashCode('hello')).toBe('number');
|
|
59
|
+
});
|
|
60
|
+
it('returns the same value for the same input', () => {
|
|
61
|
+
expect(hashCode('hello')).toBe(hashCode('hello'));
|
|
62
|
+
});
|
|
63
|
+
it('returns different values for different inputs', () => {
|
|
64
|
+
expect(hashCode('hello')).not.toBe(hashCode('world'));
|
|
65
|
+
});
|
|
66
|
+
it('returns 0 for an empty string', () => {
|
|
67
|
+
expect(hashCode('')).toBe(0);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
describe('sortByTimestamp', () => {
|
|
71
|
+
it('returns an empty array for an empty input', () => {
|
|
72
|
+
expect(sortByTimestamp([])).toEqual([]);
|
|
73
|
+
});
|
|
74
|
+
it('sorts items in descending timestamp order (most recent first)', () => {
|
|
75
|
+
const items = [
|
|
76
|
+
{ timestamp: '2021-01-01T00:00:00Z' },
|
|
77
|
+
{ timestamp: '2021-03-01T00:00:00Z' },
|
|
78
|
+
{ timestamp: '2021-02-01T00:00:00Z' }
|
|
79
|
+
];
|
|
80
|
+
const sorted = sortByTimestamp(items);
|
|
81
|
+
expect(sorted[0].timestamp).toBe('2021-03-01T00:00:00Z');
|
|
82
|
+
expect(sorted[2].timestamp).toBe('2021-01-01T00:00:00Z');
|
|
83
|
+
});
|
|
84
|
+
it('does not mutate the original array', () => {
|
|
85
|
+
const original = [{ timestamp: '2021-01-01T00:00:00Z' }, { timestamp: '2021-03-01T00:00:00Z' }];
|
|
86
|
+
const copy = [...original];
|
|
87
|
+
sortByTimestamp(original);
|
|
88
|
+
expect(original).toEqual(copy);
|
|
89
|
+
});
|
|
90
|
+
it('handles items with missing timestamps', () => {
|
|
91
|
+
const items = [{ timestamp: '2021-01-01T00:00:00Z' }, {}];
|
|
92
|
+
expect(() => sortByTimestamp(items)).not.toThrow();
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
describe('getTimeRange', () => {
|
|
96
|
+
it('returns [earliest, latest] from an array of timestamps', () => {
|
|
97
|
+
const timestamps = ['2021-03-01T00:00:00Z', '2021-01-01T00:00:00Z', '2021-02-01T00:00:00Z'];
|
|
98
|
+
const [start, end] = getTimeRange(timestamps);
|
|
99
|
+
expect(start).toBe('2021-01-01T00:00:00Z');
|
|
100
|
+
expect(end).toBe('2021-03-01T00:00:00Z');
|
|
101
|
+
});
|
|
102
|
+
it('returns the same value for both when given a single timestamp', () => {
|
|
103
|
+
const [start, end] = getTimeRange(['2021-01-01T00:00:00Z']);
|
|
104
|
+
expect(start).toBe(end);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
describe('removeEmpty', () => {
|
|
108
|
+
it('removes null values from a flat object', () => {
|
|
109
|
+
expect(removeEmpty({ a: null, b: 'val' })).toEqual({ b: 'val' });
|
|
110
|
+
});
|
|
111
|
+
it('removes undefined values from a flat object', () => {
|
|
112
|
+
expect(removeEmpty({ a: undefined, b: 'val' })).toEqual({ b: 'val' });
|
|
113
|
+
});
|
|
114
|
+
it('recursively removes null values from nested objects', () => {
|
|
115
|
+
expect(removeEmpty({ nested: { a: null, b: 'val' } })).toEqual({ nested: { b: 'val' } });
|
|
116
|
+
});
|
|
117
|
+
it('handles an empty object', () => {
|
|
118
|
+
expect(removeEmpty({})).toEqual({});
|
|
119
|
+
});
|
|
120
|
+
it('handles null input gracefully', () => {
|
|
121
|
+
expect(removeEmpty(null)).toEqual({});
|
|
122
|
+
});
|
|
123
|
+
it('keeps arrays as-is', () => {
|
|
124
|
+
const result = removeEmpty({ arr: [1, 2, 3] });
|
|
125
|
+
expect(result.arr).toEqual([1, 2, 3]);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
describe('searchObject', () => {
|
|
129
|
+
const obj = { name: 'Alice', role: 'admin', nested: { city: 'Ottawa' } };
|
|
130
|
+
it('returns the full object when query is empty', () => {
|
|
131
|
+
const result = searchObject(obj, '');
|
|
132
|
+
expect(result).toMatchObject(obj);
|
|
133
|
+
});
|
|
134
|
+
it('returns matching entries for a key match', () => {
|
|
135
|
+
const result = searchObject(obj, 'name');
|
|
136
|
+
expect(result.name).toBe('Alice');
|
|
137
|
+
});
|
|
138
|
+
it('returns matching entries for a value match', () => {
|
|
139
|
+
const result = searchObject(obj, 'Alice');
|
|
140
|
+
expect(result.name).toBe('Alice');
|
|
141
|
+
});
|
|
142
|
+
it('returns an empty object when nothing matches', () => {
|
|
143
|
+
const result = searchObject(obj, 'zzznomatch');
|
|
144
|
+
expect(result).toEqual({});
|
|
145
|
+
});
|
|
146
|
+
it('returns flat result when returnFlat=true', () => {
|
|
147
|
+
const result = searchObject(obj, 'city', true);
|
|
148
|
+
expect(result['nested.city']).toBe('Ottawa');
|
|
149
|
+
});
|
|
150
|
+
it('returns full flat object when query is empty and returnFlat=true', () => {
|
|
151
|
+
const result = searchObject({ a: 1 }, '', true);
|
|
152
|
+
expect(result.a).toBe(1);
|
|
153
|
+
});
|
|
154
|
+
it('handles an invalid regex gracefully by returning the full object', () => {
|
|
155
|
+
const result = searchObject(obj, '[invalid');
|
|
156
|
+
expect(result).toMatchObject(obj);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
describe('convertDateToLucene', () => {
|
|
160
|
+
it('returns "[now-1d TO now]" for a 1-day range', () => {
|
|
161
|
+
expect(convertDateToLucene('date.range.1.day')).toBe('[now-1d TO now]');
|
|
162
|
+
});
|
|
163
|
+
it('returns "[now-1w TO now]" for a 1-week range', () => {
|
|
164
|
+
expect(convertDateToLucene('date.range.1.week')).toBe('[now-1w TO now]');
|
|
165
|
+
});
|
|
166
|
+
it('returns "[now-1M TO now]" for a 1-month range', () => {
|
|
167
|
+
expect(convertDateToLucene('date.range.1.month')).toBe('[now-1M TO now]');
|
|
168
|
+
});
|
|
169
|
+
it('returns "[now-1y TO now]" for a 1-year range', () => {
|
|
170
|
+
expect(convertDateToLucene('date.range.1.year')).toBe('[now-1y TO now]');
|
|
171
|
+
});
|
|
172
|
+
it('returns "*" for the "all" range', () => {
|
|
173
|
+
expect(convertDateToLucene('date.range.all')).toBe('*');
|
|
174
|
+
});
|
|
175
|
+
it('returns the default 1-day range when input does not start with "date.range."', () => {
|
|
176
|
+
expect(convertDateToLucene('something.else')).toBe('[now-1d TO now]');
|
|
177
|
+
});
|
|
178
|
+
it('uses the day unit as fallback for an unknown period type', () => {
|
|
179
|
+
expect(convertDateToLucene('date.range.3.unknown')).toBe('[now-3d TO now]');
|
|
180
|
+
});
|
|
181
|
+
it('handles multi-unit amounts', () => {
|
|
182
|
+
expect(convertDateToLucene('date.range.3.day')).toBe('[now-3d TO now]');
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
describe('convertCustomDateRangeToLucene', () => {
|
|
186
|
+
it('formats a custom date range', () => {
|
|
187
|
+
expect(convertCustomDateRangeToLucene('2021-01-01', '2021-12-31')).toBe('[2021-01-01 TO 2021-12-31]');
|
|
188
|
+
});
|
|
189
|
+
it('works with ISO datetime strings', () => {
|
|
190
|
+
expect(convertCustomDateRangeToLucene('2021-01-01T00:00:00Z', '2021-12-31T23:59:59Z')).toBe('[2021-01-01T00:00:00Z TO 2021-12-31T23:59:59Z]');
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
describe('convertLuceneToDate', () => {
|
|
194
|
+
it('converts a 1-day lucene range back to "date.range.1.day"', () => {
|
|
195
|
+
expect(convertLuceneToDate('event.created:[now-1d TO now]')).toBe('date.range.1.day');
|
|
196
|
+
});
|
|
197
|
+
it('converts a 1-week lucene range back to "date.range.1.week"', () => {
|
|
198
|
+
expect(convertLuceneToDate('event.created:[now-1w TO now]')).toBe('date.range.1.week');
|
|
199
|
+
});
|
|
200
|
+
it('converts a 1-month lucene range back to "date.range.1.month"', () => {
|
|
201
|
+
expect(convertLuceneToDate('event.created:[now-1M TO now]')).toBe('date.range.1.month');
|
|
202
|
+
});
|
|
203
|
+
it('returns the input unchanged when there is no colon (not a field query)', () => {
|
|
204
|
+
expect(convertLuceneToDate('*')).toBe('*');
|
|
205
|
+
});
|
|
206
|
+
it('falls back to "day" for an unrecognised unit suffix', () => {
|
|
207
|
+
expect(convertLuceneToDate('event.created:[now-5z TO now]')).toBe('date.range.5.day');
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
describe('tryParse', () => {
|
|
211
|
+
it('parses valid JSON and returns the value', () => {
|
|
212
|
+
expect(tryParse('{"a":1}')).toEqual({ a: 1 });
|
|
213
|
+
});
|
|
214
|
+
it('parses a JSON array', () => {
|
|
215
|
+
expect(tryParse('[1,2,3]')).toEqual([1, 2, 3]);
|
|
216
|
+
});
|
|
217
|
+
it('returns the raw string when JSON is invalid', () => {
|
|
218
|
+
expect(tryParse('not json')).toBe('not json');
|
|
219
|
+
});
|
|
220
|
+
it('parses a quoted JSON string', () => {
|
|
221
|
+
expect(tryParse('"hello"')).toBe('hello');
|
|
222
|
+
});
|
|
223
|
+
it('returns the raw string for partially-valid JSON', () => {
|
|
224
|
+
expect(tryParse('{invalid}')).toBe('{invalid}');
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
describe('flattenDeep', () => {
|
|
228
|
+
it('flattens a simple nested object', () => {
|
|
229
|
+
const result = flattenDeep({ a: { b: 1 } });
|
|
230
|
+
expect(result).toEqual({ 'a.b': 1 });
|
|
231
|
+
});
|
|
232
|
+
it('leaves a flat object unchanged', () => {
|
|
233
|
+
const result = flattenDeep({ a: 1, b: 2 });
|
|
234
|
+
expect(result).toEqual({ a: 1, b: 2 });
|
|
235
|
+
});
|
|
236
|
+
it('flattens arrays of objects by merging values under a common key', () => {
|
|
237
|
+
const result = flattenDeep({ items: [{ id: 'x' }, { id: 'y' }] });
|
|
238
|
+
expect(result['items.id']).toEqual(['x', 'y']);
|
|
239
|
+
});
|
|
240
|
+
it('keeps a primitive array as-is', () => {
|
|
241
|
+
const result = flattenDeep({ tags: ['a', 'b', 'c'] });
|
|
242
|
+
expect(result.tags).toEqual(['a', 'b', 'c']);
|
|
243
|
+
});
|
|
244
|
+
it('handles an empty object', () => {
|
|
245
|
+
expect(flattenDeep({})).toEqual({});
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
describe('formatDate', () => {
|
|
249
|
+
it('returns "?" for a falsy value', () => {
|
|
250
|
+
expect(formatDate(null)).toBe('?');
|
|
251
|
+
});
|
|
252
|
+
it('returns "?" for an empty string', () => {
|
|
253
|
+
expect(formatDate('')).toBe('?');
|
|
254
|
+
});
|
|
255
|
+
it('formats an ISO string as UTC in YYYY/MM/DD HH:mm:ss format', () => {
|
|
256
|
+
// 2021-06-15T12:30:45Z → UTC → "2021/06/15 12:30:45"
|
|
257
|
+
expect(formatDate('2021-06-15T12:30:45Z')).toBe('2021/06/15 12:30:45');
|
|
258
|
+
});
|
|
259
|
+
it('formats a Date object correctly', () => {
|
|
260
|
+
const date = new Date('2023-01-01T00:00:00Z');
|
|
261
|
+
expect(formatDate(date)).toBe('2023/01/01 00:00:00');
|
|
262
|
+
});
|
|
263
|
+
it('formats a unix timestamp (ms) correctly', () => {
|
|
264
|
+
// 1000ms = 1970-01-01T00:00:01Z
|
|
265
|
+
expect(formatDate(1000)).toBe('1970/01/01 00:00:01');
|
|
266
|
+
});
|
|
267
|
+
it('returns "?" for a numeric 0 (treated as falsy by the guard)', () => {
|
|
268
|
+
expect(formatDate(0)).toBe('?');
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
describe('twitterShort', () => {
|
|
272
|
+
it('returns "?" for a falsy value', () => {
|
|
273
|
+
expect(twitterShort(null)).toBe('?');
|
|
274
|
+
});
|
|
275
|
+
it('returns "?" for the literal string "?"', () => {
|
|
276
|
+
expect(twitterShort('?')).toBe('?');
|
|
277
|
+
});
|
|
278
|
+
it('returns a non-empty relative string for a recent date', () => {
|
|
279
|
+
const result = twitterShort(new Date().toISOString());
|
|
280
|
+
expect(result).toBeTruthy();
|
|
281
|
+
expect(typeof result).toBe('string');
|
|
282
|
+
});
|
|
283
|
+
it('returns "a few seconds ago" for a date just in the past', () => {
|
|
284
|
+
const recent = new Date(Date.now() - 2000).toISOString();
|
|
285
|
+
expect(twitterShort(recent)).toBe('a few seconds ago');
|
|
286
|
+
});
|
|
287
|
+
it('returns a sensible relative string for a date one year in the past', () => {
|
|
288
|
+
const oneYearAgo = new Date(Date.now() - 365 * 24 * 60 * 60 * 1000).toISOString();
|
|
289
|
+
const result = twitterShort(oneYearAgo);
|
|
290
|
+
expect(result).toMatch(/year/);
|
|
291
|
+
});
|
|
292
|
+
});
|
package/utils/viewUtils.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { buildViewUrl } from './viewUtils';
|
|
3
|
+
const makeView = (overrides = {}) => ({
|
|
4
|
+
view_id: 'view-1',
|
|
5
|
+
title: 'Test View',
|
|
6
|
+
query: 'howler.status:open',
|
|
7
|
+
sort: 'event.created desc',
|
|
8
|
+
span: 'date.range.1.month',
|
|
9
|
+
type: 'personal',
|
|
10
|
+
owner: 'testuser',
|
|
11
|
+
...overrides
|
|
12
|
+
});
|
|
13
|
+
describe('buildViewUrl', () => {
|
|
14
|
+
it('includes the view_id as the "view" query param', () => {
|
|
15
|
+
const url = buildViewUrl(makeView({ view_id: 'abc-123' }));
|
|
16
|
+
expect(url).toContain('view=abc-123');
|
|
17
|
+
});
|
|
18
|
+
it('starts with /search', () => {
|
|
19
|
+
const url = buildViewUrl(makeView());
|
|
20
|
+
expect(url.startsWith('/search?')).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
it('includes the span param when provided', () => {
|
|
23
|
+
const url = buildViewUrl(makeView({ span: 'date.range.1.week' }));
|
|
24
|
+
expect(url).toContain('span=date.range.1.week');
|
|
25
|
+
});
|
|
26
|
+
it('omits the span param when span is undefined', () => {
|
|
27
|
+
const url = buildViewUrl(makeView({ span: undefined }));
|
|
28
|
+
expect(url).not.toContain('span=');
|
|
29
|
+
});
|
|
30
|
+
it('includes the sort param when provided', () => {
|
|
31
|
+
const url = buildViewUrl(makeView({ sort: 'event.created asc' }));
|
|
32
|
+
expect(url).toContain('sort=event.created+asc');
|
|
33
|
+
});
|
|
34
|
+
it('omits the sort param when sort is undefined', () => {
|
|
35
|
+
const url = buildViewUrl(makeView({ sort: undefined }));
|
|
36
|
+
expect(url).not.toContain('sort=');
|
|
37
|
+
});
|
|
38
|
+
it('builds a complete URL with all fields present', () => {
|
|
39
|
+
const url = buildViewUrl(makeView({ view_id: 'v1', span: 'date.range.1.day', sort: 'event.created desc' }));
|
|
40
|
+
const parsed = new URL(url, 'http://localhost');
|
|
41
|
+
expect(parsed.searchParams.get('view')).toBe('v1');
|
|
42
|
+
expect(parsed.searchParams.get('span')).toBe('date.range.1.day');
|
|
43
|
+
expect(parsed.searchParams.get('sort')).toBe('event.created desc');
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/// <reference types="vitest" />
|
|
2
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
3
|
+
import getXSRFCookie from './xsrf';
|
|
4
|
+
describe('getXSRFCookie', () => {
|
|
5
|
+
const originalDescriptor = Object.getOwnPropertyDescriptor(document, 'cookie');
|
|
6
|
+
const setCookie = (value) => {
|
|
7
|
+
Object.defineProperty(document, 'cookie', {
|
|
8
|
+
get: () => value,
|
|
9
|
+
configurable: true
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
if (originalDescriptor) {
|
|
14
|
+
Object.defineProperty(document, 'cookie', originalDescriptor);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
it('returns null when document.cookie is empty', () => {
|
|
18
|
+
setCookie('');
|
|
19
|
+
expect(getXSRFCookie()).toBeNull();
|
|
20
|
+
});
|
|
21
|
+
it('returns null when XSRF-TOKEN is not among the cookies', () => {
|
|
22
|
+
setCookie('session=abc; theme=dark');
|
|
23
|
+
expect(getXSRFCookie()).toBeNull();
|
|
24
|
+
});
|
|
25
|
+
it('returns the XSRF-TOKEN value when it is the only cookie', () => {
|
|
26
|
+
setCookie('XSRF-TOKEN=my-token');
|
|
27
|
+
expect(getXSRFCookie()).toBe('my-token');
|
|
28
|
+
});
|
|
29
|
+
it('returns the XSRF-TOKEN value when it appears among other cookies', () => {
|
|
30
|
+
setCookie('session=abc; XSRF-TOKEN=csrf-value; theme=dark');
|
|
31
|
+
expect(getXSRFCookie()).toBe('csrf-value');
|
|
32
|
+
});
|
|
33
|
+
it('returns the XSRF-TOKEN value when it appears first', () => {
|
|
34
|
+
setCookie('XSRF-TOKEN=first-token; session=abc');
|
|
35
|
+
expect(getXSRFCookie()).toBe('first-token');
|
|
36
|
+
});
|
|
37
|
+
it('returns the XSRF-TOKEN value when it appears last', () => {
|
|
38
|
+
setCookie('session=abc; XSRF-TOKEN=last-token');
|
|
39
|
+
expect(getXSRFCookie()).toBe('last-token');
|
|
40
|
+
});
|
|
41
|
+
});
|
package/api/search/case.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { HowlerSearchRequest, HowlerSearchResponse } from '@cccsaurora/howler-ui/api/search';
|
|
2
|
-
import type { Case } from '@cccsaurora/howler-ui/models/entities/generated/Case';
|
|
3
|
-
export declare const uri: () => string;
|
|
4
|
-
export declare const post: (request?: HowlerSearchRequest) => Promise<HowlerSearchResponse<Case>>;
|
package/api/search/case.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { hpost, joinUri } from '@cccsaurora/howler-ui/api';
|
|
2
|
-
import { uri as parentUri } from '@cccsaurora/howler-ui/api/search';
|
|
3
|
-
export const uri = () => {
|
|
4
|
-
return joinUri(parentUri(), 'case');
|
|
5
|
-
};
|
|
6
|
-
export const post = (request) => {
|
|
7
|
-
return hpost(uri(), { ...(request || {}), query: request?.query || 'case_id:*' });
|
|
8
|
-
};
|
package/api/socket/index.d.ts
DELETED
package/api/socket/index.js
DELETED
package/api/socket/viewers.d.ts
DELETED
package/api/socket/viewers.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { hget, joinAllUri } from '@cccsaurora/howler-ui/api';
|
|
2
|
-
import { uri as parentUri } from '@cccsaurora/howler-ui/api/socket';
|
|
3
|
-
export const uri = (entityId) => {
|
|
4
|
-
return entityId ? joinAllUri(parentUri(), 'viewers', entityId) : joinAllUri(parentUri(), 'viewers');
|
|
5
|
-
};
|
|
6
|
-
export const get = async (entityId) => {
|
|
7
|
-
return hget(uri(entityId));
|
|
8
|
-
};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
// ---------------------------------------------------------------------------
|
|
3
|
-
// Hoisted mocks
|
|
4
|
-
// ---------------------------------------------------------------------------
|
|
5
|
-
const mockHget = vi.hoisted(() => vi.fn());
|
|
6
|
-
vi.mock('api', async () => {
|
|
7
|
-
const urlJoin = (await import('url-join')).default;
|
|
8
|
-
return {
|
|
9
|
-
hget: mockHget,
|
|
10
|
-
joinAllUri: (...parts) => urlJoin(...parts)
|
|
11
|
-
};
|
|
12
|
-
});
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
// Import after mocks
|
|
15
|
-
// ---------------------------------------------------------------------------
|
|
16
|
-
// eslint-disable-next-line
|
|
17
|
-
import { get } from './viewers';
|
|
18
|
-
// ---------------------------------------------------------------------------
|
|
19
|
-
// Setup
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
beforeEach(() => {
|
|
22
|
-
mockHget.mockReset();
|
|
23
|
-
});
|
|
24
|
-
// ---------------------------------------------------------------------------
|
|
25
|
-
// Tests
|
|
26
|
-
// ---------------------------------------------------------------------------
|
|
27
|
-
describe('viewers API', () => {
|
|
28
|
-
describe('get', () => {
|
|
29
|
-
it('calls hget with the correct URI', async () => {
|
|
30
|
-
mockHget.mockResolvedValue(['alice', 'bob']);
|
|
31
|
-
await get('entity-1');
|
|
32
|
-
expect(mockHget).toHaveBeenCalledWith('/socket/v1/viewers/entity-1');
|
|
33
|
-
});
|
|
34
|
-
it('returns the result from hget', async () => {
|
|
35
|
-
mockHget.mockResolvedValue(['alice', 'bob']);
|
|
36
|
-
const result = await get('entity-1');
|
|
37
|
-
expect(result).toEqual(['alice', 'bob']);
|
|
38
|
-
});
|
|
39
|
-
it('propagates errors from hget', async () => {
|
|
40
|
-
mockHget.mockRejectedValue(new Error('not found'));
|
|
41
|
-
await expect(get('entity-1')).rejects.toThrow('not found');
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
});
|
package/api/v2/case/index.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import * as items from '@cccsaurora/howler-ui/api/v2/case/items';
|
|
2
|
-
import * as rules from '@cccsaurora/howler-ui/api/v2/case/rules';
|
|
3
|
-
import type { Case } from '@cccsaurora/howler-ui/models/entities/generated/Case';
|
|
4
|
-
export declare const uri: (id?: string) => string;
|
|
5
|
-
export declare const get: (id: string) => Promise<Case>;
|
|
6
|
-
export declare const post: (newData: Partial<Case>) => Promise<Case>;
|
|
7
|
-
export declare const put: (id: string, _case: Partial<Case>) => Promise<Case>;
|
|
8
|
-
export declare const del: (id: string) => Promise<void>;
|
|
9
|
-
export { items, rules };
|
package/api/v2/case/index.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// eslint-disable-next-line import/no-cycle
|
|
2
|
-
import { hdelete, hget, hpost, hput, joinAllUri, joinUri } from '@cccsaurora/howler-ui/api';
|
|
3
|
-
import { uri as parentUri } from '@cccsaurora/howler-ui/api/v2';
|
|
4
|
-
import * as items from '@cccsaurora/howler-ui/api/v2/case/items';
|
|
5
|
-
import * as rules from '@cccsaurora/howler-ui/api/v2/case/rules';
|
|
6
|
-
export const uri = (id) => {
|
|
7
|
-
return id ? joinAllUri(parentUri(), 'case', id) : joinUri(parentUri(), 'case');
|
|
8
|
-
};
|
|
9
|
-
export const get = (id) => {
|
|
10
|
-
return hget(uri(id));
|
|
11
|
-
};
|
|
12
|
-
export const post = (newData) => {
|
|
13
|
-
return hpost(uri(), newData);
|
|
14
|
-
};
|
|
15
|
-
export const put = (id, _case) => {
|
|
16
|
-
return hput(uri(id), _case);
|
|
17
|
-
};
|
|
18
|
-
export const del = (id) => {
|
|
19
|
-
return hdelete(uri(id));
|
|
20
|
-
};
|
|
21
|
-
export { items, rules };
|
package/api/v2/case/items.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { Case } from '@cccsaurora/howler-ui/models/entities/generated/Case';
|
|
2
|
-
import type { Item } from '@cccsaurora/howler-ui/models/entities/generated/Item';
|
|
3
|
-
export declare const uri: (id: string) => string;
|
|
4
|
-
export declare const post: (id: string, newData: Item) => Promise<Case>;
|
|
5
|
-
export declare const del: (id: string, values: string | string[]) => Promise<Case>;
|
|
6
|
-
export declare const put: (id: string, value: string, newPath: string) => Promise<Case>;
|
package/api/v2/case/items.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// eslint-disable-next-line import/no-cycle
|
|
2
|
-
import { hdelete, hpost, hput, joinUri } from '@cccsaurora/howler-ui/api';
|
|
3
|
-
import { uri as parentUri } from '@cccsaurora/howler-ui/api/v2/case';
|
|
4
|
-
export const uri = (id) => {
|
|
5
|
-
return joinUri(parentUri(id), 'items');
|
|
6
|
-
};
|
|
7
|
-
export const post = (id, newData) => {
|
|
8
|
-
return hpost(uri(id), newData);
|
|
9
|
-
};
|
|
10
|
-
export const del = (id, values) => {
|
|
11
|
-
if (!Array.isArray(values)) {
|
|
12
|
-
values = [values];
|
|
13
|
-
}
|
|
14
|
-
return hdelete(uri(id), { values });
|
|
15
|
-
};
|
|
16
|
-
export const put = (id, value, newPath) => {
|
|
17
|
-
return hput(uri(id), { value, new_path: newPath });
|
|
18
|
-
};
|
package/api/v2/case/rules.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { Case } from '@cccsaurora/howler-ui/models/entities/generated/Case';
|
|
2
|
-
import type { Rule } from '@cccsaurora/howler-ui/models/entities/generated/Rule';
|
|
3
|
-
export declare const uri: (caseId: string, ruleId?: string) => string;
|
|
4
|
-
export declare const post: (caseId: string, ruleData: Partial<Rule>) => Promise<Case>;
|
|
5
|
-
export declare const del: (caseId: string, ruleId: string) => Promise<Case>;
|
|
6
|
-
export declare const put: (caseId: string, ruleId: string, data: Partial<Rule>) => Promise<Case>;
|
package/api/v2/case/rules.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// eslint-disable-next-line import/no-cycle
|
|
2
|
-
import { hdelete, hpost, hput, joinAllUri } from '@cccsaurora/howler-ui/api';
|
|
3
|
-
import { uri as parentUri } from '@cccsaurora/howler-ui/api/v2/case';
|
|
4
|
-
export const uri = (caseId, ruleId) => {
|
|
5
|
-
if (ruleId) {
|
|
6
|
-
return joinAllUri(parentUri(caseId), 'rules', ruleId);
|
|
7
|
-
}
|
|
8
|
-
return joinAllUri(parentUri(caseId), 'rules');
|
|
9
|
-
};
|
|
10
|
-
export const post = (caseId, ruleData) => {
|
|
11
|
-
return hpost(uri(caseId), ruleData);
|
|
12
|
-
};
|
|
13
|
-
export const del = (caseId, ruleId) => {
|
|
14
|
-
return hdelete(uri(caseId, ruleId));
|
|
15
|
-
};
|
|
16
|
-
export const put = (caseId, ruleId, data) => {
|
|
17
|
-
return hput(uri(caseId, ruleId), data);
|
|
18
|
-
};
|
package/api/v2/index.d.ts
DELETED
package/api/v2/index.js
DELETED
package/api/v2/search/facet.d.ts
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { HowlerFacetSearchRequest, HowlerFacetSearchResponse } from '@cccsaurora/howler-ui/api/search/facet';
|
|
2
|
-
export declare const uri: (indexes: string[]) => string;
|
|
3
|
-
export declare const post: (indexes: string | string[], request?: HowlerFacetSearchRequest) => Promise<HowlerFacetSearchResponse>;
|
package/api/v2/search/facet.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// eslint-disable-next-line import/no-cycle
|
|
2
|
-
import { hpost, joinAllUri } from '@cccsaurora/howler-ui/api';
|
|
3
|
-
import { uri as parentUri } from '@cccsaurora/howler-ui/api/v2';
|
|
4
|
-
export const uri = (indexes) => {
|
|
5
|
-
return joinAllUri(parentUri(), 'search', 'facet', indexes.join(','));
|
|
6
|
-
};
|
|
7
|
-
export const post = (indexes, request) => {
|
|
8
|
-
if (typeof indexes === 'string') {
|
|
9
|
-
indexes = indexes.split(',');
|
|
10
|
-
}
|
|
11
|
-
return hpost(uri(indexes), { ...(request || {}), query: request?.query || 'howler.id:*' });
|
|
12
|
-
};
|
package/api/v2/search/index.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { HowlerSearchRequest, HowlerSearchResponse } from '@cccsaurora/howler-ui/api/search';
|
|
2
|
-
import * as facet from './facet';
|
|
3
|
-
export declare const uri: (indexes: string[]) => string;
|
|
4
|
-
export declare const post: <T = any>(indexes: string | string[], request?: HowlerSearchRequest) => Promise<HowlerSearchResponse<T>>;
|
|
5
|
-
export { facet };
|
package/api/v2/search/index.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
// eslint-disable-next-line import/no-cycle
|
|
2
|
-
import { hpost, joinAllUri } from '@cccsaurora/howler-ui/api';
|
|
3
|
-
import { uri as parentUri } from '@cccsaurora/howler-ui/api/v2';
|
|
4
|
-
import { identity, isNil } from 'lodash-es';
|
|
5
|
-
import * as facet from './facet';
|
|
6
|
-
export const uri = (indexes) => {
|
|
7
|
-
return joinAllUri(parentUri(), 'search', indexes.join(','));
|
|
8
|
-
};
|
|
9
|
-
export const post = (indexes, request) => {
|
|
10
|
-
if (isNil(indexes)) {
|
|
11
|
-
throw new Error('Indexes cannot be null or undefined.');
|
|
12
|
-
}
|
|
13
|
-
if (typeof indexes === 'string') {
|
|
14
|
-
indexes = indexes.split(',').filter(identity);
|
|
15
|
-
}
|
|
16
|
-
if (indexes.some(index => !['hit', 'observable', 'case'].includes(index))) {
|
|
17
|
-
throw new Error('Only hit, case, and observable indexes should be used currently.');
|
|
18
|
-
}
|
|
19
|
-
if (indexes.length < 1) {
|
|
20
|
-
throw new Error('indexes must have length of at least 1.');
|
|
21
|
-
}
|
|
22
|
-
return hpost(uri(indexes), { ...(request || {}), query: request?.query || 'howler.id:*' });
|
|
23
|
-
};
|
|
24
|
-
export { facet };
|