Flutter auth app with TDD Clean Architecture

Overview

Flutter App Auth πŸ“±

This is App with Auth Function like Login and Register. All API using reqres.in.
This app also implementing Flutter Clean Architecture with TDD.

demo.mp4

Pre-requisites πŸ“

Technology Recommended Version Installation Guide
Flutter v3.0.4 Flutter Official Docs
Dart v2.17.5 Installed automatically with Flutter

Get Started πŸš€

  • Clone this project
  • Run flutter run --flavor stg -t lib/main_stg.dart for staging or
  • Run flutter run --flavor prd -t lib/main_prd.dart for production
  • Run Test flutter test
  • To generate launcher icon based on Flavor flutter pub run flutter_launcher_icons:main -f flutter_launcher_icons*

Feature βœ…

  • BLoC State Management
  • Clean Architecture with TDD
    • Unit Test
    • Widget Test
    • BLoC test
  • Theme Configuration : System, Light, Dark
  • Multi Language : English, Bahasa
  • Login, Register Example
  • Pagination Example
  • Autofill Username and Password

TODO πŸ“

  • Integration Test
  • Implement multi flavor

Architecture Proposal by Resocoder


architecture-proposal

Project Structure

lib
 β”œβ”€β”€ core
 β”‚   β”œβ”€β”€ core.dart
 β”‚   β”œβ”€β”€ core_mapper.dart
 β”‚   β”œβ”€β”€ error
 β”‚   β”‚   β”œβ”€β”€ error.dart
 β”‚   β”‚   β”œβ”€β”€ exceptions.dart
 β”‚   β”‚   └── failure.dart
 β”‚   β”œβ”€β”€ localization
 β”‚   β”‚   β”œβ”€β”€ generated
 β”‚   β”‚   β”‚   β”œβ”€β”€ strings.dart
 β”‚   β”‚   β”‚   β”œβ”€β”€ strings_en.dart
 β”‚   β”‚   β”‚   └── strings_id.dart
 β”‚   β”‚   β”œβ”€β”€ intl_en.arb
 β”‚   β”‚   β”œβ”€β”€ intl_id.arb
 β”‚   β”‚   β”œβ”€β”€ l10n.dart
 β”‚   β”‚   └── localization.dart
 β”‚   └── usecase
 β”‚       └── usecase.dart
 β”œβ”€β”€ data
 β”‚   β”œβ”€β”€ data.dart
 β”‚   β”œβ”€β”€ datasources
 β”‚   β”‚   β”œβ”€β”€ datasources.dart
 β”‚   β”‚   β”œβ”€β”€ local
 β”‚   β”‚   β”‚   β”œβ”€β”€ data_helper.dart
 β”‚   β”‚   β”‚   β”œβ”€β”€ local.dart
 β”‚   β”‚   β”‚   └── pref_manager.dart
 β”‚   β”‚   └── remote
 β”‚   β”‚       β”œβ”€β”€ auth_remote_datasources.dart
 β”‚   β”‚       β”œβ”€β”€ model
 β”‚   β”‚       β”‚   β”œβ”€β”€ auth
 β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ auth.dart
 β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ login_response.dart
 β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ register_response.dart
 β”‚   β”‚       β”‚   β”‚   └── users_response.dart
 β”‚   β”‚       β”‚   └── model.dart
 β”‚   β”‚       β”œβ”€β”€ remote.dart
 β”‚   β”‚       └── services
 β”‚   β”‚           β”œβ”€β”€ dio_client.dart
 β”‚   β”‚           β”œβ”€β”€ dio_interceptor.dart
 β”‚   β”‚           β”œβ”€β”€ list_api.dart
 β”‚   β”‚           └── services.dart
 β”‚   └── repositories
 β”‚       β”œβ”€β”€ auth_repository_impl.dart
 β”‚       └── repositories.dart
 β”œβ”€β”€ di
 β”‚   └── di.dart
 β”œβ”€β”€ domain
 β”‚   β”œβ”€β”€ domain.dart
 β”‚   β”œβ”€β”€ entities
 β”‚   β”‚   β”œβ”€β”€ auth
 β”‚   β”‚   β”‚   β”œβ”€β”€ auth.dart
 β”‚   β”‚   β”‚   β”œβ”€β”€ login.dart
 β”‚   β”‚   β”‚   β”œβ”€β”€ register.dart
 β”‚   β”‚   β”‚   └── users.dart
 β”‚   β”‚   └── entities.dart
 β”‚   β”œβ”€β”€ repositories
 β”‚   β”‚   β”œβ”€β”€ auth_repository.dart
 β”‚   β”‚   └── repositories.dart
 β”‚   └── usecases
 β”‚       β”œβ”€β”€ auth
 β”‚       β”‚   β”œβ”€β”€ auth.dart
 β”‚       β”‚   β”œβ”€β”€ get_users.dart
 β”‚       β”‚   β”œβ”€β”€ post_login.dart
 β”‚       β”‚   └── post_register.dart
 β”‚       └── usecases.dart
 β”œβ”€β”€ main.dart
 β”œβ”€β”€ presentation
 β”‚   β”œβ”€β”€ page
 β”‚   β”‚   β”œβ”€β”€ app_route.dart
 β”‚   β”‚   β”œβ”€β”€ auth
 β”‚   β”‚   β”‚   β”œβ”€β”€ auth.dart
 β”‚   β”‚   β”‚   β”œβ”€β”€ cubit
 β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ cubit.dart
 β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ login_cubit.dart
 β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ login_state.dart
 β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ register_cubit.dart
 β”‚   β”‚   β”‚   β”‚   └── register_state.dart
 β”‚   β”‚   β”‚   β”œβ”€β”€ login_page.dart
 β”‚   β”‚   β”‚   └── register_page.dart
 β”‚   β”‚   β”œβ”€β”€ main
 β”‚   β”‚   β”‚   β”œβ”€β”€ cubit
 β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ cubit.dart
 β”‚   β”‚   β”‚   β”‚   └── navdrawer_cubit.dart
 β”‚   β”‚   β”‚   β”œβ”€β”€ dashboard
 β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ cubit
 β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ cubit.dart
 β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ users_cubit.dart
 β”‚   β”‚   β”‚   β”‚   β”‚   └── users_state.dart
 β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ dashboard.dart
 β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ dashboard_page.dart
 β”‚   β”‚   β”‚   β”‚   └── dashboard_success.dart
 β”‚   β”‚   β”‚   β”œβ”€β”€ main.dart
 β”‚   β”‚   β”‚   β”œβ”€β”€ main_page.dart
 β”‚   β”‚   β”‚   β”œβ”€β”€ menu_drawer.dart
 β”‚   β”‚   β”‚   └── settings
 β”‚   β”‚   β”‚       β”œβ”€β”€ cubit
 β”‚   β”‚   β”‚       β”‚   β”œβ”€β”€ cubit.dart
 β”‚   β”‚   β”‚       β”‚   └── settings_cubit.dart
 β”‚   β”‚   β”‚       β”œβ”€β”€ settings.dart
 β”‚   β”‚   β”‚       └── settings_page.dart
 β”‚   β”‚   β”œβ”€β”€ pages.dart
 β”‚   β”‚   └── splashscreen
 β”‚   β”‚       └── splash_screen_page.dart
 β”‚   β”œβ”€β”€ presentation.dart
 β”‚   β”œβ”€β”€ resources
 β”‚   β”‚   β”œβ”€β”€ dimens.dart
 β”‚   β”‚   β”œβ”€β”€ images.dart
 β”‚   β”‚   β”œβ”€β”€ palette.dart
 β”‚   β”‚   β”œβ”€β”€ resources.dart
 β”‚   β”‚   └── styles.dart
 β”‚   └── widgets
 β”‚       β”œβ”€β”€ button.dart
 β”‚       β”œβ”€β”€ button_notification.dart
 β”‚       β”œβ”€β”€ button_text.dart
 β”‚       β”œβ”€β”€ circle_image.dart
 β”‚       β”œβ”€β”€ color_loaders.dart
 β”‚       β”œβ”€β”€ drop_down.dart
 β”‚       β”œβ”€β”€ empty.dart
 β”‚       β”œβ”€β”€ loading.dart
 β”‚       β”œβ”€β”€ my_appbar.dart
 β”‚       β”œβ”€β”€ parent.dart
 β”‚       β”œβ”€β”€ spacer_h.dart
 β”‚       β”œβ”€β”€ spacer_v.dart
 β”‚       β”œβ”€β”€ text_f.dart
 β”‚       β”œβ”€β”€ toast.dart
 β”‚       └── widgets.dart
 └── utils
     β”œβ”€β”€ ext
     β”‚   β”œβ”€β”€ context.dart
     β”‚   β”œβ”€β”€ ext.dart
     β”‚   └── string.dart
     β”œβ”€β”€ helper
     β”‚   β”œβ”€β”€ common.dart
     β”‚   β”œβ”€β”€ constant.dart
     β”‚   └── helper.dart
     └── utils.dart

Test Project Structure

  test
    β”œβ”€β”€ data
    β”‚   β”œβ”€β”€ datasources
    β”‚   β”‚   └── remote
    β”‚   β”‚       β”œβ”€β”€ auth_remote_datasources_test.dart
    β”‚   β”‚       └── model
    β”‚   β”‚           └── auth
    β”‚   β”‚               β”œβ”€β”€ login_response_test.dart
    β”‚   β”‚               β”œβ”€β”€ register_response_test.dart
    β”‚   β”‚               └── users_response_test.dart
    β”‚   └── repositories
    β”‚       └── auth_repository_impl_test.dart
    β”œβ”€β”€ domain
    β”‚   └── usecases
    β”‚       └── auth
    β”‚           β”œβ”€β”€ get_users_test.dart
    β”‚           β”œβ”€β”€ post_login_test.dart
    β”‚           └── post_register_test.dart
    β”œβ”€β”€ helpers
    β”‚   β”œβ”€β”€ data_dummy
    β”‚   β”‚   β”œβ”€β”€ list_user_empty_response.json
    β”‚   β”‚   β”œβ”€β”€ list_user_response.json
    β”‚   β”‚   β”œβ”€β”€ login_success_response.json
    β”‚   β”‚   β”œβ”€β”€ login_unsuccessful_response.json
    β”‚   β”‚   β”œβ”€β”€ register_success_response.json
    β”‚   β”‚   └── register_unsuccessful_response.json
    β”‚   β”œβ”€β”€ json_reader.dart
    β”‚   β”œβ”€β”€ paths.dart
    β”‚   β”œβ”€β”€ test_mock.dart
    β”‚   └── test_mock.mocks.dart
    └── presentation
        └── page
            β”œβ”€β”€ auth
            β”‚   β”œβ”€β”€ cubit
            β”‚   β”‚   β”œβ”€β”€ login_cubit_test.dart
            β”‚   β”‚   β”œβ”€β”€ login_cubit_test.mocks.dart
            β”‚   β”‚   β”œβ”€β”€ login_state_test.dart
            β”‚   β”‚   β”œβ”€β”€ register_cubit_test.dart
            β”‚   β”‚   β”œβ”€β”€ register_cubit_test.mocks.dart
            β”‚   β”‚   └── register_state_test.dart
            β”‚   β”œβ”€β”€ login_page_test.dart
            β”‚   └── register_page_test.dart
            └── main
                β”œβ”€β”€ cubit
                β”‚   └── navdrawer_cubit_test.dart
                β”œβ”€β”€ dashboard
                β”‚   β”œβ”€β”€ cubit
                β”‚   β”‚   β”œβ”€β”€ users_cubit_test.dart
                β”‚   β”‚   β”œβ”€β”€ users_cubit_test.mocks.dart
                β”‚   β”‚   └── users_state_test.dart
                β”‚   └── dashboard_page_test.dart
                └── settings
                    β”œβ”€β”€ cubit
                    β”‚   └── settings_cubit_test.dart
                    └── settings_page_test.dart



