Skip to content

Commit 482309d

Browse files
committed
tests/tokens/create: Use insta and serde_json::Value for response testing
Using insta ensures that tests will fail if we unintentionally change anything about the serialization format (e.g. adding token scopes fields 😉)
1 parent a4c94a7 commit 482309d

5 files changed

+76
-25
lines changed

src/tests/routes/me/tokens/create.rs

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
1+
use crate::util::insta::{self, assert_yaml_snapshot};
12
use crate::util::{RequestHelper, TestApp};
23
use cargo_registry::models::token::{CrateScope, EndpointScope};
34
use cargo_registry::models::ApiToken;
4-
use cargo_registry::views::EncodableApiTokenWithToken;
55
use diesel::prelude::*;
66
use http::StatusCode;
7+
use serde_json::Value;
78

89
static NEW_BAR: &[u8] = br#"{ "api_token": { "name": "bar" } }"#;
910

10-
#[derive(Deserialize)]
11-
struct NewResponse {
12-
api_token: EncodableApiTokenWithToken,
13-
}
14-
1511
#[test]
1612
fn create_token_logged_out() {
1713
let (_, anon) = TestApp::init().empty();
@@ -63,9 +59,14 @@ fn create_token_exceeded_tokens_per_user() {
6359
fn create_token_success() {
6460
let (app, _, user) = TestApp::init().with_user();
6561

66-
let json: NewResponse = user.put("/api/v1/me/tokens", NEW_BAR).good();
67-
assert_eq!(json.api_token.name, "bar");
68-
assert!(!json.api_token.token.is_empty());
62+
let response = user.put::<()>("/api/v1/me/tokens", NEW_BAR);
63+
assert_eq!(response.status(), StatusCode::OK);
64+
assert_yaml_snapshot!(response.into_json(), {
65+
".api_token.id" => insta::any_id_redaction(),
66+
".api_token.created_at" => "[datetime]",
67+
".api_token.last_used_at" => "[datetime]",
68+
".api_token.token" => insta::api_token_redaction(),
69+
});
6970

7071
let tokens: Vec<ApiToken> =
7172
app.db(|conn| assert_ok!(ApiToken::belonging_to(user.as_model()).load(conn)));
@@ -80,21 +81,22 @@ fn create_token_success() {
8081
#[test]
8182
fn create_token_multiple_have_different_values() {
8283
let (_, _, user) = TestApp::init().with_user();
83-
let first: NewResponse = user.put("/api/v1/me/tokens", NEW_BAR).good();
84-
let second: NewResponse = user.put("/api/v1/me/tokens", NEW_BAR).good();
84+
let first: Value = user.put("/api/v1/me/tokens", NEW_BAR).good();
85+
let second: Value = user.put("/api/v1/me/tokens", NEW_BAR).good();
8586

86-
assert_ne!(first.api_token.token, second.api_token.token);
87+
assert_eq!(first["api_token"]["name"], second["api_token"]["name"]);
88+
assert_ne!(first["api_token"]["token"], second["api_token"]["token"]);
8789
}
8890

8991
#[test]
9092
fn create_token_multiple_users_have_different_values() {
9193
let (app, _, user1) = TestApp::init().with_user();
92-
let first_token: NewResponse = user1.put("/api/v1/me/tokens", NEW_BAR).good();
94+
let first: Value = user1.put("/api/v1/me/tokens", NEW_BAR).good();
9395

9496
let user2 = app.db_new_user("bar");
95-
let second_token: NewResponse = user2.put("/api/v1/me/tokens", NEW_BAR).good();
97+
let second: Value = user2.put("/api/v1/me/tokens", NEW_BAR).good();
9698

97-
assert_ne!(first_token.api_token.token, second_token.api_token.token);
99+
assert_ne!(first["api_token"]["token"], second["api_token"]["token"]);
98100
}
99101

100102
#[test]
@@ -123,11 +125,14 @@ fn create_token_with_scopes() {
123125
}
124126
});
125127

126-
let json: NewResponse = user
127-
.put("/api/v1/me/tokens", &serde_json::to_vec(&json).unwrap())
128-
.good();
129-
assert_eq!(json.api_token.name, "bar");
130-
assert!(!json.api_token.token.is_empty());
128+
let response = user.put::<()>("/api/v1/me/tokens", &serde_json::to_vec(&json).unwrap());
129+
assert_eq!(response.status(), StatusCode::OK);
130+
assert_yaml_snapshot!(response.into_json(), {
131+
".api_token.id" => insta::any_id_redaction(),
132+
".api_token.created_at" => "[datetime]",
133+
".api_token.last_used_at" => "[datetime]",
134+
".api_token.token" => insta::api_token_redaction(),
135+
});
131136

132137
let tokens: Vec<ApiToken> =
133138
app.db(|conn| assert_ok!(ApiToken::belonging_to(user.as_model()).load(conn)));
@@ -160,11 +165,14 @@ fn create_token_with_null_scopes() {
160165
}
161166
});
162167

163-
let json: NewResponse = user
164-
.put("/api/v1/me/tokens", &serde_json::to_vec(&json).unwrap())
165-
.good();
166-
assert_eq!(json.api_token.name, "bar");
167-
assert!(!json.api_token.token.is_empty());
168+
let response = user.put::<()>("/api/v1/me/tokens", &serde_json::to_vec(&json).unwrap());
169+
assert_eq!(response.status(), StatusCode::OK);
170+
assert_yaml_snapshot!(response.into_json(), {
171+
".api_token.id" => insta::any_id_redaction(),
172+
".api_token.created_at" => "[datetime]",
173+
".api_token.last_used_at" => "[datetime]",
174+
".api_token.token" => insta::api_token_redaction(),
175+
});
168176

169177
let tokens: Vec<ApiToken> =
170178
app.db(|conn| assert_ok!(ApiToken::belonging_to(user.as_model()).load(conn)));
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
source: src/tests/routes/me/tokens/create.rs
3+
expression: response.into_json()
4+
---
5+
api_token:
6+
created_at: "[datetime]"
7+
id: "[id]"
8+
last_used_at: "[datetime]"
9+
name: bar
10+
revoked: false
11+
token: "[token]"
12+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
source: src/tests/routes/me/tokens/create.rs
3+
expression: response.into_json()
4+
---
5+
api_token:
6+
created_at: "[datetime]"
7+
id: "[id]"
8+
last_used_at: "[datetime]"
9+
name: bar
10+
revoked: false
11+
token: "[token]"
12+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
source: src/tests/routes/me/tokens/create.rs
3+
expression: response.into_json()
4+
---
5+
api_token:
6+
created_at: "[datetime]"
7+
id: "[id]"
8+
last_used_at: "[datetime]"
9+
name: bar
10+
revoked: false
11+
token: "[token]"
12+

src/tests/util/insta.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,10 @@ pub fn any_id_redaction() -> insta::internals::Redaction {
1313
"[id]"
1414
})
1515
}
16+
17+
pub fn api_token_redaction() -> insta::internals::Redaction {
18+
insta::dynamic_redaction(move |value, _path| {
19+
assert!(assert_some!(value.as_str()).starts_with("cio"));
20+
"[token]"
21+
})
22+
}

0 commit comments

Comments
 (0)