diff --git a/.vscode/settings.json b/.vscode/settings.json
index 7f69797..6451b67 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,3 +1,8 @@
{
- "dart.runPubGetOnPubspecChanges": false
+ "dart.runPubGetOnPubspecChanges": false,
+ "markdownlint.config": {
+ "MD007": false,
+ "MD033": false,
+ "MD041": false
+ }
}
\ No newline at end of file
diff --git a/packages/apklis_web_api/.metadata b/packages/apklis_web_api/.metadata
new file mode 100644
index 0000000..cb69e6e
--- /dev/null
+++ b/packages/apklis_web_api/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: 02c026b03cd31dd3f867e5faeb7e104cce174c5f
+ channel: stable
+
+project_type: package
diff --git a/packages/apklis_web_api/LICENSE b/packages/apklis_web_api/LICENSE
new file mode 100644
index 0000000..749ff23
--- /dev/null
+++ b/packages/apklis_web_api/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Flutter Cuba Contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/packages/apklis_web_api/README.md b/packages/apklis_web_api/README.md
new file mode 100644
index 0000000..c60f344
--- /dev/null
+++ b/packages/apklis_web_api/README.md
@@ -0,0 +1,38 @@
+
Apklis Web API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+---
+
+Interfaz para la posterior implementación de un paquete en [Dart](https://dart.dev) para interactuar con la API de [Apklis](https://apklis.cu). El resto de paquetes del [ecosistema de Apklis Dart/Flutter](https://github.com/fluttercuba/apklis-dart-flutter) utilizará este paquete como un contrato en el que mediante inyección de dependencias se inyectarian las implementaciones concretas.
diff --git a/packages/apklis_web_api/assets/response_example.json b/packages/apklis_web_api/assets/response_example.json
new file mode 100644
index 0000000..d4dd5d4
--- /dev/null
+++ b/packages/apklis_web_api/assets/response_example.json
@@ -0,0 +1,180 @@
+{
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "facets": {},
+ "results": [
+ {
+ "icon": "https://archive.apklis.cu/application/icon/club.postdata.covid19cuba-v14.png",
+ "background": "",
+ "package_name": "club.postdata.covid19cuba",
+ "name": "Covid19 Cuba Data",
+ "video_url": "",
+ "video_img": "",
+ "description": "Proyecto para conocer los reportes diarios, estadísticas, etc. respecto a la Covid-19 en Cuba.
Sitio Web: https://covid19cubadata.github.io
Autores:
- MatCom: http://www.matcom.uh.cu
- Postdata.club: https://www.postdata.club
- Juventud Técnica: https://medium.com/juventud-técnica
Los datos se actualizan a partir de la información oficial del MINSAP informados por las autoridades al día siguiente.
Canal de Telegram: https://t.me/covid19cubadata
Grupo de Telegram: https://t.me/covid19cubadatachat
",
+ "updated": "2020-07-20T14:03:06+00:00",
+ "sale_count": 0,
+ "download_count": 354838,
+ "price": 0.0,
+ "rating": 4.066666666666666,
+ "sponsored": 0,
+ "with_db": false,
+ "reviews_star_1": 24,
+ "reviews_star_2": 5,
+ "reviews_star_3": 6,
+ "reviews_star_4": 17,
+ "reviews_star_5": 98,
+ "releases_count": 14,
+ "reviews_count": 150,
+ "categories": [
+ {
+ "id": 3,
+ "name": "Utilidades",
+ "icon": "utils",
+ "group": "Applications",
+ "icon_url": "https://archive.apklis.cu/category/Utilidades_b48JMjB.png"
+ },
+ {
+ "id": 50,
+ "name": "Internet",
+ "icon": "internet",
+ "group": "Applications",
+ "icon_url": "https://archive.apklis.cu/category/Internet_feq0fhU.png"
+ },
+ {
+ "id": 46,
+ "name": "Medicina",
+ "icon": "medicine",
+ "group": "Applications",
+ "icon_url": "https://archive.apklis.cu/category/Medicina.png"
+ },
+ {
+ "id": 44,
+ "name": "Mapas y navegación",
+ "icon": "maps",
+ "group": "Applications",
+ "icon_url": "https://archive.apklis.cu/category/MapasNavegaci%C3%B3n.png"
+ },
+ {
+ "id": 6,
+ "name": "Noticias y revistas",
+ "icon": "news_magazines",
+ "group": "Applications",
+ "icon_url": "https://archive.apklis.cu/category/NoticiasRevistas.png"
+ },
+ {
+ "id": 5,
+ "name": "Salud y bienestar",
+ "icon": "health",
+ "group": "Applications",
+ "icon_url": "https://archive.apklis.cu/category/SaludBienestar.png"
+ },
+ {
+ "id": 1,
+ "name": "Cuba",
+ "icon": "cubans",
+ "group": "Applications",
+ "icon_url": "https://archive.apklis.cu/category/Aplicaciones_y_juegos_cubanos.png"
+ }
+ ],
+ "size": 13842621,
+ "developer": {
+ "username": "leynier",
+ "first_name": "Leynier",
+ "last_name": "Gutiérrez González",
+ "fullname": "Leynier Gutiérrez González",
+ "avatar": "https://archive.apklis.cu/user/avatar/avatar_zF8cIFo.png",
+ "background": null,
+ "apps": 3,
+ "is_active": true,
+ "description": "leynier.github.io"
+ },
+ "last_release": {
+ "abi": [
+ {
+ "abi": "armeabi-v7a"
+ }
+ ],
+ "no_abi": false,
+ "version_name": "v1.0.0",
+ "package_name": "club.postdata.covid19cuba",
+ "app_name": "Covid19 Cuba Data",
+ "version_sdk_name": "Jelly Bean 4.1.x",
+ "version_target_sdk_name": "Pie 9.0",
+ "permissions": [
+ {
+ "icon": "",
+ "description": "",
+ "name": "Get tasks"
+ },
+ {
+ "icon": "",
+ "description": "",
+ "name": "Internet"
+ },
+ {
+ "icon": "",
+ "description": "",
+ "name": "Receive boot completed"
+ },
+ {
+ "icon": "",
+ "description": "",
+ "name": "Vibrate"
+ },
+ {
+ "icon": "",
+ "description": "",
+ "name": "Wake lock"
+ }
+ ],
+ "screenshots": [
+ {
+ "description": "",
+ "img": "https://archive.apklis.cu/application/screenshot/photo_2020-07-20_05-39-37.jpg"
+ },
+ {
+ "description": "",
+ "img": "https://archive.apklis.cu/application/screenshot/photo_2020-07-20_05-39-42.jpg"
+ },
+ {
+ "description": "",
+ "img": "https://archive.apklis.cu/application/screenshot/photo_2020-07-20_05-39-47.jpg"
+ },
+ {
+ "description": "",
+ "img": "https://archive.apklis.cu/application/screenshot/photo_2020-07-20_05-39-50.jpg"
+ },
+ {
+ "description": "",
+ "img": "https://archive.apklis.cu/application/screenshot/photo_2020-07-20_05-39-52.jpg"
+ },
+ {
+ "description": "",
+ "img": "https://archive.apklis.cu/application/screenshot/photo_2020-07-20_05-39-55.jpg"
+ },
+ {
+ "description": "",
+ "img": "https://archive.apklis.cu/application/screenshot/photo_2020-07-20_05-39-58.jpg"
+ },
+ {
+ "description": "",
+ "img": "https://archive.apklis.cu/application/screenshot/photo_2020-07-20_05-40-01.jpg"
+ }
+ ],
+ "changelog": "1. Reducción del tamaño de la aplicación a la mitad del tamaño de la versión anterior.
2. Nuevas imágenes y descripciones al carrusel inicial de bienvenida.
3. Separación de hombres y mujeres en la gráfica de Distribución por rangos etarios en la sección de gráficas General de Cuba.
4. Gráficas de casos sintomáticos/asintomáticos en la sección de gráficas General de Cuba.
5. Gráficas de la evolución de las personas en vigilancia en la sección de gráficas General de Cuba.
6. Gráficas de la evolución de las personas hospitalizadas en la sección de gráficas General de Cuba.
7. Sección de gráficos de casos Fallecidos en Cuba.
8. Más fuentes de noticias como Juventud Técnica, la Agencia Cubana de Noticias, Cubadebate, entre otras.
9. Fráfica de radar de comparación de varios parámetros de Cuba con otros países en la sección de Mundo.
10. Sección de boletines del Centro de Estudios Demográficos (CEDEM) de la Universidad de La Habana enfocados en la temática de la COVID-19.
11. Sección con las medidas de cada fase de la etapa de recuperación post Covid-19, así como la fase en la que se encuentran las provincias
12. Sección de descargas con las bases de datos utilizadas en diferentes formatos.
13. Sección con los protocolos de actuación, con alcance nacional, que contribuyen a la prevención, control y manejo de los casos relacionados con la enfermedad de la Covid-19.
14. Registro manual de las personas con que tuvo contacto (además de la fecha y el lugar) para mejorar y ayudar la labor de las autoridades satinarías en la lucha contra la pandemia.
15. Sección de Atención a la Población con los números telefónicos de cada provincia para la Covid-19.
16. Configuración de proxy para los usuarios que utilizan una red corporativa, estudiantil, etc. en la que se necesite configurar un proxy.
17. Configuración de las notificaciones por tipo de notificación y por horario del día.
",
+ "version_code": 14,
+ "published": "2020-07-20T14:03:06.180774Z",
+ "sha256": "ffbca10a07c2e0f922dc31d1470ec823df0b395fc0c79f3d4e06efd669288cf1",
+ "size": "13.20 MB",
+ "icon": "https://archive.apklis.cu/application/icon/club.postdata.covid19cuba-v14.png",
+ "public": true,
+ "beta": false,
+ "version_sdk": "Jelly Bean 4.1.x",
+ "version_target_sdk": "Pie 9.0",
+ "deleted": false
+ },
+ "announced": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/apklis_web_api/lib/apklis_api_result.dart b/packages/apklis_web_api/lib/apklis_api_result.dart
new file mode 100644
index 0000000..3495edf
--- /dev/null
+++ b/packages/apklis_web_api/lib/apklis_api_result.dart
@@ -0,0 +1,11 @@
+import 'package:apklis_web_api/models/models.dart';
+import 'package:freezed_annotation/freezed_annotation.dart';
+
+part 'apklis_api_result.freezed.dart';
+
+@freezed
+class ApklisApiResult with _$ApklisApiResult {
+ const factory ApklisApiResult.success(ApklisModel result) =
+ _SuccessApklisApiResult;
+ const factory ApklisApiResult.failure(String error) = _FailureApklisApiResult;
+}
diff --git a/packages/apklis_web_api/lib/apklis_api_result.freezed.dart b/packages/apklis_web_api/lib/apklis_api_result.freezed.dart
new file mode 100644
index 0000000..fb7ee00
--- /dev/null
+++ b/packages/apklis_web_api/lib/apklis_api_result.freezed.dart
@@ -0,0 +1,316 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+
+part of 'apklis_api_result.dart';
+
+// **************************************************************************
+// FreezedGenerator
+// **************************************************************************
+
+T _$identity(T value) => value;
+
+final _privateConstructorUsedError = UnsupportedError(
+ 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
+
+/// @nodoc
+class _$ApklisApiResultTearOff {
+ const _$ApklisApiResultTearOff();
+
+ _SuccessApklisApiResult success(ApklisModel result) {
+ return _SuccessApklisApiResult(
+ result,
+ );
+ }
+
+ _FailureApklisApiResult failure(String error) {
+ return _FailureApklisApiResult(
+ error,
+ );
+ }
+}
+
+/// @nodoc
+const $ApklisApiResult = _$ApklisApiResultTearOff();
+
+/// @nodoc
+mixin _$ApklisApiResult {
+ @optionalTypeArgs
+ TResult when({
+ required TResult Function(ApklisModel result) success,
+ required TResult Function(String error) failure,
+ }) =>
+ throw _privateConstructorUsedError;
+ @optionalTypeArgs
+ TResult maybeWhen({
+ TResult Function(ApklisModel result)? success,
+ TResult Function(String error)? failure,
+ required TResult orElse(),
+ }) =>
+ throw _privateConstructorUsedError;
+ @optionalTypeArgs
+ TResult map({
+ required TResult Function(_SuccessApklisApiResult value) success,
+ required TResult Function(_FailureApklisApiResult value) failure,
+ }) =>
+ throw _privateConstructorUsedError;
+ @optionalTypeArgs
+ TResult maybeMap({
+ TResult Function(_SuccessApklisApiResult value)? success,
+ TResult Function(_FailureApklisApiResult value)? failure,
+ required TResult orElse(),
+ }) =>
+ throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $ApklisApiResultCopyWith<$Res> {
+ factory $ApklisApiResultCopyWith(
+ ApklisApiResult value, $Res Function(ApklisApiResult) then) =
+ _$ApklisApiResultCopyWithImpl<$Res>;
+}
+
+/// @nodoc
+class _$ApklisApiResultCopyWithImpl<$Res>
+ implements $ApklisApiResultCopyWith<$Res> {
+ _$ApklisApiResultCopyWithImpl(this._value, this._then);
+
+ final ApklisApiResult _value;
+ // ignore: unused_field
+ final $Res Function(ApklisApiResult) _then;
+}
+
+/// @nodoc
+abstract class _$SuccessApklisApiResultCopyWith<$Res> {
+ factory _$SuccessApklisApiResultCopyWith(_SuccessApklisApiResult value,
+ $Res Function(_SuccessApklisApiResult) then) =
+ __$SuccessApklisApiResultCopyWithImpl<$Res>;
+ $Res call({ApklisModel result});
+}
+
+/// @nodoc
+class __$SuccessApklisApiResultCopyWithImpl<$Res>
+ extends _$ApklisApiResultCopyWithImpl<$Res>
+ implements _$SuccessApklisApiResultCopyWith<$Res> {
+ __$SuccessApklisApiResultCopyWithImpl(_SuccessApklisApiResult _value,
+ $Res Function(_SuccessApklisApiResult) _then)
+ : super(_value, (v) => _then(v as _SuccessApklisApiResult));
+
+ @override
+ _SuccessApklisApiResult get _value => super._value as _SuccessApklisApiResult;
+
+ @override
+ $Res call({
+ Object? result = freezed,
+ }) {
+ return _then(_SuccessApklisApiResult(
+ result == freezed
+ ? _value.result
+ : result // ignore: cast_nullable_to_non_nullable
+ as ApklisModel,
+ ));
+ }
+}
+
+/// @nodoc
+
+class _$_SuccessApklisApiResult implements _SuccessApklisApiResult {
+ const _$_SuccessApklisApiResult(this.result);
+
+ @override
+ final ApklisModel result;
+
+ @override
+ String toString() {
+ return 'ApklisApiResult.success(result: $result)';
+ }
+
+ @override
+ bool operator ==(dynamic other) {
+ return identical(this, other) ||
+ (other is _SuccessApklisApiResult &&
+ (identical(other.result, result) ||
+ const DeepCollectionEquality().equals(other.result, result)));
+ }
+
+ @override
+ int get hashCode =>
+ runtimeType.hashCode ^ const DeepCollectionEquality().hash(result);
+
+ @JsonKey(ignore: true)
+ @override
+ _$SuccessApklisApiResultCopyWith<_SuccessApklisApiResult> get copyWith =>
+ __$SuccessApklisApiResultCopyWithImpl<_SuccessApklisApiResult>(
+ this, _$identity);
+
+ @override
+ @optionalTypeArgs
+ TResult when({
+ required TResult Function(ApklisModel result) success,
+ required TResult Function(String error) failure,
+ }) {
+ return success(result);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeWhen({
+ TResult Function(ApklisModel result)? success,
+ TResult Function(String error)? failure,
+ required TResult orElse(),
+ }) {
+ if (success != null) {
+ return success(result);
+ }
+ return orElse();
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult map({
+ required TResult Function(_SuccessApklisApiResult value) success,
+ required TResult Function(_FailureApklisApiResult value) failure,
+ }) {
+ return success(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeMap({
+ TResult Function(_SuccessApklisApiResult value)? success,
+ TResult Function(_FailureApklisApiResult value)? failure,
+ required TResult orElse(),
+ }) {
+ if (success != null) {
+ return success(this);
+ }
+ return orElse();
+ }
+}
+
+abstract class _SuccessApklisApiResult implements ApklisApiResult {
+ const factory _SuccessApklisApiResult(ApklisModel result) =
+ _$_SuccessApklisApiResult;
+
+ ApklisModel get result => throw _privateConstructorUsedError;
+ @JsonKey(ignore: true)
+ _$SuccessApklisApiResultCopyWith<_SuccessApklisApiResult> get copyWith =>
+ throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class _$FailureApklisApiResultCopyWith<$Res> {
+ factory _$FailureApklisApiResultCopyWith(_FailureApklisApiResult value,
+ $Res Function(_FailureApklisApiResult) then) =
+ __$FailureApklisApiResultCopyWithImpl<$Res>;
+ $Res call({String error});
+}
+
+/// @nodoc
+class __$FailureApklisApiResultCopyWithImpl<$Res>
+ extends _$ApklisApiResultCopyWithImpl<$Res>
+ implements _$FailureApklisApiResultCopyWith<$Res> {
+ __$FailureApklisApiResultCopyWithImpl(_FailureApklisApiResult _value,
+ $Res Function(_FailureApklisApiResult) _then)
+ : super(_value, (v) => _then(v as _FailureApklisApiResult));
+
+ @override
+ _FailureApklisApiResult get _value => super._value as _FailureApklisApiResult;
+
+ @override
+ $Res call({
+ Object? error = freezed,
+ }) {
+ return _then(_FailureApklisApiResult(
+ error == freezed
+ ? _value.error
+ : error // ignore: cast_nullable_to_non_nullable
+ as String,
+ ));
+ }
+}
+
+/// @nodoc
+
+class _$_FailureApklisApiResult implements _FailureApklisApiResult {
+ const _$_FailureApklisApiResult(this.error);
+
+ @override
+ final String error;
+
+ @override
+ String toString() {
+ return 'ApklisApiResult.failure(error: $error)';
+ }
+
+ @override
+ bool operator ==(dynamic other) {
+ return identical(this, other) ||
+ (other is _FailureApklisApiResult &&
+ (identical(other.error, error) ||
+ const DeepCollectionEquality().equals(other.error, error)));
+ }
+
+ @override
+ int get hashCode =>
+ runtimeType.hashCode ^ const DeepCollectionEquality().hash(error);
+
+ @JsonKey(ignore: true)
+ @override
+ _$FailureApklisApiResultCopyWith<_FailureApklisApiResult> get copyWith =>
+ __$FailureApklisApiResultCopyWithImpl<_FailureApklisApiResult>(
+ this, _$identity);
+
+ @override
+ @optionalTypeArgs
+ TResult when({
+ required TResult Function(ApklisModel result) success,
+ required TResult Function(String error) failure,
+ }) {
+ return failure(error);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeWhen({
+ TResult Function(ApklisModel result)? success,
+ TResult Function(String error)? failure,
+ required TResult orElse(),
+ }) {
+ if (failure != null) {
+ return failure(error);
+ }
+ return orElse();
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult map({
+ required TResult Function(_SuccessApklisApiResult value) success,
+ required TResult Function(_FailureApklisApiResult value) failure,
+ }) {
+ return failure(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeMap({
+ TResult Function(_SuccessApklisApiResult value)? success,
+ TResult Function(_FailureApklisApiResult value)? failure,
+ required TResult orElse(),
+ }) {
+ if (failure != null) {
+ return failure(this);
+ }
+ return orElse();
+ }
+}
+
+abstract class _FailureApklisApiResult implements ApklisApiResult {
+ const factory _FailureApklisApiResult(String error) =
+ _$_FailureApklisApiResult;
+
+ String get error => throw _privateConstructorUsedError;
+ @JsonKey(ignore: true)
+ _$FailureApklisApiResultCopyWith<_FailureApklisApiResult> get copyWith =>
+ throw _privateConstructorUsedError;
+}
diff --git a/packages/apklis_web_api/lib/apklis_web_api.dart b/packages/apklis_web_api/lib/apklis_web_api.dart
new file mode 100644
index 0000000..24d3aae
--- /dev/null
+++ b/packages/apklis_web_api/lib/apklis_web_api.dart
@@ -0,0 +1,23 @@
+library apklis_web_api;
+
+import 'package:apklis_web_api/apklis_api_result.dart';
+
+abstract class ApklisWebApi {
+ static const API_URL = 'https://api.apklis.cu';
+
+ Future get(List apps) {
+ final uri = buildUri(apps);
+ return getByUri(uri);
+ }
+
+ static Uri buildUri(List apps) {
+ final uri = Uri.https(
+ 'api.apklis.cu',
+ 'v2/application',
+ {'package_name': apps},
+ );
+ return uri;
+ }
+
+ Future getByUri(Uri uri);
+}
diff --git a/packages/apklis_web_api/lib/models/apklis_abi_model.dart b/packages/apklis_web_api/lib/models/apklis_abi_model.dart
new file mode 100644
index 0000000..a1ee01a
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_abi_model.dart
@@ -0,0 +1,17 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'apklis_abi_model.g.dart';
+
+@JsonSerializable(explicitToJson: true)
+class ApklisAbiModel {
+ final String abi;
+
+ const ApklisAbiModel({
+ required this.abi,
+ });
+
+ factory ApklisAbiModel.fromJson(Map json) =>
+ _$ApklisAbiModelFromJson(json);
+
+ Map toJson() => _$ApklisAbiModelToJson(this);
+}
diff --git a/packages/apklis_web_api/lib/models/apklis_abi_model.g.dart b/packages/apklis_web_api/lib/models/apklis_abi_model.g.dart
new file mode 100644
index 0000000..879df06
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_abi_model.g.dart
@@ -0,0 +1,18 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'apklis_abi_model.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ApklisAbiModel _$ApklisAbiModelFromJson(Map json) {
+ return ApklisAbiModel(
+ abi: json['abi'] as String,
+ );
+}
+
+Map _$ApklisAbiModelToJson(ApklisAbiModel instance) =>
+ {
+ 'abi': instance.abi,
+ };
diff --git a/packages/apklis_web_api/lib/models/apklis_category_model.dart b/packages/apklis_web_api/lib/models/apklis_category_model.dart
new file mode 100644
index 0000000..3dc9a03
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_category_model.dart
@@ -0,0 +1,26 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'apklis_category_model.g.dart';
+
+@JsonSerializable(explicitToJson: true)
+class ApklisCategoryModel {
+ final int id;
+ final String name;
+ final String icon;
+ final String group;
+ @JsonKey(name: 'icon_url')
+ final String iconUrl;
+
+ const ApklisCategoryModel({
+ required this.id,
+ required this.name,
+ required this.icon,
+ required this.group,
+ required this.iconUrl,
+ });
+
+ factory ApklisCategoryModel.fromJson(Map json) =>
+ _$ApklisCategoryModelFromJson(json);
+
+ Map toJson() => _$ApklisCategoryModelToJson(this);
+}
diff --git a/packages/apklis_web_api/lib/models/apklis_category_model.g.dart b/packages/apklis_web_api/lib/models/apklis_category_model.g.dart
new file mode 100644
index 0000000..b6a4eed
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_category_model.g.dart
@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'apklis_category_model.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ApklisCategoryModel _$ApklisCategoryModelFromJson(Map json) {
+ return ApklisCategoryModel(
+ id: json['id'] as int,
+ name: json['name'] as String,
+ icon: json['icon'] as String,
+ group: json['group'] as String,
+ iconUrl: json['icon_url'] as String,
+ );
+}
+
+Map _$ApklisCategoryModelToJson(
+ ApklisCategoryModel instance) =>
+ {
+ 'id': instance.id,
+ 'name': instance.name,
+ 'icon': instance.icon,
+ 'group': instance.group,
+ 'icon_url': instance.iconUrl,
+ };
diff --git a/packages/apklis_web_api/lib/models/apklis_developer_model.dart b/packages/apklis_web_api/lib/models/apklis_developer_model.dart
new file mode 100644
index 0000000..60dac6c
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_developer_model.dart
@@ -0,0 +1,36 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'apklis_developer_model.g.dart';
+
+@JsonSerializable(explicitToJson: true)
+class ApklisDeveloperModel {
+ final String username;
+ @JsonKey(name: 'first_name')
+ final String firstName;
+ @JsonKey(name: 'last_name')
+ final String lastName;
+ final String fullname;
+ final String avatar;
+ final String? background;
+ final int apps;
+ @JsonKey(name: 'is_active')
+ final bool isActive;
+ final String description;
+
+ const ApklisDeveloperModel({
+ required this.username,
+ required this.firstName,
+ required this.lastName,
+ required this.fullname,
+ required this.avatar,
+ required this.background,
+ required this.apps,
+ required this.isActive,
+ required this.description,
+ });
+
+ factory ApklisDeveloperModel.fromJson(Map json) =>
+ _$ApklisDeveloperModelFromJson(json);
+
+ Map toJson() => _$ApklisDeveloperModelToJson(this);
+}
diff --git a/packages/apklis_web_api/lib/models/apklis_developer_model.g.dart b/packages/apklis_web_api/lib/models/apklis_developer_model.g.dart
new file mode 100644
index 0000000..d0affdb
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_developer_model.g.dart
@@ -0,0 +1,35 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'apklis_developer_model.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ApklisDeveloperModel _$ApklisDeveloperModelFromJson(Map json) {
+ return ApklisDeveloperModel(
+ username: json['username'] as String,
+ firstName: json['first_name'] as String,
+ lastName: json['last_name'] as String,
+ fullname: json['fullname'] as String,
+ avatar: json['avatar'] as String,
+ background: json['background'] as String?,
+ apps: json['apps'] as int,
+ isActive: json['is_active'] as bool,
+ description: json['description'] as String,
+ );
+}
+
+Map _$ApklisDeveloperModelToJson(
+ ApklisDeveloperModel instance) =>
+ {
+ 'username': instance.username,
+ 'first_name': instance.firstName,
+ 'last_name': instance.lastName,
+ 'fullname': instance.fullname,
+ 'avatar': instance.avatar,
+ 'background': instance.background,
+ 'apps': instance.apps,
+ 'is_active': instance.isActive,
+ 'description': instance.description,
+ };
diff --git a/packages/apklis_web_api/lib/models/apklis_item_model.dart b/packages/apklis_web_api/lib/models/apklis_item_model.dart
new file mode 100644
index 0000000..312bc45
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_item_model.dart
@@ -0,0 +1,82 @@
+import 'package:apklis_web_api/models/models.dart';
+import 'package:json_annotation/json_annotation.dart';
+
+part 'apklis_item_model.g.dart';
+
+@JsonSerializable(explicitToJson: true)
+class ApklisItemModel {
+ final String icon;
+ final String background;
+ @JsonKey(name: 'package_name')
+ final String packageName;
+ final String name;
+ @JsonKey(name: 'video_url')
+ final String videoUrl;
+ @JsonKey(name: 'video_img')
+ final String videoImg;
+ final String description;
+ final String updated;
+ @JsonKey(name: 'sale_count')
+ final int saleCount;
+ @JsonKey(name: 'download_count')
+ final int downloadCount;
+ final double price;
+ final double rating;
+ final int sponsored;
+ @JsonKey(name: 'with_db')
+ final bool withDb;
+ @JsonKey(name: 'reviews_star_1')
+ final int reviewsStar1;
+ @JsonKey(name: 'reviews_star_2')
+ final int reviewsStar2;
+ @JsonKey(name: 'reviews_star_3')
+ final int reviewsStar3;
+ @JsonKey(name: 'reviews_star_4')
+ final int reviewsStar4;
+ @JsonKey(name: 'reviews_star_5')
+ final int reviewsStar5;
+ @JsonKey(name: 'releases_count')
+ final int releasesCount;
+ @JsonKey(name: 'reviews_count')
+ final int reviewsCount;
+ final List categories;
+ final int size;
+ final ApklisDeveloperModel developer;
+ @JsonKey(name: 'last_release')
+ final ApklisReleaseModel lastRelease;
+ final bool announced;
+
+ const ApklisItemModel({
+ required this.icon,
+ required this.background,
+ required this.packageName,
+ required this.name,
+ required this.videoUrl,
+ required this.videoImg,
+ required this.description,
+ required this.updated,
+ required this.saleCount,
+ required this.downloadCount,
+ required this.price,
+ required this.rating,
+ required this.sponsored,
+ required this.withDb,
+ required this.reviewsStar1,
+ required this.reviewsStar2,
+ required this.reviewsStar3,
+ required this.reviewsStar4,
+ required this.reviewsStar5,
+ required this.releasesCount,
+ required this.reviewsCount,
+ required this.categories,
+ required this.size,
+ required this.developer,
+ required this.lastRelease,
+ required this.announced,
+ });
+
+ factory ApklisItemModel.fromJson(Map json) =>
+ _$ApklisItemModelFromJson(json);
+
+ Map toJson() => _$ApklisItemModelToJson(this);
+}
diff --git a/packages/apklis_web_api/lib/models/apklis_item_model.g.dart b/packages/apklis_web_api/lib/models/apklis_item_model.g.dart
new file mode 100644
index 0000000..e249dbe
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_item_model.g.dart
@@ -0,0 +1,72 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'apklis_item_model.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ApklisItemModel _$ApklisItemModelFromJson(Map json) {
+ return ApklisItemModel(
+ icon: json['icon'] as String,
+ background: json['background'] as String,
+ packageName: json['package_name'] as String,
+ name: json['name'] as String,
+ videoUrl: json['video_url'] as String,
+ videoImg: json['video_img'] as String,
+ description: json['description'] as String,
+ updated: json['updated'] as String,
+ saleCount: json['sale_count'] as int,
+ downloadCount: json['download_count'] as int,
+ price: (json['price'] as num).toDouble(),
+ rating: (json['rating'] as num).toDouble(),
+ sponsored: json['sponsored'] as int,
+ withDb: json['with_db'] as bool,
+ reviewsStar1: json['reviews_star_1'] as int,
+ reviewsStar2: json['reviews_star_2'] as int,
+ reviewsStar3: json['reviews_star_3'] as int,
+ reviewsStar4: json['reviews_star_4'] as int,
+ reviewsStar5: json['reviews_star_5'] as int,
+ releasesCount: json['releases_count'] as int,
+ reviewsCount: json['reviews_count'] as int,
+ categories: (json['categories'] as List)
+ .map((e) => ApklisCategoryModel.fromJson(e as Map))
+ .toList(),
+ size: json['size'] as int,
+ developer: ApklisDeveloperModel.fromJson(
+ json['developer'] as Map),
+ lastRelease: ApklisReleaseModel.fromJson(
+ json['last_release'] as Map),
+ announced: json['announced'] as bool,
+ );
+}
+
+Map _$ApklisItemModelToJson(ApklisItemModel instance) =>
+ {
+ 'icon': instance.icon,
+ 'background': instance.background,
+ 'package_name': instance.packageName,
+ 'name': instance.name,
+ 'video_url': instance.videoUrl,
+ 'video_img': instance.videoImg,
+ 'description': instance.description,
+ 'updated': instance.updated,
+ 'sale_count': instance.saleCount,
+ 'download_count': instance.downloadCount,
+ 'price': instance.price,
+ 'rating': instance.rating,
+ 'sponsored': instance.sponsored,
+ 'with_db': instance.withDb,
+ 'reviews_star_1': instance.reviewsStar1,
+ 'reviews_star_2': instance.reviewsStar2,
+ 'reviews_star_3': instance.reviewsStar3,
+ 'reviews_star_4': instance.reviewsStar4,
+ 'reviews_star_5': instance.reviewsStar5,
+ 'releases_count': instance.releasesCount,
+ 'reviews_count': instance.reviewsCount,
+ 'categories': instance.categories.map((e) => e.toJson()).toList(),
+ 'size': instance.size,
+ 'developer': instance.developer.toJson(),
+ 'last_release': instance.lastRelease.toJson(),
+ 'announced': instance.announced,
+ };
diff --git a/packages/apklis_web_api/lib/models/apklis_model.dart b/packages/apklis_web_api/lib/models/apklis_model.dart
new file mode 100644
index 0000000..9cba4f9
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_model.dart
@@ -0,0 +1,24 @@
+import 'package:apklis_web_api/models/models.dart';
+import 'package:json_annotation/json_annotation.dart';
+
+part 'apklis_model.g.dart';
+
+@JsonSerializable(explicitToJson: true)
+class ApklisModel {
+ final int count;
+ final String? next;
+ final String? previous;
+ final List results;
+
+ const ApklisModel({
+ required this.count,
+ required this.next,
+ required this.previous,
+ required this.results,
+ });
+
+ factory ApklisModel.fromJson(Map json) =>
+ _$ApklisModelFromJson(json);
+
+ Map toJson() => _$ApklisModelToJson(this);
+}
diff --git a/packages/apklis_web_api/lib/models/apklis_model.g.dart b/packages/apklis_web_api/lib/models/apklis_model.g.dart
new file mode 100644
index 0000000..7e874f4
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_model.g.dart
@@ -0,0 +1,26 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'apklis_model.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ApklisModel _$ApklisModelFromJson(Map json) {
+ return ApklisModel(
+ count: json['count'] as int,
+ next: json['next'] as String?,
+ previous: json['previous'] as String?,
+ results: (json['results'] as List)
+ .map((e) => ApklisItemModel.fromJson(e as Map))
+ .toList(),
+ );
+}
+
+Map _$ApklisModelToJson(ApklisModel instance) =>
+ {
+ 'count': instance.count,
+ 'next': instance.next,
+ 'previous': instance.previous,
+ 'results': instance.results.map((e) => e.toJson()).toList(),
+ };
diff --git a/packages/apklis_web_api/lib/models/apklis_permission_model.dart b/packages/apklis_web_api/lib/models/apklis_permission_model.dart
new file mode 100644
index 0000000..f1e29dc
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_permission_model.dart
@@ -0,0 +1,21 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'apklis_permission_model.g.dart';
+
+@JsonSerializable(explicitToJson: true)
+class ApklisPermissionModel {
+ final String icon;
+ final String description;
+ final String name;
+
+ const ApklisPermissionModel({
+ required this.icon,
+ required this.description,
+ required this.name,
+ });
+
+ factory ApklisPermissionModel.fromJson(Map json) =>
+ _$ApklisPermissionModelFromJson(json);
+
+ Map toJson() => _$ApklisPermissionModelToJson(this);
+}
diff --git a/packages/apklis_web_api/lib/models/apklis_permission_model.g.dart b/packages/apklis_web_api/lib/models/apklis_permission_model.g.dart
new file mode 100644
index 0000000..624ab02
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_permission_model.g.dart
@@ -0,0 +1,24 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'apklis_permission_model.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ApklisPermissionModel _$ApklisPermissionModelFromJson(
+ Map json) {
+ return ApklisPermissionModel(
+ icon: json['icon'] as String,
+ description: json['description'] as String,
+ name: json['name'] as String,
+ );
+}
+
+Map _$ApklisPermissionModelToJson(
+ ApklisPermissionModel instance) =>
+ {
+ 'icon': instance.icon,
+ 'description': instance.description,
+ 'name': instance.name,
+ };
diff --git a/packages/apklis_web_api/lib/models/apklis_release_model.dart b/packages/apklis_web_api/lib/models/apklis_release_model.dart
new file mode 100644
index 0000000..31838cb
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_release_model.dart
@@ -0,0 +1,65 @@
+import 'package:apklis_web_api/models/models.dart';
+import 'package:json_annotation/json_annotation.dart';
+
+part 'apklis_release_model.g.dart';
+
+@JsonSerializable(explicitToJson: true)
+class ApklisReleaseModel {
+ final List abi;
+ @JsonKey(name: 'no_abi')
+ final bool noAbi;
+ @JsonKey(name: 'version_name')
+ final String versionName;
+ @JsonKey(name: 'package_name')
+ final String packageName;
+ @JsonKey(name: 'app_name')
+ final String appName;
+ @JsonKey(name: 'version_sdk_name')
+ final String versionSdkName;
+ @JsonKey(name: 'version_target_sdk_name')
+ final String versionTargetSdkName;
+ final List permissions;
+ final List screenshots;
+ final String changelog;
+ @JsonKey(name: 'version_code')
+ final int versionCode;
+ final String published;
+ final String sha256;
+ final String size;
+ final String icon;
+ final bool public;
+ final bool beta;
+ @JsonKey(name: 'version_sdk')
+ final String versionSdk;
+ @JsonKey(name: 'version_target_sdk')
+ final String versionTargetSdk;
+ final bool deleted;
+
+ const ApklisReleaseModel({
+ required this.abi,
+ required this.noAbi,
+ required this.versionName,
+ required this.packageName,
+ required this.appName,
+ required this.versionSdkName,
+ required this.versionTargetSdkName,
+ required this.permissions,
+ required this.screenshots,
+ required this.changelog,
+ required this.versionCode,
+ required this.published,
+ required this.sha256,
+ required this.size,
+ required this.icon,
+ required this.public,
+ required this.beta,
+ required this.versionSdk,
+ required this.versionTargetSdk,
+ required this.deleted,
+ });
+
+ factory ApklisReleaseModel.fromJson(Map json) =>
+ _$ApklisReleaseModelFromJson(json);
+
+ Map toJson() => _$ApklisReleaseModelToJson(this);
+}
diff --git a/packages/apklis_web_api/lib/models/apklis_release_model.g.dart b/packages/apklis_web_api/lib/models/apklis_release_model.g.dart
new file mode 100644
index 0000000..4c00e44
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_release_model.g.dart
@@ -0,0 +1,62 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'apklis_release_model.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ApklisReleaseModel _$ApklisReleaseModelFromJson(Map json) {
+ return ApklisReleaseModel(
+ abi: (json['abi'] as List)
+ .map((e) => ApklisAbiModel.fromJson(e as Map))
+ .toList(),
+ noAbi: json['no_abi'] as bool,
+ versionName: json['version_name'] as String,
+ packageName: json['package_name'] as String,
+ appName: json['app_name'] as String,
+ versionSdkName: json['version_sdk_name'] as String,
+ versionTargetSdkName: json['version_target_sdk_name'] as String,
+ permissions: (json['permissions'] as List)
+ .map((e) => ApklisPermissionModel.fromJson(e as Map))
+ .toList(),
+ screenshots: (json['screenshots'] as List)
+ .map((e) => ApklisScreenshotModel.fromJson(e as Map))
+ .toList(),
+ changelog: json['changelog'] as String,
+ versionCode: json['version_code'] as int,
+ published: json['published'] as String,
+ sha256: json['sha256'] as String,
+ size: json['size'] as String,
+ icon: json['icon'] as String,
+ public: json['public'] as bool,
+ beta: json['beta'] as bool,
+ versionSdk: json['version_sdk'] as String,
+ versionTargetSdk: json['version_target_sdk'] as String,
+ deleted: json['deleted'] as bool,
+ );
+}
+
+Map _$ApklisReleaseModelToJson(ApklisReleaseModel instance) =>
+ {
+ 'abi': instance.abi.map((e) => e.toJson()).toList(),
+ 'no_abi': instance.noAbi,
+ 'version_name': instance.versionName,
+ 'package_name': instance.packageName,
+ 'app_name': instance.appName,
+ 'version_sdk_name': instance.versionSdkName,
+ 'version_target_sdk_name': instance.versionTargetSdkName,
+ 'permissions': instance.permissions.map((e) => e.toJson()).toList(),
+ 'screenshots': instance.screenshots.map((e) => e.toJson()).toList(),
+ 'changelog': instance.changelog,
+ 'version_code': instance.versionCode,
+ 'published': instance.published,
+ 'sha256': instance.sha256,
+ 'size': instance.size,
+ 'icon': instance.icon,
+ 'public': instance.public,
+ 'beta': instance.beta,
+ 'version_sdk': instance.versionSdk,
+ 'version_target_sdk': instance.versionTargetSdk,
+ 'deleted': instance.deleted,
+ };
diff --git a/packages/apklis_web_api/lib/models/apklis_screenshot_model.dart b/packages/apklis_web_api/lib/models/apklis_screenshot_model.dart
new file mode 100644
index 0000000..31f8582
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_screenshot_model.dart
@@ -0,0 +1,20 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'apklis_screenshot_model.g.dart';
+
+@JsonSerializable(explicitToJson: true)
+class ApklisScreenshotModel {
+ final String description;
+ @JsonKey(name: 'img')
+ final String image;
+
+ const ApklisScreenshotModel({
+ required this.description,
+ required this.image,
+ });
+
+ factory ApklisScreenshotModel.fromJson(Map json) =>
+ _$ApklisScreenshotModelFromJson(json);
+
+ Map toJson() => _$ApklisScreenshotModelToJson(this);
+}
diff --git a/packages/apklis_web_api/lib/models/apklis_screenshot_model.g.dart b/packages/apklis_web_api/lib/models/apklis_screenshot_model.g.dart
new file mode 100644
index 0000000..bac2000
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/apklis_screenshot_model.g.dart
@@ -0,0 +1,22 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'apklis_screenshot_model.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ApklisScreenshotModel _$ApklisScreenshotModelFromJson(
+ Map json) {
+ return ApklisScreenshotModel(
+ description: json['description'] as String,
+ image: json['img'] as String,
+ );
+}
+
+Map _$ApklisScreenshotModelToJson(
+ ApklisScreenshotModel instance) =>
+ {
+ 'description': instance.description,
+ 'img': instance.image,
+ };
diff --git a/packages/apklis_web_api/lib/models/models.dart b/packages/apklis_web_api/lib/models/models.dart
new file mode 100644
index 0000000..a7df174
--- /dev/null
+++ b/packages/apklis_web_api/lib/models/models.dart
@@ -0,0 +1,8 @@
+export 'apklis_abi_model.dart';
+export 'apklis_category_model.dart';
+export 'apklis_developer_model.dart';
+export 'apklis_item_model.dart';
+export 'apklis_model.dart';
+export 'apklis_permission_model.dart';
+export 'apklis_release_model.dart';
+export 'apklis_screenshot_model.dart';
diff --git a/packages/apklis_web_api/pubspec.yaml b/packages/apklis_web_api/pubspec.yaml
new file mode 100644
index 0000000..1d63a08
--- /dev/null
+++ b/packages/apklis_web_api/pubspec.yaml
@@ -0,0 +1,22 @@
+name: apklis_web_api
+description: Interfaz para la posterior implementación de un paquete en Dart
+ para interactuar con la API de Apklis. El resto de paquetes del ecosistema de
+ Apklis Dart/Flutter utilizará este paquete como un contrato en el que mediante
+ inyección de dependencias se inyectarian las implementaciones concretas.
+version: 0.0.0
+homepage: https://github.com/fluttercuba/apklis-dart-flutter
+
+environment:
+ sdk: ">=2.12.0 <3.0.0"
+
+dependencies:
+ freezed_annotation: ^0.14.2
+ json_annotation: ^4.0.1
+
+dev_dependencies:
+ build_runner: ^2.0.4
+ freezed: ^0.14.2
+ json_serializable: ^4.1.3
+ lint: ^1.5.3
+ mocktail: ^0.1.4
+ test: ^1.17.5
diff --git a/packages/apklis_web_api/test/apklis_web_api_test.dart b/packages/apklis_web_api/test/apklis_web_api_test.dart
new file mode 100644
index 0000000..d049752
--- /dev/null
+++ b/packages/apklis_web_api/test/apklis_web_api_test.dart
@@ -0,0 +1,41 @@
+import 'dart:convert';
+
+import 'package:apklis_web_api/apklis_api_result.dart';
+import 'package:apklis_web_api/apklis_web_api.dart';
+import 'package:apklis_web_api/models/apklis_model.dart';
+import 'package:mocktail/mocktail.dart';
+import 'package:test/test.dart';
+
+import 'utils.dart';
+
+class MockApklisWebApi extends Mock implements ApklisWebApi {}
+
+void main() {
+ test('check build uri', () {
+ final apps = ['com.example.app1', 'com.example.app2'];
+ final queryString = apps.map((e) => 'package_name=$e').join('&');
+ final url = '${ApklisWebApi.API_URL}/v2/application?$queryString';
+ final uri = ApklisWebApi.buildUri(apps);
+ expect(uri.toString(), url);
+ });
+
+ test('check parser', () async {
+ final api = MockApklisWebApi();
+ final file = await getProjectFile('assets/response_example.json');
+ final text = await file.readAsString();
+ expect(text, isNotEmpty);
+ final resp = jsonDecode(text) as Map;
+ when(() => api.get(['club.postdata.covid19cuba'])).thenAnswer(
+ (_) => Future.value(ApklisApiResult.success(ApklisModel.fromJson(resp))),
+ );
+ final model = await api.get(['club.postdata.covid19cuba']);
+ model.when(
+ success: (result) {
+ expect(result.results.isNotEmpty, true);
+ },
+ failure: (error) {
+ throw Exception('Result should be success.');
+ },
+ );
+ });
+}
diff --git a/packages/apklis_web_api/test/utils.dart b/packages/apklis_web_api/test/utils.dart
new file mode 100644
index 0000000..6751344
--- /dev/null
+++ b/packages/apklis_web_api/test/utils.dart
@@ -0,0 +1,11 @@
+import 'dart:io';
+
+/// Get a stable path to a test resource by scanning up to the project root.
+Future getProjectFile(String path) async {
+ var dir = Directory.current;
+ while (
+ !await dir.list().any((entity) => entity.path.endsWith('pubspec.yaml'))) {
+ dir = dir.parent;
+ }
+ return File('${dir.path}/$path');
+}