Buy me coffee if you love my works β˜•οΈ

buymeacoffe      ko-fi      paypal



Comments
  • SharedPreference token

    SharedPreference token

    Malam gan, Sebelumnya terima kasih banyak project flutter nya.

    Saya mau bertanya mengenai token saat menggunakan postRequest, Ketika login dan mendapatkan token, setelah itu saya cek token nya ada isi.

    Tetapi ketika saya mau loading data dari api menggunakan method POST dan memanggil token yang ada di PrefManager, isi nya null.

    Mohon bantuannya gan, saat memanggil token kembali yang ada di prefManager.

    Terima kasih

    opened by restia79 7
  • Undefined name 'Strings'. What is it exactly?

    Undefined name 'Strings'. What is it exactly?

    What does the Strings class actually accomplish and how do we access it?

    I didn't find any point that enlightened me about this so that I could run the project without errors.

    For example:

    image

    In what I can collaborate, I make myself available for help. :)

    opened by felipecastrosales 2
  • [FEAT] Implementation Go Router

    [FEAT] Implementation Go Router

    What it does

    How to test

    1. Clone the project
    2. Run flutter run --flavor stg -t lib/main_stg.dart

    Screenshot

    Automatically direct user to login page if user not login

    image

    Grouping Router

    image

    Router in navigation drawer

    image

    image

    image

    References

    • https://github.com/flutter/packages/tree/main/packages/go_router/example
    • https://gorouter.dev/getting-started
    opened by Lzyct 0
  • [FEAT] Implement Multi Flavor

    [FEAT] Implement Multi Flavor

    What it does

    • Support multi flavor for Android and iOS
    • Setup different Firebase Project for Staging and Production
    • Setup Icon Launcher for Staging and Production

    How to test

    1. Run flutter run --flavor stg -t lib/main_stg.dart for staging or
    2. Run flutter run --flavor prd-t lib/main_prd.dart for production

    Screenshot

    iOS

    Simulator Screen Shot - iPhone 8 - 2022-07-03 at 22 50 58

    Android

    Screenshot_1656860730

    opened by Lzyct 0
  • [FEAT] Autofill Username and Password

    [FEAT] Autofill Username and Password

    What it does

    • Create Logout Function
    • Update library version to support Flutter 3
    • Autofill username and password on Android and iOS

    TODOS

    To make Autofill works, you need follow this :

    Android

    • You must login Google Account on your phone

    iOS

    • You must enable Associated Domains first to make Save Password support on iOS References : https://developer.apple.com/documentation/xcode/supporting-associated-domains

    How to test

    1. Install the app
    2. Fill username and password
    3. Logout
    4. Tap username and select saved username to fill username and password field

    Screenshot

    Android

    https://user-images.githubusercontent.com/1531684/171656247-d8827c1b-284d-4aab-87ac-1c160e8d4fee.mov

    iOS

    https://user-images.githubusercontent.com/1531684/171657016-1586b5d8-924c-4eec-b68b-7854d4fb14ef.mp4

    opened by Lzyct 0
  • [FIX] Resolve unit test issue

    [FIX] Resolve unit test issue

    What it does

    • Resolve build test issue
    • Update library version

    How to test

    1. run flutter clean && flutter pub get && flutter pub run build_runner build --delete-conflicting-outputs && flutter test

    Screenshot

    Not available

    opened by Lzyct 0
