@@ -79,6 +79,14 @@ fn unique_name(prefix: &str) -> String {
7979 format ! ( "{prefix}-{suffix:06}" )
8080}
8181
82+ fn output_contains ( output : & str , needle : & str ) -> bool {
83+ output. to_lowercase ( ) . contains ( & needle. to_lowercase ( ) )
84+ }
85+
86+ fn output_mentions_template_not_found ( output : & str ) -> bool {
87+ output_contains ( output, "sandbox template" ) && output_contains ( output, "not found" )
88+ }
89+
8290#[ tokio:: test]
8391async fn sandbox_create_from_template_uses_reusable_workload ( ) {
8492 let template_name = unique_name ( "tmpl" ) ;
@@ -171,3 +179,97 @@ async fn sandbox_create_from_template_uses_reusable_workload() {
171179 sandbox. cleanup ( ) . await ;
172180 template. cleanup ( ) . await ;
173181}
182+
183+ #[ tokio:: test]
184+ async fn sandbox_template_get_after_delete_returns_not_found ( ) {
185+ let template_name = unique_name ( "tmpl-del" ) ;
186+ let template = TemplateGuard :: new ( template_name. clone ( ) ) ;
187+
188+ let create_template = run_cli ( & [ "sandbox" , "template" , "create" , & template_name] ) . await ;
189+ assert ! (
190+ create_template. success,
191+ "sandbox template create failed:\n {}" ,
192+ create_template. output
193+ ) ;
194+
195+ let delete_template = run_cli ( & [ "sandbox" , "template" , "delete" , & template_name] ) . await ;
196+ assert ! (
197+ delete_template. success,
198+ "sandbox template delete failed:\n {}" ,
199+ delete_template. output
200+ ) ;
201+
202+ let get_deleted = run_cli ( & [ "sandbox" , "template" , "get" , & template_name] ) . await ;
203+ assert ! (
204+ !get_deleted. success,
205+ "deleted template should not be fetchable:\n {}" ,
206+ get_deleted. output
207+ ) ;
208+ assert ! (
209+ output_mentions_template_not_found( & get_deleted. output) ,
210+ "deleted template should return not-found:\n {}" ,
211+ get_deleted. output
212+ ) ;
213+
214+ template. cleanup ( ) . await ;
215+ }
216+
217+ #[ tokio:: test]
218+ async fn sandbox_template_create_rejects_duplicate_name ( ) {
219+ let template_name = unique_name ( "tmpl-dupe" ) ;
220+ let template = TemplateGuard :: new ( template_name. clone ( ) ) ;
221+
222+ let create_template = run_cli ( & [ "sandbox" , "template" , "create" , & template_name] ) . await ;
223+ assert ! (
224+ create_template. success,
225+ "sandbox template create failed:\n {}" ,
226+ create_template. output
227+ ) ;
228+
229+ let duplicate = run_cli ( & [ "sandbox" , "template" , "create" , & template_name] ) . await ;
230+ assert ! (
231+ !duplicate. success,
232+ "duplicate sandbox template create should fail:\n {}" ,
233+ duplicate. output
234+ ) ;
235+ assert ! (
236+ output_contains( & duplicate. output, "already exists" ) ,
237+ "duplicate sandbox template create should report already-exists:\n {}" ,
238+ duplicate. output
239+ ) ;
240+
241+ template. cleanup ( ) . await ;
242+ }
243+
244+ #[ tokio:: test]
245+ async fn sandbox_create_from_missing_template_returns_not_found ( ) {
246+ let template_name = unique_name ( "tmpl-missing" ) ;
247+ let sandbox_name = unique_name ( "sb-missing" ) ;
248+
249+ let create_sandbox = run_cli ( & [
250+ "sandbox" ,
251+ "create" ,
252+ "--name" ,
253+ & sandbox_name,
254+ "--template" ,
255+ & template_name,
256+ "--" ,
257+ "true" ,
258+ ] )
259+ . await ;
260+
261+ if create_sandbox. success {
262+ let _ = run_cli ( & [ "sandbox" , "delete" , & sandbox_name] ) . await ;
263+ }
264+
265+ assert ! (
266+ !create_sandbox. success,
267+ "sandbox create from missing template should fail:\n {}" ,
268+ create_sandbox. output
269+ ) ;
270+ assert ! (
271+ output_mentions_template_not_found( & create_sandbox. output) ,
272+ "sandbox create from missing template should report not-found:\n {}" ,
273+ create_sandbox. output
274+ ) ;
275+ }
0 commit comments