@@ -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,13 +62,6 @@ macro_rules! t {
61
62
} ;
62
63
}
63
64
64
- // TODO: Remove, this is equivalent to t!
65
- macro_rules! t_resp {
66
- ( $e: expr) => {
67
- t!( $e)
68
- } ;
69
- }
70
-
71
65
macro_rules! ok_resp {
72
66
( $e: expr) => { {
73
67
let resp = t!( $e) ;
@@ -88,73 +82,6 @@ macro_rules! bad_resp {
88
82
} } ;
89
83
}
90
84
91
- #[ derive( Deserialize , Debug ) ]
92
- struct Error {
93
- detail : String ,
94
- }
95
- #[ derive( Deserialize ) ]
96
- struct Bad {
97
- errors : Vec < Error > ,
98
- }
99
-
100
- type DieselConnection =
101
- diesel:: r2d2:: PooledConnection < diesel:: r2d2:: ConnectionManager < diesel:: PgConnection > > ;
102
- type ResponseResult = Result < conduit:: Response , Box < std:: error:: Error + Send > > ;
103
-
104
- #[ must_use]
105
- struct Response < T > {
106
- response : conduit:: Response ,
107
- callback_on_good : Option < Box < Fn ( & T ) > > ,
108
- }
109
-
110
- impl < T > Response < T >
111
- where
112
- for < ' de > T : serde:: Deserialize < ' de > ,
113
- {
114
- pub fn new ( response : ResponseResult ) -> Self {
115
- Self {
116
- response : t ! ( response) ,
117
- callback_on_good : None ,
118
- }
119
- }
120
-
121
- pub fn with_callback ( response : ResponseResult , callback_on_good : Box < Fn ( & T ) > ) -> Self {
122
- Self {
123
- response : t ! ( response) ,
124
- callback_on_good : Some ( callback_on_good) ,
125
- }
126
- }
127
-
128
- pub fn good ( mut self ) -> T {
129
- if !ok_resp ( & self . response ) {
130
- panic ! ( "bad response: {:?}" , self . response. status) ;
131
- }
132
- let good = json ( & mut self . response ) ;
133
- if let Some ( callback) = self . callback_on_good {
134
- callback ( & good)
135
- }
136
- good
137
- }
138
-
139
- pub fn bad_with_status ( & mut self , code : u32 ) -> Bad {
140
- assert_eq ! ( self . response. status. 0 , code) ;
141
- match bad_resp ( & mut self . response ) {
142
- None => panic ! ( "ok response: {:?}" , self . response. status) ,
143
- Some ( b) => b,
144
- }
145
- }
146
- }
147
-
148
- impl Response < ( ) > {
149
- pub fn assert_not_found ( & self ) {
150
- assert_eq ! ( ( 404 , "Not Found" ) , self . response. status) ;
151
- }
152
-
153
- pub fn assert_forbidden ( & self ) {
154
- assert_eq ! ( ( 403 , "Forbidden" ) , self . response. status) ;
155
- }
156
- }
157
-
158
85
mod badge;
159
86
mod categories;
160
87
mod category;
@@ -167,10 +94,11 @@ mod schema_details;
167
94
mod team;
168
95
mod token;
169
96
mod user;
97
+ mod util;
170
98
mod version;
171
99
172
100
#[ derive( Deserialize , Debug ) ]
173
- struct GoodCrate {
101
+ pub struct GoodCrate {
174
102
#[ serde( rename = "crate" ) ]
175
103
krate : EncodableCrate ,
176
104
warnings : Warnings ,
@@ -810,205 +738,6 @@ fn new_crate_to_body_with_tarball(new_crate: &u::NewCrate, tarball: &[u8]) -> Ve
810
738
body
811
739
}
812
740
813
- /// A struct representing a user's session to be used for the duration of a test.
814
- /// This injects requests directly into the router, so doesn't quite exercise the application
815
- /// exactly as in production, but it's close enough for most testing purposes.
816
- /// Has useful methods for making common HTTP requests.
817
- struct MockUserSession {
818
- app : Arc < App > ,
819
- // The bomb needs to be held in scope until the end of the test.
820
- _bomb : record:: Bomb ,
821
- middle : conduit_middleware:: MiddlewareBuilder ,
822
- user : Option < User > ,
823
- }
824
-
825
- impl MockUserSession {
826
- /// Create a session with no logged in user.
827
- pub fn anonymous ( ) -> Self {
828
- let ( bomb, app, middle) = app ( ) ;
829
- MockUserSession {
830
- app,
831
- _bomb : bomb,
832
- middle,
833
- user : None ,
834
- }
835
- }
836
-
837
- /// Create a session logged in with an arbitrary user.
838
- pub fn logged_in ( ) -> Self {
839
- let ( bomb, app, middle) = app ( ) ;
840
- let conn = app. diesel_database . get ( ) . unwrap ( ) ;
841
- let user = new_user ( "foo" ) . create_or_update ( & conn) . unwrap ( ) ;
842
-
843
- MockUserSession {
844
- app,
845
- _bomb : bomb,
846
- middle,
847
- user : Some ( user) ,
848
- }
849
- }
850
-
851
- /// Obtain the database connection and pass it to the closure
852
- ///
853
- /// Within each test, the connection pool only has 1 connection so it is necessary to drop the
854
- /// connection before making any API calls. Once the closure returns, the connection is
855
- /// dropped, ensuring it is available for any API calls.
856
- pub fn db < T , F : FnOnce ( & DieselConnection ) -> T > ( & self , f : F ) -> T {
857
- let conn = self . app . diesel_database . get ( ) . unwrap ( ) ;
858
- f ( & conn)
859
- }
860
-
861
- /// Build a MockRequest with a User if one is present
862
- fn request_builder ( & self , method : Method , path : & str ) -> MockRequest {
863
- let mut request = MockRequest :: new ( method, path) ;
864
- if let Some ( ref user) = self . user {
865
- request. mut_extensions ( ) . insert ( user. clone ( ) ) ;
866
- request
867
- . mut_extensions ( )
868
- . insert ( AuthenticationSource :: SessionCookie ) ;
869
- }
870
- request
871
- }
872
-
873
- /// Issue a GET request as the current user
874
- pub fn get < T > ( & self , path : & str ) -> Response < T >
875
- where
876
- for < ' de > T : serde:: Deserialize < ' de > ,
877
- {
878
- let mut request = self . request_builder ( Method :: Get , path) ;
879
- Response :: new ( self . middle . call ( & mut request) )
880
- }
881
-
882
- /// Issue a GET request as the current user
883
- pub fn get_with_query < T > ( & self , path : & str , query : & str ) -> Response < T >
884
- where
885
- for < ' de > T : serde:: Deserialize < ' de > ,
886
- {
887
- let mut request = self . request_builder ( Method :: Get , path) ;
888
- request. with_query ( query) ;
889
- Response :: new ( self . middle . call ( & mut request) )
890
- }
891
-
892
- /// Issue a PUT request as the current user
893
- pub fn put < T > ( & self , path : & str , body : & [ u8 ] ) -> Response < T >
894
- where
895
- for < ' de > T : serde:: Deserialize < ' de > ,
896
- {
897
- let mut builder = self . request_builder ( Method :: Put , path) ;
898
- let request = builder. with_body ( body) ;
899
- Response :: new ( self . middle . call ( request) )
900
- }
901
-
902
- /// Issue a DELETE request as the current user
903
- pub fn delete < T > ( & self , path : & str ) -> Response < T >
904
- where
905
- for < ' de > T : serde:: Deserialize < ' de > ,
906
- {
907
- let mut request = self . request_builder ( Method :: Delete , path) ;
908
- Response :: new ( self . middle . call ( & mut request) )
909
- }
910
-
911
- /// Log out the currently logged in user.
912
- pub fn logout ( & mut self ) {
913
- self . user = None ;
914
- }
915
-
916
- /// Using the same session, log in as a different user.
917
- pub fn log_in_as ( & mut self , user : User ) {
918
- self . user = Some ( user) ;
919
- }
920
-
921
- /// Create and log in as a new user, returning a reference to the user
922
- pub fn log_in_as_new ( & mut self , user : & str ) -> & User {
923
- let user = self . db ( |conn| new_user ( user) . create_or_update ( conn) . unwrap ( ) ) ;
924
- self . user = Some ( user) ;
925
- self . user ( )
926
- }
927
-
928
- /// Return a reference to the current user
929
- ///
930
- /// # Panics
931
- ///
932
- /// This function panics if there is no current user.
933
- pub fn user ( & self ) -> & User {
934
- self . user . as_ref ( ) . unwrap ( )
935
- }
936
-
937
- /// Publish the crate as specified by the given builder
938
- pub fn publish ( & self , publish_builder : PublishBuilder ) -> Response < GoodCrate > {
939
- let krate_name = publish_builder. krate_name . clone ( ) ;
940
- let mut builder = self . request_builder ( Method :: Put , "/api/v1/crates/new" ) ;
941
- let request = builder. with_body ( & publish_builder. body ( ) ) ;
942
- let response = self . middle . call ( request) ;
943
- let callback_on_good = move |json : & GoodCrate | assert_eq ! ( json. krate. name, krate_name) ;
944
- Response :: with_callback ( response, Box :: new ( callback_on_good) )
945
- }
946
-
947
- /// Request the JSON used for a crate's page.
948
- pub fn show_crate ( & mut self , krate_name : & str ) -> CrateResponse {
949
- let url = format ! ( "/api/v1/crates/{}" , krate_name) ;
950
- self . get ( & url) . good ( )
951
- }
952
-
953
- /// Yank the specified version of the specified crate.
954
- pub fn yank ( & mut self , krate_name : & str , version : & str ) -> Response < OkBool > {
955
- let url = format ! ( "/api/v1/crates/{}/{}/yank" , krate_name, version) ;
956
- let mut request = self . request_builder ( Method :: Delete , & url) ;
957
- Response :: new ( self . middle . call ( & mut request) )
958
- }
959
-
960
- /// Add a user as an owner for a crate.
961
- pub fn add_owner ( & mut self , krate_name : & str , user : & User ) {
962
- let url = format ! ( "/api/v1/crates/{}/owners" , krate_name) ;
963
- let body = format ! ( "{{\" users\" :[\" {}\" ]}}" , user. gh_login) ;
964
- let mut builder = self . request_builder ( Method :: Put , & url) ;
965
- let request = builder. with_body ( body. as_bytes ( ) ) ;
966
-
967
- let response: OkBool = Response :: new ( self . middle . call ( request) ) . good ( ) ;
968
- assert ! ( response. ok) ;
969
- }
970
-
971
- /// As the currently logged in user, accept an invitation to become an owner of the named
972
- /// crate.
973
- pub fn accept_ownership_invitation ( & mut self , krate_name : & str ) {
974
- use views:: InvitationResponse ;
975
-
976
- let krate_id = self . db ( |conn| Crate :: by_name ( krate_name) . first :: < Crate > ( conn) . unwrap ( ) . id ) ;
977
-
978
- let body = json ! ( {
979
- "crate_owner_invite" : {
980
- "invited_by_username" : "" ,
981
- "crate_name" : krate_name,
982
- "crate_id" : krate_id,
983
- "created_at" : "" ,
984
- "accepted" : true
985
- }
986
- } ) ;
987
-
988
- let url = format ! ( "/api/v1/me/crate_owner_invitations/{}" , krate_id) ;
989
- let mut builder = self . request_builder ( Method :: Put , & url) ;
990
- let request = builder. with_body ( body. to_string ( ) . as_bytes ( ) ) ;
991
-
992
- #[ derive( Deserialize ) ]
993
- struct CrateOwnerInvitation {
994
- crate_owner_invitation : InvitationResponse ,
995
- }
996
-
997
- let crate_owner_invite: CrateOwnerInvitation =
998
- Response :: new ( self . middle . call ( request) ) . good ( ) ;
999
- assert ! ( crate_owner_invite. crate_owner_invitation. accepted) ;
1000
- assert_eq ! ( crate_owner_invite. crate_owner_invitation. crate_id, krate_id) ;
1001
- }
1002
-
1003
- /// Get the crates owned by the specified user.
1004
- pub fn crates_owned_by ( & mut self , user : & User ) -> CrateList {
1005
- let query = format ! ( "user_id={}" , user. id) ;
1006
- let mut builder = self . request_builder ( Method :: Get , "/api/v1/crates" ) ;
1007
- let request = builder. with_query ( & query) ;
1008
- Response :: new ( self . middle . call ( request) ) . good ( )
1009
- }
1010
- }
1011
-
1012
741
lazy_static ! {
1013
742
static ref EMPTY_TARBALL_BYTES : Vec <u8 > = {
1014
743
let mut empty_tarball = vec![ ] ;
@@ -1024,7 +753,7 @@ lazy_static! {
1024
753
/// A builder for constructing a crate for the purposes of testing publishing. If you only need
1025
754
/// a crate to exist and don't need to test behavior caused by the publish request, inserting
1026
755
/// a crate into the database directly by using CrateBuilder will be faster.
1027
- struct PublishBuilder {
756
+ pub struct PublishBuilder {
1028
757
pub krate_name : String ,
1029
758
version : semver:: Version ,
1030
759
tarball : Vec < u8 > ,
0 commit comments