This commit is contained in:
Phil Booth 2018-10-29 10:48:01 +00:00
Родитель 03f19145e7
Коммит 2057d57ac7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 36FBB106F9C32516
22 изменённых файлов: 131 добавлений и 81 удалений

Просмотреть файл

@ -1,3 +1,2 @@
merge_imports = true
use_field_init_shorthand = true
wrap_comments = true

Просмотреть файл

@ -83,7 +83,8 @@ impl Db for DbClient {
problem_type,
problem_subtype,
created_at: 0,
}).send()?;
})
.send()?;
match response.status() {
StatusCode::Ok => Ok(()),
status => Err(AppErrorKind::AuthDbError(format!("{}", status)).into()),

Просмотреть файл

@ -27,7 +27,8 @@ fn create_bounce() {
&email_addresses[0],
ProblemType::HardBounce,
ProblemSubtype::General,
).and_then(|_| db.get_bounces(&email_addresses[0]))
)
.and_then(|_| db.get_bounces(&email_addresses[0]))
.expect("db error");
let now = now_as_milliseconds();
@ -50,13 +51,15 @@ fn create_bounce() {
&email_addresses[1],
ProblemType::SoftBounce,
ProblemSubtype::MailboxFull,
).and_then(|_| {
)
.and_then(|_| {
db.create_bounce(
&email_addresses[1],
ProblemType::Complaint,
ProblemSubtype::Virus,
)
}).and_then(|_| db.get_bounces(&email_addresses[1]))
})
.and_then(|_| db.get_bounces(&email_addresses[1]))
.expect("db error");
let now = now_as_milliseconds();
@ -80,7 +83,8 @@ fn generate_email_address(variant: &str) -> EmailAddress {
"fxa-email-service.test.auth-db.{}.{}@example.com",
variant,
now_as_milliseconds()
).parse()
)
.parse()
.unwrap()
}

Просмотреть файл

@ -85,7 +85,8 @@ fn main() {
);
}
Ok(Loop::Continue(total_count))
}).or_else(move |error: AppError| {
})
.or_else(move |error: AppError| {
let logger = MozlogLogger(slog_scope::logger());
let log = MozlogLogger::with_app_error(&logger, &error)
.expect("MozlogLogger::with_app_error error");

Просмотреть файл

@ -16,14 +16,7 @@
extern crate fxa_email_service;
extern crate rocket;
#[macro_use(
slog_b,
slog_info,
slog_kv,
slog_log,
slog_record,
slog_record_static
)]
#[macro_use(slog_b, slog_info, slog_kv, slog_log, slog_record, slog_record_static)]
extern crate slog;
#[macro_use]
extern crate sentry;

Просмотреть файл

@ -44,7 +44,8 @@ impl Client {
Self {
client: RedisClient::open(
format!("redis://{}:{}/", settings.redis.host, settings.redis.port).as_str(),
).expect("redis connection error"),
)
.expect("redis connection error"),
hmac_key: settings.hmackey.clone(),
}
}

Просмотреть файл

@ -29,7 +29,8 @@ impl TestFixture {
internal_key,
redis_client: RedisClient::open(
format!("redis://{}:{}/", settings.redis.host, settings.redis.port).as_str(),
).unwrap(),
)
.unwrap(),
}
}

Просмотреть файл

@ -78,23 +78,27 @@ where
address: address.clone(),
time: problem.created_at,
problem: From::from(problem.clone()),
}.into()),
}
.into()),
ProblemType::SoftBounce => Err(AppErrorKind::BounceSoftError {
address: address.clone(),
time: problem.created_at,
problem: From::from(problem.clone()),
}.into()),
}
.into()),
ProblemType::Complaint => Err(AppErrorKind::ComplaintError {
address: address.clone(),
time: problem.created_at,
problem: From::from(problem.clone()),
}.into()),
}
.into()),
};
}
}
Ok(counts)
}).map(|_| ())
})
.map(|_| ())
}
/// Record a hard or soft bounce

Просмотреть файл

