-
Notifications
You must be signed in to change notification settings - Fork 0
update: setup testing #5
Changes from all commits
0fd5bc7
19d57ae
7dea63c
81859a6
b38095a
c7b59da
675e36f
c4488ad
b20b154
5536cdc
2732e8f
32c1437
59f24a1
1548acd
1af57fe
9f34bd7
2924e33
1709bdf
1b80f76
bedf85a
eb02902
84ed6eb
5591e3f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # 🎁 Gift Idea Tracker | ||
|
|
||
| A mobile application built with **React Native + Redux + Supabase**, designed to help users organize and track gift ideas for their friends, family, and special occasions — all in one place. | ||
|
|
||
| > 📆 Plan ahead. 🎁 Stay thoughtful. 💡 Never forget a gift again. | ||
|
|
||
| --- | ||
|
|
||
| ## 💡 AI-Powered Development Workflow | ||
|
|
||
| We leveraged **cutting-edge AI tools** throughout the entire software development lifecycle to accelerate productivity, improve quality, and stay creative: | ||
|
|
||
| | Phase | Tools Used | | ||
| | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | 📋 Requirement Gathering | [ChatGPT](https://chat.openai.com) – Assist in defining user stories and features | | ||
| | 🎨 UI/UX Design | [Uizard](https://uizard.io) + Autodesigner 1.5 for AI wireframes and flows<br>[Figma](https://figma.com) + Codia AI plugin for auto-generating UI components | | ||
| | 💻 Development | [a0.dev](https://a0.dev) to generate boilerplate code from designs<br>[VSCode](https://code.visualstudio.com) with [GitHub Copilot](https://github.com/features/copilot) for live coding, bug fixes, and code suggestions | | ||
| | 🧪 Testing | Combination of **GitHub Copilot** and **ChatGPT** for writing test cases and debugging<br>Manual & automated testing via Jest + React Native Testing Library | | ||
|
|
||
| <br> | ||
|
|
||
| ## ✨ Features | ||
|
|
||
| - 🧠 AI-assisted wireframes for fast UI prototyping | ||
| - 📋 Manage gift ideas with title, image, notes, and tags | ||
| - 👥 Add & manage recipients and event dates | ||
| - 💰 Track budgets for each recipient and overall spending | ||
| - 📊 Visual charts for budget analysis | ||
| - ⏰ Reminder & calendar sync for upcoming events | ||
| - 🔔 Push notifications (optional) | ||
| - ☁️ Data stored securely using Supabase | ||
|
|
||
|
|
||
| <br> | ||
|
|
||
| ## 🛠️ Tech Stack | ||
|
|
||
| | Layer | Tools/Tech | | ||
| | ------------ | ----------------------------------------- | | ||
| | Frontend | React Native, Redux Toolkit, TypeScript | | ||
| | Backend | Supabase (PostgreSQL, Auth, Storage) | | ||
| | Design | Uizard, Figma (with Codia AI) | | ||
| | AI Assistant | ChatGPT, GitHub Copilot, a0.dev | | ||
| | Testing | Jest, React Native Testing Library, Detox | | ||
| | Build/Deploy | Expo, EAS Build, Google Play, TestFlight | |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| module.exports = { | ||
| preset: 'react-native', | ||
| transform: { | ||
| '^.+\\.(js|jsx|ts|tsx)$': 'babel-jest', | ||
| }, | ||
| transformIgnorePatterns: [ | ||
| 'node_modules/(?!(jest-)?react-native|@react-native|@react-navigation|react-native-reanimated|react-native-gesture-handler)', | ||
| ], | ||
|
|
||
| moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], | ||
| setupFilesAfterEnv: ['@testing-library/jest-native/extend-expect'], | ||
| moduleNameMapper: { | ||
| '^@/(.*)$': '<rootDir>/src/$1', // chỉnh lại nếu bạn dùng alias khác | ||
| }, | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // Jest setup file | ||
|
|
||
| // Mock global functions or modules if needed | ||
| jest.mock('react-native', () => { | ||
| const ReactNative = jest.requireActual('react-native'); | ||
| return { | ||
| ...ReactNative, | ||
| ActionSheetIOS: { | ||
| showActionSheetWithOptions: jest.fn(), | ||
| }, | ||
| }; | ||
| }); | ||
|
|
||
| // Add any other global mocks or configurations here |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| import { fireEvent, render } from '@testing-library/react-native'; | ||
| import React from 'react'; | ||
|
|
||
| import CalendarIntegration from '@/components/settings/CalendarIntegration'; | ||
|
|
||
| describe('CalendarIntegration Component', () => { | ||
| it('should render the calendar integration button', () => { | ||
| const mockFn = jest.fn(); | ||
| const { getByText } = render(<CalendarIntegration onIntegrate={mockFn} />); | ||
| expect(getByText('Integrate Calendar')).toBeTruthy(); | ||
| }); | ||
|
|
||
| it('should trigger calendar integration on button press', () => { | ||
| const mockIntegrateCalendar = jest.fn(); | ||
| const { getByText } = render( | ||
| <CalendarIntegration onIntegrate={mockIntegrateCalendar} />, | ||
| ); | ||
| fireEvent.press(getByText('Integrate Calendar')); | ||
| expect(mockIntegrateCalendar).toHaveBeenCalled(); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,20 @@ | ||||||
| import { fireEvent, render } from '@testing-library/react-native'; | ||||||
| import React from 'react'; | ||||||
|
|
||||||
| import ReminderSettings from '@/components/settings/ReminderSettings'; | ||||||
|
|
||||||
| describe('ReminderSettings Component', () => { | ||||||
| it('should render the reminder toggle', () => { | ||||||
| const { getByText } = render(<ReminderSettings />); | ||||||
| expect(getByText('Enable Reminders')).toBeTruthy(); | ||||||
|
||||||
| expect(getByText('Enable Reminders')).toBeTruthy(); | |
| expect(getByText('Reminder Settings')).toBeTruthy(); |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,27 @@ | ||||||||||||||
| import { fireEvent, render } from '@testing-library/react-native'; | ||||||||||||||
| import React from 'react'; | ||||||||||||||
|
|
||||||||||||||
| import SyncedEvents from '@/components/settings/SyncedEvents'; | ||||||||||||||
|
|
||||||||||||||
| describe('SyncedEvents Component', () => { | ||||||||||||||
| it('should render a list of synced events', () => { | ||||||||||||||
| const events = [ | ||||||||||||||
| { id: 1, name: 'Event 1', date: '2025-05-01', synced: true }, | ||||||||||||||
| { id: 2, name: 'Event 2', date: '2025-05-03', synced: false }, | ||||||||||||||
| ]; | ||||||||||||||
| const { getByText } = render(<SyncedEvents events={events} />); | ||||||||||||||
| expect(getByText('Event 1')).toBeTruthy(); | ||||||||||||||
| expect(getByText('Event 2')).toBeTruthy(); | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| it('should refresh events on button press', () => { | ||||||||||||||
| const events = [ | ||||||||||||||
| { id: 1, name: 'Event 1', date: '2025-05-01', synced: true }, | ||||||||||||||
| { id: 2, name: 'Event 2', date: '2025-05-03', synced: false }, | ||||||||||||||
| ]; | ||||||||||||||
| const mockRefreshEvents = jest.fn(); | ||||||||||||||
| const { getByText } = render(<SyncedEvents events={events} />); | ||||||||||||||
|
||||||||||||||
| const { getByText } = render(<SyncedEvents events={events} />); | |
| const { getByText } = render(<SyncedEvents events={events} refreshEvents={mockRefreshEvents} />); |
Copilot
AI
May 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test attempts to trigger a refresh action by pressing a 'Refresh Events' button, but the SyncedEvents component code does not render such a button. Consider updating the component to include a refresh control or modifying the test to match the current UI behavior.
| const { getByText } = render(<SyncedEvents events={events} />); | |
| fireEvent.press(getByText('Refresh Events')); | |
| const { getByText } = render(<SyncedEvents events={events} onRefresh={mockRefreshEvents} />); | |
| const refreshButton = getByText('Refresh Events'); | |
| expect(refreshButton).toBeTruthy(); | |
| fireEvent.press(refreshButton); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ReminderSettings test is expecting a text 'Enable Reminders', but the updated component only renders a title such as 'Reminder Settings'. Please update the test assertion to match the current UI or modify the component accordingly.