Files
inbuxa-server/tests/src/jmap/calendar/calendars.rs
T
jcoffey-dev 89665decfa Rebrand to INBUXA: product name, protocol greetings, sign-in page, calendar templates, logos, README
One branding module (types::brand!) supplies the name to every protocol
greeting, the HTTP realm, the startup banner, Received headers, the
user agent, the IMAP ID response and calendar PRODIDs. The sign-in and
calendar pages take ihasmail's palette and font and the INBUXA logo, and
calendar emails embed the INBUXA lockup. Default calendar and address book
names follow. Protocol identifiers (urn:stalwart:jmap, vnd.stalwart Sieve
extensions) and upstream copyright notices are unchanged.
2026-09-18 10:52:34 -07:00

378 lines
12 KiB
Rust

/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use crate::utils::{
jmap::{ChangeType, JmapUtils},
server::TestServer,
};
use jmap_proto::{object::calendar::CalendarProperty, request::method::MethodObject};
use serde_json::json;
pub async fn test(test: &TestServer) {
println!("Running Calendar tests...");
let account = test.account("[email protected]");
// Make sure the default calendar exists
let response = account
.jmap_get(
MethodObject::Calendar,
[
CalendarProperty::Id,
CalendarProperty::Name,
CalendarProperty::Description,
CalendarProperty::SortOrder,
CalendarProperty::Color,
CalendarProperty::TimeZone,
CalendarProperty::IsSubscribed,
CalendarProperty::IsDefault,
CalendarProperty::IsVisible,
CalendarProperty::IncludeInAvailability,
CalendarProperty::DefaultAlertsWithTime,
CalendarProperty::DefaultAlertsWithoutTime,
],
Vec::<&str>::new(),
)
.await;
let list = response.list();
assert_eq!(list.len(), 1);
let default_calendar_id = list[0].id().to_string();
assert_eq!(
list[0],
json!({
"id": default_calendar_id,
"name": "INBUXA Calendar ([email protected])",
"description": null,
"sortOrder": 0,
"isSubscribed": true,
"isDefault": true,
"color": null,
"timeZone": null,
"isVisible": true,
"includeInAvailability": "all",
"defaultAlertsWithTime": {},
"defaultAlertsWithoutTime": {}
})
);
let change_id = response.state();
// Create Calendar
let calendar_id = account
.jmap_create(
MethodObject::Calendar,
[json!({
"name": "Test calendar",
"description": "My personal calendar",
"sortOrder": 1,
"isSubscribed": true,
"color": "#ff0000",
"timeZone": "Indian/Christmas",
"isVisible": false,
"includeInAvailability": "attending",
"defaultAlertsWithTime": {
"0": {
"action": "display",
"trigger": {
"relativeTo": "start",
"offset": "PT15M"
}
},
"1": {
"action": "email",
"trigger": {
"relativeTo": "end",
"offset": "PT30M"
}
}
},
"defaultAlertsWithoutTime": {
"0": {
"action": "display",
"trigger": {
"relativeTo": "start",
"offset": "P1D"
}
},
"1": {
"action": "email",
"trigger": {
"relativeTo": "end",
"offset": "P2D"
}
}
}
})],
Vec::<(&str, &str)>::new(),
)
.await
.created(0)
.id()
.to_string();
// Validate changes
assert_eq!(
account
.jmap_changes(MethodObject::Calendar, change_id)
.await
.changes()
.collect::<Vec<_>>(),
[ChangeType::Created(&calendar_id)]
);
// Get Calendar
let response = account
.jmap_get(
MethodObject::Calendar,
[
CalendarProperty::Id,
CalendarProperty::Name,
CalendarProperty::Description,
CalendarProperty::SortOrder,
CalendarProperty::Color,
CalendarProperty::TimeZone,
CalendarProperty::IsSubscribed,
CalendarProperty::IsDefault,
CalendarProperty::IsVisible,
CalendarProperty::IncludeInAvailability,
CalendarProperty::DefaultAlertsWithTime,
CalendarProperty::DefaultAlertsWithoutTime,
],
[&calendar_id],
)
.await;
response.list()[0].assert_is_equal(json!({
"name": "Test calendar",
"description": "My personal calendar",
"sortOrder": 1,
"isSubscribed": true,
"isVisible": false,
"isDefault": false,
"color": "#ff0000",
"timeZone": "Indian/Christmas",
"includeInAvailability": "attending",
"defaultAlertsWithTime": {
"0": {
"@type": "Alert",
"action": "display",
"trigger": {
"@type": "OffsetTrigger",
"relativeTo": "start",
"offset": "PT15M"
}
},
"1": {
"@type": "Alert",
"action": "email",
"trigger": {
"@type": "OffsetTrigger",
"relativeTo": "end",
"offset": "PT30M"
}
}
},
"defaultAlertsWithoutTime": {
"0": {
"@type": "Alert",
"action": "display",
"trigger": {
"@type": "OffsetTrigger",
"relativeTo": "start",
"offset": "P1D"
}
},
"1": {
"@type": "Alert",
"action": "email",
"trigger": {
"@type": "OffsetTrigger",
"relativeTo": "end",
"offset": "P2D"
}
}
},
"id": calendar_id,
}));
// Update Calendar and set it as default
account
.jmap_update(
MethodObject::Calendar,
[(
calendar_id.as_str(),
json!({
"name": "Updated calendar",
"description": "My updated personal calendar",
"sortOrder": 2,
"isSubscribed": false,
"isVisible": true,
"timeZone": null,
"color": null,
"includeInAvailability": "none",
"defaultAlertsWithTime": {
"0": {
"action": "email",
"trigger": {
"relativeTo": "start",
"offset": "PT10M"
}
}
},
"defaultAlertsWithoutTime/0": {
"action": "email",
"trigger": {
"relativeTo": "start",
"offset": "P3D"
}
},
"defaultAlertsWithoutTime/1": null,
"defaultAlertsWithoutTime/2": {
"action": "display",
"trigger": {
"relativeTo": "end",
"offset": "P1W"
}
}
}),
)],
[("onSuccessSetIsDefault", calendar_id.as_str())],
)
.await
.updated(&calendar_id);
// Validate changes
let response = account
.jmap_get(
MethodObject::Calendar,
[
CalendarProperty::Id,
CalendarProperty::Name,
CalendarProperty::Description,
CalendarProperty::SortOrder,
CalendarProperty::Color,
CalendarProperty::TimeZone,
CalendarProperty::IsSubscribed,
CalendarProperty::IsDefault,
CalendarProperty::IsVisible,
CalendarProperty::IncludeInAvailability,
CalendarProperty::DefaultAlertsWithTime,
CalendarProperty::DefaultAlertsWithoutTime,
],
[&calendar_id, &default_calendar_id],
)
.await;
response.list()[0].assert_is_equal(json!({
"id": calendar_id,
"name": "Updated calendar",
"description": "My updated personal calendar",
"sortOrder": 2,
"isSubscribed": false,
"isDefault": true,
"color": null,
"timeZone": null,
"isVisible": true,
"includeInAvailability": "none",
"defaultAlertsWithTime": {
"0": {
"@type": "Alert",
"action": "email",
"trigger": {
"@type": "OffsetTrigger",
"relativeTo": "start",
"offset": "PT10M"
}
}
},
"defaultAlertsWithoutTime": {
"0": {
"@type": "Alert",
"action": "email",
"trigger": {
"@type": "OffsetTrigger",
"relativeTo": "start",
"offset": "P3D"
}
},
"2": {
"@type": "Alert",
"action": "display",
"trigger": {
"@type": "OffsetTrigger",
"relativeTo": "end",
"offset": "P1W"
}
}
}
}));
response.list()[1].assert_is_equal(json!({
"id": default_calendar_id,
"name": "INBUXA Calendar ([email protected])",
"description": (),
"sortOrder": 0,
"isSubscribed": true,
"isDefault": false,
"color": null,
"timeZone": null,
"isVisible": true,
"includeInAvailability": "all",
"defaultAlertsWithTime": {},
"defaultAlertsWithoutTime": {}
}));
// Create an event
let _ = account
.jmap_create(
MethodObject::CalendarEvent,
[json!({
"calendarIds": {
&calendar_id: true
},
"@type": "Event",
"uid": "a8df6573-0474-496d-8496-033ad45d7fea",
"updated": "2020-01-02T18:23:04Z",
"title": "Some event",
"start": "2020-01-15T13:00:00",
"timeZone": "America/New_York",
"duration": "PT1H"
})],
Vec::<(&str, &str)>::new(),
)
.await
.created(0)
.id();
// Try destroying the calendar (should fail)
assert_eq!(
account
.jmap_destroy(
MethodObject::Calendar,
[&calendar_id],
Vec::<(&str, &str)>::new(),
)
.await
.not_destroyed(&calendar_id)
.typ(),
"calendarHasEvent"
);
// Destroy using force
assert_eq!(
account
.jmap_destroy(
MethodObject::Calendar,
[&calendar_id],
[("onDestroyRemoveEvents", true)],
)
.await
.destroyed()
.collect::<Vec<_>>(),
vec![&calendar_id]
);
// Destroy all mailboxes
account.destroy_all_calendars().await;
test.assert_is_empty().await;
}