@@ -4,6 +4,23 @@ use anyhow::Result;
44use serde:: { Deserialize , Serialize } ;
55
66use super :: BacklogClient ;
7+ use crate :: api:: user:: Star ;
8+
9+ #[ derive( Debug , Clone , Serialize , Deserialize ) ]
10+ pub struct WikiCount {
11+ pub count : u64 ,
12+ }
13+
14+ #[ derive( Debug , Clone , Serialize , Deserialize ) ]
15+ #[ serde( rename_all = "camelCase" ) ]
16+ pub struct WikiSharedFile {
17+ pub id : u64 ,
18+ pub dir : String ,
19+ pub name : String ,
20+ pub size : u64 ,
21+ #[ serde( flatten) ]
22+ pub extra : BTreeMap < String , serde_json:: Value > ,
23+ }
724
825#[ derive( Debug , Clone , Serialize , Deserialize ) ]
926#[ serde( rename_all = "camelCase" ) ]
@@ -116,6 +133,82 @@ impl BacklogClient {
116133 let value = self . get ( & format ! ( "/wikis/{}/attachments" , wiki_id) ) ?;
117134 deserialize ( value)
118135 }
136+
137+ pub fn get_wiki_count ( & self , params : & [ ( String , String ) ] ) -> Result < WikiCount > {
138+ let value = self . get_with_query ( "/wikis/count" , params) ?;
139+ deserialize ( value)
140+ }
141+
142+ pub fn get_wiki_tags ( & self , params : & [ ( String , String ) ] ) -> Result < Vec < WikiTag > > {
143+ let value = self . get_with_query ( "/wikis/tags" , params) ?;
144+ deserialize ( value)
145+ }
146+
147+ pub fn get_wiki_stars ( & self , wiki_id : u64 ) -> Result < Vec < Star > > {
148+ let value = self . get ( & format ! ( "/wikis/{}/stars" , wiki_id) ) ?;
149+ deserialize ( value)
150+ }
151+
152+ pub fn add_wiki_attachments (
153+ & self ,
154+ wiki_id : u64 ,
155+ attachment_ids : & [ u64 ] ,
156+ ) -> Result < Vec < WikiAttachment > > {
157+ let params: Vec < ( String , String ) > = attachment_ids
158+ . iter ( )
159+ . map ( |id| ( "attachmentId[]" . to_string ( ) , id. to_string ( ) ) )
160+ . collect ( ) ;
161+ let value = self . post_form ( & format ! ( "/wikis/{}/attachments" , wiki_id) , & params) ?;
162+ deserialize ( value)
163+ }
164+
165+ pub fn download_wiki_attachment (
166+ & self ,
167+ wiki_id : u64 ,
168+ attachment_id : u64 ,
169+ ) -> Result < ( Vec < u8 > , String ) > {
170+ self . download ( & format ! ( "/wikis/{}/attachments/{}" , wiki_id, attachment_id) )
171+ }
172+
173+ pub fn delete_wiki_attachment (
174+ & self ,
175+ wiki_id : u64 ,
176+ attachment_id : u64 ,
177+ ) -> Result < WikiAttachment > {
178+ let value =
179+ self . delete_req ( & format ! ( "/wikis/{}/attachments/{}" , wiki_id, attachment_id) ) ?;
180+ deserialize ( value)
181+ }
182+
183+ pub fn get_wiki_shared_files ( & self , wiki_id : u64 ) -> Result < Vec < WikiSharedFile > > {
184+ let value = self . get ( & format ! ( "/wikis/{}/sharedFiles" , wiki_id) ) ?;
185+ deserialize ( value)
186+ }
187+
188+ pub fn link_wiki_shared_files (
189+ & self ,
190+ wiki_id : u64 ,
191+ shared_file_ids : & [ u64 ] ,
192+ ) -> Result < Vec < WikiSharedFile > > {
193+ let params: Vec < ( String , String ) > = shared_file_ids
194+ . iter ( )
195+ . map ( |id| ( "fileId[]" . to_string ( ) , id. to_string ( ) ) )
196+ . collect ( ) ;
197+ let value = self . post_form ( & format ! ( "/wikis/{}/sharedFiles" , wiki_id) , & params) ?;
198+ deserialize ( value)
199+ }
200+
201+ pub fn unlink_wiki_shared_file (
202+ & self ,
203+ wiki_id : u64 ,
204+ shared_file_id : u64 ,
205+ ) -> Result < WikiSharedFile > {
206+ let value = self . delete_req ( & format ! (
207+ "/wikis/{}/sharedFiles/{}" ,
208+ wiki_id, shared_file_id
209+ ) ) ?;
210+ deserialize ( value)
211+ }
119212}
120213
121214#[ cfg( test) ]
@@ -286,4 +379,163 @@ mod tests {
286379 let wiki: Wiki = serde_json:: from_value ( v) . unwrap ( ) ;
287380 assert ! ( wiki. created_user. user_id. is_none( ) ) ;
288381 }
382+
383+ fn shared_file_json ( ) -> serde_json:: Value {
384+ json ! ( {
385+ "id" : 1 ,
386+ "dir" : "/docs" ,
387+ "name" : "spec.pdf" ,
388+ "size" : 2048_u64
389+ } )
390+ }
391+
392+ fn star_json ( ) -> serde_json:: Value {
393+ json ! ( {
394+ "id" : 1 ,
395+ "comment" : null,
396+ "url" : "https://example.backlog.com/wiki/TEST/Home" ,
397+ "title" : "Home" ,
398+ "presenter" : {
399+ "id" : 1 , "userId" : "john" , "name" : "John Doe" ,
400+ "roleType" : 1 , "mailAddress" : "john@example.com"
401+ } ,
402+ "created" : "2024-01-01T00:00:00Z"
403+ } )
404+ }
405+
406+ #[ test]
407+ fn get_wiki_count_returns_count ( ) {
408+ let server = MockServer :: start ( ) ;
409+ server. mock ( |when, then| {
410+ when. method ( GET )
411+ . path ( "/wikis/count" )
412+ . query_param ( "apiKey" , TEST_KEY )
413+ . query_param ( "projectIdOrKey" , "TEST" ) ;
414+ then. status ( 200 ) . json_body ( json ! ( { "count" : 42 } ) ) ;
415+ } ) ;
416+ let client = super :: super :: BacklogClient :: new_with ( & server. base_url ( ) , TEST_KEY ) . unwrap ( ) ;
417+ let result = client
418+ . get_wiki_count ( & [ ( "projectIdOrKey" . to_string ( ) , "TEST" . to_string ( ) ) ] )
419+ . unwrap ( ) ;
420+ assert_eq ! ( result. count, 42 ) ;
421+ }
422+
423+ #[ test]
424+ fn get_wiki_tags_returns_list ( ) {
425+ let server = MockServer :: start ( ) ;
426+ server. mock ( |when, then| {
427+ when. method ( GET )
428+ . path ( "/wikis/tags" )
429+ . query_param ( "apiKey" , TEST_KEY ) ;
430+ then. status ( 200 )
431+ . json_body ( json ! ( [ { "id" : 1 , "name" : "guide" } ] ) ) ;
432+ } ) ;
433+ let client = super :: super :: BacklogClient :: new_with ( & server. base_url ( ) , TEST_KEY ) . unwrap ( ) ;
434+ let tags = client. get_wiki_tags ( & [ ] ) . unwrap ( ) ;
435+ assert_eq ! ( tags. len( ) , 1 ) ;
436+ assert_eq ! ( tags[ 0 ] . name, "guide" ) ;
437+ }
438+
439+ #[ test]
440+ fn get_wiki_stars_returns_list ( ) {
441+ let server = MockServer :: start ( ) ;
442+ server. mock ( |when, then| {
443+ when. method ( GET )
444+ . path ( "/wikis/1/stars" )
445+ . query_param ( "apiKey" , TEST_KEY ) ;
446+ then. status ( 200 ) . json_body ( json ! ( [ star_json( ) ] ) ) ;
447+ } ) ;
448+ let client = super :: super :: BacklogClient :: new_with ( & server. base_url ( ) , TEST_KEY ) . unwrap ( ) ;
449+ let stars = client. get_wiki_stars ( 1 ) . unwrap ( ) ;
450+ assert_eq ! ( stars. len( ) , 1 ) ;
451+ assert_eq ! ( stars[ 0 ] . title, "Home" ) ;
452+ }
453+
454+ #[ test]
455+ fn add_wiki_attachments_returns_list ( ) {
456+ let server = MockServer :: start ( ) ;
457+ server. mock ( |when, then| {
458+ when. method ( POST )
459+ . path ( "/wikis/1/attachments" )
460+ . query_param ( "apiKey" , TEST_KEY ) ;
461+ then. status ( 200 ) . json_body ( json ! ( [ attachment_json( ) ] ) ) ;
462+ } ) ;
463+ let client = super :: super :: BacklogClient :: new_with ( & server. base_url ( ) , TEST_KEY ) . unwrap ( ) ;
464+ let attachments = client. add_wiki_attachments ( 1 , & [ 1 ] ) . unwrap ( ) ;
465+ assert_eq ! ( attachments. len( ) , 1 ) ;
466+ assert_eq ! ( attachments[ 0 ] . name, "image.png" ) ;
467+ }
468+
469+ #[ test]
470+ fn download_wiki_attachment_returns_bytes ( ) {
471+ let server = MockServer :: start ( ) ;
472+ server. mock ( |when, then| {
473+ when. method ( GET ) . path ( "/wikis/1/attachments/1" ) ;
474+ then. status ( 200 )
475+ . header ( "Content-Disposition" , "attachment; filename=\" image.png\" " )
476+ . body ( b"hello" ) ;
477+ } ) ;
478+ let client = super :: super :: BacklogClient :: new_with ( & server. base_url ( ) , TEST_KEY ) . unwrap ( ) ;
479+ let ( bytes, filename) = client. download_wiki_attachment ( 1 , 1 ) . unwrap ( ) ;
480+ assert_eq ! ( bytes, b"hello" ) ;
481+ assert_eq ! ( filename, "image.png" ) ;
482+ }
483+
484+ #[ test]
485+ fn delete_wiki_attachment_returns_attachment ( ) {
486+ let server = MockServer :: start ( ) ;
487+ server. mock ( |when, then| {
488+ when. method ( DELETE )
489+ . path ( "/wikis/1/attachments/1" )
490+ . query_param ( "apiKey" , TEST_KEY ) ;
491+ then. status ( 200 ) . json_body ( attachment_json ( ) ) ;
492+ } ) ;
493+ let client = super :: super :: BacklogClient :: new_with ( & server. base_url ( ) , TEST_KEY ) . unwrap ( ) ;
494+ let attachment = client. delete_wiki_attachment ( 1 , 1 ) . unwrap ( ) ;
495+ assert_eq ! ( attachment. name, "image.png" ) ;
496+ }
497+
498+ #[ test]
499+ fn get_wiki_shared_files_returns_list ( ) {
500+ let server = MockServer :: start ( ) ;
501+ server. mock ( |when, then| {
502+ when. method ( GET )
503+ . path ( "/wikis/1/sharedFiles" )
504+ . query_param ( "apiKey" , TEST_KEY ) ;
505+ then. status ( 200 ) . json_body ( json ! ( [ shared_file_json( ) ] ) ) ;
506+ } ) ;
507+ let client = super :: super :: BacklogClient :: new_with ( & server. base_url ( ) , TEST_KEY ) . unwrap ( ) ;
508+ let files = client. get_wiki_shared_files ( 1 ) . unwrap ( ) ;
509+ assert_eq ! ( files. len( ) , 1 ) ;
510+ assert_eq ! ( files[ 0 ] . name, "spec.pdf" ) ;
511+ }
512+
513+ #[ test]
514+ fn link_wiki_shared_files_returns_list ( ) {
515+ let server = MockServer :: start ( ) ;
516+ server. mock ( |when, then| {
517+ when. method ( POST )
518+ . path ( "/wikis/1/sharedFiles" )
519+ . query_param ( "apiKey" , TEST_KEY ) ;
520+ then. status ( 200 ) . json_body ( json ! ( [ shared_file_json( ) ] ) ) ;
521+ } ) ;
522+ let client = super :: super :: BacklogClient :: new_with ( & server. base_url ( ) , TEST_KEY ) . unwrap ( ) ;
523+ let files = client. link_wiki_shared_files ( 1 , & [ 1 ] ) . unwrap ( ) ;
524+ assert_eq ! ( files. len( ) , 1 ) ;
525+ assert_eq ! ( files[ 0 ] . name, "spec.pdf" ) ;
526+ }
527+
528+ #[ test]
529+ fn unlink_wiki_shared_file_returns_file ( ) {
530+ let server = MockServer :: start ( ) ;
531+ server. mock ( |when, then| {
532+ when. method ( DELETE )
533+ . path ( "/wikis/1/sharedFiles/1" )
534+ . query_param ( "apiKey" , TEST_KEY ) ;
535+ then. status ( 200 ) . json_body ( shared_file_json ( ) ) ;
536+ } ) ;
537+ let client = super :: super :: BacklogClient :: new_with ( & server. base_url ( ) , TEST_KEY ) . unwrap ( ) ;
538+ let file = client. unlink_wiki_shared_file ( 1 , 1 ) . unwrap ( ) ;
539+ assert_eq ! ( file. name, "spec.pdf" ) ;
540+ }
289541}
0 commit comments