@@ -109,61 +109,11 @@ pub(crate) fn get_releases(conn: &mut Client, page: i64, limit: i64, order: Orde
109109 . collect ( )
110110}
111111
112- fn get_releases_by_author (
113- conn : & mut Client ,
114- page : i64 ,
115- limit : i64 ,
116- author : & str ,
117- ) -> ( String , Vec < Release > ) {
118- let offset = ( page - 1 ) * limit;
119-
120- let query = "
121- SELECT crates.name,
122- releases.version,
123- releases.description,
124- releases.target_name,
125- releases.release_time,
126- releases.rustdoc_status,
127- github_repos.stars,
128- authors.name
129- FROM crates
130- INNER JOIN releases ON releases.id = crates.latest_version_id
131- INNER JOIN author_rels ON releases.id = author_rels.rid
132- INNER JOIN authors ON authors.id = author_rels.aid
133- LEFT JOIN github_repos ON releases.github_repo = github_repos.id
134- WHERE authors.slug = $1
135- ORDER BY github_repos.stars DESC NULLS LAST
136- LIMIT $2 OFFSET $3" ;
137- let query = conn. query ( query, & [ & author, & limit, & offset] ) . unwrap ( ) ;
138-
139- let mut author_name = None ;
140- let packages = query
141- . into_iter ( )
142- . map ( |row| {
143- if author_name. is_none ( ) {
144- author_name = Some ( row. get ( 7 ) ) ;
145- }
146-
147- Release {
148- name : row. get ( 0 ) ,
149- version : row. get ( 1 ) ,
150- description : row. get ( 2 ) ,
151- target_name : row. get ( 3 ) ,
152- release_time : row. get ( 4 ) ,
153- rustdoc_status : row. get ( 5 ) ,
154- stars : row. get :: < _ , Option < i32 > > ( 6 ) . unwrap_or ( 0 ) ,
155- }
156- } )
157- . collect ( ) ;
158-
159- ( author_name. unwrap_or_default ( ) , packages)
160- }
161-
162112fn get_releases_by_owner (
163113 conn : & mut Client ,
164114 page : i64 ,
165115 limit : i64 ,
166- author : & str ,
116+ owner : & str ,
167117) -> ( String , Vec < Release > ) {
168118 let offset = ( page - 1 ) * limit;
169119
@@ -184,14 +134,14 @@ fn get_releases_by_owner(
184134 WHERE owners.login = $1
185135 ORDER BY github_repos.stars DESC NULLS LAST
186136 LIMIT $2 OFFSET $3" ;
187- let query = conn. query ( query, & [ & author , & limit, & offset] ) . unwrap ( ) ;
137+ let query = conn. query ( query, & [ & owner , & limit, & offset] ) . unwrap ( ) ;
188138
189- let mut author_name = None ;
139+ let mut owner_name = None ;
190140 let packages = query
191141 . into_iter ( )
192142 . map ( |row| {
193- if author_name . is_none ( ) {
194- author_name = Some ( if !row. get :: < usize , String > ( 7 ) . is_empty ( ) {
143+ if owner_name . is_none ( ) {
144+ owner_name = Some ( if !row. get :: < usize , String > ( 7 ) . is_empty ( ) {
195145 row. get ( 7 )
196146 } else {
197147 row. get ( 8 )
@@ -210,7 +160,7 @@ fn get_releases_by_owner(
210160 } )
211161 . collect ( ) ;
212162
213- ( author_name . unwrap_or_default ( ) , packages)
163+ ( owner_name . unwrap_or_default ( ) , packages)
214164}
215165
216166/// Get the search results for a crate search query
@@ -336,7 +286,7 @@ struct ViewReleases {
336286 show_next_page : bool ,
337287 show_previous_page : bool ,
338288 page_number : i64 ,
339- author : Option < String > ,
289+ owner : Option < String > ,
340290}
341291
342292impl_webpage ! {
@@ -350,7 +300,7 @@ pub(super) enum ReleaseType {
350300 Stars ,
351301 RecentFailures ,
352302 Failures ,
353- Author ,
303+ Owner ,
354304 Search ,
355305}
356306
@@ -369,8 +319,8 @@ fn releases_handler(req: &mut Request, release_type: ReleaseType) -> IronResult<
369319 Order :: FailuresByGithubStars ,
370320 ) ,
371321
372- ReleaseType :: Author | ReleaseType :: Search => panic ! (
373- "The authors and search page have special requirements and cannot use this handler" ,
322+ ReleaseType :: Owner | ReleaseType :: Search => panic ! (
323+ "The owners and search page have special requirements and cannot use this handler" ,
374324 ) ,
375325 } ;
376326
@@ -392,7 +342,7 @@ fn releases_handler(req: &mut Request, release_type: ReleaseType) -> IronResult<
392342 show_next_page,
393343 show_previous_page,
394344 page_number,
395- author : None ,
345+ owner : None ,
396346 }
397347 . into_response ( req)
398348}
@@ -413,39 +363,29 @@ pub fn releases_failures_by_stars_handler(req: &mut Request) -> IronResult<Respo
413363 releases_handler ( req, ReleaseType :: Failures )
414364}
415365
416- pub fn author_handler ( req : & mut Request ) -> IronResult < Response > {
366+ pub fn owner_handler ( req : & mut Request ) -> IronResult < Response > {
417367 let router = extension ! ( req, Router ) ;
418368 // page number of releases
419369 let page_number: i64 = router
420370 . find ( "page" )
421371 . and_then ( |page_num| page_num. parse ( ) . ok ( ) )
422372 . unwrap_or ( 1 ) ;
423- let author = router
424- . find ( "author" )
425- // TODO: Accurate error here, the author wasn't provided
426- . ok_or ( Nope :: CrateNotFound ) ?;
373+ let owner_route_value = router. find ( "owner" ) . unwrap ( ) ;
427374
428- let ( author_name , releases) = {
375+ let ( owner_name , releases) = {
429376 let mut conn = extension ! ( req, Pool ) . get ( ) ?;
430377
431- if author. starts_with ( '@' ) {
432- let mut author = author. split ( '@' ) ;
433-
434- get_releases_by_owner (
435- & mut conn,
436- page_number,
437- RELEASES_IN_RELEASES ,
438- // TODO: Is this fallible?
439- cexpect ! ( req, author. nth( 1 ) ) ,
440- )
441- } else {
442- get_releases_by_author ( & mut conn, page_number, RELEASES_IN_RELEASES , author)
378+ // We need to keep the owner_route_value unchanged, as we may render paginated links in the page.
379+ // Changing the owner_route_value directly will cause the link to change, for example: @foobar -> foobar.
380+ let mut owner = owner_route_value;
381+ if owner. starts_with ( '@' ) {
382+ owner = & owner[ 1 ..] ;
443383 }
384+ get_releases_by_owner ( & mut conn, page_number, RELEASES_IN_RELEASES , owner)
444385 } ;
445386
446387 if releases. is_empty ( ) {
447- // TODO: Accurate error here, the author wasn't found
448- return Err ( Nope :: CrateNotFound . into ( ) ) ;
388+ return Err ( Nope :: OwnerNotFound . into ( ) ) ;
449389 }
450390
451391 // Show next and previous page buttons
@@ -456,12 +396,12 @@ pub fn author_handler(req: &mut Request) -> IronResult<Response> {
456396
457397 ViewReleases {
458398 releases,
459- description : format ! ( "Crates from {}" , author_name ) ,
460- release_type : ReleaseType :: Author ,
399+ description : format ! ( "Crates from {}" , owner_name ) ,
400+ release_type : ReleaseType :: Owner ,
461401 show_next_page,
462402 show_previous_page,
463403 page_number,
464- author : Some ( author . into ( ) ) ,
404+ owner : Some ( owner_route_value . into ( ) ) ,
465405 }
466406 . into_response ( req)
467407}
@@ -754,6 +694,7 @@ pub fn build_queue_handler(req: &mut Request) -> IronResult<Response> {
754694#[ cfg( test) ]
755695mod tests {
756696 use super :: * ;
697+ use crate :: index:: api:: CrateOwner ;
757698 use crate :: test:: { assert_redirect, assert_success, wrapper, TestFrontend } ;
758699 use chrono:: { Duration , TimeZone } ;
759700 use failure:: Error ;
@@ -1446,29 +1387,75 @@ mod tests {
14461387 }
14471388
14481389 #[ test]
1449- fn authors_page ( ) {
1390+ fn nonexistent_owner_page ( ) {
1391+ wrapper ( |env| {
1392+ env. fake_release ( )
1393+ . name ( "some_random_crate" )
1394+ . add_owner ( CrateOwner {
1395+ login : "foobar" . into ( ) ,
1396+ avatar : "https://example.org/foobar" . into ( ) ,
1397+ name : "Foo Bar" . into ( ) ,
1398+ email : "foobar@example.org" . into ( ) ,
1399+ } )
1400+ . create ( ) ?;
1401+ let page = kuchiki:: parse_html ( ) . one (
1402+ env. frontend ( )
1403+ . get ( "/releases/random-author" )
1404+ . send ( ) ?
1405+ . text ( ) ?,
1406+ ) ;
1407+
1408+ assert_eq ! ( page. select( "#crate-title" ) . unwrap( ) . count( ) , 1 ) ;
1409+ assert_eq ! (
1410+ page. select( "#crate-title" )
1411+ . unwrap( )
1412+ . next( )
1413+ . unwrap( )
1414+ . text_contents( ) ,
1415+ "The requested owner does not exist" ,
1416+ ) ;
1417+
1418+ Ok ( ( ) )
1419+ } ) ;
1420+ }
1421+
1422+ #[ test]
1423+ fn owners_page ( ) {
14501424 wrapper ( |env| {
14511425 let web = env. frontend ( ) ;
14521426 env. fake_release ( )
14531427 . name ( "some_random_crate" )
1454- . author ( "frankenstein <frankie@stein.com>" )
1428+ . add_owner ( CrateOwner {
1429+ login : "foobar" . into ( ) ,
1430+ avatar : "https://example.org/foobar" . into ( ) ,
1431+ name : "Foo Bar" . into ( ) ,
1432+ email : "foobar@example.org" . into ( ) ,
1433+ } )
14551434 . create ( ) ?;
1456- assert_success ( "/releases/frankenstein" , web)
1435+ // Request an owner without @ sign.
1436+ assert_success ( "/releases/foobar" , web) ?;
1437+ // Request an owner with @ sign.
1438+ assert_success ( "/releases/@foobar" , web)
14571439 } )
14581440 }
14591441
14601442 #[ test]
1461- fn authors_pagination ( ) {
1443+ fn owners_pagination ( ) {
14621444 wrapper ( |env| {
14631445 let web = env. frontend ( ) ;
14641446 for i in 0 ..RELEASES_IN_RELEASES {
14651447 env. fake_release ( )
14661448 . name ( & format ! ( "some_random_crate_{}" , i) )
1467- . author ( "frankenstein <frankie@stein.com" )
1449+ . add_owner ( CrateOwner {
1450+ login : "foobar" . into ( ) ,
1451+ avatar : "https://example.org/foobar" . into ( ) ,
1452+ name : "Foo Bar" . into ( ) ,
1453+ email : "foobar@example.org" . into ( ) ,
1454+ } )
14681455 . create ( ) ?;
14691456 }
1470- let page = kuchiki:: parse_html ( ) . one ( web. get ( "/releases/frankenstein " ) . send ( ) ?. text ( ) ?) ;
1471- let button = page. select_first ( "a[href='/releases/frankenstein /2']" ) ;
1457+ let page = kuchiki:: parse_html ( ) . one ( web. get ( "/releases/@foobar " ) . send ( ) ?. text ( ) ?) ;
1458+ let button = page. select_first ( "a[href='/releases/@foobar /2']" ) ;
14721459
14731460 assert ! ( button. is_ok( ) ) ;
14741461
@@ -1482,7 +1469,12 @@ mod tests {
14821469 let web = env. frontend ( ) ;
14831470 env. fake_release ( )
14841471 . name ( "some_random_crate" )
1485- . author ( "frankenstein <frankie@stein.com>" )
1472+ . add_owner ( CrateOwner {
1473+ login : "foobar" . into ( ) ,
1474+ avatar : "https://example.org/foobar" . into ( ) ,
1475+ name : "Foo Bar" . into ( ) ,
1476+ email : "foobar@example.org" . into ( ) ,
1477+ } )
14861478 . create ( ) ?;
14871479
14881480 let mut urls = vec ! [ ] ;
0 commit comments