@ -36,7 +36,8 @@ fn check_no_bounces() {
{ "period": "month", "limit": 0 }
]
}"#,
).expect("Unexpected json parsing error");
)
.expect("Unexpected json parsing error");
let settings = create_settings(bounce_settings);
let db = DbMockNoBounce;
let problems = DeliveryProblems::new(&settings, db);
@ -100,7 +101,8 @@ fn check_soft_bounce() {
"hard": [],
"complaint": []
}"#,
).expect("Unexpected json parsing error");
)
.expect("Unexpected json parsing error");
let settings = create_settings(bounce_settings);
let db = DbMockBounceSoft;
let problems = DeliveryProblems::new(&settings, db);
@ -151,7 +153,8 @@ fn check_hard_bounce() {
],
"complaint": []
}"#,
).expect("Unexpected json parsing error");
)
.expect("Unexpected json parsing error");
let settings = create_settings(bounce_settings);
let db = DbMockBounceHard;
let problems = DeliveryProblems::new(&settings, db);
@ -202,7 +205,8 @@ fn check_complaint() {
{ "period": "month", "limit": 0 }
]
}"#,
).expect("Unexpected json parsing error");
)
.expect("Unexpected json parsing error");
let settings = create_settings(bounce_settings);
let db = DbMockComplaint;
let problems = DeliveryProblems::new(&settings, db);
@ -257,7 +261,8 @@ fn check_db_error() {
{ "period": "month", "limit": 0 }
]
}"#,
).expect("Unexpected json parsing error");
)
.expect("Unexpected json parsing error");
let settings = create_settings(bounce_settings);
let db = DbMockError;
let problems = DeliveryProblems::new(&settings, db);
@ -294,7 +299,8 @@ fn check_no_bounces_with_nonzero_limits() {
{ "period": "month", "limit": 2 }
]
}"#,
).expect("Unexpected json parsing error");
)
.expect("Unexpected json parsing error");
let settings = create_settings(bounce_settings);
let db = DbMockNoBounceWithNonZeroLimits;
let problems = DeliveryProblems::new(&settings, db);
@ -381,7 +387,8 @@ fn check_bounce_with_multiple_limits() {
"hard": [],
"complaint": []
}"#,
).expect("Unexpected json parsing error");
)
.expect("Unexpected json parsing error");
let settings = create_settings(bounce_settings);
let db = DbMockBounceWithMultipleLimits;
let problems = DeliveryProblems::new(&settings, db);
@ -453,7 +460,8 @@ fn record_bounce() {
&address,
BounceType::Transient,
BounceSubtype::AttachmentRejected,
).unwrap();
)
.unwrap();
test.assert_set();
@ -498,7 +506,8 @@ fn create_address(test: &str) -> EmailAddress {
"fxa-email-service.bounces.test.{}.{}@example.com",
test,
now_as_milliseconds()
).parse()
)
.parse()
.unwrap()
}

Просмотреть файл

@ -85,7 +85,8 @@ fn successful_version() {
"commit": "TBD",
"source": "https://github.com/mozilla/fxa-email-service",
"version": "TBD"
}).to_string()
})
.to_string()
);
assert_eq!(response.status(), Status::Ok);
}

Просмотреть файл

@ -62,7 +62,8 @@ fn build_multipart_mime(
SinglePart::quoted_printable()
.with_header(header::ContentType(
"text/plain; charset=utf8".parse().unwrap(),
)).with_body(body_text.to_owned()),
))
.with_body(body_text.to_owned()),
);
if let Some(body_html) = body_html {
body = body.with_multipart(
@ -70,7 +71,8 @@ fn build_multipart_mime(
SinglePart::eight_bit()
.with_header(header::ContentType(
"text/html; charset=utf8".parse().unwrap(),
)).with_body(body_html.to_owned()),
))
.with_body(body_html.to_owned()),
),
)
}

Просмотреть файл

@ -89,14 +89,17 @@ impl Provider for SendgridProvider {
description: String::from(
"Missing or duplicate X-Message-Id header in Sendgrid response",
),
}.into(),
).and_then(|message_id| from_utf8(message_id).map_err(From::from))
}
.into(),
)
.and_then(|message_id| from_utf8(message_id).map_err(From::from))
.map(|message_id| message_id.to_string())
} else {
Err(AppErrorKind::ProviderError {
name: String::from("Sendgrid"),
description: format!("Unsuccesful response status: {}", status),
}.into())
}
.into())
}
})
}
@ -107,7 +110,8 @@ impl From<SendgridError> for AppError {
AppErrorKind::ProviderError {
name: String::from("Sendgrid"),
description: format!("{:?}", error),
}.into()
}
.into()
}
}
@ -116,6 +120,7 @@ impl From<Utf8Error> for AppError {
AppErrorKind::ProviderError {
name: String::from("Sendgrid"),
description: format!("Failed to decode string as UTF-8: {:?}", error),
}.into()
}
.into()
}
}

