diff --git a/Cargo.lock b/Cargo.lock index a5f00db..2c6c3c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,6 +31,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "anstream" version = "0.6.14" @@ -86,6 +95,16 @@ version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "assert-json-diff" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -137,6 +156,12 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.6.1" @@ -201,6 +226,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + [[package]] name = "const-random" version = "0.1.18" @@ -500,6 +535,12 @@ version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + [[package]] name = "hyper" version = "1.4.1" @@ -513,6 +554,7 @@ dependencies = [ "http", "http-body", "httparse", + "httpdate", "itoa", "pin-project-lite", "smallvec", @@ -638,6 +680,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.155" @@ -650,6 +698,16 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.22" @@ -689,6 +747,30 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "mockito" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b34bd91b9e5c5b06338d392463e1318d683cf82ec3d3af4014609be6e2108d" +dependencies = [ + "assert-json-diff", + "bytes", + "colored", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "log", + "rand", + "regex", + "serde_json", + "serde_urlencoded", + "similar", + "tokio", +] + [[package]] name = "native-tls" version = "0.2.12" @@ -774,6 +856,29 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -818,6 +923,15 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -836,6 +950,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "rayon" version = "1.10.0" @@ -856,6 +1000,44 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + [[package]] name = "reqwest" version = "0.12.5" @@ -1018,6 +1200,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "security-framework" version = "2.11.1" @@ -1107,6 +1295,12 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "similar" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" + [[package]] name = "slab" version = "0.4.9" @@ -1179,6 +1373,7 @@ dependencies = [ "clap", "csv", "itertools", + "mockito", "rayon", "reqwest", "rhai", @@ -1302,6 +1497,7 @@ dependencies = [ "bytes", "libc", "mio", + "parking_lot", "pin-project-lite", "socket2", "windows-sys 0.52.0", @@ -1744,6 +1940,7 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] diff --git a/Cargo.toml b/Cargo.toml index 91486c4..37f5675 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,9 @@ csv = "1.3.0" itertools = "0.13.0" rhai = { version = "1.19.0", features = ["serde", "sync"] } +[dev-dependencies] +mockito = "1.5.0" + [profile.release] lto = true # Enable link-time optimization codegen-units = 1 # Reduce number of codegen units to increase optimizations diff --git a/src/api/mod.rs b/src/api/mod.rs index 5d18bf9..50f98b9 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -501,8 +501,9 @@ pub type Entity = serde_json::Map; #[cfg(test)] mod tests { - use crate::api::CurrencyList; - use crate::api::IsoLanguageList; + use super::*; + use crate::config_file::Credentials; + use mockito::ServerGuard; use std::collections::HashMap; #[test] @@ -558,4 +559,95 @@ mod tests { ); assert_eq!(currency_list.get_currency_id_by_iso_code("GBP"), ""); } + + #[test] + fn test_sw_client_auth() { + let mut server = mockito::Server::new(); + + let base_url = server.url(); + let credentials = Credentials { + base_url, + access_key_id: "access_key_id".to_string(), + access_key_secret: "access_key_secret".to_string(), + }; + + let mock = server + .mock("POST", "/api/oauth/token") + .match_header("content-type", "application/json") + .match_body(mockito::Matcher::Json( + serde_json::to_value(&AuthBody { + grant_type: "client_credentials".to_string(), + client_id: credentials.access_key_id.clone(), + client_secret: credentials.access_key_secret.clone(), + }) + .unwrap(), + )) + .with_header("content-type", "application/json") + .with_body( + r#"{ + "access_token": "access_token" + }"#, + ) + .create(); + + // client new also authenticates + let client = SwClient::new(credentials).unwrap(); + mock.assert(); + + assert_eq!(client.access_token.lock().unwrap().as_str(), "access_token"); + } + + fn create_shopware_mock_server() -> (ServerGuard, SwClient) { + let mut server = mockito::Server::new(); + + let base_url = server.url(); + let credentials = Credentials { + base_url, + access_key_id: "access_key_id".to_string(), + access_key_secret: "access_key_secret".to_string(), + }; + + let mock = server + .mock("POST", "/api/oauth/token") + .match_header("content-type", "application/json") + .match_body(mockito::Matcher::Json( + serde_json::to_value(&AuthBody { + grant_type: "client_credentials".to_string(), + client_id: credentials.access_key_id.clone(), + client_secret: credentials.access_key_secret.clone(), + }) + .unwrap(), + )) + .with_header("content-type", "application/json") + .with_body( + r#"{ + "access_token": "access_token" + }"#, + ) + .create(); + + let client = SwClient::new(credentials).unwrap(); + mock.assert(); + (server, client) + } + + #[test] + fn test_sw_client_entity_schema() { + let (mut server, client) = create_shopware_mock_server(); + + let mock = server + .mock("GET", "/api/_info/entity-schema.json") + .with_header("content-type", "application/json") + .with_body_from_file("./fixtures/entity-schema-2024-08-01.json") + .create(); + + let schema = client.entity_schema().unwrap(); + mock.assert(); + + let expected_schema: Entity = serde_json::from_str( + &std::fs::read_to_string("./fixtures/entity-schema-2024-08-01.json").unwrap(), + ) + .unwrap(); + assert_eq!(schema, expected_schema); + } }