Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wip] [#18] [Backend] As a logged-in user, I can see the Survey Detail screen #76

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
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
6 changes: 6 additions & 0 deletions lib/api/survey_api_service.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:dio/dio.dart';
import 'package:retrofit/http.dart';
import 'package:survey_flutter/model/response/survey_detail_data_response.dart';
import 'package:survey_flutter/model/response/surveys_container_response.dart';

part 'survey_api_service.g.dart';
Expand All @@ -13,4 +14,9 @@ abstract class SurveyApiService {
@Query('page[number]') int pageNumber,
@Query('page[size]') int pageSize,
);

@GET('/surveys/{surveyId}')
Future<SurveyDetailDataResponse> getSurveyDetail(
@Path('surveyId') String surveyId,
);
}
28 changes: 28 additions & 0 deletions lib/model/answer_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'package:survey_flutter/model/response/answer_response.dart';
import 'package:survey_flutter/utils/string_extension.dart';

class AnswerModel {
final String id;
final String type;
final String text;
final int displayOrder;
final String displayType;

const AnswerModel({

Check warning on line 11 in lib/model/answer_model.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/answer_model.dart#L11

Added line #L11 was not covered by tests
required this.id,
required this.type,
required this.text,
required this.displayOrder,
required this.displayType,
});
}

extension AnswerModelExtension on AnswerResponse {
AnswerModel toAnswerModel() => AnswerModel(
id: id.orEmpty(),
type: type.orEmpty(),
text: text.orEmpty(),
displayOrder: displayOrder ?? 0,
displayType: displayType.orEmpty(),

Check warning on line 26 in lib/model/answer_model.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/answer_model.dart#L21-L26

Added lines #L21 - L26 were not covered by tests
);
}
30 changes: 30 additions & 0 deletions lib/model/question_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'package:survey_flutter/model/answer_model.dart';
import 'package:survey_flutter/model/response/question_response.dart';
import 'package:survey_flutter/utils/string_extension.dart';

class QuestionModel {
final String id;
final String type;
final String text;
final String displayType;
final List<AnswerModel> answers;

QuestionModel({

Check warning on line 12 in lib/model/question_model.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/question_model.dart#L12

Added line #L12 was not covered by tests
required this.id,
required this.type,
required this.text,
required this.displayType,
required this.answers,
});
}

extension QuestionModelExtension on QuestionResponse {
QuestionModel toQuestionModel() => QuestionModel(
id: id.orEmpty(),
type: type.orEmpty(),
text: text.orEmpty(),
displayType: displayType.orEmpty(),

Check warning on line 26 in lib/model/question_model.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/question_model.dart#L22-L26

Added lines #L22 - L26 were not covered by tests
answers:
answers?.map((answer) => answer.toAnswerModel()).toList() ?? [],

Check warning on line 28 in lib/model/question_model.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/question_model.dart#L28

Added line #L28 was not covered by tests
);
}
28 changes: 28 additions & 0 deletions lib/model/response/answer_response.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'package:freezed_annotation/freezed_annotation.dart';

part 'answer_response.g.dart';

@JsonSerializable()
class AnswerResponse {
@JsonKey(name: 'id')
final String? id;
@JsonKey(name: 'type')
final String? type;
@JsonKey(name: 'text')
final String? text;
@JsonKey(name: 'display_order')
final int? displayOrder;
@JsonKey(name: 'display_type')
final String? displayType;

AnswerResponse({

Check warning on line 18 in lib/model/response/answer_response.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/response/answer_response.dart#L18

Added line #L18 was not covered by tests
this.id,
this.type,
this.text,
this.displayOrder,
this.displayType,
});

factory AnswerResponse.fromJson(Map<String, dynamic> json) =>
_$AnswerResponseFromJson(json);

Check warning on line 27 in lib/model/response/answer_response.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/response/answer_response.dart#L26-L27

Added lines #L26 - L27 were not covered by tests
}
29 changes: 29 additions & 0 deletions lib/model/response/question_response.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:survey_flutter/model/response/answer_response.dart';

