Repository: cookiecutter/cookiecutter-django
Pull request: Fix #2249 -- Broken static files with whitenoise=n & cloud_prov…
[//]: # (Thank you for helping us out: your efforts mean great deal to the project and the community as a whole!)

[//]: # (Before you proceed:)

[//]: # (1. Make sure to add yourself to `CONTRIBUTORS.rst` through this PR provided you're contributing here for the first time)
[//]: # (2. Don't forget to update the `docs/` presuming others would benefit from a concise description of whatever that you're proposing)


## Description

[//]: # (What's it you're proposing?)

Fixes https://github.com/pydanny/cookiecutter-django/issues/2249


## Rationale

[//]: # (Why does the project need that?)

If the user chooses use_whitenoise=n & cloud_provider=None, it should not be allowed and show an error when trying to generate the project.


## Use case(s) / visualization(s)

[//]: # ("Better to see something once than to hear about it a thousand times.")




Problem statement:
Broken static files with whitenoise=n & cloud_provider=none
## What happened?

If the user chooses `use_whitenoise=n` & `cloud_provider=None`, then the static files are not served properly.

## What should've happened instead?

This combination should not be allowed and show an error when trying to generate the project.

Hints from issue discussion:
To fix that, I think we should implement a check in one of the hooks, show an error to the user and not generate anything. 

The tests will need to be updated to:

1. Cover only the working combination in the main fixture:

   https://github.com/pydanny/cookiecutter-django/blob/63453b6e51faae64c872059cb4d90dd38d4b8865/tests/test_cookiecutter_generation.py#L39-L40

2. Add a new test to make sure the project isn't generated when the invalid combination is selected.

More details about cookiecutter's hook mechanism: https://cookiecutter.readthedocs.io/en/latest/advanced/hooks.html#writing-hooks
@browniebroke I'll be working on this one as well

Commit message: Add docstring

Patch to review:
diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py
index 91332f144f..7f9bd3eac2 100644
--- a/hooks/pre_gen_project.py
+++ b/hooks/pre_gen_project.py
@@ -59,3 +59,12 @@
                     )
                     + TERMINATOR
                 )
+
+if (
+    "{{ cookiecutter.use_whitenoise }}".lower() == "n"
+    and "{{ cookiecutter.cloud_provider }}" == "None"
+):
+    print(
+        "You should either use Whitenoise or select a Cloud Provider to serve static files"
+    )
+    sys.exit(1)
diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py
index 77f71df5b8..b02bba360a 100755
--- a/tests/test_cookiecutter_generation.py
+++ b/tests/test_cookiecutter_generation.py
@@ -49,6 +49,11 @@ def context_combination(
     cloud_provider,
 ):
     """Fixture that parametrize the function where it's used."""
+    if cloud_provider == "None":
+        # Either of the two should be set for serving static files, so if cloud provider
+        # is not set, we force Whitenoise to be set
+        use_whitenoise = "y"
+
     return {
         "windows": windows,
         "use_docker": use_docker,
@@ -157,3 +162,11 @@ def test_invalid_slug(cookies, context, slug):
 
     assert result.exit_code != 0
     assert isinstance(result.exception, FailedHookException)
+
+
+def test_no_whitenoise_and_no_cloud_provider(cookies, context):
+    """It should not generate project if neither whitenoise or cloud provider are set"""
+    context.update({"use_whitenoise": "n", "cloud_provider": "None"})
+    result = cookies.bake(extra_context=context)
+
+    assert result.exit_code == 1


Code review comments:
diff_hunk: @@ -157,3 +162,11 @@ def test_invalid_slug(cookies, context, slug):
 
     assert result.exit_code != 0
     assert isinstance(result.exception, FailedHookException)
+
+
+def test_no_whitenoise_and_no_cloud_provider(cookies, context):
+    """It should not generate project if neither whitenoise or cloud provider are set"""
+    context.update({"use_whitenoise": "n", "cloud_provider": "None"})
+    result = cookies.bake(extra_context=context)
+
+    assert result.exit_code == 1
path: tests/test_cookiecutter_generation.py
text: @user1:
Looks like it's `-1` for some reason... I suppose it's good enough to check that it's non-zero, and that the exception type is what we want. We don't really need a specific number:

```suggestion
    assert result.exit_code != 0
    assert isinstance(result.exception, FailedHookException)
```