@@ -38,13 +38,14 @@ use cargo_registry::app::App;
38
38
use cargo_registry:: middleware:: current_user:: AuthenticationSource ;
39
39
use cargo_registry:: Replica ;
40
40
use chrono:: Utc ;
41
- use conduit:: { Handler , Method , Request } ;
41
+ use conduit:: { Method , Request } ;
42
42
use conduit_test:: MockRequest ;
43
43
use diesel:: prelude:: * ;
44
44
use flate2:: write:: GzEncoder ;
45
45
use flate2:: Compression ;
46
46
47
- pub use cargo_registry:: { models, schema, views} ;
47
+ use cargo_registry:: { models, schema, views} ;
48
+ use util:: { Bad , RequestHelper , TestApp } ;
48
49
49
50
use models:: { Crate , CrateDownload , CrateOwner , Dependency , Keyword , Team , User , Version } ;
50
51
use models:: { NewCategory , NewCrate , NewTeam , NewUser , NewVersion } ;
@@ -61,15 +62,9 @@ macro_rules! t {
61
62
} ;
62
63
}
63
64
64
- macro_rules! t_resp {
65
- ( $e: expr) => {
66
- t!( $e)
67
- } ;
68
- }
69
-
70
65
macro_rules! ok_resp {
71
66
( $e: expr) => { {
72
- let resp = t_resp !( $e) ;
67
+ let resp = t !( $e) ;
73
68
if !:: ok_resp( & resp) {
74
69
panic!( "bad response: {:?}" , resp. status) ;
75
70
}
@@ -79,23 +74,14 @@ macro_rules! ok_resp {
79
74
80
75
macro_rules! bad_resp {
81
76
( $e: expr) => { {
82
- let mut resp = t_resp !( $e) ;
77
+ let mut resp = t !( $e) ;
83
78
match :: bad_resp( & mut resp) {
84
79
None => panic!( "ok response: {:?}" , resp. status) ,
85
80
Some ( b) => b,
86
81
}
87
82
} } ;
88
83
}
89
84
90
- #[ derive( Deserialize , Debug ) ]
91
- struct Error {
92
- detail : String ,
93
- }
94
- #[ derive( Deserialize ) ]
95
- struct Bad {
96
- errors : Vec < Error > ,
97
- }
98
-
99
85
mod badge;
100
86
mod categories;
101
87
mod category;
@@ -108,10 +94,11 @@ mod schema_details;
108
94
mod team;
109
95
mod token;
110
96
mod user;
97
+ mod util;
111
98
mod version;
112
99
113
100
#[ derive( Deserialize , Debug ) ]
114
- struct GoodCrate {
101
+ pub struct GoodCrate {
115
102
#[ serde( rename = "crate" ) ]
116
103
krate : EncodableCrate ,
117
104
warnings : Warnings ,
@@ -137,6 +124,10 @@ pub struct CrateResponse {
137
124
versions : Vec < EncodableVersion > ,
138
125
keywords : Vec < EncodableKeyword > ,
139
126
}
127
+ #[ derive( Deserialize ) ]
128
+ struct OkBool {
129
+ ok : bool ,
130
+ }
140
131
141
132
fn app ( ) -> (
142
133
record:: Bomb ,
@@ -185,16 +176,15 @@ fn app() -> (
185
176
}
186
177
187
178
// Return the environment variable only if it has been defined
188
- fn env ( s : & str ) -> String {
189
- // Handles both the `None` and empty string cases e.g. VAR=
190
- // by converting `None` to an empty string
191
- let env_result = env:: var ( s) . ok ( ) . unwrap_or_default ( ) ;
192
-
193
- if env_result == "" {
194
- panic ! ( "must have `{}` defined" , s) ;
179
+ fn env ( var : & str ) -> String {
180
+ match env:: var ( var) {
181
+ Ok ( ref s) if s == "" => panic ! ( "environment variable `{}` must not be empty" , var) ,
182
+ Ok ( s) => s,
183
+ _ => panic ! (
184
+ "environment variable `{}` must be defined and valid unicode" ,
185
+ var
186
+ ) ,
195
187
}
196
-
197
- env_result
198
188
}
199
189
200
190
fn req ( method : conduit:: Method , path : & str ) -> MockRequest {
@@ -226,11 +216,11 @@ where
226
216
}
227
217
}
228
218
229
- static NEXT_ID : AtomicUsize = ATOMIC_USIZE_INIT ;
219
+ static NEXT_GH_ID : AtomicUsize = ATOMIC_USIZE_INIT ;
230
220
231
221
fn new_user ( login : & str ) -> NewUser < ' _ > {
232
222
NewUser {
233
- gh_id : NEXT_ID . fetch_add ( 1 , Ordering :: SeqCst ) as i32 ,
223
+ gh_id : NEXT_GH_ID . fetch_add ( 1 , Ordering :: SeqCst ) as i32 ,
234
224
gh_login : login,
235
225
email : None ,
236
226
name : None ,
@@ -239,21 +229,9 @@ fn new_user(login: &str) -> NewUser<'_> {
239
229
}
240
230
}
241
231
242
- fn user ( login : & str ) -> User {
243
- User {
244
- id : NEXT_ID . fetch_add ( 1 , Ordering :: SeqCst ) as i32 ,
245
- gh_id : NEXT_ID . fetch_add ( 1 , Ordering :: SeqCst ) as i32 ,
246
- gh_login : login. to_string ( ) ,
247
- email : None ,
248
- name : None ,
249
- gh_avatar : None ,
250
- gh_access_token : "some random token" . into ( ) ,
251
- }
252
- }
253
-
254
232
fn new_team ( login : & str ) -> NewTeam < ' _ > {
255
233
NewTeam {
256
- github_id : NEXT_ID . fetch_add ( 1 , Ordering :: SeqCst ) as i32 ,
234
+ github_id : NEXT_GH_ID . fetch_add ( 1 , Ordering :: SeqCst ) as i32 ,
257
235
login,
258
236
name : None ,
259
237
avatar : None ,
@@ -511,8 +489,10 @@ fn new_version(crate_id: i32, num: &str, crate_size: Option<i32>) -> NewVersion
511
489
}
512
490
513
491
fn krate ( name : & str ) -> Crate {
492
+ static NEXT_CRATE_ID : AtomicUsize = ATOMIC_USIZE_INIT ;
493
+
514
494
Crate {
515
- id : NEXT_ID . fetch_add ( 1 , Ordering :: SeqCst ) as i32 ,
495
+ id : NEXT_CRATE_ID . fetch_add ( 1 , Ordering :: SeqCst ) as i32 ,
516
496
name : name. to_string ( ) ,
517
497
updated_at : Utc :: now ( ) . naive_utc ( ) ,
518
498
created_at : Utc :: now ( ) . naive_utc ( ) ,
@@ -758,165 +738,6 @@ fn new_crate_to_body_with_tarball(new_crate: &u::NewCrate, tarball: &[u8]) -> Ve
758
738
body
759
739
}
760
740
761
- /// A struct representing a user's session to be used for the duration of a test.
762
- /// This injects requests directly into the router, so doesn't quite exercise the application
763
- /// exactly as in production, but it's close enough for most testing purposes.
764
- /// Has useful methods for making common HTTP requests.
765
- pub struct MockUserSession {
766
- app : Arc < App > ,
767
- // The bomb needs to be held in scope until the end of the test.
768
- _bomb : record:: Bomb ,
769
- middle : conduit_middleware:: MiddlewareBuilder ,
770
- request : MockRequest ,
771
- _user : User ,
772
- }
773
-
774
- impl MockUserSession {
775
- /// Create a session logged in with an arbitrary user.
776
- pub fn logged_in ( ) -> Self {
777
- let ( bomb, app, middle) = app ( ) ;
778
-
779
- let mut request = MockRequest :: new ( Method :: Get , "/" ) ;
780
- let user = {
781
- let conn = app. diesel_database . get ( ) . unwrap ( ) ;
782
- let user = new_user ( "foo" ) . create_or_update ( & conn) . unwrap ( ) ;
783
- request. mut_extensions ( ) . insert ( user. clone ( ) ) ;
784
- request
785
- . mut_extensions ( )
786
- . insert ( AuthenticationSource :: SessionCookie ) ;
787
-
788
- user
789
- } ;
790
-
791
- MockUserSession {
792
- app,
793
- _bomb : bomb,
794
- middle,
795
- request,
796
- _user : user,
797
- }
798
- }
799
-
800
- /// Create a session logged in with the given user.
801
- // pub fn logged_in_as(_user: &User) -> Self {
802
- // unimplemented!();
803
- // }
804
-
805
- /// For internal use only: make the current request
806
- fn make_request ( & mut self ) -> conduit:: Response {
807
- ok_resp ! ( self . middle. call( & mut self . request) )
808
- }
809
-
810
- /// Log out the currently logged in user.
811
- pub fn logout ( & mut self ) {
812
- logout ( & mut self . request ) ;
813
- }
814
-
815
- /// Using the same session, log in as a different user.
816
- pub fn log_in_as ( & mut self , user : & User ) {
817
- sign_in_as ( & mut self . request , user) ;
818
- }
819
-
820
- /// Publish the crate as specified by the given builder
821
- pub fn publish ( & mut self , publish_builder : PublishBuilder ) {
822
- let krate_name = publish_builder. krate_name . clone ( ) ;
823
- self . request
824
- . with_path ( "/api/v1/crates/new" )
825
- . with_method ( Method :: Put )
826
- . with_body ( & publish_builder. body ( ) ) ;
827
- let mut response = self . make_request ( ) ;
828
- let json: GoodCrate = json ( & mut response) ;
829
- assert_eq ! ( json. krate. name, krate_name) ;
830
- }
831
-
832
- /// Request the JSON used for a crate's page.
833
- pub fn show_crate ( & mut self , krate_name : & str ) -> CrateResponse {
834
- self . request
835
- . with_method ( Method :: Get )
836
- . with_path ( & format ! ( "/api/v1/crates/{}" , krate_name) ) ;
837
- let mut response = self . make_request ( ) ;
838
- json ( & mut response)
839
- }
840
-
841
- /// Yank the specified version of the specified crate.
842
- pub fn yank ( & mut self , krate_name : & str , version : & str ) -> conduit:: Response {
843
- self . request
844
- . with_path ( & format ! ( "/api/v1/crates/{}/{}/yank" , krate_name, version) )
845
- . with_method ( Method :: Delete ) ;
846
- self . make_request ( )
847
- }
848
-
849
- /// Add a user as an owner for a crate.
850
- pub fn add_owner ( & mut self , krate_name : & str , user : & User ) {
851
- let body = format ! ( "{{\" users\" :[\" {}\" ]}}" , user. gh_login) ;
852
- self . request
853
- . with_path ( & format ! ( "/api/v1/crates/{}/owners" , krate_name) )
854
- . with_method ( Method :: Put )
855
- . with_body ( body. as_bytes ( ) ) ;
856
-
857
- let mut response = self . make_request ( ) ;
858
-
859
- #[ derive( Deserialize ) ]
860
- struct O {
861
- ok : bool ,
862
- }
863
- assert ! ( json:: <O >( & mut response) . ok) ;
864
- }
865
-
866
- /// As the currently logged in user, accept an invitation to become an owner of the named
867
- /// crate.
868
- pub fn accept_ownership_invitation ( & mut self , krate_name : & str ) {
869
- use views:: InvitationResponse ;
870
-
871
- let krate_id = {
872
- let conn = self . app . diesel_database . get ( ) . unwrap ( ) ;
873
- Crate :: by_name ( krate_name)
874
- . first :: < Crate > ( & * conn)
875
- . unwrap ( )
876
- . id
877
- } ;
878
-
879
- let body = json ! ( {
880
- "crate_owner_invite" : {
881
- "invited_by_username" : "" ,
882
- "crate_name" : krate_name,
883
- "crate_id" : krate_id,
884
- "created_at" : "" ,
885
- "accepted" : true
886
- }
887
- } ) ;
888
-
889
- self . request
890
- . with_path ( & format ! ( "/api/v1/me/crate_owner_invitations/{}" , krate_id) )
891
- . with_method ( Method :: Put )
892
- . with_body ( body. to_string ( ) . as_bytes ( ) ) ;
893
-
894
- let mut response = self . make_request ( ) ;
895
-
896
- #[ derive( Deserialize ) ]
897
- struct CrateOwnerInvitation {
898
- crate_owner_invitation : InvitationResponse ,
899
- }
900
-
901
- let crate_owner_invite = :: json :: < CrateOwnerInvitation > ( & mut response) ;
902
- assert ! ( crate_owner_invite. crate_owner_invitation. accepted) ;
903
- assert_eq ! ( crate_owner_invite. crate_owner_invitation. crate_id, krate_id) ;
904
- }
905
-
906
- /// Get the crates owned by the specified user.
907
- pub fn crates_owned_by ( & mut self , user : & User ) -> CrateList {
908
- let query = format ! ( "user_id={}" , user. id) ;
909
- self . request
910
- . with_path ( "/api/v1/crates" )
911
- . with_method ( Method :: Get )
912
- . with_query ( & query) ;
913
-
914
- let mut response = self . make_request ( ) ;
915
-
916
- json :: < CrateList > ( & mut response)
917
- }
918
- }
919
-
920
741
lazy_static ! {
921
742
static ref EMPTY_TARBALL_BYTES : Vec <u8 > = {
922
743
let mut empty_tarball = vec![ ] ;
0 commit comments