Skip to content

Commit f0537f1

Browse files
authored
Merge pull request #106 from vohoanglong0107/mock-comment
test: mock comment creation api
2 parents 1be871e + e5be852 commit f0537f1

File tree

7 files changed

+170
-16
lines changed

7 files changed

+170
-16
lines changed

src/bors/handlers/ping.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ pub(super) async fn command_ping<Client: RepositoryClient>(
1717

1818
#[cfg(test)]
1919
mod tests {
20+
use tracing_test::traced_test;
21+
2022
use crate::tests::event::default_pr_number;
23+
use crate::tests::mocks::BorsBuilder;
2124
use crate::tests::state::ClientBuilder;
2225

2326
#[sqlx::test]
@@ -32,15 +35,14 @@ mod tests {
3235
.check_comments(default_pr_number(), &["Pong 🏓!"]);
3336
}
3437

35-
// Failing tests - needs comment and PR endpoints to be implemented
36-
// #[traced_test]
37-
// #[sqlx::test]
38-
// async fn test_ping2(pool: sqlx::PgPool) {
39-
// BorsBuilder::new(pool)
40-
// .run_test(|mut tester| async {
41-
// tester.comment("@bors ping").await;
42-
// Ok(tester)
43-
// })
44-
// .await;
45-
// }
38+
#[traced_test]
39+
#[sqlx::test]
40+
async fn test_ping2(pool: sqlx::PgPool) {
41+
BorsBuilder::new(pool)
42+
.run_test(|mut tester| async {
43+
tester.comment("@bors ping").await;
44+
Ok(tester)
45+
})
46+
.await;
47+
}
4648
}

src/database/client.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ impl DbClient for PgDbClient {
3636
if let Some(pr) = get_pull_request(&self.pool, repo, pr_number).await? {
3737
return Ok(pr);
3838
}
39-
println!("Creating PR");
4039
create_pull_request(&self.pool, repo, pr_number).await?;
4140
let pr = get_pull_request(&self.pool, repo, pr_number)
4241
.await?

src/tests/mocks/comment.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::tests::event::default_pr_number;
1010
use crate::tests::mocks::repository::{GitHubRepository, Repo};
1111
use crate::tests::mocks::user::{GitHubUser, User};
1212

13+
#[derive(Clone, Debug)]
1314
pub struct Comment {
1415
repo: GithubRepoName,
1516
pr: u64,
@@ -123,7 +124,7 @@ struct GitHubIssue {
123124

124125
// Copied from octocrab, since its version if #[non_exhaustive]
125126
#[derive(Serialize)]
126-
struct GitHubComment {
127+
pub(super) struct GitHubComment {
127128
id: CommentId,
128129
node_id: String,
129130
url: Url,
@@ -135,6 +136,24 @@ struct GitHubComment {
135136
created_at: chrono::DateTime<chrono::Utc>,
136137
}
137138

139+
impl From<Comment> for GitHubComment {
140+
fn from(value: Comment) -> Self {
141+
let time = Utc::now();
142+
let url = Url::parse("https://foo.bar").unwrap();
143+
Self {
144+
id: CommentId(1),
145+
node_id: "1".to_string(),
146+
url: url.clone(),
147+
html_url: url,
148+
body: Some(value.content.clone()),
149+
body_text: Some(value.content.clone()),
150+
body_html: Some(value.content.clone()),
151+
user: value.author.into(),
152+
created_at: time,
153+
}
154+
}
155+
}
156+
138157
// Copied from octocrab, since its version if #[non_exhaustive]
139158
#[derive(Serialize)]
140159
struct GitHubPullRequestLink {

src/tests/mocks/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ mod bors;
1717
mod comment;
1818
mod github;
1919
mod permissions;
20+
mod pull_request;
2021
mod repository;
2122
mod user;
2223
mod webhook;
@@ -47,7 +48,7 @@ impl Default for World {
4748
}
4849
}
4950

50-
#[derive(Default)]
51+
#[derive(Clone, Default)]
5152
pub struct Permissions {
5253
pub users: HashMap<User, Vec<PermissionType>>,
5354
}

src/tests/mocks/pull_request.rs

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
use std::{
2+
collections::HashMap,
3+
sync::{Arc, Mutex},
4+
};
5+
6+
use serde::{Deserialize, Serialize};
7+
use wiremock::{
8+
matchers::{method, path},
9+
Mock, MockServer, Request, ResponseTemplate,
10+
};
11+
12+
use super::{
13+
comment::{Comment, GitHubComment},
14+
Repo,
15+
};
16+
17+
/// Handles all repositories related requests
18+
/// Only handle one PR for now, since bors don't create PRs itself
19+
#[derive(Default)]
20+
pub(super) struct PullRequestsHandler {
21+
repo: Repo,
22+
number: u64,
23+
comments: Arc<Mutex<HashMap<u64, Vec<Comment>>>>,
24+
}
25+
26+
impl PullRequestsHandler {
27+
pub(super) fn new(repo: Repo) -> Self {
28+
PullRequestsHandler {
29+
repo,
30+
number: default_pr_number(),
31+
comments: Arc::new(Mutex::new(HashMap::new())),
32+
}
33+
}
34+
pub(super) async fn mount(&self, mock_server: &MockServer) {
35+
Mock::given(method("GET"))
36+
.and(path(format!(
37+
"/repos/{}/pulls/{}",
38+
self.repo.name, self.number
39+
)))
40+
.respond_with(ResponseTemplate::new(200).set_body_json(GitHubPullRequest::default()))
41+
.mount(mock_server)
42+
.await;
43+
44+
let comments = self.comments.clone();
45+
Mock::given(method("POST"))
46+
.and(path(format!(
47+
"/repos/{}/issues/{}/comments",
48+
self.repo.name, self.number
49+
)))
50+
.respond_with(move |req: &Request| {
51+
let comment_payload: CommentCreatePayload = req.body_json().unwrap();
52+
let comment: Comment = comment_payload.into();
53+
let mut comments = comments.lock().unwrap();
54+
comments.entry(1).or_default().push(comment.clone());
55+
ResponseTemplate::new(201).set_body_json(GitHubComment::from(comment))
56+
})
57+
.mount(mock_server)
58+
.await;
59+
}
60+
}
61+
62+
#[derive(Serialize)]
63+
struct GitHubPullRequest {
64+
url: String,
65+
id: u64,
66+
title: String,
67+
body: String,
68+
69+
/// The pull request number. Note that GitHub's REST API
70+
/// considers every pull-request an issue with the same number.
71+
number: u64,
72+
73+
head: Box<Head>,
74+
base: Box<Base>,
75+
}
76+
77+
impl Default for GitHubPullRequest {
78+
fn default() -> Self {
79+
GitHubPullRequest {
80+
url: "https://test.com".to_string(),
81+
id: 1,
82+
title: format!("PR #{}", default_pr_number()),
83+
body: "test".to_string(),
84+
number: default_pr_number(),
85+
head: Box::new(Head {
86+
label: "test".to_string(),
87+
ref_field: "test".to_string(),
88+
sha: "test".to_string(),
89+
}),
90+
base: Box::new(Base {
91+
ref_field: "test".to_string(),
92+
sha: "test".to_string(),
93+
}),
94+
}
95+
}
96+
}
97+
98+
#[derive(Serialize)]
99+
struct Head {
100+
label: String,
101+
#[serde(rename = "ref")]
102+
ref_field: String,
103+
sha: String,
104+
}
105+
106+
#[derive(Serialize)]
107+
struct Base {
108+
#[serde(rename = "ref")]
109+
ref_field: String,
110+
sha: String,
111+
}
112+
113+
fn default_pr_number() -> u64 {
114+
1
115+
}
116+
117+
#[derive(Deserialize)]
118+
struct CommentCreatePayload {
119+
body: String,
120+
}
121+
122+
impl From<CommentCreatePayload> for Comment {
123+
fn from(payload: CommentCreatePayload) -> Self {
124+
Comment::new(payload.body.as_str())
125+
}
126+
}

src/tests/mocks/repository.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@ use wiremock::{
1111

1212
use crate::tests::mocks::{Permissions, World};
1313

14-
use super::user::{GitHubUser, User};
14+
use super::{
15+
pull_request::PullRequestsHandler,
16+
user::{GitHubUser, User},
17+
};
1518

19+
#[derive(Clone)]
1620
pub struct Repo {
1721
pub name: GithubRepoName,
1822
pub permissions: Permissions,
@@ -87,6 +91,9 @@ impl RepositoriesHandler {
8791
.await;
8892

8993
for repo in world.repos.values() {
94+
PullRequestsHandler::new(repo.to_owned())
95+
.mount(mock_server)
96+
.await;
9097
Mock::given(method("GET"))
9198
.and(path(format!(
9299
"/repos/{}/contents/rust-bors.toml",

src/tests/mocks/user.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use serde::Serialize;
22
use url::Url;
33

4-
#[derive(Eq, PartialEq, Hash, Clone)]
4+
#[derive(Eq, PartialEq, Hash, Clone, Debug)]
55
pub struct User {
66
pub github_id: u64,
77
pub name: String,

0 commit comments

Comments
 (0)