integration-utils.test.ts 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. import { beforeEach, describe, expect, it, vi } from 'vitest'
  2. import {
  3. getInitialMigrationSQLFromGitHubRepo,
  4. getIntegrationConfigurationUrl,
  5. } from './integration-utils'
  6. import type {
  7. GitHubAccount,
  8. Integration,
  9. VercelAccount,
  10. VercelTeamAccount,
  11. } from '@/data/integrations/integrations.types'
  12. vi.mock('@/data/fetchers', () => ({
  13. fetchHandler: vi.fn(),
  14. }))
  15. describe('integration-utils', () => {
  16. beforeEach(() => {
  17. vi.clearAllMocks()
  18. })
  19. describe('getInitialMigrationSQLFromGitHubRepo', () => {
  20. it('should return null when no externalId is provided', async () => {
  21. const result = await getInitialMigrationSQLFromGitHubRepo()
  22. expect(result).toBeNull()
  23. })
  24. it('should fetch and combine migration files correctly', async () => {
  25. const mockGitHubUrl = 'https://github.com/org/repo/tree/main/examples/with-briven'
  26. const mockBrivenFiles = [{ name: 'seed.sql', download_url: 'https://github.com/seed.sql' }]
  27. const mockMigrationFiles = [
  28. { name: '20230101000000_initial.sql', download_url: 'https://github.com/migration1.sql' },
  29. { name: '20230101000001_second.sql', download_url: 'https://github.com/migration2.sql' },
  30. ]
  31. const mockMigrationContent1 = 'CREATE TABLE users (id serial PRIMARY KEY);'
  32. const mockMigrationContent2 = 'CREATE TABLE posts (id serial PRIMARY KEY);'
  33. const mockSeedContent = 'INSERT INTO users (id) VALUES (1);'
  34. // Mock the fetch responses
  35. const { fetchHandler } = await import('@/data/fetchers')
  36. const mockFetchHandler = fetchHandler as unknown as ReturnType<typeof vi.fn>
  37. mockFetchHandler
  38. .mockResolvedValueOnce(
  39. new Response(JSON.stringify(mockBrivenFiles), {
  40. status: 200,
  41. statusText: 'OK',
  42. headers: { 'Content-Type': 'application/json' },
  43. })
  44. )
  45. .mockResolvedValueOnce(
  46. new Response(JSON.stringify(mockMigrationFiles), {
  47. status: 200,
  48. statusText: 'OK',
  49. headers: { 'Content-Type': 'application/json' },
  50. })
  51. )
  52. .mockResolvedValueOnce(
  53. new Response(mockSeedContent, {
  54. status: 200,
  55. statusText: 'OK',
  56. headers: { 'Content-Type': 'text/plain' },
  57. })
  58. )
  59. .mockResolvedValueOnce(
  60. new Response(mockMigrationContent1, {
  61. status: 200,
  62. statusText: 'OK',
  63. headers: { 'Content-Type': 'text/plain' },
  64. })
  65. )
  66. .mockResolvedValueOnce(
  67. new Response(mockMigrationContent2, {
  68. status: 200,
  69. statusText: 'OK',
  70. headers: { 'Content-Type': 'text/plain' },
  71. })
  72. )
  73. const result = await getInitialMigrationSQLFromGitHubRepo(mockGitHubUrl)
  74. expect(result).toContain(mockMigrationContent1)
  75. expect(result).toContain(mockMigrationContent2)
  76. expect(result).toContain(mockSeedContent)
  77. expect(result).toContain('create schema if not exists briven_migrations')
  78. expect(result).toContain('create table if not exists briven_migrations.schema_migrations')
  79. })
  80. it('should handle GitHub API errors gracefully', async () => {
  81. const mockGitHubUrl = 'https://github.com/org/repo/tree/main/examples/with-briven'
  82. const { fetchHandler } = await import('@/data/fetchers')
  83. const mockFetchHandler = fetchHandler as unknown as ReturnType<typeof vi.fn>
  84. mockFetchHandler
  85. .mockResolvedValueOnce(
  86. new Response(null, {
  87. status: 404,
  88. statusText: 'Not Found',
  89. headers: { 'Content-Type': 'application/json' },
  90. })
  91. )
  92. .mockResolvedValueOnce(
  93. new Response(null, {
  94. status: 404,
  95. statusText: 'Not Found',
  96. headers: { 'Content-Type': 'application/json' },
  97. })
  98. )
  99. const result = await getInitialMigrationSQLFromGitHubRepo(mockGitHubUrl)
  100. expect(result).toBeNull()
  101. })
  102. })
  103. describe('getIntegrationConfigurationUrl', () => {
  104. it('should return correct Vercel configuration URL for personal account', () => {
  105. const vercelIntegration: Integration = {
  106. id: '123',
  107. added_by: {
  108. username: 'testuser',
  109. id: '123',
  110. primary_email: 'test@example.com',
  111. },
  112. inserted_at: '2024-01-01',
  113. updated_at: '2024-01-01',
  114. connections: [],
  115. organization: { slug: 'org' },
  116. integration: { name: 'Vercel' },
  117. metadata: {
  118. account: {
  119. type: 'Personal',
  120. name: 'Test User',
  121. avatar: 'test-avatar',
  122. source: 'marketplace',
  123. owner_id: '123',
  124. } as VercelAccount,
  125. configuration_id: '123',
  126. },
  127. }
  128. const result = getIntegrationConfigurationUrl(vercelIntegration)
  129. expect(result).toBe('https://vercel.com/dashboard/integrations/123')
  130. })
  131. it('should return correct Vercel configuration URL for team account', () => {
  132. const vercelIntegration: Integration = {
  133. id: '123',
  134. added_by: {
  135. username: 'testuser',
  136. id: '123',
  137. primary_email: 'test@example.com',
  138. },
  139. inserted_at: '2024-01-01',
  140. updated_at: '2024-01-01',
  141. connections: [],
  142. organization: { slug: 'org' },
  143. integration: { name: 'Vercel' },
  144. metadata: {
  145. account: {
  146. type: 'Team',
  147. name: 'Test Team',
  148. avatar: 'test-avatar',
  149. source: 'marketplace',
  150. owner_id: '123',
  151. team_id: 'team123',
  152. team_slug: 'my-team',
  153. } as VercelTeamAccount,
  154. configuration_id: '123',
  155. },
  156. }
  157. const result = getIntegrationConfigurationUrl(vercelIntegration)
  158. expect(result).toBe('https://vercel.com/dashboard/my-team/integrations/123')
  159. })
  160. it('should return correct GitHub configuration URL for personal account', () => {
  161. const githubIntegration: Integration = {
  162. id: '456',
  163. added_by: {
  164. username: 'testuser',
  165. id: '123',
  166. primary_email: 'test@example.com',
  167. },
  168. inserted_at: '2024-01-01',
  169. updated_at: '2024-01-01',
  170. connections: [],
  171. organization: { slug: 'org' },
  172. integration: { name: 'GitHub' },
  173. metadata: {
  174. account: {
  175. type: 'User',
  176. name: 'Test User',
  177. avatar: 'test-avatar',
  178. installed_by_user_id: 123,
  179. } as GitHubAccount,
  180. installation_id: 456,
  181. },
  182. }
  183. const result = getIntegrationConfigurationUrl(githubIntegration)
  184. expect(result).toBe('https://github.com/settings/installations/456')
  185. })
  186. it('should return correct GitHub configuration URL for organization', () => {
  187. const githubIntegration: Integration = {
  188. id: '456',
  189. added_by: {
  190. username: 'testuser',
  191. id: '123',
  192. primary_email: 'test@example.com',
  193. },
  194. inserted_at: '2024-01-01',
  195. updated_at: '2024-01-01',
  196. connections: [],
  197. organization: { slug: 'org' },
  198. integration: { name: 'GitHub' },
  199. metadata: {
  200. account: {
  201. type: 'Organization',
  202. name: 'org-name',
  203. avatar: 'test-avatar',
  204. installed_by_user_id: 123,
  205. } as GitHubAccount,
  206. installation_id: 456,
  207. },
  208. }
  209. const result = getIntegrationConfigurationUrl(githubIntegration)
  210. expect(result).toBe('https://github.com/organizations/org-name/settings/installations/456')
  211. })
  212. it('should return empty string for unknown integration', () => {
  213. const unknownIntegration = {
  214. id: '789',
  215. added_by: {
  216. username: 'testuser',
  217. id: '123',
  218. primary_email: 'test@example.com',
  219. },
  220. inserted_at: '2024-01-01',
  221. updated_at: '2024-01-01',
  222. connections: [],
  223. organization: { slug: 'org' },
  224. integration: { name: 'Unknown' as any },
  225. metadata: {
  226. account: {
  227. type: 'User',
  228. name: 'Test User',
  229. avatar: 'test-avatar',
  230. installed_by_user_id: 123,
  231. } as GitHubAccount,
  232. installation_id: 789,
  233. },
  234. } as Integration
  235. const result = getIntegrationConfigurationUrl(unknownIntegration)
  236. expect(result).toBe('')
  237. })
  238. })
  239. })