@@ -4,12 +4,13 @@ use std::collections::HashMap;
44use std:: io:: prelude:: * ;
55use std:: fs:: { self , File } ;
66
7+ use chrono:: Utc ;
78use conduit:: { Handler , Method } ;
8-
9- use git2;
9+ use diesel:: update;
1010use self :: diesel:: prelude:: * ;
11- use serde_json ;
11+ use git2 ;
1212use semver;
13+ use serde_json;
1314
1415use cargo_registry:: dependency:: EncodableDependency ;
1516use cargo_registry:: download:: EncodableVersionDownload ;
@@ -18,11 +19,11 @@ use cargo_registry::keyword::EncodableKeyword;
1819use cargo_registry:: krate:: { Crate , EncodableCrate , MAX_NAME_LENGTH } ;
1920
2021use cargo_registry:: token:: ApiToken ;
21- use cargo_registry:: schema:: { crates, versions} ;
22+ use cargo_registry:: schema:: { crates, metadata , versions} ;
2223
2324use cargo_registry:: upload as u;
2425use cargo_registry:: version:: EncodableVersion ;
25- use cargo_registry:: category:: Category ;
26+ use cargo_registry:: category:: { Category , EncodableCategory } ;
2627
2728use { CrateList , CrateMeta , GoodCrate } ;
2829
@@ -51,6 +52,18 @@ struct Downloads {
5152 version_downloads : Vec < EncodableVersionDownload > ,
5253}
5354
55+ #[ derive( Deserialize ) ]
56+ struct SummaryResponse {
57+ num_downloads : i64 ,
58+ num_crates : i64 ,
59+ new_crates : Vec < EncodableCrate > ,
60+ most_downloaded : Vec < EncodableCrate > ,
61+ most_recently_downloaded : Vec < EncodableCrate > ,
62+ just_updated : Vec < EncodableCrate > ,
63+ popular_keywords : Vec < EncodableKeyword > ,
64+ popular_categories : Vec < EncodableCategory > ,
65+ }
66+
5467fn new_crate ( name : & str ) -> u:: NewCrate {
5568 u:: NewCrate {
5669 name : u:: CrateName ( name. to_string ( ) ) ,
@@ -984,6 +997,80 @@ fn summary_doesnt_die() {
984997 ok_resp ! ( middle. call( & mut req) ) ;
985998}
986999
1000+ #[ test]
1001+ fn summary_new_crates ( ) {
1002+ let ( _b, app, middle) = :: app ( ) ;
1003+ let u;
1004+ let krate;
1005+ let krate2;
1006+ let krate3;
1007+ {
1008+ let conn = app. diesel_database . get ( ) . unwrap ( ) ;
1009+ u = :: new_user ( "foo" ) . create_or_update ( & conn) . unwrap ( ) ;
1010+
1011+ krate = :: CrateBuilder :: new ( "some_downloads" , u. id )
1012+ . version ( :: VersionBuilder :: new ( "0.1.0" ) )
1013+ . description ( "description" )
1014+ . keyword ( "popular" )
1015+ . downloads ( 20 )
1016+ . recent_downloads ( 10 )
1017+ . expect_build ( & conn) ;
1018+
1019+ krate2 = :: CrateBuilder :: new ( "most_recent_downloads" , u. id )
1020+ . version ( :: VersionBuilder :: new ( "0.2.0" ) )
1021+ . keyword ( "popular" )
1022+ . downloads ( 5000 )
1023+ . recent_downloads ( 50 )
1024+ . expect_build ( & conn) ;
1025+
1026+ krate3 = :: CrateBuilder :: new ( "just_updated" , u. id )
1027+ . version ( :: VersionBuilder :: new ( "0.1.0" ) )
1028+ . expect_build ( & conn) ;
1029+
1030+ :: CrateBuilder :: new ( "with_downloads" , u. id )
1031+ . version ( :: VersionBuilder :: new ( "0.3.0" ) )
1032+ . keyword ( "popular" )
1033+ . downloads ( 1000 )
1034+ . expect_build ( & conn) ;
1035+
1036+ :: new_category ( "Category 1" , "cat1" )
1037+ . create_or_update ( & conn)
1038+ . unwrap ( ) ;
1039+ Category :: update_crate ( & conn, & krate, & [ "cat1" ] ) . unwrap ( ) ;
1040+ Category :: update_crate ( & conn, & krate2, & [ "cat1" ] ) . unwrap ( ) ;
1041+
1042+ // set total_downloads global value for `num_downloads` prop
1043+ update ( metadata:: table)
1044+ . set ( metadata:: total_downloads. eq ( 6000 ) )
1045+ . execute ( & * conn)
1046+ . unwrap ( ) ;
1047+
1048+ // update 'just_updated' krate. Others won't appear because updated_at == created_at.
1049+ let updated = Utc :: now ( ) . naive_utc ( ) ;
1050+ update ( & krate3)
1051+ . set ( crates:: updated_at. eq ( updated) )
1052+ . execute ( & * conn)
1053+ . unwrap ( ) ;
1054+ }
1055+
1056+ let mut req = :: req ( app. clone ( ) , Method :: Get , "/api/v1/summary" ) ;
1057+ let mut response = ok_resp ! ( middle. call( & mut req) ) ;
1058+ let json: SummaryResponse = :: json ( & mut response) ;
1059+
1060+ assert_eq ! ( json. num_crates, 4 ) ;
1061+ assert_eq ! ( json. num_downloads, 6000 ) ;
1062+ assert_eq ! ( json. most_downloaded[ 0 ] . name, "most_recent_downloads" ) ;
1063+ assert_eq ! (
1064+ json. most_recently_downloaded[ 0 ] . name,
1065+ "most_recent_downloads"
1066+ ) ;
1067+ assert_eq ! ( json. popular_keywords[ 0 ] . keyword, "popular" ) ;
1068+ assert_eq ! ( json. popular_categories[ 0 ] . category, "Category 1" ) ;
1069+ assert_eq ! ( json. just_updated. len( ) , 1 ) ;
1070+ assert_eq ! ( json. just_updated[ 0 ] . name, "just_updated" ) ;
1071+ assert_eq ! ( json. new_crates. len( ) , 4 ) ;
1072+ }
1073+
9871074#[ test]
9881075fn download ( ) {
9891076 use chrono:: { Duration , Utc } ;
0 commit comments