Repository: getmoto/moto

Issue:
Listing CloudFormation stacks should include deleted stacks
Using the AWS API directly returns stacks with a status `DELETE_COMPLETE`; using moto those stacks are not returned.

The existing unit tests actually test for this incorrect behaviour:
https://github.com/spulec/moto/blob/4a275cc/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py#L516-L518

The tests should be updated and the `list_stacks` method on the backend should include the `self.deleted_stacks` data (https://github.com/spulec/moto/blob/4a275cc/moto/cloudformation/models.py#L225-L226)


Discussion:
OK, those tests might be correct - I think this might just be in the `list_stacks` call.

Resolving patch:
diff --git a/moto/cloudformation/models.py b/moto/cloudformation/models.py
--- a/moto/cloudformation/models.py
+++ b/moto/cloudformation/models.py
@@ -223,7 +223,11 @@ def describe_stacks(self, name_or_stack_id):
             return list(stacks)
 
     def list_stacks(self):
-        return self.stacks.values()
+        return [
+            v for v in self.stacks.values()
+        ] + [
+            v for v in self.deleted_stacks.values()
+        ]
 
     def get_stack(self, name_or_stack_id):
         all_stacks = dict(self.deleted_stacks, **self.stacks)


Test patch:
diff --git a/tests/test_cloudformation/test_cloudformation_stack_crud.py b/tests/test_cloudformation/test_cloudformation_stack_crud.py
--- a/tests/test_cloudformation/test_cloudformation_stack_crud.py
+++ b/tests/test_cloudformation/test_cloudformation_stack_crud.py
@@ -266,9 +266,9 @@ def test_delete_stack_by_name():
         template_body=dummy_template_json,
     )
 
-    conn.list_stacks().should.have.length_of(1)
+    conn.describe_stacks().should.have.length_of(1)
     conn.delete_stack("test_stack")
-    conn.list_stacks().should.have.length_of(0)
+    conn.describe_stacks().should.have.length_of(0)
 
 
 @mock_cloudformation_deprecated
@@ -279,9 +279,9 @@ def test_delete_stack_by_id():
         template_body=dummy_template_json,
     )
 
-    conn.list_stacks().should.have.length_of(1)
+    conn.describe_stacks().should.have.length_of(1)
     conn.delete_stack(stack_id)
-    conn.list_stacks().should.have.length_of(0)
+    conn.describe_stacks().should.have.length_of(0)
     with assert_raises(BotoServerError):
         conn.describe_stacks("test_stack")
 
@@ -296,9 +296,9 @@ def test_delete_stack_with_resource_missing_delete_attr():
         template_body=dummy_template_json3,
     )
 
-    conn.list_stacks().should.have.length_of(1)
+    conn.describe_stacks().should.have.length_of(1)
     conn.delete_stack("test_stack")
-    conn.list_stacks().should.have.length_of(0)
+    conn.describe_stacks().should.have.length_of(0)
 
 
 @mock_cloudformation_deprecated
diff --git a/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py b/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py
--- a/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py
+++ b/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py
@@ -532,6 +532,21 @@ def test_delete_stack_by_name():
     cf_conn.describe_stacks()['Stacks'].should.have.length_of(0)
 
 
+@mock_cloudformation
+def test_delete_stack():
+    cf = boto3.client('cloudformation', region_name='us-east-1')
+    cf.create_stack(
+        StackName="test_stack",
+        TemplateBody=dummy_template_json,
+    )
+
+    cf.delete_stack(
+        StackName="test_stack",
+    )
+    stacks = cf.list_stacks()
+    assert stacks['StackSummaries'][0]['StackStatus'] == 'DELETE_COMPLETE'
+
+
 @mock_cloudformation
 def test_describe_deleted_stack():
     cf_conn = boto3.client('cloudformation', region_name='us-east-1')