Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions habitTrackerApp/jest.setup.js
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
import '@testing-library/jest-dom'

// Mock environment variables for tests
process.env.NEXT_PUBLIC_SUPABASE_URL = 'https://test-url.supabase.co'
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY = 'test-anon-key'
169 changes: 169 additions & 0 deletions habitTrackerApp/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions habitTrackerApp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"eslint-config-next": "^15.5.5",
"jest": "^30.2.0",
"jest-environment-jsdom": "^30.2.0",
"node-mocks-http": "^1.17.2",
"postcss": "^8.5.6",
"tailwindcss": "^3.4.15",
"ts-jest": "^29.4.5",
Expand Down
95 changes: 95 additions & 0 deletions habitTrackerApp/tests/unit/GoogleCalendarConnect.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Mock Supabase to avoid ESM transform errors
jest.mock('@supabase/auth-helpers-nextjs', () => ({
createClientComponentClient: () => ({
from: jest.fn(() => ({
select: jest.fn(() => ({
eq: jest.fn(() => ({
single: jest.fn()
}))
}))
}))
})
}));

import { render, screen, waitFor } from '@testing-library/react';
import GoogleCalendarConnect from '../../src/app/components/GoogleCalendarConnect';

// Mock user object
const mockUser = {
id: 'test-user-id',
email: 'test@example.com',
user_metadata: {}
};

describe('GoogleCalendarConnect Component', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('should render the component', async () => {
render(<GoogleCalendarConnect user={mockUser as any} />);

// Wait for loading to complete and check for the main heading
await waitFor(() => {
expect(screen.getByText('Google Calendar')).toBeInTheDocument();
});
});

it('should show loading state initially', () => {
render(<GoogleCalendarConnect user={mockUser as any} />);

// Check for loading spinner
const spinner = document.querySelector('.animate-spin');
expect(spinner).toBeInTheDocument();
});

it('should handle connection check', async () => {
render(<GoogleCalendarConnect user={mockUser as any} />);

// Wait for the component to load and show the "not connected" state
await waitFor(() => {
expect(screen.getByText('Connect Google Calendar')).toBeInTheDocument();
});
});

it('should handle no connection found', async () => {
const mockSupabase = require('@supabase/auth-helpers-nextjs').createClientComponentClient();

// Mock no connection found
mockSupabase.from().select().eq().single.mockRejectedValue(new Error('No connection'));

render(<GoogleCalendarConnect user={mockUser as any} />);

await waitFor(() => {
expect(screen.getByText('Connect Google Calendar')).toBeInTheDocument();
});
});

it('should handle expired token', async () => {
const mockSupabase = require('@supabase/auth-helpers-nextjs').createClientComponentClient();

// Mock expired token
mockSupabase.from().select().eq().single.mockResolvedValue({
data: {
id: 'token-id',
expires_at: new Date(Date.now() - 3600000).toISOString() // 1 hour ago
},
error: null
});

render(<GoogleCalendarConnect user={mockUser as any} />);

await waitFor(() => {
expect(screen.getByText('Connect Google Calendar')).toBeInTheDocument();
});
});

it('should display user information', async () => {
render(<GoogleCalendarConnect user={mockUser as any} />);

// Wait for loading to complete and check for the main heading
await waitFor(() => {
expect(screen.getByText('Google Calendar')).toBeInTheDocument();
});
});
});
Loading