Skip to content

Dario-Maselli/github-search-app

Repository files navigation

GitHub Search App

A Flutter app for exploring GitHub users, their repositories, and related data via the GitHub REST API.

The project showcases clean architecture, API integration with Dio, state management using flutter_bloc, and golden/widget testing for reliability.

🚀 Features Implemented

Core Features

User Search

  • Search GitHub users by username via /search/users endpoint.

  • Paginated results with scroll-to-load-more support.

  • Debounced search input to reduce API calls.

User Details

  • View individual user details (/users/{login}).

  • Displays profile information (avatar, bio, stats, created_at).

User Repositories

  • List repositories for a user (/users/{login}/repos).

  • Repository widget displays:

  1. Name
  2. Description
  3. Language
  4. Stars, forks, watchers
  5. Creation date

Favorites

  • Mark/unmark users as favorites.

  • Stored locally with SQLite (sqflite) using a Favorite Users Repository.

  • State managed via a FavoritesCubit.

Utilities

  • Date Formatting

  • DateTimeUtils.formatDate() for normalizing ISO 8601 timestamps into yyyy-MM-dd.

Endpoint Resolver

  • determineEndpoint(RequestOptions) to map Dio request paths into semantic enums (Endpoints.user, Endpoints.userRepos, etc.) for consistent handling.

Extensions

  • String.padStart (later replaced/fixed with Dart’s padLeft for zero-padding consistency).

🧪 Testing

Unit Tests

  • determineEndpoint → verifies correct endpoint resolution with normalized/messy paths.

  • DateTimeUtils → ensures valid ISO strings format correctly, invalid strings return unchanged, and padding works.

  • FavoritesCubit → validates state transitions when toggling favorites.

  • Database migrations tested for applying/upgrading schemas.

Golden Tests

  • GoldenToolkit used for UI snapshots (CustomAppBar, search result tiles, etc.).

  • Helped catch regressions in design during refactors.

Widget Tests (Via Goldens)

  • Verified snackbars and state flows (e.g., “Added to favorites”).

🛠️ Architecture & Stack

  • Framework: Flutter (3.x with FVM).

  • State Management: flutter_bloc / Cubits.

  • Networking: Dio (with error handling & request interception).

  • Database: sqflite (with DatabaseHelper and migration runner).

  • Testing: flutter_test, mockito, golden_toolkit.

⚡ Challenges Faced

Endpoint Mapping Ambiguity

  • Normalizing URLs like ///users//dario///repos/// was tricky.

  • Solved with _normalize and _segs helpers.

Date Formatting Edge Cases

  • Extension padStart clashed with Dart’s own padLeft.

  • Produced bugs like 2025-1-3 instead of 2025-01-03.

  • Fixed by dropping the extension in favor of native padLeft.

SQLite Foreign Key Errors

  • Inserting favorites triggered FOREIGN KEY constraint failed.

  • Root cause: mismatched schema vs. insert queries.

  • Fixed by ensuring favorite_github_users schema included proper relations.

Bloc State Handling

  • FavoriteButton repeatedly triggered snackbars.

  • Needed BlocSelector / BlocConsumer to refine rebuild behavior.

  • Testing RepositoryProvider Contexts

Golden tests failed when RepositoryProvider.of<Storage>() couldn’t find context.

  • Fixed by wrapping widgets in RepositoryProvider setup in tests.

GitHub Rate Limiting

  • API unauthenticated requests hit 60 req/hr.

  • Planned solution: add OAuth token support in Dio interceptors.

🔮 What I Would Do Differently

  • Stronger Type Safety

  • Replace raw String endpoints with enums or sealed classes across the networking layer.

  • Error Boundaries in UI

  • Build dedicated error widgets instead of snackbars-only flows.

  • Better Offline Support

  • Cache search results and user details in SQLite/Hive for offline browsing.

  • CI/CD GitHub Actions pipeline to:

  1. Run widget tests with golden diffs.
  2. Auto-update golden images with approval step.
  3. Push code coverage to Codecov.
  • Use Retrofit/Chopper for APIs (potentially)

  • Handwriting models & Dio calls was verbose.

  • A Retrofit-style generator would cut boilerplate.

  • Refine DB Layer

  • Wrap raw sqflite with a repo/DAO pattern for cleaner testing.

Auth Integration

  • Add GitHub OAuth login to raise rate limits & enable private repo support

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors