1mod crypto;
4mod domain;
5mod endpoints;
6mod error;
7mod models;
8mod sdk;
9mod transport;
10
11pub use domain::Page;
12pub use endpoints::{Discovery, Library, Profile, SearchKind, SearchQuery};
13pub use error::{Error, Result};
14pub use models::{
15 AccountBody, Album, ApiResponse, Artist, Playlist, SearchBody, SearchResults, StreamUrl,
16 StreamUrlsBody, Track, TrackDetailsBody, TrackId, UserDetailsBody, UserId, UserPlaylistsBody,
17 UserProfile,
18};
19pub use sdk::{NcmClient, NcmClientBuilder};
20#[deprecated(note = "use NcmClient instead")]
21pub type NcmApi = NcmClient;
22pub(crate) type TResult<T> = Result<T>;
23
24#[cfg(test)]
25mod public_api_tests {
26 use std::sync::Arc;
27
28 use async_trait::async_trait;
29
30 use super::{NcmClient, SearchQuery};
31 use crate::{
32 Result,
33 transport::{RequestPlan, Response, Transport},
34 };
35
36 struct StubTransport;
37
38 #[async_trait]
39 impl Transport for StubTransport {
40 async fn execute(&self, _: RequestPlan) -> Result<Response> {
41 Ok(Response::new(
42 br#"{"code":200,"result":{"songs":[{"id":1,"name":"mota"}]}}"#.to_vec(),
43 ))
44 }
45 }
46
47 #[test]
48 fn ncm_client_is_the_primary_constructible_api() {
49 NcmClient::builder()
50 .cache(false)
51 .persist_cookies(false)
52 .build()
53 .expect("default client configuration is valid");
54 }
55
56 #[tokio::test(flavor = "multi_thread")]
57 async fn services_are_testable_without_a_remote_server() {
58 let client = NcmClient::with_transport(Arc::new(StubTransport));
59 let response = client
60 .discovery()
61 .search(SearchQuery::new("mota").unwrap())
62 .await
63 .expect("the stub transport returns a response");
64
65 assert_eq!(response.code, 200);
66 assert!(response.is_success());
67 assert_eq!(response.body.result.songs[0].name, "mota");
68 }
69}