1use urlencoding::encode;
20
21pub enum Endpoint<'a> {
23 PlayerState,
24 PlayerCurrentlyPlaying,
25 PlayerPlay,
26 PlayerPause,
27 PlayerNext,
28 PlayerPrevious,
29 PlayerQueue,
30 PlayerQueueAdd {
31 uri: &'a str,
32 },
33 PlayerDevices,
34 PlayerRecentlyPlayed,
35 PlayerSeek {
36 position_ms: u64,
37 },
38 PlayerVolume {
39 volume_percent: u8,
40 },
41 PlayerShuffle {
42 state: bool,
43 },
44 PlayerRepeat {
45 state: &'a str,
46 },
47
48 Playlist {
49 id: &'a str,
50 },
51 PlaylistTracks {
52 id: &'a str,
53 },
54 PlaylistItems {
55 id: &'a str,
56 limit: u8,
57 offset: u32,
58 },
59 PlaylistFollowers {
60 id: &'a str,
61 },
62 PlaylistCoverImage {
63 id: &'a str,
64 },
65 CurrentUserPlaylists {
66 limit: u8,
67 offset: u32,
68 },
69 UserPlaylists {
70 user_id: &'a str,
71 },
72 CategoryPlaylists {
73 category_id: &'a str,
74 limit: u8,
75 offset: u32,
76 },
77
78 SavedTracks {
79 limit: u8,
80 offset: u32,
81 },
82 SavedTracksIds {
83 ids: &'a str,
84 },
85 SavedTracksContains {
86 ids: &'a str,
87 },
88
89 SavedAlbums {
90 limit: u8,
91 offset: u32,
92 },
93 SavedAlbumsIds {
94 ids: &'a str,
95 },
96 SavedAlbumsContains {
97 ids: &'a str,
98 },
99
100 Track {
101 id: &'a str,
102 },
103 Tracks {
104 ids: &'a str,
105 },
106
107 Album {
108 id: &'a str,
109 },
110 Albums {
111 ids: &'a str,
112 },
113 AlbumTracks {
114 id: &'a str,
115 limit: u8,
116 offset: u32,
117 },
118 NewReleases {
119 limit: u8,
120 offset: u32,
121 },
122
123 Artist {
124 id: &'a str,
125 },
126 Artists {
127 ids: &'a str,
128 },
129 ArtistTopTracks {
130 id: &'a str,
131 market: &'a str,
132 },
133 ArtistAlbums {
134 id: &'a str,
135 limit: u8,
136 offset: u32,
137 },
138 ArtistRelatedArtists {
139 id: &'a str,
140 },
141
142 CurrentUser,
143 UserProfile {
144 user_id: &'a str,
145 },
146 UserTopItems {
147 item_type: &'a str,
148 time_range: &'a str,
149 limit: u8,
150 offset: u32,
151 },
152 FollowedArtists {
153 limit: u8,
154 },
155 FollowArtistsOrUsers {
156 entity_type: &'a str,
157 ids: &'a str,
158 },
159 FollowingContains {
160 entity_type: &'a str,
161 ids: &'a str,
162 },
163 FollowPlaylist {
164 playlist_id: &'a str,
165 },
166 FollowPlaylistContains {
167 playlist_id: &'a str,
168 ids: &'a str,
169 },
170
171 Category {
172 id: &'a str,
173 },
174 Categories {
175 limit: u8,
176 offset: u32,
177 },
178
179 Markets,
180
181 Search {
182 query: &'a str,
183 types: &'a str,
184 limit: u8,
185 market: Option<&'a str>,
186 },
187
188 Show {
189 id: &'a str,
190 },
191 Shows {
192 ids: &'a str,
193 },
194 ShowEpisodes {
195 id: &'a str,
196 limit: u8,
197 offset: u32,
198 },
199 SavedShows {
200 limit: u8,
201 offset: u32,
202 },
203 SavedShowsIds {
204 ids: &'a str,
205 },
206 SavedShowsContains {
207 ids: &'a str,
208 },
209
210 Episode {
211 id: &'a str,
212 },
213 Episodes {
214 ids: &'a str,
215 },
216 SavedEpisodes {
217 limit: u8,
218 offset: u32,
219 },
220 SavedEpisodesIds {
221 ids: &'a str,
222 },
223 SavedEpisodesContains {
224 ids: &'a str,
225 },
226
227 Audiobook {
228 id: &'a str,
229 },
230 Audiobooks {
231 ids: &'a str,
232 },
233 AudiobookChapters {
234 id: &'a str,
235 limit: u8,
236 offset: u32,
237 },
238 SavedAudiobooks {
239 limit: u8,
240 offset: u32,
241 },
242 SavedAudiobooksIds {
243 ids: &'a str,
244 },
245 SavedAudiobooksContains {
246 ids: &'a str,
247 },
248
249 Chapter {
250 id: &'a str,
251 },
252 Chapters {
253 ids: &'a str,
254 },
255}
256
257impl<'a> Endpoint<'a> {
258 pub fn path(&self) -> String {
260 match self {
261 Endpoint::PlayerState => "/me/player".to_string(),
262 Endpoint::PlayerCurrentlyPlaying => "/me/player/currently-playing".to_string(),
263 Endpoint::PlayerPlay => "/me/player/play".to_string(),
264 Endpoint::PlayerPause => "/me/player/pause".to_string(),
265 Endpoint::PlayerNext => "/me/player/next".to_string(),
266 Endpoint::PlayerPrevious => "/me/player/previous".to_string(),
267 Endpoint::PlayerQueue => "/me/player/queue".to_string(),
268 Endpoint::PlayerQueueAdd { uri } => format!("/me/player/queue?uri={}", encode(uri)),
269 Endpoint::PlayerDevices => "/me/player/devices".to_string(),
270 Endpoint::PlayerRecentlyPlayed => "/me/player/recently-played".to_string(),
271 Endpoint::PlayerSeek { position_ms } => {
272 format!("/me/player/seek?position_ms={}", position_ms)
273 }
274 Endpoint::PlayerVolume { volume_percent } => {
275 format!("/me/player/volume?volume_percent={}", volume_percent)
276 }
277 Endpoint::PlayerShuffle { state } => format!("/me/player/shuffle?state={}", state),
278 Endpoint::PlayerRepeat { state } => format!("/me/player/repeat?state={}", state),
279
280 Endpoint::Playlist { id } => format!("/playlists/{}", id),
281 Endpoint::PlaylistTracks { id } => format!("/playlists/{}/tracks", id),
282 Endpoint::PlaylistItems { id, limit, offset } => {
283 format!("/playlists/{}/tracks?limit={}&offset={}", id, limit, offset)
284 }
285 Endpoint::PlaylistFollowers { id } => format!("/playlists/{}/followers", id),
286 Endpoint::PlaylistCoverImage { id } => format!("/playlists/{}/images", id),
287 Endpoint::CurrentUserPlaylists { limit, offset } => {
288 format!("/me/playlists?limit={}&offset={}", limit, offset)
289 }
290 Endpoint::UserPlaylists { user_id } => format!("/users/{}/playlists", user_id),
291 Endpoint::CategoryPlaylists {
292 category_id,
293 limit,
294 offset,
295 } => {
296 format!(
297 "/browse/categories/{}/playlists?limit={}&offset={}",
298 category_id, limit, offset
299 )
300 }
301
302 Endpoint::SavedTracks { limit, offset } => {
303 format!("/me/tracks?limit={}&offset={}", limit, offset)
304 }
305 Endpoint::SavedTracksIds { ids } => format!("/me/tracks?ids={}", ids),
306 Endpoint::SavedTracksContains { ids } => format!("/me/tracks/contains?ids={}", ids),
307
308 Endpoint::SavedAlbums { limit, offset } => {
309 format!("/me/albums?limit={}&offset={}", limit, offset)
310 }
311 Endpoint::SavedAlbumsIds { ids } => format!("/me/albums?ids={}", ids),
312 Endpoint::SavedAlbumsContains { ids } => format!("/me/albums/contains?ids={}", ids),
313
314 Endpoint::Track { id } => format!("/tracks/{}", id),
315 Endpoint::Tracks { ids } => format!("/tracks?ids={}", ids),
316
317 Endpoint::Album { id } => format!("/albums/{}", id),
318 Endpoint::Albums { ids } => format!("/albums?ids={}", ids),
319 Endpoint::AlbumTracks { id, limit, offset } => {
320 format!("/albums/{}/tracks?limit={}&offset={}", id, limit, offset)
321 }
322 Endpoint::NewReleases { limit, offset } => {
323 format!("/browse/new-releases?limit={}&offset={}", limit, offset)
324 }
325
326 Endpoint::Artist { id } => format!("/artists/{}", id),
327 Endpoint::Artists { ids } => format!("/artists?ids={}", ids),
328 Endpoint::ArtistTopTracks { id, market } => {
329 format!("/artists/{}/top-tracks?market={}", id, market)
330 }
331 Endpoint::ArtistAlbums { id, limit, offset } => {
332 format!("/artists/{}/albums?limit={}&offset={}", id, limit, offset)
333 }
334 Endpoint::ArtistRelatedArtists { id } => format!("/artists/{}/related-artists", id),
335
336 Endpoint::CurrentUser => "/me".to_string(),
337 Endpoint::UserProfile { user_id } => format!("/users/{}", user_id),
338 Endpoint::UserTopItems {
339 item_type,
340 time_range,
341 limit,
342 offset,
343 } => {
344 format!(
345 "/me/top/{}?time_range={}&limit={}&offset={}",
346 item_type, time_range, limit, offset
347 )
348 }
349 Endpoint::FollowedArtists { limit } => {
350 format!("/me/following?type=artist&limit={}", limit)
351 }
352 Endpoint::FollowArtistsOrUsers { entity_type, ids } => {
353 format!("/me/following?type={}&ids={}", entity_type, ids)
354 }
355 Endpoint::FollowingContains { entity_type, ids } => {
356 format!("/me/following/contains?type={}&ids={}", entity_type, ids)
357 }
358 Endpoint::FollowPlaylist { playlist_id } => {
359 format!("/playlists/{}/followers", playlist_id)
360 }
361 Endpoint::FollowPlaylistContains { playlist_id, ids } => {
362 format!("/playlists/{}/followers/contains?ids={}", playlist_id, ids)
363 }
364
365 Endpoint::Category { id } => format!("/browse/categories/{}", id),
366 Endpoint::Categories { limit, offset } => {
367 format!("/browse/categories?limit={}&offset={}", limit, offset)
368 }
369
370 Endpoint::Markets => "/markets".to_string(),
371
372 Endpoint::Search {
373 query,
374 types,
375 limit,
376 market,
377 } => {
378 let base = format!("/search?q={}&type={}&limit={}", encode(query), types, limit);
379 match market {
380 Some(m) => format!("{}&market={}", base, m),
381 None => base,
382 }
383 }
384
385 Endpoint::Show { id } => format!("/shows/{}", id),
386 Endpoint::Shows { ids } => format!("/shows?ids={}", ids),
387 Endpoint::ShowEpisodes { id, limit, offset } => {
388 format!("/shows/{}/episodes?limit={}&offset={}", id, limit, offset)
389 }
390 Endpoint::SavedShows { limit, offset } => {
391 format!("/me/shows?limit={}&offset={}", limit, offset)
392 }
393 Endpoint::SavedShowsIds { ids } => format!("/me/shows?ids={}", ids),
394 Endpoint::SavedShowsContains { ids } => format!("/me/shows/contains?ids={}", ids),
395
396 Endpoint::Episode { id } => format!("/episodes/{}", id),
397 Endpoint::Episodes { ids } => format!("/episodes?ids={}", ids),
398 Endpoint::SavedEpisodes { limit, offset } => {
399 format!("/me/episodes?limit={}&offset={}", limit, offset)
400 }
401 Endpoint::SavedEpisodesIds { ids } => format!("/me/episodes?ids={}", ids),
402 Endpoint::SavedEpisodesContains { ids } => format!("/me/episodes/contains?ids={}", ids),
403
404 Endpoint::Audiobook { id } => format!("/audiobooks/{}", id),
405 Endpoint::Audiobooks { ids } => format!("/audiobooks?ids={}", ids),
406 Endpoint::AudiobookChapters { id, limit, offset } => {
407 format!(
408 "/audiobooks/{}/chapters?limit={}&offset={}",
409 id, limit, offset
410 )
411 }
412 Endpoint::SavedAudiobooks { limit, offset } => {
413 format!("/me/audiobooks?limit={}&offset={}", limit, offset)
414 }
415 Endpoint::SavedAudiobooksIds { ids } => format!("/me/audiobooks?ids={}", ids),
416 Endpoint::SavedAudiobooksContains { ids } => {
417 format!("/me/audiobooks/contains?ids={}", ids)
418 }
419
420 Endpoint::Chapter { id } => format!("/chapters/{}", id),
421 Endpoint::Chapters { ids } => format!("/chapters?ids={}", ids),
422 }
423 }
424}
425
426#[cfg(test)]
427mod tests {
428 use super::*;
429
430 #[test]
431 fn player_endpoints() {
432 assert_eq!(Endpoint::PlayerState.path(), "/me/player");
433 assert_eq!(
434 Endpoint::PlayerCurrentlyPlaying.path(),
435 "/me/player/currently-playing"
436 );
437 assert_eq!(Endpoint::PlayerPlay.path(), "/me/player/play");
438 assert_eq!(Endpoint::PlayerPause.path(), "/me/player/pause");
439 assert_eq!(Endpoint::PlayerNext.path(), "/me/player/next");
440 assert_eq!(Endpoint::PlayerPrevious.path(), "/me/player/previous");
441 assert_eq!(Endpoint::PlayerQueue.path(), "/me/player/queue");
442 assert_eq!(Endpoint::PlayerDevices.path(), "/me/player/devices");
443 assert_eq!(
444 Endpoint::PlayerRecentlyPlayed.path(),
445 "/me/player/recently-played"
446 );
447 }
448
449 #[test]
450 fn player_endpoints_with_params() {
451 assert_eq!(
452 Endpoint::PlayerSeek { position_ms: 30000 }.path(),
453 "/me/player/seek?position_ms=30000"
454 );
455 assert_eq!(
456 Endpoint::PlayerVolume { volume_percent: 50 }.path(),
457 "/me/player/volume?volume_percent=50"
458 );
459 assert_eq!(
460 Endpoint::PlayerShuffle { state: true }.path(),
461 "/me/player/shuffle?state=true"
462 );
463 assert_eq!(
464 Endpoint::PlayerRepeat { state: "track" }.path(),
465 "/me/player/repeat?state=track"
466 );
467 }
468
469 #[test]
470 fn queue_add_encodes_uri() {
471 let uri = "spotify:track:abc123";
472 let path = Endpoint::PlayerQueueAdd { uri }.path();
473 assert!(path.starts_with("/me/player/queue?uri="));
474 assert!(path.contains("spotify"));
475 }
476
477 #[test]
478 fn playlist_endpoints() {
479 assert_eq!(
480 Endpoint::Playlist { id: "abc123" }.path(),
481 "/playlists/abc123"
482 );
483 assert_eq!(
484 Endpoint::PlaylistTracks { id: "abc123" }.path(),
485 "/playlists/abc123/tracks"
486 );
487 assert_eq!(
488 Endpoint::PlaylistItems {
489 id: "abc123",
490 limit: 50,
491 offset: 0
492 }
493 .path(),
494 "/playlists/abc123/tracks?limit=50&offset=0"
495 );
496 assert_eq!(
497 Endpoint::PlaylistFollowers { id: "abc123" }.path(),
498 "/playlists/abc123/followers"
499 );
500 }
501
502 #[test]
503 fn user_playlist_endpoints() {
504 assert_eq!(
505 Endpoint::CurrentUserPlaylists {
506 limit: 20,
507 offset: 40
508 }
509 .path(),
510 "/me/playlists?limit=20&offset=40"
511 );
512 assert_eq!(
513 Endpoint::UserPlaylists { user_id: "user123" }.path(),
514 "/users/user123/playlists"
515 );
516 }
517
518 #[test]
519 fn browse_endpoints() {
520 assert_eq!(
521 Endpoint::CategoryPlaylists {
522 category_id: "pop",
523 limit: 20,
524 offset: 0
525 }
526 .path(),
527 "/browse/categories/pop/playlists?limit=20&offset=0"
528 );
529 assert_eq!(
530 Endpoint::NewReleases {
531 limit: 20,
532 offset: 0
533 }
534 .path(),
535 "/browse/new-releases?limit=20&offset=0"
536 );
537 assert_eq!(
538 Endpoint::Category { id: "rock" }.path(),
539 "/browse/categories/rock"
540 );
541 assert_eq!(
542 Endpoint::Categories {
543 limit: 50,
544 offset: 0
545 }
546 .path(),
547 "/browse/categories?limit=50&offset=0"
548 );
549 }
550
551 #[test]
552 fn saved_tracks_endpoints() {
553 assert_eq!(
554 Endpoint::SavedTracks {
555 limit: 20,
556 offset: 0
557 }
558 .path(),
559 "/me/tracks?limit=20&offset=0"
560 );
561 assert_eq!(
562 Endpoint::SavedTracksIds { ids: "id1,id2" }.path(),
563 "/me/tracks?ids=id1,id2"
564 );
565 assert_eq!(
566 Endpoint::SavedTracksContains { ids: "id1" }.path(),
567 "/me/tracks/contains?ids=id1"
568 );
569 }
570
571 #[test]
572 fn saved_albums_endpoints() {
573 assert_eq!(
574 Endpoint::SavedAlbums {
575 limit: 20,
576 offset: 0
577 }
578 .path(),
579 "/me/albums?limit=20&offset=0"
580 );
581 assert_eq!(
582 Endpoint::SavedAlbumsIds { ids: "id1,id2" }.path(),
583 "/me/albums?ids=id1,id2"
584 );
585 assert_eq!(
586 Endpoint::SavedAlbumsContains { ids: "id1" }.path(),
587 "/me/albums/contains?ids=id1"
588 );
589 }
590
591 #[test]
592 fn track_endpoints() {
593 assert_eq!(
594 Endpoint::Track { id: "track123" }.path(),
595 "/tracks/track123"
596 );
597 assert_eq!(
598 Endpoint::Tracks { ids: "t1,t2,t3" }.path(),
599 "/tracks?ids=t1,t2,t3"
600 );
601 }
602
603 #[test]
604 fn album_endpoints() {
605 assert_eq!(
606 Endpoint::Album { id: "album123" }.path(),
607 "/albums/album123"
608 );
609 assert_eq!(
610 Endpoint::Albums { ids: "a1,a2" }.path(),
611 "/albums?ids=a1,a2"
612 );
613 assert_eq!(
614 Endpoint::AlbumTracks {
615 id: "album123",
616 limit: 50,
617 offset: 0
618 }
619 .path(),
620 "/albums/album123/tracks?limit=50&offset=0"
621 );
622 }
623
624 #[test]
625 fn artist_endpoints() {
626 assert_eq!(
627 Endpoint::Artist { id: "artist123" }.path(),
628 "/artists/artist123"
629 );
630 assert_eq!(
631 Endpoint::Artists { ids: "a1,a2" }.path(),
632 "/artists?ids=a1,a2"
633 );
634 assert_eq!(
635 Endpoint::ArtistTopTracks {
636 id: "artist123",
637 market: "US"
638 }
639 .path(),
640 "/artists/artist123/top-tracks?market=US"
641 );
642 assert_eq!(
643 Endpoint::ArtistAlbums {
644 id: "artist123",
645 limit: 20,
646 offset: 0
647 }
648 .path(),
649 "/artists/artist123/albums?limit=20&offset=0"
650 );
651 assert_eq!(
652 Endpoint::ArtistRelatedArtists { id: "artist123" }.path(),
653 "/artists/artist123/related-artists"
654 );
655 }
656
657 #[test]
658 fn user_endpoints() {
659 assert_eq!(Endpoint::CurrentUser.path(), "/me");
660 assert_eq!(
661 Endpoint::UserProfile { user_id: "user123" }.path(),
662 "/users/user123"
663 );
664 assert_eq!(
665 Endpoint::UserTopItems {
666 item_type: "tracks",
667 time_range: "medium_term",
668 limit: 20,
669 offset: 0
670 }
671 .path(),
672 "/me/top/tracks?time_range=medium_term&limit=20&offset=0"
673 );
674 }
675
676 #[test]
677 fn follow_endpoints() {
678 assert_eq!(
679 Endpoint::FollowedArtists { limit: 20 }.path(),
680 "/me/following?type=artist&limit=20"
681 );
682 assert_eq!(
683 Endpoint::FollowArtistsOrUsers {
684 entity_type: "artist",
685 ids: "id1,id2"
686 }
687 .path(),
688 "/me/following?type=artist&ids=id1,id2"
689 );
690 assert_eq!(
691 Endpoint::FollowingContains {
692 entity_type: "artist",
693 ids: "id1"
694 }
695 .path(),
696 "/me/following/contains?type=artist&ids=id1"
697 );
698 assert_eq!(
699 Endpoint::FollowPlaylist {
700 playlist_id: "pl123"
701 }
702 .path(),
703 "/playlists/pl123/followers"
704 );
705 assert_eq!(
706 Endpoint::FollowPlaylistContains {
707 playlist_id: "pl123",
708 ids: "user1"
709 }
710 .path(),
711 "/playlists/pl123/followers/contains?ids=user1"
712 );
713 }
714
715 #[test]
716 fn markets_endpoint() {
717 assert_eq!(Endpoint::Markets.path(), "/markets");
718 }
719
720 #[test]
721 fn search_encodes_query() {
722 let path = Endpoint::Search {
723 query: "hello world",
724 types: "track",
725 limit: 20,
726 market: None,
727 }
728 .path();
729 assert!(path.contains("hello%20world") || path.contains("hello+world"));
730 assert!(path.contains("type=track"));
731 assert!(path.contains("limit=20"));
732 }
733
734 #[test]
735 fn search_includes_market() {
736 let path = Endpoint::Search {
737 query: "test",
738 types: "track",
739 limit: 20,
740 market: Some("US"),
741 }
742 .path();
743 assert!(path.contains("market=US"));
744 }
745
746 #[test]
747 fn show_endpoints() {
748 assert_eq!(Endpoint::Show { id: "show123" }.path(), "/shows/show123");
749 assert_eq!(Endpoint::Shows { ids: "s1,s2" }.path(), "/shows?ids=s1,s2");
750 assert_eq!(
751 Endpoint::ShowEpisodes {
752 id: "show123",
753 limit: 20,
754 offset: 0
755 }
756 .path(),
757 "/shows/show123/episodes?limit=20&offset=0"
758 );
759 assert_eq!(
760 Endpoint::SavedShows {
761 limit: 20,
762 offset: 0
763 }
764 .path(),
765 "/me/shows?limit=20&offset=0"
766 );
767 }
768
769 #[test]
770 fn episode_endpoints() {
771 assert_eq!(Endpoint::Episode { id: "ep123" }.path(), "/episodes/ep123");
772 assert_eq!(
773 Endpoint::Episodes { ids: "e1,e2" }.path(),
774 "/episodes?ids=e1,e2"
775 );
776 assert_eq!(
777 Endpoint::SavedEpisodes {
778 limit: 20,
779 offset: 0
780 }
781 .path(),
782 "/me/episodes?limit=20&offset=0"
783 );
784 }
785
786 #[test]
787 fn audiobook_endpoints() {
788 assert_eq!(
789 Endpoint::Audiobook { id: "ab123" }.path(),
790 "/audiobooks/ab123"
791 );
792 assert_eq!(
793 Endpoint::Audiobooks { ids: "ab1,ab2" }.path(),
794 "/audiobooks?ids=ab1,ab2"
795 );
796 assert_eq!(
797 Endpoint::AudiobookChapters {
798 id: "ab123",
799 limit: 50,
800 offset: 0
801 }
802 .path(),
803 "/audiobooks/ab123/chapters?limit=50&offset=0"
804 );
805 assert_eq!(
806 Endpoint::SavedAudiobooks {
807 limit: 20,
808 offset: 0
809 }
810 .path(),
811 "/me/audiobooks?limit=20&offset=0"
812 );
813 }
814
815 #[test]
816 fn chapter_endpoints() {
817 assert_eq!(Endpoint::Chapter { id: "ch123" }.path(), "/chapters/ch123");
818 assert_eq!(
819 Endpoint::Chapters { ids: "c1,c2" }.path(),
820 "/chapters?ids=c1,c2"
821 );
822 }
823
824 #[test]
825 fn saved_shows_ids_endpoint() {
826 assert_eq!(
827 Endpoint::SavedShowsIds { ids: "show1,show2" }.path(),
828 "/me/shows?ids=show1,show2"
829 );
830 }
831
832 #[test]
833 fn saved_shows_contains_endpoint() {
834 assert_eq!(
835 Endpoint::SavedShowsContains { ids: "show1" }.path(),
836 "/me/shows/contains?ids=show1"
837 );
838 }
839
840 #[test]
841 fn saved_episodes_ids_endpoint() {
842 assert_eq!(
843 Endpoint::SavedEpisodesIds { ids: "ep1,ep2" }.path(),
844 "/me/episodes?ids=ep1,ep2"
845 );
846 }
847
848 #[test]
849 fn saved_episodes_contains_endpoint() {
850 assert_eq!(
851 Endpoint::SavedEpisodesContains { ids: "ep1" }.path(),
852 "/me/episodes/contains?ids=ep1"
853 );
854 }
855
856 #[test]
857 fn saved_audiobooks_ids_endpoint() {
858 assert_eq!(
859 Endpoint::SavedAudiobooksIds { ids: "ab1,ab2" }.path(),
860 "/me/audiobooks?ids=ab1,ab2"
861 );
862 }
863
864 #[test]
865 fn saved_audiobooks_contains_endpoint() {
866 assert_eq!(
867 Endpoint::SavedAudiobooksContains { ids: "ab1" }.path(),
868 "/me/audiobooks/contains?ids=ab1"
869 );
870 }
871
872 #[test]
873 fn playlist_cover_image_endpoint() {
874 assert_eq!(
875 Endpoint::PlaylistCoverImage { id: "pl123" }.path(),
876 "/playlists/pl123/images"
877 );
878 }
879}