From 150b3d9ebcb8b09fa759cfd72ae6c891a9706c88 Mon Sep 17 00:00:00 2001 From: sethisusil Date: Mon, 17 Feb 2020 22:45:18 +0530 Subject: [PATCH 1/3] Submitting the coding challenge for displaying countries --- .../Paymentsense.Coding.Challenge.Api.sln | 42 ++++++++++ .../Controllers/GeographicController.cs | 32 +++++++ .../Paymentsense.Coding.Challenge.Api.csproj | 9 ++ .../Startup.cs | 3 + .../appsettings.json | 1 + .../Contracts/Geographic/Country.cs | 32 +++++++ .../Contracts/Geographic/Currency.cs | 9 ++ .../Contracts/Geographic/Language.cs | 10 +++ .../Contracts/Geographic/RegionalBloc.cs | 12 +++ .../Contracts/Geographic/Translations.cs | 13 +++ .../paymentsense.common.csproj | 7 ++ .../Bootstrapper.cs | 14 ++++ .../Geographic.cs | 43 ++++++++++ .../IGeographic.cs | 11 +++ .../paymentsense.geographic.business.csproj | 12 +++ .../paymentsense.utility/Bootstrapper.cs | 15 ++++ .../CacheHelpers/ICache.cs | 8 ++ .../CacheHelpers/InMemoryCache.cs | 38 +++++++++ .../HtppHelpers/HttpHelpers.cs | 44 ++++++++++ .../HtppHelpers/IHttpHelpers.cs | 10 +++ .../paymentsense.utility.csproj | 14 ++++ .../package-lock.json | 8 ++ .../package.json | 3 +- .../src/app/app.component.html | 7 ++ .../src/app/app.component.ts | 15 +++- .../src/app/app.module.ts | 16 +++- .../geography-countrylist.component.html | 84 +++++++++++++++++++ .../geography-countrylist.component.ts | 48 +++++++++++ .../models/paymentsense-geography.model.ts | 66 +++++++++++++++ .../paymentsense-geography.service.ts | 15 ++++ .../src/app/modals/modal.component.ts | 57 +++++++++++++ .../src/app/modals/modal.less | 50 +++++++++++ .../src/app/modals/modal.service.ts | 25 ++++++ ...ymentsense-coding-challenge-api.service.ts | 2 +- .../src/styles.scss | 59 +++++++++++++ 35 files changed, 826 insertions(+), 8 deletions(-) create mode 100644 paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Controllers/GeographicController.cs create mode 100644 paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Country.cs create mode 100644 paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Currency.cs create mode 100644 paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Language.cs create mode 100644 paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/RegionalBloc.cs create mode 100644 paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Translations.cs create mode 100644 paymentsense-coding-challenge-api/paymentsense.common/paymentsense.common.csproj create mode 100644 paymentsense-coding-challenge-api/paymentsense.geographic.business/Bootstrapper.cs create mode 100644 paymentsense-coding-challenge-api/paymentsense.geographic.business/Geographic.cs create mode 100644 paymentsense-coding-challenge-api/paymentsense.geographic.business/IGeographic.cs create mode 100644 paymentsense-coding-challenge-api/paymentsense.geographic.business/paymentsense.geographic.business.csproj create mode 100644 paymentsense-coding-challenge-api/paymentsense.utility/Bootstrapper.cs create mode 100644 paymentsense-coding-challenge-api/paymentsense.utility/CacheHelpers/ICache.cs create mode 100644 paymentsense-coding-challenge-api/paymentsense.utility/CacheHelpers/InMemoryCache.cs create mode 100644 paymentsense-coding-challenge-api/paymentsense.utility/HtppHelpers/HttpHelpers.cs create mode 100644 paymentsense-coding-challenge-api/paymentsense.utility/HtppHelpers/IHttpHelpers.cs create mode 100644 paymentsense-coding-challenge-api/paymentsense.utility/paymentsense.utility.csproj create mode 100644 paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.html create mode 100644 paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.ts create mode 100644 paymentsense-coding-challenge-website/src/app/geography/models/paymentsense-geography.model.ts create mode 100644 paymentsense-coding-challenge-website/src/app/geography/services/paymentsense-geography.service.ts create mode 100644 paymentsense-coding-challenge-website/src/app/modals/modal.component.ts create mode 100644 paymentsense-coding-challenge-website/src/app/modals/modal.less create mode 100644 paymentsense-coding-challenge-website/src/app/modals/modal.service.ts diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.sln b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.sln index e692c1b..0d7abc4 100644 --- a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.sln +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.sln @@ -7,6 +7,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Paymentsense.Coding.Challen EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Paymentsense.Coding.Challenge.Api.Tests", "Paymentsense.Coding.Challenge.Api.Tests\Paymentsense.Coding.Challenge.Api.Tests.csproj", "{29B33764-7D72-4940-90F9-28467B569288}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "paymentsense.geographic.business", "paymentsense.geographic.business\paymentsense.geographic.business.csproj", "{019F8FA6-93A7-4C67-B1F2-B94621C73375}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "paymentsense.common", "paymentsense.common\paymentsense.common.csproj", "{77EA15B9-720C-4BCA-BDF5-33911F73E179}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "paymentsense.utility", "paymentsense.utility\paymentsense.utility.csproj", "{FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -41,6 +47,42 @@ Global {29B33764-7D72-4940-90F9-28467B569288}.Release|x64.Build.0 = Release|Any CPU {29B33764-7D72-4940-90F9-28467B569288}.Release|x86.ActiveCfg = Release|Any CPU {29B33764-7D72-4940-90F9-28467B569288}.Release|x86.Build.0 = Release|Any CPU + {019F8FA6-93A7-4C67-B1F2-B94621C73375}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {019F8FA6-93A7-4C67-B1F2-B94621C73375}.Debug|Any CPU.Build.0 = Debug|Any CPU + {019F8FA6-93A7-4C67-B1F2-B94621C73375}.Debug|x64.ActiveCfg = Debug|Any CPU + {019F8FA6-93A7-4C67-B1F2-B94621C73375}.Debug|x64.Build.0 = Debug|Any CPU + {019F8FA6-93A7-4C67-B1F2-B94621C73375}.Debug|x86.ActiveCfg = Debug|Any CPU + {019F8FA6-93A7-4C67-B1F2-B94621C73375}.Debug|x86.Build.0 = Debug|Any CPU + {019F8FA6-93A7-4C67-B1F2-B94621C73375}.Release|Any CPU.ActiveCfg = Release|Any CPU + {019F8FA6-93A7-4C67-B1F2-B94621C73375}.Release|Any CPU.Build.0 = Release|Any CPU + {019F8FA6-93A7-4C67-B1F2-B94621C73375}.Release|x64.ActiveCfg = Release|Any CPU + {019F8FA6-93A7-4C67-B1F2-B94621C73375}.Release|x64.Build.0 = Release|Any CPU + {019F8FA6-93A7-4C67-B1F2-B94621C73375}.Release|x86.ActiveCfg = Release|Any CPU + {019F8FA6-93A7-4C67-B1F2-B94621C73375}.Release|x86.Build.0 = Release|Any CPU + {77EA15B9-720C-4BCA-BDF5-33911F73E179}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {77EA15B9-720C-4BCA-BDF5-33911F73E179}.Debug|Any CPU.Build.0 = Debug|Any CPU + {77EA15B9-720C-4BCA-BDF5-33911F73E179}.Debug|x64.ActiveCfg = Debug|Any CPU + {77EA15B9-720C-4BCA-BDF5-33911F73E179}.Debug|x64.Build.0 = Debug|Any CPU + {77EA15B9-720C-4BCA-BDF5-33911F73E179}.Debug|x86.ActiveCfg = Debug|Any CPU + {77EA15B9-720C-4BCA-BDF5-33911F73E179}.Debug|x86.Build.0 = Debug|Any CPU + {77EA15B9-720C-4BCA-BDF5-33911F73E179}.Release|Any CPU.ActiveCfg = Release|Any CPU + {77EA15B9-720C-4BCA-BDF5-33911F73E179}.Release|Any CPU.Build.0 = Release|Any CPU + {77EA15B9-720C-4BCA-BDF5-33911F73E179}.Release|x64.ActiveCfg = Release|Any CPU + {77EA15B9-720C-4BCA-BDF5-33911F73E179}.Release|x64.Build.0 = Release|Any CPU + {77EA15B9-720C-4BCA-BDF5-33911F73E179}.Release|x86.ActiveCfg = Release|Any CPU + {77EA15B9-720C-4BCA-BDF5-33911F73E179}.Release|x86.Build.0 = Release|Any CPU + {FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}.Debug|x64.ActiveCfg = Debug|Any CPU + {FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}.Debug|x64.Build.0 = Debug|Any CPU + {FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}.Debug|x86.ActiveCfg = Debug|Any CPU + {FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}.Debug|x86.Build.0 = Debug|Any CPU + {FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}.Release|Any CPU.Build.0 = Release|Any CPU + {FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}.Release|x64.ActiveCfg = Release|Any CPU + {FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}.Release|x64.Build.0 = Release|Any CPU + {FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}.Release|x86.ActiveCfg = Release|Any CPU + {FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Controllers/GeographicController.cs b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Controllers/GeographicController.cs new file mode 100644 index 0000000..fb1de0f --- /dev/null +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Controllers/GeographicController.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using paymentsense.geographic.business; + +namespace Paymentsense.Coding.Challenge.Api.Controllers +{ + + [ApiController] + [Route("[controller]")] + public class GeographicController : ControllerBase + { + IGeographic _geographic; + public GeographicController(IGeographic geographic) + { + _geographic = geographic; + } + + // GET: Geographic/countries + [HttpGet] + [Route("countries")] + public async Task GetCountries() + { + var data = await _geographic.GetCountries(); + return Ok(data); + } + + } +} diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Paymentsense.Coding.Challenge.Api.csproj b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Paymentsense.Coding.Challenge.Api.csproj index 1d82fb7..75b417f 100644 --- a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Paymentsense.Coding.Challenge.Api.csproj +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Paymentsense.Coding.Challenge.Api.csproj @@ -10,4 +10,13 @@ + + + + + + + + + diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Startup.cs b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Startup.cs index 623b8b2..2b0a007 100644 --- a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Startup.cs +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Startup.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using paymentsense.geographic.business; namespace Paymentsense.Coding.Challenge.Api { @@ -29,6 +30,8 @@ public void ConfigureServices(IServiceCollection services) .AllowAnyHeader(); }); }); + services.AddMemoryCache(); + services.UseGeoGraphicServices(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/appsettings.json b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/appsettings.json index d9d9a9b..8770d7f 100644 --- a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/appsettings.json +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/appsettings.json @@ -6,5 +6,6 @@ "Microsoft.Hosting.Lifetime": "Information" } }, + "RestGetCountryBaseUrl": "https://restcountries.eu/rest/v2/all", "AllowedHosts": "*" } diff --git a/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Country.cs b/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Country.cs new file mode 100644 index 0000000..d8ea2e5 --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Country.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; + +namespace paymentsense.common.Contracts.Geographic +{ + public class Country + { + public string name { get; set; } + public List topLevelDomain { get; set; } + public string alpha2Code { get; set; } + public string alpha3Code { get; set; } + public List callingCodes { get; set; } + public string capital { get; set; } + public List altSpellings { get; set; } + public string region { get; set; } + public string subregion { get; set; } + public int population { get; set; } + public List latlng { get; set; } + public string demonym { get; set; } + public double? area { get; set; } + public double? gini { get; set; } + public List timezones { get; set; } + public List borders { get; set; } + public string nativeName { get; set; } + public string numericCode { get; set; } + public List currencies { get; set; } + public List languages { get; set; } + public Translations translations { get; set; } + public string flag { get; set; } + public List regionalBlocs { get; set; } + public string cioc { get; set; } + } +} diff --git a/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Currency.cs b/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Currency.cs new file mode 100644 index 0000000..90bda40 --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Currency.cs @@ -0,0 +1,9 @@ +namespace paymentsense.common.Contracts.Geographic +{ + public class Currency + { + public string code { get; set; } + public string name { get; set; } + public string symbol { get; set; } + } +} diff --git a/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Language.cs b/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Language.cs new file mode 100644 index 0000000..ec1dbc1 --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Language.cs @@ -0,0 +1,10 @@ +namespace paymentsense.common.Contracts.Geographic +{ + public class Language + { + public string iso639_1 { get; set; } + public string iso639_2 { get; set; } + public string name { get; set; } + public string nativeName { get; set; } + } +} diff --git a/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/RegionalBloc.cs b/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/RegionalBloc.cs new file mode 100644 index 0000000..feb2dde --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/RegionalBloc.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace paymentsense.common.Contracts.Geographic +{ + public class RegionalBloc + { + public string acronym { get; set; } + public string name { get; set; } + public List otherAcronyms { get; set; } + public List otherNames { get; set; } + } +} diff --git a/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Translations.cs b/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Translations.cs new file mode 100644 index 0000000..74c672f --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.common/Contracts/Geographic/Translations.cs @@ -0,0 +1,13 @@ +namespace paymentsense.common.Contracts.Geographic +{ + public class Translations + { + public string de { get; set; } + public string es { get; set; } + public string fr { get; set; } + public string ja { get; set; } + public string it { get; set; } + public string br { get; set; } + public string pt { get; set; } + } +} diff --git a/paymentsense-coding-challenge-api/paymentsense.common/paymentsense.common.csproj b/paymentsense-coding-challenge-api/paymentsense.common/paymentsense.common.csproj new file mode 100644 index 0000000..f7731aa --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.common/paymentsense.common.csproj @@ -0,0 +1,7 @@ + + + + netcoreapp3.0 + + + diff --git a/paymentsense-coding-challenge-api/paymentsense.geographic.business/Bootstrapper.cs b/paymentsense-coding-challenge-api/paymentsense.geographic.business/Bootstrapper.cs new file mode 100644 index 0000000..c1f1eca --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.geographic.business/Bootstrapper.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.DependencyInjection; +using paymentsense.utility; + +namespace paymentsense.geographic.business +{ + public static class Bootstrapper + { + public static void UseGeoGraphicServices(this IServiceCollection services) + { + services.UseUtilityServices(); + services.AddSingleton(); + } + } +} diff --git a/paymentsense-coding-challenge-api/paymentsense.geographic.business/Geographic.cs b/paymentsense-coding-challenge-api/paymentsense.geographic.business/Geographic.cs new file mode 100644 index 0000000..4ea29b4 --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.geographic.business/Geographic.cs @@ -0,0 +1,43 @@ +using Microsoft.Extensions.Configuration; +using paymentsense.common.Contracts.Geographic; +using paymentsense.utility.CacheHelpers; +using paymentsense.utility.HtppHelpers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace paymentsense.geographic.business +{ + public class Geographic : IGeographic + { + ICache _cache; + IHttpHelpers _httpHelpers; + string countryCacheKey = "lstcountry"; + string url = string.Empty; + public Geographic(ICache cache, IHttpHelpers httpHelpers, IConfiguration config) + { + _cache = cache; + _httpHelpers = httpHelpers; + url = config.GetValue("RestGetCountryBaseUrl"); + } + + public async Task> GetCountries() + { + List countries = new List(); + try + { + countries = _cache.Get>(countryCacheKey); + if (countries == null || countries.Any() == false) + { + countries = await _httpHelpers.Get>(url); + _cache.Set>(countryCacheKey,countries); + } + } + catch (Exception ex) + { + } + return countries; + } + } +} diff --git a/paymentsense-coding-challenge-api/paymentsense.geographic.business/IGeographic.cs b/paymentsense-coding-challenge-api/paymentsense.geographic.business/IGeographic.cs new file mode 100644 index 0000000..cbbb2c3 --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.geographic.business/IGeographic.cs @@ -0,0 +1,11 @@ +using paymentsense.common.Contracts.Geographic; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace paymentsense.geographic.business +{ + public interface IGeographic + { + Task> GetCountries(); + } +} diff --git a/paymentsense-coding-challenge-api/paymentsense.geographic.business/paymentsense.geographic.business.csproj b/paymentsense-coding-challenge-api/paymentsense.geographic.business/paymentsense.geographic.business.csproj new file mode 100644 index 0000000..a1e62db --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.geographic.business/paymentsense.geographic.business.csproj @@ -0,0 +1,12 @@ + + + + netcoreapp3.0 + + + + + + + + diff --git a/paymentsense-coding-challenge-api/paymentsense.utility/Bootstrapper.cs b/paymentsense-coding-challenge-api/paymentsense.utility/Bootstrapper.cs new file mode 100644 index 0000000..0a7d2f2 --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.utility/Bootstrapper.cs @@ -0,0 +1,15 @@ +using Microsoft.Extensions.DependencyInjection; +using paymentsense.utility.CacheHelpers; +using paymentsense.utility.HtppHelpers; + +namespace paymentsense.utility +{ + public static class Bootstrapper + { + public static void UseUtilityServices(this IServiceCollection services) + { + services.AddHttpClient(); + services.AddSingleton(); + } + } +} diff --git a/paymentsense-coding-challenge-api/paymentsense.utility/CacheHelpers/ICache.cs b/paymentsense-coding-challenge-api/paymentsense.utility/CacheHelpers/ICache.cs new file mode 100644 index 0000000..f840c69 --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.utility/CacheHelpers/ICache.cs @@ -0,0 +1,8 @@ +namespace paymentsense.utility.CacheHelpers +{ + public interface ICache + { + T Get(string key); + bool Set(string key, T data); + } +} diff --git a/paymentsense-coding-challenge-api/paymentsense.utility/CacheHelpers/InMemoryCache.cs b/paymentsense-coding-challenge-api/paymentsense.utility/CacheHelpers/InMemoryCache.cs new file mode 100644 index 0000000..49aa91a --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.utility/CacheHelpers/InMemoryCache.cs @@ -0,0 +1,38 @@ + +using Microsoft.Extensions.Caching.Memory; +using System; + +namespace paymentsense.utility.CacheHelpers +{ + public class InMemoryCache : ICache + { + private readonly IMemoryCache _memoryCache; + public InMemoryCache(IMemoryCache memoryCache) + { + _memoryCache = memoryCache; + } + + public T Get(string key) + { + T data = default(T); + if (_memoryCache.TryGetValue(key, out var outObj)) + { + data = (T)outObj; + } + return data; + } + + public bool Set(string key, T data) + { + bool bIsSuccess = false; + var cacheEntryOptions = new MemoryCacheEntryOptions() + .SetSlidingExpiration(TimeSpan.FromMinutes(60)); + var result = _memoryCache.Set(key, data, cacheEntryOptions); + if (result != null) + { + bIsSuccess = true; + } + return bIsSuccess; + } + } +} diff --git a/paymentsense-coding-challenge-api/paymentsense.utility/HtppHelpers/HttpHelpers.cs b/paymentsense-coding-challenge-api/paymentsense.utility/HtppHelpers/HttpHelpers.cs new file mode 100644 index 0000000..7a71d06 --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.utility/HtppHelpers/HttpHelpers.cs @@ -0,0 +1,44 @@ +using Newtonsoft.Json; +using System; +using System.Net.Http; +using System.Threading.Tasks; + +namespace paymentsense.utility.HtppHelpers +{ + public class HttpHelpers : IHttpHelpers + { + private readonly HttpClient _client; + + public HttpHelpers(HttpClient client) + { + _client = client; + } + + public async Task Get(string url) + { + T data = default(T); + try + { + if (!string.IsNullOrWhiteSpace(url)) + { + var httpResponse = await _client.GetAsync(url); + if (httpResponse != null && httpResponse.IsSuccessStatusCode) + { + var content = await httpResponse.Content.ReadAsStringAsync(); + data = JsonConvert.DeserializeObject(content); + } + } + } + catch (Exception ex) + { + + } + return data; + } + + public async Task Post(string url, T data) + { + throw new NotImplementedException(); + } + } +} diff --git a/paymentsense-coding-challenge-api/paymentsense.utility/HtppHelpers/IHttpHelpers.cs b/paymentsense-coding-challenge-api/paymentsense.utility/HtppHelpers/IHttpHelpers.cs new file mode 100644 index 0000000..410099f --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.utility/HtppHelpers/IHttpHelpers.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; + +namespace paymentsense.utility.HtppHelpers +{ + public interface IHttpHelpers + { + Task Get(string url); + Task Post(string url,T data); + } +} diff --git a/paymentsense-coding-challenge-api/paymentsense.utility/paymentsense.utility.csproj b/paymentsense-coding-challenge-api/paymentsense.utility/paymentsense.utility.csproj new file mode 100644 index 0000000..51779d1 --- /dev/null +++ b/paymentsense-coding-challenge-api/paymentsense.utility/paymentsense.utility.csproj @@ -0,0 +1,14 @@ + + + + netcoreapp3.0 + + + + + + + + + + diff --git a/paymentsense-coding-challenge-website/package-lock.json b/paymentsense-coding-challenge-website/package-lock.json index ca397d9..83428e7 100644 --- a/paymentsense-coding-challenge-website/package-lock.json +++ b/paymentsense-coding-challenge-website/package-lock.json @@ -2271,6 +2271,14 @@ } } }, + "@swimlane/ngx-datatable": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@swimlane/ngx-datatable/-/ngx-datatable-16.0.3.tgz", + "integrity": "sha512-SuVd89CTFhy+21SF8W+qmGoXGFeB7KB5/VwkrgvDRs0GnBC5m9u1nAyN0ypSXMmqilcem6vPmh4yVhjPL1rseg==", + "requires": { + "tslib": "^1.9.0" + } + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", diff --git a/paymentsense-coding-challenge-website/package.json b/paymentsense-coding-challenge-website/package.json index c43f4f8..886b903 100644 --- a/paymentsense-coding-challenge-website/package.json +++ b/paymentsense-coding-challenge-website/package.json @@ -28,7 +28,8 @@ "core-js": "^2.5.4", "rxjs": "~6.5.2", "tslib": "^1.9.0", - "zone.js": "~0.9.1" + "zone.js": "~0.9.1", + "@swimlane/ngx-datatable": "^16.0.3" }, "devDependencies": { "@angular-devkit/build-angular": "~0.803.8", diff --git a/paymentsense-coding-challenge-website/src/app/app.component.html b/paymentsense-coding-challenge-website/src/app/app.component.html index 9201572..788710a 100644 --- a/paymentsense-coding-challenge-website/src/app/app.component.html +++ b/paymentsense-coding-challenge-website/src/app/app.component.html @@ -8,4 +8,11 @@

