< Summary

Class:TheGraph
Assembly:TheGraph
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/ServiceProviders/TheGraph/TheGraph.cs
Covered lines:33
Uncovered lines:37
Coverable lines:70
Total lines:151
Line coverage:47.1% (33 of 70)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
TheGraph()0%110100%
Query(...)0%2100%
Query(...)0%8.18088.24%
QueryLands(...)0%2100%
QueryLands(...)0%42600%
QueryPolygonMana(...)0%110100%
Dispose()0%2100%
ProcessReceivedLandsData(...)0%12300%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/ServiceProviders/TheGraph/TheGraph.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4using System.Text.RegularExpressions;
 5using DCL;
 6using DCL.Helpers;
 7using Newtonsoft.Json.Linq;
 8using UnityEngine;
 9using UnityEngine.Networking;
 10
 11public class TheGraph : ITheGraph
 12{
 13    private const float DEFAULT_CACHE_TIME = 5 * 60;
 14    private const string LAND_SUBGRAPH_URL_ORG = "https://api.thegraph.com/subgraphs/name/decentraland/land-manager";
 15    private const string LAND_SUBGRAPH_URL_ZONE = "https://api.thegraph.com/subgraphs/name/decentraland/land-manager-rop
 16    private const string LAND_SUBGRAPH_URL_MATIC = "https://api.thegraph.com/subgraphs/name/decentraland/mana-matic-main
 17
 53118    private readonly IDataCache<List<Land>> landQueryCache = new DataCache<List<Land>>();
 19
 020    public Promise<string> Query(string url, string query) { return Query(url, query, null); }
 21
 22    public Promise<string> Query(string url, string query, QueryVariablesBase variables)
 23    {
 124        Promise<string> promise = new Promise<string>();
 25
 126        if (string.IsNullOrEmpty(query) || string.IsNullOrEmpty(url))
 27        {
 028            promise.Reject($"error: {(string.IsNullOrEmpty(url) ? "url" : "query")} is empty");
 029            return promise;
 30        }
 31
 132        string queryJson = $"\"query\":\"{Regex.Replace(query, @"\p{C}+", string.Empty)}\"";
 133        string variablesJson = variables != null ? $",\"variables\":{JsonUtility.ToJson(variables)}" : string.Empty;
 134        string bodyString = $"{{{queryJson}{variablesJson}}}";
 35
 136        var request = new UnityWebRequest();
 137        request.url = url;
 138        request.method = UnityWebRequest.kHttpVerbPOST;
 139        request.downloadHandler = new DownloadHandlerBuffer();
 140        request.uploadHandler = new UploadHandlerRaw(string.IsNullOrEmpty(bodyString) ? null : Encoding.UTF8.GetBytes(bo
 141        request.SetRequestHeader("Content-Type", "application/json");
 142        request.timeout = 60;
 43
 144        var operation = request.SendWebRequest();
 45
 146        operation.completed += asyncOperation =>
 47        {
 148            if (request.WebRequestSucceded())
 49            {
 150                promise.Resolve(request.downloadHandler.text);
 151            }
 52            else
 53            {
 054                promise.Reject($"error: {request.error} response: {request.downloadHandler.text}");
 55            }
 56
 157            request.Dispose();
 158        };
 59
 160        return promise;
 61    }
 62
 063    public Promise<List<Land>> QueryLands(string tld, string address) { return QueryLands(tld, address, DEFAULT_CACHE_TI
 64
 65    public Promise<List<Land>> QueryLands(string tld, string address, float cacheMaxAgeSeconds)
 66    {
 067        string lowerCaseAddress = address.ToLower();
 68
 069        Promise<List<Land>> promise = new Promise<List<Land>>();
 70
 071        if (cacheMaxAgeSeconds >= 0)
 72        {
 073            if (landQueryCache.TryGet(lowerCaseAddress, out List<Land> cacheValue, out float lastUpdate))
 74            {
 075                if (Time.unscaledTime - lastUpdate <= cacheMaxAgeSeconds)
 76                {
 077                    promise.Resolve(cacheValue);
 078                    return promise;
 79                }
 80            }
 81        }
 82
 083        string url = tld == "org" ? LAND_SUBGRAPH_URL_ORG : LAND_SUBGRAPH_URL_ZONE;
 84
 085        Query(url, TheGraphQueries.getLandQuery, new AddressVariable() { address = lowerCaseAddress })
 86            .Then(resultJson =>
 87            {
 088                ProcessReceivedLandsData(promise, resultJson, lowerCaseAddress, true);
 089            })
 090            .Catch(error => promise.Reject(error));
 91
 092        return promise;
 93    }
 94
 95    public Promise<double> QueryPolygonMana(string address)
 96    {
 197        Promise<double> promise = new Promise<double>();
 98
 199        string lowerCaseAddress = address.ToLower();
 1100        Query(LAND_SUBGRAPH_URL_MATIC, TheGraphQueries.getPolygonManaQuery, new AddressVariable() { address = lowerCaseA
 101            .Then(resultJson =>
 102            {
 103                try
 104                {
 1105                    JObject result = JObject.Parse(resultJson);
 1106                    JToken manaObject = result["data"]?["accounts"].First?["mana"];
 1107                    if (manaObject == null || !double.TryParse(manaObject.Value<string>(), out double parsedMana))
 1108                        throw new Exception($"QueryMana response couldn't be parsed: {resultJson}");
 109
 0110                    promise.Resolve(parsedMana / 1e18);
 0111                }
 1112                catch (Exception e)
 113                {
 1114                    promise.Reject(e.ToString());
 1115                }
 1116            })
 0117            .Catch(error => promise.Reject(error));
 1118        return promise;
 119    }
 120
 0121    public void Dispose() { landQueryCache.Dispose(); }
 122
 123    private void ProcessReceivedLandsData(Promise<List<Land>> landPromise, string jsonValue, string lowerCaseAddress, bo
 124    {
 0125        bool hasException = false;
 0126        List<Land> lands = null;
 127
 128        try
 129        {
 0130            LandQueryResultWrapped result = JsonUtility.FromJson<LandQueryResultWrapped>(jsonValue);
 0131            lands = LandHelper.ConvertQueryResult(result.data, lowerCaseAddress);
 132
 0133            if (cache)
 134            {
 0135                landQueryCache.Add(lowerCaseAddress, lands, DEFAULT_CACHE_TIME);
 136            }
 0137        }
 0138        catch (Exception exception)
 139        {
 0140            landPromise.Reject(exception.Message);
 0141            hasException = true;
 0142        }
 143        finally
 144        {
 0145            if (!hasException)
 146            {
 0147                landPromise.Resolve(lands);
 148            }
 0149        }
 0150    }
 151}