Owner
LazyCat Labs
LazyCat Labs Playground
LazyCat Labs
Random Users app, developed with Flutter and using Clean Architecture, BLoC, TDD and Functional Programming.

random_users This project is a sample of how to build a Flutter application using de benefits of Clean Architecture, TDD and Functional Programming. G

Yago Nunes 3 Jul 21, 2022
COVID-19 application made with Flutter, following Test Driven Development (TDD) and Clean Architecture along with Internationalization with JSON.

Covid App COVID-19 application made with Flutter, following Test Driven Development (TDD) and Clean Architecture along with Internationalization with

Sandip Pramanik 4 Aug 4, 2022
Flutter - Clean Architecture & TDD

Flutter - Clean Architecture & TDD IntroducciΓ³n Este proyecto consta de una aplicaciΓ³n mΓ³vil desarrollada en Flutter, la cual muestra informaciΓ³n acer

Jorge FernΓ‘ndez 21 Oct 26, 2022
Flutterstarterproject - Clean Architecture Flutter starter project, using tdd + bloc

Flutter Starter Project Generated by the Nero Lab CLI ?? A Nero Lab Project crea

Muhammad Noerhidayatullah 12 Dec 8, 2022
Flutter, Dart, TDD, Clean Architecture, SOLID e GetX

