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:

- -

+ +
+

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') }} + +
+
{% 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)