-
Notifications
You must be signed in to change notification settings - Fork 243
/
gateway.rs
133 lines (111 loc) · 3.86 KB
/
gateway.rs
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use http::Method;
use tracing::instrument;
use shuttle_common::models;
use super::{header_map_with_bearer, Error, ServicesApiClient};
/// Interact with all the data relating to projects
#[allow(async_fn_in_trait)]
pub trait ProjectsDal {
/// Get a user project
async fn get_user_project(
&self,
user_token: &str,
project_name: &str,
) -> Result<models::project::Response, Error>;
/// Check the HEAD of a user project
async fn head_user_project(&self, user_token: &str, project_name: &str) -> Result<bool, Error>;
/// Get the projects that belong to a user
async fn get_user_projects(
&self,
user_token: &str,
) -> Result<Vec<models::project::Response>, Error>;
/// Get the IDs of all the projects belonging to a user
async fn get_user_project_ids(&self, user_token: &str) -> Result<Vec<String>, Error> {
let ids = self
.get_user_projects(user_token)
.await?
.into_iter()
.map(|p| p.id)
.collect();
Ok(ids)
}
}
impl ProjectsDal for ServicesApiClient {
#[instrument(skip_all)]
async fn get_user_project(
&self,
user_token: &str,
project_name: &str,
) -> Result<models::project::Response, Error> {
self.get(
format!("projects/{}", project_name).as_str(),
Some(header_map_with_bearer(user_token)),
)
.await
}
#[instrument(skip_all)]
async fn head_user_project(&self, user_token: &str, project_name: &str) -> Result<bool, Error> {
self.request_raw(
Method::HEAD,
format!("projects/{}", project_name).as_str(),
None::<()>,
Some(header_map_with_bearer(user_token)),
)
.await?;
Ok(true)
}
#[instrument(skip_all)]
async fn get_user_projects(
&self,
user_token: &str,
) -> Result<Vec<models::project::Response>, Error> {
self.get("projects", Some(header_map_with_bearer(user_token)))
.await
}
}
#[cfg(test)]
mod tests {
use test_context::{test_context, AsyncTestContext};
use shuttle_common::models::project::{Response, State};
use crate::client::ServicesApiClient;
use crate::test_utils::gateway::get_mocked_gateway_server;
use super::ProjectsDal;
impl AsyncTestContext for ServicesApiClient {
async fn setup() -> Self {
let server = get_mocked_gateway_server().await;
ServicesApiClient::new(server.uri().parse().unwrap())
}
async fn teardown(self) {}
}
#[test_context(ServicesApiClient)]
#[tokio::test]
async fn get_user_projects(client: &mut ServicesApiClient) {
let res = client.get_user_projects("user-1").await.unwrap();
assert_eq!(
res,
vec![
Response {
id: "00000000000000000000000001".to_string(),
name: "user-1-project-1".to_string(),
state: State::Stopped,
idle_minutes: Some(30),
owner: shuttle_common::models::project::Owner::User("user-1".to_string()),
is_admin: true,
},
Response {
id: "00000000000000000000000002".to_string(),
name: "user-1-project-2".to_string(),
state: State::Ready,
idle_minutes: Some(30),
owner: shuttle_common::models::project::Owner::User("user-1".to_string()),
is_admin: true,
}
]
)
}
#[test_context(ServicesApiClient)]
#[tokio::test]
async fn get_user_project_ids(client: &mut ServicesApiClient) {
let res = client.get_user_project_ids("user-2").await.unwrap();
assert_eq!(res, vec!["00000000000000000000000003"])
}
}