headless_lms_models/
playground_examples.rs

1use crate::prelude::*;
2
3#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Eq)]
4#[cfg_attr(feature = "ts_rs", derive(TS))]
5pub struct PlaygroundExample {
6    pub id: Uuid,
7    pub created_at: DateTime<Utc>,
8    pub updated_at: DateTime<Utc>,
9    pub deleted_at: Option<DateTime<Utc>>,
10    pub name: String,
11    pub url: String,
12    pub width: i32,
13    pub data: serde_json::Value,
14}
15
16#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Eq)]
17#[cfg_attr(feature = "ts_rs", derive(TS))]
18pub struct PlaygroundExampleData {
19    pub name: String,
20    pub url: String,
21    pub width: i32,
22    pub data: serde_json::Value,
23}
24
25pub async fn get_all_playground_examples(
26    conn: &mut PgConnection,
27) -> ModelResult<Vec<PlaygroundExample>> {
28    let examples = sqlx::query_as!(
29        PlaygroundExample,
30        "
31SELECT *
32from playground_examples
33WHERE deleted_at IS NULL;
34  "
35    )
36    .fetch_all(&mut *conn)
37    .await?;
38    Ok(examples)
39}
40
41pub async fn insert_playground_example(
42    conn: &mut PgConnection,
43    data: PlaygroundExampleData,
44) -> ModelResult<PlaygroundExample> {
45    let res = sqlx::query!(
46        "
47INSERT INTO playground_examples (name, url, width, data)
48VALUES ($1, $2, $3, $4)
49RETURNING *;
50  ",
51        data.name,
52        data.url,
53        data.width,
54        data.data
55    )
56    .fetch_one(&mut *conn)
57    .await?;
58    Ok(PlaygroundExample {
59        id: res.id,
60        created_at: res.created_at,
61        updated_at: res.updated_at,
62        deleted_at: res.deleted_at,
63        name: res.name,
64        url: res.url,
65        width: res.width,
66        data: res.data,
67    })
68}
69
70pub async fn update_playground_example(
71    conn: &mut PgConnection,
72    data: PlaygroundExample,
73) -> ModelResult<PlaygroundExample> {
74    let res = sqlx::query_as!(
75        PlaygroundExample,
76        "
77UPDATE playground_examples
78SET updated_at = now(),
79  name = $1,
80  url = $2,
81  width = $3,
82  data = $4
83WHERE id = $5
84RETURNING *;
85    ",
86        data.name,
87        data.url,
88        data.width,
89        data.data,
90        data.id
91    )
92    .fetch_one(&mut *conn)
93    .await?;
94
95    Ok(res)
96}
97
98pub async fn delete_playground_example(
99    conn: &mut PgConnection,
100    id: Uuid,
101) -> ModelResult<PlaygroundExample> {
102    let res = sqlx::query!(
103        "
104UPDATE playground_examples
105SET deleted_at = now()
106WHERE id = $1
107RETURNING *;
108  ",
109        id
110    )
111    .fetch_one(&mut *conn)
112    .await
113    .unwrap();
114
115    Ok(PlaygroundExample {
116        id: res.id,
117        created_at: res.created_at,
118        updated_at: res.updated_at,
119        deleted_at: res.deleted_at,
120        name: res.name,
121        url: res.url,
122        width: res.width,
123        data: res.data,
124    })
125}
126
127#[cfg(test)]
128mod test {
129
130    use super::*;
131    use crate::{playground_examples::PlaygroundExampleData, test_helper::Conn};
132
133    #[tokio::test]
134    async fn insert_and_fetch_playground_example() {
135        let mut conn = Conn::init().await;
136        let mut tx = conn.begin().await;
137
138        let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
139        let previous_length = fetched_data.len();
140
141        let inserted_data = insert_playground_example(
142            tx.as_mut(),
143            PlaygroundExampleData {
144                name: "test".to_string(),
145                url: "https:\\test.com".to_string(),
146                width: 500,
147                data: serde_json::json!({"data":"test"}),
148            },
149        )
150        .await
151        .unwrap();
152
153        assert!(inserted_data.name == *"test");
154        assert!(inserted_data.url == *"https:\\test.com");
155        assert!(inserted_data.width == 500);
156        assert!(inserted_data.data == serde_json::json!({"data":"test"}));
157
158        let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
159
160        assert_eq!(fetched_data.len(), previous_length + 1);
161    }
162
163    #[tokio::test]
164    async fn insert_and_delete_playground_example() {
165        let mut conn = Conn::init().await;
166        let mut tx = conn.begin().await;
167
168        let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
169        let previous_length = fetched_data.len();
170
171        let inserted_data = insert_playground_example(
172            tx.as_mut(),
173            PlaygroundExampleData {
174                name: "test".to_string(),
175                url: "https:\\test.com".to_string(),
176                width: 500,
177                data: serde_json::json!({"data":"test"}),
178            },
179        )
180        .await
181        .unwrap();
182
183        assert!(inserted_data.name == *"test");
184        assert!(inserted_data.url == *"https:\\test.com");
185        assert!(inserted_data.width == 500);
186        assert!(inserted_data.data == serde_json::json!({"data":"test"}));
187
188        let res = delete_playground_example(tx.as_mut(), inserted_data.id)
189            .await
190            .unwrap();
191
192        assert!(res.deleted_at.is_some());
193
194        let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
195
196        assert_eq!(fetched_data.len(), previous_length);
197    }
198
199    #[tokio::test]
200    async fn insert_and_update_playground_example() {
201        let mut conn = Conn::init().await;
202        let mut tx = conn.begin().await;
203
204        let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
205        let previous_length = fetched_data.len();
206
207        let inserted_data = insert_playground_example(
208            tx.as_mut(),
209            PlaygroundExampleData {
210                name: "test".to_string(),
211                url: "https:\\test.com".to_string(),
212                width: 500,
213                data: serde_json::json!({"data":"test"}),
214            },
215        )
216        .await
217        .unwrap();
218
219        assert!(inserted_data.name == *"test");
220        assert!(inserted_data.url == *"https:\\test.com");
221        assert!(inserted_data.width == 500);
222        assert!(inserted_data.data == serde_json::json!({"data":"test"}));
223
224        let updated_data = PlaygroundExample {
225            name: "updated name".to_string(),
226            url: "https:\\updated-url.com".to_string(),
227            width: 600,
228            data: serde_json::json!({"data": "updated data"}),
229            ..inserted_data
230        };
231
232        let res = update_playground_example(tx.as_mut(), updated_data)
233            .await
234            .unwrap();
235
236        assert!(res.name == *"updated name");
237        assert!(res.url == *"https:\\updated-url.com");
238        assert!(res.width == 600);
239        assert!(res.data == serde_json::json!({"data":"updated data"}));
240
241        let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
242
243        assert_eq!(fetched_data.len(), previous_length + 1);
244    }
245}