lsx.spec.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // tests for assuring axios request succeeds in version change
  2. import type { Server } from 'node:http';
  3. import { renderHook, waitFor } from '@testing-library/react';
  4. import axios from 'axios';
  5. import express from 'express';
  6. import lsxMiddleware from '../../../server';
  7. import { useSWRxLsx } from './lsx';
  8. // Mock the generateBaseQuery function
  9. vi.mock('../../../server/routes/list-pages/generate-base-query', () => ({
  10. generateBaseQuery: vi.fn().mockResolvedValue({
  11. query: {
  12. skip: vi.fn().mockReturnThis(),
  13. limit: vi.fn().mockReturnThis(),
  14. sort: vi.fn().mockReturnThis(),
  15. and: vi.fn().mockReturnThis(),
  16. clone: vi.fn().mockReturnThis(),
  17. count: vi.fn().mockResolvedValue(10),
  18. exec: vi.fn().mockResolvedValue([]),
  19. },
  20. addConditionToListOnlyDescendants: vi.fn().mockReturnThis(),
  21. addConditionToFilteringByViewerForList: vi.fn().mockReturnThis(),
  22. }),
  23. }));
  24. // Mock mongoose model
  25. vi.mock('mongoose', () => ({
  26. model: vi.fn().mockReturnValue({
  27. find: vi.fn().mockReturnValue({
  28. skip: vi.fn().mockReturnThis(),
  29. limit: vi.fn().mockReturnThis(),
  30. sort: vi.fn().mockReturnThis(),
  31. and: vi.fn().mockReturnThis(),
  32. clone: vi.fn().mockReturnThis(),
  33. count: vi.fn().mockResolvedValue(10),
  34. exec: vi.fn().mockResolvedValue([]),
  35. }),
  36. countDocuments: vi.fn().mockResolvedValue(0),
  37. aggregate: vi.fn().mockResolvedValue([{ count: 5 }]),
  38. }),
  39. }));
  40. const TEST_PORT = 3001;
  41. const TEST_SERVER_URL = `http://localhost:${TEST_PORT}`;
  42. describe('useSWRxLsx integration tests', () => {
  43. let server: Server;
  44. let app: express.Application;
  45. // Helper function to setup axios spy
  46. const setupAxiosSpy = () => {
  47. const originalAxios = axios.create();
  48. return vi.spyOn(axios, 'get').mockImplementation((url, config) => {
  49. const fullUrl = url.startsWith('/_api')
  50. ? `${TEST_SERVER_URL}${url}`
  51. : url;
  52. return originalAxios.get(fullUrl, config);
  53. });
  54. };
  55. beforeAll(async () => {
  56. // Create minimal Express app with just the LSX route
  57. app = express();
  58. app.use(express.json());
  59. app.use(express.urlencoded({ extended: true }));
  60. // Add CORS headers to prevent cross-origin issues
  61. app.use((req, res, next) => {
  62. res.header('Access-Control-Allow-Origin', '*');
  63. res.header(
  64. 'Access-Control-Allow-Methods',
  65. 'GET, POST, PUT, DELETE, OPTIONS',
  66. );
  67. res.header(
  68. 'Access-Control-Allow-Headers',
  69. 'Origin, X-Requested-With, Content-Type, Accept, Authorization',
  70. );
  71. next();
  72. });
  73. // Mock minimal GROWI-like structure for the middleware
  74. const mockCrowi = {
  75. require: () => () => (req: any, res: any, next: any) => next(),
  76. accessTokenParser: () => (req: any, res: any, next: any) => next(),
  77. pageService: {
  78. getExcludedPathsBySystem: vi.fn().mockReturnValue(['/user']),
  79. },
  80. };
  81. // Import and setup the LSX middleware
  82. lsxMiddleware(mockCrowi, app);
  83. // Start test server
  84. return new Promise<void>((resolve) => {
  85. server = app.listen(TEST_PORT, () => {
  86. resolve();
  87. });
  88. });
  89. });
  90. afterAll(() => {
  91. return new Promise<void>((resolve) => {
  92. if (server) {
  93. server.close(() => {
  94. resolve();
  95. });
  96. } else {
  97. resolve();
  98. }
  99. });
  100. });
  101. it('should make actual server request and receive 2xx response for basic lsx request', async () => {
  102. const axiosGetSpy = setupAxiosSpy();
  103. const { result } = renderHook(() =>
  104. useSWRxLsx('/test-page', { depth: '1' }, false),
  105. );
  106. await waitFor(() => expect(result.current.data).toBeDefined(), {
  107. timeout: 5000,
  108. });
  109. expect(axiosGetSpy).toHaveBeenCalledWith(
  110. '/_api/lsx',
  111. expect.objectContaining({
  112. params: expect.objectContaining({
  113. pagePath: '/test-page',
  114. options: expect.objectContaining({ depth: '1' }),
  115. }),
  116. }),
  117. );
  118. expect(result.current.data).toBeDefined();
  119. expect(result.current.error).toBeUndefined();
  120. axiosGetSpy.mockRestore();
  121. });
  122. it('should handle server validation errors properly', async () => {
  123. const axiosGetSpy = setupAxiosSpy();
  124. const { result } = renderHook(() => useSWRxLsx('', {}, false));
  125. await waitFor(() => expect(result.current.error).toBeDefined(), {
  126. timeout: 5000,
  127. });
  128. expect(result.current.error).toBeDefined();
  129. expect(result.current.data).toBeUndefined();
  130. axiosGetSpy.mockRestore();
  131. });
  132. });