@@ -46,13 +46,27 @@ impl RequestHandler for UnregisterNotificationsRequestHandler {
4646 request_payload : Option < UPayload > ,
4747 ) -> Result < Option < UPayload > , ServiceInvocationError > {
4848 // [impl->dsn~usubscription-unregister-notifications-protobuf~1]
49- let ( _subscription_request , source) = helpers:: extract_inputs :: < NotificationsRequest > (
49+ let ( notification_request , source) = helpers:: extract_inputs :: < NotificationsRequest > (
5050 RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS ,
5151 resource_id,
5252 & request_payload,
5353 message_attributes,
5454 ) ?;
5555
56+ let Some ( topic) = notification_request. topic . as_ref ( ) else {
57+ return Err ( ServiceInvocationError :: InvalidArgument (
58+ "No topic defined in request" . to_string ( ) ,
59+ ) ) ;
60+ } ;
61+
62+ // [impl->dsn~usubscription-unregister-notifications-invalid-topic~1]
63+ helpers:: validate_uri ( topic) . map_err ( |e| {
64+ ServiceInvocationError :: InvalidArgument ( format ! ( "Invalid topic uri '{topic}': {e}" ) )
65+ } ) ?;
66+
67+ // TODO: can/should we actually use the topic alongside the subscriber, for notification-removal?
68+ // UGH - this entire notifications storage thing doesn't work, can only store one topic per subscriber atm. Needs fixed...
69+
5670 // Interact with notification manager backend
5771 let se = NotificationEvent :: RemoveNotifyee {
5872 subscriber : source. clone ( ) ,
@@ -78,8 +92,12 @@ impl RequestHandler for UnregisterNotificationsRequestHandler {
7892#[ cfg( test) ]
7993mod tests {
8094 use super :: * ;
95+ use std:: str:: FromStr ;
96+ use test_case:: test_case;
8197 use tokio:: sync:: mpsc:: { self } ;
8298
99+ use up_rust:: UUri ;
100+
83101 use crate :: { helpers, tests:: test_lib} ;
84102
85103 // [utest->dsn~usubscription-unregister-notifications-protobuf~1]
@@ -236,4 +254,38 @@ mod tests {
236254
237255 assert ! ( result. is_err_and( |err| matches!( err, ServiceInvocationError :: InvalidArgument ( _) ) ) ) ;
238256 }
257+
258+ // [utest->dsn~usubscription-unregister-notifications-invalid-topic~1]
259+ #[ test_case( "up:/0/0/0" ; "Bad topic UUri" ) ]
260+ #[ test_case( "up://*/100000/1/8AC7" ; "Wildcard authority in topic UUri" ) ]
261+ #[ test_case( "up://LOCAL/FFFF0000/1/8AC7" ; "Wildcard entity id in topic UUri" ) ]
262+ #[ test_case( "up://LOCAL/100000/1/FFFF" ; "Wildcard resource id in topic UUri" ) ]
263+ #[ tokio:: test]
264+ async fn test_invalid_topic_uri ( topic : & str ) {
265+ helpers:: init_once ( ) ;
266+
267+ // create request and other required object(s)
268+ let topic = UUri :: from_str ( topic) . expect ( "Test parameter UUri failed to parse" ) ;
269+ // create request and other required object(s)
270+ let subscribe_request = test_lib:: helpers:: subscription_request ( topic, None ) ;
271+ let request_payload = UPayload :: try_from_protobuf ( subscribe_request. clone ( ) ) . unwrap ( ) ;
272+ let message_attributes = UAttributes {
273+ source : Some ( test_lib:: helpers:: subscriber_uri1 ( ) ) . into ( ) ,
274+ ..Default :: default ( )
275+ } ;
276+ let ( subscription_sender, _) = mpsc:: channel :: < NotificationEvent > ( 1 ) ;
277+
278+ // create handler and perform tested operation
279+ let request_handler = UnregisterNotificationsRequestHandler :: new ( subscription_sender) ;
280+
281+ let result = request_handler
282+ . handle_request (
283+ up_rust:: core:: usubscription:: RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS ,
284+ & message_attributes,
285+ Some ( request_payload) ,
286+ )
287+ . await ;
288+
289+ assert ! ( result. is_err_and( |err| matches!( err, ServiceInvocationError :: InvalidArgument ( _) ) ) ) ;
290+ }
239291}
0 commit comments