From bb9ddcc335d6f216b49791a59ba2c118b25b627f Mon Sep 17 00:00:00 2001 From: cada69 <34744773+cada69@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:14:39 +0100 Subject: [PATCH 1/6] Davide Capuccio Davide Capuccio --- .vscode/launch.json | 35 ++++++ .vscode/tasks.json | 41 +++++++ TestDB/Data/SeedData.sql | 2 +- TestDB/Stored Procedures/usp_movecase.sql | 139 ++++++++++++++++------ 4 files changed, 180 insertions(+), 37 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e9b2fcf --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,35 @@ +{ + "version": "0.2.0", + "configurations": [ + { + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md. + "name": ".NET Core Launch (web)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/TestAPI/bin/Debug/net5.0/TestAPI.dll", + "args": [], + "cwd": "${workspaceFolder}/TestAPI", + "stopAtEntry": false, + // Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser + "serverReadyAction": { + "action": "openExternally", + "pattern": "\\bNow listening on:\\s+(https?://\\S+)" + }, + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "sourceFileMap": { + "/Views": "${workspaceFolder}/Views" + } + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..ad45275 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,41 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/TestAPI.sln", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary;ForceNoAlign" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/TestAPI.sln", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary;ForceNoAlign" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "--project", + "${workspaceFolder}/TestAPI.sln" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/TestDB/Data/SeedData.sql b/TestDB/Data/SeedData.sql index eef574e..f9a879a 100644 --- a/TestDB/Data/SeedData.sql +++ b/TestDB/Data/SeedData.sql @@ -16,7 +16,7 @@ VALUES('1de2e437-f16a-4c1a-84b4-3cfc63310eca', '9a03fc4b-37af-4560-8923-7657e804 ('35bf4e4a-94b9-46b0-b9ea-ed92bff095a3', '844b12ea-f822-4223-9011-6f4d8b6367a1', 'c8b50ee6-f09d-451f-b7e2-53193c8f6839'), ('9873fba8-276e-4b13-92f3-1ea2255b1c16', '8cd9d41a-33a7-4df3-9eb2-6d1d7aca20d1', 'c8b50ee6-f09d-451f-b7e2-53193c8f6839'), - ('9873fba8-276e-4b13-92f3-1ea2255b1c16', '8cd9d41a-33a7-4df3-9eb2-6d1d7aca20d1', 'cf1b257a-99b0-4abe-9428-983295073b14') + ('9873fba8-276e-4b13-92f3-1ea2255b1c17', '8cd9d41a-33a7-4df3-9eb2-6d1d7aca20d1', 'cf1b257a-99b0-4abe-9428-983295073b14') INSERT INTO [dbo].[pallet] ([guid]) diff --git a/TestDB/Stored Procedures/usp_movecase.sql b/TestDB/Stored Procedures/usp_movecase.sql index ea3452f..8a3bc25 100644 --- a/TestDB/Stored Procedures/usp_movecase.sql +++ b/TestDB/Stored Procedures/usp_movecase.sql @@ -1,39 +1,106 @@ -CREATE PROCEDURE [dbo].[usp_movecase] - @casetomove UNIQUEIDENTIFIER +CREATE PROCEDURE [dbo].[usp_movecase] @casetomove UNIQUEIDENTIFIER WITH ENCRYPTION AS BEGIN - SET NOCOUNT ON; - - DECLARE @Result AS INT = 0 - DECLARE @_errormessage NVARCHAR(MAX) - - BEGIN TRANSACTION - BEGIN TRY - - PRINT 'your code goes here' - - END TRY - BEGIN CATCH - SET @Result = -1 - - SELECT @_errormessage = ERROR_MESSAGE() - - END CATCH - - IF (@@TRANCOUNT > 0) - BEGIN - IF (@Result >= 0) - BEGIN - COMMIT TRANSACTION - PRINT 'Commited Transaction at ' + GETDATE() - END - ELSE - BEGIN - ROLLBACK TRANSACTION - PRINT 'Rolled back Transaction at ' + GETDATE() + 'because of error: ' + @_errormessage - END - END - - RETURN @Result -END \ No newline at end of file + SET NOCOUNT ON; + + DECLARE @Result AS INT = 0 + DECLARE @_errormessage NVARCHAR(MAX) + + BEGIN TRANSACTION + + BEGIN TRY + DECLARE @caseproductgui UNIQUEIDENTIFIER = NULL; + DECLARE @casepalletguid UNIQUEIDENTIFIER = NULL; + DECLARE @casenewpalletguid UNIQUEIDENTIFIER = NULL; + DECLARE @newcasetomove UNIQUEIDENTIFIER = NULL; + + -- check if case id is in the DB + IF EXISTS ( + SELECT * + FROM [case] + WHERE [guid] = @casetomove + ) + BEGIN + -- case exists in [case] db, proceed mooving the case & + -- get case product id + -- get pallet id + -- for this record + SELECT @casepalletguid = palletguid + ,@caseproductgui = productguid + FROM [case] + WHERE [guid] = @casetomove; + + -- check if there is a pallet in the DB that stacks cases with + -- same product ID as @casetomove, not the same of @casetomove pallet id + IF EXISTS ( + SELECT * + FROM [case] + WHERE productguid = @caseproductgui + AND [guid] <> @casetomove + AND palletguid <> @casepalletguid + ) + BEGIN + -- yes there is, get the new pallet id @casetomove has to move to + SELECT @casenewpalletguid = palletguid + FROM [case] + WHERE productguid = @caseproductgui + AND [guid] <> @casetomove + AND palletguid <> @casepalletguid + + -- update new pallet id for @casetomove + UPDATE [case] + SET palletguid = @casenewpalletguid + WHERE [guid] = @casetomove + + -- if the new pallet contains case with prod id different from @casetomove, try to move + -- these cases to a different pallet containing same prod ids + IF EXISTS ( + SELECT * + FROM [case] + WHERE palletguid = @casenewpalletguid + AND productguid <> @caseproductgui + ) + BEGIN + -- yes, there is, get this new case id + SELECT TOP 1 @newcasetomove = [guid] + FROM [case] + WHERE palletguid = @casenewpalletguid + AND productguid <> @caseproductgui + + -- just simply recall this procedure with new case id to move as parameter + EXEC [dbo].[usp_movecase] @newcasetomove + + END + END + ELSE + PRINT 'No pallet with the same product ID of ' + cast(@casetomove AS VARCHAR(64)) + ' available' + END + ELSE + PRINT 'case id provided [' + cast(@casetomove AS VARCHAR(64)) + '] does not exists' + END TRY + + BEGIN CATCH + SET @Result = - 1 + + SELECT @_errormessage = ERROR_MESSAGE() + END CATCH + + IF (@@TRANCOUNT > 0) + BEGIN + IF (@Result >= 0) + BEGIN + COMMIT TRANSACTION + + PRINT 'Commited Transaction at ' + cast(GETDATE() AS VARCHAR(30)) + END + ELSE + BEGIN + ROLLBACK TRANSACTION + + PRINT 'Rolled back Transaction at ' + cast(GETDATE() AS VARCHAR(30)) + 'because of error: ' + @_errormessage + END + END + + RETURN @Result +END From 58eb477d5e3e8477de6940ea67c5a2875d56004f Mon Sep 17 00:00:00 2001 From: cada69 <34744773+cada69@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:29:02 +0100 Subject: [PATCH 2/6] Davide Capuccio TestUI --- TestUI/src/app/app.component.html | 7 ++- TestUI/src/app/app.component.scss | 4 ++ TestUI/src/app/app.component.spec.ts | 61 +++++++++++++++++++++++++- TestUI/src/app/app.component.ts | 36 ++++++++++++++- TestUI/src/app/weatherapp.swagger.ts | 9 +++- TestUI/src/environments/environment.ts | 2 +- 6 files changed, 111 insertions(+), 8 deletions(-) diff --git a/TestUI/src/app/app.component.html b/TestUI/src/app/app.component.html index 56bba0c..de68919 100644 --- a/TestUI/src/app/app.component.html +++ b/TestUI/src/app/app.component.html @@ -1,12 +1,15 @@
+
TestUI app is running!
+
-
{{weather.date}}
+
{{weather.date| date: 'dd/MM/yyyy'}}
{{weather.temperatureF}} °F
{{weather.temperatureC}} °C
-

{{weather.summary}}

+

{{weather.summary}}

+
diff --git a/TestUI/src/app/app.component.scss b/TestUI/src/app/app.component.scss index 64a2c06..1a355c4 100644 --- a/TestUI/src/app/app.component.scss +++ b/TestUI/src/app/app.component.scss @@ -1,3 +1,7 @@ .card { top: 1rem; } + +.content{ + text-align: center; +} diff --git a/TestUI/src/app/app.component.spec.ts b/TestUI/src/app/app.component.spec.ts index 0254631..b5ef401 100644 --- a/TestUI/src/app/app.component.spec.ts +++ b/TestUI/src/app/app.component.spec.ts @@ -1,17 +1,38 @@ import { TestBed } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { AppComponent } from './app.component'; +import { Client, WeatherForecast } from './weatherapp.swagger'; +import { HttpClient, HttpErrorResponse } from '@angular/common/http'; + + + describe('AppComponent', () => { + + let httpClient: HttpClientTestingModule; + let httpTestingController: HttpTestingController; + let wheaterservice: Client; + beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ - RouterTestingModule + RouterTestingModule, + HttpClientTestingModule, ], + providers: [Client], declarations: [ AppComponent + ], }).compileComponents(); + + // Inject the http, test controller, and service-under-test + // as they will be referenced by each test. + httpClient = TestBed.inject(HttpClient); + httpTestingController = TestBed.inject(HttpTestingController); + wheaterservice = TestBed.inject(Client); + }); it('should create the app', () => { @@ -32,4 +53,42 @@ describe('AppComponent', () => { const compiled = fixture.nativeElement as HTMLElement; expect(compiled.querySelector('.content span')?.textContent).toContain('TestUI app is running!'); }); + + // test web service + it('should get WS data and expect record lenght to be 30', () => { + + + const response: WeatherForecast[] = [ + + // { + // //"date": "2023-11-20T00:00:00", + // "temperatureC": -12, + // "temperatureF": 11, + // "summary": "Freezing" + // } + + + + ]; + + wheaterservice.unauthenticated().subscribe((res) => { + + expect(res).toEqual(response); + + + + }); + + const req = httpTestingController.expectOne({ + method: 'GET', + url: wheaterservice.getBaseUrl() + '/WeatherForecast/unauthenticated/?days=1', + }); + + req.flush(response); + + + }) + + + }); diff --git a/TestUI/src/app/app.component.ts b/TestUI/src/app/app.component.ts index 12ba596..34a6b41 100644 --- a/TestUI/src/app/app.component.ts +++ b/TestUI/src/app/app.component.ts @@ -1,6 +1,8 @@ import {Component} from '@angular/core'; import {Client, WeatherForecast} from "./weatherapp.swagger"; +//import { DatePipe, formatDate } from '@angular/common'; + @Component({ selector: 'app-root', templateUrl: './app.component.html', @@ -10,6 +12,8 @@ import {Client, WeatherForecast} from "./weatherapp.swagger"; export class AppComponent { weatherData: WeatherForecast[] = []; + title: string = "TestUI"; + constructor( private client: Client ) { @@ -27,12 +31,40 @@ export class AppComponent { error: (error) => { this.handleError(error); }, - next: (data: WeatherForecast[]) => { - this.weatherData = data; + next: + (data: WeatherForecast[]) => { + this.weatherData = data; + } }) } + + + + getColor(summary: any){ + switch(summary){ + case "Freezing": + case "Bracing": + case "Chilly": + return "cyan"; + case "Mild": + case "Balmy": + case "Cool": + return "green"; + case "Warm": + case "Hot": + return "orange"; + case "Sweltering": + case "Scorching": + return "red"; + default: + return "black"; + + } + + + } /** * Dummy Error Handler diff --git a/TestUI/src/app/weatherapp.swagger.ts b/TestUI/src/app/weatherapp.swagger.ts index 8984d7e..6c84e25 100644 --- a/TestUI/src/app/weatherapp.swagger.ts +++ b/TestUI/src/app/weatherapp.swagger.ts @@ -26,11 +26,16 @@ export class Client { this.baseUrl = baseUrl !== undefined && baseUrl !== null ? baseUrl : ""; } + getBaseUrl():string{ + + return this.baseUrl; + } + /** * @return Success */ weatherForecast(): Observable { - let url_ = this.baseUrl + "/WeatherForecast"; + let url_ = this.baseUrl + "/WeatherForecast/unauthenticated/?days=1"; // this.baseUrl + "/WeatherForecast"; url_ = url_.replace(/[?&]$/, ""); let options_ : any = { @@ -80,7 +85,7 @@ export class Client { * @return Success */ unauthenticated(): Observable { - let url_ = this.baseUrl + "/WeatherForecast/unauthenticated"; + let url_ = this.baseUrl + "/WeatherForecast/unauthenticated/?days=1"; url_ = url_.replace(/[?&]$/, ""); let options_ : any = { diff --git a/TestUI/src/environments/environment.ts b/TestUI/src/environments/environment.ts index 12ba3e4..05727ae 100644 --- a/TestUI/src/environments/environment.ts +++ b/TestUI/src/environments/environment.ts @@ -4,7 +4,7 @@ export const environment = { production: false, - url:'https://localhost:5001' + url:'http://localhost:5100' }; /* From 539fc01a6077202b0a0a6bd981c7978f014afad8 Mon Sep 17 00:00:00 2001 From: cada69 <34744773+cada69@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:36:26 +0100 Subject: [PATCH 3/6] Davide Capuccio TestApi xUnit tests --- TestAPI.sln | 11 +++ TestApi.xUnitTest/TestApi.xUnitTest.csproj | 30 ++++++ TestApi.xUnitTest/Usings.cs | 1 + .../WhaterForecastControllerXTest.cs | 93 +++++++++++++++++++ 4 files changed, 135 insertions(+) create mode 100644 TestApi.xUnitTest/TestApi.xUnitTest.csproj create mode 100644 TestApi.xUnitTest/Usings.cs create mode 100644 TestApi.xUnitTest/WhaterForecastControllerXTest.cs diff --git a/TestAPI.sln b/TestAPI.sln index 19a1031..424ea35 100644 --- a/TestAPI.sln +++ b/TestAPI.sln @@ -12,6 +12,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Readme.md = Readme.md EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{E44E3154-6770-45E0-BA16-AE1291B71BD3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApi.xUnitTest", "TestApi.xUnitTest\TestApi.xUnitTest.csproj", "{50BA1259-845C-4BF3-88E1-782DEE076DD0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -28,10 +32,17 @@ Global {A720BF0D-868C-404E-9A87-410694A01C6F}.Release|Any CPU.ActiveCfg = Release|Any CPU {A720BF0D-868C-404E-9A87-410694A01C6F}.Release|Any CPU.Build.0 = Release|Any CPU {A720BF0D-868C-404E-9A87-410694A01C6F}.Release|Any CPU.Deploy.0 = Release|Any CPU + {50BA1259-845C-4BF3-88E1-782DEE076DD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {50BA1259-845C-4BF3-88E1-782DEE076DD0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {50BA1259-845C-4BF3-88E1-782DEE076DD0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {50BA1259-845C-4BF3-88E1-782DEE076DD0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {50BA1259-845C-4BF3-88E1-782DEE076DD0} = {E44E3154-6770-45E0-BA16-AE1291B71BD3} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3A5247-53B1-4545-B0E1-9197A1BF6562} EndGlobalSection diff --git a/TestApi.xUnitTest/TestApi.xUnitTest.csproj b/TestApi.xUnitTest/TestApi.xUnitTest.csproj new file mode 100644 index 0000000..1f0a02f --- /dev/null +++ b/TestApi.xUnitTest/TestApi.xUnitTest.csproj @@ -0,0 +1,30 @@ + + + + net7.0 + enable + enable + + false + true + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/TestApi.xUnitTest/Usings.cs b/TestApi.xUnitTest/Usings.cs new file mode 100644 index 0000000..8c927eb --- /dev/null +++ b/TestApi.xUnitTest/Usings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/TestApi.xUnitTest/WhaterForecastControllerXTest.cs b/TestApi.xUnitTest/WhaterForecastControllerXTest.cs new file mode 100644 index 0000000..35900a0 --- /dev/null +++ b/TestApi.xUnitTest/WhaterForecastControllerXTest.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using TestAPI.Models; +using TestAPI; +using Microsoft.AspNetCore.Mvc.Testing; + +namespace TestApi.xUnitTest +{ + public class WhaterForecastControllerXTest : IClassFixture> + { + // common chhtp client instance + readonly HttpClient _client; + + + public WhaterForecastControllerXTest(WebApplicationFactory application) + { + // assing httpclient instance + _client = application.CreateClient(); + } + + // test to check response is OK from Api WebForecast + [Fact] + public async Task CheckIfReturnsOk() + { + // fetch api WebForecast & get a response + var response = await _client.GetAsync("http://localhost:5100/WeatherForecast/unauthenticated"); + + response.EnsureSuccessStatusCode(); + // do the test + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + } + + // test to check if Api response is Ok and returns n days ahead forecast + [Theory] + [InlineData(3)] // parametric test + public async Task CheckIfWFreturnsnDaysAhead(int days) + { + + + // fetch api WebForecast & get a response + var response = await _client.GetAsync(string.Format("http://localhost:5100/WeatherForecast/unauthenticated/?days={0}", days)); + + response.EnsureSuccessStatusCode(); + + //deserialize response to a IEnumerable Wheaterforecast object + var record = Newtonsoft.Json.JsonConvert.DeserializeObject>(await response.Content.ReadAsStringAsync()); + + // do the test + Assert.True(record != null && record.Count() == days); + + } + // test to check if Api WebForecasts response time is less than a spcific thresold + [Fact] + public async Task CheckIfWFApiResponseIsLessThen1mSec() + { + // initialze a stopWatch object + var _stopWatch = new System.Diagnostics.Stopwatch(); + _stopWatch.Start(); + // fetch api WebForecast & get a response + var response = await _client.GetAsync("http://localhost:5100/WeatherForecast/unauthenticated/?days=1"); + response.EnsureSuccessStatusCode(); + // stop the stop watch + _stopWatch.Stop(); + // do the test + Assert.True(_stopWatch.ElapsedMilliseconds < 1000, $"Elapsed time: {_stopWatch.ElapsedMilliseconds} mSecs. "); + + } + + // check if datas returned from Api WheaterForecast are consistent + [Fact] + public async Task CheckIfresponseDataRConsistent() + { + + // fetch api WebForecast & get a response + var response = await _client.GetAsync("http://localhost:5100/WeatherForecast/unauthenticated/?days=10"); + response.EnsureSuccessStatusCode(); + + //deserialize response to a IEnumerable Wheaterforecast object + var record = Newtonsoft.Json.JsonConvert.DeserializeObject>(await response.Content.ReadAsStringAsync()); + + + // do the tests + Assert.True(record != null, "WS returned a null object"); + Assert.True(record.Where(x => string.IsNullOrEmpty(x.Summary)).Count() < 1, $"Some data in recordset are inconsistent: {record.Where(x => string.IsNullOrEmpty(x.Summary)).Count()} records. "); + + } + } +} From 3161750f3590694f9c951f0a4cceff89d9e092ea Mon Sep 17 00:00:00 2001 From: cada69 <34744773+cada69@users.noreply.github.com> Date: Mon, 18 Dec 2023 10:34:26 +0100 Subject: [PATCH 4/6] Revert "Davide Capuccio" This reverts commit 539fc01a6077202b0a0a6bd981c7978f014afad8. --- TestAPI.sln | 11 --- TestApi.xUnitTest/TestApi.xUnitTest.csproj | 30 ------ TestApi.xUnitTest/Usings.cs | 1 - .../WhaterForecastControllerXTest.cs | 93 ------------------- 4 files changed, 135 deletions(-) delete mode 100644 TestApi.xUnitTest/TestApi.xUnitTest.csproj delete mode 100644 TestApi.xUnitTest/Usings.cs delete mode 100644 TestApi.xUnitTest/WhaterForecastControllerXTest.cs diff --git a/TestAPI.sln b/TestAPI.sln index 424ea35..19a1031 100644 --- a/TestAPI.sln +++ b/TestAPI.sln @@ -12,10 +12,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Readme.md = Readme.md EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{E44E3154-6770-45E0-BA16-AE1291B71BD3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApi.xUnitTest", "TestApi.xUnitTest\TestApi.xUnitTest.csproj", "{50BA1259-845C-4BF3-88E1-782DEE076DD0}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -32,17 +28,10 @@ Global {A720BF0D-868C-404E-9A87-410694A01C6F}.Release|Any CPU.ActiveCfg = Release|Any CPU {A720BF0D-868C-404E-9A87-410694A01C6F}.Release|Any CPU.Build.0 = Release|Any CPU {A720BF0D-868C-404E-9A87-410694A01C6F}.Release|Any CPU.Deploy.0 = Release|Any CPU - {50BA1259-845C-4BF3-88E1-782DEE076DD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {50BA1259-845C-4BF3-88E1-782DEE076DD0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {50BA1259-845C-4BF3-88E1-782DEE076DD0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {50BA1259-845C-4BF3-88E1-782DEE076DD0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {50BA1259-845C-4BF3-88E1-782DEE076DD0} = {E44E3154-6770-45E0-BA16-AE1291B71BD3} - EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3A5247-53B1-4545-B0E1-9197A1BF6562} EndGlobalSection diff --git a/TestApi.xUnitTest/TestApi.xUnitTest.csproj b/TestApi.xUnitTest/TestApi.xUnitTest.csproj deleted file mode 100644 index 1f0a02f..0000000 --- a/TestApi.xUnitTest/TestApi.xUnitTest.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - net7.0 - enable - enable - - false - true - - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - diff --git a/TestApi.xUnitTest/Usings.cs b/TestApi.xUnitTest/Usings.cs deleted file mode 100644 index 8c927eb..0000000 --- a/TestApi.xUnitTest/Usings.cs +++ /dev/null @@ -1 +0,0 @@ -global using Xunit; \ No newline at end of file diff --git a/TestApi.xUnitTest/WhaterForecastControllerXTest.cs b/TestApi.xUnitTest/WhaterForecastControllerXTest.cs deleted file mode 100644 index 35900a0..0000000 --- a/TestApi.xUnitTest/WhaterForecastControllerXTest.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading.Tasks; -using TestAPI.Models; -using TestAPI; -using Microsoft.AspNetCore.Mvc.Testing; - -namespace TestApi.xUnitTest -{ - public class WhaterForecastControllerXTest : IClassFixture> - { - // common chhtp client instance - readonly HttpClient _client; - - - public WhaterForecastControllerXTest(WebApplicationFactory application) - { - // assing httpclient instance - _client = application.CreateClient(); - } - - // test to check response is OK from Api WebForecast - [Fact] - public async Task CheckIfReturnsOk() - { - // fetch api WebForecast & get a response - var response = await _client.GetAsync("http://localhost:5100/WeatherForecast/unauthenticated"); - - response.EnsureSuccessStatusCode(); - // do the test - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - - } - - // test to check if Api response is Ok and returns n days ahead forecast - [Theory] - [InlineData(3)] // parametric test - public async Task CheckIfWFreturnsnDaysAhead(int days) - { - - - // fetch api WebForecast & get a response - var response = await _client.GetAsync(string.Format("http://localhost:5100/WeatherForecast/unauthenticated/?days={0}", days)); - - response.EnsureSuccessStatusCode(); - - //deserialize response to a IEnumerable Wheaterforecast object - var record = Newtonsoft.Json.JsonConvert.DeserializeObject>(await response.Content.ReadAsStringAsync()); - - // do the test - Assert.True(record != null && record.Count() == days); - - } - // test to check if Api WebForecasts response time is less than a spcific thresold - [Fact] - public async Task CheckIfWFApiResponseIsLessThen1mSec() - { - // initialze a stopWatch object - var _stopWatch = new System.Diagnostics.Stopwatch(); - _stopWatch.Start(); - // fetch api WebForecast & get a response - var response = await _client.GetAsync("http://localhost:5100/WeatherForecast/unauthenticated/?days=1"); - response.EnsureSuccessStatusCode(); - // stop the stop watch - _stopWatch.Stop(); - // do the test - Assert.True(_stopWatch.ElapsedMilliseconds < 1000, $"Elapsed time: {_stopWatch.ElapsedMilliseconds} mSecs. "); - - } - - // check if datas returned from Api WheaterForecast are consistent - [Fact] - public async Task CheckIfresponseDataRConsistent() - { - - // fetch api WebForecast & get a response - var response = await _client.GetAsync("http://localhost:5100/WeatherForecast/unauthenticated/?days=10"); - response.EnsureSuccessStatusCode(); - - //deserialize response to a IEnumerable Wheaterforecast object - var record = Newtonsoft.Json.JsonConvert.DeserializeObject>(await response.Content.ReadAsStringAsync()); - - - // do the tests - Assert.True(record != null, "WS returned a null object"); - Assert.True(record.Where(x => string.IsNullOrEmpty(x.Summary)).Count() < 1, $"Some data in recordset are inconsistent: {record.Where(x => string.IsNullOrEmpty(x.Summary)).Count()} records. "); - - } - } -} From de7ead10c17b8371c8516df6fe2ff4ba396290dc Mon Sep 17 00:00:00 2001 From: cada69 <34744773+cada69@users.noreply.github.com> Date: Mon, 18 Dec 2023 10:34:35 +0100 Subject: [PATCH 5/6] Revert "Davide Capuccio" This reverts commit 58eb477d5e3e8477de6940ea67c5a2875d56004f. --- TestUI/src/app/app.component.html | 7 +-- TestUI/src/app/app.component.scss | 4 -- TestUI/src/app/app.component.spec.ts | 61 +------------------------- TestUI/src/app/app.component.ts | 36 +-------------- TestUI/src/app/weatherapp.swagger.ts | 9 +--- TestUI/src/environments/environment.ts | 2 +- 6 files changed, 8 insertions(+), 111 deletions(-) diff --git a/TestUI/src/app/app.component.html b/TestUI/src/app/app.component.html index de68919..56bba0c 100644 --- a/TestUI/src/app/app.component.html +++ b/TestUI/src/app/app.component.html @@ -1,15 +1,12 @@
-
TestUI app is running!
-
-
{{weather.date| date: 'dd/MM/yyyy'}}
+
{{weather.date}}
{{weather.temperatureF}} °F
{{weather.temperatureC}} °C
-

{{weather.summary}}

- +

{{weather.summary}}

diff --git a/TestUI/src/app/app.component.scss b/TestUI/src/app/app.component.scss index 1a355c4..64a2c06 100644 --- a/TestUI/src/app/app.component.scss +++ b/TestUI/src/app/app.component.scss @@ -1,7 +1,3 @@ .card { top: 1rem; } - -.content{ - text-align: center; -} diff --git a/TestUI/src/app/app.component.spec.ts b/TestUI/src/app/app.component.spec.ts index b5ef401..0254631 100644 --- a/TestUI/src/app/app.component.spec.ts +++ b/TestUI/src/app/app.component.spec.ts @@ -1,38 +1,17 @@ import { TestBed } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; -import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { AppComponent } from './app.component'; -import { Client, WeatherForecast } from './weatherapp.swagger'; -import { HttpClient, HttpErrorResponse } from '@angular/common/http'; - - - describe('AppComponent', () => { - - let httpClient: HttpClientTestingModule; - let httpTestingController: HttpTestingController; - let wheaterservice: Client; - beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ - RouterTestingModule, - HttpClientTestingModule, + RouterTestingModule ], - providers: [Client], declarations: [ AppComponent - ], }).compileComponents(); - - // Inject the http, test controller, and service-under-test - // as they will be referenced by each test. - httpClient = TestBed.inject(HttpClient); - httpTestingController = TestBed.inject(HttpTestingController); - wheaterservice = TestBed.inject(Client); - }); it('should create the app', () => { @@ -53,42 +32,4 @@ describe('AppComponent', () => { const compiled = fixture.nativeElement as HTMLElement; expect(compiled.querySelector('.content span')?.textContent).toContain('TestUI app is running!'); }); - - // test web service - it('should get WS data and expect record lenght to be 30', () => { - - - const response: WeatherForecast[] = [ - - // { - // //"date": "2023-11-20T00:00:00", - // "temperatureC": -12, - // "temperatureF": 11, - // "summary": "Freezing" - // } - - - - ]; - - wheaterservice.unauthenticated().subscribe((res) => { - - expect(res).toEqual(response); - - - - }); - - const req = httpTestingController.expectOne({ - method: 'GET', - url: wheaterservice.getBaseUrl() + '/WeatherForecast/unauthenticated/?days=1', - }); - - req.flush(response); - - - }) - - - }); diff --git a/TestUI/src/app/app.component.ts b/TestUI/src/app/app.component.ts index 34a6b41..12ba596 100644 --- a/TestUI/src/app/app.component.ts +++ b/TestUI/src/app/app.component.ts @@ -1,8 +1,6 @@ import {Component} from '@angular/core'; import {Client, WeatherForecast} from "./weatherapp.swagger"; -//import { DatePipe, formatDate } from '@angular/common'; - @Component({ selector: 'app-root', templateUrl: './app.component.html', @@ -12,8 +10,6 @@ import {Client, WeatherForecast} from "./weatherapp.swagger"; export class AppComponent { weatherData: WeatherForecast[] = []; - title: string = "TestUI"; - constructor( private client: Client ) { @@ -31,40 +27,12 @@ export class AppComponent { error: (error) => { this.handleError(error); }, - next: - (data: WeatherForecast[]) => { - this.weatherData = data; - + next: (data: WeatherForecast[]) => { + this.weatherData = data; } }) } - - - - getColor(summary: any){ - switch(summary){ - case "Freezing": - case "Bracing": - case "Chilly": - return "cyan"; - case "Mild": - case "Balmy": - case "Cool": - return "green"; - case "Warm": - case "Hot": - return "orange"; - case "Sweltering": - case "Scorching": - return "red"; - default: - return "black"; - - } - - - } /** * Dummy Error Handler diff --git a/TestUI/src/app/weatherapp.swagger.ts b/TestUI/src/app/weatherapp.swagger.ts index 6c84e25..8984d7e 100644 --- a/TestUI/src/app/weatherapp.swagger.ts +++ b/TestUI/src/app/weatherapp.swagger.ts @@ -26,16 +26,11 @@ export class Client { this.baseUrl = baseUrl !== undefined && baseUrl !== null ? baseUrl : ""; } - getBaseUrl():string{ - - return this.baseUrl; - } - /** * @return Success */ weatherForecast(): Observable { - let url_ = this.baseUrl + "/WeatherForecast/unauthenticated/?days=1"; // this.baseUrl + "/WeatherForecast"; + let url_ = this.baseUrl + "/WeatherForecast"; url_ = url_.replace(/[?&]$/, ""); let options_ : any = { @@ -85,7 +80,7 @@ export class Client { * @return Success */ unauthenticated(): Observable { - let url_ = this.baseUrl + "/WeatherForecast/unauthenticated/?days=1"; + let url_ = this.baseUrl + "/WeatherForecast/unauthenticated"; url_ = url_.replace(/[?&]$/, ""); let options_ : any = { diff --git a/TestUI/src/environments/environment.ts b/TestUI/src/environments/environment.ts index 05727ae..12ba3e4 100644 --- a/TestUI/src/environments/environment.ts +++ b/TestUI/src/environments/environment.ts @@ -4,7 +4,7 @@ export const environment = { production: false, - url:'http://localhost:5100' + url:'https://localhost:5001' }; /* From d94560477a86d3c2fc8174a4ad6be7799891bf49 Mon Sep 17 00:00:00 2001 From: cada69 <34744773+cada69@users.noreply.github.com> Date: Mon, 18 Dec 2023 10:34:43 +0100 Subject: [PATCH 6/6] Revert "Davide Capuccio" This reverts commit bb9ddcc335d6f216b49791a59ba2c118b25b627f. --- .vscode/launch.json | 35 ------ .vscode/tasks.json | 41 ------- TestDB/Data/SeedData.sql | 2 +- TestDB/Stored Procedures/usp_movecase.sql | 139 ++++++---------------- 4 files changed, 37 insertions(+), 180 deletions(-) delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/tasks.json diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index e9b2fcf..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - // Use IntelliSense to find out which attributes exist for C# debugging - // Use hover for the description of the existing attributes - // For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md. - "name": ".NET Core Launch (web)", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/TestAPI/bin/Debug/net5.0/TestAPI.dll", - "args": [], - "cwd": "${workspaceFolder}/TestAPI", - "stopAtEntry": false, - // Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser - "serverReadyAction": { - "action": "openExternally", - "pattern": "\\bNow listening on:\\s+(https?://\\S+)" - }, - "env": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "sourceFileMap": { - "/Views": "${workspaceFolder}/Views" - } - }, - { - "name": ".NET Core Attach", - "type": "coreclr", - "request": "attach" - } - ] -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index ad45275..0000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "build", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/TestAPI.sln", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary;ForceNoAlign" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "publish", - "command": "dotnet", - "type": "process", - "args": [ - "publish", - "${workspaceFolder}/TestAPI.sln", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary;ForceNoAlign" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "watch", - "command": "dotnet", - "type": "process", - "args": [ - "watch", - "run", - "--project", - "${workspaceFolder}/TestAPI.sln" - ], - "problemMatcher": "$msCompile" - } - ] -} \ No newline at end of file diff --git a/TestDB/Data/SeedData.sql b/TestDB/Data/SeedData.sql index f9a879a..eef574e 100644 --- a/TestDB/Data/SeedData.sql +++ b/TestDB/Data/SeedData.sql @@ -16,7 +16,7 @@ VALUES('1de2e437-f16a-4c1a-84b4-3cfc63310eca', '9a03fc4b-37af-4560-8923-7657e804 ('35bf4e4a-94b9-46b0-b9ea-ed92bff095a3', '844b12ea-f822-4223-9011-6f4d8b6367a1', 'c8b50ee6-f09d-451f-b7e2-53193c8f6839'), ('9873fba8-276e-4b13-92f3-1ea2255b1c16', '8cd9d41a-33a7-4df3-9eb2-6d1d7aca20d1', 'c8b50ee6-f09d-451f-b7e2-53193c8f6839'), - ('9873fba8-276e-4b13-92f3-1ea2255b1c17', '8cd9d41a-33a7-4df3-9eb2-6d1d7aca20d1', 'cf1b257a-99b0-4abe-9428-983295073b14') + ('9873fba8-276e-4b13-92f3-1ea2255b1c16', '8cd9d41a-33a7-4df3-9eb2-6d1d7aca20d1', 'cf1b257a-99b0-4abe-9428-983295073b14') INSERT INTO [dbo].[pallet] ([guid]) diff --git a/TestDB/Stored Procedures/usp_movecase.sql b/TestDB/Stored Procedures/usp_movecase.sql index 8a3bc25..ea3452f 100644 --- a/TestDB/Stored Procedures/usp_movecase.sql +++ b/TestDB/Stored Procedures/usp_movecase.sql @@ -1,106 +1,39 @@ -CREATE PROCEDURE [dbo].[usp_movecase] @casetomove UNIQUEIDENTIFIER +CREATE PROCEDURE [dbo].[usp_movecase] + @casetomove UNIQUEIDENTIFIER WITH ENCRYPTION AS BEGIN - SET NOCOUNT ON; - - DECLARE @Result AS INT = 0 - DECLARE @_errormessage NVARCHAR(MAX) - - BEGIN TRANSACTION - - BEGIN TRY - DECLARE @caseproductgui UNIQUEIDENTIFIER = NULL; - DECLARE @casepalletguid UNIQUEIDENTIFIER = NULL; - DECLARE @casenewpalletguid UNIQUEIDENTIFIER = NULL; - DECLARE @newcasetomove UNIQUEIDENTIFIER = NULL; - - -- check if case id is in the DB - IF EXISTS ( - SELECT * - FROM [case] - WHERE [guid] = @casetomove - ) - BEGIN - -- case exists in [case] db, proceed mooving the case & - -- get case product id - -- get pallet id - -- for this record - SELECT @casepalletguid = palletguid - ,@caseproductgui = productguid - FROM [case] - WHERE [guid] = @casetomove; - - -- check if there is a pallet in the DB that stacks cases with - -- same product ID as @casetomove, not the same of @casetomove pallet id - IF EXISTS ( - SELECT * - FROM [case] - WHERE productguid = @caseproductgui - AND [guid] <> @casetomove - AND palletguid <> @casepalletguid - ) - BEGIN - -- yes there is, get the new pallet id @casetomove has to move to - SELECT @casenewpalletguid = palletguid - FROM [case] - WHERE productguid = @caseproductgui - AND [guid] <> @casetomove - AND palletguid <> @casepalletguid - - -- update new pallet id for @casetomove - UPDATE [case] - SET palletguid = @casenewpalletguid - WHERE [guid] = @casetomove - - -- if the new pallet contains case with prod id different from @casetomove, try to move - -- these cases to a different pallet containing same prod ids - IF EXISTS ( - SELECT * - FROM [case] - WHERE palletguid = @casenewpalletguid - AND productguid <> @caseproductgui - ) - BEGIN - -- yes, there is, get this new case id - SELECT TOP 1 @newcasetomove = [guid] - FROM [case] - WHERE palletguid = @casenewpalletguid - AND productguid <> @caseproductgui - - -- just simply recall this procedure with new case id to move as parameter - EXEC [dbo].[usp_movecase] @newcasetomove - - END - END - ELSE - PRINT 'No pallet with the same product ID of ' + cast(@casetomove AS VARCHAR(64)) + ' available' - END - ELSE - PRINT 'case id provided [' + cast(@casetomove AS VARCHAR(64)) + '] does not exists' - END TRY - - BEGIN CATCH - SET @Result = - 1 - - SELECT @_errormessage = ERROR_MESSAGE() - END CATCH - - IF (@@TRANCOUNT > 0) - BEGIN - IF (@Result >= 0) - BEGIN - COMMIT TRANSACTION - - PRINT 'Commited Transaction at ' + cast(GETDATE() AS VARCHAR(30)) - END - ELSE - BEGIN - ROLLBACK TRANSACTION - - PRINT 'Rolled back Transaction at ' + cast(GETDATE() AS VARCHAR(30)) + 'because of error: ' + @_errormessage - END - END - - RETURN @Result -END + SET NOCOUNT ON; + + DECLARE @Result AS INT = 0 + DECLARE @_errormessage NVARCHAR(MAX) + + BEGIN TRANSACTION + BEGIN TRY + + PRINT 'your code goes here' + + END TRY + BEGIN CATCH + SET @Result = -1 + + SELECT @_errormessage = ERROR_MESSAGE() + + END CATCH + + IF (@@TRANCOUNT > 0) + BEGIN + IF (@Result >= 0) + BEGIN + COMMIT TRANSACTION + PRINT 'Commited Transaction at ' + GETDATE() + END + ELSE + BEGIN + ROLLBACK TRANSACTION + PRINT 'Rolled back Transaction at ' + GETDATE() + 'because of error: ' + @_errormessage + END + END + + RETURN @Result +END \ No newline at end of file