Skip to content

Commit c7d8cf7

Browse files
authored
Merge pull request #3 from aj-enns/250
250
2 parents af71b65 + 15d1d95 commit c7d8cf7

File tree

11 files changed

+331
-22
lines changed

11 files changed

+331
-22
lines changed

.github/workflows/deploy.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Azure Bicep
2+
3+
on:
4+
workflow_dispatch
5+
6+
env:
7+
targetEnv: dev
8+
9+
jobs:
10+
build-and-deploy:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
pages: write
15+
id-token: write
16+
steps:
17+
# Checkout code
18+
- uses: actions/checkout@main
19+
20+
# Log into Azure
21+
- uses: azure/[email protected]
22+
with:
23+
client-id: ${{ secrets.AZURE_CLIENT_ID }}
24+
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
25+
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
26+
enable-AzPSSession: true
27+
28+
# Deploy ARM template
29+
- name: Run ARM deploy
30+
uses: azure/arm-deploy@v1
31+
with:
32+
subscriptionId: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
33+
resourceGroupName: ${{ secrets.AZURE_RG }}
34+
template: ./src/InfrastructureAsCode/main.bicep
35+
parameters: environment=${{ env.targetEnv }}

.github/workflows/dotnet-deploy-1.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: .NET CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
paths:
7+
- src/Application/**
8+
pull_request:
9+
branches: [ main ]
10+
paths:
11+
- src/Application/**
12+
# Allows you to run this workflow manually from the Actions tab
13+
workflow_dispatch:
14+
jobs:
15+
build:
16+
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- uses: actions/checkout@v3
21+
- name: Setup .NET
22+
uses: actions/setup-dotnet@v3
23+
with:
24+
dotnet-version: '8.0.x'
25+
26+
- name: Restore dependencies
27+
run: dotnet restore ./src/Application/src/RazorPagesTestSample/RazorPagesTestSample.csproj
28+
- name: Build
29+
run: dotnet build --no-restore ./src/Application/src/RazorPagesTestSample/RazorPagesTestSample.csproj
30+
- name: Test
31+
run: dotnet test --no-build --verbosity normal ./src/Application/tests/RazorPagesTestSample.Tests/RazorPagesTestSample.Tests.csproj

.vscode/tasks.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "Save All Files",
6+
"command": "${command:workbench.action.files.saveAll}",
7+
"type": "shell",
8+
"problemMatcher": []
9+
},
10+
{
11+
"label": "Build Project",
12+
"dependsOn": "Save All Files",
13+
"command": "dotnet build",
14+
"type": "shell",
15+
"group": {
16+
"kind": "build",
17+
"isDefault": true
18+
},
19+
"problemMatcher": "$msCompile"
20+
}
21+
]
22+
}

docs/03_improve_deploy_app/0301.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ We have a work machine configured, so now it is time to ensure that everything w
1313

1414
## Description
1515

16-
Developers at Munson's Pickles and Preserves like the Team Messaging System in general, but they consistently bring up issues with one aspect of the application: it limits messages to 200 characters or fewer. Developers have made a case that the app should support messages of up to 250 characters in length instead.
16+
Developers at Munson's Pickles and Preserves like the Team Messaging System in general, but they consistently bring up issues with one aspect of the application: it limits messages to 250 characters or fewer. Developers have made a case that the app should support messages of up to 250 characters in length instead.
1717

1818
In this task, you will modify the application to support 250 characters instead of 200. You will also follow a feature branching strategy and use a pull request to bring your change into the `main` branch. If you wish to complete this task using a Test-Driven Design approach, please read the **Advanced Challenges (optional)** section below before making any changes.
1919

src/Application/src/RazorPagesTestSample/Data/Message.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ public class Message
99

1010
[Required]
1111
[DataType(DataType.Text)]
12-
[StringLength(200, ErrorMessage = "There's a 200 character limit on messages. Please shorten your message.")]
12+
[StringLength(250, ErrorMessage = "There's a 250 character limit on messages. Please shorten your message.")]
1313
public string Text { get; set; }
1414
}
1515
#endregion
16-
}
16+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Use the official .NET 8 SDK image as a build stage
2+
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
3+
WORKDIR /app
4+
5+
# Copy the project file and restore dependencies
6+
COPY *.csproj .
7+
RUN dotnet restore
8+
9+
# Copy the rest of the application code
10+
COPY . .
11+
12+
# Build the application
13+
RUN dotnet publish -c Release -o out
14+
15+
# Use the official .NET 8 runtime image as a runtime stage
16+
FROM mcr.microsoft.com/dotnet/aspnet:8.0
17+
WORKDIR /app
18+
COPY --from=build /app/out .
19+
20+
# Set the environment variable for ASP.NET Core HTTP ports
21+
ENV ASPNETCORE_HTTP_PORTS=80
22+
23+
# Set the entry point for the application
24+
ENTRYPOINT ["dotnet", "RazorPagesTestSample.dll"]

src/Application/src/RazorPagesTestSample/Pages/Error.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
}
66

77
<h1 class="text-danger">Error.</h1>
8-
<h2 class="text-danger">An error occurred while processing your request.</h2>
8+
<h3 class="text-danger">An error occurred while processing your request.</h3>
99

1010
@if (Model.ShowRequestId)
1111
{
Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
2-
32
<PropertyGroup>
43
<TargetFramework>net8.0</TargetFramework>
54
</PropertyGroup>
6-
75
<!-- https://github.com/NuGet/Home/issues/4412 -->
8-
9-
106
<ItemGroup>
117
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="8.0.3" />
128
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.3" />
139
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.3" />
1410
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
1511
<PackageReference Include="Moq" Version="4.20.70" />
16-
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
12+
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
1713
<PackageReference Include="System.Diagnostics.TraceSource" Version="4.3.0" />
1814
<PackageReference Include="System.Net.Http" Version="4.3.4" />
1915
<PackageReference Include="xunit" Version="2.7.0" />
@@ -22,12 +18,7 @@
2218
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2319
</PackageReference>
2420
</ItemGroup>
25-
26-
2721
<ItemGroup>
28-
<Reference Include="RazorPagesTestSample">
29-
<HintPath>..\..\src\RazorPagesTestSample\bin\Debug\net8.0\RazorPagesTestSample.dll</HintPath>
30-
</Reference>
22+
<ProjectReference Include="..\..\src\RazorPagesTestSample\RazorPagesTestSample.csproj" />
3123
</ItemGroup>
32-
33-
</Project>
24+
</Project>

src/Application/tests/RazorPagesTestSample.Tests/UnitTests/DataAccessLayerTest.cs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Microsoft.EntityFrameworkCore;
55
using Xunit;
66
using RazorPagesTestSample.Data;
7+
using System.ComponentModel.DataAnnotations;
78

89
namespace RazorPagesTestSample.Tests.UnitTests
910
{
@@ -25,7 +26,7 @@ public async Task GetMessagesAsync_MessagesAreReturned()
2526
// Assert
2627
var actualMessages = Assert.IsAssignableFrom<List<Message>>(result);
2728
Assert.Equal(
28-
expectedMessages.OrderBy(m => m.Id).Select(m => m.Text),
29+
expectedMessages.OrderBy(m => m.Id).Select(m => m.Text),
2930
actualMessages.OrderBy(m => m.Id).Select(m => m.Text));
3031
}
3132
}
@@ -77,7 +78,7 @@ public async Task DeleteMessageAsync_MessageIsDeleted_WhenMessageIsFound()
7778
await db.AddRangeAsync(seedMessages);
7879
await db.SaveChangesAsync();
7980
var recId = 1;
80-
var expectedMessages =
81+
var expectedMessages =
8182
seedMessages.Where(message => message.Id != recId).ToList();
8283
#endregion
8384

@@ -90,7 +91,7 @@ public async Task DeleteMessageAsync_MessageIsDeleted_WhenMessageIsFound()
9091
// Assert
9192
var actualMessages = await db.Messages.AsNoTracking().ToListAsync();
9293
Assert.Equal(
93-
expectedMessages.OrderBy(m => m.Id).Select(m => m.Text),
94+
expectedMessages.OrderBy(m => m.Id).Select(m => m.Text),
9495
actualMessages.OrderBy(m => m.Id).Select(m => m.Text));
9596
#endregion
9697
}
@@ -121,10 +122,42 @@ public async Task DeleteMessageAsync_NoMessageIsDeleted_WhenMessageIsNotFound()
121122
// Assert
122123
var actualMessages = await db.Messages.AsNoTracking().ToListAsync();
123124
Assert.Equal(
124-
expectedMessages.OrderBy(m => m.Id).Select(m => m.Text),
125+
expectedMessages.OrderBy(m => m.Id).Select(m => m.Text),
125126
actualMessages.OrderBy(m => m.Id).Select(m => m.Text));
126127
}
127128
}
129+
130+
131+
132+
//Generate a unit test theory to generate messages of various lengths including 250 and try to validate the message object.
133+
[Theory]
134+
[InlineData(150, true)]
135+
[InlineData(199, true)]
136+
[InlineData(200, true)]
137+
[InlineData(201, true)]
138+
[InlineData(249, true)]
139+
[InlineData(250, true)]
140+
[InlineData(251, false)]
141+
[InlineData(300, false)]
142+
public async Task AddMessageAsync_TestMessageLength(int messageLength, bool expectedValidMessage)
143+
{
144+
using (var db = new AppDbContext(Utilities.TestDbContextOptions()))
145+
{
146+
// Arrange
147+
var recId = 10;
148+
var expectedMessage = new Message() { Id = recId, Text = new string('X', messageLength) };
149+
150+
// Act
151+
var isValidMessage = Validator.TryValidateObject(expectedMessage, new ValidationContext(expectedMessage), null, validateAllProperties: true);
152+
153+
// Simulate an asynchronous operation
154+
await Task.Delay(1);
155+
156+
// Assert
157+
Assert.Equal(expectedValidMessage, isValidMessage);
158+
}
159+
}
160+
128161
#endregion
129162
}
130163
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
using System.ComponentModel.DataAnnotations;
2+
using RazorPagesTestSample.Data;
3+
using Xunit;
4+
using System.Collections.Generic;
5+
6+
namespace RazorPagesTestSample.Tests.UnitTests
7+
{
8+
public class MessageTests
9+
{
10+
[Fact]
11+
public void MessageText_ShouldNotExceed250Characters()
12+
{
13+
// Arrange
14+
var message = new Message
15+
{
16+
Text = new string('a', 251) // 251 characters
17+
};
18+
var validationContext = new ValidationContext(message);
19+
var validationResults = new List<ValidationResult>();
20+
21+
// Act
22+
var isValid = Validator.TryValidateObject(message, validationContext, validationResults, true);
23+
24+
// Assert
25+
Assert.False(isValid);
26+
Assert.Contains(validationResults, v => v.ErrorMessage.Contains("250 character limit"));
27+
}
28+
29+
[Fact]
30+
public void MessageText_ShouldBeValid_WhenWithin250Characters()
31+
{
32+
// Arrange
33+
var message = new Message
34+
{
35+
Text = new string('a', 250) // 250 characters
36+
};
37+
var validationContext = new ValidationContext(message);
38+
var validationResults = new List<ValidationResult>();
39+
40+
// Act
41+
var isValid = Validator.TryValidateObject(message, validationContext, validationResults, true);
42+
43+
// Assert
44+
Assert.True(isValid);
45+
}
46+
47+
//test the insertion of a message of length 150
48+
[Fact]
49+
public void MessageText_ShouldBeValid_WhenWithin150Characters()
50+
{
51+
// Arrange
52+
var message = new Message
53+
{
54+
Text = new string('a', 150) // 150 characters
55+
};
56+
var validationContext = new ValidationContext(message);
57+
var validationResults = new List<ValidationResult>();
58+
59+
// Act
60+
var isValid = Validator.TryValidateObject(message, validationContext, validationResults, true);
61+
62+
// Assert
63+
Assert.True(isValid);
64+
}
65+
66+
//test a message of length 249
67+
[Fact]
68+
public void MessageText_ShouldBeValid_WhenWithin249Characters()
69+
{
70+
// Arrange
71+
var message = new Message
72+
{
73+
Text = new string('a', 249) // 249 characters
74+
};
75+
var validationContext = new ValidationContext(message);
76+
var validationResults = new List<ValidationResult>();
77+
78+
// Act
79+
var isValid = Validator.TryValidateObject(message, validationContext, validationResults, true);
80+
81+
// Assert
82+
Assert.True(isValid);
83+
}
84+
}
85+
}

0 commit comments

Comments
 (0)