fix listings json api (#331) and maildir e2e tests (#335)

This commit is contained in:
Clément DOUIN 2022-03-12 00:33:50 +01:00
parent 811ea45610
commit 6b042f5e6a
No known key found for this signature in database
GPG key ID: 353E4A18EE0FAB72
11 changed files with 70 additions and 46 deletions

View file

@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `In-Reply-To` not set properly when replying to a message [#323]
- `Cc` missing or invalid when replying to a message [#324]
- Notmuch backend hangs [#329]
- Maildir e2e tests [#335]
- JSON API for listings [#331]
## [0.5.8] - 2022-03-04
@ -499,3 +501,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#323]: https://github.com/soywod/himalaya/issues/323
[#324]: https://github.com/soywod/himalaya/issues/324
[#329]: https://github.com/soywod/himalaya/issues/329
[#331]: https://github.com/soywod/himalaya/issues/331
[#335]: https://github.com/soywod/himalaya/issues/335

View file

@ -15,13 +15,16 @@ use super::{ImapFlag, ImapFlags};
/// Represents a list of IMAP envelopes.
#[derive(Debug, Default, serde::Serialize)]
pub struct ImapEnvelopes(pub Vec<ImapEnvelope>);
pub struct ImapEnvelopes {
#[serde(rename = "response")]
pub envelopes: Vec<ImapEnvelope>,
}
impl Deref for ImapEnvelopes {
type Target = Vec<ImapEnvelope>;
fn deref(&self) -> &Self::Target {
&self.0
&self.envelopes
}
}
@ -99,7 +102,7 @@ impl TryFrom<RawImapEnvelopes> for ImapEnvelopes {
for raw_envelope in raw_envelopes.iter().rev() {
envelopes.push(ImapEnvelope::try_from(raw_envelope).context("cannot parse envelope")?);
}
Ok(Self(envelopes))
Ok(Self { envelopes })
}
}

View file

@ -4,6 +4,7 @@
//! to the mailbox.
use anyhow::Result;
use serde::Serialize;
use std::fmt::{self, Display};
use std::ops::Deref;
@ -16,14 +17,17 @@ use crate::{
use super::ImapMboxAttrs;
/// Represents a list of IMAP mailboxes.
#[derive(Debug, Default, serde::Serialize)]
pub struct ImapMboxes(pub Vec<ImapMbox>);
#[derive(Debug, Default, Serialize)]
pub struct ImapMboxes {
#[serde(rename = "response")]
pub mboxes: Vec<ImapMbox>,
}
impl Deref for ImapMboxes {
type Target = Vec<ImapMbox>;
fn deref(&self) -> &Self::Target {
&self.0
&self.mboxes
}
}
@ -130,7 +134,9 @@ pub type RawImapMboxes = imap::types::ZeroCopy<Vec<RawImapMbox>>;
impl<'a> From<RawImapMboxes> for ImapMboxes {
fn from(raw_mboxes: RawImapMboxes) -> Self {
Self(raw_mboxes.iter().map(ImapMbox::from).collect())
Self {
mboxes: raw_mboxes.iter().map(ImapMbox::from).collect(),
}
}
}

View file

@ -151,7 +151,7 @@ impl<'a> Backend<'a> for MaildirBackend<'a> {
envelopes.sort_by(|a, b| b.date.partial_cmp(&a.date).unwrap());
// Applies pagination boundaries.
envelopes.0 = envelopes[page_begin..page_end].to_owned();
envelopes.envelopes = envelopes[page_begin..page_end].to_owned();
// Appends envelopes hash to the id mapper cache file and
// calculates the new short hash length. The short hash length

View file

@ -20,19 +20,22 @@ use crate::{
/// Represents a list of envelopes.
#[derive(Debug, Default, serde::Serialize)]
pub struct MaildirEnvelopes(pub Vec<MaildirEnvelope>);
pub struct MaildirEnvelopes {
#[serde(rename = "response")]
pub envelopes: Vec<MaildirEnvelope>,
}
impl Deref for MaildirEnvelopes {
type Target = Vec<MaildirEnvelope>;
fn deref(&self) -> &Self::Target {
&self.0
&self.envelopes
}
}
impl DerefMut for MaildirEnvelopes {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
&mut self.envelopes
}
}
@ -114,7 +117,7 @@ impl<'a> TryFrom<RawMaildirEnvelopes> for MaildirEnvelopes {
envelopes.push(envelope);
}
Ok(MaildirEnvelopes(envelopes))
Ok(MaildirEnvelopes { envelopes })
}
}

View file

@ -19,13 +19,16 @@ use crate::{
/// Represents a list of Maildir mailboxes.
#[derive(Debug, Default, serde::Serialize)]
pub struct MaildirMboxes(pub Vec<MaildirMbox>);
pub struct MaildirMboxes {
#[serde(rename = "response")]
pub mboxes: Vec<MaildirMbox>,
}
impl Deref for MaildirMboxes {
type Target = Vec<MaildirMbox>;
fn deref(&self) -> &Self::Target {
&self.0
&self.mboxes
}
}
@ -113,7 +116,7 @@ impl TryFrom<RawMaildirMboxes> for MaildirMboxes {
for entry in mail_entries {
mboxes.push(entry?.try_into()?);
}
Ok(MaildirMboxes(mboxes))
Ok(MaildirMboxes { mboxes })
}
}

View file

@ -81,7 +81,7 @@ impl<'a> NotmuchBackend<'a> {
envelopes.sort_by(|a, b| b.date.partial_cmp(&a.date).unwrap());
// Applies pagination boundaries.
envelopes.0 = envelopes[page_begin..page_end].to_owned();
envelopes.envelopes = envelopes[page_begin..page_end].to_owned();
// Appends envelopes hash to the id mapper cache file and
// calculates the new short hash length. The short hash length
@ -118,17 +118,17 @@ impl<'a> Backend<'a> for NotmuchBackend<'a> {
fn get_mboxes(&mut self) -> Result<Box<dyn Mboxes>> {
info!(">> get notmuch virtual mailboxes");
let mut virt_mboxes: Vec<_> = self
let mut mboxes: Vec<_> = self
.account_config
.mailboxes
.iter()
.map(|(k, v)| NotmuchMbox::new(k, v))
.collect();
trace!("virtual mailboxes: {:?}", virt_mboxes);
virt_mboxes.sort_by(|a, b| b.name.partial_cmp(&a.name).unwrap());
trace!("virtual mailboxes: {:?}", mboxes);
mboxes.sort_by(|a, b| b.name.partial_cmp(&a.name).unwrap());
info!("<< get notmuch virtual mailboxes");
Ok(Box::new(NotmuchMboxes(virt_mboxes)))
Ok(Box::new(NotmuchMboxes { mboxes }))
}
fn del_mbox(&mut self, _mbox: &str) -> Result<()> {
@ -202,7 +202,7 @@ impl<'a> Backend<'a> for NotmuchBackend<'a> {
// Adds the message to the maildir folder and gets its hash.
let hash = self
.mdir
.add_msg("inbox", msg, "seen")
.add_msg("", msg, "seen")
.with_context(|| {
format!(
"cannot add notmuch message to maildir {:?}",

View file

@ -19,19 +19,22 @@ use crate::{
/// Represents a list of envelopes.
#[derive(Debug, Default, serde::Serialize)]
pub struct NotmuchEnvelopes(pub Vec<NotmuchEnvelope>);
pub struct NotmuchEnvelopes {
#[serde(rename = "response")]
pub envelopes: Vec<NotmuchEnvelope>,
}
impl Deref for NotmuchEnvelopes {
type Target = Vec<NotmuchEnvelope>;
fn deref(&self) -> &Self::Target {
&self.0
&self.envelopes
}
}
impl DerefMut for NotmuchEnvelopes {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
&mut self.envelopes
}
}
@ -107,7 +110,7 @@ impl<'a> TryFrom<RawNotmuchEnvelopes> for NotmuchEnvelopes {
.context("cannot parse notmuch mail entry")?;
envelopes.push(envelope);
}
Ok(NotmuchEnvelopes(envelopes))
Ok(NotmuchEnvelopes { envelopes })
}
}

View file

@ -17,13 +17,16 @@ use crate::{
/// Represents a list of Notmuch mailboxes.
#[derive(Debug, Default, serde::Serialize)]
pub struct NotmuchMboxes(pub Vec<NotmuchMbox>);
pub struct NotmuchMboxes {
#[serde(rename = "response")]
pub mboxes: Vec<NotmuchMbox>,
}
impl Deref for NotmuchMboxes {
type Target = Vec<NotmuchMbox>;
fn deref(&self) -> &Self::Target {
&self.0
&self.mboxes
}
}

View file

@ -115,21 +115,23 @@ mod tests {
unimplemented!();
}
fn get_mboxes(&mut self) -> Result<Box<dyn Mboxes>> {
Ok(Box::new(ImapMboxes(vec![
ImapMbox {
delim: "/".into(),
name: "INBOX".into(),
attrs: ImapMboxAttrs(vec![ImapMboxAttr::NoSelect]),
},
ImapMbox {
delim: "/".into(),
name: "Sent".into(),
attrs: ImapMboxAttrs(vec![
ImapMboxAttr::NoInferiors,
ImapMboxAttr::Custom("HasNoChildren".into()),
]),
},
])))
Ok(Box::new(ImapMboxes {
mboxes: vec![
ImapMbox {
delim: "/".into(),
name: "INBOX".into(),
attrs: ImapMboxAttrs(vec![ImapMboxAttr::NoSelect]),
},
ImapMbox {
delim: "/".into(),
name: "Sent".into(),
attrs: ImapMboxAttrs(vec![
ImapMboxAttr::NoInferiors,
ImapMboxAttr::Custom("HasNoChildren".into()),
]),
},
],
}))
}
fn del_mbox(&mut self, _: &str) -> Result<()> {
unimplemented!();

View file

@ -19,10 +19,7 @@ fn test_maildir_backend() {
// configure accounts
let account_config = AccountConfig {
mailboxes: HashMap::from_iter([
("inbox".into(), "INBOX".into()),
("subdir".into(), "Subdir".into()),
]),
mailboxes: HashMap::from_iter([("subdir".into(), "Subdir".into())]),
..AccountConfig::default()
};
let mdir_config = MaildirBackendConfig {