diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/Controllers/PaymentsenseCodingChallengeControllerTests.cs b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/Controllers/PaymentsenseCodingChallengeControllerTests.cs index 9f33c41..259e2c2 100644 --- a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/Controllers/PaymentsenseCodingChallengeControllerTests.cs +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api.Tests/Controllers/PaymentsenseCodingChallengeControllerTests.cs @@ -1,7 +1,17 @@ -using FluentAssertions; +using System; +using System.Net; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using FluentAssertions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Moq; +using Moq.Protected; using Paymentsense.Coding.Challenge.Api.Controllers; +using Paymentsense.Coding.Challenge.Api.Interfaces; +using Paymentsense.Coding.Challenge.Api.Services; using Xunit; namespace Paymentsense.Coding.Challenge.Api.Tests.Controllers @@ -11,12 +21,62 @@ public class PaymentsenseCodingChallengeControllerTests [Fact] public void Get_OnInvoke_ReturnsExpectedMessage() { - var controller = new PaymentsenseCodingChallengeController(); + var countryRepoServiceMock = new Mock(); + var controller = new PaymentsenseCodingChallengeController(countryRepoServiceMock.Object); var result = controller.Get().Result as OkObjectResult; result.StatusCode.Should().Be(StatusCodes.Status200OK); result.Value.Should().Be("Paymentsense Coding Challenge!"); } + + [Fact] + public void CountryList_MissingDataSource_ReturnsErrorMessage() + { + // Mock configuration to return wrong config key + var configurationMock = new Mock(); + var configurationSection = new Mock(); + configurationSection.Setup(a => a.Value).Returns("testvalue"); + configurationMock.Setup(a => a.GetSection("TestValueKey")).Returns(configurationSection.Object); + + var httpClientFactoryMock = new Mock(); + var countryRepoService = new CountryDataProvider(httpClientFactoryMock.Object, configurationMock.Object); + var controller = new PaymentsenseCodingChallengeController(countryRepoService); + + Assert.ThrowsAsync(() => controller.CountryList()); + } + + [Fact] + public async Task CountryList_WrongDataSource_ReturnsNullMessage() + { + // Mock configuration to return wrong data source url + var configurationMock = new Mock(); + var configurationSection = new Mock(); + configurationSection.Setup(a => a.Value).Returns("test123"); + configurationMock.Setup(a => a.GetSection("DataSource")).Returns(configurationSection.Object); + + var httpClientFactoryMock = new Mock(); + var mockHttpMessageHandlerMock = new Mock(); + + mockHttpMessageHandlerMock.Protected() + .Setup>("SendAsync", ItExpr.IsAny(), + ItExpr.IsAny()) + .ReturnsAsync(new HttpResponseMessage + { + StatusCode = HttpStatusCode.NotFound, + }); + + var client = new HttpClient(mockHttpMessageHandlerMock.Object) + { + BaseAddress = new Uri("https://restcountries.eu/rest/v2/all"), + }; + httpClientFactoryMock.Setup(_ => _.CreateClient(It.IsAny())).Returns(client); + + var countryRepoService = new CountryDataProvider(httpClientFactoryMock.Object, configurationMock.Object); + var controller = new PaymentsenseCodingChallengeController(countryRepoService); + + var result = await controller.CountryList() as ObjectResult; + Assert.Null(result.Value); + } } } 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..137b9e7 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 @@ -10,6 +10,7 @@ + all diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Controllers/PaymentsenseCodingChallengeController.cs b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Controllers/PaymentsenseCodingChallengeController.cs index d7ced3c..033a2db 100644 --- a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Controllers/PaymentsenseCodingChallengeController.cs +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Controllers/PaymentsenseCodingChallengeController.cs @@ -1,4 +1,7 @@ -using Microsoft.AspNetCore.Mvc; +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Paymentsense.Coding.Challenge.Api.Interfaces; namespace Paymentsense.Coding.Challenge.Api.Controllers { @@ -6,10 +9,26 @@ namespace Paymentsense.Coding.Challenge.Api.Controllers [Route("[controller]")] public class PaymentsenseCodingChallengeController : ControllerBase { + public ICountryDataProvider _countryRepositoryService { get; } + + public PaymentsenseCodingChallengeController(ICountryDataProvider countryRepositoryService) + { + _countryRepositoryService = countryRepositoryService; + } + [HttpGet] public ActionResult Get() { return Ok("Paymentsense Coding Challenge!"); } + + [ResponseCache(Duration = int.MaxValue)] + [Route("countries/list")] + [HttpGet] + public async Task CountryList() + { + var list = await _countryRepositoryService.GetCountryList(); + return Ok(list); + } } } diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Interfaces/ICountryDataProvider.cs b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Interfaces/ICountryDataProvider.cs new file mode 100644 index 0000000..e0dc54d --- /dev/null +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Interfaces/ICountryDataProvider.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using Paymentsense.Coding.Challenge.Api.Models; + +namespace Paymentsense.Coding.Challenge.Api.Interfaces +{ + public interface ICountryDataProvider + { + Task GetCountryList(); + } +} diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Models/Country.cs b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Models/Country.cs new file mode 100644 index 0000000..32d4270 --- /dev/null +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Models/Country.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; + +namespace Paymentsense.Coding.Challenge.Api.Models +{ + public class Country + { + public string Name { get; set; } + public string Flag { get; set; } + public int Population { get; set; } + public List Timezones { get; set; } + public List Currencies { get; set; } + public List Languages { get; set; } + public string Capital { get; set; } + } + + public class Currency + { + public string Code { get; set; } + public string Name { get; set; } + public string Symbol { get; set; } + } + + 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.Coding.Challenge.Api/Paymentsense.Coding.Challenge.Api.csproj b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Paymentsense.Coding.Challenge.Api.csproj index 1d82fb7..bdce095 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 @@ -6,8 +6,7 @@ - - + diff --git a/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Services/CountryDataProvider.cs b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Services/CountryDataProvider.cs new file mode 100644 index 0000000..d9d6817 --- /dev/null +++ b/paymentsense-coding-challenge-api/Paymentsense.Coding.Challenge.Api/Services/CountryDataProvider.cs @@ -0,0 +1,43 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Newtonsoft.Json; +using Paymentsense.Coding.Challenge.Api.Interfaces; +using Paymentsense.Coding.Challenge.Api.Models; + +namespace Paymentsense.Coding.Challenge.Api.Services +{ + public class CountryDataProvider : ICountryDataProvider + { + private readonly IHttpClientFactory _clientFactory; + private readonly IConfiguration _configuration; + + public CountryDataProvider(IHttpClientFactory clientFactory, IConfiguration configuration) + { + _clientFactory = clientFactory; + _configuration = configuration; + } + + public async Task GetCountryList() + { + // Get country data source url from config + var sourceUrl = _configuration.GetValue("DataSource"); + if (string.IsNullOrEmpty(sourceUrl)) + { + throw new ApplicationException("Country data source url missing in configuration file"); + } + + // Make call to fetch country list + var client = _clientFactory.CreateClient(); + var response = await client.GetAsync(sourceUrl); + if (response != null && response.IsSuccessStatusCode) + { + var content = await response.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject(content); + } + + return null; + } + } +} 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..0adb0bb 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,8 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Paymentsense.Coding.Challenge.Api.Interfaces; +using Paymentsense.Coding.Challenge.Api.Services; namespace Paymentsense.Coding.Challenge.Api { @@ -29,6 +31,13 @@ public void ConfigureServices(IServiceCollection services) .AllowAnyHeader(); }); }); + + // Register country data provider + services.AddScoped(); + services.AddHttpClient(); + + // Enable response caching + services.AddResponseCaching(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -52,6 +61,9 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) endpoints.MapControllers(); endpoints.MapHealthChecks("/health"); }); + + // Activate response caching middleware + app.UseResponseCaching(); } } } 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..00d6432 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" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "DataSource": "https://restcountries.eu/rest/v2/all" } diff --git a/paymentsense-coding-challenge-website/src/app/app.component.html b/paymentsense-coding-challenge-website/src/app/app.component.html index 9201572..b5926f9 100644 --- a/paymentsense-coding-challenge-website/src/app/app.component.html +++ b/paymentsense-coding-challenge-website/src/app/app.component.html @@ -1,11 +1,27 @@ -
- Paymentsense Logo +
+ Paymentsense Logo

{{ title }}

-

... Paymentsense Coding Challenge API is ...

+

+ ... Paymentsense Coding Challenge API is + + ... +

+ +
+
diff --git a/paymentsense-coding-challenge-website/src/app/app.component.spec.ts b/paymentsense-coding-challenge-website/src/app/app.component.spec.ts index 1a932fc..1be9b82 100644 --- a/paymentsense-coding-challenge-website/src/app/app.component.spec.ts +++ b/paymentsense-coding-challenge-website/src/app/app.component.spec.ts @@ -1,27 +1,35 @@ -import { TestBed, async } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { AppComponent } from './app.component'; -import { PaymentsenseCodingChallengeApiService } from './services'; -import { MockPaymentsenseCodingChallengeApiService } from './testing/mock-paymentsense-coding-challenge-api.service'; -import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { TestBed, async } from "@angular/core/testing"; +import { RouterTestingModule } from "@angular/router/testing"; +import { AppComponent } from "./app.component"; +import { PaymentsenseCodingChallengeApiService } from "./services"; +import { MockPaymentsenseCodingChallengeApiService } from "./testing/mock-paymentsense-coding-challenge-api.service"; +import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; +import { CountryListComponent } from "./country-list/country-list.component"; +import { MatTableModule } from "@angular/material/table"; +import { MatPaginatorModule } from "@angular/material/paginator"; +import { HttpClientModule } from "@angular/common/http"; -describe('AppComponent', () => { +describe("AppComponent", () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ RouterTestingModule, - FontAwesomeModule - ], - declarations: [ - AppComponent + FontAwesomeModule, + MatTableModule, + MatPaginatorModule, + HttpClientModule, ], + declarations: [AppComponent, CountryListComponent], providers: [ - { provide: PaymentsenseCodingChallengeApiService, useClass: MockPaymentsenseCodingChallengeApiService } - ] + { + provide: PaymentsenseCodingChallengeApiService, + useClass: MockPaymentsenseCodingChallengeApiService, + }, + ], }).compileComponents(); })); - it('should create the app', () => { + it("should create the app", () => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.debugElement.componentInstance; expect(app).toBeTruthy(); @@ -30,13 +38,15 @@ describe('AppComponent', () => { it(`should have as title 'Paymentsense Coding Challenge'`, () => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.debugElement.componentInstance; - expect(app.title).toEqual('Paymentsense Coding Challenge!'); + expect(app.title).toEqual("Paymentsense Coding Challenge!"); }); - it('should render title in a h1 tag', () => { + it("should render title in a h1 tag", () => { const fixture = TestBed.createComponent(AppComponent); fixture.detectChanges(); const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain('Paymentsense Coding Challenge!'); + expect(compiled.querySelector("h1").textContent).toContain( + "Paymentsense Coding Challenge!" + ); }); }); diff --git a/paymentsense-coding-challenge-website/src/app/app.module.ts b/paymentsense-coding-challenge-website/src/app/app.module.ts index 77745c5..2b21184 100644 --- a/paymentsense-coding-challenge-website/src/app/app.module.ts +++ b/paymentsense-coding-challenge-website/src/app/app.module.ts @@ -1,25 +1,32 @@ -import { BrowserModule } from '@angular/platform-browser'; -import { NgModule } from '@angular/core'; +import { BrowserModule } from "@angular/platform-browser"; +import { NgModule } from "@angular/core"; -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { PaymentsenseCodingChallengeApiService } from './services'; -import { HttpClientModule } from '@angular/common/http'; -import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { AppRoutingModule } from "./app-routing.module"; +import { AppComponent } from "./app.component"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { PaymentsenseCodingChallengeApiService } from "./services"; +import { HttpClientModule } from "@angular/common/http"; +import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; +import { CountryListComponent } from "./country-list/country-list.component"; +import { CountryDataProviderService } from "./services/country-data-provider.service"; +import { MatTableModule } from "@angular/material/table"; +import { MatPaginatorModule } from "@angular/material/paginator"; @NgModule({ - declarations: [ - AppComponent - ], + declarations: [AppComponent, CountryListComponent], imports: [ BrowserModule, AppRoutingModule, BrowserAnimationsModule, HttpClientModule, - FontAwesomeModule + FontAwesomeModule, + MatTableModule, + MatPaginatorModule, + ], + providers: [ + PaymentsenseCodingChallengeApiService, + CountryDataProviderService, ], - providers: [PaymentsenseCodingChallengeApiService], - bootstrap: [AppComponent] + bootstrap: [AppComponent], }) -export class AppModule { } +export class AppModule {} diff --git a/paymentsense-coding-challenge-website/src/app/country-list/country-list.component.html b/paymentsense-coding-challenge-website/src/app/country-list/country-list.component.html new file mode 100644 index 0000000..f6361ed --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/country-list/country-list.component.html @@ -0,0 +1,73 @@ +
+
+

Loading...

+
+
+
+
+
+

No country found

+
+
+
+ + + + + + + + + + + + + + + + + + + + +
Flag + flag + Name{{ element.name }} +
+
+ Population: {{ element.population }} + Timezones: {{ element.timezones?.join() }} + Currencies: + {{ getCurrencies(element.currencies) }} + Languages: + {{ getLanguages(element.languages) }} Capital: + {{ element.capital }} +
+
+
+ +
+
diff --git a/paymentsense-coding-challenge-website/src/app/country-list/country-list.component.scss b/paymentsense-coding-challenge-website/src/app/country-list/country-list.component.scss new file mode 100644 index 0000000..a783c10 --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/country-list/country-list.component.scss @@ -0,0 +1,24 @@ +table { + width: 100%; +} + +tr.country-detail-row { + height: 0; +} + +tr.country-element-row:not(.country-expanded-row):hover { + background: whitesmoke; +} + +tr.country-element-row:not(.country-expanded-row):active { + background: #efefef; +} + +.country-element-row td { + border-bottom-width: 0; +} + +.country-element-detail { + overflow: hidden; + display: flex; +} diff --git a/paymentsense-coding-challenge-website/src/app/country-list/country-list.component.spec.ts b/paymentsense-coding-challenge-website/src/app/country-list/country-list.component.spec.ts new file mode 100644 index 0000000..6bd374c --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/country-list/country-list.component.spec.ts @@ -0,0 +1,35 @@ +import { async, ComponentFixture, TestBed } from "@angular/core/testing"; +import { CountryListComponent } from "./country-list.component"; +import { RouterTestingModule } from "@angular/router/testing"; +import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; +import { MatTableModule } from "@angular/material/table"; +import { MatPaginatorModule } from "@angular/material/paginator"; +import { HttpClientModule } from "@angular/common/http"; + +describe("CountryListComponent", () => { + let component: CountryListComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + RouterTestingModule, + FontAwesomeModule, + MatTableModule, + MatPaginatorModule, + HttpClientModule, + ], + declarations: [CountryListComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CountryListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/paymentsense-coding-challenge-website/src/app/country-list/country-list.component.ts b/paymentsense-coding-challenge-website/src/app/country-list/country-list.component.ts new file mode 100644 index 0000000..105e0dd --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/country-list/country-list.component.ts @@ -0,0 +1,80 @@ +import { CountryDataProviderService } from "./../services/country-data-provider.service"; +import { Component, OnInit, ViewChild } from "@angular/core"; +import { Country } from "../models/country"; +import { Subject, of } from "rxjs"; +import { takeUntil, tap, catchError, finalize } from "rxjs/operators"; +import { MatPaginator } from "@angular/material/paginator"; +import { MatTableDataSource } from "@angular/material/table"; +import { + animate, + state, + style, + transition, + trigger, +} from "@angular/animations"; +import { Currency } from "../models/currency"; +import { Language } from "../models/language"; + +@Component({ + selector: "country-list", + templateUrl: "./country-list.component.html", + styleUrls: ["./country-list.component.scss"], + animations: [ + trigger("detailExpand", [ + state("collapsed", style({ height: "0px", minHeight: "0" })), + state("expanded", style({ height: "*" })), + transition( + "expanded <=> collapsed", + animate("225ms cubic-bezier(0.4, 0.0, 0.2, 1)") + ), + ]), + ], +}) +export class CountryListComponent implements OnInit { + public countryList: any; + public columnsToDisplay: string[] = ["flag", "name"]; + public loading = false; + private unsubscribe$ = new Subject(); + @ViewChild(MatPaginator, { static: false }) set matPaginator( + paginator: MatPaginator + ) { + if (this.countryList) { + this.countryList.paginator = paginator; + } + } + expandedElement: Country | null; + + constructor(private countryDataProviderService: CountryDataProviderService) {} + + ngOnInit(): void { + this.getCountryList(); + } + + getCountryList() { + this.loading = true; + this.countryDataProviderService + .getCountryList() + .pipe( + takeUntil(this.unsubscribe$), + tap((data: Country[]) => { + this.countryList = new MatTableDataSource(data); + }), + catchError((error: any) => { + console.error(error); + return of(); + }), + finalize(() => { + this.loading = false; + }) + ) + .subscribe(); + } + + getCurrencies(currencies: Currency[]): string { + return currencies.map((c) => c.name).join(","); + } + + getLanguages(languages: Language[]): string { + return languages.map((l) => l.name).join(","); + } +} diff --git a/paymentsense-coding-challenge-website/src/app/models/country.ts b/paymentsense-coding-challenge-website/src/app/models/country.ts new file mode 100644 index 0000000..e27b232 --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/models/country.ts @@ -0,0 +1,12 @@ +import { Currency } from "./currency"; +import { Language } from "./language"; + +export class Country { + name: string; + flag: string; + population: number; + timezones: string[]; + currencies: Currency[]; + languages: Language[]; + capital: string; +} diff --git a/paymentsense-coding-challenge-website/src/app/models/currency.ts b/paymentsense-coding-challenge-website/src/app/models/currency.ts new file mode 100644 index 0000000..16e6bca --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/models/currency.ts @@ -0,0 +1,5 @@ +export class Currency { + code: string; + name: string; + symbol: string; +} diff --git a/paymentsense-coding-challenge-website/src/app/models/language.ts b/paymentsense-coding-challenge-website/src/app/models/language.ts new file mode 100644 index 0000000..1933ede --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/models/language.ts @@ -0,0 +1,6 @@ +export class Language { + iso639_1: string; + iso639_2: string; + name: string; + nativeName: string; +} diff --git a/paymentsense-coding-challenge-website/src/app/services/country-data-provider.service.ts b/paymentsense-coding-challenge-website/src/app/services/country-data-provider.service.ts new file mode 100644 index 0000000..a40b895 --- /dev/null +++ b/paymentsense-coding-challenge-website/src/app/services/country-data-provider.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from "@angular/core"; +import { Observable } from "rxjs"; +import { HttpClient } from "@angular/common/http"; +import { map } from "rxjs/operators"; +import { Country } from "../models/country"; + +@Injectable({ + providedIn: "root", +}) +export class CountryDataProviderService { + constructor(private httpClient: HttpClient) {} + + public getCountryList(): Observable { + return this.httpClient + .get("https://localhost:44339/PaymentsenseCodingChallenge/countries/list") + .pipe(map((data: any) => data)); + } +} diff --git a/paymentsense-coding-challenge-website/src/app/services/index.ts b/paymentsense-coding-challenge-website/src/app/services/index.ts index d1f65b8..06b9c7a 100644 --- a/paymentsense-coding-challenge-website/src/app/services/index.ts +++ b/paymentsense-coding-challenge-website/src/app/services/index.ts @@ -1 +1,2 @@ -export * from './paymentsense-coding-challenge-api.service'; +export * from "./paymentsense-coding-challenge-api.service"; +export * from "./country-data-provider.service"; 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..66d7621 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:44339/health', { responseType: 'text' }); } }