Skip to content

Commit

Permalink
Test empty request errors
Browse files Browse the repository at this point in the history
  • Loading branch information
dcadenas committed Apr 1, 2024
1 parent a955c65 commit 49bf378
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 27 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ serde_json = "1.0.115"
slack-morphism = { version = "2.1.0", features = ["axum"] }
tokio = { version = "1.36.0", features = ["full"] }
tokio-util = { version = "0.7.10", features = ["rt"] }
tower = "0.4.13"
tower-http = { version = "0.5.2", features = ["timeout", "trace"] }
tower-layer = "0.3.2"
tracing = "0.1.40"
Expand Down
2 changes: 1 addition & 1 deletion src/actors/gift_unwrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ mod tests {

let messages_received = Arc::new(Mutex::new(Vec::<ReportRequest>::new()));
let (receiver_actor_ref, receiver_actor_handle) =
Actor::spawn(None, TestActor::default(), messages_received.clone())
Actor::spawn(None, TestActor::default(), Some(messages_received.clone()))
.await
.unwrap();

Expand Down
2 changes: 1 addition & 1 deletion src/actors/relay_event_dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ mod tests {
let received_messages = Arc::new(Mutex::new(Vec::<GiftWrappedReportRequest>::new()));

let (receiver_ref, receiver_handle) =
Actor::spawn(None, TestActor::default(), received_messages.clone())
Actor::spawn(None, TestActor::default(), Some(received_messages.clone()))
.await
.unwrap();

Expand Down
2 changes: 1 addition & 1 deletion src/actors/utilities/output_port_subscriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::fmt::Debug;

pub type OutputPortSubscriber<InputMessage> = Box<dyn OutputPortSubscriberTrait<InputMessage>>;

pub trait OutputPortSubscriberTrait<I>: Debug + Send
pub trait OutputPortSubscriberTrait<I>: Debug + Send + Sync
where
I: Send + Clone + Debug + 'static,
{
Expand Down
22 changes: 18 additions & 4 deletions src/actors/utilities/test_actor.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
use anyhow::Result;
use ractor::SpawnErr;
use ractor::{Actor, ActorProcessingErr, ActorRef};
use std::sync::Arc;
use tokio::sync::Mutex;
use tokio::task::JoinHandle;

pub type TestActorMessagesReceived<T> = Arc<Mutex<Vec<T>>>;
pub struct TestActor<T> {
_phantom: std::marker::PhantomData<T>,
}

impl<T> TestActor<T>
where
T: Send + Sync + 'static,
{
pub async fn spawn_default() -> Result<(ActorRef<T>, JoinHandle<()>), SpawnErr> {
Actor::spawn(None, TestActor::<T>::default(), None).await
}
}

impl<T> Default for TestActor<T> {
fn default() -> Self {
Self {
Expand All @@ -17,7 +28,7 @@ impl<T> Default for TestActor<T> {
}

pub struct TestActorState<T> {
pub messages_received: TestActorMessagesReceived<T>,
pub messages_received: Option<TestActorMessagesReceived<T>>,
}

#[ractor::async_trait]
Expand All @@ -27,12 +38,12 @@ where
{
type Msg = T;
type State = TestActorState<T>;
type Arguments = TestActorMessagesReceived<T>;
type Arguments = Option<TestActorMessagesReceived<T>>;

async fn pre_start(
&self,
_: ActorRef<Self::Msg>,
messages_received: TestActorMessagesReceived<T>,
messages_received: Option<TestActorMessagesReceived<T>>,
) -> Result<Self::State, ActorProcessingErr> {
let state = TestActorState { messages_received };
Ok(state)
Expand All @@ -44,7 +55,10 @@ where
message: Self::Msg,
state: &mut Self::State,
) -> Result<(), ActorProcessingErr> {
state.messages_received.lock().await.push(message);
if let Some(messages_received) = &state.messages_received {
messages_received.lock().await.push(message);
};

Ok(())
}
}
8 changes: 0 additions & 8 deletions src/adapters/http_server/app_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use axum::{
#[derive(Debug)]
enum AppErrorKind {
General(Error),
MissingResponseUrl,
// TODO: Let's be more specific later
SlackParsingError(String),
}
Expand All @@ -22,10 +21,6 @@ impl AppError {
Self { kind }
}

pub fn missing_response_url() -> Self {
Self::new(AppErrorKind::MissingResponseUrl)
}

pub fn slack_parsing_error(context: &str) -> Self {
Self::new(AppErrorKind::SlackParsingError(context.to_string()))
}
Expand All @@ -39,9 +34,6 @@ impl IntoResponse for AppError {
format!("Something went wrong: {}", err),
)
.into_response(),
AppErrorKind::MissingResponseUrl => {
(StatusCode::BAD_REQUEST, "Missing response URL.".to_string()).into_response()
}
AppErrorKind::SlackParsingError(context) => (
StatusCode::BAD_REQUEST,
format!("Slack parsing error: {}.", context),
Expand Down
52 changes: 44 additions & 8 deletions src/adapters/http_server/slack_interactions_route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ pub fn slack_interactions_route() -> Result<Router<WebAppState>> {
.context("Missing SLACK_SIGNING_SECRET")
.map(|secret| secret.into())?;
let listener = SlackEventsAxumListener::<SlackHyperHttpsConnector>::new(listener_environment);
let slack_layer = listener
.events_layer(&signing_secret)
.with_event_extractor(SlackEventsExtractors::interaction_event());

Ok(Router::new().route(
let route = Router::new().route(
"/slack/interactions",
post(slack_interaction_handler).layer(
listener
.events_layer(&signing_secret)
.with_event_extractor(SlackEventsExtractors::interaction_event()),
),
))
post(slack_interaction_handler).layer(slack_layer),
);

Ok(route)
}

fn prepare_slack_client() -> Result<Arc<SlackHyperClient>> {
Expand Down Expand Up @@ -117,7 +118,6 @@ fn parse_slack_action(
.map_err(|_| AppError::slack_parsing_error("reporter_pubkey"))?;

let report_request = ReportRequest::new(reported_event, reporter_pubkey, Some(reporter_text));

let maybe_category = ModerationCategory::from_str(action_id).ok();
let maybe_moderated_report = report_request.report(maybe_category)?;

Expand Down Expand Up @@ -188,7 +188,43 @@ fn slack_error_handler(
#[cfg(test)]
mod tests {
use super::*;
use crate::actors::TestActor;
use axum::{
body::Body,
http::{Request, StatusCode},
};
use handlebars::Handlebars;
use http_body_util::BodyExt;
use serde_json::json;
use tower::ServiceExt;

#[tokio::test]
async fn test_fails_with_empty_request() {
let (test_actor_ref, _receiver_actor_handle) =
TestActor::<RelayEventDispatcherMessage>::spawn_default()
.await
.unwrap();
let state = WebAppState {
event_dispatcher: test_actor_ref,
hb: Arc::new(Handlebars::new()),
};

let router = slack_interactions_route().unwrap().with_state(state);

let response = router
.oneshot(
Request::builder()
.uri("/slack/interactions")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();

assert_eq!(response.status(), StatusCode::BAD_REQUEST);
let body = response.into_body().collect().await.unwrap().to_bytes();
assert!(body.is_empty());
}

#[test]
fn test_parse_slack_action_with_hateful() {
Expand Down
1 change: 1 addition & 0 deletions src/domain_objects/gift_wrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ impl GiftWrappedReportRequest {
GiftWrappedReportRequest(event)
}

#[allow(unused)]
pub fn as_json(&self) -> String {
self.0.as_json()
}
Expand Down
4 changes: 0 additions & 4 deletions src/domain_objects/moderated_report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,6 @@ impl ModeratedReport {
pub fn event(&self) -> Event {
self.event.clone()
}

pub fn to_json(&self) -> String {
serde_json::to_string(self).expect("Failed to serialize ModeratedReport to JSON")
}
}

impl Display for ModeratedReport {
Expand Down

0 comments on commit 49bf378

Please sign in to comment.