Fakultas Ilmu Komputer UI

Commit f93d3b87 authored by Dzaky Noor Hasyim's avatar Dzaky Noor Hasyim
Browse files

Merge branch 'PBI-9-info_kegiatan' of...

Merge branch 'PBI-9-info_kegiatan' of https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/sosial/bisago/bisago-fe into dev-noor
parents 67baa1a5 2960d367
import 'dart:async';
import 'package:bisaGo/model/kegiatan.dart';
import 'package:bisaGo/network/data/network_model.dart';
import 'package:bisaGo/repository/kegiatan_repository.dart';
import 'package:get_it/get_it.dart';
import 'package:rxdart/rxdart.dart';
class KegiatanBloc {
KegiatanRepository _kegiatanRepository;
StreamController _kegiatanListController;
List<KegiatanModel> allKegiatanFromApi;
StreamSink<NetworkModel<KegiatanList>> get kegiatanListSink =>
_kegiatanListController.sink;
Stream<NetworkModel<KegiatanList>> get kegiatanListStream =>
_kegiatanListController.stream;
KegiatanBloc(String placeId) {
_kegiatanListController = BehaviorSubject<NetworkModel<KegiatanList>>();
_kegiatanRepository = GetIt.instance.get<BaseKegiatanRepository>();
fetchKegiatanList(placeId);
}
Future<void> fetchKegiatanList(String placeId) async {
kegiatanListSink.add(NetworkModel.loading('Getting Kegiatan'));
try {
final kegiatanListResponse =
await _kegiatanRepository.fetchKegiatan(placeId);
allKegiatanFromApi = List.from(kegiatanListResponse.allKegiatan);
kegiatanListSink.add(NetworkModel.completed(kegiatanListResponse));
} catch (e) {
kegiatanListSink.add(NetworkModel.error(e.toString()));
}
}
void resetKegiatanList() {
kegiatanListSink
.add(NetworkModel.completed(KegiatanList(allKegiatanFromApi)));
}
void dispose() {
_kegiatanListController?.close();
}
}
\ No newline at end of file
import 'package:bisaGo/repository/kegiatan_repository.dart';
import 'package:bisaGo/repository/komentar_posting_repository.dart';
import 'package:bisaGo/repository/komentar_repository.dart';
import 'package:bisaGo/repository/komunitas_repository.dart';
......@@ -24,7 +25,9 @@ class AppGetIt {
() => KomentarPostingRepository());
_getIt
.registerLazySingleton<BaseLokasiRepository>(() => LokasiRepository());
_getIt
.registerLazySingleton<BaseLayananRepository>(() => LayananRepository());
_getIt
.registerLazySingleton<BaseLayananRepository>(() => LayananRepository());
_getIt
.registerLazySingleton<BaseKegiatanRepository>(() => KegiatanRepository());
}
}
import 'package:json_annotation/json_annotation.dart';
import 'package:bisaGo/config/custom_serializer.dart';
part 'kegiatan.g.dart';
@JsonSerializable()
class KegiatanList {
final List<KegiatanModel> allKegiatan;
KegiatanList(this.allKegiatan);
}
@JsonSerializable()
class KegiatanModel {
final int id;
@JsonKey(name: 'nama_lokasi')
final String namaLokasi;
final String creator;
final String namaKegiatan;
final String penyelenggara;
final String narahubung;
final String deskripsi;
@JsonKey(name: 'time_start', fromJson: CustomSerializer.stringToDateTime)
final DateTime timeStart;
@JsonKey(name: 'time_end', fromJson: CustomSerializer.stringToDateTime)
final DateTime timeEnd;
KegiatanModel(
{
this.id,
this.namaLokasi,
this.creator,
this.namaKegiatan,
this.penyelenggara,
this.narahubung,
this.deskripsi,
this.timeStart,
this.timeEnd
}
);
factory KegiatanModel.fromJson(Map<String, dynamic> json) => _$KegiatanModelFromJson(json);
Map<String, dynamic> toJson() => _$KegiatanModelToJson(this);
}
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'kegiatan.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
KegiatanList _$KegiatanListFromJson(Map<String, dynamic> json) {
return KegiatanList(
(json['allKegiatan'] as List)
?.map((e) => e == null
? null
: KegiatanModel.fromJson(e as Map<String, dynamic>))
?.toList(),
);
}
Map<String, dynamic> _$KegiatanListToJson(KegiatanList instance) =>
<String, dynamic>{
'allKegiatan': instance.allKegiatan,
};
KegiatanModel _$KegiatanModelFromJson(Map<String, dynamic> json) {
return KegiatanModel(
id: json['id'] as int,
namaLokasi: json['nama_lokasi'] as String,
creator: json['creator'] as String,
namaKegiatan: json['namaKegiatan'] as String,
penyelenggara: json['penyelenggara'] as String,
narahubung: json['narahubung'] as String,
deskripsi: json['deskripsi'] as String,
timeStart: CustomSerializer.stringToDateTime(json['time_start'] as String),
timeEnd: CustomSerializer.stringToDateTime(json['time_end'] as String),
);
}
Map<String, dynamic> _$KegiatanModelToJson(KegiatanModel instance) =>
<String, dynamic>{
'id': instance.id,
'nama_lokasi': instance.namaLokasi,
'creator': instance.creator,
'namaKegiatan': instance.namaKegiatan,
'penyelenggara': instance.penyelenggara,
'narahubung': instance.narahubung,
'deskripsi': instance.deskripsi,
'time_start': instance.timeStart?.toIso8601String(),
'time_end': instance.timeEnd?.toIso8601String(),
};
import 'package:bisaGo/bloc/kegiatan_bloc.dart';
import 'package:bisaGo/bloc/lokasi_response_bloc.dart';
import 'package:bisaGo/component/image_holder.dart';
import 'package:bisaGo/model/kegiatan.dart';
import 'package:bisaGo/model/lokasi.dart';
import 'package:flutter/material.dart';
import 'package:bisaGo/bloc/komentar_bloc.dart';
......@@ -13,10 +15,13 @@ import 'package:bisaGo/model/komentar.dart';
import 'package:bisaGo/page/login/login.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'kegiatan.dart';
class Fasilitas extends StatefulWidget {
final Lokasi lokasi;
final KegiatanModel kegiatan;
final KomentarModel komentar;
const Fasilitas({@required this.lokasi, this.komentar, Key key})
const Fasilitas({@required this.lokasi, this.kegiatan, this.komentar, Key key})
: super(key: key);
@override
_FasilitasState createState() => _FasilitasState();
......@@ -38,14 +43,18 @@ class _FasilitasState extends State<Fasilitas> {
var runningTextVal = true;
var sortKomentar = -1;
var showUrutan = true;
List<KegiatanModel> allKegiatanFromApi;
List<KomentarModel> allKomentarFromApi;
KomentarBloc _bloc;
KegiatanBloc _kegiatanBloc;
KomentarBloc _komentarBloc;
LokasiResponseBloc _lokasiBloc;
@override
void initState() {
allKegiatanFromApi = [];
allKomentarFromApi = [];
_bloc = KomentarBloc(widget.lokasi.placeId);
_kegiatanBloc = KegiatanBloc(widget.lokasi.placeId);
_komentarBloc = KomentarBloc(widget.lokasi.placeId);
_lokasiBloc = LokasiResponseBloc();
_postSearchHistory();
super.initState();
......@@ -243,7 +252,7 @@ class _FasilitasState extends State<Fasilitas> {
bottom: regularSpace,
),
child: StreamBuilder(
stream: _bloc.komentarListStream,
stream: _komentarBloc.komentarListStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
switch (snapshot.data.status) {
......@@ -351,9 +360,46 @@ class _FasilitasState extends State<Fasilitas> {
right: doubleSpace,
bottom: regularSpace,
),
child: const Center(
child: Text('Belum ada informasi'),
),
child: StreamBuilder(
stream: _kegiatanBloc.kegiatanListStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
switch (snapshot.data.status) {
case Status.loading:
return const Center(
child: CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation<Color>(greenPrimary),
),
);
break;
case Status.completed:
allKegiatanFromApi = snapshot.data.data.allKegiatan;
if (allKegiatanFromApi.isEmpty) {
return const Center(
child: Text('Belum ada informasi')
);
}
return Column(
children: allKegiatanFromApi
.map<Widget>((k) => Kegiatan(
lokasi: widget.lokasi,
kegiatan: k))
.toList()
);
break;
case Status.error:
return const Center(
child: Text('Belum ada informasi'),
);
break;
}
}
return Container();
}
)
),
],
),
......@@ -383,7 +429,8 @@ class _FasilitasState extends State<Fasilitas> {
kursiDisabilitasVal = true;
runningTextVal = true;
sortKomentar = -1;
_bloc.dispose();
_komentarBloc.dispose();
_kegiatanBloc.dispose();
super.dispose();
}
......@@ -400,7 +447,7 @@ class _FasilitasState extends State<Fasilitas> {
nama: widget.lokasi.name,
placeId: widget.lokasi.placeId,
)))
.then((value) => _bloc.fetchKomentarList(widget.lokasi.placeId));
.then((value) => _komentarBloc.fetchKomentarList(widget.lokasi.placeId));
}
}
......
// import 'package:bisaGo/config/strings.dart';
import 'package:bisaGo/model/lokasi.dart';
import 'package:flutter/material.dart';
// import 'package:bisaGo/component/image_holder.dart';
import 'package:bisaGo/config/styles.dart';
import 'package:bisaGo/model/kegiatan.dart';
class Kegiatan extends StatefulWidget {
final Lokasi lokasi;
final KegiatanModel kegiatan;
const Kegiatan({@required this.kegiatan, @required this.lokasi, Key key})
: super(key: key);
@override
_KegiatanState createState() => _KegiatanState();
}
class _KegiatanState extends State<Kegiatan> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return InkWell(
// key: Key('Kegiatan'),
child: Container(
margin: const EdgeInsets.only(bottom: regularSpace),
padding: const EdgeInsets.all(doubleSpace),
decoration: BoxDecoration(
boxShadow: regularShadow,
border: Border.all(width: 2, color: greenPrimary.withOpacity(0.4)),
borderRadius: const BorderRadius.all(
Radius.circular(10)
),
color: Colors.white,
),
child: Stack(
children: <Widget>[
Column(
children: <Widget>[
Container(
margin: const EdgeInsets.only(bottom: regularSpace),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Kegiatan',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w800,
color: Colors.black,
fontFamily: 'Muli',
),
),
],
),
),
Container(
margin: const EdgeInsets.only(bottom: regularSpace),
child: SizedBox(
height: 160,
// child: ImageHolder(
// url: widget.kegiatan.image,
// fasilitas: widget.kegiatan.tag
// )
child: Text('Image here'),
)
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Flexible(
child: Text(
'ditambahkan oleh TEST',
softWrap: true,
style: const TextStyle(
fontSize: 12,
color: Colors.black,
fontFamily: 'Muli',
fontStyle: FontStyle.italic,
),
),
),
],
),
],
),
],
),
));
}
}
This diff is collapsed.
import 'package:bisaGo/model/kegiatan.dart';
import 'package:bisaGo/network/network_interface.dart';
abstract class BaseKegiatanRepository {
Future<KegiatanList> fetchKegiatan(String placeId);
}
class KegiatanRepository implements BaseKegiatanRepository {
final NetworkInterface _network = NetworkInterface();
@override
Future<KegiatanList> fetchKegiatan(String placeId) async {
final url = '/informasi-fasilitas/lokasi/list-kegiatan/$placeId';
final response = await _network.get(url: url, isLogin: false);
final data = response.values.toList().reversed.toList();
return KegiatanList(data
.map<KegiatanModel>((kegiatan) => KegiatanModel.fromJson(kegiatan))
.toList());
}
}
\ No newline at end of file
......@@ -29,7 +29,6 @@ dependencies:
cupertino_icons: ^0.1.2
google_maps_flutter: ^0.5.24+1
flutter_dotenv: ^2.1.0
json_serializable: ^3.2.5
cached_network_image: ^2.0.0
shared_preferences: 0.5.6+3
smooth_star_rating: ^1.1.0+1
......@@ -45,6 +44,7 @@ dependencies:
material_design_icons_flutter: ^4.0.5755
get_it: ^5.0.1
rxdart: ^0.23.1
json_annotation: ^3.1.1
dev_dependencies:
flutter_test:
......@@ -54,6 +54,7 @@ dev_dependencies:
# Linter dependency
pedantic: ^1.8.0 # The default Linter package used in Google
build_runner: ^1.8.0
json_serializable: ^3.2.5
flutter_icons:
android: "launcher_icon"
......
import 'package:bisaGo/config/strings.dart';
import 'package:bisaGo/model/kegiatan.dart';
import 'package:bisaGo/model/lokasi.dart';
import 'package:bisaGo/page/filter_fasilitas/postingan/detail_post_kegiatan.dart';
import 'package:bisaGo/repository/kegiatan_repository.dart';
import 'package:bisaGo/repository/lokasi_repository.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:get_it/get_it.dart';
class MockDetailPostKegiatan extends Fake implements KegiatanRepository {
final mockKegiatan = {
'id': 2,
'nama_lokasi': 'Margo City',
'creator': 'Putri Salsabila',
'nama_kegiatan': 'Kopdar Rutin',
'penyelenggara': 'DTB Indonesia',
'narahubung': 'Putsal 08123123123',
'deskripsi': 'lorem ipsum dolor sit amet',
'time_start': '12-12-2021 06:30:00',
'time_end': '12-12-2021 09:30:00'
};
@override
Future<KegiatanList> fetchKegiatan(String namaLokasi) async {
return Future.value(KegiatanList([KegiatanModel.fromJson(mockKegiatan)]));
}
@override
Future<dynamic> updateKegiatan(Map<String, dynamic> newKegiatanData,
String namaLokasi, int id, String token) async {
final responseBody = {'response': 'Fasilitas updated'};
final statusCode = 202;
return Future.value(Response(responseBody.toString(), statusCode));
}
}
class MockLokasi extends Fake implements LokasiRepository {
final mockLokasi = {
'name': 'Margo City',
'alamat': 'Jl. Margonda Raya No.358, Kemiri Muka, Kecamatan Beji, Kota Depok, Jawa Barat 16423',
'image': 'Margo.jpg',
'no_telp': '02178870888',
'counter': 69,
};
@override
Future<LokasiListResponse> fetchLokasi() async {
return Future.value(LokasiListResponse([Lokasi.fromJson(mockLokasi)]));
}
}
class MockKomentarPostingKegiatan extends Fake implements KomentarPostingKegiatanRepository {}
void main() {
final mockLokasi = {
'name': 'Margo City',
'alamat': 'Jl. Margonda Raya No.358, Kemiri Muka, Kecamatan Beji, Kota Depok, Jawa Barat 16423',
'image': 'Margo.jpg',
'no_telp': '02178870888',
'counter': 69,
};
final mockKegiatan = {
'id': 2,
'nama_lokasi': 'Margo City',
'creator': 'Putri Salsabila',
'nama_kegiatan': 'Kopdar Rutin',
'penyelenggara': 'DTB Indonesia',
'narahubung': 'Putsal 08123123123',
'deskripsi': 'lorem ipsum dolor sit amet',
'time_start': '12-12-2021 06:30:00',
'time_end': '12-12-2021 09:30:00'
};
setUpAll(() {
final _getIt = GetIt.instance;
_getIt.registerLazySingleton<BaseKegiatanRepository>(
() => MockDetailPostKegiatan());
_getIt.registerLazySingleton<BaseLokasiRepository>(
() => MockLokasi());
_getIt.registerLazySingleton<BaseKomentarPostingKegiatanRepository>(
() => MockKomentarPostingKegiatan());
});
testWidgets(
'Detail Post Kegiatan Page - Positive Test', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: DetailPostKegiatanPage(
lokasi: Lokasi.fromJson(mockLokasi),
kegiatan: KegiatanModel.fromJson(mockKegiatan)
)
));
await tester.pump();
expect(find.byType(DetailPostKegiatanPage), findsOneWidget);
expect(find.text('Kopdar Rutin'), findsOneWidget);
expect(find.text('oleh DTB Indonesia'), findsOneWidget);
expect(find.text('lorem ipsum dolor sit amet'), findsOneWidget);
expect(find.text('Putsal 08123123123'), findsOneWidget);
expect(find.text('Putri Salsabila'), findsOneWidget);
expect(find.text('Komentar'), findsOneWidget);
expect(find.text('Tambah Komentar'), findsOneWidget);
});
testWidgets(
'Detail Post Kegiatan Page - Negative Test', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: DetailPostKegiatanPage(
lokasi: Lokasi.fromJson(mockLokasi),
kegiatan: KegiatanModel.fromJson(mockKegiatan)
)
));
await tester.pump();
expect(find.byType(DetailPostKegiatanPage), findsOneWidget);
expect(find.text('Kopdar Rajin'), findsOneWidget);
expect(find.text('oleh DTB'), findsOneWidget);
expect(find.text('lorem ipsum'), findsOneWidget);
expect(find.text('Putra 08123123123'), findsOneWidget);
expect(find.text('Putri Putra'), findsOneWidget);
expect(find.text('Komentar Review'), findsOneWidget);
expect(find.text('Post Komentar'), findsOneWidget);
});
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment