Skip to content

Commit

Permalink
Move email utilities into their own module
Browse files Browse the repository at this point in the history
  • Loading branch information
marcua committed Sep 18, 2023
1 parent 7e1f2ee commit d262f54
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 47 deletions.
56 changes: 9 additions & 47 deletions tests/e2e.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use assert_cmd::prelude::*;
use ayb::error::AybError;
use quoted_printable;
use serde::{Deserialize, Serialize};
use std::fs;
use std::process::Command;
use std::thread;
use std::time;

mod utils;

fn client_query(
server_url: &str,
query: &str,
Expand All @@ -30,43 +29,6 @@ fn client_query(
Ok(())
}

// TODO(marcua): Move all email stuff to an email_utils module.
#[derive(Serialize, Deserialize)]
struct EmailEntry {
from: String,
to: String,
reply_to: String,
subject: String,
content_type: String,
content_transfer_encoding: String,
date: String,
content: Vec<String>,
}

fn parse_smtp_log(file_path: &str) -> Result<Vec<EmailEntry>, serde_json::Error> {
let mut entries = Vec::new();
for line in fs::read_to_string(file_path).unwrap().lines() {
entries.push(serde_json::from_str(line)?);
}
return Ok(entries);
}

fn extract_token(email: &EmailEntry) -> Result<String, AybError> {
let prefix = "\tayb client confirm ";
assert_eq!(email.subject, "Your login credentials");
for line in &email.content {
if line.starts_with(prefix) && line.len() > prefix.len() {
return Ok(String::from_utf8(quoted_printable::decode(
line[prefix.len()..].to_owned(),
quoted_printable::ParseMode::Robust,
)?)?);
}
}
return Err(AybError {
message: "No token found in email".to_owned(),
});
}

#[test]
fn client_server_integration_postgres() -> Result<(), Box<dyn std::error::Error>> {
return client_server_integration("postgres", "http://127.0.0.1:5433", 10025);
Expand Down Expand Up @@ -128,16 +90,16 @@ fn client_server_integration(
.stdout("Check your email to finish registering e2e\n");

// Check that two emails were received
let entries = parse_smtp_log(&format!("tests/smtp_data_{}/e2e@example.org", smtp_port))?;
let entries = utils::parse_smtp_log(&format!("tests/smtp_data_{}/e2e@example.org", smtp_port))?;
assert_eq!(entries.len(), 2);
let token0 = extract_token(&entries[0])?;
let token1 = extract_token(&entries[1])?;
let entries = parse_smtp_log(&format!(
let token0 = utils::extract_token(&entries[0])?;
let token1 = utils::extract_token(&entries[1])?;
let entries = utils::parse_smtp_log(&format!(
"tests/smtp_data_{}/e2e-another@example.org",
smtp_port
))?;
assert_eq!(entries.len(), 1);
let token2 = extract_token(&entries[0])?;
let token2 = utils::extract_token(&entries[0])?;

// Using a bad token (appending a letter) doesn't work.
Command::cargo_bin("ayb")?
Expand Down Expand Up @@ -183,9 +145,9 @@ fn client_server_integration(
.success()
.stdout("Check your email to finish logging in e2e\n");

let entries = parse_smtp_log(&format!("tests/smtp_data_{}/e2e@example.org", smtp_port))?;
let entries = utils::parse_smtp_log(&format!("tests/smtp_data_{}/e2e@example.org", smtp_port))?;
assert_eq!(entries.len(), 3);
let login_token = extract_token(&entries[2])?;
let login_token = utils::extract_token(&entries[2])?;
Command::cargo_bin("ayb")?
.args(["client", "confirm", &login_token])
.env("AYB_SERVER_URL", server_url)
Expand Down
40 changes: 40 additions & 0 deletions tests/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use ayb::error::AybError;
use quoted_printable;
use serde::{Deserialize, Serialize};
use std::fs;

#[derive(Serialize, Deserialize)]
pub struct EmailEntry {
from: String,
to: String,
reply_to: String,
subject: String,
content_type: String,
content_transfer_encoding: String,
date: String,
content: Vec<String>,
}

pub fn extract_token(email: &EmailEntry) -> Result<String, AybError> {
let prefix = "\tayb client confirm ";
assert_eq!(email.subject, "Your login credentials");
for line in &email.content {
if line.starts_with(prefix) && line.len() > prefix.len() {
return Ok(String::from_utf8(quoted_printable::decode(
line[prefix.len()..].to_owned(),
quoted_printable::ParseMode::Robust,
)?)?);
}
}
return Err(AybError {
message: "No token found in email".to_owned(),
});
}

pub fn parse_smtp_log(file_path: &str) -> Result<Vec<EmailEntry>, serde_json::Error> {
let mut entries = Vec::new();
for line in fs::read_to_string(file_path).unwrap().lines() {
entries.push(serde_json::from_str(line)?);
}
return Ok(entries);
}

0 comments on commit d262f54

Please sign in to comment.