The crate, binary, library path and every name the tool writes or reads become inbuxa-migrate: the CLI name and about text, the HTTP user agent, the credential variables (INBUXA_MIGRATE_PASSWORD, _TOKEN, _EWS_CLIENT_SECRET and _GRAPH_TOKEN, with no fallback to the old names), thread names, synthesized UIDs and calendar addresses (urn:x-inbuxa-migrate:attendee:), and the Maildir file suffix used by the export script. This is a new tool, so archives written by Vandelay are not read back. The version moves to the date scheme the release tags use (2026.9.30), and the package metadata points at the inbuxa-migrate repository. The cargo-dist and MSI metadata goes with the release tooling it served. Modified files carry an added copyright line; the original notices stay.
114 lines
3.2 KiB
Rust
114 lines
3.2 KiB
Rust
/*
|
|
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
|
* SPDX-FileCopyrightText: 2026 John Coffey <[email protected]>
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*/
|
|
|
|
mod integration;
|
|
mod seeder;
|
|
|
|
use inbuxa_migrate::jmap::account::{self, AccountSelector};
|
|
use inbuxa_migrate::jmap::http::{Auth, HttpClient, RetryPolicy};
|
|
use inbuxa_migrate::jmap::session::Session;
|
|
use integration::stalwart::shared as shared_stalwart;
|
|
|
|
fn admin_client() -> HttpClient {
|
|
HttpClient::new(
|
|
Auth::Basic {
|
|
user: seeder::ADMIN_USER.into(),
|
|
password: seeder::ADMIN_PASSWORD.into(),
|
|
},
|
|
RetryPolicy::new(5),
|
|
true,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
#[ignore = "requires Docker"]
|
|
fn session_discovery_and_admin_principal_resolution() {
|
|
let stalwart = shared_stalwart();
|
|
let fx = seeder::provision(stalwart.base_url()).expect("provision");
|
|
let client = admin_client();
|
|
|
|
let session =
|
|
Session::discover(&client, &fx.base_url).expect("session discovery via .well-known");
|
|
assert!(
|
|
session.api_url.starts_with("https://") || session.api_url.starts_with("http://"),
|
|
"apiUrl should be absolute: {}",
|
|
session.api_url
|
|
);
|
|
let limits = session.core_limits().expect("core limits present");
|
|
assert!(limits.max_objects_in_get >= 1);
|
|
assert!(limits.max_concurrent_requests >= 1);
|
|
assert!(
|
|
!session.accounts.is_empty(),
|
|
"authenticated admin session must enumerate accounts"
|
|
);
|
|
|
|
assert_eq!(fx.domain, seeder::DOMAIN);
|
|
assert!(
|
|
!fx.domain_id.is_empty(),
|
|
"seeder should have ensured a domain id"
|
|
);
|
|
assert_eq!(
|
|
fx.admin_login,
|
|
(
|
|
seeder::ADMIN_USER.to_owned(),
|
|
seeder::ADMIN_PASSWORD.to_owned()
|
|
)
|
|
);
|
|
|
|
let target = fx.account("test1").expect("test1 seeded");
|
|
assert!(
|
|
!target.admin_role,
|
|
"test1 must be a regular user, not admin"
|
|
);
|
|
let seeded = target.seeded.as_ref().expect("test1 seed stats");
|
|
assert!(seeded.emails > 0, "test1 should be seeded with emails");
|
|
assert!(
|
|
seeded.mailboxes_created >= 7,
|
|
"test1 layout has at least 7 mailboxes"
|
|
);
|
|
assert!(
|
|
seeded.file_nodes >= 9,
|
|
"test1 layout has at least 9 file nodes"
|
|
);
|
|
assert!(
|
|
seeded.contacts > 0,
|
|
"test1 should be seeded with at least one contact"
|
|
);
|
|
assert!(
|
|
seeded.events > 0,
|
|
"test1 should be seeded with at least one event"
|
|
);
|
|
assert!(
|
|
seeded.address_books > 0,
|
|
"test1 layout requests an extra address book"
|
|
);
|
|
assert!(
|
|
seeded.calendars > 0,
|
|
"test1 layout requests an extra calendar"
|
|
);
|
|
assert!(seeded.identity, "test1 layout requests a custom identity");
|
|
assert_eq!(
|
|
seeded.sieve_active,
|
|
Some(true),
|
|
"test1 layout activates a sieve script"
|
|
);
|
|
|
|
let resolved = account::resolve(
|
|
&AccountSelector::Name(target.email.clone()),
|
|
&session,
|
|
&client,
|
|
)
|
|
.expect("admin principal resolution");
|
|
assert_eq!(
|
|
resolved, target.account_id,
|
|
"{} must resolve to the seeded account id {}",
|
|
target.email, target.account_id
|
|
);
|
|
|
|
seeder::teardown(stalwart.base_url()).expect("teardown");
|
|
}
|