Skip to content

Commit 56fa953

Browse files
test(common): coverage for desktop tab navigation (hoppscotch#5291)
This adds test coverage for the tab navigation methods added in FE-907 the native tab keyboard shortcuts implementation. Closes FE-909 The recently implemented desktop tab keyboard shortcuts added new tab navigation methods to the `TabService` class (`goToNextTab()`, `goToPreviousTab()`, `goToFirstTab()`, `goToLastTab()`, `goToTabByIndex()`, and `reopenClosedTab()`). These methods lacked corresponding test coverage.
1 parent f5aee59 commit 56fa953

File tree

1 file changed

+209
-0
lines changed

1 file changed

+209
-0
lines changed

packages/hoppscotch-common/src/services/tab/__tests__/tab.service.spec.ts

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,213 @@ describe("TabService", () => {
132132

133133
expect(service.getActiveTabs().value.length).toEqual(1)
134134
})
135+
136+
describe("Tab Navigation", () => {
137+
it("should navigate to next tab", () => {
138+
const container = new TestContainer()
139+
const service = container.bind(MockTabService)
140+
141+
const tab2 = service.createNewTab({ request: "second request" })
142+
const tab3 = service.createNewTab({ request: "third request" })
143+
144+
service.setActiveTab("test")
145+
expect(service.getActiveTab()?.id).toEqual("test")
146+
147+
service.goToNextTab()
148+
expect(service.getActiveTab()?.id).toEqual(tab2.id)
149+
150+
service.goToNextTab()
151+
expect(service.getActiveTab()?.id).toEqual(tab3.id)
152+
153+
service.goToNextTab()
154+
expect(service.getActiveTab()?.id).toEqual("test")
155+
})
156+
157+
it("should navigate to previous tab", () => {
158+
const container = new TestContainer()
159+
const service = container.bind(MockTabService)
160+
161+
const tab2 = service.createNewTab({ request: "second request" })
162+
const tab3 = service.createNewTab({ request: "third request" })
163+
164+
service.setActiveTab(tab3.id)
165+
expect(service.getActiveTab()?.id).toEqual(tab3.id)
166+
167+
service.goToPreviousTab()
168+
expect(service.getActiveTab()?.id).toEqual(tab2.id)
169+
170+
service.goToPreviousTab()
171+
expect(service.getActiveTab()?.id).toEqual("test")
172+
173+
service.goToPreviousTab()
174+
expect(service.getActiveTab()?.id).toEqual(tab3.id)
175+
})
176+
177+
it("should navigate to first tab", () => {
178+
const container = new TestContainer()
179+
const service = container.bind(MockTabService)
180+
181+
// Unused variable that improves readability.
182+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
183+
const tab2 = service.createNewTab({ request: "second request" })
184+
const tab3 = service.createNewTab({ request: "third request" })
185+
186+
service.setActiveTab(tab3.id)
187+
expect(service.getActiveTab()?.id).toEqual(tab3.id)
188+
189+
service.goToFirstTab()
190+
expect(service.getActiveTab()?.id).toEqual("test")
191+
})
192+
193+
it("should navigate to last tab", () => {
194+
const container = new TestContainer()
195+
const service = container.bind(MockTabService)
196+
197+
// Unused variable that improves readability.
198+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
199+
const tab2 = service.createNewTab({ request: "second request" })
200+
const tab3 = service.createNewTab({ request: "third request" })
201+
202+
service.setActiveTab("test")
203+
expect(service.getActiveTab()?.id).toEqual("test")
204+
205+
service.goToLastTab()
206+
expect(service.getActiveTab()?.id).toEqual(tab3.id)
207+
})
208+
209+
it("should navigate to tab by index", () => {
210+
const container = new TestContainer()
211+
const service = container.bind(MockTabService)
212+
213+
const tab2 = service.createNewTab({ request: "second request" })
214+
const tab3 = service.createNewTab({ request: "third request" })
215+
216+
service.goToTabByIndex(1)
217+
expect(service.getActiveTab()?.id).toEqual("test")
218+
219+
service.goToTabByIndex(2)
220+
expect(service.getActiveTab()?.id).toEqual(tab2.id)
221+
222+
service.goToTabByIndex(3)
223+
expect(service.getActiveTab()?.id).toEqual(tab3.id)
224+
})
225+
226+
it("should handle invalid tab index gracefully", () => {
227+
const container = new TestContainer()
228+
const service = container.bind(MockTabService)
229+
230+
const originalActiveTab = service.getActiveTab()
231+
232+
service.goToTabByIndex(0) // Invalid (0-based)
233+
expect(service.getActiveTab()?.id).toEqual(originalActiveTab?.id)
234+
235+
service.goToTabByIndex(5) // Invalid (out of range)
236+
expect(service.getActiveTab()?.id).toEqual(originalActiveTab?.id)
237+
238+
service.goToTabByIndex(-1) // Invalid (negative)
239+
expect(service.getActiveTab()?.id).toEqual(originalActiveTab?.id)
240+
})
241+
242+
it("should handle navigation with single tab", () => {
243+
const container = new TestContainer()
244+
const service = container.bind(MockTabService)
245+
246+
const originalActiveTab = service.getActiveTab()
247+
248+
service.goToNextTab()
249+
expect(service.getActiveTab()?.id).toEqual(originalActiveTab?.id)
250+
251+
service.goToPreviousTab()
252+
expect(service.getActiveTab()?.id).toEqual(originalActiveTab?.id)
253+
254+
service.goToFirstTab()
255+
expect(service.getActiveTab()?.id).toEqual(originalActiveTab?.id)
256+
257+
service.goToLastTab()
258+
expect(service.getActiveTab()?.id).toEqual(originalActiveTab?.id)
259+
})
260+
})
261+
262+
// NOTE: This feature is currently WIP.
263+
describe("Recently Closed Tabs", () => {
264+
it("should reopen closed tab", () => {
265+
const container = new TestContainer()
266+
const service = container.bind(MockTabService)
267+
268+
const tab2 = service.createNewTab({ request: "second request" })
269+
expect(service.getActiveTabs().value.length).toEqual(2)
270+
271+
service.setActiveTab("test")
272+
273+
service.closeTab(tab2.id)
274+
expect(service.getActiveTabs().value.length).toEqual(1)
275+
expect(service.getActiveTab()?.id).toEqual("test")
276+
277+
const reopened = service.reopenClosedTab()
278+
expect(reopened).toBe(true)
279+
expect(service.getActiveTabs().value.length).toEqual(2)
280+
expect(service.getActiveTab()?.id).toEqual(tab2.id)
281+
})
282+
283+
it("should return false when no tabs to reopen", () => {
284+
const container = new TestContainer()
285+
const service = container.bind(MockTabService)
286+
287+
const reopened = service.reopenClosedTab()
288+
expect(reopened).toBe(false)
289+
expect(service.getActiveTabs().value.length).toEqual(1)
290+
})
291+
292+
it("should maintain closed tabs history with correct order", () => {
293+
const container = new TestContainer()
294+
const service = container.bind(MockTabService)
295+
296+
const tab2 = service.createNewTab({ request: "second request" })
297+
const tab3 = service.createNewTab({ request: "third request" })
298+
const tab4 = service.createNewTab({ request: "fourth request" })
299+
300+
service.closeTab(tab2.id)
301+
service.closeTab(tab3.id)
302+
service.closeTab(tab4.id)
303+
304+
expect(service.getActiveTabs().value.length).toEqual(1)
305+
306+
service.reopenClosedTab()
307+
expect(service.getActiveTab()?.id).toEqual(tab4.id)
308+
309+
service.reopenClosedTab()
310+
expect(service.getActiveTab()?.id).toEqual(tab3.id)
311+
312+
service.reopenClosedTab()
313+
expect(service.getActiveTab()?.id).toEqual(tab2.id)
314+
315+
expect(service.getActiveTabs().value.length).toEqual(4)
316+
})
317+
318+
it("should restore tab at correct position when reopened", () => {
319+
const container = new TestContainer()
320+
const service = container.bind(MockTabService)
321+
322+
const tab2 = service.createNewTab({ request: "second request" })
323+
const tab3 = service.createNewTab({ request: "third request" })
324+
325+
const originalOrdering = service
326+
.getActiveTabs()
327+
.value.map((tab) => tab.id)
328+
expect(originalOrdering).toEqual(["test", tab2.id, tab3.id])
329+
330+
service.closeTab(tab2.id)
331+
expect(service.getActiveTabs().value.map((tab) => tab.id)).toEqual([
332+
"test",
333+
tab3.id,
334+
])
335+
336+
service.reopenClosedTab()
337+
expect(service.getActiveTabs().value.map((tab) => tab.id)).toEqual([
338+
"test",
339+
tab2.id,
340+
tab3.id,
341+
])
342+
})
343+
})
135344
})

0 commit comments

Comments
 (0)