From aa745b6e6cddbd25ba4611454dd4fd69239a62e2 Mon Sep 17 00:00:00 2001 From: Rajesh0000018 Date: Fri, 12 Dec 2025 13:49:08 +0000 Subject: [PATCH 1/2] Add CI pipeline --- .github/workflows/ci.yml | 41 +++++++++++++++++ .../BDD/BloodPressureBDDTests.cs | 45 +++++++++++++++++++ BPCalculator.Tests/BPCalculator.Tests.csproj | 31 +++++++++++++ BPCalculator.Tests/BloodPressureTests.cs | 44 ++++++++++++++++++ BPCalculator.sln | 26 +++++++++++ BPCalculator/BloodPressure.cs | 25 +++++++++-- 6 files changed, 208 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 BPCalculator.Tests/BDD/BloodPressureBDDTests.cs create mode 100644 BPCalculator.Tests/BPCalculator.Tests.csproj create mode 100644 BPCalculator.Tests/BloodPressureTests.cs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..5f7921d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,41 @@ +name: CI Pipeline + +on: + push: + branches: [ "**" ] + pull_request: + branches: [ "**" ] + +jobs: + build-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0.x' + + - name: Restore dependencies + run: dotnet restore + + - name: Build solution + run: dotnet build --no-restore --configuration Release + + - name: Run Tests (Unit + BDD) + Coverage + run: dotnet test --no-build --configuration Release --collect "XPlat Code Coverage" + + - name: Upload Coverage Report + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: '**/coverage.cobertura.xml' + + - name: Run Code Analysis + run: dotnet format --verify-no-changes || true + + - name: Dependency Vulnerability Scan + run: dotnet list package --vulnerable || true diff --git a/BPCalculator.Tests/BDD/BloodPressureBDDTests.cs b/BPCalculator.Tests/BDD/BloodPressureBDDTests.cs new file mode 100644 index 0000000..716eaa9 --- /dev/null +++ b/BPCalculator.Tests/BDD/BloodPressureBDDTests.cs @@ -0,0 +1,45 @@ +using Xunit; +using BPCalculator; + +namespace BPCalculator.Tests.BDD +{ + public class BloodPressureBDDTests + { + [Fact] + public void GivenLowValues_WhenICheckCategory_ThenItIsLow() + { + // Given + var bp = new BloodPressure { Systolic = 85, Diastolic = 55 }; + + // When + var category = bp.Category; + + // Then + Assert.Equal(BPCategory.Low, category); + } + + [Fact] + public void GivenIdealValues_WhenICheckCategory_ThenItIsIdeal() + { + var bp = new BloodPressure { Systolic = 110, Diastolic = 75 }; + var category = bp.Category; + Assert.Equal(BPCategory.Ideal, category); + } + + [Fact] + public void GivenPreHighValues_WhenICheckCategory_ThenItIsPreHigh() + { + var bp = new BloodPressure { Systolic = 130, Diastolic = 85 }; + var category = bp.Category; + Assert.Equal(BPCategory.PreHigh, category); + } + + [Fact] + public void GivenHighValues_WhenICheckCategory_ThenItIsHigh() + { + var bp = new BloodPressure { Systolic = 150, Diastolic = 95 }; + var category = bp.Category; + Assert.Equal(BPCategory.High, category); + } + } +} diff --git a/BPCalculator.Tests/BPCalculator.Tests.csproj b/BPCalculator.Tests/BPCalculator.Tests.csproj new file mode 100644 index 0000000..8c2872f --- /dev/null +++ b/BPCalculator.Tests/BPCalculator.Tests.csproj @@ -0,0 +1,31 @@ + + + + net9.0 + enable + enable + false + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + + diff --git a/BPCalculator.Tests/BloodPressureTests.cs b/BPCalculator.Tests/BloodPressureTests.cs new file mode 100644 index 0000000..63a40d9 --- /dev/null +++ b/BPCalculator.Tests/BloodPressureTests.cs @@ -0,0 +1,44 @@ +using Xunit; +using BPCalculator; + +namespace BPCalculator.Tests +{ + public class BloodPressureTests + { + [Theory] + [InlineData(85, 55, BPCategory.Low)] + [InlineData(80, 70, BPCategory.Low)] + public void Category_ReturnsLow(int systolic, int diastolic, BPCategory expected) + { + var bp = new BloodPressure { Systolic = systolic, Diastolic = diastolic }; + Assert.Equal(expected, bp.Category); + } + + [Theory] + [InlineData(100, 70, BPCategory.Ideal)] + [InlineData(110, 75, BPCategory.Ideal)] + public void Category_ReturnsIdeal(int systolic, int diastolic, BPCategory expected) + { + var bp = new BloodPressure { Systolic = systolic, Diastolic = diastolic }; + Assert.Equal(expected, bp.Category); + } + + [Theory] + [InlineData(130, 85, BPCategory.PreHigh)] + [InlineData(125, 88, BPCategory.PreHigh)] + public void Category_ReturnsPreHigh(int systolic, int diastolic, BPCategory expected) + { + var bp = new BloodPressure { Systolic = systolic, Diastolic = diastolic }; + Assert.Equal(expected, bp.Category); + } + + [Theory] + [InlineData(150, 95, BPCategory.High)] + [InlineData(140, 70, BPCategory.High)] + public void Category_ReturnsHigh(int systolic, int diastolic, BPCategory expected) + { + var bp = new BloodPressure { Systolic = systolic, Diastolic = diastolic }; + Assert.Equal(expected, bp.Category); + } + } +} diff --git a/BPCalculator.sln b/BPCalculator.sln index 652d73a..f7c58db 100644 --- a/BPCalculator.sln +++ b/BPCalculator.sln @@ -5,16 +5,42 @@ VisualStudioVersion = 16.0.30002.166 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPCalculator", "BPCalculator\BPCalculator.csproj", "{5966DA6C-819D-4303-ADC7-425B8541EC84}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPCalculator.Tests", "BPCalculator.Tests\BPCalculator.Tests.csproj", "{12E1E52C-274E-4D93-AF85-68A7EF9452AA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {5966DA6C-819D-4303-ADC7-425B8541EC84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5966DA6C-819D-4303-ADC7-425B8541EC84}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5966DA6C-819D-4303-ADC7-425B8541EC84}.Debug|x64.ActiveCfg = Debug|Any CPU + {5966DA6C-819D-4303-ADC7-425B8541EC84}.Debug|x64.Build.0 = Debug|Any CPU + {5966DA6C-819D-4303-ADC7-425B8541EC84}.Debug|x86.ActiveCfg = Debug|Any CPU + {5966DA6C-819D-4303-ADC7-425B8541EC84}.Debug|x86.Build.0 = Debug|Any CPU {5966DA6C-819D-4303-ADC7-425B8541EC84}.Release|Any CPU.ActiveCfg = Release|Any CPU {5966DA6C-819D-4303-ADC7-425B8541EC84}.Release|Any CPU.Build.0 = Release|Any CPU + {5966DA6C-819D-4303-ADC7-425B8541EC84}.Release|x64.ActiveCfg = Release|Any CPU + {5966DA6C-819D-4303-ADC7-425B8541EC84}.Release|x64.Build.0 = Release|Any CPU + {5966DA6C-819D-4303-ADC7-425B8541EC84}.Release|x86.ActiveCfg = Release|Any CPU + {5966DA6C-819D-4303-ADC7-425B8541EC84}.Release|x86.Build.0 = Release|Any CPU + {12E1E52C-274E-4D93-AF85-68A7EF9452AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {12E1E52C-274E-4D93-AF85-68A7EF9452AA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {12E1E52C-274E-4D93-AF85-68A7EF9452AA}.Debug|x64.ActiveCfg = Debug|Any CPU + {12E1E52C-274E-4D93-AF85-68A7EF9452AA}.Debug|x64.Build.0 = Debug|Any CPU + {12E1E52C-274E-4D93-AF85-68A7EF9452AA}.Debug|x86.ActiveCfg = Debug|Any CPU + {12E1E52C-274E-4D93-AF85-68A7EF9452AA}.Debug|x86.Build.0 = Debug|Any CPU + {12E1E52C-274E-4D93-AF85-68A7EF9452AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {12E1E52C-274E-4D93-AF85-68A7EF9452AA}.Release|Any CPU.Build.0 = Release|Any CPU + {12E1E52C-274E-4D93-AF85-68A7EF9452AA}.Release|x64.ActiveCfg = Release|Any CPU + {12E1E52C-274E-4D93-AF85-68A7EF9452AA}.Release|x64.Build.0 = Release|Any CPU + {12E1E52C-274E-4D93-AF85-68A7EF9452AA}.Release|x86.ActiveCfg = Release|Any CPU + {12E1E52C-274E-4D93-AF85-68A7EF9452AA}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/BPCalculator/BloodPressure.cs b/BPCalculator/BloodPressure.cs index 3e8fee9..591ddd0 100644 --- a/BPCalculator/BloodPressure.cs +++ b/BPCalculator/BloodPressure.cs @@ -29,11 +29,28 @@ public class BloodPressure // calculate BP category public BPCategory Category { - get + get { - // implement as part of project - //throw new NotImplementedException("not implemented yet"); - return new BPCategory(); // replace this + // LOW BP + if (Systolic < 90 || Diastolic < 60) + return BPCategory.Low; + + // IDEAL BP + if (Systolic >= 90 && Systolic < 120 && + Diastolic >= 60 && Diastolic < 80) + return BPCategory.Ideal; + + // PRE-HIGH BP + if ((Systolic >= 120 && Systolic < 140) || + (Diastolic >= 80 && Diastolic < 90)) + return BPCategory.PreHigh; + + // HIGH BP + if (Systolic >= 140 || Diastolic >= 90) + return BPCategory.High; + + // fallback — should never reach here + return BPCategory.High; } } } From 66e8ba8c52f6dc2f4a9c0fe9abf9c5b645f2b03b Mon Sep 17 00:00:00 2001 From: Rajesh0000018 Date: Fri, 12 Dec 2025 13:55:30 +0000 Subject: [PATCH 2/2] Add SonarCloud analysis to CI pipeline --- .github/workflows/ci.yml | 36 ++++++++++++++++++++++++++++-------- .sonarcloud.properties | 7 +++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f7921d..d8c669b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: CI Pipeline +name: CI Pipeline with SonarCloud on: push: @@ -7,35 +7,55 @@ on: branches: [ "**" ] jobs: - build-test: + build-test-analyze: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 + with: + fetch-depth: 0 # Required for SonarCloud - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.x' + - name: Install SonarScanner + uses: SonarSource/sonarcloud-github-action@v2 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + - name: Restore dependencies run: dotnet restore - name: Build solution run: dotnet build --no-restore --configuration Release - - name: Run Tests (Unit + BDD) + Coverage + - name: Run Tests with Coverage run: dotnet test --no-build --configuration Release --collect "XPlat Code Coverage" + - name: Locate coverage file + id: coverage + run: echo "##[set-output name=path;]$(find . -type f -name 'coverage.cobertura.xml')" + + - name: SonarCloud Scan + uses: SonarSource/sonarcloud-github-action@v2 + with: + args: > + -Dsonar.projectKey=chan27052705_bp + -Dsonar.organization=chan27052705-1 + -Dsonar.cs.opencover.reportsPaths=${{ steps.coverage.outputs.path }} + -Dsonar.coverage.exclusions=**/wwwroot/** + + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + - name: Upload Coverage Report uses: actions/upload-artifact@v4 with: name: coverage-report - path: '**/coverage.cobertura.xml' - - - name: Run Code Analysis - run: dotnet format --verify-no-changes || true + path: ${{ steps.coverage.outputs.path }} - - name: Dependency Vulnerability Scan + - name: Vulnerability Scan run: dotnet list package --vulnerable || true diff --git a/.sonarcloud.properties b/.sonarcloud.properties index 8b13789..076d656 100644 --- a/.sonarcloud.properties +++ b/.sonarcloud.properties @@ -1 +1,8 @@ +sonar.projectKey=chan27052705_bp +sonar.organization=chan27052705-1 +sonar.host.url=https://sonarcloud.io + +sonar.cs.opencover.reportsPaths=**/coverage.cobertura.xml +sonar.language=cs +sonar.sourceEncoding=UTF-8