cep_search_clean_architecture A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to ge

Jadiel Santana 3 Feb 22, 2022
Made with Clean architecture + TDD + GraphQL + flutter_bloc + CodeCov + GitHooks + GitHub Actions (CI/CD) and finally with πŸ’™

Rick and Morty Info A simple app to demonstrate Clean Architecture with GraphQL and flutter_bloc Motivation In Martin Fowler's words, β€œAny fool can wr

Venkatesh Prasad 473 Dec 25, 2022
Clean Architecture Project with TDD Approach

Clean-Architecture-Project-with-TDD-Approach Small project to implement TDD(Testing Driven Development) by applying SOLID and YAGNI and rules(Clean Ar

null 7 Jun 24, 2022
Clean Architecture + TDD + SOLID + Dependency Injection + GitFlow + Mobx

Clean Architecture + TDD + SOLID + Dependency Injection + GitFlow + Mobx Flutter Interview Challenge This app is part of an interview process. It took

Vinicius Souza 13 Dec 28, 2022
Ouday 25 Dec 15, 2022
Flutter plugin for Firebase Auth UI. Supports popular auth providers by using native SDK for Android and iOS.

firebase_auth_ui Flutter plugin of Firebase UI which allows to add login/sign-up quickly. NOTE: This plugin is under development. Please provide Feedb

Sandip Fichadiya 50 Mar 23, 2022
User auth form - Signup and signin user auth form with ability to stay signed in and have an option to signout.

user_auth_form SIgnup and signin user authentification form Getting Started This project is a starting point for a Flutter application. A few resource

null 0 Jan 6, 2022
Flutter boilerplate with TDD architecture

flutter_tdd_architecture A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you

Dao Hong Vinh 6 May 25, 2022
clean architecture and clean code with flutter , with bloc and getx state managment .

example_bloc A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if

Khaled ElTohamy 6 Aug 22, 2022
Flutter Architecture inspired by Domain Driven Design, Onion and Clean Architecture

Inspiring Domain Driven Design Flutter Architecture Please take a look at my slides to learn more Strategic Domain Driven Design For Improving Flutter

Majid Hajian 324 Dec 25, 2022
Proyect with Clean Architecture / Hexagonal Architecture - Patron BLoC - The MovieDB API

flutter_movies_db A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you starte

null 2 Sep 22, 2022
πŸš€ Sample Flutter Clean Architecture on Rorty App focused on the scalability, testability and maintainability written in Dart, following best practices using Flutter.

Rorty Flutter Rorty ?? (work-in-progress for V2 ?? ??️ ??‍♀️ ⛏ ) Getting Started Flutter Clean Architecture in Rorty is a sample project that presents

Mr.Sanchez 138 Jan 1, 2023
This project follows the Reso Coder course for flutter test-driven-development with clean architecture and BloC state management for a random trivia simple app.

This project follows the Reso Coder course for flutter test-driven-development with clean architecture and BloC state management for a random trivia simple app.

Tomas B Sarmiento Abella 1 Jan 5, 2022
Build flutter posts app using Robert Martin (Uncle Bob) clean architecture.

Flutter clean architecture - Posts app Ψ¨Ψ§Ω„ΨΉΨ±Ψ¨ΩŠ #1 Intro Video Link #2 Explain clean architecture Video Link #3 Initial project , Add and explain requi

Rabee Omran 41 Dec 23, 2022
Carros Flutter - App utilizando Clean Architecture

Carros Flutter - App utilizando Clean Architecture Arquitetura Proposta de Arquitetura Limpa para o Dart/Flutter

Vinicius Zimmer 2 Nov 24, 2022