@@ -6,18 +6,32 @@ import MockAdapter from "axios-mock-adapter";
6
6
import flushPromises from "flush-promises" ;
7
7
import { createPinia } from "pinia" ;
8
8
import { getLocalVue } from "tests/jest/helpers" ;
9
+ import { ref } from "vue" ;
9
10
10
11
import toolsList from "@/components/ToolsView/testData/toolsList.json" ;
11
12
import toolsListInPanel from "@/components/ToolsView/testData/toolsListInPanel.json" ;
13
+ import { useUserLocalStorage } from "@/composables/userLocalStorage" ;
14
+ import { useToolStore } from "@/stores/toolStore" ;
12
15
13
- import viewsList from "./testData/viewsList.json" ;
16
+ import viewsListJson from "./testData/viewsList.json" ;
14
17
import { types_to_icons } from "./utilities" ;
15
18
16
19
import ToolPanel from "./ToolPanel.vue" ;
17
20
21
+ interface ToolPanelView {
22
+ id : string ;
23
+ model_class : string ;
24
+ name : string ;
25
+ description : string | null ;
26
+ view_type : string ;
27
+ searchable : boolean ;
28
+ }
29
+
18
30
const localVue = getLocalVue ( ) ;
19
31
20
32
const TEST_PANELS_URI = "/api/tool_panels" ;
33
+ const DEFAULT_VIEW_ID = "default" ;
34
+ const PANEL_VIEW_ERR_MSG = "Error loading panel view" ;
21
35
22
36
jest . mock ( "@/composables/config" , ( ) => ( {
23
37
useConfig : jest . fn ( ( ) => ( {
@@ -26,16 +40,59 @@ jest.mock("@/composables/config", () => ({
26
40
} ) ) ,
27
41
} ) ) ;
28
42
43
+ jest . mock ( "@/composables/userLocalStorage" , ( ) => ( {
44
+ useUserLocalStorage : jest . fn ( ( ) => ref ( DEFAULT_VIEW_ID ) ) ,
45
+ } ) ) ;
46
+
29
47
describe ( "ToolPanel" , ( ) => {
30
- it ( "test navigation of tool panel views menu" , async ( ) => {
48
+ const viewsList = viewsListJson as Record < string , ToolPanelView > ;
49
+
50
+ /** Mocks and stores a non-default panel view as the current panel view */
51
+ function storeNonDefaultView ( ) {
52
+ // find a view in object viewsList that is not DEFAULT_VIEW_ID
53
+ const viewKey = Object . keys ( viewsList ) . find ( ( id ) => id !== DEFAULT_VIEW_ID ) ;
54
+ if ( ! viewKey ) {
55
+ throw new Error ( "No non-default view found in viewsList" ) ;
56
+ }
57
+ const view = viewsList [ viewKey ] ;
58
+ if ( ! view ) {
59
+ throw new Error ( `View with key ${ viewKey } not found in viewsList` ) ;
60
+ }
61
+ // ref and useUserLocalStorage are already imported at the top
62
+ ( useUserLocalStorage as jest . Mock ) . mockImplementation ( ( ) => ref ( viewKey ) ) ;
63
+ return { viewKey, view } ;
64
+ }
65
+
66
+ /**
67
+ * Sets up wrapper for ToolPanel component
68
+ * @param {String } errorView If provided, we mock an error for this view
69
+ * @param {Boolean } failDefault If true and error view is provided, we
70
+ * mock an error for the default view as well
71
+ * @returns wrapper
72
+ */
73
+ async function createWrapper ( errorView = "" , failDefault = false ) {
31
74
const axiosMock = new MockAdapter ( axios ) ;
32
75
axiosMock
33
- . onGet ( / \/ a p i \/ t o o l _ p a n e l s \/ .* / )
34
- . reply ( 200 , toolsListInPanel )
35
76
. onGet ( `/api/tools?in_panel=False` )
36
77
. replyOnce ( 200 , toolsList )
37
78
. onGet ( TEST_PANELS_URI )
38
- . reply ( 200 , { default_panel_view : "default" , views : viewsList } ) ;
79
+ . reply ( 200 , { default_panel_view : DEFAULT_VIEW_ID , views : viewsList } ) ;
80
+
81
+ if ( errorView ) {
82
+ axiosMock . onGet ( `/api/tool_panels/${ errorView } ` ) . reply ( 400 , { err_msg : PANEL_VIEW_ERR_MSG } ) ;
83
+ if ( errorView !== DEFAULT_VIEW_ID && ! failDefault ) {
84
+ axiosMock . onGet ( `/api/tool_panels/${ DEFAULT_VIEW_ID } ` ) . reply ( 200 , toolsListInPanel ) ;
85
+ } else if ( failDefault ) {
86
+ axiosMock . onGet ( `/api/tool_panels/${ DEFAULT_VIEW_ID } ` ) . reply ( 400 , { err_msg : PANEL_VIEW_ERR_MSG } ) ;
87
+ }
88
+ } else {
89
+ // mock response for all panel views
90
+ axiosMock . onGet ( / \/ a p i \/ t o o l _ p a n e l s \/ .* / ) . reply ( 200 , toolsListInPanel ) ;
91
+ }
92
+
93
+ // setting this because for the default view, we just show "Tools" as the name
94
+ // even though the backend returns "Full Tool Panel"
95
+ viewsList [ DEFAULT_VIEW_ID ] ! . name = "Tools" ;
39
96
40
97
const pinia = createPinia ( ) ;
41
98
const wrapper = mount ( ToolPanel as object , {
@@ -55,12 +112,17 @@ describe("ToolPanel", () => {
55
112
56
113
await flushPromises ( ) ;
57
114
115
+ return { wrapper } ;
116
+ }
117
+
118
+ it ( "test navigation of tool panel views menu" , async ( ) => {
119
+ const { wrapper } = await createWrapper ( ) ;
58
120
// there is a panel view selector initially collapsed
59
121
expect ( wrapper . find ( ".panel-view-selector" ) . exists ( ) ) . toBe ( true ) ;
60
122
expect ( wrapper . find ( ".dropdown-menu.show" ) . exists ( ) ) . toBe ( false ) ;
61
123
62
124
// Test: starts up with a default panel view, click to open menu
63
- expect ( wrapper . find ( "#toolbox-heading" ) . text ( ) ) . toBe ( "Tools" ) ;
125
+ expect ( wrapper . find ( "#toolbox-heading" ) . text ( ) ) . toBe ( viewsList [ DEFAULT_VIEW_ID ] ! . name ) ;
64
126
await wrapper . find ( "#toolbox-heading" ) . trigger ( "click" ) ;
65
127
await flushPromises ( ) ;
66
128
@@ -75,7 +137,7 @@ describe("ToolPanel", () => {
75
137
for ( const [ key , value ] of Object . entries ( viewsList ) ) {
76
138
// find dropdown item
77
139
const currItem = dropdownMenu . find ( `[data-panel-id='${ key } ']` ) ;
78
- if ( key !== "default" ) {
140
+ if ( key !== DEFAULT_VIEW_ID ) {
79
141
// Test: check if the panel view has appropriate description
80
142
const description = currItem . attributes ( ) . title || null ;
81
143
expect ( description ) . toBe ( value . description ) ;
@@ -92,12 +154,50 @@ describe("ToolPanel", () => {
92
154
expect ( panelViewIcon . classes ( ) ) . toContain (
93
155
`fa-${ types_to_icons [ value . view_type as keyof typeof types_to_icons ] } `
94
156
) ;
95
- expect ( wrapper . find ( "#toolbox-heading" ) . text ( ) ) . toBe ( value . name ) ;
157
+ expect ( wrapper . find ( "#toolbox-heading" ) . text ( ) ) . toBe ( value ! . name ) ;
96
158
} else {
97
159
// Test: check if the default panel view is already selected, and no icon
98
160
expect ( currItem . find ( ".fa-check" ) . exists ( ) ) . toBe ( true ) ;
99
161
expect ( wrapper . find ( "[data-description='panel view header icon']" ) . exists ( ) ) . toBe ( false ) ;
100
162
}
101
163
}
102
164
} ) ;
165
+
166
+ it ( "initializes non default current panel view correctly" , async ( ) => {
167
+ const { viewKey, view } = storeNonDefaultView ( ) ;
168
+
169
+ const { wrapper } = await createWrapper ( ) ;
170
+
171
+ // starts up with a non default panel view
172
+ expect ( wrapper . find ( "#toolbox-heading" ) . text ( ) ) . toBe ( view ! . name ) ;
173
+ const toolStore = useToolStore ( ) ;
174
+ expect ( toolStore . currentPanelView ) . toBe ( viewKey ) ;
175
+ } ) ;
176
+
177
+ it ( "changes panel to default if current panel view throws error" , async ( ) => {
178
+ const { viewKey, view } = storeNonDefaultView ( ) ;
179
+
180
+ const { wrapper } = await createWrapper ( viewKey ) ;
181
+
182
+ // does not initialize non default panel view, and changes to default
183
+ expect ( wrapper . find ( "#toolbox-heading" ) . text ( ) ) . not . toBe ( view ! . name ) ;
184
+ expect ( wrapper . find ( "#toolbox-heading" ) . text ( ) ) . toBe ( viewsList [ DEFAULT_VIEW_ID ] ! . name ) ;
185
+ const toolStore = useToolStore ( ) ;
186
+ expect ( toolStore . currentPanelView ) . toBe ( DEFAULT_VIEW_ID ) ;
187
+
188
+ // toolbox loaded
189
+ expect ( wrapper . find ( '[data-description="panel toolbox"]' ) . exists ( ) ) . toBe ( true ) ;
190
+ } ) ;
191
+
192
+ it ( "simply shows error if even default panel view throws error" , async ( ) => {
193
+ const { viewKey } = storeNonDefaultView ( ) ;
194
+
195
+ const { wrapper } = await createWrapper ( viewKey , true ) ;
196
+
197
+ // toolbox not loaded
198
+ expect ( wrapper . find ( '[data-description="panel toolbox"]' ) . exists ( ) ) . toBe ( false ) ;
199
+
200
+ // error message shown
201
+ expect ( wrapper . find ( '[data-description="tool panel error message"]' ) . text ( ) ) . toBe ( PANEL_VIEW_ERR_MSG ) ;
202
+ } ) ;
103
203
} ) ;
0 commit comments