1pub mod auth;
41pub mod config;
42pub mod error;
43pub mod library;
44pub mod openapi;
45pub mod sdk;
46
47pub use auth::{AuthSession, AuthState, AuthTokenResponse, SessionTransition};
48pub use config::Config;
49pub use error::{AuthSessionError, SdkError};
50pub use library::{
51 ClientError, FileChecksum, IncludedItem, LibraryClient, LibraryItemsParams,
52 OrderProductAttribute, OrderProductAttributes, OrderProductDescription, OrderProductFile,
53 OrderProductFilter, OrderProductHistoryEntry, OrderProductInfo, OrderProductItem,
54 OrderProductItemResponse, OrderProductListResponse, OrderProductOrder, OrderProductPublisher,
55 OrderProductRelationships, PageParams, PaginationLinks, PaginationMeta, ProductListAttributes,
56 ProductListCollectionResponse, ProductListItem, ProductListItemCreateRequest,
57 ProductListItemCreateResponse, ProductListItemsResponse, PublisherAttributes, PublisherItem,
58 RelationshipData, RelationshipRef,
59};
60pub use openapi::{OPERATIONS, OpenApiOperation};
61pub use sdk::DriveThruRpgSdk;
62
63#[cfg(test)]
64mod tests {
65 use super::{
66 AuthSessionError, AuthState, AuthTokenResponse, Config, DriveThruRpgSdk, SdkError,
67 };
68
69 #[test]
70 fn sdk_requires_configuration_before_auth_session_is_applied() {
71 let mut sdk = DriveThruRpgSdk::new();
72 let response = AuthTokenResponse::new("jwt-token", "refresh-token", 1_771_547_233);
73
74 let error = sdk.apply_auth_response(response).unwrap_err();
75
76 assert_eq!(error, SdkError::Unconfigured);
77 }
78
79 #[test]
80 fn sdk_stores_api_defined_auth_session_after_configuration() {
81 let mut sdk = DriveThruRpgSdk::with_config(Config::new("app-key"));
82 let response = AuthTokenResponse::new("jwt-token", "refresh-token", 1_771_547_233);
83
84 let session = sdk.apply_auth_response(response).unwrap();
85
86 assert_eq!(session.token(), "jwt-token");
87 assert_eq!(session.refresh_token(), "refresh-token");
88 assert!(!session.refresh_token_expired_at(1_771_547_232));
89 assert!(session.refresh_token_expired_at(1_771_547_233));
90 }
91
92 #[test]
93 fn invalidating_session_preserves_api_auth_state_meaning() {
94 let mut sdk = DriveThruRpgSdk::with_config(Config::new("app-key"));
95 let response = AuthTokenResponse::new("jwt-token", "refresh-token", 1_771_547_233);
96 sdk.apply_auth_response(response).unwrap();
97
98 let error = AuthSessionError::new(
99 "token_expired",
100 "The authentication token has expired.",
101 AuthState::TokenExpired,
102 );
103
104 let invalidation = sdk.invalidate_session(error.clone()).unwrap();
105
106 assert_eq!(invalidation, error);
107 assert_eq!(
108 sdk.require_session().unwrap_err(),
109 SdkError::Unauthenticated
110 );
111 }
112
113 #[test]
114 fn rust_sdk_generates_api_metadata_from_openapi_spec() {
115 assert_eq!(
116 crate::openapi::DEFAULT_SERVER_URL,
117 "https://api.drivethrurpg.com/api"
118 );
119 const { assert!(crate::openapi::OPENAPI_SPEC_BYTES > 0) };
120 assert!(
121 crate::openapi::OPERATIONS.contains(&crate::OpenApiOperation {
122 method: "POST",
123 path: "/{DTRPG_API_VERSION}/auth_key",
124 })
125 );
126 assert!(
127 crate::openapi::OPERATIONS.contains(&crate::OpenApiOperation {
128 method: "GET",
129 path: "/{DTRPG_API_VERSION}/order_products",
130 })
131 );
132 }
133}