Skip to main content

headless_lms_models/
playground_examples.rs

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