Skip to content

Commit f54dc11

Browse files
authored
Merge pull request #65 from FBoucher/v-next
Adds unit tests and CI workflow
2 parents 21a0c89 + 0e9769e commit f54dc11

32 files changed

+2915
-34
lines changed

.github/workflows/azure-dev.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
name: Deploy to Azure
2+
13
on:
24
workflow_dispatch:
35
push:
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: Unit Tests
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
- v-next
11+
12+
permissions:
13+
contents: read
14+
checks: write
15+
pull-requests: write
16+
17+
env:
18+
DEFAULT_DOTNET_VERSION: "8.0.x"
19+
20+
jobs:
21+
test:
22+
runs-on: ubuntu-latest
23+
name: Run Unit Tests
24+
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@v4
28+
29+
- name: Setup .NET
30+
uses: actions/setup-dotnet@v4
31+
with:
32+
dotnet-version: |
33+
${{ env.DEFAULT_DOTNET_VERSION }}
34+
9.0.x
35+
36+
- name: Restore dependencies
37+
run: dotnet restore
38+
39+
- name: Build solution
40+
run: dotnet build --no-restore --configuration Release
41+
42+
- name: Run unit tests
43+
run: dotnet test --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --results-directory ./TestResults --logger trx --logger "console;verbosity=detailed"
44+
45+
- name: Publish Test Results
46+
uses: dorny/test-reporter@v1
47+
if: always()
48+
with:
49+
name: .NET Tests
50+
path: ./TestResults/**/*.trx
51+
reporter: dotnet-trx
52+
fail-on-error: true
53+
54+
- name: Code Coverage Report
55+
uses: irongut/[email protected]
56+
if: always()
57+
with:
58+
filename: ./TestResults/**/coverage.cobertura.xml
59+
badge: true
60+
fail_below_min: false
61+
format: markdown
62+
hide_branch_rate: false
63+
hide_complexity: true
64+
indicators: true
65+
output: both
66+
thresholds: '60 80'
67+
68+
- name: Add Coverage PR Comment
69+
uses: marocchino/sticky-pull-request-comment@v2
70+
if: github.event_name == 'pull_request'
71+
with:
72+
recreate: true
73+
path: code-coverage-results.md
74+
75+
- name: Upload test results
76+
uses: actions/upload-artifact@v4
77+
if: always()
78+
with:
79+
name: test-results-${{ github.run_number }}
80+
path: ./TestResults
81+
82+
- name: Upload coverage reports
83+
uses: actions/upload-artifact@v4
84+
if: always()
85+
with:
86+
name: coverage-reports-${{ github.run_number }}
87+
path: ./TestResults/**/coverage.cobertura.xml
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using FluentAssertions;
2+
using NoteBookmark.Domain;
3+
using Xunit;
4+
5+
namespace NoteBookmark.Api.Tests.Domain;
6+
7+
public class NoteTests
8+
{
9+
[Fact]
10+
public void Note_WhenCreated_HasCorrectDefaultValues()
11+
{
12+
// Act
13+
var note = new Note();
14+
15+
// Assert
16+
note.PostId.Should().BeNull();
17+
note.Comment.Should().BeNull();
18+
note.Tags.Should().BeNull();
19+
note.Category.Should().BeNull();
20+
}
21+
22+
[Fact]
23+
public void Note_WhenPropertiesSet_ReturnsCorrectValues()
24+
{
25+
// Arrange
26+
var note = new Note
27+
{
28+
PartitionKey = "reading-notes-123",
29+
RowKey = "note-456",
30+
PostId = "post-789",
31+
Comment = "Excellent article about Azure Functions",
32+
Tags = "azure, functions, serverless",
33+
Category = "Technology"
34+
};
35+
36+
// Assert
37+
note.PartitionKey.Should().Be("reading-notes-123");
38+
note.RowKey.Should().Be("note-456");
39+
note.PostId.Should().Be("post-789");
40+
note.Comment.Should().Be("Excellent article about Azure Functions");
41+
note.Tags.Should().Be("azure, functions, serverless");
42+
note.Category.Should().Be("Technology");
43+
}
44+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using FluentAssertions;
2+
using NoteBookmark.Domain;
3+
using Xunit;
4+
5+
namespace NoteBookmark.Api.Tests.Domain;
6+
7+
public class PostLTests
8+
{
9+
[Fact]
10+
public void PostL_WhenCreated_HasCorrectDefaultValues()
11+
{
12+
// Act
13+
var postL = new PostL
14+
{
15+
PartitionKey = "posts",
16+
RowKey = "test-post"
17+
};
18+
19+
// Assert
20+
postL.Id.Should().BeNull();
21+
postL.Date_published.Should().BeNull();
22+
postL.is_read.Should().BeNull();
23+
postL.Title.Should().BeNull();
24+
postL.Url.Should().BeNull();
25+
postL.Note.Should().BeNull();
26+
postL.NoteId.Should().BeNull();
27+
}
28+
29+
[Fact]
30+
public void PostL_WhenPropertiesSet_ReturnsCorrectValues()
31+
{
32+
// Arrange
33+
var postL = new PostL
34+
{
35+
PartitionKey = "posts",
36+
RowKey = "post-123",
37+
Id = "test-id-123",
38+
Date_published = "2025-06-03",
39+
is_read = true,
40+
Title = "Azure Storage Best Practices",
41+
Url = "https://docs.microsoft.com/azure/storage",
42+
Note = "Excellent article with practical examples",
43+
NoteId = "note-456"
44+
};
45+
46+
// Assert
47+
postL.PartitionKey.Should().Be("posts");
48+
postL.RowKey.Should().Be("post-123");
49+
postL.Id.Should().Be("test-id-123");
50+
postL.Date_published.Should().Be("2025-06-03");
51+
postL.is_read.Should().BeTrue();
52+
postL.Title.Should().Be("Azure Storage Best Practices");
53+
postL.Url.Should().Be("https://docs.microsoft.com/azure/storage");
54+
postL.Note.Should().Be("Excellent article with practical examples");
55+
postL.NoteId.Should().Be("note-456");
56+
}
57+
58+
[Fact]
59+
public void PostL_Note_CanBeEmptyString()
60+
{
61+
// Arrange
62+
var postL = new PostL
63+
{
64+
PartitionKey = "posts",
65+
RowKey = "test-post",
66+
Note = ""
67+
};
68+
69+
// Assert
70+
postL.Note.Should().Be("");
71+
}
72+
73+
[Fact]
74+
public void PostL_NoteId_CanBeEmptyString()
75+
{
76+
// Arrange
77+
var postL = new PostL
78+
{
79+
PartitionKey = "posts",
80+
RowKey = "test-post",
81+
NoteId = ""
82+
};
83+
84+
// Assert
85+
postL.NoteId.Should().Be("");
86+
}
87+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using FluentAssertions;
2+
using NoteBookmark.Domain;
3+
using Xunit;
4+
5+
namespace NoteBookmark.Api.Tests.Domain;
6+
7+
public class PostTests
8+
{
9+
[Fact]
10+
public void Post_WhenCreated_HasCorrectDefaultValues()
11+
{
12+
// Act
13+
var post = new Post
14+
{
15+
PartitionKey = "posts",
16+
RowKey = "test-post"
17+
};
18+
19+
// Assert
20+
post.is_read.Should().BeNull();
21+
post.Title.Should().BeNull();
22+
post.Url.Should().BeNull();
23+
post.Author.Should().BeNull();
24+
post.Date_published.Should().BeNull();
25+
post.Id.Should().BeNull();
26+
}
27+
28+
[Fact]
29+
public void Post_WhenPropertiesSet_ReturnsCorrectValues()
30+
{
31+
// Arrange
32+
var post = new Post
33+
{
34+
PartitionKey = "posts",
35+
RowKey = "test-post-123",
36+
Title = "Azure Functions Best Practices",
37+
Url = "https://docs.microsoft.com/azure/functions",
38+
Author = "Microsoft",
39+
Date_published = "2025-06-03",
40+
is_read = true,
41+
Id = "func-123"
42+
};
43+
44+
// Assert
45+
post.PartitionKey.Should().Be("posts");
46+
post.RowKey.Should().Be("test-post-123");
47+
post.Title.Should().Be("Azure Functions Best Practices");
48+
post.Url.Should().Be("https://docs.microsoft.com/azure/functions");
49+
post.Author.Should().Be("Microsoft");
50+
post.Date_published.Should().Be("2025-06-03");
51+
post.is_read.Should().BeTrue();
52+
post.Id.Should().Be("func-123");
53+
}
54+
55+
[Theory]
56+
[InlineData(true)]
57+
[InlineData(false)]
58+
[InlineData(null)]
59+
public void Post_is_read_CanBeSetToAnyBooleanValue(bool? readStatus)
60+
{
61+
// Arrange
62+
var post = new Post
63+
{
64+
PartitionKey = "posts",
65+
RowKey = "test-post"
66+
};
67+
68+
// Act
69+
post.is_read = readStatus;
70+
71+
// Assert
72+
post.is_read.Should().Be(readStatus);
73+
}
74+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using FluentAssertions;
2+
using NoteBookmark.Domain;
3+
using Xunit;
4+
5+
namespace NoteBookmark.Api.Tests.Domain;
6+
7+
public class ReadingNoteTests
8+
{
9+
[Fact]
10+
public void ReadingNote_WhenCreated_HasCorrectDefaultValues()
11+
{
12+
// Act
13+
var readingNote = new ReadingNote();
14+
15+
// Assert
16+
readingNote.PostId.Should().BeNull();
17+
readingNote.Title.Should().BeNull();
18+
readingNote.Url.Should().BeNull();
19+
readingNote.Author.Should().BeNull();
20+
readingNote.Comment.Should().BeNull();
21+
readingNote.Tags.Should().BeNull();
22+
readingNote.Category.Should().BeNull();
23+
readingNote.ReadingNotesID.Should().BeNull();
24+
}
25+
26+
[Fact]
27+
public void ReadingNote_WhenPropertiesSet_ReturnsCorrectValues()
28+
{
29+
// Arrange
30+
var readingNote = new ReadingNote
31+
{
32+
PartitionKey = "reading-notes-123",
33+
RowKey = "note-456",
34+
PostId = "post-789",
35+
Title = "Azure Functions Performance Tips",
36+
Url = "https://docs.microsoft.com/azure/functions/performance",
37+
Author = "Azure Team",
38+
Comment = "Great insights on optimizing Azure Functions",
39+
Tags = "azure, functions, performance",
40+
Category = "Performance",
41+
ReadingNotesID = "reading-notes-123"
42+
};
43+
44+
// Assert
45+
readingNote.PartitionKey.Should().Be("reading-notes-123");
46+
readingNote.RowKey.Should().Be("note-456");
47+
readingNote.PostId.Should().Be("post-789");
48+
readingNote.Title.Should().Be("Azure Functions Performance Tips");
49+
readingNote.Url.Should().Be("https://docs.microsoft.com/azure/functions/performance");
50+
readingNote.Author.Should().Be("Azure Team");
51+
readingNote.Comment.Should().Be("Great insights on optimizing Azure Functions");
52+
readingNote.Tags.Should().Be("azure, functions, performance");
53+
readingNote.Category.Should().Be("Performance");
54+
readingNote.ReadingNotesID.Should().Be("reading-notes-123");
55+
}
56+
}

0 commit comments

Comments
 (0)