Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shippingservice rust #179

Merged
merged 20 commits into from
Jul 13, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
testing for shipping service
  • Loading branch information
GaryPWhite committed Jun 28, 2022
commit 5448cb685a1524897a9718bd92f129a0e65f06be
2 changes: 1 addition & 1 deletion src/shippingservice/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"

[[bin]]
name = "shippingservice"
path = "src/server.rs"
path = "src/main.rs"

[dependencies]
tonic = "0.7"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use tonic::{transport::Server};

use std::env;

mod shipping_service;
use shipping_service::ShippingServer;
use shipping_service::shop::shipping_service_server::ShippingServiceServer;
Expand All @@ -10,7 +12,8 @@ use health_service::health::health_server::HealthServer;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::1]:50051".parse()?;
let port = env::var("PORT").unwrap_or_else( |_|{"50051".to_string()});
GaryPWhite marked this conversation as resolved.
Show resolved Hide resolved
let addr = format!("[::1]:{}", port).parse()?;
let shipper = ShippingServer::default();
let health = HealthCheckServer::default();

Expand Down
123 changes: 112 additions & 11 deletions src/shippingservice/src/shipping_service.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use shop::shipping_service_server::ShippingService;
use shop::{GetQuoteRequest, GetQuoteResponse, Money, ShipOrderRequest, ShipOrderResponse};
use tonic::{Request, Response, Status};
use shop::shipping_service_server::{ShippingService};
use shop::{GetQuoteRequest,GetQuoteResponse, ShipOrderRequest,ShipOrderResponse, Money};

mod quote;
use quote::create_quote_from_count;

mod tracking;
use tracking::create_tracking_id;

const NANOS_MULTIPLE: i32 = 10000000i32;

pub mod shop {
tonic::include_proto!("hipstershop"); // The string specified here must match the proto package name
}
Expand All @@ -18,31 +21,129 @@ pub struct ShippingServer {}
impl ShippingService for ShippingServer {
async fn get_quote(
&self,
request: Request<GetQuoteRequest>
request: Request<GetQuoteRequest>,
) -> Result<Response<GetQuoteResponse>, Status> {
println!("GetQuoteRequest: {:?}", request);

let itemct: u32 = request
.into_inner()
.items
.into_iter()
.fold(0, |accum, cart_item| accum + (cart_item.quantity as u32));

let q = create_quote_from_count(request.into_inner().items.len().try_into().unwrap());
println!("itemct: {}", itemct);
let q = create_quote_from_count(itemct);
let reply = GetQuoteResponse {
cost_usd: Some(Money{
cost_usd: Some(Money {
currency_code: "USD".into(),
units: q.dollars,
nanos: q.cents * 10000000i32,
})
units: q.dollars,
nanos: q.cents * NANOS_MULTIPLE,
}),
};

Ok(Response::new(reply))
}
async fn ship_order(
&self,
request: Request<ShipOrderRequest>
request: Request<ShipOrderRequest>,
) -> Result<Response<ShipOrderResponse>, Status> {
println!("ShipOrderRequest: {:?}", request);

let reply = ShipOrderResponse{
let reply = ShipOrderResponse {
tracking_id: create_tracking_id(),
};

Ok(Response::new(reply))
}
}
}

#[cfg(test)]
mod tests {
use super::{
shop::shipping_service_server::ShippingService,
shop::{CartItem, ShipOrderRequest},
shop::{Address, GetQuoteRequest},
ShippingServer, NANOS_MULTIPLE,
};
use tonic::Request;
use uuid::Uuid;

fn make_quote_request_with_items(items: Vec<i32>) -> Request<GetQuoteRequest> {
let cart_items: Vec<CartItem> = items.into_iter().fold(Vec::new(), |mut accum, count| {
accum.push(CartItem {
product_id: "fake-item".to_string(),
mic-max marked this conversation as resolved.
Show resolved Hide resolved
quantity: count,
});
accum
});

Request::new(GetQuoteRequest {
address: Some(Address::default()),
items: cart_items,
})
}

fn make_empty_quote_request() -> Request<GetQuoteRequest> {
Request::new(GetQuoteRequest::default())
}
#[tokio::test]
async fn empty_quote() {
let server = ShippingServer::default();

// when we provide no items, the quote should be empty
match server.get_quote(make_empty_quote_request()).await {
Ok(resp) => {
let money = resp.into_inner().cost_usd.unwrap();
assert_eq!(money.units, 0);
assert_eq!(money.nanos, 0);
},
Err(e) => panic!("error when making empty quote request: {}", e),
}
}

#[tokio::test]
async fn quote_for_one_value() {
let server = ShippingServer::default();

match server.get_quote(make_quote_request_with_items(vec![1_i32])).await {
Ok(resp) => {
// items are fixed at 8.99, so we should see that price reflected.
let money = resp.into_inner().cost_usd.unwrap();
assert_eq!(money.units, 8);
assert_eq!(money.nanos, 99 * NANOS_MULTIPLE);
},
Err(e) => panic!("error when making quote request for one value: {}", e),
}
}

#[tokio::test]
async fn quote_for_many_values() {
let server = ShippingServer::default();

match server.get_quote(make_quote_request_with_items(vec![1_i32, 2_i32])).await {
Ok(resp) => {
// items are fixed at 8.99, so we should see that price reflected for 3 items
let money = resp.into_inner().cost_usd.unwrap();
assert_eq!(money.units, 26);
assert_eq!(money.nanos, 97 * NANOS_MULTIPLE);
},
Err(e) => panic!("error when making quote request for many values: {}", e),
}
}

#[tokio::test]
async fn can_get_tracking_id() {
let server = ShippingServer::default();

match server.ship_order(Request::new(ShipOrderRequest::default())).await {
Ok(resp) => {
// we should see a uuid
match Uuid::parse_str(&resp.into_inner().tracking_id) {
Ok(_) => {}
Err(e) => panic!("error when parsing uuid: {}", e)
}
},
Err(e) => panic!("error when making request for tracking ID: {}", e),
}
}
}
5 changes: 3 additions & 2 deletions src/shippingservice/src/shipping_service/quote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ pub struct Quote {
pub cents: i32,
}

// TODO: Check product catalog for price on each item, accept item ID
pub fn create_quote_from_count(count: u32) -> Quote {
let f = if count == 0 { 0.0 } else { 8.99 };
let f = if count == 0 { 0.0 } else { 8.99*(count as f64) };
create_quote_from_float(f)
}

pub fn create_quote_from_float(value: f64) -> Quote {
Quote {
dollars: value.floor() as i64,
cents: (value.rem_euclid(1_f64) * 100_f64) as i32,
cents: ((value * 100_f64) as i32) % 100,
}
}