part 'question_response.g.dart';

@JsonSerializable()
class QuestionResponse {
@JsonKey(name: 'id')
final String? id;
@JsonKey(name: 'type')
final String? type;
@JsonKey(name: 'text')
final String? text;
@JsonKey(name: 'display_type')
final String? displayType;
@JsonKey(name: 'answers')
final List<AnswerResponse>? answers;

QuestionResponse({

Check warning on line 19 in lib/model/response/question_response.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/response/question_response.dart#L19

Added line #L19 was not covered by tests
this.id,
this.type,
this.text,
this.displayType,
this.answers,
});

factory QuestionResponse.fromJson(Map<String, dynamic> json) =>
_$QuestionResponseFromJson(json);

Check warning on line 28 in lib/model/response/question_response.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/response/question_response.dart#L27-L28

Added lines #L27 - L28 were not covered by tests
}
15 changes: 15 additions & 0 deletions lib/model/response/survey_detail_data_response.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:survey_flutter/model/response/survey_detail_response.dart';

part 'survey_detail_data_response.g.dart';

@JsonSerializable()
class SurveyDetailDataResponse {
@JsonKey(name: 'data')
final SurveyDetailResponse? surveyDetailResponse;

SurveyDetailDataResponse(this.surveyDetailResponse);

Check warning on line 11 in lib/model/response/survey_detail_data_response.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/response/survey_detail_data_response.dart#L11

Added line #L11 was not covered by tests

factory SurveyDetailDataResponse.fromJson(Map<String, dynamic> json) =>
_$SurveyDetailDataResponseFromJson(json);

Check warning on line 14 in lib/model/response/survey_detail_data_response.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/response/survey_detail_data_response.dart#L13-L14

Added lines #L13 - L14 were not covered by tests
}
35 changes: 35 additions & 0 deletions lib/model/response/survey_detail_response.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:survey_flutter/model/response/question_response.dart';

part 'survey_detail_response.g.dart';

@JsonSerializable()
class SurveyDetailResponse {
@JsonKey(name: 'id')
final String? id;
@JsonKey(name: 'type')
final String? type;
@JsonKey(name: 'title')
final String? title;
@JsonKey(name: 'description')
final String? description;
@JsonKey(name: 'cover_image_url')
final String? coverImageUrl;
@JsonKey(name: 'survey_type')
final String? surveyType;
@JsonKey(name: 'questions')
final List<QuestionResponse>? questions;

SurveyDetailResponse({

Check warning on line 23 in lib/model/response/survey_detail_response.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/response/survey_detail_response.dart#L23

Added line #L23 was not covered by tests
this.id,
this.type,
this.title,
this.description,
this.coverImageUrl,
this.surveyType,
this.questions,
});

factory SurveyDetailResponse.fromJson(Map<String, dynamic> json) =>
_$SurveyDetailResponseFromJson(json);

Check warning on line 34 in lib/model/response/survey_detail_response.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/response/survey_detail_response.dart#L33-L34

Added lines #L33 - L34 were not covered by tests
}
37 changes: 37 additions & 0 deletions lib/model/survey_detail_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import 'package:survey_flutter/model/question_model.dart';
import 'package:survey_flutter/model/response/survey_detail_response.dart';
import 'package:survey_flutter/utils/string_extension.dart';

class SurveyDetailModel {
final String id;
final String type;
final String title;
final String description;
final String coverImageUrl;
final String surveyType;
final List<QuestionModel> questions;

const SurveyDetailModel({

Check warning on line 14 in lib/model/survey_detail_model.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/survey_detail_model.dart#L14

Added line #L14 was not covered by tests
required this.id,
required this.type,
required this.title,
required this.description,
required this.coverImageUrl,
required this.surveyType,
required this.questions,
});
}