Просмотреть файл

@ -90,6 +90,7 @@ impl From<SendRawEmailError> for AppError {
AppErrorKind::ProviderError {
name: String::from("SES"),
description: format!("{:?}", error),
}.into()
}
.into()
}
}

Просмотреть файл

@ -74,7 +74,8 @@ impl Provider for SmtpProvider {
Err(AppErrorKind::ProviderError {
name: String::from("Smtp"),
description: format!("{:?}", result),
}.into())
}
.into())
}
}
}
@ -84,7 +85,8 @@ impl From<SmtpError> for AppError {
AppErrorKind::ProviderError {
name: String::from("Smtp"),
description: format!("{:?}", error),
}.into()
}
.into()
}
}
@ -93,6 +95,7 @@ impl From<EmailError> for AppError {
AppErrorKind::ProviderError {
name: String::from("Smtp"),
description: format!("{:?}", error),
}.into()
}
.into()
}
}

Просмотреть файл

@ -59,7 +59,8 @@ impl Provider for SocketLabsProvider {
self.settings.serverid,
self.settings.key.clone(),
vec![message],
)?.send()
)?
.send()
.map_err(From::from)
.and_then(|response| {
if response.error_code == PostMessageErrorCode::Success {
@ -68,7 +69,8 @@ impl Provider for SocketLabsProvider {
Err(AppErrorKind::ProviderError {
name: String::from("SocketLabs"),
description: format!("{:?}: {}", response.error_code, response.error_code),
}.into())
}
.into())
}
})
}
@ -79,6 +81,7 @@ impl From<SocketLabsError> for AppError {
AppErrorKind::ProviderError {
name: String::from("SocketLabs"),
description: format!("{}", error),
}.into()
}
.into()
}
}

Просмотреть файл

@ -33,7 +33,8 @@ fn build_mime_with_cc_headers() {
"subject",
"body",
None,
).unwrap();
)
.unwrap();
let message: Vec<String> = format!("{}", message)
.split("\r\n")
.map(|s| s.to_owned())
@ -60,7 +61,8 @@ fn build_mime_with_custom_headers() {
"subject",
"body",
None,
).unwrap();
)
.unwrap();
let message: Vec<String> = format!("{}", message)
.split("\r\n")
.map(|s| s.to_owned())
@ -85,7 +87,8 @@ fn build_mime_with_body_html() {
"subject",
"body",
Some("<p>body</p>"),
).unwrap();
)
.unwrap();
let message: Vec<String> = format!("{}", message)
.split("\r\n")
.map(|s| s.to_owned())

Просмотреть файл

@ -34,11 +34,9 @@ impl Incoming for Queue {
bounce_message.notification.bounce = Some(Bounce {
bounce_type: BounceType::Permanent,
bounce_subtype: BounceSubtype::General,
bounced_recipients: vec![
"fxa-email-service.queues.mock.bounce@example.com"
.parse()
.unwrap(),
],
bounced_recipients: vec!["fxa-email-service.queues.mock.bounce@example.com"
.parse()
.unwrap()],
timestamp: Utc::now(),
});
bounce_message
@ -64,11 +62,9 @@ impl Incoming for Queue {
delivery_message.notification.notification_type = NotificationType::Delivery;
delivery_message.notification.delivery = Some(Delivery {
timestamp: Utc::now(),
recipients: vec![
"fxa-email-service.queues.mock.delivery@example.com"
.parse()
.unwrap(),
],
recipients: vec!["fxa-email-service.queues.mock.delivery@example.com"
.parse()
.unwrap()],
});
delivery_message
}

Просмотреть файл

@ -97,7 +97,8 @@ impl Queues {
.join3(
self.process_queue(&self.complaint_queue),
self.process_queue(&self.delivery_queue),
).map(|results| results.0 + results.1 + results.2);
)
.map(|results| results.0 + results.1 + results.2);
Box::new(joined_futures)
}
@ -116,7 +117,8 @@ impl Queues {
}
}
future::join_all(futures.into_iter())
}).map(|results| results.len());
})
.map(|results| results.len());
Box::new(future)
}
@ -143,7 +145,8 @@ impl Queues {
.map(|id| {
info!("{}", "Sent message to notification queue"; "id" => id);
()
}).or_else(|error| {
})
.or_else(|error| {
// Errors sending to this queue are non-fatal because it's only used
// for logging. We still want to delete the message from the queue.
let logger = MozlogLogger(slog_scope::logger());

Просмотреть файл

@ -46,7 +46,8 @@ impl Queue {
return Err(AppErrorKind::MissingSqsMessageFields {
field: "body".to_string(),
queue: self.url.clone(),
}.into());
}
.into());
}
if let Some(hash) = message.md5_of_body {
@ -55,7 +56,8 @@ impl Queue {
queue: self.url.clone(),
hash,
body,
}.into());
}
.into());
}
}
@ -64,7 +66,8 @@ impl Queue {
return Err(AppErrorKind::MissingSqsMessageFields {
field: "receipt_handle".to_string(),
queue: self.url.clone(),
}.into());
}
.into());
}
if let Some(ref message) = serde_json::from_str::<JsonValue>(&body)?["Message"].as_str() {
@ -80,19 +83,22 @@ impl Queue {
notification: From::from(notification),
id: receipt_handle,
}
}).map_err(|error| {
})
.map_err(|error| {
AppErrorKind::SqsMessageParsingError {
message: format!("{:?}", error),
queue: self.url.clone(),
body: format!("{}", body),
}.into()
}
.into()
})
} else {
Err(AppErrorKind::SqsMessageParsingError {
message: format!("{}", "Unexpected SQS message structure"),
queue: self.url.clone(),
body: format!("{}", body),
}.into())
}
.into())
}
}
}

