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
107AND deleted_at IS NULL
108RETURNING *;
109  ",
110        id
111    )
112    .fetch_one(&mut *conn)
113    .await
114    .unwrap();
115
116    Ok(PlaygroundExample {
117        id: res.id,
118        created_at: res.created_at,
119        updated_at: res.updated_at,
120        deleted_at: res.deleted_at,
121        name: res.name,
122        url: res.url,
123        width: res.width,
124        data: res.data,
125    })
126}
127
128#[cfg(test)]
129mod test {
130
131    use super::*;
132    use crate::{playground_examples::PlaygroundExampleData, test_helper::Conn};
133
134    #[tokio::test]
135    async fn insert_and_fetch_playground_example() {
136        let mut conn = Conn::init().await;
137        let mut tx = conn.begin().await;
138
139        let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
140        let previous_length = fetched_data.len();
141
142        let inserted_data = insert_playground_example(
143            tx.as_mut(),
144            PlaygroundExampleData {
145                name: "test".to_string(),
146                url: "https:\\test.com".to_string(),
147                width: 500,
148                data: serde_json::json!({"data":"test"}),
149            },
150        )
151        .await
152        .unwrap();
153
154        assert!(inserted_data.name == *"test");
155        assert!(inserted_data.url == *"https:\\test.com");
156        assert!(inserted_data.width == 500);
157        assert!(inserted_data.data == serde_json::json!({"data":"test"}));
158
159        let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
160
161        assert_eq!(fetched_data.len(), previous_length + 1);
162    }
163
164    #[tokio::test]
165    async fn insert_and_delete_playground_example() {
166        let mut conn = Conn::init().await;
167        let mut tx = conn.begin().await;
168
169        let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
170        let previous_length = fetched_data.len();
171
172        let inserted_data = insert_playground_example(
173            tx.as_mut(),
174            PlaygroundExampleData {
175                name: "test".to_string(),
176                url: "https:\\test.com".to_string(),
177                width: 500,
178                data: serde_json::json!({"data":"test"}),
179            },
180        )
181        .await
182        .unwrap();
183
184        assert!(inserted_data.name == *"test");
185        assert!(inserted_data.url == *"https:\\test.com");
186        assert!(inserted_data.width == 500);
187        assert!(inserted_data.data == serde_json::json!({"data":"test"}));
188
189        let res = delete_playground_example(tx.as_mut(), inserted_data.id)
190            .await
191            .unwrap();
192
193        assert!(res.deleted_at.is_some());
194
195        let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
196
197        assert_eq!(fetched_data.len(), previous_length);
198    }
199
200    #[tokio::test]
201    async fn insert_and_update_playground_example() {
202        let mut conn = Conn::init().await;
203        let mut tx = conn.begin().await;
204
205        let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
206        let previous_length = fetched_data.len();
207
208        let inserted_data = insert_playground_example(
209            tx.as_mut(),
210            PlaygroundExampleData {
211                name: "test".to_string(),
212                url: "https:\\test.com".to_string(),
213                width: 500,
214                data: serde_json::json!({"data":"test"}),
215            },
216        )
217        .await
218        .unwrap();
219
220        assert!(inserted_data.name == *"test");
221        assert!(inserted_data.url == *"https:\\test.com");
222        assert!(inserted_data.width == 500);
223        assert!(inserted_data.data == serde_json::json!({"data":"test"}));
224
225        let updated_data = PlaygroundExample {
226            name: "updated name".to_string(),
227            url: "https:\\updated-url.com".to_string(),
228            width: 600,
229            data: serde_json::json!({"data": "updated data"}),
230            ..inserted_data
231        };
232
233        let res = update_playground_example(tx.as_mut(), updated_data)
234            .await
235            .unwrap();
236
237        assert!(res.name == *"updated name");
238        assert!(res.url == *"https:\\updated-url.com");
239        assert!(res.width == 600);
240        assert!(res.data == serde_json::json!({"data":"updated data"}));
241
242        let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
243
244        assert_eq!(fetched_data.len(), previous_length + 1);
245    }
246}