Files
inbuxa-server/tests/src/jmap/contacts/addressbook.rs
T
jcoffey-dev a993f9ab01
ci / fork-checks (pull_request) Successful in 47s
ci / build (pull_request) Successful in 5m4s
Write the brand in lowercase where people see it
The name is inbuxa, lowercase, like the wordmark; INBUXA reads as an
acronym. The admin and webmail already changed. Here that's everything
the server shows people: the brand macro behind the protocol greetings,
the HTTP and SCIM realms, the startup banner and the calendar and contact
PRODID; the first-party OAuth client descriptions; the legacy-protocol
refusals; the default calendar and address book names and the SMTP
greeting default, in the code and the schema served to the admin
(checksum regenerated); startup and shutdown events; the User-Agent;
the sign-in and RSVP pages; the service units; the OpenAPI realm; the
crate descriptions and the README, where it's set in bold.

Identifiers that are uppercase for their own reasons stay: INBUXA_*
settings, SUBSPACE_INBUXA. So do code comments and the AGPL 5(a) notice
lines.

Tests follow: the IMAP ID name, the default collection names, the PRODID
in the iTIP fixtures and the CalDAV free-busy expectations, and the e2e
legacy-protocol refusals. The webdav, imap and jmap suites pass, so do
the unit tests of every crate touched, and 73 of 75 SMTP tests; of the
other two, antispam fails on main too, and queue_retry is a timing flake
that passes on its own.
2026-09-22 20:08:10 -07:00

219 lines
6.1 KiB
Rust

/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*
* Modified by Coffey Labs in 2026 for INBUXA.
*/
use crate::utils::{
jmap::{ChangeType, JmapUtils},
server::TestServer,
};
use jmap_proto::{object::addressbook::AddressBookProperty, request::method::MethodObject};
use serde_json::json;
pub async fn test(test: &TestServer) {
println!("Running AddressBook tests...");
let account = test.account("[email protected]");
// Make sure the default address book exists
let response = account
.jmap_get(
MethodObject::AddressBook,
[
AddressBookProperty::Id,
AddressBookProperty::Name,
AddressBookProperty::Description,
AddressBookProperty::SortOrder,
AddressBookProperty::IsSubscribed,
AddressBookProperty::IsDefault,
],
Vec::<&str>::new(),
)
.await;
let list = response.list();
assert_eq!(list.len(), 1);
let default_addressbook_id = list[0].id().to_string();
assert_eq!(
list[0],
json!({
"name": "inbuxa Address Book ([email protected])",
"description": (),
"sortOrder": 0,
"isSubscribed": true,
"isDefault": true,
"id": default_addressbook_id,
})
);
let change_id = response.state();
// Create Address Book
let addressbook_id = account
.jmap_create(
MethodObject::AddressBook,
[json!({
"name": "Test address book",
"description": "My personal address book",
"sortOrder": 1,
"isSubscribed": true
})],
Vec::<(&str, &str)>::new(),
)
.await
.created(0)
.id()
.to_string();
// Validate changes
assert_eq!(
account
.jmap_changes(MethodObject::AddressBook, change_id)
.await
.changes()
.collect::<Vec<_>>(),
[ChangeType::Created(&addressbook_id)]
);
// Get Address Book
let response = account
.jmap_get(
MethodObject::AddressBook,
[
AddressBookProperty::Id,
AddressBookProperty::Name,
AddressBookProperty::Description,
AddressBookProperty::SortOrder,
AddressBookProperty::IsSubscribed,
AddressBookProperty::IsDefault,
],
[&addressbook_id],
)
.await;
assert_eq!(
response.list()[0],
json!({
"name": "Test address book",
"description": "My personal address book",
"sortOrder": 1,
"isSubscribed": true,
"isDefault": false,
"id": addressbook_id,
})
);
// Update Address Book and set it as default
account
.jmap_update(
MethodObject::AddressBook,
[(
addressbook_id.as_str(),
json!({
"name": "Updated address book",
"description": "My updated personal address book",
"sortOrder": 2,
"isSubscribed": false
}),
)],
[("onSuccessSetIsDefault", addressbook_id.as_str())],
)
.await
.updated(&addressbook_id);
// Validate changes
assert_eq!(
account
.jmap_get(
MethodObject::AddressBook,
[
AddressBookProperty::Id,
AddressBookProperty::Name,
AddressBookProperty::Description,
AddressBookProperty::SortOrder,
AddressBookProperty::IsSubscribed,
AddressBookProperty::IsDefault,
],
[&addressbook_id, &default_addressbook_id],
)
.await
.list(),
vec![
json!({
"name": "Updated address book",
"description": "My updated personal address book",
"sortOrder": 2,
"isSubscribed": false,
"isDefault": true,
"id": addressbook_id,
}),
json!({
"name": "inbuxa Address Book ([email protected])",
"description": (),
"sortOrder": 0,
"isSubscribed": true,
"isDefault": false,
"id": default_addressbook_id,
})
]
);
// Create a contact
let _ = account
.jmap_create(
MethodObject::ContactCard,
[json!({
"addressBookIds": {
&addressbook_id: true
},
"name": {
"components": [
{ "kind": "given", "value": "Joe" },
{ "kind": "surname", "value": "Bloggs" }
]
},
"emails": {
"0": {
"address": "[email protected]"
}
}
})],
Vec::<(&str, &str)>::new(),
)
.await
.created(0)
.id();
// Try destroying the address book (should fail)
assert_eq!(
account
.jmap_destroy(
MethodObject::AddressBook,
[&addressbook_id],
Vec::<(&str, &str)>::new(),
)
.await
.not_destroyed(&addressbook_id)
.typ(),
"addressBookHasContents"
);
// Destroy using force
assert_eq!(
account
.jmap_destroy(
MethodObject::AddressBook,
[&addressbook_id],
[("onDestroyRemoveContents", true)],
)
.await
.destroyed()
.collect::<Vec<_>>(),
vec![&addressbook_id]
);
// Destroy all mailboxes
account.destroy_all_addressbooks().await;
test.assert_is_empty().await;
}