@@ -14,33 +14,41 @@ use axum::{
14
14
pub ( crate ) async fn status_handler (
15
15
Path ( ( name, req_version) ) : Path < ( String , String ) > ,
16
16
Extension ( pool) : Extension < Pool > ,
17
- ) -> AxumResult < impl IntoResponse > {
18
- let ( _, id) = match_version_axum ( & pool, & name, Some ( & req_version) )
19
- . await ?
20
- . exact_name_only ( ) ?
21
- . exact_version_only ( ) ?;
22
-
23
- let rustdoc_status: bool = spawn_blocking ( {
24
- move || {
25
- Ok ( pool
26
- . get ( ) ?
27
- . query_one (
28
- "SELECT releases.rustdoc_status
29
- FROM releases
30
- WHERE releases.id = $1
31
- " ,
32
- & [ & id] ,
33
- ) ?
34
- . get ( "rustdoc_status" ) )
35
- }
36
- } )
37
- . await ?;
38
-
39
- Ok ( (
17
+ ) -> impl IntoResponse {
18
+ (
40
19
Extension ( CachePolicy :: NoStoreMustRevalidate ) ,
41
20
[ ( ACCESS_CONTROL_ALLOW_ORIGIN , "*" ) ] ,
42
- Json ( serde_json:: json!( { "doc_status" : rustdoc_status } ) ) ,
43
- ) )
21
+ // We use an async block to emulate a try block so that we can apply the above CORS header
22
+ // and cache policy to both successful and failed responses
23
+ async move {
24
+ let ( version, id) = match_version_axum ( & pool, & name, Some ( & req_version) )
25
+ . await ?
26
+ . exact_name_only ( ) ?
27
+ . into_parts ( ) ;
28
+
29
+ let rustdoc_status: bool = spawn_blocking ( {
30
+ move || {
31
+ Ok ( pool
32
+ . get ( ) ?
33
+ . query_one (
34
+ "SELECT releases.rustdoc_status
35
+ FROM releases
36
+ WHERE releases.id = $1
37
+ " ,
38
+ & [ & id] ,
39
+ ) ?
40
+ . get ( "rustdoc_status" ) )
41
+ }
42
+ } )
43
+ . await ?;
44
+
45
+ AxumResult :: Ok ( Json ( serde_json:: json!( {
46
+ "version" : version,
47
+ "doc_status" : rustdoc_status,
48
+ } ) ) )
49
+ }
50
+ . await ,
51
+ )
44
52
}
45
53
46
54
#[ cfg( test) ]
@@ -50,93 +58,88 @@ mod tests {
50
58
web:: cache:: CachePolicy ,
51
59
} ;
52
60
use reqwest:: StatusCode ;
61
+ use test_case:: test_case;
53
62
54
- #[ test]
55
- fn success ( ) {
63
+ #[ test_case( "latest" ) ]
64
+ #[ test_case( "0.1" ) ]
65
+ #[ test_case( "0.1.0" ) ]
66
+ fn status ( version : & str ) {
56
67
wrapper ( |env| {
57
68
env. fake_release ( ) . name ( "foo" ) . version ( "0.1.0" ) . create ( ) ?;
58
69
59
- let response = env. frontend ( ) . get ( "/crate/foo/0.1.0/status.json" ) . send ( ) ?;
70
+ let response = env
71
+ . frontend ( )
72
+ . get ( & format ! ( "/crate/foo/{version}/status.json" ) )
73
+ . send ( ) ?;
60
74
assert_cache_control ( & response, CachePolicy :: NoStoreMustRevalidate , & env. config ( ) ) ;
61
75
assert_eq ! ( response. headers( ) [ "access-control-allow-origin" ] , "*" ) ;
76
+ assert_eq ! ( response. status( ) , StatusCode :: OK ) ;
62
77
let value: serde_json:: Value = serde_json:: from_str ( & response. text ( ) ?) ?;
63
78
64
- assert_eq ! ( value, serde_json:: json!( { "doc_status" : true } ) ) ;
79
+ assert_eq ! (
80
+ value,
81
+ serde_json:: json!( {
82
+ "version" : "0.1.0" ,
83
+ "doc_status" : true ,
84
+ } )
85
+ ) ;
65
86
66
87
Ok ( ( ) )
67
88
} ) ;
68
89
}
69
90
70
- #[ test]
71
- fn failure ( ) {
91
+ #[ test_case( "latest" ) ]
92
+ #[ test_case( "0.1" ) ]
93
+ #[ test_case( "0.1.0" ) ]
94
+ fn failure ( version : & str ) {
72
95
wrapper ( |env| {
73
96
env. fake_release ( )
74
97
. name ( "foo" )
75
98
. version ( "0.1.0" )
76
99
. build_result_failed ( )
77
100
. create ( ) ?;
78
101
79
- let response = env. frontend ( ) . get ( "/crate/foo/0.1.0/status.json" ) . send ( ) ?;
102
+ let response = env
103
+ . frontend ( )
104
+ . get ( & format ! ( "/crate/foo/{version}/status.json" ) )
105
+ . send ( ) ?;
80
106
assert_cache_control ( & response, CachePolicy :: NoStoreMustRevalidate , & env. config ( ) ) ;
81
107
assert_eq ! ( response. headers( ) [ "access-control-allow-origin" ] , "*" ) ;
108
+ assert_eq ! ( response. status( ) , StatusCode :: OK ) ;
82
109
let value: serde_json:: Value = serde_json:: from_str ( & response. text ( ) ?) ?;
83
110
84
- assert_eq ! ( value, serde_json:: json!( { "doc_status" : false } ) ) ;
111
+ assert_eq ! (
112
+ value,
113
+ serde_json:: json!( {
114
+ "version" : "0.1.0" ,
115
+ "doc_status" : false ,
116
+ } )
117
+ ) ;
85
118
86
119
Ok ( ( ) )
87
120
} ) ;
88
121
}
89
122
90
- #[ test]
91
- fn crate_version_not_found ( ) {
123
+ // crate not found
124
+ #[ test_case( "bar" , "0.1" ) ]
125
+ #[ test_case( "bar" , "0.1.0" ) ]
126
+ // version not found
127
+ #[ test_case( "foo" , "0.2" ) ]
128
+ #[ test_case( "foo" , "0.2.0" ) ]
129
+ // invalid semver
130
+ #[ test_case( "foo" , "0,1" ) ]
131
+ #[ test_case( "foo" , "0,1,0" ) ]
132
+ fn not_found ( krate : & str , version : & str ) {
92
133
wrapper ( |env| {
93
134
env. fake_release ( ) . name ( "foo" ) . version ( "0.1.0" ) . create ( ) ?;
94
135
95
- let response = env. frontend ( ) . get ( "/crate/foo/0.2.0/status.json" ) . send ( ) ?;
96
- assert ! ( response
97
- . url( )
98
- . as_str( )
99
- . ends_with( "/crate/foo/0.2.0/status.json" ) ) ;
100
- assert_eq ! ( response. status( ) , StatusCode :: NOT_FOUND ) ;
101
- Ok ( ( ) )
102
- } ) ;
103
- }
104
-
105
- #[ test]
106
- fn invalid_semver ( ) {
107
- wrapper ( |env| {
108
- env. fake_release ( ) . name ( "foo" ) . version ( "0.1.0" ) . create ( ) ?;
109
-
110
- let response = env. frontend ( ) . get ( "/crate/foo/0,1,0/status.json" ) . send ( ) ?;
111
- assert ! ( response
112
- . url( )
113
- . as_str( )
114
- . ends_with( "/crate/foo/0,1,0/status.json" ) ) ;
115
- assert_eq ! ( response. status( ) , StatusCode :: NOT_FOUND ) ;
116
- Ok ( ( ) )
117
- } ) ;
118
- }
119
-
120
- /// We only support asking for the status of exact versions
121
- #[ test]
122
- fn no_semver ( ) {
123
- wrapper ( |env| {
124
- env. fake_release ( ) . name ( "foo" ) . version ( "0.1.0" ) . create ( ) ?;
125
-
126
- let response = env. frontend ( ) . get ( "/crate/foo/latest/status.json" ) . send ( ) ?;
127
- assert ! ( response
128
- . url( )
129
- . as_str( )
130
- . ends_with( "/crate/foo/latest/status.json" ) ) ;
131
- assert_eq ! ( response. status( ) , StatusCode :: NOT_FOUND ) ;
132
-
133
- let response = env. frontend ( ) . get ( "/crate/foo/0.1/status.json" ) . send ( ) ?;
134
- assert ! ( response
135
- . url( )
136
- . as_str( )
137
- . ends_with( "/crate/foo/0.1/status.json" ) ) ;
136
+ let response = env
137
+ . frontend ( )
138
+ . get ( & format ! ( "/crate/{krate}/{version}/status.json" ) )
139
+ . send ( ) ?;
140
+ assert_cache_control ( & response, CachePolicy :: NoStoreMustRevalidate , & env. config ( ) ) ;
141
+ assert_eq ! ( response. headers( ) [ "access-control-allow-origin" ] , "*" ) ;
138
142
assert_eq ! ( response. status( ) , StatusCode :: NOT_FOUND ) ;
139
-
140
143
Ok ( ( ) )
141
144
} ) ;
142
145
}
0 commit comments