From dd72593e421fbddd08a37bcb277672ba394001a1 Mon Sep 17 00:00:00 2001
From: George Hickman <ghickman@users.noreply.github.com>
Date: Mon, 12 Aug 2019 14:59:04 +0100
Subject: [PATCH] Add Projects Feature Flag (#1394)

* Add feature flag to Project creation
* Show project related UI elements when Projects are enabled
* Enable Project URLs based on feature flag
* Enable projects for testing
---
 .circleci/config.yml                             |  1 +
 .travis.yml                                      |  1 +
 .../applicationsubmission_admin_detail.html      |  2 ++
 .../funds/applicationsubmission_detail.html      |  2 +-
 opentech/apply/projects/models.py                |  7 +++++++
 opentech/apply/projects/tests/test_settings.py   | 15 +++++++++++++++
 opentech/apply/projects/urls.py                  | 16 ++++++++++------
 opentech/settings/base.py                        |  6 ++++++
 8 files changed, 43 insertions(+), 7 deletions(-)
 create mode 100644 opentech/apply/projects/tests/test_settings.py

diff --git a/.circleci/config.yml b/.circleci/config.yml
index 5d1ba2991..c7e509566 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -13,6 +13,7 @@ jobs:
           PGUSER: root
           DJANGO_SETTINGS_MODULE: opentech.settings.test
           SEND_MESSAGES: false
+          PROJECTS_ENABLED: true
 
       - image: circleci/postgres:10.5
         environment:
diff --git a/.travis.yml b/.travis.yml
index 3a9983e24..d2e18cf9f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -21,6 +21,7 @@ env:
   global:
     - DJANGO_SETTINGS_MODULE=opentech.settings.test
     - DATABASE_URL=postgres://postgres@localhost/test_db
+    - PROJECTS_ENABLED=true
 
 before_script:
   # Create a database
diff --git a/opentech/apply/funds/templates/funds/applicationsubmission_admin_detail.html b/opentech/apply/funds/templates/funds/applicationsubmission_admin_detail.html
index 49940120e..2216c7cfc 100644
--- a/opentech/apply/funds/templates/funds/applicationsubmission_admin_detail.html
+++ b/opentech/apply/funds/templates/funds/applicationsubmission_admin_detail.html
@@ -17,7 +17,9 @@
         {% include "funds/includes/update_lead_form.html" %}
         {% include "funds/includes/update_reviewer_form.html" %}
         {% include "funds/includes/update_partner_form.html" %}
+        {% if settings.PROJECTS_ENABLED %}
         {% include "funds/includes/create_project_form.html" %}
+        {% endif %}
         {% include "funds/includes/update_meta_categories_form.html" %}
 {% endblock %}
 
diff --git a/opentech/apply/funds/templates/funds/applicationsubmission_detail.html b/opentech/apply/funds/templates/funds/applicationsubmission_detail.html
index 0583233d3..077f4ae6e 100644
--- a/opentech/apply/funds/templates/funds/applicationsubmission_detail.html
+++ b/opentech/apply/funds/templates/funds/applicationsubmission_detail.html
@@ -99,7 +99,7 @@
                     {% endblock %}
                 {% endif %}
 
-                {% if object.project %}
+                {% if object.project and settings.PROJECTS_ENABLED %}
                     {% include 'funds/includes/project_block.html' %}
                 {% endif %}
 
diff --git a/opentech/apply/projects/models.py b/opentech/apply/projects/models.py
index c3fb3e4a6..f13d8eed8 100644
--- a/opentech/apply/projects/models.py
+++ b/opentech/apply/projects/models.py
@@ -1,6 +1,7 @@
 import collections
 import decimal
 import json
+import logging
 
 from addressfield.fields import ADDRESS_FIELDS_ORDER
 from django.conf import settings
@@ -11,6 +12,8 @@ from django.db import models
 from django.urls import reverse
 from django.utils.translation import ugettext as _
 
+logger = logging.getLogger(__name__)
+
 
 class Approval(models.Model):
     project = models.ForeignKey("Project", on_delete=models.CASCADE, related_name="approvals")
@@ -118,6 +121,10 @@ class Project(models.Model):
         Returns a new Project or the given ApplicationSubmissions existing
         Project.
         """
+        if not settings.PROJECTS_ENABLED:
+            logging.error(f'Tried to create a Project for Submission ID={submission.id} while projects are disabled')
+            return None
+
         # OneToOne relations on the targetted model cannot be accessed without
         # an exception when the relation doesn't exist (is None).  Since we
         # want to fail fast here, we can use hasattr instead.
diff --git a/opentech/apply/projects/tests/test_settings.py b/opentech/apply/projects/tests/test_settings.py
new file mode 100644
index 000000000..a627795b1
--- /dev/null
+++ b/opentech/apply/projects/tests/test_settings.py
@@ -0,0 +1,15 @@
+from django.test import TestCase, override_settings
+
+from opentech.apply.users.tests.factories import StaffFactory
+
+
+class TestProjectFeatureFlag(TestCase):
+    @override_settings(PROJECTS_ENABLED=False)
+    def test_urls_404_when_turned_off(self):
+        self.client.force_login(StaffFactory())
+
+        response = self.client.get('/apply/projects/', follow=True)
+        self.assertEqual(response.status_code, 404)
+
+        response = self.client.get('/apply/projects/1/', follow=True)
+        self.assertEqual(response.status_code, 404)
diff --git a/opentech/apply/projects/urls.py b/opentech/apply/projects/urls.py
index ad585c9d1..d2d815129 100644
--- a/opentech/apply/projects/urls.py
+++ b/opentech/apply/projects/urls.py
@@ -1,10 +1,14 @@
+from django.conf import settings
 from django.urls import include, path
 
 from .views import ProjectDetailView, ProjectEditView
 
-urlpatterns = [
-    path('<int:pk>/', include([
-        path('', ProjectDetailView.as_view(), name='detail'),
-        path('edit/', ProjectEditView.as_view(), name="edit"),
-    ])),
-]
+urlpatterns = []
+
+if settings.PROJECTS_ENABLED:
+    urlpatterns = [
+        path('<int:pk>/', include([
+            path('', ProjectDetailView.as_view(), name='detail'),
+            path('edit/', ProjectEditView.as_view(), name="edit"),
+        ])),
+    ]
diff --git a/opentech/settings/base.py b/opentech/settings/base.py
index cff3aacac..6fa7c5852 100644
--- a/opentech/settings/base.py
+++ b/opentech/settings/base.py
@@ -668,3 +668,9 @@ REST_FRAMEWORK = {
         'rest_framework.permissions.IsAuthenticated',
     )
 }
+
+
+# Projects Feature Flag
+PROJECTS_ENABLED = False
+if env.get('PROJECTS_ENABLED', 'false').lower().strip() == 'true':
+    PROJECTS_ENABLED = True
-- 
GitLab