@@ -202,6 +202,57 @@ public function testPrivate()
202202 $ this ->assertFalse ($ this ->torrent ->isPrivate ());
203203 }
204204
205+ public function testGetMagnetLink ()
206+ {
207+ $ xtComponent = '' ;
208+ if ($ this ->protocol === TorrentFile::PROTOCOL_V1 ) {
209+ $ xtComponent = 'xt=urn:btih: ' . $ this ->infoHashs [TorrentFile::PROTOCOL_V1 ];
210+ }
211+
212+ if ($ this ->protocol === TorrentFile::PROTOCOL_V2 ) {
213+ $ xtComponent = 'xt=url:btmh:1220 ' . $ this ->infoHashs [TorrentFile::PROTOCOL_V2 ];
214+ }
215+
216+ if ($ this ->protocol === TorrentFile::PROTOCOL_HYBRID ) {
217+ $ xtComponent = 'xt=urn:btih: ' . $ this ->infoHashs [TorrentFile::PROTOCOL_V1 ] .
218+ '&xt=url:btmh:1220 ' . $ this ->infoHashs [TorrentFile::PROTOCOL_V2 ];
219+ }
220+
221+ $ name = $ this ->fileMode === TorrentFile::FILEMODE_MULTI ? 'tname ' : 'file1.dat ' ;
222+ $ dnComponent = 'dn= ' . rawurlencode ($ name );
223+
224+ $ trComponent = 'tr=https%3A%2F%2Fexample.com%2Fannounce&tr=https%3A%2F%2Fexample1.com%2Fannounce ' ;
225+
226+ $ this ->assertEquals ('magnet:? ' . implode ('& ' , [$ xtComponent , $ dnComponent , $ trComponent ]), $ this ->torrent ->getMagnetLink ());
227+ $ this ->assertEquals ('magnet:? ' . implode ('& ' , [$ xtComponent , $ dnComponent ]), $ this ->torrent ->getMagnetLink (true , false ));
228+ $ this ->assertEquals ('magnet:? ' . implode ('& ' , [$ xtComponent , $ trComponent ]), $ this ->torrent ->getMagnetLink (false , true ));
229+ $ this ->assertEquals ('magnet:? ' . $ xtComponent , $ this ->torrent ->getMagnetLink (false , false ));
230+
231+ // torrent without `announce` and `announce-list` should no `&tr=` component in uri.
232+ $ torrentWithoutAnnounce = clone $ this ->torrent ;
233+ $ torrentWithoutAnnounce ->unsetRootField ('announce ' )->unsetRootField ('announce-list ' );
234+ $ this ->assertEquals ('magnet:? ' . implode ('& ' , [$ xtComponent , $ dnComponent ]), $ torrentWithoutAnnounce ->getMagnetLink ());
235+
236+ /**
237+ * Torrent with Multitracker Metadata Extension (BEP0012)
238+ * Note:
239+ * 1. if the "announce-list" key is present, the client will ignore the "announce" key
240+ * and only use the URLs in "announce-list". ( From BEP )
241+ * So the "announce" field will not exist in magnet link if "announce-list" exists.
242+ * 2. dupe tracker will be ignored.
243+ */
244+ $ torrentWithEditAnnounce = clone $ this ->torrent ;
245+ $ torrentWithEditAnnounce
246+ ->setAnnounce ('https://127.0.0.1:8888/announce ' )
247+ ->setAnnounceList ([
248+ ['https://127.0.0.2:8890/announce ' ],
249+ ['https://127.0.0.3:8891/announce ' , 'https://127.0.0.4:8892/announce ' ],
250+ ['https://127.0.0.2:8890/announce ' ]
251+ ]);
252+ $ trComponent = 'tr=https%3A%2F%2F127.0.0.2%3A8890%2Fannounce&tr=https%3A%2F%2F127.0.0.3%3A8891%2Fannounce&tr=https%3A%2F%2F127.0.0.4%3A8892%2Fannounce ' ;
253+ $ this ->assertEquals ('magnet:? ' . implode ('& ' , [$ xtComponent , $ dnComponent , $ trComponent ]), $ torrentWithEditAnnounce ->getMagnetLink ());
254+ }
255+
205256 public function testGetSize ()
206257 {
207258 $ size = $ this ->fileMode === TorrentFile::FILEMODE_MULTI ? 33554432 /* 32MiB */ : 16777216 /* 16MiB */ ;
0 commit comments