Просмотреть файл

@ -88,7 +88,8 @@ fn handler(
email.body.text.as_ref(),
email.body.html.as_ref().map(|html| html.as_ref()),
email.provider.as_ref().map(|provider| provider.as_ref()),
).map(|message_id| {
)
.map(|message_id| {
email
.metadata
.as_ref()
@ -99,5 +100,6 @@ fn handler(
slog_error!(log, "{}", "Request errored");
});
Json(json!({ "messageId": message_id }))
}).map_err(|error| error)
})
.map_err(|error| error)
}

Просмотреть файл

@ -61,7 +61,8 @@ fn single_recipient() {
},
"provider": "mock"
}"#,
).dispatch();
)
.dispatch();
assert_eq!(response.status(), Status::Ok);
@ -87,7 +88,8 @@ fn multiple_recipients() {
},
"provider": "mock"
}"#,
).dispatch();
)
.dispatch();
assert_eq!(response.status(), Status::Ok);
@ -111,7 +113,8 @@ fn without_optional_data() {
},
"provider": "mock"
}"#,
).dispatch();
)
.dispatch();
assert_eq!(response.status(), Status::Ok);
@ -135,7 +138,8 @@ fn unicode_email_field() {
},
"provider": "mock"
}"#,
).dispatch();
)
.dispatch();
assert_eq!(response.status(), Status::Ok);
@ -160,7 +164,8 @@ fn unicode_message_body() {
},
"provider": "mock"
}"#,
).dispatch();
)
.dispatch();
assert_eq!(response.status(), Status::Ok);
@ -184,7 +189,8 @@ fn unicode_message_subject() {
},
"provider": "mock"
}"#,
).dispatch();
)
.dispatch();
assert_eq!(response.status(), Status::Ok);
@ -207,7 +213,8 @@ fn missing_to_field() {
},
"provider": "mock"
}"#,
).dispatch();
)
.dispatch();
assert_eq!(response.status(), Status::BadRequest);
@ -231,7 +238,8 @@ fn missing_subject_field() {
},
"provider": "mock"
}"#,
).dispatch();
)
.dispatch();
assert_eq!(response.status(), Status::BadRequest);
@ -256,7 +264,8 @@ fn missing_body_text_field() {
},
"provider": "mock"
}"#,
).dispatch();
)
.dispatch();
assert_eq!(response.status(), Status::BadRequest);
@ -281,7 +290,8 @@ fn invalid_to_field() {
},
"provider": "mock"
}"#,
).dispatch();
)
.dispatch();
assert_eq!(response.status(), Status::BadRequest);
@ -307,7 +317,8 @@ fn invalid_cc_field() {
},
"provider": "mock"
}"#,
).dispatch();
)
.dispatch();
assert_eq!(response.status(), Status::BadRequest);

Просмотреть файл

@ -136,7 +136,8 @@ fn env_vars_take_precedence() {
"sendgrid"
} else {
"ses"
}.to_string(),
}
.to_string(),
),
forcedefault: !settings.provider.forcedefault,
};