11import  std/ net
2+ import  std/ strformat
23import  std/ sequtils
4+ import  std/ json except  `%`, `%*`
35import  pkg/ nimcrypto
4- from  pkg/ libp2p import  `==`, `$`, MultiHash , init
6+ from  pkg/ libp2p import  `==`, `$`, MultiHash , init, digest, hex 
57import  pkg/ codex/ units
68import  pkg/ codex/ utils/ iter
79import  pkg/ codex/ manifest
@@ -10,7 +12,6 @@ import pkg/codex/bittorrent/manifest
1012import  ./ twonodes
1113import  ../ examples
1214import  ../ codex/ examples
13- import  json
1415
1516proc  createInfoDictionaryForContent (
1617    content: seq [byte ], pieceLength =  DefaultPieceLength .int , name =  string .none
@@ -55,12 +56,93 @@ proc createInfoDictionaryForContent(
5556  success  info
5657
5758twonodessuite  " BitTorrent API"  :
59+   setup:
60+     #  why we do not seem to need this? yet it is twice as fast with this
61+     let  infoPeer1 =  (await  client1.info ()).tryGet
62+     let  peerId1 =  infoPeer1[" id"  ].getStr ()
63+     let  announceAddress1 =  infoPeer1[" announceAddresses"  ][0 ].getStr ()
64+     (await  client2.connect (peerId1, announceAddress1)).tryGet
65+ 
5866  test  " uploading and downloading the content"  , twoNodesConfig:
5967    let  exampleContent =  exampleString (100 )
6068    let  infoHash =  (await  client1.uploadTorrent (exampleContent)).tryGet
6169    let  downloadedContent =  (await  client2.downloadTorrent (infoHash)).tryGet
6270    check  downloadedContent ==  exampleContent
6371
72+   test  " downloading content using magnet link"  , twoNodesConfig:
73+     let  exampleContent =  exampleString (100 )
74+     let  multiHash =  (await  client1.uploadTorrent (exampleContent)).tryGet
75+     let  infoHash =  byteutils.toHex (multiHash.data.buffer[multiHash.dpos ..  ^ 1 ])
76+     let  magnetLink =  fmt" magnet:?xt=urn:btih:{ infoHash}  " 
77+     let  downloadedContent =  (await  client2.downloadTorrent (magnetLink)).tryGet
78+     check  downloadedContent ==  exampleContent
79+ 
80+   test  " downloading content using torrent file"  , twoNodesConfig:
81+     let  exampleFileName =  " example.txt" 
82+     let  exampleContent =  exampleString (100 )
83+     let  multiHash =  (
84+       await  client1.uploadTorrent (
85+         contents =  exampleContent,
86+         filename =  some  exampleFileName,
87+         contentType =  " text/plain"  ,
88+       )
89+     ).tryGet
90+ 
91+     let  expectedInfo =  createInfoDictionaryForContent (
92+       content =  exampleContent.toBytes, name =  some  exampleFileName
93+     ).tryGet
94+ 
95+     let  expectedInfoBencoded =  expectedInfo.bencode ()
96+     let  expectedMultiHash = 
97+       MultiHash .digest ($ Sha1HashCodec , expectedInfoBencoded).mapFailure.tryGet ()
98+ 
99+     assert  expectedMultiHash ==  multiHash
100+ 
101+     let  torrentFileContent =  " d4:info"   &  string .fromBytes (expectedInfoBencoded) &  " e" 
102+ 
103+     let  downloadedContent =  (
104+       await  client2.downloadTorrent (
105+         contents =  torrentFileContent,
106+         contentType =  " application/octet-stream"  ,
107+         endpoint =  " torrent-file"  ,
108+       )
109+     ).tryGet
110+     check  downloadedContent ==  exampleContent
111+ 
112+   test  " downloading content using torrent file (JSON format)"  , twoNodesConfig:
113+     let  exampleFileName =  " example.txt" 
114+     let  exampleContent =  exampleString (100 )
115+     let  multiHash =  (
116+       await  client1.uploadTorrent (
117+         contents =  exampleContent,
118+         filename =  some  exampleFileName,
119+         contentType =  " text/plain"  ,
120+       )
121+     ).tryGet
122+ 
123+     let  expectedInfo =  createInfoDictionaryForContent (
124+       content =  exampleContent.toBytes, name =  some  exampleFileName
125+     ).tryGet
126+ 
127+     let  expectedInfoBencoded =  expectedInfo.bencode ()
128+     let  expectedMultiHash = 
129+       MultiHash .digest ($ Sha1HashCodec , expectedInfoBencoded).mapFailure.tryGet ()
130+ 
131+     assert  expectedMultiHash ==  multiHash
132+ 
133+     let  infoJson =  %* {" info"  : % expectedInfo}
134+ 
135+     let  torrentJson =  $ infoJson
136+ 
137+     let  downloadedContent =  (
138+       await  client2.downloadTorrent (
139+         contents =  torrentJson,
140+         contentType =  " application/json"  ,
141+         endpoint =  " torrent-file"  ,
142+       )
143+     ).tryGet
144+     check  downloadedContent ==  exampleContent
145+ 
64146  test  " uploading and downloading the content (exactly one piece long)"  , twoNodesConfig:
65147    let  numOfBlocksPerPiece =  int  (DefaultPieceLength  div  BitTorrentBlockSize )
66148    let  bytes =  await  RandomChunker .example (
0 commit comments