FloatingMobileToolbar.utils.test.ts 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import { describe, expect, it } from 'vitest'
  2. import {
  3. clampPosition,
  4. getNextPosition,
  5. getToolbarStyle,
  6. isMenuContent,
  7. shouldShowMenuButton,
  8. } from './FloatingMobileToolbar.utils'
  9. describe('isMenuContent', () => {
  10. it('returns false for null', () => {
  11. expect(isMenuContent(null)).toBe(false)
  12. })
  13. it('returns false for sidebar id string', () => {
  14. expect(isMenuContent('help-panel')).toBe(false)
  15. })
  16. it('returns true for non-string content', () => {
  17. expect(isMenuContent({})).toBe(true)
  18. expect(isMenuContent(0)).toBe(true)
  19. })
  20. })
  21. describe('shouldShowMenuButton', () => {
  22. it('returns true for project, org, account paths', () => {
  23. expect(shouldShowMenuButton('/project/ref')).toBe(true)
  24. expect(shouldShowMenuButton('/org/slug')).toBe(true)
  25. expect(shouldShowMenuButton('/account/me')).toBe(true)
  26. })
  27. it('returns false for other paths', () => {
  28. expect(shouldShowMenuButton('/organizations')).toBe(false)
  29. expect(shouldShowMenuButton('/')).toBe(false)
  30. })
  31. })
  32. describe('clampPosition', () => {
  33. const viewport = { width: 400, height: 800 }
  34. const navSize = { width: 100, height: 48 }
  35. it('clamps to viewport bounds', () => {
  36. const next = clampPosition({ x: 0, y: 0 }, { dx: 500, dy: 900 }, viewport, navSize)
  37. expect(next.x).toBe(300)
  38. expect(next.y).toBe(752)
  39. })
  40. it('does not go negative', () => {
  41. const next = clampPosition({ x: 10, y: 10 }, { dx: -20, dy: -20 }, viewport, navSize)
  42. expect(next.x).toBe(0)
  43. expect(next.y).toBe(0)
  44. })
  45. })
  46. describe('getNextPosition', () => {
  47. const viewport = { width: 400, height: 800 }
  48. const navSize = { width: 100, height: 48 }
  49. const dragStart = { x: 50, y: 100, startX: 60, startY: 110 }
  50. it('returns null when under threshold', () => {
  51. expect(getNextPosition(dragStart, 62, 111, viewport, navSize, 8)).toBeNull()
  52. })
  53. it('returns clamped position when over threshold', () => {
  54. const next = getNextPosition(dragStart, 80, 130, viewport, navSize, 5)
  55. expect(next).toEqual({ x: 70, y: 120 })
  56. })
  57. })
  58. describe('getToolbarStyle', () => {
  59. const viewport = { width: 390, height: 844 }
  60. const navSize = { width: 200, height: 48 }
  61. it('returns style with transform and zIndex', () => {
  62. const style = getToolbarStyle({
  63. position: null,
  64. navSize,
  65. isSheetOpen: false,
  66. viewport,
  67. isDragging: false,
  68. })
  69. expect(style.zIndex).toBe(41)
  70. expect(style.transform).toBeDefined()
  71. expect(style.left).toBe('50%')
  72. })
  73. it('uses higher zIndex when sheet open', () => {
  74. const style = getToolbarStyle({
  75. position: null,
  76. navSize,
  77. isSheetOpen: true,
  78. viewport,
  79. isDragging: false,
  80. })
  81. expect(style.zIndex).toBe(101)
  82. })
  83. })