Skip to content

Commit

Permalink
Add support for updating a watchlist
Browse files Browse the repository at this point in the history
So far watchlists have been effectively immutable: one could only create
one, retrieve it, and delete it eventually.
With this change we add support for updating such a list, allowing for
renaming and/or changing of contained symbols.
  • Loading branch information
d-e-s-o committed Feb 12, 2024
1 parent 7336830 commit f143b18
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- This variant is now used to signal a multitude of conditions,
including certain order submission issues
- Added `name` attribute to `api::v2::watchlist::Watchlist` type
- Added support for updating a watchlist
- Bumped minimum supported Rust version to `1.63`
- Bumped `websocket-util` dependency to `0.12`
- Bumped `tokio-tungstenite` dependency to `0.20`
Expand Down
77 changes: 76 additions & 1 deletion src/api/v2/watchlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub struct Watchlist {
}


/// A create watchlist request item
/// A request to create a watch list.
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct CreateReq {
/// The watchlist's name.
Expand All @@ -72,6 +72,10 @@ pub struct CreateReq {
}


/// A request to update a watch list.
pub type UpdateReq = CreateReq;


Endpoint! {
/// The representation of a POST request to the /v2/watchlists endpoint.
pub Post(CreateReq),
Expand Down Expand Up @@ -122,6 +126,41 @@ Endpoint! {
}


Endpoint! {
/// The representation of a PUT request to the
/// /v2/watchlists/{watchlist-id} endpoint.
pub Update((Id, UpdateReq)),
Ok => Watchlist, [
/// The watchlist object with the given ID was retrieved successfully.
/* 200 */ OK,
],
Err => UpdateError, [
/// No watchlist was found with the given ID.
/* 404 */ NOT_FOUND => NotFound,
/// The watchlist name was not unique or other parts of the input
/// are not valid.
/* 422 */ UNPROCESSABLE_ENTITY => InvalidInput,
]

fn path(input: &Self::Input) -> Str {
let (id, _) = input;
format!("/v2/watchlists/{}", id.as_simple()).into()
}

#[inline]
fn method() -> Method {
Method::PUT
}

fn body(input: &Self::Input) -> Result<Option<Bytes>, Self::ConversionError> {
let (_, request) = input;
let json = to_json(request)?;
let bytes = Bytes::from(json);
Ok(Some(bytes))
}
}


EndpointNoParse! {
/// The representation of a DELETE request to the
/// /v2/watchlists/{watchlist-id} endpoint.
Expand Down Expand Up @@ -253,6 +292,42 @@ mod tests {
};
}

/// Check that we can update a watchlist.
#[test(tokio::test)]
async fn update() {
let api_info = ApiInfo::from_env().unwrap();
let client = Client::new(api_info);
let symbols = vec!["AAPL".to_string()];
let id = Uuid::new_v4().to_string();
let created = client
.issue::<Post>(&CreateReq {
name: id.clone(),
symbols: symbols.clone(),
})
.await
.unwrap();

let id2 = Uuid::new_v4().to_string();
let symbols = vec!["AMZN".to_string(), "SPY".to_string()];

let req = UpdateReq {
name: id2.clone(),
symbols: symbols.clone(),
};

let result = client.issue::<Update>(&(created.id, req)).await;
let () = client.issue::<Delete>(&created.id).await.unwrap();

let watchlist = result.unwrap();
assert_eq!(watchlist.name, id2.to_string());
let symbols = watchlist
.assets
.iter()
.map(|asset| &asset.symbol)
.collect::<Vec<_>>();
assert_eq!(symbols, vec!["AMZN", "SPY"]);
}

/// Verify that we report the appropriate error when attempting to
/// delete a watchlist that does not exist.
#[test(tokio::test)]
Expand Down

0 comments on commit f143b18

Please sign in to comment.