@@ -8,9 +8,10 @@ use relayer_modules::ics24_host::identifier::{ChannelId, PortId};
8
8
9
9
use crate :: commands:: utils:: block_on;
10
10
use relayer:: chain:: tendermint:: TendermintChain ;
11
+ use relayer_modules:: ics24_host:: error:: ValidationError ;
11
12
use tendermint:: chain:: Id as ChainId ;
12
13
13
- #[ derive( Command , Debug , Options ) ]
14
+ #[ derive( Clone , Command , Debug , Options ) ]
14
15
pub struct QueryChannelEndsCmd {
15
16
#[ options( free, help = "identifier of the chain to query" ) ]
16
17
chain_id : Option < ChainId > ,
@@ -41,32 +42,42 @@ impl QueryChannelEndsCmd {
41
42
& self ,
42
43
config : & Config ,
43
44
) -> Result < ( ChainConfig , QueryChannelOptions ) , String > {
44
- match ( & self . chain_id , & self . port_id , & self . channel_id ) {
45
- ( Some ( chain_id) , Some ( port_id) , Some ( channel_id) ) => {
46
- let chain_config = config. chains . iter ( ) . find ( |c| c. id == * chain_id) ;
47
- match chain_config {
48
- Some ( chain_config) => {
49
- let opts = QueryChannelOptions {
50
- port_id : port_id. parse ( ) . unwrap ( ) ,
51
- channel_id : channel_id. parse ( ) . unwrap ( ) ,
52
- height : match self . height {
53
- Some ( h) => h,
54
- None => 0 as u64 ,
55
- } ,
56
- proof : match self . proof {
57
- Some ( proof) => proof,
58
- None => true ,
59
- } ,
60
- } ;
61
- Ok ( ( chain_config. clone ( ) , opts) )
62
- }
63
- _ => Err ( format ! ( "cannot find chain {} in config" , chain_id) ) ,
64
- }
65
- }
66
- ( None , _, _) => Err ( "missing chain identifier" . to_string ( ) ) ,
67
- ( _, None , _) => Err ( "missing port identifier" . to_string ( ) ) ,
68
- ( _, _, None ) => Err ( "missing channel identifier" . to_string ( ) ) ,
69
- }
45
+ let chain_id = self
46
+ . chain_id
47
+ . ok_or_else ( || "missing chain identifier" . to_string ( ) ) ?;
48
+ let chain_config = config
49
+ . chains
50
+ . iter ( )
51
+ . find ( |c| c. id == chain_id)
52
+ . ok_or_else ( || "missing chain configuration" . to_string ( ) ) ?;
53
+
54
+ let port_id = self
55
+ . port_id
56
+ . as_ref ( )
57
+ . ok_or_else ( || "missing port identifier" . to_string ( ) ) ?
58
+ . parse ( )
59
+ . map_err ( |err : ValidationError | err. to_string ( ) ) ?;
60
+
61
+ let channel_id = self
62
+ . channel_id
63
+ . as_ref ( )
64
+ . ok_or_else ( || "missing channel identifier" . to_string ( ) ) ?
65
+ . parse ( )
66
+ . map_err ( |err : ValidationError | err. to_string ( ) ) ?;
67
+
68
+ let opts = QueryChannelOptions {
69
+ port_id,
70
+ channel_id,
71
+ height : match self . height {
72
+ Some ( h) => h,
73
+ None => 0 as u64 ,
74
+ } ,
75
+ proof : match self . proof {
76
+ Some ( proof) => proof,
77
+ None => true ,
78
+ } ,
79
+ } ;
80
+ Ok ( ( chain_config. clone ( ) , opts) )
70
81
}
71
82
}
72
83
@@ -105,3 +116,112 @@ impl Runnable for QueryChannelEndsCmd {
105
116
}
106
117
}
107
118
}
119
+
120
+ #[ cfg( test) ]
121
+ mod tests {
122
+ use crate :: commands:: query:: channel:: QueryChannelEndsCmd ;
123
+ use relayer:: config:: parse;
124
+
125
+ #[ test]
126
+ fn parse_query_ends_parameters ( ) {
127
+ let default_params = QueryChannelEndsCmd {
128
+ chain_id : Some ( "ibc0" . to_string ( ) . parse ( ) . unwrap ( ) ) ,
129
+ port_id : Some ( "transfer" . to_string ( ) . parse ( ) . unwrap ( ) ) ,
130
+ channel_id : Some ( "testchannel" . to_string ( ) . parse ( ) . unwrap ( ) ) ,
131
+ height : None ,
132
+ proof : None ,
133
+ } ;
134
+
135
+ struct Test {
136
+ name : String ,
137
+ params : QueryChannelEndsCmd ,
138
+ want_pass : bool ,
139
+ }
140
+
141
+ let tests: Vec < Test > = vec ! [
142
+ Test {
143
+ name: "Good parameters" . to_string( ) ,
144
+ params: default_params. clone( ) ,
145
+ want_pass: true ,
146
+ } ,
147
+ Test {
148
+ name: "No chain specified" . to_string( ) ,
149
+ params: QueryChannelEndsCmd {
150
+ chain_id: None ,
151
+ ..default_params. clone( )
152
+ } ,
153
+ want_pass: false ,
154
+ } ,
155
+ Test {
156
+ name: "Chain not configured" . to_string( ) ,
157
+ params: QueryChannelEndsCmd {
158
+ chain_id: Some ( "notibc0oribc1" . to_string( ) . parse( ) . unwrap( ) ) ,
159
+ ..default_params. clone( )
160
+ } ,
161
+ want_pass: false ,
162
+ } ,
163
+ Test {
164
+ name: "No port id specified" . to_string( ) ,
165
+ params: QueryChannelEndsCmd {
166
+ port_id: None ,
167
+ ..default_params. clone( )
168
+ } ,
169
+ want_pass: false ,
170
+ } ,
171
+ Test {
172
+ name: "Bad port, non-alpha" . to_string( ) ,
173
+ params: QueryChannelEndsCmd {
174
+ port_id: Some ( "p34" . to_string( ) ) ,
175
+ ..default_params. clone( )
176
+ } ,
177
+ want_pass: false ,
178
+ } ,
179
+ Test {
180
+ name: "No channel id specified" . to_string( ) ,
181
+ params: QueryChannelEndsCmd {
182
+ channel_id: None ,
183
+ ..default_params. clone( )
184
+ } ,
185
+ want_pass: false ,
186
+ } ,
187
+ Test {
188
+ name: "Bad channel, name too short" . to_string( ) ,
189
+ params: QueryChannelEndsCmd {
190
+ channel_id: Some ( "chshort" . to_string( ) ) ,
191
+ ..default_params. clone( )
192
+ } ,
193
+ want_pass: false ,
194
+ } ,
195
+ ]
196
+ . into_iter ( )
197
+ . collect ( ) ;
198
+
199
+ let path = concat ! (
200
+ env!( "CARGO_MANIFEST_DIR" ) ,
201
+ "/tests/fixtures/two_chains.toml"
202
+ ) ;
203
+
204
+ let config = parse ( path) . unwrap ( ) ;
205
+
206
+ for test in tests {
207
+ let res = test. params . validate_options ( & config) ;
208
+
209
+ match res {
210
+ Ok ( _res) => {
211
+ assert ! (
212
+ test. want_pass,
213
+ "validate_options should have failed for test {}" ,
214
+ test. name
215
+ ) ;
216
+ }
217
+ Err ( err) => {
218
+ assert ! (
219
+ !test. want_pass,
220
+ "validate_options failed for test {}, \n err {}" ,
221
+ test. name, err
222
+ ) ;
223
+ }
224
+ }
225
+ }
226
+ }
227
+ }
0 commit comments