diff --git a/packages/ui-components/src/__tests__/License.test.ts b/packages/ui-components/src/__tests__/License.test.ts new file mode 100644 index 0000000000..07b9a750d4 --- /dev/null +++ b/packages/ui-components/src/__tests__/License.test.ts @@ -0,0 +1,82 @@ +import { render, screen, waitFor } from '@testing-library/svelte'; +import { beforeEach, expect, describe, vi, afterEach } from 'vitest'; +import License from '../lib/components/License.svelte'; +import { LICENSE_URL } from '../lib/consts'; + +// Mock the global fetch function +const mockFetch = vi.fn(); + +vi.stubGlobal('fetch', mockFetch); + +vi.mock('svelte-markdown', async () => { + const MockMarkdown = (await import('../lib/__mocks__/MockComponent.svelte')).default; + return { default: MockMarkdown }; +}); + +describe('License', () => { + const mockMarkdownContent = 'This is license text.'; + + beforeEach(() => { + mockFetch.mockReset(); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('fetches and renders markdown content on mount', async () => { + mockFetch.mockResolvedValue({ + ok: true, + text: async () => mockMarkdownContent + }); + + render(License); + + await waitFor(() => { + expect(mockFetch).toHaveBeenCalledTimes(1); + expect(mockFetch).toHaveBeenCalledWith(LICENSE_URL); + }); + + await waitFor(() => { + expect(screen.getByTestId('mock-component').getAttribute('source')).toBe(mockMarkdownContent); + }); + }); + + it('handles fetch network error gracefully', async () => { + mockFetch.mockRejectedValue(new Error('Network error')); + + render(License); + + await waitFor(() => { + expect(mockFetch).toHaveBeenCalledTimes(1); + expect(mockFetch).toHaveBeenCalledWith(LICENSE_URL); + }); + + await waitFor(() => { + expect(screen.getByTestId('mock-component').getAttribute('source')).toBe( + 'Failed to fetch license.' + ); + }); + }); + + it('handles non-OK HTTP responses gracefully', async () => { + mockFetch.mockResolvedValue({ + ok: false, + status: 404, + statusText: 'Not Found' + }); + + render(License); + + await waitFor(() => { + expect(mockFetch).toHaveBeenCalledTimes(1); + expect(mockFetch).toHaveBeenCalledWith(LICENSE_URL); + }); + + await waitFor(() => { + expect(screen.getByTestId('mock-component').getAttribute('source')).toBe( + 'Failed to fetch license: HTTP 404' + ); + }); + }); +}); diff --git a/packages/ui-components/src/lib/components/License.svelte b/packages/ui-components/src/lib/components/License.svelte index 85ef2e65a4..417672ae94 100644 --- a/packages/ui-components/src/lib/components/License.svelte +++ b/packages/ui-components/src/lib/components/License.svelte @@ -2,19 +2,20 @@ import { Heading, Text, BlockQuote } from '@rainlanguage/ui-components'; import Markdown from 'svelte-markdown'; import { onMount } from 'svelte'; + import { LICENSE_URL } from '../consts'; let source = ''; onMount(async () => { try { - const response = await fetch( - 'https://raw.githubusercontent.com/rainlanguage/decentralicense/refs/heads/master/README.md' - ); + const response = await fetch(LICENSE_URL); if (response.ok) { source = await response.text(); + } else { + source = `Failed to fetch license: HTTP ${response.status}`; } } catch { - source = ''; + source = 'Failed to fetch license.'; } }); diff --git a/packages/ui-components/src/lib/consts.ts b/packages/ui-components/src/lib/consts.ts new file mode 100644 index 0000000000..670260033f --- /dev/null +++ b/packages/ui-components/src/lib/consts.ts @@ -0,0 +1,2 @@ +export const LICENSE_URL = + 'https://raw.githubusercontent.com/rainlanguage/decentralicense/refs/heads/master/README.md';