feat: discoverability (NodeInfo, hashtags) and moderation (domain/actor blocking)

- NodeInfo at /.well-known/nodeinfo + /nodeinfo/2.0
- Hashtags #MoviesDiary + #MovieTitle on review posts; /tags/{tag} redirect
- Domain blocking: blocked_domains table, admin API + HTML, inbox enforcement
- Per-actor blocking: blocked_actors table, user API + HTML, BlockActivity send/receive
- Delivery filter excludes blocked actors and blocked-domain inboxes
This commit is contained in:
2026-05-12 00:49:30 +02:00
parent 80f620c840
commit f0620f5aa1
40 changed files with 1410 additions and 543 deletions

View File

@@ -302,6 +302,38 @@ async fn get_api_movie_detail_returns_404_for_unknown_id() {
assert_eq!(response.status(), StatusCode::NOT_FOUND);
}
#[tokio::test]
async fn tags_moviesdiary_redirects_to_home() {
let app = test_app().await;
let response = app
.oneshot(with_ip(
Request::builder()
.uri("/tags/moviesdiary")
.body(Body::empty())
.unwrap(),
))
.await
.unwrap();
assert_eq!(response.status(), StatusCode::TEMPORARY_REDIRECT);
assert_eq!(response.headers().get("location").unwrap(), "/");
}
#[tokio::test]
async fn tags_other_redirects_to_search() {
let app = test_app().await;
let response = app
.oneshot(with_ip(
Request::builder()
.uri("/tags/batman")
.body(Body::empty())
.unwrap(),
))
.await
.unwrap();
assert_eq!(response.status(), StatusCode::TEMPORARY_REDIRECT);
assert_eq!(response.headers().get("location").unwrap(), "/?search=batman");
}
#[tokio::test]
async fn get_movie_detail_html_returns_404_for_unknown_id() {
let app = test_app().await;