extension SurveyDetailModelExtension on SurveyDetailResponse {
SurveyDetailModel toSurveyDetailModel() => SurveyDetailModel(
id: id.orEmpty(),
type: type.orEmpty(),
title: type.orEmpty(),
description: description.orEmpty(),
coverImageUrl: coverImageUrl.orEmpty(),
surveyType: surveyType.orEmpty(),

Check warning on line 32 in lib/model/survey_detail_model.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/survey_detail_model.dart#L26-L32

Added lines #L26 - L32 were not covered by tests
questions:
questions?.map((question) => question.toQuestionModel()).toList() ??
[],

Check warning on line 35 in lib/model/survey_detail_model.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/survey_detail_model.dart#L34-L35

Added lines #L34 - L35 were not covered by tests
);
}
18 changes: 18 additions & 0 deletions lib/repositories/survey_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import 'package:survey_flutter/api/exception/network_exceptions.dart';
import 'package:survey_flutter/api/survey_api_service.dart';
import 'package:survey_flutter/di/provider/dio_provider.dart';
import 'package:survey_flutter/model/survey_detail_model.dart';
import 'package:survey_flutter/model/survey_model.dart';
import 'package:survey_flutter/storage/survey_storage.dart';

Expand All @@ -21,6 +22,8 @@
required int pageNumber,
required int pageSize,
});

Future<SurveyDetailModel> getSurveyDetail(String surveyid);
}

class SurveyRepositoryImpl extends SurveyRepository {
Expand All @@ -45,4 +48,19 @@
throw NetworkExceptions.fromDioException(exception);
}
}

@override

Check warning on line 52 in lib/repositories/survey_repository.dart

View check run for this annotation

Codecov / codecov/patch

lib/repositories/survey_repository.dart#L52

Added line #L52 was not covered by tests
Future<SurveyDetailModel> getSurveyDetail(String surveyid) async {
try {
final response = await _apiService.getSurveyDetail(surveyid);
final surveyDetailResponse = response.surveyDetailResponse;

Check warning on line 56 in lib/repositories/survey_repository.dart

View check run for this annotation

Codecov / codecov/patch

lib/repositories/survey_repository.dart#L55-L56

Added lines #L55 - L56 were not covered by tests
if (surveyDetailResponse == null) {
// TODO: Update catching
throw const NetworkExceptions.unexpectedError();
}
return surveyDetailResponse.toSurveyDetailModel();

Check warning on line 61 in lib/repositories/survey_repository.dart

View check run for this annotation

Codecov / codecov/patch

lib/repositories/survey_repository.dart#L61

Added line #L61 was not covered by tests
} catch (exception) {
throw NetworkExceptions.fromDioException(exception);

Check warning on line 63 in lib/repositories/survey_repository.dart

View check run for this annotation

Codecov / codecov/patch

lib/repositories/survey_repository.dart#L63

Added line #L63 was not covered by tests
}
}
}
20 changes: 20 additions & 0 deletions lib/usecases/get_survey_detail_use_case.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:survey_flutter/model/survey_detail_model.dart';
import 'package:survey_flutter/repositories/survey_repository.dart';
import 'package:survey_flutter/usecases/base/base_use_case.dart';

class GetSurveyDetailUseCase extends UseCase<SurveyDetailModel, String> {
final SurveyRepository _surveyRepository;

GetSurveyDetailUseCase(this._surveyRepository);

@override
// ignore: avoid_renaming_method_parameters
Future<Result<SurveyDetailModel>> call(String surveyId) async {
try {
final result = await _surveyRepository.getSurveyDetail(surveyId);
return Success(result);
} catch (exception) {
return Failed(UseCaseException(exception));
}
}
}
4 changes: 4 additions & 0 deletions lib/utils/string_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
extension StringExtension on String? {
String unWrappedOr(String fallback) => this ?? fallback;
String orEmpty() => unWrappedOr('');

Check warning on line 3 in lib/utils/string_extension.dart

View check run for this annotation

Codecov / codecov/patch

lib/utils/string_extension.dart#L2-L3

Added lines #L2 - L3 were not covered by tests
}
Loading