Skip to content

Commit

Permalink
Merge pull request #125 from chornerman/release/0.5.0
Browse files Browse the repository at this point in the history
Release - 0.5.0
  • Loading branch information
chornerman authored Jan 19, 2023
2 parents 4b54fd5 + 9077c71 commit ccab404
Show file tree
Hide file tree
Showing 76 changed files with 1,382 additions and 165 deletions.
48 changes: 40 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,48 @@
# survey
# Survey

Nimble Flutter internal certification

## Prerequisite

- Flutter 3.3
- [Recommended] [Flutter Version Management (fvm)](https://fvm.app/)

## Getting Started

This project is a starting point for a Flutter application.
### Set up the project
To set up this project locally, follow the steps below:
- Create `.env` files inside the project's root directory and add the required environment variables into them. Take a look at the `.env.sample` to see the list of all required environment variables
- To set up the **staging** environment, create `.env.staging`
- To set up the **production** environment, create `.env`
- Generate Flutter files using the below command:
```
fvm flutter packages pub run build_runner build --delete-conflicting-outputs
```

### Run the app

#### Staging
To run the staging flavor app, use the below command:
```
fvm flutter run --flavor staging
```

#### Production
To run the production flavor app, use the below command:
```
fvm flutter run --flavor production
```

A few resources to get you started if this is your first Flutter project:
### Run tests

- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
#### Unit tests
To run all unit tests, use the below command:
```
fvm flutter test
```

For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
#### Integration tests
To run integration tests with an emulator, use the below command:
```
fvm flutter drive --driver=integration_test_driver/integration_test_driver.dart --flavor staging --target=integration_test/{test_file}.dart
```
15 changes: 7 additions & 8 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="co.nimblehq.survey">

<application
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
Expand All @@ -12,25 +11,25 @@
android:hardwareAccelerated="true"
android:label="@string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:theme="@style/LaunchTheme"
android:windowSoftInputMode="adjustResize">
android:windowSoftInputMode="adjustResize"
android:screenOrientation="portrait">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" />
android:resource="@style/NormalTheme"/>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
android:value="2"/>
</application>
</manifest>
</manifest>
Binary file added android/app/src/main/res/drawable-hdpi/splash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added android/app/src/main/res/drawable-mdpi/splash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 6 additions & 9 deletions android/app/src/main/res/drawable-v21/launch_background.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />

<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
<item>
<bitmap android:gravity="center" android:src="@drawable/splash"/>
</item>
</layer-list>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added android/app/src/main/res/drawable/background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 6 additions & 9 deletions android/app/src/main/res/drawable/launch_background.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />

<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
<item>
<bitmap android:gravity="center" android:src="@drawable/splash"/>
</item>
</layer-list>
19 changes: 19 additions & 0 deletions android/app/src/main/res/values-night-v31/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowSplashScreenBackground">#15151A</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
19 changes: 19 additions & 0 deletions android/app/src/main/res/values-v31/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowSplashScreenBackground">#15151A</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
3 changes: 3 additions & 0 deletions android/app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Expand Down
Binary file added assets/images/ic_nimble_splash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions flutter_native_splash.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
flutter_native_splash:
background_image: "assets/images/bg_onboarding.png"
image: assets/images/ic_nimble_splash.png
android_12:
color: "#15151A"
android_screen_orientation: portrait
31 changes: 31 additions & 0 deletions integration_test/fake_service/fake_auth_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:survey/api/request/login_request.dart';
import 'package:survey/api/request/reset_password_request.dart';
import 'package:survey/api/response/token_response.dart';
import 'package:survey/api/service/auth_service.dart';

import 'fake_data.dart';

const loginKey = 'login';
const resetPasswordKey = 'resetPassword';

class FakeAuthService extends Fake implements AuthService {
@override
Future<TokenResponse> login(LoginRequest body) async {
final response = FakeData.fakeResponses[loginKey]!;

if (response.statusCode != successStatusCode) {
throw fakeDioError(response.statusCode);
}
return TokenResponse.fromJson(response.json);
}

@override
Future<void> resetPassword(ResetPasswordRequest body) async {
final response = FakeData.fakeResponses[resetPasswordKey]!;

if (response.statusCode != successStatusCode) {
throw fakeDioError(response.statusCode);
}
}
}
36 changes: 36 additions & 0 deletions integration_test/fake_service/fake_data.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'package:dio/dio.dart';

const successStatusCode = 200;
const _errorStatusCode = 400;

class FakeResponse {
final int statusCode;
final Map<String, dynamic> json;

FakeResponse(this.statusCode, this.json);
}

class FakeData {
FakeData._();

static Map<String, FakeResponse> fakeResponses = {};

static void addSuccessResponse(String key, Map<String, dynamic> response) {
final newResponse = FakeResponse(successStatusCode, response);
fakeResponses.update(key, (response) => newResponse,
ifAbsent: () => newResponse);
}

static void addErrorResponse(String key) {
final newResponse = FakeResponse(_errorStatusCode, {});
fakeResponses.update(key, (response) => newResponse,
ifAbsent: () => newResponse);
}
}

DioError fakeDioError(int statusCode) => DioError(
response: Response(
statusCode: statusCode, requestOptions: RequestOptions(path: '')),
type: DioErrorType.response,
requestOptions: RequestOptions(path: ''),
);
42 changes: 42 additions & 0 deletions integration_test/fake_service/fake_survey_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:survey/api/request/submit_survey_request.dart';
import 'package:survey/api/response/survey_detail_response.dart';
import 'package:survey/api/response/surveys_response.dart';
import 'package:survey/api/service/survey_service.dart';

import 'fake_data.dart';

const getSurveysKey = 'getSurveys';
const getSurveyDetailKey = 'getSurveyDetail';
const submitSurveyKey = 'submitSurvey';

class FakeSurveyService extends Fake implements SurveyService {
@override
Future<SurveysResponse> getSurveys(int pageNumber, int pageSize) async {
final response = FakeData.fakeResponses[getSurveysKey]!;

if (response.statusCode != successStatusCode) {
throw fakeDioError(response.statusCode);
}
return SurveysResponse.fromJson(response.json);
}

@override
Future<SurveyDetailResponse> getSurveyDetail(String surveyId) async {
final response = FakeData.fakeResponses[getSurveyDetailKey]!;

if (response.statusCode != successStatusCode) {
throw fakeDioError(response.statusCode);
}
return SurveyDetailResponse.fromJson(response.json);
}

@override
Future<void> submitSurvey(SubmitSurveyRequest body) async {
final response = FakeData.fakeResponses[submitSurveyKey]!;

if (response.statusCode != successStatusCode) {
throw fakeDioError(response.statusCode);
}
}
}
19 changes: 19 additions & 0 deletions integration_test/fake_service/fake_user_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:survey/api/response/user_response.dart';
import 'package:survey/api/service/user_service.dart';

import 'fake_data.dart';

const getUserKey = 'getUser';

class FakeUserService extends Fake implements UserService {
@override
Future<UserResponse> getUser() async {
final response = FakeData.fakeResponses[getUserKey]!;

if (response.statusCode != successStatusCode) {
throw fakeDioError(response.statusCode);
}
return UserResponse.fromJson(response.json);
}
}
Loading

0 comments on commit ccab404

Please sign in to comment.