feat: add blog feed (#3)

* chore: begin working on post service

* chore: add debug assets

* chore: add whitelist words

* feat: add prism for syntax highlighting

* feat: updated favicon

* feat: add blog feed

* fix: add link to written by image

* feat: add custom error pages

* fix: focus on h2 since h1 is always the journal site title

* feat: use status code pages with redirects

* fix: add discernible text to link

* feat: add support for light and dark theme

* fix: wrap body with main tag

* fix: style main element in pages to take up full width of container

* fix: add heading to home page

* feat: add not-found-corgi image

* chore: add robots.txt file

* chore: clean up place holder posts

* fix: namespace header in layouts

* fix: use logger instead of console

* fix: use new text context in each test when registering services

* chore: update workflow to debug failing tests

* chore: install playwright deps

* fix: extend expect timeout

* fix: extend expect timeout

* fix: capture traces

* fix: capture traces

* fix: index file name
This commit is contained in:
Stevan Freeborn
2024-04-10 01:28:38 -05:00
committed by GitHub
parent d25e5d4944
commit c4795dfdae
42 changed files with 16676 additions and 63 deletions
+23 -14
View File
@@ -1,6 +1,10 @@
using Blog.Posts;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Blog.Tests.EndToEnd;
@@ -31,13 +35,18 @@ public class BlogHostFactory<TProgram> : WebApplicationFactory<TProgram> where T
}
protected override IHost CreateHost(IHostBuilder builder)
{
{
var testHost = builder
.ConfigureWebHost(
webHostBuilder => webHostBuilder.ConfigureLogging(
config => config.ClearProviders()
)
)
.ConfigureWebHost(webHostBuilder =>
{
webHostBuilder.ConfigureLogging(config => config.ClearProviders());
webHostBuilder.ConfigureTestServices(services =>
{
var postsDirectory = Path.Combine(Directory.GetCurrentDirectory(), "TestPosts");
var postServiceOptions = new FilePostServiceOptions() { PostsDirectory = postsDirectory };
services.AddSingleton(Options.Create(postServiceOptions));
});
})
.Build();
builder.ConfigureWebHost(
@@ -46,17 +55,17 @@ public class BlogHostFactory<TProgram> : WebApplicationFactory<TProgram> where T
)
);
_host = builder.Build();
_host.Start();
_host = builder.Build();
_host.Start();
var server = _host.Services.GetRequiredService<IServer>();
var addresses = server.Features.GetRequiredFeature<IServerAddressesFeature>();
var server = _host.Services.GetRequiredService<IServer>();
var addresses = server.Features.GetRequiredFeature<IServerAddressesFeature>();
ClientOptions.BaseAddress = addresses.Addresses
.Select(x => new Uri(x))
ClientOptions.BaseAddress = addresses.Addresses
.Select(x => new Uri(x))
.Last();
testHost.Start();
return testHost;
testHost.Start();
return testHost;
}
}
+25
View File
@@ -14,4 +14,29 @@ public class BlogTest : PageTest
options.BaseURL = _factory.ServerAddress;
return options;
}
[SetUp]
public async Task Setup()
{
await Context.Tracing.StartAsync(new()
{
Title = TestContext.CurrentContext.Test.ClassName + "." + TestContext.CurrentContext.Test.Name,
Screenshots = true,
Snapshots = true,
Sources = true
});
}
[TearDown]
public async Task TearDown()
{
await Context.Tracing.StopAsync(new()
{
Path = Path.Combine(
TestContext.CurrentContext.WorkDirectory,
"playwright-traces",
$"{TestContext.CurrentContext.Test.ClassName}.{TestContext.CurrentContext.Test.Name}.zip"
)
});
}
}
+17 -1
View File
@@ -15,7 +15,7 @@ public class HomeTests : BlogTest
public async Task Home_WhenNavigatedTo_ItShouldCorrectSiteTitle()
{
await Page.GotoAsync("/");
var message = Page.GetByRole(AriaRole.Heading, new () { Name = "journal" });
var message = Page.GetByRole(AriaRole.Heading, new() { Name = "journal" });
await Expect(message).ToBeVisibleAsync();
}
@@ -29,4 +29,20 @@ public class HomeTests : BlogTest
await Expect(message).ToBeVisibleAsync();
await Expect(image).ToBeVisibleAsync();
}
[Test]
public async Task Home_WhenNavigatedTo_ItShouldDisplayPostFeed()
{
await Page.GotoAsync("/");
var feed = Page.GetByRole(AriaRole.Feed);
await Expect(feed).ToBeVisibleAsync();
}
[Test]
public async Task Home_WhenNavigatedTo_ItShouldDisplayPosts()
{
await Page.GotoAsync("/");
var posts = Page.GetByRole(AriaRole.Article);
await Expect(posts).ToHaveCountAsync(2);
}
}
@@ -0,0 +1,76 @@
# Test Blog
```json meta
{
"title": "Another Test Blog",
"lead": "This is a test blog post",
"isPublished": true,
"publishedAt": "2020-01-01"
}
```
Welcome to my Markdown blog post! In this post, I'll cover various Markdown elements to help you test styling.
## Text Formatting
Here are some examples of text formatting:
- *Italic Text*
- **Bold Text**
- ***Bold Italic Text***
- ~~Strikethrough Text~~
## Lists
### Unordered List
- Item 1
- Item 2
- Subitem A
- Subitem B
- Item 3
### Ordered List
1. First item
2. Second item
3. Third item
## Links and Images
### Link
[OpenAI](https://openai.com) - An amazing AI research organization.
### Image
![Markdown Logo](https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Markdown-mark.svg/1920px-Markdown-mark.svg.png)
## Blockquotes
> Markdown is a lightweight markup language with plain-text formatting syntax.
## Code Blocks
```python
def greet(name):
print(f"Hello, {name}!")
greet("World")
```
## Tables
| Name | Age |
|-------|-----|
| Alice | 30 |
| Bob | 25 |
| Carol | 35 |
## Horizontal Rule
---
## Conclusion
That's it for this Markdown blog post! Feel free to experiment with styling these elements further.
@@ -0,0 +1,76 @@
# Test Blog
```json meta
{
"title": "Test Blog",
"lead": "This is a test blog post.",
"isPublished": true,
"publishedAt": "2021-01-01"
}
```
Welcome to my Markdown blog post! In this post, I'll cover various Markdown elements to help you test styling.
## Text Formatting
Here are some examples of text formatting:
- *Italic Text*
- **Bold Text**
- ***Bold Italic Text***
- ~~Strikethrough Text~~
## Lists
### Unordered List
- Item 1
- Item 2
- Subitem A
- Subitem B
- Item 3
### Ordered List
1. First item
2. Second item
3. Third item
## Links and Images
### Link
[OpenAI](https://openai.com) - An amazing AI research organization.
### Image
![Markdown Logo](https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Markdown-mark.svg/1920px-Markdown-mark.svg.png)
## Blockquotes
> Markdown is a lightweight markup language with plain-text formatting syntax.
## Code Blocks
```python
def greet(name):
print(f"Hello, {name}!")
greet("World")
```
## Tables
| Name | Age |
|-------|-----|
| Alice | 30 |
| Bob | 25 |
| Carol | 35 |
## Horizontal Rule
---
## Conclusion
That's it for this Markdown blog post! Feel free to experiment with styling these elements further.