Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
You can’t perform that action at this time.