1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use crate::error::RangerError;
use crate::models::Comment;
use sqlx::sqlite::SqliteConnection;

pub async fn add(
    conn: &mut SqliteConnection,
    task_id: i64,
    body: &str,
) -> Result<Comment, RangerError> {
    let comment = sqlx::query_as::<_, Comment>(
        "INSERT INTO comments (task_id, body) VALUES (?, ?) \
         RETURNING id, task_id, body, created_at",
    )
    .bind(task_id)
    .bind(body)
    .fetch_one(&mut *conn)
    .await?;
    Ok(comment)
}

pub async fn list(conn: &mut SqliteConnection, task_id: i64) -> Result<Vec<Comment>, RangerError> {
    let comments = sqlx::query_as::<_, Comment>(
        "SELECT id, task_id, body, created_at FROM comments WHERE task_id = ? ORDER BY created_at",
    )
    .bind(task_id)
    .fetch_all(&mut *conn)
    .await?;
    Ok(comments)
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::db;
    use crate::ops::{backlog, task};
    use tempfile::tempdir;

    async fn test_pool() -> sqlx::SqlitePool {
        let dir = tempdir().unwrap();
        let dir = Box::leak(Box::new(dir));
        db::connect(&dir.path().join("test.db")).await.unwrap()
    }

    #[tokio::test]
    async fn add_and_list_comments() {
        let pool = test_pool().await;
        let mut conn = pool.acquire().await.unwrap();
        let bl = backlog::create(&mut conn, "Test").await.unwrap();
        let t = task::create(
            &mut conn,
            task::CreateTask {
                title: "Task",
                backlog_id: bl.id,
                state: None,
                description: None,
            },
        )
        .await
        .unwrap();

        add(&mut conn, t.id, "First comment").await.unwrap();
        add(&mut conn, t.id, "Second comment").await.unwrap();

        let comments = list(&mut conn, t.id).await.unwrap();
        assert_eq!(comments.len(), 2);
        assert_eq!(comments[0].body, "First comment");
        assert_eq!(comments[1].body, "Second comment");
    }
}