personal-setting-devices.spec.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { within } from '@testing-library/vue'
  3. import {
  4. checkSimpleTableContent,
  5. checkSimpleTableHeader,
  6. } from '#tests/support/components/checkSimpleTableContent.ts'
  7. import { visitView } from '#tests/support/components/visitView.ts'
  8. import { mockPermissions } from '#tests/support/mock-permissions.ts'
  9. import { mockUserCurrent } from '#tests/support/mock-userCurrent.ts'
  10. import { waitForNextTick } from '#tests/support/utils.ts'
  11. import { convertToGraphQLId } from '#shared/graphql/utils.ts'
  12. import { mockUserCurrentDeviceDeleteMutation } from '../graphql/mutations/userCurrentDeviceDelete.mocks.ts'
  13. import { mockUserCurrentDeviceListQuery } from '../graphql/queries/userCurrentDeviceList.mocks.ts'
  14. import { getUserCurrentDevicesUpdatesSubscriptionHandler } from '../graphql/subscriptions/userCurrentDevicesUpdates.mocks.ts'
  15. vi.hoisted(() => {
  16. vi.setSystemTime(new Date('2024-04-25T10:00:00Z'))
  17. })
  18. const generateFingerprintSpy = vi.fn()
  19. vi.mock('#shared/utils/browser.ts', () => {
  20. return {
  21. generateFingerprint: () => {
  22. generateFingerprintSpy()
  23. return 'dummy'
  24. },
  25. }
  26. })
  27. const userCurrentDeviceList = [
  28. {
  29. id: convertToGraphQLId('UserDevice', 1),
  30. name: 'Chrome on Mac',
  31. fingerprint: 'dummy',
  32. location: 'Germany, Berlin',
  33. updatedAt: '2024-02-01T12:00:00Z',
  34. },
  35. {
  36. id: convertToGraphQLId('UserDevice', 2),
  37. name: 'Firefox on Mac',
  38. fingerprint: 'random',
  39. location: 'Germany, Frankfurt',
  40. updatedAt: '2024-01-01T12:00:00Z',
  41. },
  42. ]
  43. const rowContents = [
  44. ['Chrome on Mac', 'Germany, Berlin', ['2024-02-01 12:00', '2 months ago']],
  45. [
  46. 'Firefox on Mac',
  47. 'Germany, Frankfurt',
  48. ['2024-01-01 12:00', '3 months ago'],
  49. ],
  50. ]
  51. describe('devices personal settings', () => {
  52. beforeEach(() => {
  53. mockUserCurrent({
  54. firstname: 'John',
  55. lastname: 'Doe',
  56. })
  57. mockPermissions(['user_preferences.device'])
  58. })
  59. afterAll(() => {
  60. vi.useRealTimers()
  61. })
  62. it('shows the list of all devices', async () => {
  63. mockUserCurrentDeviceListQuery({ userCurrentDeviceList })
  64. const view = await visitView('/personal-setting/devices')
  65. const tableHeaders = ['Name', 'Location', 'Most recent activity', 'Actions']
  66. checkSimpleTableHeader(view, tableHeaders)
  67. checkSimpleTableContent(view, rowContents)
  68. const table = within(view.getByRole('table'))
  69. expect(
  70. within(table.getAllByRole('row')[0]).getAllByRole('cell')[0],
  71. ).toHaveTextContent(/This device/)
  72. expect(
  73. table.getAllByRole('button', { name: 'Delete this device' }),
  74. ).toHaveLength(1)
  75. })
  76. it('can delete a device', async () => {
  77. mockUserCurrentDeviceListQuery({ userCurrentDeviceList })
  78. const view = await visitView('/personal-setting/devices')
  79. const table = within(view.getByRole('table'))
  80. const deleteButton = table.getByRole('button', {
  81. name: 'Delete this device',
  82. })
  83. mockUserCurrentDeviceDeleteMutation({
  84. userCurrentDeviceDelete: {
  85. success: true,
  86. },
  87. })
  88. await view.events.click(deleteButton)
  89. await waitForNextTick()
  90. expect(
  91. await view.findByRole('dialog', { name: 'Delete Object' }),
  92. ).toBeInTheDocument()
  93. await view.events.click(view.getByRole('button', { name: 'Delete Object' }))
  94. checkSimpleTableContent(view, [rowContents[0]])
  95. })
  96. it('updates the device list when a new device is added', async () => {
  97. mockUserCurrentDeviceListQuery({ userCurrentDeviceList })
  98. const view = await visitView('/personal-setting/devices')
  99. const devicesUpdateSubscription =
  100. getUserCurrentDevicesUpdatesSubscriptionHandler()
  101. devicesUpdateSubscription.trigger({
  102. userCurrentDevicesUpdates: {
  103. devices: [
  104. ...userCurrentDeviceList,
  105. {
  106. id: convertToGraphQLId('UserDevice', 3),
  107. name: 'Safari on Mac',
  108. fingerprint: 'new',
  109. location: 'Germany, Munich',
  110. updatedAt: '2024-04-25T09:59:59Z',
  111. },
  112. ],
  113. },
  114. })
  115. await waitForNextTick()
  116. const newDeviceRowContents = [
  117. 'Safari on Mac',
  118. 'Germany, Munich',
  119. ['2024-04-25 09:59', 'just now'],
  120. ]
  121. checkSimpleTableContent(view, [...rowContents, newDeviceRowContents])
  122. const table = within(view.getByRole('table'))
  123. expect(
  124. table.getAllByRole('button', { name: 'Delete this device' }),
  125. ).toHaveLength(2)
  126. })
  127. })