1use serde_json::{json, Value};
2use syncular_runtime::error::Result;
3use syncular_runtime::fixtures::todo;
4use syncular_runtime::protocol::{
5 CombinedResponse, PullResponse, SubscriptionResponse, SyncSnapshot,
6};
7use syncular_runtime::transport::SyncTransport;
8
9use crate::app::{
10 open_app_client_with_options, open_app_client_with_transport, AppFixture, AppFixtureOptions,
11 TestAppFixture,
12};
13
14#[derive(Debug, Clone)]
15pub struct TodoFixtureOptions {
16 pub base_url: String,
17 pub client_id: String,
18 pub actor_id: String,
19 pub project_id: Option<String>,
20}
21
22impl Default for TodoFixtureOptions {
23 fn default() -> Self {
24 Self {
25 base_url: "http://syncular.test/sync".to_string(),
26 client_id: "test-client".to_string(),
27 actor_id: "user-rust".to_string(),
28 project_id: Some("p0".to_string()),
29 }
30 }
31}
32
33pub type TodoFixture<T> = AppFixture<T>;
34pub type TestTodoFixture = TestAppFixture;
35
36pub fn open_todo_client() -> Result<TestTodoFixture> {
37 open_todo_client_with_options(TodoFixtureOptions::default())
38}
39
40pub fn open_todo_client_with_options(options: TodoFixtureOptions) -> Result<TestTodoFixture> {
41 open_app_client_with_options(todo::app_schema(), todo_app_fixture_options(options))
42}
43
44pub fn open_todo_client_with_transport<T>(
45 transport: T,
46 options: TodoFixtureOptions,
47) -> Result<TodoFixture<T>>
48where
49 T: SyncTransport,
50{
51 open_app_client_with_transport(
52 todo::app_schema(),
53 transport,
54 todo_app_fixture_options(options),
55 )
56}
57
58fn todo_app_fixture_options(options: TodoFixtureOptions) -> AppFixtureOptions {
59 AppFixtureOptions {
60 db_prefix: "syncular-todo-test".to_string(),
61 base_url: options.base_url,
62 client_id: options.client_id,
63 actor_id: options.actor_id,
64 project_id: options.project_id,
65 }
66}
67
68pub fn todo_task_row(id: &str, title: &str, server_version: i64) -> Value {
69 json!({
70 "id": id,
71 "title": title,
72 "completed": 0,
73 "user_id": "user-rust",
74 "project_id": "p0",
75 "server_version": server_version,
76 "image": null,
77 "title_yjs_state": null
78 })
79}
80
81pub fn todo_snapshot_response(rows: Vec<Value>) -> CombinedResponse {
82 CombinedResponse {
83 ok: true,
84 required_schema_version: None,
85 latest_schema_version: None,
86 push: None,
87 pull: Some(PullResponse {
88 ok: true,
89 subscriptions: vec![SubscriptionResponse {
90 id: "sub-tasks".to_string(),
91 status: "active".to_string(),
92 scopes: serde_json::Map::from_iter([
93 (
94 "user_id".to_string(),
95 Value::String("user-rust".to_string()),
96 ),
97 ("project_id".to_string(), Value::String("p0".to_string())),
98 ]),
99 bootstrap: true,
100 bootstrap_state: None,
101 next_cursor: 1,
102 integrity: None,
103 commits: Vec::new(),
104 snapshots: Some(vec![SyncSnapshot {
105 table: "tasks".to_string(),
106 rows,
107 chunks: None,
108 artifacts: None,
109 manifest: None,
110 is_first_page: true,
111 is_last_page: true,
112 bootstrap_state_after: None,
113 }]),
114 }],
115 }),
116 }
117}