... Paymentsense Coding Challenge API is ...

+
+

Click on bellow button to show list of available countries

+ + + + +
diff --git a/paymentsense-coding-challenge-website/src/app/app.component.ts b/paymentsense-coding-challenge-website/src/app/app.component.ts index 11956d4..8c857d4 100644 --- a/paymentsense-coding-challenge-website/src/app/app.component.ts +++ b/paymentsense-coding-challenge-website/src/app/app.component.ts @@ -1,22 +1,25 @@ -import { Component } from '@angular/core'; +import { Component,OnInit } from '@angular/core'; import { PaymentsenseCodingChallengeApiService } from './services'; import { take } from 'rxjs/operators'; import { faThumbsUp, faThumbsDown } from '@fortawesome/free-regular-svg-icons'; +import { PaymentsenseGeographyService } from './geography/services/paymentsense-geography.service'; + @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) -export class AppComponent { +export class AppComponent implements OnInit { public faThumbsUp = faThumbsUp; public faThumbsDown = faThumbsDown; public title = 'Paymentsense Coding Challenge!'; public paymentsenseCodingChallengeApiIsActive = false; public paymentsenseCodingChallengeApiActiveIcon = this.faThumbsDown; public paymentsenseCodingChallengeApiActiveIconColour = 'red'; + public showCountry:boolean=false; - constructor(private paymentsenseCodingChallengeApiService: PaymentsenseCodingChallengeApiService) { + constructor(private paymentsenseCodingChallengeApiService: PaymentsenseCodingChallengeApiService,private geographyservice:PaymentsenseGeographyService) { paymentsenseCodingChallengeApiService.getHealth().pipe(take(1)) .subscribe( apiHealth => { @@ -34,4 +37,10 @@ export class AppComponent { this.paymentsenseCodingChallengeApiActiveIconColour = 'red'; }); } + ngOnInit() { + } + public showCountryClick():void + { + this.showCountry=true; + } } diff --git a/paymentsense-coding-challenge-website/src/app/app.module.ts b/paymentsense-coding-challenge-website/src/app/app.module.ts index 77745c5..636a359 100644 --- a/paymentsense-coding-challenge-website/src/app/app.module.ts +++ b/paymentsense-coding-challenge-website/src/app/app.module.ts @@ -1,5 +1,6 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @@ -7,19 +8,28 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { PaymentsenseCodingChallengeApiService } from './services'; import { HttpClientModule } from '@angular/common/http'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { NgxDatatableModule } from '@swimlane/ngx-datatable'; +import { PaymentsenseGeographyService } from './geography/services/paymentsense-geography.service'; +import { LstCountryComponent } from './geography/geography-countrylist.component'; +import { ModalComponent } from './modals/modal.component'; +import { ModalService } from './modals/modal.service'; @NgModule({ declarations: [ - AppComponent + AppComponent, + LstCountryComponent, + ModalComponent ], imports: [ BrowserModule, AppRoutingModule, BrowserAnimationsModule, HttpClientModule, - FontAwesomeModule + FontAwesomeModule, + NgxDatatableModule, + FormsModule ], - providers: [PaymentsenseCodingChallengeApiService], + providers: [PaymentsenseCodingChallengeApiService,PaymentsenseGeographyService,ModalService], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.html b/paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.html new file mode 100644 index 0000000..19d5b59 --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.html @@ -0,0 +1,84 @@ +

+ Bellow are the available country list: +

+
+ + + Country Name + + {{ value }} + + + + + + Flag Image + + + + + + + +
+
+ Plesae wit... +
+ + + + + \ No newline at end of file diff --git a/paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.ts b/paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.ts new file mode 100644 index 0000000..9b2a5fe --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.ts @@ -0,0 +1,48 @@ +import { Component,OnInit } from '@angular/core'; +import { take } from 'rxjs/operators'; +import { faThumbsUp, faThumbsDown } from '@fortawesome/free-regular-svg-icons'; +import { PaymentsenseGeographyService } from './services/paymentsense-geography.service'; +import { Country } from './models/paymentsense-geography.model'; +import { ModalService } from '../modals/modal.service'; + + +@Component({ + selector: 'country-list', + templateUrl: './geography-countrylist.component.html' +}) +export class LstCountryComponent implements OnInit { + public isFetchingData:boolean=false; + public countries:Country[]=[]; + public country:Country=new Country(); + constructor(private geographyservice:PaymentsenseGeographyService,private modalService: ModalService) { + + } + + ngOnInit() { + this.getCountries(); + } + private getCountries():void{ + this.isFetchingData=true; + this.geographyservice.getCountries().pipe(take(1)) + .subscribe( + result => { + this.countries=result; + this.isFetchingData=false; + }, + _ => { + this.isFetchingData=false; + }); + } + + openModal(id: string,row:Country) { + if(row){ + this.country=row; + this.modalService.open(id); + } + + } + + closeModal(id: string) { + this.modalService.close(id); + } +} diff --git a/paymentsense-coding-challenge-website/src/app/geography/models/paymentsense-geography.model.ts b/paymentsense-coding-challenge-website/src/app/geography/models/paymentsense-geography.model.ts new file mode 100644 index 0000000..9e6fb77 --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/geography/models/paymentsense-geography.model.ts @@ -0,0 +1,66 @@ +export class Country{ + public name:string; + public topLevelDomain:string[]; + public alpha2Code:string; + public alpha3Code:string; + public callingCodes:string[]; + public capital:string; + public altSpellings:string[]; + public region:string; + public subregion:string; + public population?:number; + public latlng?:number[]; + public demonym:string; + public area?:number[]; + public gini?:number[]; + public timezones:string[]; + public borders:string[]; + public nativeName:string; + public numericCode:string; + public currencies:Currency[]; + public languages:Language[]; + public translations:Translations; + public flag:string; + public regionalBlocs:RegionalBloc[]; + public cioc:string; + +} + +export class Currency { + public code:string; + public name:string; + public symbol:string; +} + +export class Language { + public iso639_1:string; + public iso639_2:string; + public name:string; + public nativeName:string; +} + +export class RegionalBloc { + public acronym:string; + public name:string; + public otherAcronyms:any[]; + public otherNames:string[]; +} +export class Translations { + public de:string; + public fr:string; + public ja:string; + public it:string; + public br:string; + public pt:string; +} + +export class Page { + //The number of elements in the page + size: number = 0; + //The total number of elements + totalElements: number = 0; + //The total number of pages + totalPages: number = 0; + //The current page number + pageNumber: number = 0; + } \ No newline at end of file diff --git a/paymentsense-coding-challenge-website/src/app/geography/services/paymentsense-geography.service.ts b/paymentsense-coding-challenge-website/src/app/geography/services/paymentsense-geography.service.ts new file mode 100644 index 0000000..d1661f4 --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/geography/services/paymentsense-geography.service.ts @@ -0,0 +1,15 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { HttpClient } from '@angular/common/http'; +import { Country } from 'src/app/geography/models/paymentsense-geography.model'; + +@Injectable({ + providedIn: 'root' +}) +export class PaymentsenseGeographyService { + constructor(private httpClient: HttpClient) {} + + public getCountries(): Observable { + return this.httpClient.get('https://localhost:44352//Geographic//countries', { }); + } +} diff --git a/paymentsense-coding-challenge-website/src/app/modals/modal.component.ts b/paymentsense-coding-challenge-website/src/app/modals/modal.component.ts new file mode 100644 index 0000000..c158a28 --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/modals/modal.component.ts @@ -0,0 +1,57 @@ +import { Component, ElementRef, Input, OnInit, OnDestroy } from '@angular/core'; +import { ModalService } from './modal.service'; + +@Component({ + selector: 'modal', + template: '', + styleUrls: ['./modal.less'] +}) +export class ModalComponent implements OnInit, OnDestroy { + @Input() id: string; + private element: any; + + constructor(private modalService: ModalService, private el: ElementRef) { + this.element = el.nativeElement; + } + + ngOnInit(): void { + let modal = this; + + // ensure id attribute exists + if (!this.id) { + console.error('modal must have an id'); + return; + } + + // move element to bottom of page (just before ) so it can be displayed above everything else + document.body.appendChild(this.element); + + // close modal on background click + this.element.addEventListener('click', function (e: any) { + if (e.target.className === 'modal') { + modal.close(); + } + }); + + // add self (this modal instance) to the modal service so it's accessible from controllers + this.modalService.add(this); + } + + // remove self from modal service when directive is destroyed + ngOnDestroy(): void { + this.modalService.remove(this.id); + this.element.remove(); + } + + // open modal + open(): void { + this.element.style.display = 'block'; + document.body.classList.add('modal-open'); + } + + // close modal + close(): void { + this.element.style.display = 'none'; + document.body.classList.remove('modal-open'); + } +} \ No newline at end of file diff --git a/paymentsense-coding-challenge-website/src/app/modals/modal.less b/paymentsense-coding-challenge-website/src/app/modals/modal.less new file mode 100644 index 0000000..924bed5 --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/modals/modal.less @@ -0,0 +1,50 @@ +/* MODAL STYLES +-------------------------------*/ +modal { + /* modals are hidden by default */ + display: none; + + .modal { + /* modal container fixed across whole screen */ + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + + /* z-index must be higher than .modal-background */ + z-index: 1000; + + /* enables scrolling for tall modals */ + overflow: auto; + + .modal-body { + padding: 20px; + background: #fff; + + /* margin exposes part of the modal background */ + margin: 40px; + } + } + + .modal-background { + /* modal background fixed across whole screen */ + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + + /* semi-transparent black */ + background-color: #000; + opacity: 0.75; + + /* z-index must be below .modal and above everything else */ + z-index: 900; + } +} + +body.modal-open { + /* body overflow is hidden to hide main scrollbar when modal window is open */ + overflow: hidden; +} diff --git a/paymentsense-coding-challenge-website/src/app/modals/modal.service.ts b/paymentsense-coding-challenge-website/src/app/modals/modal.service.ts new file mode 100644 index 0000000..97d5787 --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/modals/modal.service.ts @@ -0,0 +1,25 @@ +export class ModalService { + private modals: any[] = []; + + add(modal: any) { + // add modal to array of active modals + this.modals.push(modal); + } + + remove(id: string) { + // remove modal from array of active modals + this.modals = this.modals.filter(x => x.id !== id); + } + + open(id: string) { + // open modal specified by id + let modal: any = this.modals.filter(x => x.id === id)[0]; + modal.open(); + } + + close(id: string) { + // close modal specified by id + let modal: any = this.modals.filter(x => x.id === id)[0]; + modal.close(); + } +} \ No newline at end of file diff --git a/paymentsense-coding-challenge-website/src/app/services/paymentsense-coding-challenge-api.service.ts b/paymentsense-coding-challenge-website/src/app/services/paymentsense-coding-challenge-api.service.ts index 1dddc8c..45d26c2 100644 --- a/paymentsense-coding-challenge-website/src/app/services/paymentsense-coding-challenge-api.service.ts +++ b/paymentsense-coding-challenge-website/src/app/services/paymentsense-coding-challenge-api.service.ts @@ -9,6 +9,6 @@ export class PaymentsenseCodingChallengeApiService { constructor(private httpClient: HttpClient) {} public getHealth(): Observable { - return this.httpClient.get('https://localhost:44341/health', { responseType: 'text' }); + return this.httpClient.get('https://localhost:44352//health', { responseType: 'text' }); } } diff --git a/paymentsense-coding-challenge-website/src/styles.scss b/paymentsense-coding-challenge-website/src/styles.scss index 7e7239a..5603ea9 100644 --- a/paymentsense-coding-challenge-website/src/styles.scss +++ b/paymentsense-coding-challenge-website/src/styles.scss @@ -1,4 +1,63 @@ /* You can add global styles to this file, and also import other style files */ +@import '~@angular/material/theming'; +@include mat-core(); + +$default-theme-primary: mat-palette($mat-indigo); +$default-theme-accent: mat-palette($mat-grey); +$default-theme: mat-light-theme($default-theme-primary, $default-theme-accent); +@include angular-material-theme($default-theme); + +@import '~@swimlane/ngx-datatable/index.scss'; +@import '~@swimlane/ngx-datatable/themes/material.css'; +@import '~@swimlane/ngx-datatable/assets/icons.css'; html, body { height: 100%; } body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } +modal { + /* modals are hidden by default */ + display: none; + + .modal { + /* modal container fixed across whole screen */ + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + + /* z-index must be higher than .modal-background */ + z-index: 1000; + + /* enables scrolling for tall modals */ + overflow: auto; + + .modal-body { + padding: 20px; + background: #fff; + + /* margin exposes part of the modal background */ + margin: 40px; + } + } + + .modal-background { + /* modal background fixed across whole screen */ + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + + /* semi-transparent black */ + background-color: #000; + opacity: 0.75; + + /* z-index must be below .modal and above everything else */ + z-index: 900; + } +} + +body.modal-open { + /* body overflow is hidden to hide main scrollbar when modal window is open */ + overflow: hidden; +} From 0f7cb54a909d9df397fa4272a5d1d36f1532d6f8 Mon Sep 17 00:00:00 2001 From: sethisusil Date: Tue, 18 Feb 2020 09:12:38 +0530 Subject: [PATCH 2/3] Routing implementation --- .../src/app/app.component.html | 4 ++-- .../src/app/app.component.ts | 4 +++- .../src/app/app.module.ts | 7 ++++++- .../src/app/geography/geography-countrylist.component.html | 5 ++++- .../src/app/geography/geography-countrylist.component.ts | 1 + 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/paymentsense-coding-challenge-website/src/app/app.component.html b/paymentsense-coding-challenge-website/src/app/app.component.html index 788710a..1e53824 100644 --- a/paymentsense-coding-challenge-website/src/app/app.component.html +++ b/paymentsense-coding-challenge-website/src/app/app.component.html @@ -11,8 +11,8 @@

... Paymentsense Coding Challenge API is

Click on bellow button to show list of available countries

- + diff --git a/paymentsense-coding-challenge-website/src/app/app.component.ts b/paymentsense-coding-challenge-website/src/app/app.component.ts index 8c857d4..64fc9be 100644 --- a/paymentsense-coding-challenge-website/src/app/app.component.ts +++ b/paymentsense-coding-challenge-website/src/app/app.component.ts @@ -1,6 +1,7 @@ import { Component,OnInit } from '@angular/core'; import { PaymentsenseCodingChallengeApiService } from './services'; import { take } from 'rxjs/operators'; +import { Router, ActivatedRoute } from "@angular/router"; import { faThumbsUp, faThumbsDown } from '@fortawesome/free-regular-svg-icons'; import { PaymentsenseGeographyService } from './geography/services/paymentsense-geography.service'; @@ -19,7 +20,7 @@ export class AppComponent implements OnInit { public paymentsenseCodingChallengeApiActiveIconColour = 'red'; public showCountry:boolean=false; - constructor(private paymentsenseCodingChallengeApiService: PaymentsenseCodingChallengeApiService,private geographyservice:PaymentsenseGeographyService) { + constructor(private paymentsenseCodingChallengeApiService: PaymentsenseCodingChallengeApiService,private geographyservice:PaymentsenseGeographyService,private router: Router, private route: ActivatedRoute) { paymentsenseCodingChallengeApiService.getHealth().pipe(take(1)) .subscribe( apiHealth => { @@ -41,6 +42,7 @@ export class AppComponent implements OnInit { } public showCountryClick():void { + this.router.navigateByUrl('/countrylist', { relativeTo: this.route }); this.showCountry=true; } } diff --git a/paymentsense-coding-challenge-website/src/app/app.module.ts b/paymentsense-coding-challenge-website/src/app/app.module.ts index 636a359..8025dab 100644 --- a/paymentsense-coding-challenge-website/src/app/app.module.ts +++ b/paymentsense-coding-challenge-website/src/app/app.module.ts @@ -1,6 +1,7 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @@ -27,7 +28,11 @@ import { ModalService } from './modals/modal.service'; HttpClientModule, FontAwesomeModule, NgxDatatableModule, - FormsModule + FormsModule, + RouterModule.forRoot([ + // { path: '', component: AppComponent }, + { path: 'countrylist', component: LstCountryComponent } + ], { onSameUrlNavigation: 'reload' }), ], providers: [PaymentsenseCodingChallengeApiService,PaymentsenseGeographyService,ModalService], bootstrap: [AppComponent] diff --git a/paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.html b/paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.html index 19d5b59..5900f56 100644 --- a/paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.html +++ b/paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.html @@ -1,3 +1,6 @@ +
+ +

Bellow are the available country list:

@@ -81,4 +84,4 @@

{{country.name}}

- \ No newline at end of file +
\ No newline at end of file diff --git a/paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.ts b/paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.ts index 9b2a5fe..94e2f3c 100644 --- a/paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.ts +++ b/paymentsense-coding-challenge-website/src/app/geography/geography-countrylist.component.ts @@ -1,5 +1,6 @@ import { Component,OnInit } from '@angular/core'; import { take } from 'rxjs/operators'; +import { Router, ActivatedRoute } from "@angular/router"; import { faThumbsUp, faThumbsDown } from '@fortawesome/free-regular-svg-icons'; import { PaymentsenseGeographyService } from './services/paymentsense-geography.service'; import { Country } from './models/paymentsense-geography.model'; From e90121ae307c4a5e818dea3d894f60d922935071 Mon Sep 17 00:00:00 2001 From: sethisusil Date: Wed, 26 Feb 2020 23:48:17 +0530 Subject: [PATCH 3/3] Test cases --- .../Controllers/GeographicControllerTests.cs | 47 +++++++++++++++++++ ...entsense.Coding.Challenge.Api.Tests.csproj | 18 +++++++ .../appsettings.Development.json | 9 ++++ .../appsettings.json | 11 +++++ .../Paymentsense.Coding.Challenge.Api.sln | 6 +-- 5 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/Controllers/GeographicControllerTests.cs create mode 100644 paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/appsettings.Development.json create mode 100644 paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/appsettings.json diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/Controllers/GeographicControllerTests.cs b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/Controllers/GeographicControllerTests.cs new file mode 100644 index 0000000..90655c6 --- /dev/null +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/Controllers/GeographicControllerTests.cs @@ -0,0 +1,47 @@ +using FluentAssertions; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using paymentsense.geographic.business; +using paymentsense.utility; +using Paymentsense.Coding.Challenge.Api.Controllers; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Xunit; + +namespace Paymentsense.Coding.Challenge.Api.Tests.Controllers +{ + + public class GeographicControllerTests + { + private IServiceCollection services; + private IServiceProvider serviceProvider; + public GeographicControllerTests() + { + var builder = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", false, true); + var configuration = builder.Build(); + services = new ServiceCollection(); + services.UseGeoGraphicServices(); + services.AddMemoryCache(); + services.AddSingleton(configuration); + serviceProvider = services.BuildServiceProvider(); + + } + + [Fact] + public void Get_OnInvoke_ReturnsExpectedMessage() + { + var controller = new GeographicController(serviceProvider.GetRequiredService()); + + var result = controller.GetCountries().Result as OkObjectResult; + + result.StatusCode.Should().Be(StatusCodes.Status200OK); + result.Value.Should().NotBeNull(); + } + } +} diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/Paymentsense.Coding.Challenge.Api.Tests.csproj b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/Paymentsense.Coding.Challenge.Api.Tests.csproj index ba38576..d3f9ac6 100644 --- a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/Paymentsense.Coding.Challenge.Api.Tests.csproj +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/Paymentsense.Coding.Challenge.Api.Tests.csproj @@ -6,6 +6,24 @@ false + + + + + + + + PreserveNewest + true + PreserveNewest + + + PreserveNewest + true + PreserveNewest + + + diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/appsettings.Development.json b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/appsettings.Development.json new file mode 100644 index 0000000..e203e94 --- /dev/null +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/appsettings.json b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/appsettings.json new file mode 100644 index 0000000..8770d7f --- /dev/null +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/appsettings.json @@ -0,0 +1,11 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "RestGetCountryBaseUrl": "https://restcountries.eu/rest/v2/all", + "AllowedHosts": "*" +} diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.sln b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.sln index 0d7abc4..d495375 100644 --- a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.sln +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.sln @@ -7,11 +7,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Paymentsense.Coding.Challen EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Paymentsense.Coding.Challenge.Api.Tests", "Paymentsense.Coding.Challenge.Api.Tests\Paymentsense.Coding.Challenge.Api.Tests.csproj", "{29B33764-7D72-4940-90F9-28467B569288}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "paymentsense.geographic.business", "paymentsense.geographic.business\paymentsense.geographic.business.csproj", "{019F8FA6-93A7-4C67-B1F2-B94621C73375}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "paymentsense.geographic.business", "paymentsense.geographic.business\paymentsense.geographic.business.csproj", "{019F8FA6-93A7-4C67-B1F2-B94621C73375}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "paymentsense.common", "paymentsense.common\paymentsense.common.csproj", "{77EA15B9-720C-4BCA-BDF5-33911F73E179}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "paymentsense.common", "paymentsense.common\paymentsense.common.csproj", "{77EA15B9-720C-4BCA-BDF5-33911F73E179}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "paymentsense.utility", "paymentsense.utility\paymentsense.utility.csproj", "{FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "paymentsense.utility", "paymentsense.utility\paymentsense.utility.csproj", "{FAC3A7F9-3FC6-42CE-9658-2436A4D643E4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution