Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions ocg-server/src/handlers/community.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
activity_tracker::{Activity, DynActivityTracker},
db::DynDB,
handlers::{
error::HandlerError, extractors::CommunityId, prepare_headers, request_matches_site,
error::HandlerError, prepare_headers, request_matches_site, site::not_found,
trim_public_gallery_images,
},
templates::{PageId, auth::User, community},
Expand All @@ -34,21 +34,22 @@ mod tests;
#[instrument(skip_all, err)]
pub(crate) async fn page(
State(db): State<DynDB>,
CommunityId(community_id): CommunityId,
Path(community_name): Path<String>,
uri: Uri,
) -> Result<impl IntoResponse, HandlerError> {
// Get community and site settings
let (community_id, site_settings) = tokio::try_join!(
db.get_community_id_by_name(&community_name),
db.get_site_settings()
)?;
let Some(community_id) = community_id else {
return not_found::render(site_settings);
};

// Prepare template
let (
mut community,
recently_added_groups,
site_settings,
upcoming_in_person_events,
upcoming_virtual_events,
stats,
) = tokio::try_join!(
let (mut community, recently_added_groups, upcoming_in_person_events, upcoming_virtual_events, stats) = tokio::try_join!(
db.get_community_full(community_id),
db.get_community_recently_added_groups(community_id),
db.get_site_settings(),
db.get_community_upcoming_events(community_id, vec![EventKind::InPerson, EventKind::Hybrid]),
db.get_community_upcoming_events(community_id, vec![EventKind::Virtual, EventKind::Hybrid]),
db.get_community_site_stats(community_id),
Expand Down Expand Up @@ -78,7 +79,7 @@ pub(crate) async fn page(
// Prepare response headers
let headers = prepare_headers(Duration::hours(1), &[])?;

Ok((headers, Html(template.render()?)))
Ok((headers, Html(template.render()?)).into_response())
}

// Actions handlers.
Expand Down
41 changes: 41 additions & 0 deletions ocg-server/src/handlers/community/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,47 @@ async fn test_page_success() {
assert!(!bytes.is_empty());
}

#[tokio::test]
async fn test_page_community_not_found() {
// Setup database mock
let mut db = MockDB::new();
db.expect_get_community_id_by_name()
.times(1)
.withf(|name| name == "missing-community")
.returning(|_| Ok(None));
db.expect_get_site_settings()
.times(1)
.returning(|| Ok(sample_site_settings()));

// Setup notifications manager mock
let nm = MockNotificationsManager::new();

// Setup router and send request
let router = TestRouterBuilder::new(db, nm).build().await;
let request = Request::builder()
.method("GET")
.uri("/missing-community")
.body(Body::empty())
.unwrap();
let response = router.oneshot(request).await.unwrap();
let (parts, body) = response.into_parts();
let bytes = to_bytes(body, usize::MAX).await.unwrap();

// Check response matches expectations
assert_eq!(parts.status, StatusCode::NOT_FOUND);
assert_eq!(
parts.headers.get(CONTENT_TYPE).unwrap(),
&HeaderValue::from_static("text/html; charset=utf-8")
);
assert_eq!(
parts.headers.get(CACHE_CONTROL).unwrap(),
&HeaderValue::from_static("max-age=300")
);
let body = String::from_utf8(bytes.to_vec()).unwrap();
assert!(body.contains("We could not find that page"));
assert!(body.contains("Go to home page"));
}

#[tokio::test]
async fn test_page_db_error() {
// Setup identifiers and data structures
Expand Down
31 changes: 23 additions & 8 deletions ocg-server/src/handlers/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ use crate::{
db::{DynDB, payments::PrepareEventCheckoutPurchaseInput},
handlers::{
extractors::{CurrentUser, ValidatedForm, ValidatedFormQs},
prepare_headers, request_matches_site, trim_public_gallery_images,
prepare_headers, request_matches_site,
site::not_found,
trim_public_gallery_images,
},
router::CACHE_CONTROL_NO_CACHE,
services::{
Expand Down Expand Up @@ -55,17 +57,30 @@ mod tests;
#[instrument(skip_all)]
pub(crate) async fn page(
State(db): State<DynDB>,
CommunityId(community_id): CommunityId,
Path((_, group_slug, event_slug)): Path<(String, String, String)>,
Path((community_name, group_slug, event_slug)): Path<(String, String, String)>,
uri: Uri,
) -> Result<impl IntoResponse, HandlerError> {
// Prepare template
let (event, site_settings) = tokio::try_join!(
db.get_event_full_by_slug(community_id, &group_slug, &event_slug),
// Get community and site settings
let (community_id, site_settings) = tokio::try_join!(
db.get_community_id_by_name(&community_name),
db.get_site_settings()
)?;
let mut event = event.ok_or(HandlerError::NotFound)?;
let Some(community_id) = community_id else {
return not_found::render(site_settings);
};

// Fetch event page data
let event = db
.get_event_full_by_slug(community_id, &group_slug, &event_slug)
.await?;
let Some(mut event) = event else {
return not_found::render(site_settings);
};

// Trim gallery media
trim_public_gallery_images(&mut event.photos_urls);

// Prepare template
let template = Page {
event,
page_id: PageId::Event,
Expand All @@ -77,7 +92,7 @@ pub(crate) async fn page(
// Prepare response headers
let headers = prepare_headers(Duration::hours(1), &[])?;

Ok((headers, Html(template.render()?)))
Ok((headers, Html(template.render()?)).into_response())
}

/// Handler that renders the check-in page.
Expand Down
62 changes: 58 additions & 4 deletions ocg-server/src/handlers/event/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,15 @@ async fn test_page_success() {
.times(1)
.withf(|name| name == "test-community")
.returning(move |_| Ok(Some(community_id)));
db.expect_get_site_settings()
.times(1)
.returning(|| Ok(sample_site_settings()));
db.expect_get_event_full_by_slug()
.times(1)
.withf(move |id, group_slug, event_slug| {
*id == community_id && group_slug == "test-group" && event_slug == "test-event"
})
.returning(move |_, _, _| Ok(Some(sample_event_full(community_id, event_id, group_id))));
db.expect_get_site_settings()
.times(1)
.returning(|| Ok(sample_site_settings()));

// Setup notifications manager mock
let nm = MockNotificationsManager::new();
Expand Down Expand Up @@ -156,6 +156,47 @@ async fn test_page_success() {
assert!(!bytes.is_empty());
}

#[tokio::test]
async fn test_page_community_not_found() {
// Setup database mock
let mut db = MockDB::new();
db.expect_get_community_id_by_name()
.times(1)
.withf(|name| name == "missing-community")
.returning(|_| Ok(None));
db.expect_get_site_settings()
.times(1)
.returning(|| Ok(sample_site_settings()));

// Setup notifications manager mock
let nm = MockNotificationsManager::new();

// Setup router and send request
let router = TestRouterBuilder::new(db, nm).build().await;
let request = Request::builder()
.method("GET")
.uri("/missing-community/group/test-group/event/test-event")
.body(Body::empty())
.unwrap();
let response = router.oneshot(request).await.unwrap();
let (parts, body) = response.into_parts();
let bytes = to_bytes(body, usize::MAX).await.unwrap();

// Check response matches expectations
assert_eq!(parts.status, StatusCode::NOT_FOUND);
assert_eq!(
parts.headers.get(CONTENT_TYPE).unwrap(),
&HeaderValue::from_static("text/html; charset=utf-8")
);
assert_eq!(
parts.headers.get(CACHE_CONTROL).unwrap(),
&HeaderValue::from_static("max-age=300")
);
let body = String::from_utf8(bytes.to_vec()).unwrap();
assert!(body.contains("We could not find that page"));
assert!(body.contains("Go to home page"));
}

#[tokio::test]
async fn test_page_not_found() {
// Setup identifiers and data structures
Expand Down Expand Up @@ -193,7 +234,17 @@ async fn test_page_not_found() {

// Check response matches expectations
assert_eq!(parts.status, StatusCode::NOT_FOUND);
assert!(bytes.is_empty());
assert_eq!(
parts.headers.get(CONTENT_TYPE).unwrap(),
&HeaderValue::from_static("text/html; charset=utf-8")
);
assert_eq!(
parts.headers.get(CACHE_CONTROL).unwrap(),
&HeaderValue::from_static("max-age=300")
);
let body = String::from_utf8(bytes.to_vec()).unwrap();
assert!(body.contains("We could not find that page"));
assert!(body.contains("Go to home page"));
}

#[tokio::test]
Expand All @@ -207,6 +258,9 @@ async fn test_page_db_error() {
.times(1)
.withf(|name| name == "test-community")
.returning(move |_| Ok(Some(community_id)));
db.expect_get_site_settings()
.times(1)
.returning(|| Ok(sample_site_settings()));
db.expect_get_event_full_by_slug()
.times(1)
.withf(move |id, group_slug, event_slug| {
Expand Down
26 changes: 19 additions & 7 deletions ocg-server/src/handlers/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use crate::{
activity_tracker::{Activity, DynActivityTracker},
config::HttpServerConfig,
db::DynDB,
handlers::{extractors::CurrentUser, prepare_headers, request_matches_site, trim_public_gallery_images},
handlers::{
extractors::CurrentUser, prepare_headers, request_matches_site, site::not_found,
trim_public_gallery_images,
},
services::notifications::{DynNotificationsManager, NewNotification, NotificationKind},
templates::{
PageId,
Expand All @@ -38,19 +41,28 @@ mod tests;
#[instrument(skip_all)]
pub(crate) async fn page(
State(db): State<DynDB>,
CommunityId(community_id): CommunityId,
Path((_, group_slug)): Path<(String, String)>,
Path((community_name, group_slug)): Path<(String, String)>,
uri: Uri,
) -> Result<impl IntoResponse, HandlerError> {
// Get community and site settings
let (community_id, site_settings) = tokio::try_join!(
db.get_community_id_by_name(&community_name),
db.get_site_settings()
)?;
let Some(community_id) = community_id else {
return not_found::render(site_settings);
};

// Fetch the group page data
let event_kinds = vec![EventKind::InPerson, EventKind::Virtual, EventKind::Hybrid];
let (group, past_events, site_settings, upcoming_events) = tokio::try_join!(
let (group, past_events, upcoming_events) = tokio::try_join!(
db.get_group_full_by_slug(community_id, &group_slug),
db.get_group_past_events(community_id, &group_slug, event_kinds.clone(), 9),
db.get_site_settings(),
db.get_group_upcoming_events(community_id, &group_slug, event_kinds, 9)
)?;
let mut group = group.ok_or(HandlerError::NotFound)?;
let Some(mut group) = group else {
return not_found::render(site_settings);
};

// Trim gallery media
trim_public_gallery_images(&mut group.photos_urls);
Expand Down Expand Up @@ -78,7 +90,7 @@ pub(crate) async fn page(
// Prepare response headers
let headers = prepare_headers(Duration::hours(1), &[])?;

Ok((headers, Html(template.render()?)))
Ok((headers, Html(template.render()?)).into_response())
}

// Actions handlers.
Expand Down
Loading
Loading