From c6618c503b9a2320ccb101e7948e7d3646fe7eca Mon Sep 17 00:00:00 2001
From: richard-dds
Date: Tue, 14 Aug 2018 12:54:48 -0400
Subject: [PATCH] Create new template and form field
---
atst/forms/poc.py | 28 ++++++++++++---
atst/routes/requests/jedi_request_flow.py | 9 +++++
js/components/forms/poc.js | 44 +++++++++++++++++++++++
js/index.js | 2 ++
templates/requests/screen-3.html | 36 ++++++++++++-------
tests/factories.py | 1 +
tests/routes/test_request_new.py | 40 +++++++++++++++++++++
7 files changed, 142 insertions(+), 18 deletions(-)
create mode 100644 js/components/forms/poc.js
diff --git a/atst/forms/poc.py b/atst/forms/poc.py
index 3dcdc223..02ef76ab 100644
--- a/atst/forms/poc.py
+++ b/atst/forms/poc.py
@@ -1,16 +1,34 @@
-from wtforms.fields import StringField
+from wtforms.fields import StringField, RadioField
from wtforms.fields.html5 import EmailField
-from wtforms.validators import Required, Email, Length
+from wtforms.validators import Required, Email, Length, Optional
from .forms import ValidatedForm
from .validators import IsNumber
class POCForm(ValidatedForm):
- fname_poc = StringField("First Name", validators=[Required()])
- lname_poc = StringField("Last Name", validators=[Required()])
+ def validate(self, *args, **kwargs):
+ if self.am_poc.data == "yes":
+ self.fname_poc.validators.insert(0, Optional())
+ self.lname_poc.validators.insert(0, Optional())
+ self.email_poc.validators.insert(0, Optional())
+ self.dodid_poc.validators.insert(0, Optional())
- email_poc = EmailField("Email Address", validators=[Required(), Email()])
+ return super(POCForm, self).validate(*args, **kwargs)
+
+
+ am_poc = RadioField(
+ "I am the technical POC.",
+ choices=[("yes", "Yes"), ("no", "No")],
+ default="no",
+ validators=[Required()],
+ )
+
+ fname_poc = StringField("POC First Name", validators=[Required()])
+
+ lname_poc = StringField("POC Last Name", validators=[Required()])
+
+ email_poc = EmailField("POC Email Address", validators=[Required(), Email()])
dodid_poc = StringField(
"DOD ID", validators=[Required(), Length(min=10), IsNumber()]
diff --git a/atst/routes/requests/jedi_request_flow.py b/atst/routes/requests/jedi_request_flow.py
index 79506916..ce9b3d01 100644
--- a/atst/routes/requests/jedi_request_flow.py
+++ b/atst/routes/requests/jedi_request_flow.py
@@ -130,5 +130,14 @@ class JEDIRequestFlow(object):
self.request_id = request.id
def update_request(self, section, data):
+ if section == "primary_poc":
+ if data.get("am_poc") == "yes":
+ data = {
+ "dodid_poc": self.existing_request.creator.dod_id,
+ "fname_poc": self.existing_request.creator.first_name,
+ "lname_poc": self.existing_request.creator.last_name,
+ "email_poc": self.existing_request.creator.email
+ }
+
request_data = {section: data}
Requests.update(self.request_id, request_data)
diff --git a/js/components/forms/poc.js b/js/components/forms/poc.js
new file mode 100644
index 00000000..0be9fb1f
--- /dev/null
+++ b/js/components/forms/poc.js
@@ -0,0 +1,44 @@
+import optionsinput from '../options_input'
+import textinput from '../text_input'
+
+export default {
+ name: 'poc',
+
+ components: {
+ optionsinput,
+ textinput,
+ },
+
+ props: {
+ initialData: {
+ type: Object,
+ default: () => ({})
+ }
+ },
+
+ data: function () {
+ return {
+ am_poc: "no"
+ }
+ },
+
+ mounted: function () {
+ this.$root.$on('field-change', this.handleFieldChange)
+ },
+
+ computed: {
+ amPOC: function () {
+ return this.am_poc === 'yes'
+ },
+ },
+
+ methods: {
+ handleFieldChange: function (event) {
+ const { value, name } = event
+ console.log(value, name)
+ if (typeof this[name] !== undefined) {
+ this[name] = value
+ }
+ },
+ }
+}
diff --git a/js/index.js b/js/index.js
index 5cf47a60..84b90c96 100644
--- a/js/index.js
+++ b/js/index.js
@@ -5,6 +5,7 @@ import VTooltip from 'v-tooltip'
import optionsinput from './components/options_input'
import textinput from './components/text_input'
import DetailsOfUse from './components/forms/details_of_use'
+import poc from './components/forms/poc'
Vue.use(VTooltip)
@@ -15,6 +16,7 @@ const app = new Vue({
optionsinput,
textinput,
DetailsOfUse,
+ poc,
},
methods: {
closeModal: function(name) {
diff --git a/templates/requests/screen-3.html b/templates/requests/screen-3.html
index 2f03c8bf..41c632dc 100644
--- a/templates/requests/screen-3.html
+++ b/templates/requests/screen-3.html
@@ -2,6 +2,7 @@
{% from "components/alert.html" import Alert %}
{% from "components/text_input.html" import TextInput %}
+{% from "components/options_input.html" import OptionsInput %}
{% block subtitle %}
Designate a Workspace Owner
@@ -16,20 +17,29 @@
) }}
{% endif %}
-The Workspace Owner is the primary point of contact and technical administrator of the JEDI Workspace and will have the following responsibilities:
-
- - Organize your cloud-hosted systems into projects and environments
- - Add users to this workspace and manage members
- - Manage access to the JEDI Cloud service provider’s portal
-
-
+
+
+
Please designate a Primary Point of Contact that will be responsible for owning the workspace in the JEDI Cloud.
+
The Point of Contact will become the primary owner of the workspace created to use the JEDI Cloud. As a workspace owner, this person will have the ability to:
+
+ - Create multiple application stacks and environments in the workspace to access the commercial cloud service provider portal
+ - Add and manage users in the workspace
+ - View the budget and billing history related to this workspace
+ - Manage access to the Cloud Service Provider's Console
+ - Transfer Workspace ownership to another person
+
+
This POC may be you.
+
-
This person must be a DoD employee (not a contractor).
-
The Workspace Owner may be you. You will be able to add other administrators later. This person will be invited via email once your request is approved.
+ {{ OptionsInput(f.am_poc) }}
-{{ TextInput(f.fname_poc,placeholder='First Name') }}
-{{ TextInput(f.lname_poc,placeholder='Last Name') }}
-{{ TextInput(f.email_poc,placeholder='jane@mail.mil', validation='email') }}
-{{ TextInput(f.dodid_poc,placeholder='10-digit number on the back of the CAC', validation='dodId') }}
+
+ {{ TextInput(f.fname_poc,placeholder='First Name') }}
+ {{ TextInput(f.lname_poc,placeholder='Last Name') }}
+ {{ TextInput(f.email_poc,placeholder='jane@mail.mil', validation='email') }}
+ {{ TextInput(f.dodid_poc,placeholder='10-digit number on the back of the CAC', validation='dodId') }}
+
+
+
{% endblock %}
diff --git a/tests/factories.py b/tests/factories.py
index 74124f95..41996d47 100644
--- a/tests/factories.py
+++ b/tests/factories.py
@@ -56,6 +56,7 @@ class RequestFactory(factory.alchemy.SQLAlchemyModelFactory):
def build_request_body(cls, user, dollar_value=1000000):
return {
"primary_poc": {
+ "am_poc": "no",
"dodid_poc": user.dod_id,
"email_poc": user.email,
"fname_poc": user.first_name,
diff --git a/tests/routes/test_request_new.py b/tests/routes/test_request_new.py
index fadf0ce9..217882c4 100644
--- a/tests/routes/test_request_new.py
+++ b/tests/routes/test_request_new.py
@@ -4,6 +4,7 @@ import urllib
from tests.mocks import MOCK_USER, MOCK_REQUEST
from tests.factories import RequestFactory, UserFactory
from atst.domain.roles import Roles
+from atst.domain.requests import Requests
ERROR_CLASS = "alert--error"
@@ -103,6 +104,45 @@ def test_non_creator_info_is_not_autopopulated(monkeypatch, client, user_session
assert not user.last_name in body
assert not user.email in body
+def test_am_poc_causes_poc_to_be_autopopulated(client, user_session):
+ creator = UserFactory.create()
+ user_session(creator)
+ request = RequestFactory.create(creator=creator, body={})
+ client.post(
+ "/requests/new/3/{}".format(request.id),
+ headers={"Content-Type": "application/x-www-form-urlencoded"},
+ data="am_poc=yes",
+ )
+ request = Requests.get(request.id)
+ assert request.body["primary_poc"]["dodid_poc"] == creator.dod_id
+
+
+def test_not_am_poc_requires_poc_info_to_be_completed(client, user_session):
+ creator = UserFactory.create()
+ user_session(creator)
+ request = RequestFactory.create(creator=creator, body={})
+ response = client.post(
+ "/requests/new/3/{}".format(request.id),
+ headers={"Content-Type": "application/x-www-form-urlencoded"},
+ data="am_poc=no",
+ )
+ assert ERROR_CLASS in response.data.decode()
+
+
+# def test_not_am_poc_allows_user_to_fill_in_poc_info(client, user_session):
+# creator = UserFactory.create()
+# user_session(creator)
+# request = RequestFactory.create(creator=creator, body={})
+# client.post(
+# "/requests/new/3/{}".format(request.id),
+# headers={"Content-Type": "application/x-www-form-urlencoded"},
+# data="am_poc=yes",
+# )
+
+# assert "Location" not in response.headers
+# request = Requests.get(request.id)
+
+
def test_can_review_data(user_session, client):
creator = UserFactory.create()
user_session(creator)