From 34e139ee010130df6d425f37865cff58cd441a0d Mon Sep 17 00:00:00 2001 From: pangz Date: Sat, 26 Aug 2023 01:25:46 +0900 Subject: [PATCH] added partial support for pro endpoints - added coingecko banner - Added support for the following coin PRO endpoints - getNewList - getTopGainersAndLosers - Exported exposed classes - Removed unnecessary unit test imports and replaced by the actual library --- CHANGELOG.md | 7 + README.md | 14 + lib/coingecko_client.dart | 41 ++- .../asset_platforms_endpoint.dart | 4 +- .../asset_platforms_filter.dart | 0 lib/src/domain/base_endpoint.dart | 9 +- .../categories/categories_endpoint.dart | 4 +- .../coin_categories_data_ordering.dart | 0 lib/src/domain/coins/coins_endpoint.dart | 55 +++- .../{models => enums}/coin_data_ordering.dart | 0 lib/src/domain/coins/enums/coin_duration.dart | 26 ++ .../{models => enums}/coin_price_change.dart | 0 lib/src/domain/coins/enums/coin_ranking.dart | 17 ++ .../domain/coins/models/coin_basic_info.dart | 8 +- .../coins/models/coin_ranking_info.dart | 69 +++++ .../coins/models/coin_ranking_result.dart | 25 ++ .../domain/companies/companies_endpoint.dart | 2 +- .../domain/contract/contract_endpoint.dart | 2 +- .../derivatives/derivatives_endpoint.dart | 6 +- .../derivatives_exchange_ordering.dart | 0 .../derivatives_tickers.dart | 0 .../exchange_rates_endpoint.dart | 2 +- .../exchange_data_ordering.dart | 0 .../domain/exchanges/exchanges_endpoint.dart | 4 +- lib/src/domain/global/global_endpoint.dart | 2 +- lib/src/domain/indexes/indexes_endpoint.dart | 2 +- .../{models => enums}/nfts_data_ordering.dart | 0 lib/src/domain/nfts/nfts_endpoint.dart | 4 +- lib/src/domain/ping/ping_endpoint.dart | 2 +- lib/src/domain/search/search_endpoint.dart | 2 +- lib/src/domain/simple/simple_endpoint.dart | 6 +- .../domain/trending/trending_endpoint.dart | 2 +- .../models/exceptions/request_exception.dart | 15 + pubspec.yaml | 2 +- run_test.sh | 6 +- test/coingecko_client_integration_test.dart | 54 ++-- test/coingecko_real_request_test.dart | 12 +- .../asset_platforms_endpoint_test.dart | 5 +- .../categories/categories_endpoint_test.dart | 6 +- test/domain/coins/coins_endpoint_test.dart | 264 +++++++++++++++++- test/domain/coins/mock/coins_mock_data.dart | 122 ++++++++ .../companies/companies_endpoint_test.dart | 4 +- .../contract/contract_endpoint_test.dart | 7 +- .../derivatives_endpoint_test.dart | 6 +- .../exchange_rates_endpoint_test.dart | 4 +- .../exchanges/exchanges_endpoint_test.dart | 6 +- test/domain/global/global_endpoint_test.dart | 4 +- .../domain/indexes/indexes_endpoint_test.dart | 4 +- test/domain/nfts/nfts_endpoint_test.dart | 6 +- test/domain/ping/ping_endpoint_test.dart | 4 +- test/domain/search/search_endpoint_test.dart | 4 +- test/domain/simple/simple_endpoint_test.dart | 5 +- .../trending/trending_endpoint_test.dart | 4 +- 53 files changed, 708 insertions(+), 151 deletions(-) rename lib/src/domain/asset_platforms/{models => enums}/asset_platforms_filter.dart (100%) rename lib/src/domain/categories/{models => enums}/coin_categories_data_ordering.dart (100%) rename lib/src/domain/coins/{models => enums}/coin_data_ordering.dart (100%) create mode 100644 lib/src/domain/coins/enums/coin_duration.dart rename lib/src/domain/coins/{models => enums}/coin_price_change.dart (100%) create mode 100644 lib/src/domain/coins/enums/coin_ranking.dart create mode 100644 lib/src/domain/coins/models/coin_ranking_info.dart create mode 100644 lib/src/domain/coins/models/coin_ranking_result.dart rename lib/src/domain/derivatives/{models => enums}/derivatives_exchange_ordering.dart (100%) rename lib/src/domain/derivatives/{models => enums}/derivatives_tickers.dart (100%) rename lib/src/domain/exchanges/{models => enums}/exchange_data_ordering.dart (100%) rename lib/src/domain/nfts/{models => enums}/nfts_data_ordering.dart (100%) create mode 100644 lib/src/models/exceptions/request_exception.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index b6810f9..ffbbdbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.2.0 +2023/08/26 JST +- Added support for the following coin PRO endpoints + - getNewList + - getTopGainersAndLosers +- Exported exposed classes +- Removed unnecessary unit test imports and replaced by the actual library import ## 1.1.1 2023/07/14 JST - Update http library to version 1.1.0 diff --git a/README.md b/README.md index 46405dd..c15e0a3 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,20 @@ client.coins.getOhlcList( ); ``` +## **[ 💰PRO Endpoints ]** +### 📤 */coins/list/new* +```dart +client.coins.getNewList(); +``` +### 📤 */coins/top_gainers_losers* +```dart +client.coins.getTopGainersAndLosers( + vsCurrency: Currencies.php, + duration: CoinDuration.in14Days, + topCoins: CoinRanking.top300 +); +``` + ___
diff --git a/lib/coingecko_client.dart b/lib/coingecko_client.dart index 4a902c5..fa5d906 100644 --- a/lib/coingecko_client.dart +++ b/lib/coingecko_client.dart @@ -4,47 +4,68 @@ library coingecko_client; export 'src/coingecko_client_base.dart'; +export 'src/domain/base_endpoint.dart'; +export 'src/domain/asset_platforms/asset_platforms_endpoint.dart'; +export 'src/domain/categories/categories_endpoint.dart'; +export 'src/domain/coins/coins_endpoint.dart'; +export 'src/domain/companies/companies_endpoint.dart'; +export 'src/domain/contract/contract_endpoint.dart'; +export 'src/domain/derivatives/derivatives_endpoint.dart'; +export 'src/domain/exchange_rates/exchange_rates_endpoint.dart'; +export 'src/domain/exchanges/exchanges_endpoint.dart'; +export 'src/domain/global/global_endpoint.dart'; +export 'src/domain/indexes/indexes_endpoint.dart'; +export 'src/domain/nfts/nfts_endpoint.dart'; +export 'src/domain/ping/ping_endpoint.dart'; +export 'src/domain/search/search_endpoint.dart'; +export 'src/domain/simple/simple_endpoint.dart'; +export 'src/domain/trending/trending_endpoint.dart'; export 'src/domain/asset_platforms/models/asset_platform.dart'; -export 'src/domain/asset_platforms/models/asset_platforms_filter.dart'; -export 'src/domain/categories/models/coin_categories_data_ordering.dart'; +export 'src/domain/asset_platforms/enums/asset_platforms_filter.dart'; +export 'src/domain/categories/enums/coin_categories_data_ordering.dart'; export 'src/domain/categories/models/coin_category_basic_info.dart'; export 'src/domain/categories/models/coin_category_info.dart'; -export 'src/domain/coins/models/coin_basic_info.dart'; -export 'src/domain/coins/models/coin_data_ordering.dart'; +export 'src/domain/coins/models/coin_ranking_info.dart'; +export 'src/domain/coins/models/coin_ranking_result.dart'; export 'src/domain/coins/models/coin_info.dart'; export 'src/domain/coins/models/coin_links.dart'; export 'src/domain/coins/models/coin_market.dart'; export 'src/domain/coins/models/coin_market_history.dart'; export 'src/domain/coins/models/coin_ohlc.dart'; -export 'src/domain/coins/models/coin_price_change.dart'; export 'src/domain/coins/models/coin_tickers.dart'; export 'src/domain/coins/models/market_data.dart'; export 'src/domain/coins/models/roi.dart'; export 'src/domain/coins/models/ticker_info.dart'; +export 'src/domain/coins/models/coin_basic_info.dart'; +export 'src/domain/coins/enums/coin_data_ordering.dart'; +export 'src/domain/coins/enums/coin_duration.dart'; +export 'src/domain/coins/enums/coin_price_change.dart'; +export 'src/domain/coins/enums/coin_ranking.dart'; export 'src/domain/companies/models/company_info.dart'; export 'src/domain/companies/models/company_list.dart'; export 'src/domain/contract/models/contract_info.dart'; export 'src/domain/contract/models/contract_market_history.dart'; export 'src/domain/derivatives/models/derivatives.dart'; export 'src/domain/derivatives/models/derivatives_exchange.dart'; -export 'src/domain/derivatives/models/derivatives_exchange_ordering.dart'; -export 'src/domain/derivatives/models/derivatives_tickers.dart'; export 'src/domain/derivatives/models/derivatives_ticker_info.dart'; +export 'src/domain/derivatives/enums/derivatives_exchange_ordering.dart'; +export 'src/domain/derivatives/enums/derivatives_tickers.dart'; export 'src/domain/exchanges/models/exchange_basic_info.dart'; -export 'src/domain/exchanges/models/exchange_data_ordering.dart'; export 'src/domain/exchanges/models/exchange_info.dart'; export 'src/domain/exchanges/models/exchange_status.dart'; export 'src/domain/exchanges/models/exchange_volume_chart.dart'; +export 'src/domain/exchanges/enums/exchange_data_ordering.dart'; export 'src/domain/exchange_rates/models/exchange_rate.dart'; export 'src/domain/global/models/global_crypto_info.dart'; export 'src/domain/global/models/global_defi_info.dart'; export 'src/domain/indexes/models/market_index.dart'; -export 'src/domain/nfts/models/nfts_data_ordering.dart'; export 'src/domain/nfts/models/nft_basic_info.dart'; export 'src/domain/nfts/models/nft_info.dart'; -export 'src/models/base_model.dart'; +export 'src/domain/nfts/enums/nfts_data_ordering.dart'; +export 'src/models/image.dart'; export 'src/models/currencies.dart'; export 'src/models/data_range.dart'; export 'src/models/historical_data.dart'; export 'src/models/exceptions/data_parsing_exception.dart'; export 'src/models/exceptions/network_request_exception.dart'; +export 'src/models/base_model.dart'; diff --git a/lib/src/domain/asset_platforms/asset_platforms_endpoint.dart b/lib/src/domain/asset_platforms/asset_platforms_endpoint.dart index 6f0f4ed..361c66d 100644 --- a/lib/src/domain/asset_platforms/asset_platforms_endpoint.dart +++ b/lib/src/domain/asset_platforms/asset_platforms_endpoint.dart @@ -1,6 +1,6 @@ import 'package:coingecko_client/src/domain/asset_platforms/models/asset_platform.dart'; import 'package:coingecko_client/src/domain/base_endpoint.dart'; -import 'package:coingecko_client/src/domain/asset_platforms/models/asset_platforms_filter.dart'; +import 'package:coingecko_client/src/domain/asset_platforms/enums/asset_platforms_filter.dart'; import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; import 'package:coingecko_client/src/services/http_request_service.dart'; @@ -11,7 +11,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; class AssetPlatformsEndpoint extends BaseEndpoint { AssetPlatformsEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// List all asset platforms (Blockchain networks) ///
Endpoint : /asset_platforms diff --git a/lib/src/domain/asset_platforms/models/asset_platforms_filter.dart b/lib/src/domain/asset_platforms/enums/asset_platforms_filter.dart similarity index 100% rename from lib/src/domain/asset_platforms/models/asset_platforms_filter.dart rename to lib/src/domain/asset_platforms/enums/asset_platforms_filter.dart diff --git a/lib/src/domain/base_endpoint.dart b/lib/src/domain/base_endpoint.dart index cf3547f..dde9754 100644 --- a/lib/src/domain/base_endpoint.dart +++ b/lib/src/domain/base_endpoint.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; +import 'package:coingecko_client/src/models/exceptions/request_exception.dart'; import 'package:coingecko_client/src/services/http_request_service.dart'; /// Main class that provides utility methods in preparing and sending the
@@ -17,7 +18,7 @@ class BaseEndpoint { /// Coingecko key name. This is embedded either in the url query /// of the http request header. This will contain the API key /// provided to the pro user when sent to the service. - static final apiKeyQueryParam = "x_cg_pro_api_key"; + static final apiKeyQueryParam = "x-cg-pro-api-key"; /// Current API version supported static final version = "/api/v3"; @@ -28,8 +29,7 @@ class BaseEndpoint { String get endpointPath => _endpointPath; HttpRequestServiceInterface httpRequestService; String? _apiKey; - BaseEndpoint(this.httpRequestService, Map map, - {String? apiKey}) { + BaseEndpoint(this.httpRequestService, {String? apiKey}) { _apiKey = apiKey; } @@ -51,6 +51,9 @@ class BaseEndpoint { /// ``` Future sendPro(String path) { try { + if (_apiKey?.isEmpty ?? true) { + throw RequestException.apiKeyNotFound(); + } final headers = Map.fromEntries( [MapEntry(apiKeyQueryParam, _apiKey ?? '')]); return _send(path, apiProHost, headers: headers); diff --git a/lib/src/domain/categories/categories_endpoint.dart b/lib/src/domain/categories/categories_endpoint.dart index 0291895..ab35e3f 100644 --- a/lib/src/domain/categories/categories_endpoint.dart +++ b/lib/src/domain/categories/categories_endpoint.dart @@ -1,5 +1,5 @@ import 'package:coingecko_client/src/domain/base_endpoint.dart'; -import 'package:coingecko_client/src/domain/categories/models/coin_categories_data_ordering.dart'; +import 'package:coingecko_client/src/domain/categories/enums/coin_categories_data_ordering.dart'; import 'package:coingecko_client/src/domain/categories/models/coin_category_basic_info.dart'; import 'package:coingecko_client/src/domain/categories/models/coin_category_info.dart'; import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; @@ -11,7 +11,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; class CategoriesEndpoint extends BaseEndpoint { CategoriesEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// List all categories ///
Endpoint : /coins/categories/list diff --git a/lib/src/domain/categories/models/coin_categories_data_ordering.dart b/lib/src/domain/categories/enums/coin_categories_data_ordering.dart similarity index 100% rename from lib/src/domain/categories/models/coin_categories_data_ordering.dart rename to lib/src/domain/categories/enums/coin_categories_data_ordering.dart diff --git a/lib/src/domain/coins/coins_endpoint.dart b/lib/src/domain/coins/coins_endpoint.dart index 58377a0..ca48897 100644 --- a/lib/src/domain/coins/coins_endpoint.dart +++ b/lib/src/domain/coins/coins_endpoint.dart @@ -1,12 +1,15 @@ +import 'package:coingecko_client/src/domain/base_endpoint.dart'; import 'package:coingecko_client/src/domain/coins/models/coin_basic_info.dart'; import 'package:coingecko_client/src/domain/coins/models/coin_info.dart'; import 'package:coingecko_client/src/domain/coins/models/coin_market.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_price_change.dart'; -import 'package:coingecko_client/src/domain/base_endpoint.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_data_ordering.dart'; +import 'package:coingecko_client/src/domain/coins/models/coin_ranking_result.dart'; import 'package:coingecko_client/src/domain/coins/models/coin_tickers.dart'; import 'package:coingecko_client/src/domain/coins/models/coin_market_history.dart'; import 'package:coingecko_client/src/domain/coins/models/coin_ohlc.dart'; +import 'package:coingecko_client/src/domain/coins/enums/coin_price_change.dart'; +import 'package:coingecko_client/src/domain/coins/enums/coin_duration.dart'; +import 'package:coingecko_client/src/domain/coins/enums/coin_ranking.dart'; +import 'package:coingecko_client/src/domain/coins/enums/coin_data_ordering.dart'; import 'package:coingecko_client/src/models/currencies.dart'; import 'package:coingecko_client/src/models/data_range.dart'; import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; @@ -37,7 +40,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; class CoinsEndpoint extends BaseEndpoint { CoinsEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// List all supported coins id, name and symbol (no pagination required) ///
Endpoint : /coins/list @@ -319,4 +322,48 @@ class CoinsEndpoint extends BaseEndpoint { rethrow; } } + + /// [💰PRO Endpoint] Get the latest 200 coins (id) that recently listed on CoinGecko.com + ///
Endpoint : /coins/list/new + Future> getNewList() async { + try { + final path = "/coins/list/new"; + final result = List.of(await sendPro(path)); + return result.map((value) => CoinBasicInfo.fromJson(value)).toList(); + } on FormatException { + throw DataParsingException.unreadableData(); + } on TypeError { + throw DataParsingException.mismatchedType(); + } catch (_) { + rethrow; + } + } + + /// [💰PRO Endpoint] Get the top 30 coins with largest price gain and loss by a specific time duration + ///
Endpoint : /coins/top_gainers_losers + /// + /// [vs_currency] The target currency to use for filtering the data (usd, eur, jpy, etc.) + /// [duration] Filter result by time range - Default `24h` + /// [top_coins] Filter result by MarketCap ranking or all coins (including coins that do not have MarketCap ranking) + Future getTopGainersAndLosers( + {required Currencies vsCurrency, + CoinDuration? duration, + CoinRanking? topCoins}) async { + try { + final path = createEndpointPathUrl(rawQueryItems: { + 'vs_currency': vsCurrency.code, + 'duration': duration?.value, + 'top_coins': topCoins?.value, + }, endpointPath: "/coins/top_gainers_losers"); + + final result = Map.from(await sendPro(path)); + return CoinRankingResult.fromJson(result, vsCurrency); + } on FormatException { + throw DataParsingException.unreadableData(); + } on TypeError { + throw DataParsingException.mismatchedType(); + } catch (_) { + rethrow; + } + } } diff --git a/lib/src/domain/coins/models/coin_data_ordering.dart b/lib/src/domain/coins/enums/coin_data_ordering.dart similarity index 100% rename from lib/src/domain/coins/models/coin_data_ordering.dart rename to lib/src/domain/coins/enums/coin_data_ordering.dart diff --git a/lib/src/domain/coins/enums/coin_duration.dart b/lib/src/domain/coins/enums/coin_duration.dart new file mode 100644 index 0000000..672315d --- /dev/null +++ b/lib/src/domain/coins/enums/coin_duration.dart @@ -0,0 +1,26 @@ +/// Used to filter data by duration time. +enum CoinDuration { + /// Data duration in 1 hour + in1Hour('1h'), + + /// Data duration in 24 hours + in24Hours('24h'), + + /// Data duration in 7 days + in7Days('7d'), + + /// Data duration in 14 days + in14Days('14d'), + + /// Data duration in 30 days + in30Days('30d'), + + /// Data duration in 200 days + in200Days('60d'), + + /// Data duration in 1 year + in1Year('1y'); + + const CoinDuration(this.value); + final String value; +} diff --git a/lib/src/domain/coins/models/coin_price_change.dart b/lib/src/domain/coins/enums/coin_price_change.dart similarity index 100% rename from lib/src/domain/coins/models/coin_price_change.dart rename to lib/src/domain/coins/enums/coin_price_change.dart diff --git a/lib/src/domain/coins/enums/coin_ranking.dart b/lib/src/domain/coins/enums/coin_ranking.dart new file mode 100644 index 0000000..ea664c2 --- /dev/null +++ b/lib/src/domain/coins/enums/coin_ranking.dart @@ -0,0 +1,17 @@ +/// Used to return the top N result. +enum CoinRanking { + /// Top 300 + top300('300'), + + /// Top 500 + top500('500'), + + /// Top 1000 + top1000('1000'), + + /// All + all('all'); + + const CoinRanking(this.value); + final String value; +} diff --git a/lib/src/domain/coins/models/coin_basic_info.dart b/lib/src/domain/coins/models/coin_basic_info.dart index 4b004cc..9ad060c 100644 --- a/lib/src/domain/coins/models/coin_basic_info.dart +++ b/lib/src/domain/coins/models/coin_basic_info.dart @@ -6,22 +6,26 @@ class CoinBasicInfo extends BaseModel { String? _symbol; String? _name; Map? _platforms; + DateTime? _activatedAt; CoinBasicInfo( {String? id, String? symbol, String? name, - Map? platforms}) { + Map? platforms, + DateTime? activatedAt}) { _id = id; _symbol = symbol; _name = name; _platforms = platforms; + _activatedAt = activatedAt; } String? get id => _id; String? get symbol => _symbol; String? get name => _name; Map? get platforms => _platforms; + DateTime? get activatedAt => _activatedAt; /// Converts the raw json data(contained in a Map or List) to a CoinBasicInfo object CoinBasicInfo.fromJson(Map json) { @@ -29,6 +33,7 @@ class CoinBasicInfo extends BaseModel { _symbol = json['symbol']; _name = json['name']; _platforms = toMap(json['platforms']); + _activatedAt = toDateFromTimestamp(json['activated_at']); } /// Converts the object to a Map to make it json serializable. @@ -38,6 +43,7 @@ class CoinBasicInfo extends BaseModel { data['symbol'] = _symbol; data['name'] = _name; data['platforms'] = _platforms; + data['activated_at'] = _activatedAt; return data; } } diff --git a/lib/src/domain/coins/models/coin_ranking_info.dart b/lib/src/domain/coins/models/coin_ranking_info.dart new file mode 100644 index 0000000..b0fbac5 --- /dev/null +++ b/lib/src/domain/coins/models/coin_ranking_info.dart @@ -0,0 +1,69 @@ +import 'package:coingecko_client/coingecko_client.dart'; + +/// Contains the ranking information. +class CoinRankingInfo extends BaseModel { + String? _id; + String? _symbol; + String? _name; + String? _image; + int? _marketCapRank; + double? _value; + double? _valueFor24hVolume; + double? _valueFor1hChange; + + CoinRankingInfo( + {String? id, + String? symbol, + String? name, + String? image, + int? marketCapRank, + double? value, + double? valueFor24hVolume, + double? valueFor1hChange}) { + _id = id; + _symbol = symbol; + _name = name; + _image = image; + _marketCapRank = marketCapRank; + _value = value; + _valueFor24hVolume = valueFor24hVolume; + _valueFor1hChange = valueFor1hChange; + } + + String? get id => _id; + String? get symbol => _symbol; + String? get name => _name; + String? get image => _image; + int? get marketCapRank => _marketCapRank; + double? get value => _value; + double? get valueFor24hVolume => _valueFor24hVolume; + double? get valueFor1hChange => _valueFor1hChange; + + /// Converts the raw json data(contained in a Map or List) to a CoinRankingInfo object + CoinRankingInfo.fromJson(Map json, Currencies vsCurrency) { + final currency = vsCurrency.code; + _id = json['id']; + _symbol = json['symbol']; + _name = json['name']; + _image = json['image']; + _marketCapRank = json['market_cap_rank']; + _value = json[currency]; + _valueFor24hVolume = json['${currency}_24h_vol']; + _valueFor1hChange = json['${currency}_1h_change']; + } + + /// Converts the object to a Map to make it json serializable. + Map toJson(Currencies vsCurrency) { + final Map data = {}; + final currency = vsCurrency.code; + data['id'] = _id; + data['symbol'] = _symbol; + data['name'] = _name; + data['image'] = _image; + data['market_cap_rank'] = _marketCapRank; + data[currency] = _value; + data['${currency}_24h_vol'] = _valueFor24hVolume; + data['${currency}_1h_change'] = _valueFor1hChange; + return data; + } +} diff --git a/lib/src/domain/coins/models/coin_ranking_result.dart b/lib/src/domain/coins/models/coin_ranking_result.dart new file mode 100644 index 0000000..10eca96 --- /dev/null +++ b/lib/src/domain/coins/models/coin_ranking_result.dart @@ -0,0 +1,25 @@ +import 'package:coingecko_client/coingecko_client.dart'; + +///Coins top ranking results +class CoinRankingResult extends BaseModel { + List? _topGainers; + List? _topLosers; + CoinRankingResult( + {List? topGainers, List? topLosers}) { + _topGainers = topGainers; + _topLosers = topLosers; + } + + List? get topGainers => _topGainers; + List? get topLosers => _topLosers; + + /// Converts the raw json data(contained in a Map) to a CoinRankingResult object + CoinRankingResult.fromJson(Map json, Currencies vsCurrency) { + _topGainers = List.of(json['top_gainers']) + .map((value) => CoinRankingInfo.fromJson(value, vsCurrency)) + .toList(); + _topLosers = List.of(json['top_losers']) + .map((value) => CoinRankingInfo.fromJson(value, vsCurrency)) + .toList(); + } +} diff --git a/lib/src/domain/companies/companies_endpoint.dart b/lib/src/domain/companies/companies_endpoint.dart index 5ed1dbb..6b0753c 100644 --- a/lib/src/domain/companies/companies_endpoint.dart +++ b/lib/src/domain/companies/companies_endpoint.dart @@ -9,7 +9,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; class CompaniesEndpoint extends BaseEndpoint { CompaniesEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// Get public companies bitcoin or ethereum holdings (Ordered by total holdings descending) ///
Endpoint : /companies/public_treasury/{coin_id} diff --git a/lib/src/domain/contract/contract_endpoint.dart b/lib/src/domain/contract/contract_endpoint.dart index 3e31690..ea2c126 100644 --- a/lib/src/domain/contract/contract_endpoint.dart +++ b/lib/src/domain/contract/contract_endpoint.dart @@ -13,7 +13,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; class ContractEndpoint extends BaseEndpoint { ContractEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// Get coin info from contract address ///
Endpoint : /coins/{id}/contract/{contract_address} diff --git a/lib/src/domain/derivatives/derivatives_endpoint.dart b/lib/src/domain/derivatives/derivatives_endpoint.dart index b45a8cf..5607f09 100644 --- a/lib/src/domain/derivatives/derivatives_endpoint.dart +++ b/lib/src/domain/derivatives/derivatives_endpoint.dart @@ -1,8 +1,8 @@ import 'package:coingecko_client/src/domain/base_endpoint.dart'; +import 'package:coingecko_client/src/domain/derivatives/enums/derivatives_exchange_ordering.dart'; +import 'package:coingecko_client/src/domain/derivatives/enums/derivatives_tickers.dart'; import 'package:coingecko_client/src/domain/derivatives/models/derivatives.dart'; import 'package:coingecko_client/src/domain/derivatives/models/derivatives_exchange.dart'; -import 'package:coingecko_client/src/domain/derivatives/models/derivatives_exchange_ordering.dart'; -import 'package:coingecko_client/src/domain/derivatives/models/derivatives_tickers.dart'; import 'package:coingecko_client/src/domain/exchanges/models/exchange_basic_info.dart'; import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; import 'package:coingecko_client/src/services/http_request_service.dart'; @@ -16,7 +16,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; class DerivativesEndpoint extends BaseEndpoint { DerivativesEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// List all derivative tickers ///
Endpoint : /derivatives diff --git a/lib/src/domain/derivatives/models/derivatives_exchange_ordering.dart b/lib/src/domain/derivatives/enums/derivatives_exchange_ordering.dart similarity index 100% rename from lib/src/domain/derivatives/models/derivatives_exchange_ordering.dart rename to lib/src/domain/derivatives/enums/derivatives_exchange_ordering.dart diff --git a/lib/src/domain/derivatives/models/derivatives_tickers.dart b/lib/src/domain/derivatives/enums/derivatives_tickers.dart similarity index 100% rename from lib/src/domain/derivatives/models/derivatives_tickers.dart rename to lib/src/domain/derivatives/enums/derivatives_tickers.dart diff --git a/lib/src/domain/exchange_rates/exchange_rates_endpoint.dart b/lib/src/domain/exchange_rates/exchange_rates_endpoint.dart index bc3a016..5f9ab0a 100644 --- a/lib/src/domain/exchange_rates/exchange_rates_endpoint.dart +++ b/lib/src/domain/exchange_rates/exchange_rates_endpoint.dart @@ -9,7 +9,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; class ExchangeRatesEndpoint extends BaseEndpoint { ExchangeRatesEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// Get BTC-to-Currency exchange rates ///
Endpoint : /exchange_rates diff --git a/lib/src/domain/exchanges/models/exchange_data_ordering.dart b/lib/src/domain/exchanges/enums/exchange_data_ordering.dart similarity index 100% rename from lib/src/domain/exchanges/models/exchange_data_ordering.dart rename to lib/src/domain/exchanges/enums/exchange_data_ordering.dart diff --git a/lib/src/domain/exchanges/exchanges_endpoint.dart b/lib/src/domain/exchanges/exchanges_endpoint.dart index 25e5ac6..80f378c 100644 --- a/lib/src/domain/exchanges/exchanges_endpoint.dart +++ b/lib/src/domain/exchanges/exchanges_endpoint.dart @@ -2,7 +2,7 @@ import 'package:coingecko_client/src/domain/base_endpoint.dart'; import 'package:coingecko_client/src/domain/coins/models/ticker_info.dart'; import 'package:coingecko_client/src/domain/exchanges/models/exchange_info.dart'; import 'package:coingecko_client/src/domain/exchanges/models/exchange_basic_info.dart'; -import 'package:coingecko_client/src/domain/exchanges/models/exchange_data_ordering.dart'; +import 'package:coingecko_client/src/domain/exchanges/enums/exchange_data_ordering.dart'; import 'package:coingecko_client/src/domain/exchanges/models/exchange_volume_chart.dart'; import 'package:coingecko_client/src/models/data_range.dart'; import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; @@ -30,7 +30,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; class ExchangesEndpoint extends BaseEndpoint { ExchangesEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// List all exchanges (Active with trading volumes) ///
Endpoint : /exchanges diff --git a/lib/src/domain/global/global_endpoint.dart b/lib/src/domain/global/global_endpoint.dart index 62ecc6e..0869097 100644 --- a/lib/src/domain/global/global_endpoint.dart +++ b/lib/src/domain/global/global_endpoint.dart @@ -11,7 +11,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; class GlobalEndpoint extends BaseEndpoint { GlobalEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// Get cryptocurrency global data ///
Endpoint : /global diff --git a/lib/src/domain/indexes/indexes_endpoint.dart b/lib/src/domain/indexes/indexes_endpoint.dart index e0b7a8a..aad54ef 100644 --- a/lib/src/domain/indexes/indexes_endpoint.dart +++ b/lib/src/domain/indexes/indexes_endpoint.dart @@ -10,7 +10,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; class IndexesEndpoint extends BaseEndpoint { IndexesEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// List all market indexes ///
Endpoint : /indexes diff --git a/lib/src/domain/nfts/models/nfts_data_ordering.dart b/lib/src/domain/nfts/enums/nfts_data_ordering.dart similarity index 100% rename from lib/src/domain/nfts/models/nfts_data_ordering.dart rename to lib/src/domain/nfts/enums/nfts_data_ordering.dart diff --git a/lib/src/domain/nfts/nfts_endpoint.dart b/lib/src/domain/nfts/nfts_endpoint.dart index 8e69e4b..1e1c443 100644 --- a/lib/src/domain/nfts/nfts_endpoint.dart +++ b/lib/src/domain/nfts/nfts_endpoint.dart @@ -1,7 +1,7 @@ import 'package:coingecko_client/src/domain/base_endpoint.dart'; import 'package:coingecko_client/src/domain/nfts/models/nft_basic_info.dart'; import 'package:coingecko_client/src/domain/nfts/models/nft_info.dart'; -import 'package:coingecko_client/src/domain/nfts/models/nfts_data_ordering.dart'; +import 'package:coingecko_client/src/domain/nfts/enums/nfts_data_ordering.dart'; import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; import 'package:coingecko_client/src/services/http_request_service.dart'; @@ -12,7 +12,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; /// class NftsEndpoint extends BaseEndpoint { NftsEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// List all supported NFT ids, paginated by 100 items per page, paginated to 100 items ///
Endpoint : /nfts/list diff --git a/lib/src/domain/ping/ping_endpoint.dart b/lib/src/domain/ping/ping_endpoint.dart index 06f0840..887656d 100644 --- a/lib/src/domain/ping/ping_endpoint.dart +++ b/lib/src/domain/ping/ping_endpoint.dart @@ -7,7 +7,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; /// class PingEndpoint extends BaseEndpoint { PingEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// Check API server status ///
Endpoint : /ping diff --git a/lib/src/domain/search/search_endpoint.dart b/lib/src/domain/search/search_endpoint.dart index f704d9d..c84d365 100644 --- a/lib/src/domain/search/search_endpoint.dart +++ b/lib/src/domain/search/search_endpoint.dart @@ -8,7 +8,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; class SearchEndpoint extends BaseEndpoint { SearchEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// Search for coins, categories and markets listed on CoinGecko ordered by largest Market Cap first ///
Endpoint : /search diff --git a/lib/src/domain/simple/simple_endpoint.dart b/lib/src/domain/simple/simple_endpoint.dart index 6d2deab..130b6d2 100644 --- a/lib/src/domain/simple/simple_endpoint.dart +++ b/lib/src/domain/simple/simple_endpoint.dart @@ -11,7 +11,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; class SimpleEndpoint extends BaseEndpoint { SimpleEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// Get the current price of any cryptocurrencies in any other supported currencies that you need. ///
Endpoint : /simple/price @@ -44,7 +44,7 @@ class SimpleEndpoint extends BaseEndpoint { 'precision': precision }, endpointPath: "/simple/price"); - return Map.from((await sendBasic(path))); + return Map.from(await sendBasic(path)); } on FormatException { throw DataParsingException.unreadableData(); } on TypeError { @@ -87,7 +87,7 @@ class SimpleEndpoint extends BaseEndpoint { 'precision': precision }, endpointPath: "/simple/token_price/{id}"); - return Map.from((await sendBasic(path))); + return Map.from(await sendBasic(path)); } on FormatException { throw DataParsingException.unreadableData(); } on TypeError { diff --git a/lib/src/domain/trending/trending_endpoint.dart b/lib/src/domain/trending/trending_endpoint.dart index b5b5394..a69cc51 100644 --- a/lib/src/domain/trending/trending_endpoint.dart +++ b/lib/src/domain/trending/trending_endpoint.dart @@ -8,7 +8,7 @@ import 'package:coingecko_client/src/services/http_request_service.dart'; class TrendingEndpoint extends BaseEndpoint { TrendingEndpoint(HttpRequestServiceInterface httpRequestService, {String? apiKey}) - : super(httpRequestService, {apiKey: apiKey}); + : super(httpRequestService, apiKey: apiKey); /// Get trending search coins (Top-7) on CoinGecko in the last 24 hours ///
Endpoint : /search/trending diff --git a/lib/src/models/exceptions/request_exception.dart b/lib/src/models/exceptions/request_exception.dart new file mode 100644 index 0000000..2dd8cb9 --- /dev/null +++ b/lib/src/models/exceptions/request_exception.dart @@ -0,0 +1,15 @@ +import 'package:http/http.dart'; + +/// +/// This exception is raised when an issue occured before sending an HTTP request.
+/// +class RequestException extends ClientException { + RequestException(super.message); + + /// + /// Will be raised if an API does not exist when a paid method is used. + /// + factory RequestException.apiKeyNotFound() { + return RequestException("API key is required. Request will be terminated."); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 7342e1f..ebc808e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: coingecko_client description: A simple and intuitive package for the CoinGecko REST API Service ( v3 ) -version: 1.1.1+1 +version: 1.2.0 repository: https://github.com/pangz-lab/coingecko_client license: BSD 3-Clause diff --git a/run_test.sh b/run_test.sh index 9db60a9..c1d2dc2 100755 --- a/run_test.sh +++ b/run_test.sh @@ -1,2 +1,6 @@ dart test test/domain -dart test test/coingecko* +# The following test is optional. +# This is running an integration test using the free tier which has a limit to the number of requests per minute. +# You can either disable this or just run the specific test of endpoint you want to use. + +# dart test test/coingecko* diff --git a/test/coingecko_client_integration_test.dart b/test/coingecko_client_integration_test.dart index 3753ccf..0ba26e4 100644 --- a/test/coingecko_client_integration_test.dart +++ b/test/coingecko_client_integration_test.dart @@ -1,37 +1,5 @@ import 'dart:convert'; -import 'package:coingecko_client/src/coingecko_client_base.dart'; -import 'package:coingecko_client/src/domain/asset_platforms/models/asset_platform.dart'; -import 'package:coingecko_client/src/domain/categories/models/coin_categories_data_ordering.dart'; -import 'package:coingecko_client/src/domain/categories/models/coin_category_basic_info.dart'; -import 'package:coingecko_client/src/domain/categories/models/coin_category_info.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_basic_info.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_data_ordering.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_info.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_market.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_market_history.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_ohlc.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_price_change.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_tickers.dart'; -import 'package:coingecko_client/src/domain/coins/models/ticker_info.dart'; -import 'package:coingecko_client/src/domain/companies/models/company_list.dart'; -import 'package:coingecko_client/src/domain/contract/models/contract_info.dart'; -import 'package:coingecko_client/src/domain/contract/models/contract_market_history.dart'; -import 'package:coingecko_client/src/domain/derivatives/models/derivatives_exchange.dart'; -import 'package:coingecko_client/src/domain/derivatives/models/derivatives_exchange_ordering.dart'; -import 'package:coingecko_client/src/domain/derivatives/models/derivatives_tickers.dart'; -import 'package:coingecko_client/src/domain/derivatives/models/derivatives.dart'; -import 'package:coingecko_client/src/domain/exchange_rates/models/exchange_rate.dart'; -import 'package:coingecko_client/src/domain/exchanges/models/exchange_data_ordering.dart'; -import 'package:coingecko_client/src/domain/exchanges/models/exchange_info.dart'; -import 'package:coingecko_client/src/domain/exchanges/models/exchange_basic_info.dart'; -import 'package:coingecko_client/src/domain/exchanges/models/exchange_volume_chart.dart'; -import 'package:coingecko_client/src/domain/global/models/global_crypto_info.dart'; -import 'package:coingecko_client/src/domain/global/models/global_defi_info.dart'; -import 'package:coingecko_client/src/domain/indexes/models/market_index.dart'; -import 'package:coingecko_client/src/domain/nfts/models/nft_basic_info.dart'; -import 'package:coingecko_client/src/domain/nfts/models/nft_info.dart'; -import 'package:coingecko_client/src/models/currencies.dart'; -import 'package:coingecko_client/src/models/data_range.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; void main() { @@ -136,6 +104,26 @@ void main() { expect(result.elementAt(0).runtimeType, CoinOhlc); expect(jsonEncode(result.elementAt(0).toJson()).runtimeType, String); }); + + test('getNewList: request should return a valid response', () async { + await Future.delayed(Duration(milliseconds: delay)); + final result = await sut.getNewList(); + expect(result.elementAt(0).runtimeType, CoinBasicInfo); + }); + + test('getTopGainersAndLosers: request should return a valid response', + () async { + await Future.delayed(Duration(milliseconds: delay)); + final result = await sut.getTopGainersAndLosers( + vsCurrency: Currencies.php, + duration: CoinDuration.in14Days, + topCoins: CoinRanking.top300); + expect(result.runtimeType, CoinRankingResult); + expect(jsonEncode(result.topGainers?.elementAt(0)).runtimeType, + CoinRankingInfo); + expect(jsonEncode(result.topLosers?.elementAt(0)).runtimeType, + CoinRankingInfo); + }); }); group('Integration test for ExchangesEndpoint for', () { diff --git a/test/coingecko_real_request_test.dart b/test/coingecko_real_request_test.dart index 848b7b2..c4db7c3 100644 --- a/test/coingecko_real_request_test.dart +++ b/test/coingecko_real_request_test.dart @@ -1,17 +1,17 @@ import 'package:coingecko_client/src/domain/asset_platforms/asset_platforms_endpoint.dart'; import 'package:coingecko_client/src/domain/asset_platforms/models/asset_platform.dart'; import 'package:coingecko_client/src/domain/categories/categories_endpoint.dart'; -import 'package:coingecko_client/src/domain/categories/models/coin_categories_data_ordering.dart'; +import 'package:coingecko_client/src/domain/categories/enums/coin_categories_data_ordering.dart'; import 'package:coingecko_client/src/domain/categories/models/coin_category_basic_info.dart'; import 'package:coingecko_client/src/domain/categories/models/coin_category_info.dart'; import 'package:coingecko_client/src/domain/coins/coins_endpoint.dart'; import 'package:coingecko_client/src/domain/coins/models/coin_basic_info.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_data_ordering.dart'; +import 'package:coingecko_client/src/domain/coins/enums/coin_data_ordering.dart'; import 'package:coingecko_client/src/domain/coins/models/coin_info.dart'; import 'package:coingecko_client/src/domain/coins/models/coin_market.dart'; import 'package:coingecko_client/src/domain/coins/models/coin_market_history.dart'; import 'package:coingecko_client/src/domain/coins/models/coin_ohlc.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_price_change.dart'; +import 'package:coingecko_client/src/domain/coins/enums/coin_price_change.dart'; import 'package:coingecko_client/src/domain/coins/models/coin_tickers.dart'; import 'package:coingecko_client/src/domain/coins/models/ticker_info.dart'; import 'package:coingecko_client/src/domain/companies/companies_endpoint.dart'; @@ -20,14 +20,14 @@ import 'package:coingecko_client/src/domain/contract/contract_endpoint.dart'; import 'package:coingecko_client/src/domain/contract/models/contract_info.dart'; import 'package:coingecko_client/src/domain/contract/models/contract_market_history.dart'; import 'package:coingecko_client/src/domain/derivatives/derivatives_endpoint.dart'; +import 'package:coingecko_client/src/domain/derivatives/enums/derivatives_exchange_ordering.dart'; +import 'package:coingecko_client/src/domain/derivatives/enums/derivatives_tickers.dart'; import 'package:coingecko_client/src/domain/derivatives/models/derivatives_exchange.dart'; -import 'package:coingecko_client/src/domain/derivatives/models/derivatives_exchange_ordering.dart'; -import 'package:coingecko_client/src/domain/derivatives/models/derivatives_tickers.dart'; import 'package:coingecko_client/src/domain/derivatives/models/derivatives.dart'; import 'package:coingecko_client/src/domain/exchange_rates/exchange_rates_endpoint.dart'; import 'package:coingecko_client/src/domain/exchange_rates/models/exchange_rate.dart'; import 'package:coingecko_client/src/domain/exchanges/exchanges_endpoint.dart'; -import 'package:coingecko_client/src/domain/exchanges/models/exchange_data_ordering.dart'; +import 'package:coingecko_client/src/domain/exchanges/enums/exchange_data_ordering.dart'; import 'package:coingecko_client/src/domain/exchanges/models/exchange_info.dart'; import 'package:coingecko_client/src/domain/exchanges/models/exchange_basic_info.dart'; import 'package:coingecko_client/src/domain/exchanges/models/exchange_volume_chart.dart'; diff --git a/test/domain/asset_platforms/asset_platforms_endpoint_test.dart b/test/domain/asset_platforms/asset_platforms_endpoint_test.dart index 321aacd..0974ed5 100644 --- a/test/domain/asset_platforms/asset_platforms_endpoint_test.dart +++ b/test/domain/asset_platforms/asset_platforms_endpoint_test.dart @@ -1,8 +1,5 @@ import 'dart:convert'; -import 'package:coingecko_client/src/domain/asset_platforms/asset_platforms_endpoint.dart'; -import 'package:coingecko_client/src/domain/asset_platforms/models/asset_platforms_filter.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart'; diff --git a/test/domain/categories/categories_endpoint_test.dart b/test/domain/categories/categories_endpoint_test.dart index 9d306d3..a6ce5a4 100644 --- a/test/domain/categories/categories_endpoint_test.dart +++ b/test/domain/categories/categories_endpoint_test.dart @@ -1,9 +1,5 @@ import 'dart:convert'; - -import 'package:coingecko_client/src/domain/categories/categories_endpoint.dart'; -import 'package:coingecko_client/src/domain/categories/models/coin_categories_data_ordering.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart'; diff --git a/test/domain/coins/coins_endpoint_test.dart b/test/domain/coins/coins_endpoint_test.dart index 0ebcd8f..1eed794 100644 --- a/test/domain/coins/coins_endpoint_test.dart +++ b/test/domain/coins/coins_endpoint_test.dart @@ -1,19 +1,5 @@ import 'dart:convert'; -import 'package:coingecko_client/src/domain/coins/coins_endpoint.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_basic_info.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_data_ordering.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_info.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_market_history.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_price_change.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_tickers.dart'; -import 'package:coingecko_client/src/domain/coins/models/coin_ohlc.dart'; -import 'package:coingecko_client/src/domain/coins/models/roi.dart'; -import 'package:coingecko_client/src/domain/coins/models/ticker_info.dart'; -import 'package:coingecko_client/src/models/currencies.dart'; -import 'package:coingecko_client/src/models/data_range.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; -import 'package:coingecko_client/src/models/historical_data.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart'; @@ -22,6 +8,7 @@ import 'mock/coins_mock_data.dart'; void main() { CoinsEndpoint? sut; final String apiVersionPath = "/api/v3"; + const testApiKey = '1212121212121'; group('getBasicList method in', () { group('CoinsEndpoint test endpoint path creation', () { @@ -1570,4 +1557,251 @@ void main() { }); }); }); + + group('getNewList method in', () { + final basePath = "$apiVersionPath/coins/list/new"; + group('CoinsEndpoint test endpoint path creation', () { + var sut = CoinsEndpoint( + HttpRequestServiceMock(statusCode: 200, body: '[]'), + apiKey: testApiKey); + + test('without parameters', () async { + await sut.getNewList(); + expect(sut.endpointPath, basePath); + }); + }); + + group('CoinsEndpoint test endpoint response', () { + test('with data in getting the correct response type', () async { + sut = CoinsEndpoint( + HttpRequestServiceMock( + statusCode: 200, body: CoinNewListMockData.validResponseBody), + apiKey: testApiKey); + final result = await sut!.getNewList(); + var fistElement = result.elementAt(0); + expect(result.length, 3); + expect(fistElement, isA()); + expect(fistElement.id, 'texan'); + expect(fistElement.symbol, 'texan'); + expect(fistElement.name, 'Texan'); + expect( + fistElement.activatedAt, DateTime.parse('2023-01-14 18:58:36.000')); + }); + + test('should still return a result for incomplete data format', () async { + sut = CoinsEndpoint( + HttpRequestServiceMock( + statusCode: 200, + body: CoinNewListMockData.responseBodyWithIncompleteKeys), + apiKey: testApiKey); + final result = await sut!.getNewList(); + var fistElement = result.elementAt(0); + var secondElement = result.elementAt(1); + var lastElement = result.elementAt(2); + expect(result.length, 3); + expect(fistElement, isA()); + expect(fistElement.id, null); + expect(fistElement.name, 'Texan'); + expect(fistElement.symbol, 'texan'); + expect( + fistElement.activatedAt, DateTime.parse('2023-01-14 18:58:36.000')); + expect(secondElement, isA()); + expect(secondElement.id, 'nexacoin'); + expect(secondElement.name, 'Nexacoin'); + expect(secondElement.symbol, null); + expect(secondElement.activatedAt, + DateTime.parse('2023-01-14 18:58:36.000')); + + expect(lastElement, isA()); + expect(lastElement.id, 'nexacoin'); + expect(lastElement.name, 'Nexacoin'); + expect(lastElement.symbol, 'nexa'); + expect(lastElement.activatedAt, null); + }); + }); + + group('CoinsEndpoint test for error handling', () { + test('should throw an exception for failed request', () async { + sut = CoinsEndpoint( + HttpRequestServiceMock( + statusCode: 500, + body: CoinMarketChartMockData.validResponseBody), + apiKey: testApiKey); + await expectLater( + sut!.getNewList(), throwsA(isA())); + }); + + test( + 'should return a FormatException when result is error or when parsing failed', + () async { + sut = CoinsEndpoint( + HttpRequestServiceMock( + statusCode: 200, + body: CoinMarketChartMockData.responseBodyWithInvalidFormat), + apiKey: testApiKey); + await expectLater( + sut!.getNewList(), throwsA(isA())); + + sut = CoinsEndpoint(HttpRequestServiceMock(statusCode: 200, body: "{}"), + apiKey: testApiKey); + await expectLater( + sut!.getNewList(), throwsA(isA())); + }); + }); + }); + + group('getTopGainersAndLosers method in', () { + final basePath = "$apiVersionPath/coins/top_gainers_losers"; + group('CoinsEndpoint test endpoint path creation', () { + var sut = CoinsEndpoint( + HttpRequestServiceMock( + statusCode: 200, + body: CoinTopGainersAndLosersMockData.validResponseBody), + apiKey: testApiKey); + + test('with required parameters', () async { + await sut.getTopGainersAndLosers(vsCurrency: Currencies.usd); + expect(sut.endpointPath, "$basePath?vs_currency=usd"); + }); + + test('with all parameters', () async { + await sut.getTopGainersAndLosers( + vsCurrency: Currencies.usd, + duration: CoinDuration.in14Days, + topCoins: CoinRanking.top300); + expect(sut.endpointPath, + "$basePath?vs_currency=usd&duration=14d&top_coins=300"); + }); + }); + + group('CoinsEndpoint test endpoint response', () { + test('with data in getting the correct response type', () async { + sut = CoinsEndpoint( + HttpRequestServiceMock( + statusCode: 200, + body: CoinTopGainersAndLosersMockData.validResponseBody), + apiKey: testApiKey); + final result = await sut!.getTopGainersAndLosers( + vsCurrency: Currencies.usd, + duration: CoinDuration.in14Days, + topCoins: CoinRanking.all, + ); + final topGainers = result.topGainers; + final topLosers = result.topLosers; + expect(topGainers!.length, 2); + expect(topLosers!.length, 2); + expect(result, isA()); + expect(topGainers, isA()); + expect(topLosers, isA()); + + final tgFirstElement = topGainers.elementAt(0); + final tlFirstElement = topLosers.elementAt(0); + expect(tgFirstElement, isA()); + expect(tlFirstElement, isA()); + + expect(tgFirstElement.id, "platinx"); + expect(tgFirstElement.symbol, "ptx"); + expect(tgFirstElement.name, "PlatinX"); + expect(tgFirstElement.image, + "https://assets.coingecko.com/coins/images/23726/original/logo200x200.png?1645162319"); + expect(tgFirstElement.marketCapRank, null); + expect(tgFirstElement.value, 0.020361781843315337); + expect(tgFirstElement.valueFor24hVolume, 187147.7839535509); + expect(tgFirstElement.valueFor1hChange, 96.92603350641804); + + expect(tlFirstElement.id, "nftearth"); + expect(tlFirstElement.symbol, "nfte"); + expect(tlFirstElement.name, "NFTEarth"); + expect(tlFirstElement.image, + "https://assets.coingecko.com/coins/images/29116/original/20230223_224134.jpg?1677224110"); + expect(tlFirstElement.marketCapRank, null); + expect(tlFirstElement.value, 0.013121207474003034); + expect(tlFirstElement.valueFor24hVolume, 85887.2358881691); + expect(tlFirstElement.valueFor1hChange, -30.431856675273593); + }); + + test('should still return a result for incomplete data format', () async { + sut = CoinsEndpoint( + HttpRequestServiceMock( + statusCode: 200, + body: CoinTopGainersAndLosersMockData + .responseBodyWithIncompleteKeys), + apiKey: testApiKey); + final result = await sut!.getTopGainersAndLosers( + vsCurrency: Currencies.usd, + duration: CoinDuration.in14Days, + topCoins: CoinRanking.all, + ); + final topGainers = result.topGainers; + final topLosers = result.topLosers; + + final tgFirstElement = topGainers!.elementAt(0); + final tlFirstElement = topLosers!.elementAt(0); + + expect(tgFirstElement.id, "platinx"); + expect(tgFirstElement.symbol, "ptx"); + expect(tgFirstElement.name, "PlatinX"); + expect(tgFirstElement.image, null); + expect(tgFirstElement.marketCapRank, null); + expect(tgFirstElement.value, null); + expect(tgFirstElement.valueFor24hVolume, 187147.7839535509); + expect(tgFirstElement.valueFor1hChange, 96.92603350641804); + + expect(tlFirstElement.id, "nftearth"); + expect(tlFirstElement.symbol, "nfte"); + expect(tlFirstElement.name, "NFTEarth"); + expect(tlFirstElement.image, + "https://assets.coingecko.com/coins/images/29116/original/20230223_224134.jpg?1677224110"); + expect(tlFirstElement.marketCapRank, null); + expect(tlFirstElement.value, 0.013121207474003034); + expect(tlFirstElement.valueFor24hVolume, 85887.2358881691); + expect(tlFirstElement.valueFor1hChange, null); + }); + }); + + group('CoinsEndpoint test for error handling', () { + test('should throw an exception for failed request', () async { + sut = CoinsEndpoint( + HttpRequestServiceMock( + statusCode: 500, + body: CoinTopGainersAndLosersMockData.validResponseBody), + apiKey: testApiKey); + await expectLater( + sut!.getTopGainersAndLosers( + vsCurrency: Currencies.usd, + duration: CoinDuration.in14Days, + topCoins: CoinRanking.all, + ), + throwsA(isA())); + }); + + test( + 'should return a FormatException when result is error or when parsing failed', + () async { + sut = CoinsEndpoint( + HttpRequestServiceMock( + statusCode: 200, + body: CoinTopGainersAndLosersMockData + .responseBodyWithInvalidFormat), + apiKey: testApiKey); + await expectLater( + sut!.getTopGainersAndLosers( + vsCurrency: Currencies.usd, + duration: CoinDuration.in14Days, + topCoins: CoinRanking.all, + ), + throwsA(isA())); + + sut = CoinsEndpoint(HttpRequestServiceMock(statusCode: 200, body: ""), + apiKey: testApiKey); + await expectLater( + sut!.getTopGainersAndLosers( + vsCurrency: Currencies.usd, + duration: CoinDuration.in14Days, + topCoins: CoinRanking.all, + ), + throwsA(isA())); + }); + }); + }); } diff --git a/test/domain/coins/mock/coins_mock_data.dart b/test/domain/coins/mock/coins_mock_data.dart index 1583784..13bb672 100644 --- a/test/domain/coins/mock/coins_mock_data.dart +++ b/test/domain/coins/mock/coins_mock_data.dart @@ -1229,3 +1229,125 @@ class CoinOhlcMockData { "name": "bitcoin", },'''; } + +class CoinNewListMockData { + static final validResponseBody = r'''[ + { + "id": "texan", + "symbol": "texan", + "name": "Texan", + "activated_at": 1673690316 + }, + { + "id": "nexacoin", + "symbol": "nexa", + "name": "Nexacoin", + "activated_at": 1673689429 + }, + { + "id": "nexacoin", + "symbol": "nexa", + "name": "Nexacoin", + "activated_at": 1673689429 + } +]'''; + + static final responseBodyWithIncompleteKeys = r'''[ + { + "symbol": "texan", + "name": "Texan", + "activated_at": 1673690316 + }, + { + "id": "nexacoin", + "name": "Nexacoin", + "activated_at": 1673690316 + }, + { + "id": "nexacoin", + "symbol": "nexa", + "name": "Nexacoin" + } +]'''; + //Invalid json format - with comma at the end + static final responseBodyWithInvalidFormat = r'''{ + "name": "bitcoin", +},'''; +} + +class CoinTopGainersAndLosersMockData { + static final validResponseBody = r'''{ + "top_gainers": [ + { + "id": "platinx", + "symbol": "ptx", + "name": "PlatinX", + "image": "https://assets.coingecko.com/coins/images/23726/original/logo200x200.png?1645162319", + "market_cap_rank": null, + "usd": 0.020361781843315337, + "usd_24h_vol": 187147.7839535509, + "usd_1h_change": 96.92603350641804 + }, + { + "id": "motiv-protocol", + "symbol": "mov", + "name": "MOTIV Protocol", + "image": "https://assets.coingecko.com/coins/images/11869/original/jvftnBL-_400x400.jpg?1595498693", + "market_cap_rank": null, + "usd": 0.000405080858465138, + "usd_24h_vol": 303229.51924620906, + "usd_1h_change": 40.029963487686324 + } + ], + "top_losers": [ + { + "id": "nftearth", + "symbol": "nfte", + "name": "NFTEarth", + "image": "https://assets.coingecko.com/coins/images/29116/original/20230223_224134.jpg?1677224110", + "market_cap_rank": null, + "usd": 0.013121207474003034, + "usd_24h_vol": 85887.2358881691, + "usd_1h_change": -30.431856675273593 + }, + { + "id": "bear-inu", + "symbol": "bear", + "name": "Bear Inu", + "image": "https://assets.coingecko.com/coins/images/29517/original/bear.png?1679394237", + "market_cap_rank": null, + "usd": 5.514461480763323e-06, + "usd_24h_vol": 583306.7193019107, + "usd_1h_change": -29.115041946342522 + } + ] +}'''; + + static final responseBodyWithIncompleteKeys = r'''{ + "top_gainers": [ + { + "id": "platinx", + "symbol": "ptx", + "name": "PlatinX", + "market_cap_rank": null, + "usd_24h_vol": 187147.7839535509, + "usd_1h_change": 96.92603350641804 + } + ], + "top_losers": [ + { + "id": "nftearth", + "symbol": "nfte", + "name": "NFTEarth", + "image": "https://assets.coingecko.com/coins/images/29116/original/20230223_224134.jpg?1677224110", + "market_cap_rank": null, + "usd": 0.013121207474003034, + "usd_24h_vol": 85887.2358881691 + } + ] +}'''; + //Invalid json format - with comma at the end + static final responseBodyWithInvalidFormat = r'''{ + "name": "bitcoin", +},'''; +} diff --git a/test/domain/companies/companies_endpoint_test.dart b/test/domain/companies/companies_endpoint_test.dart index db6ec7f..5b440b8 100644 --- a/test/domain/companies/companies_endpoint_test.dart +++ b/test/domain/companies/companies_endpoint_test.dart @@ -1,7 +1,5 @@ import 'dart:convert'; -import 'package:coingecko_client/src/domain/companies/companies_endpoint.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart'; diff --git a/test/domain/contract/contract_endpoint_test.dart b/test/domain/contract/contract_endpoint_test.dart index 8b362bb..08d4b64 100644 --- a/test/domain/contract/contract_endpoint_test.dart +++ b/test/domain/contract/contract_endpoint_test.dart @@ -1,10 +1,5 @@ import 'dart:convert'; -import 'package:coingecko_client/src/domain/contract/contract_endpoint.dart'; -import 'package:coingecko_client/src/models/currencies.dart'; -import 'package:coingecko_client/src/models/data_range.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; -import 'package:coingecko_client/src/models/historical_data.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart'; diff --git a/test/domain/derivatives/derivatives_endpoint_test.dart b/test/domain/derivatives/derivatives_endpoint_test.dart index 83ae8f0..8b52cc6 100644 --- a/test/domain/derivatives/derivatives_endpoint_test.dart +++ b/test/domain/derivatives/derivatives_endpoint_test.dart @@ -1,9 +1,5 @@ import 'dart:convert'; -import 'package:coingecko_client/src/domain/derivatives/derivatives_endpoint.dart'; -import 'package:coingecko_client/src/domain/derivatives/models/derivatives_exchange_ordering.dart'; -import 'package:coingecko_client/src/domain/derivatives/models/derivatives_tickers.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart'; diff --git a/test/domain/exchange_rates/exchange_rates_endpoint_test.dart b/test/domain/exchange_rates/exchange_rates_endpoint_test.dart index 875d266..c46e60e 100644 --- a/test/domain/exchange_rates/exchange_rates_endpoint_test.dart +++ b/test/domain/exchange_rates/exchange_rates_endpoint_test.dart @@ -1,7 +1,5 @@ import 'dart:convert'; -import 'package:coingecko_client/src/domain/exchange_rates/exchange_rates_endpoint.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart'; diff --git a/test/domain/exchanges/exchanges_endpoint_test.dart b/test/domain/exchanges/exchanges_endpoint_test.dart index 47fd3fe..ac44950 100644 --- a/test/domain/exchanges/exchanges_endpoint_test.dart +++ b/test/domain/exchanges/exchanges_endpoint_test.dart @@ -1,9 +1,5 @@ import 'dart:convert'; -import 'package:coingecko_client/src/domain/exchanges/exchanges_endpoint.dart'; -import 'package:coingecko_client/src/domain/exchanges/models/exchange_data_ordering.dart'; -import 'package:coingecko_client/src/models/data_range.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart'; diff --git a/test/domain/global/global_endpoint_test.dart b/test/domain/global/global_endpoint_test.dart index a5999af..5ff6566 100644 --- a/test/domain/global/global_endpoint_test.dart +++ b/test/domain/global/global_endpoint_test.dart @@ -1,7 +1,5 @@ import 'dart:convert'; -import 'package:coingecko_client/src/domain/global/global_endpoint.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart'; diff --git a/test/domain/indexes/indexes_endpoint_test.dart b/test/domain/indexes/indexes_endpoint_test.dart index a011b5a..db8fc61 100644 --- a/test/domain/indexes/indexes_endpoint_test.dart +++ b/test/domain/indexes/indexes_endpoint_test.dart @@ -1,7 +1,5 @@ import 'dart:convert'; -import 'package:coingecko_client/src/domain/indexes/indexes_endpoint.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart'; diff --git a/test/domain/nfts/nfts_endpoint_test.dart b/test/domain/nfts/nfts_endpoint_test.dart index 6f179ee..a3215a7 100644 --- a/test/domain/nfts/nfts_endpoint_test.dart +++ b/test/domain/nfts/nfts_endpoint_test.dart @@ -1,9 +1,5 @@ import 'dart:convert'; -import 'package:coingecko_client/src/domain/nfts/models/nfts_data_ordering.dart'; -import 'package:coingecko_client/src/domain/nfts/nfts_endpoint.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; -import 'package:coingecko_client/src/models/image.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart'; diff --git a/test/domain/ping/ping_endpoint_test.dart b/test/domain/ping/ping_endpoint_test.dart index f237e23..f4d8624 100644 --- a/test/domain/ping/ping_endpoint_test.dart +++ b/test/domain/ping/ping_endpoint_test.dart @@ -1,6 +1,4 @@ -import 'package:coingecko_client/src/domain/ping/ping_endpoint.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart'; diff --git a/test/domain/search/search_endpoint_test.dart b/test/domain/search/search_endpoint_test.dart index f313d3c..7f9a38c 100644 --- a/test/domain/search/search_endpoint_test.dart +++ b/test/domain/search/search_endpoint_test.dart @@ -1,7 +1,5 @@ import 'dart:convert'; -import 'package:coingecko_client/src/domain/search/search_endpoint.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart'; diff --git a/test/domain/simple/simple_endpoint_test.dart b/test/domain/simple/simple_endpoint_test.dart index eef8047..227aae1 100644 --- a/test/domain/simple/simple_endpoint_test.dart +++ b/test/domain/simple/simple_endpoint_test.dart @@ -1,8 +1,5 @@ import 'dart:convert'; -import 'package:coingecko_client/src/domain/simple/simple_endpoint.dart'; -import 'package:coingecko_client/src/models/currencies.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart'; diff --git a/test/domain/trending/trending_endpoint_test.dart b/test/domain/trending/trending_endpoint_test.dart index 7fba080..b36d77f 100644 --- a/test/domain/trending/trending_endpoint_test.dart +++ b/test/domain/trending/trending_endpoint_test.dart @@ -1,7 +1,5 @@ import 'dart:convert'; -import 'package:coingecko_client/src/domain/trending/trending_endpoint.dart'; -import 'package:coingecko_client/src/models/exceptions/data_parsing_exception.dart'; -import 'package:coingecko_client/src/models/exceptions/network_request_exception.dart'; +import 'package:coingecko_client/coingecko_client.dart'; import 'package:test/test.dart'; import '../../services/http_request_service_mock.dart';