Merge branch 'integration-testing'
This commit is contained in:
commit
e7e20c08e9
6 changed files with 284 additions and 19 deletions
56
.travis.yml
56
.travis.yml
|
|
@ -1,30 +1,50 @@
|
||||||
sudo: required
|
|
||||||
language: rust
|
language: rust
|
||||||
# Dependencies of kcov, used by coverage
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- libssl-dev
|
- libssl-dev
|
||||||
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
- osx
|
|
||||||
|
|
||||||
|
cache: cargo
|
||||||
rust:
|
rust:
|
||||||
- stable
|
- stable
|
||||||
- beta
|
- beta
|
||||||
- nightly
|
- nightly
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
- osx
|
||||||
matrix:
|
matrix:
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- rust: nightly
|
- rust: nightly
|
||||||
|
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
|
before_install:
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
||||||
|
docker pull greenmail/standalone:1.5.8 &&
|
||||||
|
docker run -d -e GREENMAIL_OPTS='-Dgreenmail.setup.test.all -Dgreenmail.hostname=0.0.0.0 -Dgreenmail.auth.disabled -Dgreenmail.verbose' -p 3025:3025 -p 3110:3110 -p 3143:3143 -p 3465:3465 -p 3993:3993 -p 3995:3995 greenmail/standalone:1.5.8;
|
||||||
|
fi
|
||||||
script:
|
script:
|
||||||
|
- cargo clean
|
||||||
- cargo check --all-targets
|
- cargo check --all-targets
|
||||||
- cargo test
|
- cargo test --doc
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
||||||
|
cargo test --tests;
|
||||||
|
else
|
||||||
|
cargo test --lib;
|
||||||
|
fi
|
||||||
|
|
||||||
after_success:
|
before_cache: |
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$TRAVIS_RUST_VERSION" == "stable" ]]; then
|
if [[ "$TRAVIS_OS_NAME" == "linux" && "$TRAVIS_RUST_VERSION" == nightly ]]; then
|
||||||
bash <(curl https://raw.githubusercontent.com/xd009642/tarpaulin/master/travis-install.sh);
|
RUSTFLAGS="--cfg procmacro2_semver_exempt" cargo install cargo-tarpaulin
|
||||||
cargo tarpaulin --ciserver travis-ci --coveralls $TRAVIS_JOB_ID;
|
fi
|
||||||
|
|
||||||
|
after_failure:
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker logs (docker ps -q); fi
|
||||||
|
|
||||||
|
after_success: |
|
||||||
|
if [[ "$TRAVIS_OS_NAME" == "linux" && "$TRAVIS_RUST_VERSION" == nightly ]]; then
|
||||||
|
cargo tarpaulin --out Xml;
|
||||||
|
bash <(curl -s https://codecov.io/bash);
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -33,3 +33,7 @@ bufstream = "0.1"
|
||||||
imap-proto = "0.6"
|
imap-proto = "0.6"
|
||||||
nom = "4.0"
|
nom = "4.0"
|
||||||
base64 = "0.10"
|
base64 = "0.10"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
lettre-openssl111 = "0.9"
|
||||||
|
lettre-openssl111_email = "0.9"
|
||||||
|
|
|
||||||
11
README.md
11
README.md
|
|
@ -69,6 +69,17 @@ fn fetch_inbox_top() -> imap::error::Result<Option<String>> {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Running the test suite
|
||||||
|
|
||||||
|
To run the integration tests, you need to have [GreenMail
|
||||||
|
running](http://www.icegreen.com/greenmail/#deploy_docker_standalone). The
|
||||||
|
easiest way to do that is with Docker:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ docker pull greenmail/standalone:1.5.8
|
||||||
|
$ docker run -t -i -e GREENMAIL_OPTS='-Dgreenmail.setup.test.all -Dgreenmail.hostname=0.0.0.0 -Dgreenmail.auth.disabled -Dgreenmail.verbose' -p 3025:3025 -p 3110:3110 -p 3143:3143 -p 3465:3465 -p 3993:3993 -p 3995:3995 greenmail/standalone:1.5.8
|
||||||
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Licensed under either of
|
Licensed under either of
|
||||||
|
|
|
||||||
11
README.tpl
11
README.tpl
|
|
@ -12,6 +12,17 @@
|
||||||
|
|
||||||
{{readme}}
|
{{readme}}
|
||||||
|
|
||||||
|
## Running the test suite
|
||||||
|
|
||||||
|
To run the integration tests, you need to have [GreenMail
|
||||||
|
running](http://www.icegreen.com/greenmail/#deploy_docker_standalone). The
|
||||||
|
easiest way to do that is with Docker:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ docker pull greenmail/standalone:1.5.8
|
||||||
|
$ docker run -t -i -e GREENMAIL_OPTS='-Dgreenmail.setup.test.all -Dgreenmail.hostname=0.0.0.0 -Dgreenmail.auth.disabled -Dgreenmail.verbose' -p 3025:3025 -p 3110:3110 -p 3143:3143 -p 3465:3465 -p 3993:3993 -p 3995:3995 greenmail/standalone:1.5.8
|
||||||
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Licensed under either of
|
Licensed under either of
|
||||||
|
|
|
||||||
|
|
@ -65,4 +65,7 @@ build: false
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- cargo check --all-targets
|
- cargo check --all-targets
|
||||||
- cargo test
|
- cargo test --lib
|
||||||
|
- cargo test --doc
|
||||||
|
- cargo test --examples
|
||||||
|
# note that we are not running integration tests!
|
||||||
|
|
|
||||||
216
tests/imap_integration.rs
Normal file
216
tests/imap_integration.rs
Normal file
|
|
@ -0,0 +1,216 @@
|
||||||
|
extern crate imap;
|
||||||
|
extern crate lettre;
|
||||||
|
extern crate lettre_email;
|
||||||
|
extern crate native_tls;
|
||||||
|
|
||||||
|
use lettre::Transport;
|
||||||
|
use std::net::TcpStream;
|
||||||
|
|
||||||
|
fn tls() -> native_tls::TlsConnector {
|
||||||
|
native_tls::TlsConnector::builder()
|
||||||
|
.danger_accept_invalid_certs(true)
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn session(user: &str) -> imap::Session<native_tls::TlsStream<TcpStream>> {
|
||||||
|
let mut s = imap::connect("127.0.0.1:3993", "imap.example.com", &tls())
|
||||||
|
.unwrap()
|
||||||
|
.login(user, user)
|
||||||
|
.unwrap();
|
||||||
|
s.debug = true;
|
||||||
|
s
|
||||||
|
}
|
||||||
|
|
||||||
|
fn smtp(user: &str) -> lettre::SmtpTransport {
|
||||||
|
let creds = lettre::smtp::authentication::Credentials::new(user.to_string(), user.to_string());
|
||||||
|
lettre::SmtpClient::new(
|
||||||
|
"127.0.0.1:3465",
|
||||||
|
lettre::ClientSecurity::Wrapper(lettre::ClientTlsParameters {
|
||||||
|
connector: tls(),
|
||||||
|
domain: "smpt.example.com".to_string(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.credentials(creds)
|
||||||
|
.transport()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn connect_insecure() {
|
||||||
|
imap::connect_insecure("127.0.0.1:3143").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn connect_insecure_then_secure() {
|
||||||
|
// ignored because of https://github.com/greenmail-mail-test/greenmail/issues/135
|
||||||
|
imap::connect_insecure("127.0.0.1:3143")
|
||||||
|
.unwrap()
|
||||||
|
.secure("imap.example.com", &tls())
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn connect_secure() {
|
||||||
|
imap::connect("127.0.0.1:3993", "imap.example.com", &tls()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn login() {
|
||||||
|
session("readonly-test@localhost");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn logout() {
|
||||||
|
let mut s = session("readonly-test@localhost");
|
||||||
|
s.logout().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn inbox_zero() {
|
||||||
|
// https://github.com/djc/tokio-imap/issues/34
|
||||||
|
let mut s = session("readonly-test@localhost");
|
||||||
|
s.select("INBOX").unwrap();
|
||||||
|
let inbox = s.search("ALL").unwrap();
|
||||||
|
assert_eq!(inbox.len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn inbox() {
|
||||||
|
let to = "inbox@localhost";
|
||||||
|
|
||||||
|
// first log in so we'll see the unsolicited e-mails
|
||||||
|
let mut c = session(to);
|
||||||
|
c.select("INBOX").unwrap();
|
||||||
|
|
||||||
|
// then send the e-mail
|
||||||
|
let mut s = smtp(to);
|
||||||
|
let e = lettre_email::Email::builder()
|
||||||
|
.from("sender@localhost")
|
||||||
|
.to(to)
|
||||||
|
.subject("My first e-mail")
|
||||||
|
.text("Hello world from SMTP")
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
s.send(e.into()).unwrap();
|
||||||
|
|
||||||
|
// now we should see the e-mail!
|
||||||
|
let inbox = c.search("ALL").unwrap();
|
||||||
|
// and the one message should have the first message sequence number
|
||||||
|
assert_eq!(inbox.len(), 1);
|
||||||
|
assert!(inbox.contains(&1));
|
||||||
|
|
||||||
|
// we should also get two unsolicited responses: Exists and Recent
|
||||||
|
c.noop().unwrap();
|
||||||
|
let mut unsolicited = Vec::new();
|
||||||
|
while let Ok(m) = c.unsolicited_responses.try_recv() {
|
||||||
|
unsolicited.push(m);
|
||||||
|
}
|
||||||
|
assert_eq!(unsolicited.len(), 2);
|
||||||
|
assert!(unsolicited
|
||||||
|
.iter()
|
||||||
|
.any(|m| m == &imap::types::UnsolicitedResponse::Exists(1)));
|
||||||
|
assert!(unsolicited
|
||||||
|
.iter()
|
||||||
|
.any(|m| m == &imap::types::UnsolicitedResponse::Recent(1)));
|
||||||
|
|
||||||
|
// let's see that we can also fetch the e-mail
|
||||||
|
let fetch = c.fetch("1", "(ALL UID)").unwrap();
|
||||||
|
assert_eq!(fetch.len(), 1);
|
||||||
|
let fetch = &fetch[0];
|
||||||
|
assert_eq!(fetch.message, 1);
|
||||||
|
assert_ne!(fetch.uid, None);
|
||||||
|
assert_eq!(fetch.size, Some(138));
|
||||||
|
let e = fetch.envelope().unwrap();
|
||||||
|
assert_eq!(e.subject, Some("My first e-mail"));
|
||||||
|
assert_ne!(e.from, None);
|
||||||
|
assert_eq!(e.from.as_ref().unwrap().len(), 1);
|
||||||
|
let from = &e.from.as_ref().unwrap()[0];
|
||||||
|
assert_eq!(from.mailbox, Some("sender"));
|
||||||
|
assert_eq!(from.host, Some("localhost"));
|
||||||
|
assert_ne!(e.to, None);
|
||||||
|
assert_eq!(e.to.as_ref().unwrap().len(), 1);
|
||||||
|
let to = &e.to.as_ref().unwrap()[0];
|
||||||
|
assert_eq!(to.mailbox, Some("inbox"));
|
||||||
|
assert_eq!(to.host, Some("localhost"));
|
||||||
|
|
||||||
|
// and let's delete it to clean up
|
||||||
|
c.store("1", "+FLAGS (\\Deleted)").unwrap();
|
||||||
|
c.expunge().unwrap();
|
||||||
|
|
||||||
|
// the e-mail should be gone now
|
||||||
|
// TODO: https://github.com/djc/tokio-imap/issues/34
|
||||||
|
// let inbox = c.search("ALL").unwrap();
|
||||||
|
// assert_eq!(inbox.len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn inbox_uid() {
|
||||||
|
let to = "inbox-uid@localhost";
|
||||||
|
|
||||||
|
// first log in so we'll see the unsolicited e-mails
|
||||||
|
let mut c = session(to);
|
||||||
|
c.select("INBOX").unwrap();
|
||||||
|
|
||||||
|
// then send the e-mail
|
||||||
|
let mut s = smtp(to);
|
||||||
|
let e = lettre_email::Email::builder()
|
||||||
|
.from("sender@localhost")
|
||||||
|
.to(to)
|
||||||
|
.subject("My first e-mail")
|
||||||
|
.text("Hello world from SMTP")
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
s.send(e.into()).unwrap();
|
||||||
|
|
||||||
|
// now we should see the e-mail!
|
||||||
|
let inbox = c.uid_search("ALL").unwrap();
|
||||||
|
// and the one message should have the first message sequence number
|
||||||
|
assert_eq!(inbox.len(), 1);
|
||||||
|
let uid = inbox.into_iter().next().unwrap();
|
||||||
|
|
||||||
|
// we should also get two unsolicited responses: Exists and Recent
|
||||||
|
c.noop().unwrap();
|
||||||
|
let mut unsolicited = Vec::new();
|
||||||
|
while let Ok(m) = c.unsolicited_responses.try_recv() {
|
||||||
|
unsolicited.push(m);
|
||||||
|
}
|
||||||
|
assert_eq!(unsolicited.len(), 2);
|
||||||
|
assert!(unsolicited
|
||||||
|
.iter()
|
||||||
|
.any(|m| m == &imap::types::UnsolicitedResponse::Exists(1)));
|
||||||
|
assert!(unsolicited
|
||||||
|
.iter()
|
||||||
|
.any(|m| m == &imap::types::UnsolicitedResponse::Recent(1)));
|
||||||
|
|
||||||
|
// let's see that we can also fetch the e-mail
|
||||||
|
let fetch = c.uid_fetch(format!("{}", uid), "(ALL UID)").unwrap();
|
||||||
|
assert_eq!(fetch.len(), 1);
|
||||||
|
let fetch = &fetch[0];
|
||||||
|
assert_eq!(fetch.uid, Some(uid));
|
||||||
|
let e = fetch.envelope().unwrap();
|
||||||
|
assert_eq!(e.subject, Some("My first e-mail"));
|
||||||
|
|
||||||
|
// and let's delete it to clean up
|
||||||
|
c.uid_store(format!("{}", uid), "+FLAGS (\\Deleted)")
|
||||||
|
.unwrap();
|
||||||
|
c.expunge().unwrap();
|
||||||
|
|
||||||
|
// the e-mail should be gone now
|
||||||
|
// TODO: https://github.com/djc/tokio-imap/issues/34
|
||||||
|
// let inbox = c.search("ALL").unwrap();
|
||||||
|
// assert_eq!(inbox.len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn list() {
|
||||||
|
let mut s = session("readonly-test@localhost");
|
||||||
|
s.select("INBOX").unwrap();
|
||||||
|
let subdirs = s.list(None, Some("%")).unwrap();
|
||||||
|
assert_eq!(subdirs.len(), 0);
|
||||||
|
|
||||||
|
// TODO: make a subdir
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue