eitri-cli 1.10.1-beta.1 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/eitri-cli-v2/eitri-cli-v2.win32-x64-msvc.node +0 -0
  2. package/eitri-cli-v2/src/commands/mod.rs +2 -0
  3. package/eitri-cli-v2/src/commands/publish.rs +35 -0
  4. package/eitri-cli-v2/src/commands/run_test.rs +41 -0
  5. package/eitri-cli-v2/src/config/mod.rs +1 -0
  6. package/eitri-cli-v2/src/config/user_credentials.rs +38 -0
  7. package/eitri-cli-v2/src/infra/http_client.rs +493 -0
  8. package/eitri-cli-v2/src/infra/mod.rs +1 -0
  9. package/eitri-cli-v2/src/lib.rs +30 -0
  10. package/eitri-cli-v2/src/model/auth_response.rs +8 -0
  11. package/eitri-cli-v2/src/model/credentials.rs +8 -0
  12. package/eitri-cli-v2/src/model/eitri_conf.rs +43 -0
  13. package/eitri-cli-v2/src/model/mod.rs +8 -0
  14. package/eitri-cli-v2/src/model/process_output.rs +8 -0
  15. package/eitri-cli-v2/src/model/revision.rs +14 -0
  16. package/eitri-cli-v2/src/model/test_config.rs +7 -0
  17. package/eitri-cli-v2/src/model/url.rs +11 -0
  18. package/eitri-cli-v2/src/model/workspace_auth.rs +4 -0
  19. package/eitri-cli-v2/src/services/blind_guardian.rs +87 -0
  20. package/eitri-cli-v2/src/services/eitri_foundry.rs +84 -0
  21. package/eitri-cli-v2/src/services/eitri_manager.rs +78 -0
  22. package/eitri-cli-v2/src/services/mod.rs +4 -0
  23. package/eitri-cli-v2/src/services/workspace.rs +49 -0
  24. package/eitri-cli-v2/src/utils/convert_eitri_conf.rs +98 -0
  25. package/eitri-cli-v2/src/utils/mod.rs +1 -0
  26. package/package.json +1 -1
  27. package/src/modules/vegvisir/VegvisirService.js +1 -1
  28. package/src/service/Emulator/AndroidEmulatorService.js +3 -25
  29. package/src/service/MiniLog.js +46 -5
  30. package/test/Executor.js +60 -0
  31. package/test/Factory.js +13 -0
  32. package/test/Helper.js +15 -0
  33. package/test/_fixtures/factory.js +30 -0
  34. package/test/_fixtures/miniWebApp/miniapp.conf.js +4 -0
  35. package/test/_fixtures/miniapp.conf.js +5 -0
  36. package/test/_fixtures/server/HelloWorldBackend.js +7 -0
  37. package/test/_fixtures/src/Home.js +5 -0
  38. package/test/_fixtures/src/Home2.js +5 -0
  39. package/test/_fixtures/src/commons/util.js +3 -0
  40. package/test/_fixtures/src/components/TagA.jsx +4 -0
  41. package/test/_fixtures/src/components/TagB.jsx +4 -0
  42. package/test/_fixtures/src/components/TagC.jsx +3 -0
  43. package/test/_fixtures/src/components/TagD.jsx +3 -0
  44. package/test/_fixtures/src/server/foo.js +7 -0
  45. package/test/_fixtures/src/views/AboutTemplate.jsx +14 -0
  46. package/test/_fixtures/woodcoffee/miniapp.conf.js +5 -0
  47. package/test/ame.conf.js +3 -0
  48. package/test/cmd/clean.test.js +66 -0
  49. package/test/cmd/create.test.js +252 -0
  50. package/test/cmd/list.test.js +74 -0
  51. package/test/cmd/manage-env.test.js +168 -0
  52. package/test/e2e/cli.test.js +473 -0
  53. package/test/miniapp.conf.js +3 -0
  54. package/test/model/Payload.test.js +35 -0
  55. package/test/modules/vegvisir/VegvisirService.test.js +37 -0
  56. package/test/service/BlindGuardian.test.js +84 -0
  57. package/test/service/CheckAmeConf.test.js +313 -0
  58. package/test/service/Http.test.js +312 -0
  59. package/test/service/InviteService.test.js +117 -0
  60. package/test/service/MiniWebAppFactory.test.js +40 -0
  61. package/test/service/TagTree.test.js +81 -0
  62. package/test/service/TargetService.test.js +48 -0
  63. package/test/service/TrackingService.test.js +105 -0
  64. package/test/service/UserAmeConf.test.js +47 -0
  65. package/test/service/WoodCoffeeFactory.test.js +148 -0
  66. package/test/service/Workspace.test.js +211 -0
  67. package/test/utils/getWorkspaceId.test.js +17 -0
@@ -0,0 +1,2 @@
1
+ pub mod publish;
2
+ pub mod run_test;
@@ -0,0 +1,35 @@
1
+ use std::process::exit;
2
+
3
+ use crate::services::{eitri_manager, workspace};
4
+
5
+ const DIVISOR: &str = "========================================================";
6
+
7
+ pub async fn execute(environment: String, message: String) {
8
+ let init_message = format!("Iniciando publicação de Eitri-App",);
9
+ println!("{DIVISOR}");
10
+ println!("\t{init_message}");
11
+ println!("{DIVISOR}");
12
+
13
+ let eitri_conf = workspace::read_eitri_conf().await;
14
+ let version = eitri_conf.version;
15
+ println!("Versão a ser publicada: {}", version);
16
+ println!("Environment: {}", environment);
17
+ println!("Mensagem: {}", message);
18
+
19
+ let revision = match eitri_manager::get_revision(&eitri_conf.id, &version).await {
20
+ Ok(revision) => revision,
21
+ Err(_err) => {
22
+ eprintln!("Houve um erro ao buscar revisão.");
23
+ exit(1)
24
+ }
25
+ };
26
+ match eitri_manager::publish_revision(&revision.id, &environment, &message).await {
27
+ Ok(_) => {
28
+ println!("Eitri-App publicado com sucesso!")
29
+ }
30
+ Err(err) => {
31
+ eprintln!("Houve um erro. Error: {:?}", err);
32
+ exit(1)
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,41 @@
1
+ use std::{env, process::exit};
2
+ use colored::*;
3
+
4
+ use crate::{
5
+ model::{url::Url, workspace_auth::WorkspaceAuth},
6
+ services::eitri_foundry,
7
+ };
8
+
9
+ pub async fn execute(_workspace_auth: WorkspaceAuth, _path: String) {
10
+ let path = env::var("FOUNDRY_CONTEXT_PATH")
11
+ .ok()
12
+ .and_then(|context_path| {
13
+ if context_path.is_empty() {
14
+ Some(String::from("foundry/run-test"))
15
+ } else {
16
+ Some(format!("{}/run-test", context_path))
17
+ }
18
+ })
19
+ .unwrap_or_else(|| String::from("foundry/run-test"));
20
+
21
+ let url = Url {
22
+ host: String::from("https://api.eitri.tech/"),
23
+ path: path,
24
+ };
25
+ let result = eitri_foundry::run_test(_workspace_auth, _path, url).await;
26
+
27
+ match result {
28
+ Ok(output) => {
29
+ let output_str = output.stderr;
30
+ eprint!("{output_str}");
31
+ }
32
+ Err(http_error) => {
33
+ if let Some(message) = http_error.get_message() {
34
+ eprintln!("{}", message.red().bold());
35
+ } else {
36
+ eprintln!("Houve um erro ao executar os testes.");
37
+ }
38
+ exit(1)
39
+ }
40
+ }
41
+ }
@@ -0,0 +1 @@
1
+ pub mod user_credentials;
@@ -0,0 +1,38 @@
1
+ use std::{fs, process::exit};
2
+
3
+ use homedir::get_my_home;
4
+
5
+ use crate::model::credentials::Credentials;
6
+
7
+ pub fn get_credentials() -> Result<Credentials, serde_json::Error> {
8
+ let home_dir = match get_my_home() {
9
+ Ok(dir) => dir,
10
+ Err(_) => {
11
+ eprintln!("Houve um erro ao ler a home do usuário");
12
+ exit(1)
13
+ }
14
+ };
15
+
16
+ let home_dir = match home_dir {
17
+ Some(dir) => dir,
18
+ _ => exit(1),
19
+ };
20
+
21
+ let credentials_file_path = home_dir.join(".eitri").join("prod-eitri.conf.js");
22
+
23
+ let content = match fs::read_to_string(credentials_file_path.to_owned()) {
24
+ Ok(c) => c,
25
+ Err(_) => {
26
+ eprintln!(
27
+ "Houve um erro ao ler credenciais do usuário, certifique-se de ter feito login"
28
+ );
29
+ exit(1)
30
+ }
31
+ };
32
+
33
+ let content = content.replace("module.exports = ", "");
34
+
35
+ let credentials: Credentials = serde_json::from_str(&content)?;
36
+
37
+ Ok(credentials)
38
+ }
@@ -0,0 +1,493 @@
1
+ // use std::sync::Arc;
2
+
3
+ use reqwest::{header::HeaderMap, multipart::Form, Client};
4
+ use serde::de::DeserializeOwned;
5
+ use serde::Serialize;
6
+ use serde_derive::Deserialize;
7
+
8
+ // use crate::services::vegvisir::get_workspace;
9
+
10
+ // use super::cookie::{get_cookie, write_cookie};
11
+
12
+ #[allow(dead_code)]
13
+ #[derive(Debug, Deserialize)]
14
+ pub struct ApiError {
15
+ pub message: String,
16
+ }
17
+
18
+ #[allow(dead_code)]
19
+ #[derive(Debug)]
20
+ pub enum HttpError {
21
+ HttpError(reqwest::StatusCode, ApiError),
22
+ Deserialize(reqwest::Error),
23
+ }
24
+
25
+ impl HttpError {
26
+ pub fn get_message(&self) -> Option<&String> {
27
+ match self {
28
+ HttpError::HttpError(_, api_error) => Some(&api_error.message),
29
+ _ => None,
30
+ }
31
+ }
32
+ }
33
+
34
+ #[allow(dead_code)]
35
+ pub async fn post<T, U>(url: &str, data: U, headers: HeaderMap) -> Result<T, HttpError>
36
+ where
37
+ T: DeserializeOwned,
38
+ U: Serialize,
39
+ {
40
+ let client = get_client(url);
41
+
42
+ let response = client
43
+ .post(url)
44
+ .headers(headers)
45
+ .json(&data)
46
+ .send()
47
+ .await
48
+ .map_err(HttpError::Deserialize)?;
49
+
50
+ if response.status().is_success() {
51
+ // write_cookie(&response.headers(), &url);
52
+ return response.json().await.map_err(HttpError::Deserialize);
53
+ }
54
+ let status = response.status();
55
+ let mensagem = response
56
+ .text()
57
+ .await
58
+ .unwrap_or_else(|_| String::from("Erro desconhecido"));
59
+ let api_error: ApiError = serde_json::from_str(&mensagem).unwrap_or_else(|_| ApiError {
60
+ message: String::from("Erro ao relizar parse do JSON"),
61
+ });
62
+ Err(HttpError::HttpError(status, api_error))
63
+ }
64
+
65
+ #[allow(dead_code)]
66
+ pub async fn post_form_data<T>(url: &str, data: Form, headers: HeaderMap) -> Result<T, HttpError>
67
+ where
68
+ T: DeserializeOwned,
69
+ {
70
+ let client = get_client(url);
71
+
72
+ let response = client
73
+ .post(url)
74
+ .headers(headers)
75
+ .multipart(data)
76
+ .send()
77
+ .await
78
+ .map_err(HttpError::Deserialize)?;
79
+
80
+ if response.status().is_success() {
81
+ // write_cookie(&response.headers(), &url);
82
+ return response.json().await.map_err(HttpError::Deserialize);
83
+ }
84
+ let status = response.status();
85
+ let mensagem = response
86
+ .text()
87
+ .await
88
+ .unwrap_or_else(|_| String::from("Erro desconhecido"));
89
+ let api_error: ApiError = serde_json::from_str(&mensagem).unwrap_or_else(|_| ApiError {
90
+ message: String::from("Erro ao relizar parse do JSON"),
91
+ });
92
+ Err(HttpError::HttpError(status, api_error))
93
+ }
94
+
95
+ #[allow(dead_code)]
96
+ pub async fn get<T>(url: &str, headers: HeaderMap) -> Result<T, HttpError>
97
+ where
98
+ T: DeserializeOwned,
99
+ {
100
+ let client = get_client(url);
101
+
102
+ let response = client
103
+ .get(url)
104
+ .headers(headers)
105
+ .send()
106
+ .await
107
+ .map_err(HttpError::Deserialize)?;
108
+
109
+ if response.status().is_success() {
110
+ // write_cookie(&response.headers(), &url);
111
+ return response.json().await.map_err(HttpError::Deserialize);
112
+ }
113
+ let status = response.status();
114
+ let mensagem = response
115
+ .text()
116
+ .await
117
+ .unwrap_or_else(|_| String::from("Erro desconhecido"));
118
+ let api_error: ApiError = serde_json::from_str(&mensagem).unwrap_or_else(|_| ApiError {
119
+ message: String::from("Erro ao relizar parse do JSON"),
120
+ });
121
+ Err(HttpError::HttpError(status, api_error))
122
+ }
123
+
124
+ #[allow(dead_code)]
125
+ pub async fn put<U>(url: &str, data: U, headers: HeaderMap) -> Result<String, HttpError>
126
+ where
127
+ U: Serialize,
128
+ {
129
+ let client = get_client(url);
130
+
131
+ let response = client
132
+ .put(url)
133
+ .headers(headers)
134
+ .json(&data)
135
+ .send()
136
+ .await
137
+ .map_err(HttpError::Deserialize)?;
138
+
139
+ if response.status().is_success() {
140
+ // write_cookie(&response.headers(), &url);
141
+ return response.text().await.map_err(HttpError::Deserialize);
142
+ }
143
+
144
+ let status = response.status();
145
+ let mensagem = response
146
+ .text()
147
+ .await
148
+ .unwrap_or_else(|_| String::from("Erro desconhecido"));
149
+ let api_error: ApiError = serde_json::from_str(&mensagem).unwrap_or_else(|_| ApiError {
150
+ message: String::from("Erro ao relizar parse do JSON"),
151
+ });
152
+ Err(HttpError::HttpError(status, api_error))
153
+ }
154
+
155
+ #[allow(dead_code)]
156
+ pub async fn delete(url: &str, headers: HeaderMap) -> Result<(), HttpError> {
157
+ let client = get_client(url);
158
+
159
+ let response = client
160
+ .delete(url)
161
+ .headers(headers)
162
+ .send()
163
+ .await
164
+ .map_err(HttpError::Deserialize)?;
165
+
166
+ if response.status().is_success() {
167
+ // write_cookie(&response.headers(), &url);
168
+ return Ok(());
169
+ }
170
+
171
+ let status = response.status();
172
+ let mensagem = response
173
+ .text()
174
+ .await
175
+ .unwrap_or_else(|_| String::from("Erro desconhecido"));
176
+ let api_error: ApiError = serde_json::from_str(&mensagem).unwrap_or_else(|_| ApiError {
177
+ message: String::from("Erro ao relizar parse do JSON"),
178
+ });
179
+ Err(HttpError::HttpError(status, api_error))
180
+ }
181
+
182
+ #[allow(dead_code)]
183
+ pub async fn get_default_headers(token: String) -> HeaderMap {
184
+ let mut headers = HeaderMap::new();
185
+
186
+ // let workspace = get_workspace().await;
187
+
188
+ headers.append("Authorization", token.parse().unwrap());
189
+ // headers.append("Workspace-Id", workspace.id.parse().unwrap());
190
+
191
+ headers
192
+ }
193
+
194
+ #[allow(dead_code, unused_variables)]
195
+ fn get_client(request_url: &str) -> Client {
196
+ // let jar = get_cookie(request_url).unwrap_or_else(|| panic!("Error ao ler cookie"));
197
+ Client::builder()
198
+ .cookie_store(true)
199
+ // .cookie_provider(Arc::from(jar))
200
+ .build()
201
+ .unwrap()
202
+ }
203
+
204
+ #[cfg(test)]
205
+ mod tests {
206
+ use std::env;
207
+
208
+ use super::*;
209
+ use httpmock::prelude::*;
210
+ use reqwest::multipart;
211
+ use serde_derive::{Deserialize, Serialize};
212
+ use serde_json::json;
213
+
214
+ #[derive(Deserialize)]
215
+ struct Response {
216
+ #[serde(rename = "resultCount")]
217
+ result_count: i32,
218
+ }
219
+
220
+ #[derive(Deserialize)]
221
+ #[serde(rename_all = "camelCase")]
222
+ struct AuthResponse {
223
+ status: String,
224
+ }
225
+
226
+ #[derive(Deserialize, Serialize)]
227
+ struct UpdateData {
228
+ status: String,
229
+ email: String,
230
+ }
231
+
232
+ #[derive(Deserialize)]
233
+ struct FileUploadResponse {
234
+ ok: bool,
235
+ }
236
+
237
+ #[derive(Serialize, Deserialize)]
238
+ struct FakeAuth {
239
+ client_id: String,
240
+ client_secret: String,
241
+ grant_type: String,
242
+ }
243
+
244
+ #[derive(Deserialize)]
245
+ struct VoidResult {}
246
+
247
+ #[tokio::test]
248
+ async fn test_http_post_success() {
249
+ let mut headers = HeaderMap::new();
250
+ headers.append("user-agent", "eitri".parse().unwrap());
251
+
252
+ let client_id = env::var("EITRI_CLI_CLIENT_ID").unwrap();
253
+ let client_secret = env::var("EITRI_CLI_CLIENT_SECRET").unwrap();
254
+
255
+ let data = FakeAuth {
256
+ client_id,
257
+ client_secret,
258
+ grant_type: String::from("client_credentials"),
259
+ };
260
+
261
+ match post::<AuthResponse, FakeAuth>(
262
+ "https://api.eitri.tech/blind-guardian-api/v1/o/auth",
263
+ data,
264
+ headers,
265
+ )
266
+ .await
267
+ {
268
+ Ok(result) => {
269
+ assert_eq!(result.status, "ACTIVE");
270
+ }
271
+ Err(error) => match error {
272
+ HttpError::HttpError(_, error) => {
273
+ panic!("{}", error.message)
274
+ }
275
+ HttpError::Deserialize(error) => {
276
+ panic!("{:?}", error)
277
+ }
278
+ },
279
+ }
280
+ }
281
+
282
+ #[tokio::test]
283
+ async fn test_http_post_form_data_success() {
284
+ let mut headers = HeaderMap::new();
285
+ headers.append("user-agent", "eitri".parse().unwrap());
286
+ headers.append(
287
+ "Workspace-Id",
288
+ "3c42595c-3da6-475f-a843-5f65cd1982e6".parse().unwrap(),
289
+ );
290
+
291
+ let form = multipart::Form::new();
292
+
293
+ let form = form.text("filepath", "src/views/Home.jsx");
294
+
295
+ let part = multipart::Part::bytes("export default function Home {}".as_bytes())
296
+ .file_name("Home")
297
+ .mime_str("text/plain");
298
+
299
+ let part_result = match part {
300
+ Ok(result) => result,
301
+ Err(_) => {
302
+ panic!("Erro ao construir part")
303
+ }
304
+ };
305
+ let form = form.part("file", part_result);
306
+
307
+ let server = MockServer::start();
308
+
309
+ server.mock(|when, then| {
310
+ when.method(POST).path("/runes-foundry/fileupload");
311
+ then.status(200)
312
+ .header("content-type", "application/json; charset=UTF-8")
313
+ .body(
314
+ json!({
315
+ "ok": true
316
+ })
317
+ .to_string()
318
+ .as_bytes(),
319
+ );
320
+ });
321
+
322
+ match post_form_data::<FileUploadResponse>(
323
+ &server.url("/runes-foundry/fileupload"),
324
+ form,
325
+ headers,
326
+ )
327
+ .await
328
+ {
329
+ Ok(result) => {
330
+ assert!(result.ok);
331
+ }
332
+ Err(error) => match error {
333
+ HttpError::HttpError(_, error) => {
334
+ panic!("{}", error.message)
335
+ }
336
+ HttpError::Deserialize(error) => {
337
+ panic!("{:?}", error)
338
+ }
339
+ },
340
+ }
341
+ }
342
+
343
+ #[tokio::test]
344
+ async fn test_http_get_success() {
345
+ let mut headers = HeaderMap::new();
346
+ headers.append("user-agent", "eitri".parse().unwrap());
347
+ let result: Result<Response, HttpError> =
348
+ get("https://calindra.tech/eitri/product_list.json", headers).await;
349
+ assert!(result.is_ok());
350
+ let data = result.unwrap();
351
+ assert_eq!(6, data.result_count);
352
+ }
353
+
354
+ #[tokio::test]
355
+ async fn test_http_get_error_unauthorized() {
356
+ let mut headers = HeaderMap::new();
357
+ headers.append("user-agent", "eitri".parse().unwrap());
358
+
359
+ match get::<Response>(
360
+ "https://api.eitri.tech/eitri-manager-api/eitri-apps",
361
+ headers,
362
+ )
363
+ .await
364
+ {
365
+ Ok(_) => {}
366
+ Err(erro) => match erro {
367
+ HttpError::HttpError(status, error) => {
368
+ assert_eq!(status, 401);
369
+ assert_eq!(error.message, "JWT missing.")
370
+ }
371
+ HttpError::Deserialize(error) => {
372
+ panic!("{:?}", error)
373
+ }
374
+ },
375
+ }
376
+ }
377
+
378
+ #[tokio::test]
379
+ async fn test_http_get_error_forbidden_with_xml_response() {
380
+ let mut headers = HeaderMap::new();
381
+ headers.append("user-agent", "eitri".parse().unwrap());
382
+ match get::<Response>("https://calindra.tech/eitri/product_listx.json", headers).await {
383
+ Ok(_) => {}
384
+ Err(erro) => match erro {
385
+ HttpError::HttpError(status, _) => {
386
+ assert_eq!(status, 403)
387
+ }
388
+ HttpError::Deserialize(error) => {
389
+ panic!("{:?}", error)
390
+ }
391
+ },
392
+ }
393
+ }
394
+
395
+ #[tokio::test]
396
+ async fn test_http_put_success() {
397
+ let mut headers = HeaderMap::new();
398
+ headers.append("user-agent", "eitri".parse().unwrap());
399
+
400
+ let email = String::from("foobar@mail.com");
401
+
402
+ let data = UpdateData {
403
+ status: String::from("ACTIVE"),
404
+ email,
405
+ };
406
+
407
+ let server = MockServer::start();
408
+
409
+ server.mock(|when, then| {
410
+ when.method(PUT).path("/blind-guardian-api/v1/p/users/self");
411
+ then.status(200)
412
+ .header("content-type", "application/json; charset=UTF-8")
413
+ .body(
414
+ json!({
415
+ "status": "ACTIVE",
416
+ "email": "foobar@gmail.com"
417
+ })
418
+ .to_string()
419
+ .as_bytes(),
420
+ );
421
+ });
422
+ match put::<UpdateData>(
423
+ &format!("{}/blind-guardian-api/v1/p/users/self", server.url("")),
424
+ data,
425
+ headers,
426
+ )
427
+ .await
428
+ {
429
+ Ok(_) => {}
430
+ Err(error) => match error {
431
+ HttpError::HttpError(_, error) => {
432
+ panic!("{}", error.message)
433
+ }
434
+ HttpError::Deserialize(error) => {
435
+ panic!("{:?}", error)
436
+ }
437
+ },
438
+ }
439
+ }
440
+
441
+ #[tokio::test]
442
+ async fn test_http_delete_success() {
443
+ let mut headers = HeaderMap::new();
444
+ headers.append("user-agent", "eitri".parse().unwrap());
445
+ headers.append(
446
+ "Workspace-Id",
447
+ "3c42595c-3da6-475f-a843-5f65cd1982e6".parse().unwrap(),
448
+ );
449
+ headers.append(
450
+ "Authorization",
451
+ "3c42595c-3da6-475f-a843-5f65cd1982e6".parse().unwrap(),
452
+ );
453
+
454
+ let server = MockServer::start();
455
+
456
+ server.mock(|when, then| {
457
+ when.method(DELETE).path("/runes-foundry/sources");
458
+ then.status(200)
459
+ .header("content-type", "application/json; charset=UTF-8")
460
+ .body(json!({}).to_string().as_bytes());
461
+ });
462
+
463
+ match delete(&server.url("/runes-foundry/sources"), headers).await {
464
+ Ok(_) => {}
465
+ Err(error) => match error {
466
+ HttpError::HttpError(_, error) => {
467
+ panic!("{}", error.message)
468
+ }
469
+ HttpError::Deserialize(error) => {
470
+ panic!("{:?}", error)
471
+ }
472
+ },
473
+ }
474
+ }
475
+
476
+ #[tokio::test]
477
+ async fn test_http_client_should_receive_cookies() {
478
+ let url = "https://api.eitri.tech/runes-foundry/health";
479
+ let client = get_client(url);
480
+
481
+ let response = client
482
+ .get(url)
483
+ .send()
484
+ .await
485
+ .unwrap_or_else(|_| panic!("Erro inesperado"));
486
+
487
+ let mut cookies = response.cookies();
488
+
489
+ let stick_cookie = cookies.find(|c| c.name() == "stick_runes_foundry").unwrap();
490
+
491
+ assert_eq!(stick_cookie.name(), "stick_runes_foundry");
492
+ }
493
+ }
@@ -0,0 +1 @@
1
+ pub mod http_client;
@@ -0,0 +1,30 @@
1
+ #![deny(clippy::all)]
2
+
3
+ use commands::{publish, run_test};
4
+ use model::workspace_auth::WorkspaceAuth;
5
+ mod commands;
6
+ mod config;
7
+ mod infra;
8
+ mod model;
9
+ mod services;
10
+ mod utils;
11
+
12
+ #[macro_use]
13
+ extern crate napi_derive;
14
+
15
+ #[napi]
16
+ pub async fn publish(environment: String, message: String) {
17
+ publish::execute(environment, message).await;
18
+ }
19
+
20
+ #[napi]
21
+ pub async fn run_test(user_jwt: String, user_workspace_id: String, test_path: String) {
22
+
23
+ let workspace_auth = WorkspaceAuth {
24
+ access_token: user_jwt,
25
+ user_workspace_id: user_workspace_id,
26
+ };
27
+
28
+ run_test::execute(workspace_auth, test_path).await;
29
+
30
+ }
@@ -0,0 +1,8 @@
1
+ use serde::Deserialize;
2
+
3
+ #[allow(dead_code)]
4
+ #[derive(Deserialize)]
5
+ #[serde(rename_all = "camelCase")]
6
+ pub struct AuthResponse {
7
+ pub access_token: String,
8
+ }
@@ -0,0 +1,8 @@
1
+ use serde::{Deserialize, Serialize};
2
+
3
+ #[derive(Debug, Deserialize, Serialize)]
4
+ #[serde(rename_all = "camelCase")]
5
+ pub struct Credentials {
6
+ pub dev_user: String,
7
+ pub dev_key: String,
8
+ }