summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/api/boot.md50
-rw-r--r--src/boot/app.rs30
-rw-r--r--src/boot/handlers/boot/test.rs22
-rw-r--r--src/boot/mod.rs5
-rw-r--r--src/channel/handlers/create/test.rs10
-rw-r--r--src/channel/handlers/delete/test.rs12
-rw-r--r--src/channel/history.rs6
-rw-r--r--src/message/handlers/delete/test.rs10
-rw-r--r--src/message/history.rs6
-rw-r--r--src/user/history.rs8
10 files changed, 41 insertions, 118 deletions
diff --git a/docs/api/boot.md b/docs/api/boot.md
index 1f6e619..f6e6dc2 100644
--- a/docs/api/boot.md
+++ b/docs/api/boot.md
@@ -92,28 +92,6 @@ This endpoint will respond with a status of
"id": "M3twnj7rfk2ph744",
"body": "test"
}
- ],
- "users": [
- {
- "id": "U1234abcd",
- "name": "example username"
- }
- ],
- "channels": [
- {
- "at": "2025-04-14T23:58:11.421901Z",
- "name": "nonsense and such",
- "id": "C1234abcd"
- }
- ],
- "messages": [
- {
- "at": "2024-09-27T23:19:10.208147Z",
- "channel": "C1234abcd",
- "sender": "U1234abcd",
- "id": "M1312acab",
- "body": "beep"
- }
]
}
```
@@ -126,9 +104,6 @@ The response will include the following fields:
| `resume_point` | integer | A resume point for [events](./events.md), such that the event stream will begin immediately after the included snapshot. |
| `heartbeat` | integer | The [heartbeat timeout](./events.md#heartbeat-events), in seconds, for events. |
| `events` | array of object | The events on the server up to the resume point. |
-| `users` | array of object | A snapshot of the users present in the service. |
-| `channels` | array of object | A snapshot of the channels present in the service. |
-| `messages` | array of object | A snapshot of the messages present in the service. |
Each element of the
`events` object is an event, as described in [Events](./events.md). Events are provided in the same order as they would appear in the event stream response.
@@ -139,28 +114,3 @@ The `user` object will include the following fields:
| :----- | :----- | :--------------------------------------- |
| `name` | string | The name of the caller's login identity. |
| `id` | string | The ID of the caller's login identity. |
-
-Each element of the `users` array describes a distinct user, and will include the following fields:
-
-| Field | Type | Description |
-| :----- | :----- | :----------------------------------------------------------------------------------------------------------------------------------- |
-| `name` | string | The name for the user. |
-| `id` | string | A unique identifier for the user. This can be used to associate the user with other events, or to make API calls targeting the user. |
-
-Each element of the `channels` array describes a distinct channel, and will include the following fields:
-
-| Field | Type | Description |
-| :----- | :-------- | :-------------------------------------------------------------------------------------------------------------------------------------------- |
-| `at` | timestamp | The moment the channel was created. |
-| `name` | string | The name for the channel. |
-| `id` | string | A unique identifier for the channel. This can be used to associate the channel with other events, or to make API calls targeting the channel. |
-
-Each element of the `messages` array describes a distinct message, and will include the following fields:
-
-| Field | Type | Description |
-| :-------- | :-------- | :-------------------------------------------------------------------------------------------------------------------------------------------- |
-| `at` | timestamp | The moment the message was sent. |
-| `channel` | string | The ID of the channel the message was sent to. |
-| `sender` | string | The ID of the user that sent the message. |
-| `id` | string | A unique identifier for the message. This can be used to associate the message with other events, or to make API calls targeting the message. |
-| `body` | string | The text of the message. |
diff --git a/src/boot/app.rs b/src/boot/app.rs
index 690bcf4..89eec12 100644
--- a/src/boot/app.rs
+++ b/src/boot/app.rs
@@ -23,42 +23,27 @@ impl<'a> Boot<'a> {
let mut tx = self.db.begin().await?;
let resume_point = tx.sequence().current().await?;
- let user_histories = tx.users().all(resume_point).await?;
- let channel_histories = tx.channels().all(resume_point).await?;
- let message_histories = tx.messages().all(resume_point).await?;
+ let users = tx.users().all(resume_point).await?;
+ let channels = tx.channels().all(resume_point).await?;
+ let messages = tx.messages().all(resume_point).await?;
tx.commit().await?;
- let users = user_histories
- .iter()
- .filter_map(|user| user.as_of(resume_point))
- .collect();
-
- let channels = channel_histories
- .iter()
- .filter_map(|channel| channel.as_of(resume_point))
- .collect();
-
- let messages = message_histories
- .iter()
- .filter_map(|message| message.as_of(resume_point))
- .collect();
-
- let user_events = user_histories
+ let user_events = users
.iter()
.map(user::History::events)
.kmerge_by(Sequence::merge)
.filter(Sequence::up_to(resume_point))
.map(Event::from);
- let channel_events = channel_histories
+ let channel_events = channels
.iter()
.map(channel::History::events)
.kmerge_by(Sequence::merge)
.filter(Sequence::up_to(resume_point))
.map(Event::from);
- let message_events = message_histories
+ let message_events = messages
.iter()
.map(message::History::events)
.kmerge_by(Sequence::merge)
@@ -72,9 +57,6 @@ impl<'a> Boot<'a> {
Ok(Snapshot {
resume_point,
- users,
- channels,
- messages,
events,
})
}
diff --git a/src/boot/handlers/boot/test.rs b/src/boot/handlers/boot/test.rs
index d68618e..1e590a7 100644
--- a/src/boot/handlers/boot/test.rs
+++ b/src/boot/handlers/boot/test.rs
@@ -25,8 +25,6 @@ async fn includes_users() {
.await
.expect("boot always succeeds");
- assert!(response.snapshot.users.contains(&spectator));
-
let created = response
.snapshot
.events
@@ -48,8 +46,6 @@ async fn includes_channels() {
.await
.expect("boot always succeeds");
- assert!(response.snapshot.channels.contains(&channel));
-
let created = response
.snapshot
.events
@@ -73,8 +69,6 @@ async fn includes_messages() {
.await
.expect("boot always succeeds");
- assert!(response.snapshot.messages.contains(&message));
-
let sent = response
.snapshot
.events
@@ -87,7 +81,7 @@ async fn includes_messages() {
}
#[tokio::test]
-async fn excludes_expired_messages() {
+async fn includes_expired_messages() {
let app = fixtures::scratch_app().await;
let sender = fixtures::user::create(&app, &fixtures::ancient()).await;
let channel = fixtures::channel::create(&app, &fixtures::ancient()).await;
@@ -104,8 +98,6 @@ async fn excludes_expired_messages() {
.await
.expect("boot always succeeds");
- assert!(!response.snapshot.messages.contains(&expired_message));
-
let sent = response
.snapshot
.events
@@ -131,7 +123,7 @@ async fn excludes_expired_messages() {
}
#[tokio::test]
-async fn excludes_deleted_messages() {
+async fn includes_deleted_messages() {
let app = fixtures::scratch_app().await;
let sender = fixtures::user::create(&app, &fixtures::now()).await;
let channel = fixtures::channel::create(&app, &fixtures::now()).await;
@@ -147,8 +139,6 @@ async fn excludes_deleted_messages() {
.await
.expect("boot always succeeds");
- assert!(!response.snapshot.messages.contains(&deleted_message));
-
let sent = response
.snapshot
.events
@@ -174,7 +164,7 @@ async fn excludes_deleted_messages() {
}
#[tokio::test]
-async fn excludes_expired_channels() {
+async fn includes_expired_channels() {
let app = fixtures::scratch_app().await;
let expired_channel = fixtures::channel::create(&app, &fixtures::ancient()).await;
@@ -188,8 +178,6 @@ async fn excludes_expired_channels() {
.await
.expect("boot always succeeds");
- assert!(!response.snapshot.channels.contains(&expired_channel));
-
let created = response
.snapshot
.events
@@ -215,7 +203,7 @@ async fn excludes_expired_channels() {
}
#[tokio::test]
-async fn excludes_deleted_channels() {
+async fn includes_deleted_channels() {
let app = fixtures::scratch_app().await;
let deleted_channel = fixtures::channel::create(&app, &fixtures::now()).await;
@@ -229,8 +217,6 @@ async fn excludes_deleted_channels() {
.await
.expect("boot always succeeds");
- assert!(!response.snapshot.channels.contains(&deleted_channel));
-
let created = response
.snapshot
.events
diff --git a/src/boot/mod.rs b/src/boot/mod.rs
index 148e87d..e0d35d9 100644
--- a/src/boot/mod.rs
+++ b/src/boot/mod.rs
@@ -1,4 +1,4 @@
-use crate::{channel::Channel, event::Event, event::Sequence, message::Message, user::User};
+use crate::{event::Event, event::Sequence};
pub mod app;
pub mod handlers;
@@ -6,8 +6,5 @@ pub mod handlers;
#[derive(serde::Serialize)]
pub struct Snapshot {
pub resume_point: Sequence,
- pub users: Vec<User>,
- pub channels: Vec<Channel>,
- pub messages: Vec<Message>,
pub events: Vec<Event>,
}
diff --git a/src/channel/handlers/create/test.rs b/src/channel/handlers/create/test.rs
index 595a879..31bb778 100644
--- a/src/channel/handlers/create/test.rs
+++ b/src/channel/handlers/create/test.rs
@@ -2,6 +2,7 @@ use std::future;
use axum::extract::{Json, State};
use futures::stream::StreamExt as _;
+use itertools::Itertools;
use crate::{
channel::app,
@@ -33,7 +34,14 @@ async fn new_channel() {
// Verify the semantics
let snapshot = app.boot().snapshot().await.expect("boot always succeeds");
- assert!(snapshot.channels.iter().any(|channel| channel == &response));
+ let created = snapshot
+ .events
+ .into_iter()
+ .filter_map(fixtures::event::channel)
+ .filter_map(fixtures::event::channel::created)
+ .exactly_one()
+ .expect("only one channel has been created");
+ assert_eq!(response, created.channel);
let channel = app
.channels()
diff --git a/src/channel/handlers/delete/test.rs b/src/channel/handlers/delete/test.rs
index b1e42ea..99c19db 100644
--- a/src/channel/handlers/delete/test.rs
+++ b/src/channel/handlers/delete/test.rs
@@ -1,4 +1,5 @@
use axum::extract::{Path, State};
+use itertools::Itertools;
use crate::{channel::app, test::fixtures};
@@ -28,7 +29,16 @@ pub async fn valid_channel() {
// Verify the semantics
let snapshot = app.boot().snapshot().await.expect("boot always succeeds");
- assert!(!snapshot.channels.contains(&channel));
+ let created = snapshot
+ .events
+ .into_iter()
+ .filter_map(fixtures::event::channel)
+ .filter_map(fixtures::event::channel::created)
+ .exactly_one()
+ .expect("only one channel has been created");
+ // We don't expect `channel` to match the event exactly, as the name will have been
+ // tombstoned and the channel given a `deleted_at` date.
+ assert_eq!(channel.id, created.channel.id);
}
#[tokio::test]
diff --git a/src/channel/history.rs b/src/channel/history.rs
index faf6a0e..7f18e45 100644
--- a/src/channel/history.rs
+++ b/src/channel/history.rs
@@ -27,12 +27,6 @@ impl History {
self.channel.clone()
}
- pub fn as_of(&self, resume_point: Sequence) -> Option<Channel> {
- self.events()
- .filter(Sequence::up_to(resume_point))
- .collect()
- }
-
// Snapshot of this channel as of all events recorded in this history.
pub fn as_snapshot(&self) -> Option<Channel> {
self.events().collect()
diff --git a/src/message/handlers/delete/test.rs b/src/message/handlers/delete/test.rs
index 15aa2c2..f567eb7 100644
--- a/src/message/handlers/delete/test.rs
+++ b/src/message/handlers/delete/test.rs
@@ -1,4 +1,5 @@
use axum::extract::{Path, State};
+use itertools::Itertools;
use crate::{message::app, test::fixtures};
@@ -29,7 +30,14 @@ pub async fn delete_message() {
// Verify the semantics
let snapshot = app.boot().snapshot().await.expect("boot always succeeds");
- assert!(!snapshot.messages.contains(&message));
+ let deleted = snapshot
+ .events
+ .into_iter()
+ .filter_map(fixtures::event::message)
+ .filter_map(fixtures::event::message::deleted)
+ .exactly_one()
+ .expect("only one message has been deleted");
+ assert_eq!(response.id, deleted.id)
}
#[tokio::test]
diff --git a/src/message/history.rs b/src/message/history.rs
index 1a72c08..7585e1c 100644
--- a/src/message/history.rs
+++ b/src/message/history.rs
@@ -27,12 +27,6 @@ impl History {
self.message.clone()
}
- pub fn as_of(&self, resume_point: Sequence) -> Option<Message> {
- self.events()
- .filter(Sequence::up_to(resume_point))
- .collect()
- }
-
// Snapshot of this message as of all events recorded in this history.
pub fn as_snapshot(&self) -> Option<Message> {
self.events().collect()
diff --git a/src/user/history.rs b/src/user/history.rs
index ae7a561..72e0aee 100644
--- a/src/user/history.rs
+++ b/src/user/history.rs
@@ -2,7 +2,7 @@ use super::{
Id, User,
event::{Created, Event},
};
-use crate::event::{Instant, Sequence};
+use crate::event::Instant;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct History {
@@ -24,12 +24,6 @@ impl History {
self.user.clone()
}
- pub fn as_of(&self, resume_point: Sequence) -> Option<User> {
- self.events()
- .filter(Sequence::up_to(resume_point))
- .collect()
- }
-
// Snapshot of this user, as of all events recorded in this history.
pub fn as_snapshot(&self) -> Option<User> {
self.events().collect()