Add tests for error queue

pull/1/head
Manos Pitsidianakis 2022-06-09 01:54:40 +03:00
parent ae9d5c4d78
commit eb75d0af4c
4 changed files with 124 additions and 2 deletions

View File

@ -21,6 +21,26 @@ use super::*;
use serde_json::{json, Value};
impl Database {
pub fn insert_to_error_queue(&self, env: &Envelope, raw: &[u8]) -> Result<i64> {
let mut stmt = self.connection.prepare("INSERT INTO error_queue(to_address, from_address, subject, message_id, message, timestamp, datetime) VALUES(?, ?, ?, ?, ?, ?, ?) RETURNING pk;")?;
let pk = stmt.query_row(
rusqlite::params![
&env.field_to_to_string(),
&env.field_from_to_string(),
&env.subject(),
&env.message_id().to_string(),
raw,
&env.timestamp,
&env.date,
],
|row| {
let pk: i64 = row.get("pk")?;
Ok(pk)
},
)?;
Ok(pk)
}
pub fn error_queue(&self) -> Result<Vec<DbVal<Value>>> {
let mut stmt = self.connection.prepare("SELECT * FROM error_queue;")?;
let error_iter = stmt.query_map([], |row| {
@ -32,8 +52,8 @@ impl Database {
"from_address": row.get::<_, String>("from_address")?,
"subject": row.get::<_, String>("subject")?,
"message_id": row.get::<_, String>("message_id")?,
"message": row.get::<_, String>("message")?,
"timestamp": row.get::<_, String>("timestamp")?,
"message": row.get::<_, Vec<u8>>("message")?,
"timestamp": row.get::<_, u64>("timestamp")?,
"datetime": row.get::<_, String>("datetime")?,
}),
pk,

View File

@ -52,6 +52,21 @@ impl Database {
}
pub fn post(&self, env: &Envelope, raw: &[u8], _dry_run: bool) -> Result<()> {
let result = self.inner_post(env, raw, _dry_run);
if let Err(err) = result {
return match self.insert_to_error_queue(env, raw) {
Ok(idx) => Err(Error::from_kind(Information(format!(
"Inserted into error_queue at index {}",
idx
)))
.chain_err(|| err)),
Err(err2) => Err(err.chain_err(|| err2)),
};
}
result
}
fn inner_post(&self, env: &Envelope, raw: &[u8], _dry_run: bool) -> Result<()> {
trace!("Received envelope to post: {:#?}", &env);
let tos = env.to().to_vec();
if tos.is_empty() {

View File

@ -34,6 +34,11 @@ error_chain! {
description("List request is invalid")
display("Your list request has been found invalid: {}.", reason)
}
Information(reason: String) {
description("")
display("{}.", reason)
}
}
foreign_links {
Sql(rusqlite::Error);

View File

@ -0,0 +1,82 @@
use mailpot::{melib, models::*, Configuration, Database, SendMail};
use tempfile::TempDir;
fn get_smtp_conf() -> melib::smtp::SmtpServerConf {
use melib::smtp::*;
SmtpServerConf {
hostname: "127.0.0.1".into(),
port: 8825,
envelope_from: "foo-chat@example.com".into(),
auth: SmtpAuth::None,
security: SmtpSecurity::None,
extensions: Default::default(),
}
}
#[test]
fn test_error_queue() {
stderrlog::new()
.quiet(false)
.verbosity(15)
.show_module_names(true)
.timestamp(stderrlog::Timestamp::Millisecond)
.init()
.unwrap();
let tmp_dir = TempDir::new().unwrap();
let db_path = tmp_dir.path().join("mpot.db");
let mut config = Configuration::default();
config.send_mail = SendMail::Smtp(get_smtp_conf());
config.db_path = Some(db_path.clone());
config.init_with().unwrap();
assert_eq!(Database::db_path().unwrap(), db_path);
let db = Database::open_or_create_db().unwrap();
assert!(db.list_lists().unwrap().is_empty());
let foo_chat = db
.create_list(MailingList {
pk: 0,
name: "foobar chat".into(),
id: "foo-chat".into(),
address: "foo-chat@example.com".into(),
description: None,
archive_url: None,
})
.unwrap();
assert_eq!(foo_chat.pk(), 1);
let post_policy = db
.set_list_policy(
foo_chat.pk(),
PostPolicy {
pk: 0,
list: foo_chat.pk(),
announce_only: false,
subscriber_only: true,
approval_needed: false,
},
)
.unwrap();
assert_eq!(post_policy.pk(), 1);
let input_bytes = include_bytes!("./test_sample_longmessage.eml");
match melib::Envelope::from_bytes(input_bytes, None) {
Ok(envelope) => {
eprintln!("envelope {:?}", &envelope);
match db
.post(&envelope, input_bytes, /* dry_run */ false)
.unwrap_err()
.kind()
{
mailpot::ErrorKind::PostRejected(_reason) => {}
other => panic!("Got unexpected error: {}", other),
}
assert_eq!(db.error_queue().unwrap().len(), 1)
}
Err(err) => {
panic!("Could not parse message: {}", err);
}
}
}