Last active
May 5, 2018 06:03
-
-
Save PulkitSethi1984/fa84746084617aae5e846574e3b21772 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public enum ServiceMode | |
{ | |
RECORD, | |
MOCK | |
} | |
public class Request | |
{ | |
public string Uri { get; set; } | |
public string RelativeUri { get; set; } | |
public string Method { get; set; } | |
public List<string> Parameters { get; set; } | |
} | |
public class Response | |
{ | |
public string HttpResponse { get; set; } | |
public string Content { get; set; } | |
} | |
public class Recording | |
{ | |
public Request Request { get; set; } | |
public Response Response { get; set; } | |
} | |
public class Recordings | |
{ | |
public List<Recording> Data { get; set; } | |
} | |
public class MockNetworkService : INetworkService | |
{ | |
const string _relativeUri = "/api/"; | |
const string _folderName = "Recordings"; | |
const string _fileName = "TestRecording.json"; | |
readonly IStorageService _storageService; | |
private List<Recording> AllRecordings { get; set; } | |
protected ServiceMode Mode { get; set; } | |
private Recordings Recordings { get; set; } | |
public MockNetworkService() | |
{ | |
// Set mode | |
Mode = ServiceMode.RECORD; | |
Recordings = new Recordings | |
{ | |
Data = new List<Recording>() | |
}; | |
_storageService = DependencyService.Get<IStorageService>(); | |
// Cannot record with storage service => iOS | |
if (null == _storageService) | |
Mode = ServiceMode.MOCK; | |
} | |
.... | |
public async Task<ServiceResult<TResult>> GetAsync<TResult>(string uri, string token = "") | |
{ | |
var method = "GET"; | |
ServiceResult<TResult> result = new ServiceResult<TResult> | |
{ | |
Data = default(TResult), | |
IsError = true, | |
}; | |
try | |
{ | |
if (ServiceMode.RECORD == Mode) | |
{ | |
var recording = new Recording | |
{ | |
Request = GetRequest(uri, method) | |
}; | |
recording.Request.Method = method; | |
recording.Response = new Response(); | |
var response = await lazyClient.Value.GetAsync(uri); | |
// Serialize response | |
recording.Response.HttpResponse = JsonConvert.SerializeObject(response); | |
// Save current recording | |
await InsertRecording(method, recording); | |
if (response.IsSuccessStatusCode) | |
{ | |
result.IsError = false; | |
result.Data = JsonConvert.DeserializeObject<TResult>(await response.Content.ReadAsStringAsync()); | |
} | |
else | |
{ | |
result.ErrorCode = (int)response.StatusCode; | |
result.ErrorMessage = response.ReasonPhrase; | |
} | |
} | |
else if (ServiceMode.MOCK == Mode) | |
{ | |
Recording savedRecording = null; | |
foreach (var r in Recordings.Data) | |
{ | |
if (MatchRequest(method, r.Request, GetRequest(uri, method))) | |
{ | |
savedRecording = r; | |
break; | |
} | |
} | |
HttpResponseMessage response = JsonConvert.DeserializeObject<HttpResponseMessage>(savedRecording.Response.HttpResponse); | |
if (response.IsSuccessStatusCode) | |
{ | |
result.IsError = false; | |
result.Data = JsonConvert.DeserializeObject<TResult>(savedRecording.Response.Content); | |
} | |
else | |
{ | |
result.ErrorCode = (int)response.StatusCode; | |
result.ErrorMessage = response.ReasonPhrase; | |
} | |
} | |
} | |
catch (Exception exp) | |
{ | |
result.IsError = true; | |
result.ErrorCode = (int)HttpStatusCode.InternalServerError; // Unknown | |
result.ErrorMessage = exp.Message; | |
} | |
return result; | |
} | |
private async Task InsertRecording(string method, Recording recording) | |
{ | |
Recordings allRecordings = null; | |
var currentRecordings = await _storageService.GetContent(_folderName, _fileName); | |
if (null != currentRecordings) | |
{ | |
allRecordings = JsonConvert.DeserializeObject<Recordings>(currentRecordings); | |
} | |
else | |
allRecordings = new Recordings { Data = new List<Recording>() }; | |
var toRemove = allRecordings.Data.Where(x => MatchRequest(method, x.Request, recording.Request)).FirstOrDefault(); | |
if (null != toRemove) | |
allRecordings.Data.Remove(toRemove); | |
allRecordings.Data.Add(recording); | |
var content = JsonConvert.SerializeObject(allRecordings); | |
await _storageService.SaveFile(_folderName, _fileName, content); | |
} | |
private bool MatchRequest(string method, Request first, Request second) | |
{ | |
if (0 == string.Compare(second.Method, method, StringComparison.CurrentCultureIgnoreCase) | |
&& (0 == string.Compare(first.Uri, second.Uri, StringComparison.CurrentCultureIgnoreCase))) | |
{ | |
if (null == first.Parameters && null == second.Parameters) | |
return true; | |
if (null == first.Parameters && null != second.Parameters || null != first.Parameters && null != second.Parameters) | |
return false; | |
if (null != first.Parameters && null != second.Parameters && first.Parameters.Intersect(second.Parameters).Count() == second.Parameters.Count()) | |
return true; | |
} | |
return false; | |
} | |
private Request GetRequest(string uri, string method) | |
{ | |
var decodedUri = HttpUtility.UrlDecode(uri); | |
string relativeUriPath = string.Empty; | |
List<string> queryParams = null; | |
if (decodedUri.ToLower().Contains(_relativeUri)) | |
{ | |
if (decodedUri.Contains('?')) | |
{ | |
var startIndex = decodedUri.IndexOf(_relativeUri, StringComparison.CurrentCultureIgnoreCase); | |
var endIndex = decodedUri.IndexOf('?'); | |
relativeUriPath = decodedUri.Substring(startIndex, endIndex - startIndex); | |
} | |
else | |
{ | |
relativeUriPath = decodedUri.Substring(decodedUri.IndexOf(_relativeUri, StringComparison.CurrentCultureIgnoreCase)); | |
} | |
} | |
if (decodedUri.Contains('?')) | |
{ | |
var queryString = decodedUri.Substring(decodedUri.IndexOf('?')).Split('#')[0]; | |
var decodeParams = HttpUtility.ParseQueryString(queryString); | |
queryParams = new List<string>(decodeParams.AllKeys); | |
} | |
return new Request | |
{ | |
Uri = decodedUri, | |
Parameters = queryParams, | |
RelativeUri = relativeUriPath, | |
Method = method | |
}; | |
} | |
private void LoadMockData(string jsonData, bool replace) | |
{ | |
if (null != Recordings.Data && replace) | |
Recordings.Data.Clear(); | |
var recordings = JsonConvert.DeserializeObject<Recordings>(jsonData); | |
if (null != recordings && null != recordings.Data) | |
Recordings.Data.AddRange(recordings.Data); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment