From 8dbb3b32a22759356d34572b1c8b57c1bdcf9812 Mon Sep 17 00:00:00 2001 From: hmbrink Date: Fri, 17 Jan 2020 17:02:15 -0500 Subject: [PATCH 01/24] Portfolio Spacing & Layout Portfolio adjustments: -Cleaned up container margins/padding -Added max-width to header and Settings section -Refined Portfolio header and nav links Other adjustments: -Reduced font size of side nav links --- styles/components/_global_layout.scss | 3 +- styles/components/_portfolio_layout.scss | 37 ++++++++++++++++++------ styles/components/_sticky_cta.scss | 3 +- styles/core/_variables.scss | 2 +- styles/elements/_sidenav.scss | 4 +-- 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/styles/components/_global_layout.scss b/styles/components/_global_layout.scss index 5ad748d1..22de84e8 100644 --- a/styles/components/_global_layout.scss +++ b/styles/components/_global_layout.scss @@ -22,14 +22,13 @@ body { padding-bottom: $footer-height * 2.5; .global-panel-container { - margin: $gap; flex-grow: 1; -ms-flex-negative: 1; top: $usa-banner-height + $topbar-height; position: relative; + padding: 0 $spacing-large; @include media($medium-screen) { - margin: $gap * 2; top: $usa-banner-height + $topbar-height; } } diff --git a/styles/components/_portfolio_layout.scss b/styles/components/_portfolio_layout.scss index 81a15b69..9dc9ee6a 100644 --- a/styles/components/_portfolio_layout.scss +++ b/styles/components/_portfolio_layout.scss @@ -4,25 +4,29 @@ min-height: 500px; } - margin-left: 2 * $gap; + .col.col--grow { + padding: 0; + } } .portfolio-header { flex-direction: column; + align-items: center; + margin: $spacing-medium 0; + max-width: 90rem; @include media($small-screen) { flex-direction: row; } - margin-bottom: $gap * 1; - .col--grow { overflow: inherit; } &__name { @include h1; + padding-right: $spacing-medium; h1 { - margin: 0 $gap ($gap * 2) 0; + margin: 0; font-size: 3.5rem; } @@ -30,6 +34,7 @@ font-size: $small-font-size; margin: 0 0 (-$gap * 0.5); color: $color-gray-medium; + max-width: 100%; } } @@ -38,9 +43,15 @@ font-size: $small-font-size; .icon-link { - padding: $gap; + padding: 0; border-radius: 0; color: $color-blue-darkest; + min-width: 10rem; + min-height: 10rem; + + .col { + margin: 0 auto; + } &:hover { background-color: $color-aqua-lightest; @@ -82,11 +93,19 @@ margin-bottom: 3 * $gap; } -.portfolio-content { - margin: (4 * $gap) $gap 0 $gap; +.portfolio-admin { + margin: $spacing-large 0; + max-width: 90rem; +} +.portfolio-content { .panel { padding-bottom: 2rem; + max-width: 90rem; + } + + hr { + max-width: 90rem; } a.add-new-button { @@ -289,8 +308,8 @@ } .portfolio-funding { - padding: 2 * $gap; - padding-top: 0; + max-width: 90rem; + margin: $spacing-large 0; .panel { @include shadow-panel; diff --git a/styles/components/_sticky_cta.scss b/styles/components/_sticky_cta.scss index a62dc326..12d67d8e 100644 --- a/styles/components/_sticky_cta.scss +++ b/styles/components/_sticky_cta.scss @@ -20,9 +20,10 @@ .sticky-cta-container { display: flex; align-items: center; + max-width: 90rem; .usa-button { - margin: $gap $gap * 1.5 $gap 0; + margin: 0; width: 20rem; height: 3.2rem; font-size: $small-font-size; diff --git a/styles/core/_variables.scss b/styles/core/_variables.scss index 122739c4..70524e97 100644 --- a/styles/core/_variables.scss +++ b/styles/core/_variables.scss @@ -189,4 +189,4 @@ $spacing-x-small: 0.5rem; $spacing-small: 1rem; $spacing-md-small: 1.5rem; $spacing-medium: 2rem; -$spacing-large: 3rem; +$spacing-large: 4rem; diff --git a/styles/elements/_sidenav.scss b/styles/elements/_sidenav.scss index 23a4f05f..81a55b4e 100644 --- a/styles/elements/_sidenav.scss +++ b/styles/elements/_sidenav.scss @@ -113,8 +113,8 @@ text-overflow: ellipsis; &--active { - @include h4; - + font-size: $base-font-size; + font-weight: $font-bold; background-color: $color-aqua-lightest !important; color: $color-primary-darker !important; box-shadow: inset ($gap / 2) 0 0 0 $color-primary-darker; From 8c0e88c5c49a1fa4c852c48728f88f86b59ddea5 Mon Sep 17 00:00:00 2001 From: hmbrink Date: Mon, 20 Jan 2020 17:03:18 -0500 Subject: [PATCH 02/24] Topbar, Portfolio Header, & Content alignment --- styles/components/_empty_state.scss | 23 +++++++++++++++------- styles/components/_global_layout.scss | 1 + styles/components/_portfolio_layout.scss | 25 +++++++++++++++++------- styles/components/_sticky_cta.scss | 7 ++++--- styles/components/_topbar.scss | 3 ++- styles/core/_variables.scss | 2 +- styles/elements/_panels.scss | 10 ++++------ styles/sections/_home.scss | 8 ++++---- templates/portfolios/admin.html | 2 +- templates/user/edit.html | 2 +- 10 files changed, 52 insertions(+), 31 deletions(-) diff --git a/styles/components/_empty_state.scss b/styles/components/_empty_state.scss index b0b73b16..1259f438 100644 --- a/styles/components/_empty_state.scss +++ b/styles/components/_empty_state.scss @@ -1,8 +1,6 @@ .empty-state { - padding: $gap * 3; - max-width: 100%; - background-color: $color-gray-lightest; - margin-top: $gap * 5; + max-width: $max-panel-width; + background-color: #F6F6F7; &--white { background-color: $color-white; @@ -18,17 +16,28 @@ margin-top: 3rem; } + h3 { + margin: 0 0 1rem; + padding: 3.2rem 2.4rem 0; + } + + p { + margin: 0; + padding: 0 $gap * 3; + } + hr { - margin-left: -$gap * 3; - margin-right: -$gap * 3; + margin: $gap * 4 0 0; } &__footer { text-align: center; + background-color: $color-gray-lightest; + padding: $gap * 3; a.usa-button { width: 60%; - display: inline-block; + margin: 0 auto; } } } diff --git a/styles/components/_global_layout.scss b/styles/components/_global_layout.scss index 22de84e8..ff84b3a0 100644 --- a/styles/components/_global_layout.scss +++ b/styles/components/_global_layout.scss @@ -28,6 +28,7 @@ body { position: relative; padding: 0 $spacing-large; + @include media($medium-screen) { top: $usa-banner-height + $topbar-height; } diff --git a/styles/components/_portfolio_layout.scss b/styles/components/_portfolio_layout.scss index 9dc9ee6a..00beae67 100644 --- a/styles/components/_portfolio_layout.scss +++ b/styles/components/_portfolio_layout.scss @@ -5,15 +5,16 @@ } .col.col--grow { + position: relative; padding: 0; } } .portfolio-header { flex-direction: column; - align-items: center; - margin: $spacing-medium 0; - max-width: 90rem; + margin: $gap * 2 0; + max-width: $max-panel-width; + @include media($small-screen) { flex-direction: row; } @@ -25,6 +26,12 @@ &__name { @include h1; padding-right: $spacing-medium; + position: absolute; + top: 50%; + left: 0; + -webkit-transform: translateX(0%) translateY(-50%); + transform: translateX(0%) translateY(-50%); + h1 { margin: 0; font-size: 3.5rem; @@ -64,6 +71,7 @@ &.active { color: $color-blue; background-color: $color-gray-lightest; + text-decoration: none; &:hover { background-color: $color-aqua-lightest; @@ -95,17 +103,17 @@ .portfolio-admin { margin: $spacing-large 0; - max-width: 90rem; + max-width: $max-panel-width; } .portfolio-content { .panel { padding-bottom: 2rem; - max-width: 90rem; + max-width: $max-panel-width; } hr { - max-width: 90rem; + max-width: $max-panel-width; } a.add-new-button { @@ -263,6 +271,7 @@ .portfolio-applications { margin-top: $gap * 5; + max-width: $max-panel-width; &__header { &--title { @@ -308,7 +317,7 @@ } .portfolio-funding { - max-width: 90rem; + max-width: $max-panel-width; margin: $spacing-large 0; .panel { @@ -378,6 +387,8 @@ } .portfolio-reports { + max-width: $max-panel-width; + &__header { margin-bottom: 4 * $gap; diff --git a/styles/components/_sticky_cta.scss b/styles/components/_sticky_cta.scss index 12d67d8e..c3a7b0ea 100644 --- a/styles/components/_sticky_cta.scss +++ b/styles/components/_sticky_cta.scss @@ -24,9 +24,6 @@ .usa-button { margin: 0; - width: 20rem; - height: 3.2rem; - font-size: $small-font-size; } } @@ -43,6 +40,10 @@ &-buttons { display: flex; + a { + font-size: 1.5rem; + } + .action-group { margin: 0; diff --git a/styles/components/_topbar.scss b/styles/components/_topbar.scss index a64a1344..7f7a3e6d 100644 --- a/styles/components/_topbar.scss +++ b/styles/components/_topbar.scss @@ -4,14 +4,15 @@ height: $topbar-height; position: fixed; top: $usa-banner-height; - width: 100%; z-index: 10; + width: 100%; &__navigation { display: flex; flex-direction: row; align-items: stretch; justify-content: space-between; + max-width: 1180px; a { color: $color-white; diff --git a/styles/core/_variables.scss b/styles/core/_variables.scss index 70524e97..feb245ad 100644 --- a/styles/core/_variables.scss +++ b/styles/core/_variables.scss @@ -16,7 +16,7 @@ $footer-height: 5rem; $usa-banner-height: 2.8rem; $sidenav-expanded-width: 25rem; $sidenav-collapsed-width: 10rem; -$max-panel-width: 80rem; +$max-panel-width: 90rem; $home-pg-icon-width: 6rem; /* diff --git a/styles/elements/_panels.scss b/styles/elements/_panels.scss index 8ecd36c6..df681767 100644 --- a/styles/elements/_panels.scss +++ b/styles/elements/_panels.scss @@ -19,10 +19,7 @@ } @mixin panel-margin { - margin-top: 0; - margin-left: 0; - margin-right: 0; - margin-bottom: $site-margins-mobile * 6; + margin: $spacing-large 0; @include media($medium-screen) { margin-bottom: $site-margins * 8; @@ -56,9 +53,10 @@ @include panel-theme-default; @include panel-margin; @include shadow-panel; + max-width: $max-panel-width; &__content { - padding: $gap * 2; + padding: 3.2rem 2.4rem; } &__body { @@ -66,7 +64,7 @@ } &__heading { - padding: $gap * 2; + padding: 3.2rem 2.4rem; @include media($medium-screen) { padding: $gap * 4; diff --git a/styles/sections/_home.scss b/styles/sections/_home.scss index b0d715d2..936f919c 100644 --- a/styles/sections/_home.scss +++ b/styles/sections/_home.scss @@ -1,12 +1,12 @@ .home { - margin: $gap * 3; + .sticky-cta { margin: -1.6rem -1.6rem 0 -1.6rem; } &__content { - margin: 4rem; - max-width: 900px; + margin: $spacing-large 0; + max-width: $max-panel-width; &--descriptions { .col { @@ -29,7 +29,7 @@ background-color: $color-white; .home-container { - max-width: 90rem; + max-width: $max-panel-width; margin-left: auto; margin-right: auto; margin-bottom: 8rem; diff --git a/templates/portfolios/admin.html b/templates/portfolios/admin.html index 3c2a9b9c..264e40f9 100644 --- a/templates/portfolios/admin.html +++ b/templates/portfolios/admin.html @@ -22,7 +22,7 @@ {{ TextInput(portfolio_form.name, validation="portfolioName", optional=False) }} {{ TextInput(portfolio_form.description, paragraph=True) }}
- {{ SaveButton(text='Save Changes', additional_classes='usa-button-big') }} + {{ SaveButton(text='Save Changes') }}
diff --git a/templates/user/edit.html b/templates/user/edit.html index fc4ac64f..226dc167 100644 --- a/templates/user/edit.html +++ b/templates/user/edit.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {% block content %} -
+
{% include "fragments/flash.html" %} From 4dcd49269f2728e9b8d2e2cfcb649363fc8638ac Mon Sep 17 00:00:00 2001 From: hmbrink Date: Tue, 21 Jan 2020 10:45:40 -0500 Subject: [PATCH 03/24] Topbar testing --- styles/components/_portfolio_layout.scss | 11 ----------- styles/components/_topbar.scss | 8 ++++++++ styles/core/_util.scss | 4 ++++ templates/base_public.html | 2 +- templates/portfolios/new/step_1.html | 8 +++++--- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/styles/components/_portfolio_layout.scss b/styles/components/_portfolio_layout.scss index 00beae67..ee7b1ed1 100644 --- a/styles/components/_portfolio_layout.scss +++ b/styles/components/_portfolio_layout.scss @@ -3,11 +3,6 @@ @include grid-row; min-height: 500px; } - - .col.col--grow { - position: relative; - padding: 0; - } } .portfolio-header { @@ -25,12 +20,6 @@ &__name { @include h1; - padding-right: $spacing-medium; - position: absolute; - top: 50%; - left: 0; - -webkit-transform: translateX(0%) translateY(-50%); - transform: translateX(0%) translateY(-50%); h1 { margin: 0; diff --git a/styles/components/_topbar.scss b/styles/components/_topbar.scss index 7f7a3e6d..03a74f55 100644 --- a/styles/components/_topbar.scss +++ b/styles/components/_topbar.scss @@ -65,3 +65,11 @@ justify-content: flex-end; } } + +.login-topbar .topbar__navigation { + max-width: 100%; +} + +.login-topbar .topbar__context .topbar__link-icon { + margin: 0 0 0 0.8rem; +} diff --git a/styles/core/_util.scss b/styles/core/_util.scss index 5203da45..0790a121 100644 --- a/styles/core/_util.scss +++ b/styles/core/_util.scss @@ -94,3 +94,7 @@ hr { margin: ($gap * 3) ($site-margins * -4); } } + +.usa-section { + padding: 0; +} diff --git a/templates/base_public.html b/templates/base_public.html index 7b872471..07447633 100644 --- a/templates/base_public.html +++ b/templates/base_public.html @@ -17,7 +17,7 @@
{% include 'components/usa_header.html' %} - {% include 'navigation/topbar.html' %} + {% block content %}{% endblock %} diff --git a/templates/portfolios/new/step_1.html b/templates/portfolios/new/step_1.html index 4a499821..abc6d25e 100644 --- a/templates/portfolios/new/step_1.html +++ b/templates/portfolios/new/step_1.html @@ -10,9 +10,11 @@
{% include "fragments/flash.html" %} -
-

{{ "portfolios.header" | translate }}

-

{{ "New Portfolio" }}

+
+
+

{{ "portfolios.header" | translate }}

+

{{ "New Portfolio" }}

+
{{ StickyCTA(text="Create New Portfolio") }} From 32451c69afdf0efdb6de5e20d5ad3c6c2cd2e266 Mon Sep 17 00:00:00 2001 From: hmbrink Date: Tue, 21 Jan 2020 15:27:30 -0500 Subject: [PATCH 04/24] Topbar max-width --- styles/components/_topbar.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/styles/components/_topbar.scss b/styles/components/_topbar.scss index 03a74f55..c536fb01 100644 --- a/styles/components/_topbar.scss +++ b/styles/components/_topbar.scss @@ -12,7 +12,6 @@ flex-direction: row; align-items: stretch; justify-content: space-between; - max-width: 1180px; a { color: $color-white; From 4fd83be37f69a228ac0f79d66c77dbf2994fbb7e Mon Sep 17 00:00:00 2001 From: hmbrink Date: Tue, 21 Jan 2020 15:31:48 -0500 Subject: [PATCH 05/24] Portfolio Header --- styles/components/_portfolio_layout.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/styles/components/_portfolio_layout.scss b/styles/components/_portfolio_layout.scss index ee7b1ed1..58039596 100644 --- a/styles/components/_portfolio_layout.scss +++ b/styles/components/_portfolio_layout.scss @@ -16,10 +16,14 @@ .col--grow { overflow: inherit; + display: table; + min-height: 10rem; } &__name { @include h1; + display: table-cell; + vertical-align: middle; h1 { margin: 0; From ae3144c82ff432eea34d8252ca759f65206a9751 Mon Sep 17 00:00:00 2001 From: hmbrink Date: Tue, 21 Jan 2020 15:41:03 -0500 Subject: [PATCH 06/24] removed extra grid column padding --- styles/core/_grid.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/styles/core/_grid.scss b/styles/core/_grid.scss index d060198d..d22a866f 100644 --- a/styles/core/_grid.scss +++ b/styles/core/_grid.scss @@ -41,7 +41,6 @@ &.col--grow { flex: 1 auto; - padding-right: $spacing-small; } &.col--half { From 16db93c2daa38025c798a525d1d4bf3f27843c80 Mon Sep 17 00:00:00 2001 From: hmbrink Date: Wed, 22 Jan 2020 14:25:56 -0500 Subject: [PATCH 07/24] Topbar navigation --- styles/components/_empty_state.scss | 2 +- styles/components/_footer.scss | 7 ++++--- styles/components/_global_layout.scss | 1 - styles/components/_topbar.scss | 5 +++-- styles/sections/_home.scss | 1 - 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/styles/components/_empty_state.scss b/styles/components/_empty_state.scss index 1259f438..71c9e742 100644 --- a/styles/components/_empty_state.scss +++ b/styles/components/_empty_state.scss @@ -1,6 +1,6 @@ .empty-state { max-width: $max-panel-width; - background-color: #F6F6F7; + background-color: #f6f6f7; &--white { background-color: $color-white; diff --git a/styles/components/_footer.scss b/styles/components/_footer.scss index bb248e4d..bd2ede65 100644 --- a/styles/components/_footer.scss +++ b/styles/components/_footer.scss @@ -3,9 +3,7 @@ background-color: $color-white; border-top: 1px solid $color-gray-lightest; display: flex; - flex-direction: row-reverse; align-items: center; - padding: $gap * 1.5; position: fixed; left: 0; bottom: 0; @@ -13,8 +11,11 @@ height: $footer-height; color: $color-gray-dark; font-size: 1.5rem; + padding: 0 $gap * 1.5; &__login { - padding-left: 0.8rem; + width: 100%; + max-width: 1165px; + text-align: right; } } diff --git a/styles/components/_global_layout.scss b/styles/components/_global_layout.scss index ff84b3a0..22de84e8 100644 --- a/styles/components/_global_layout.scss +++ b/styles/components/_global_layout.scss @@ -28,7 +28,6 @@ body { position: relative; padding: 0 $spacing-large; - @include media($medium-screen) { top: $usa-banner-height + $topbar-height; } diff --git a/styles/components/_topbar.scss b/styles/components/_topbar.scss index c536fb01..c61872ae 100644 --- a/styles/components/_topbar.scss +++ b/styles/components/_topbar.scss @@ -12,6 +12,7 @@ flex-direction: row; align-items: stretch; justify-content: space-between; + max-width: 1180px; a { color: $color-white; @@ -66,9 +67,9 @@ } .login-topbar .topbar__navigation { - max-width: 100%; + max-width: 100%; } .login-topbar .topbar__context .topbar__link-icon { - margin: 0 0 0 0.8rem; + margin: 0 0 0 0.8rem; } diff --git a/styles/sections/_home.scss b/styles/sections/_home.scss index 936f919c..23d9d2e1 100644 --- a/styles/sections/_home.scss +++ b/styles/sections/_home.scss @@ -1,5 +1,4 @@ .home { - .sticky-cta { margin: -1.6rem -1.6rem 0 -1.6rem; } From 01341be95b6dc542b4570fe66f15b09618b0a2b7 Mon Sep 17 00:00:00 2001 From: hmbrink Date: Wed, 22 Jan 2020 14:34:23 -0500 Subject: [PATCH 08/24] Profile max-width --- styles/components/_global_layout.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/styles/components/_global_layout.scss b/styles/components/_global_layout.scss index 22de84e8..2f5e0c4a 100644 --- a/styles/components/_global_layout.scss +++ b/styles/components/_global_layout.scss @@ -31,5 +31,9 @@ body { @include media($medium-screen) { top: $usa-banner-height + $topbar-height; } + + .user-edit { + max-width: $max-panel-width; + } } } From 0f2ba887d9d60c24f1c09c3fcfffae0930cf2a4a Mon Sep 17 00:00:00 2001 From: hmbrink Date: Thu, 23 Jan 2020 13:13:04 -0500 Subject: [PATCH 09/24] Large spacing variable --- styles/components/_footer.scss | 2 +- styles/components/_global_layout.scss | 2 +- styles/components/_portfolio_layout.scss | 4 ++-- styles/components/_topbar.scss | 2 +- styles/core/_variables.scss | 1 + styles/sections/_home.scss | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/styles/components/_footer.scss b/styles/components/_footer.scss index bd2ede65..881ab9a7 100644 --- a/styles/components/_footer.scss +++ b/styles/components/_footer.scss @@ -15,7 +15,7 @@ &__login { width: 100%; - max-width: 1165px; + max-width: 1175px; text-align: right; } } diff --git a/styles/components/_global_layout.scss b/styles/components/_global_layout.scss index 2f5e0c4a..9b21b41f 100644 --- a/styles/components/_global_layout.scss +++ b/styles/components/_global_layout.scss @@ -26,7 +26,7 @@ body { -ms-flex-negative: 1; top: $usa-banner-height + $topbar-height; position: relative; - padding: 0 $spacing-large; + padding: 0 $large-spacing; @include media($medium-screen) { top: $usa-banner-height + $topbar-height; diff --git a/styles/components/_portfolio_layout.scss b/styles/components/_portfolio_layout.scss index 58039596..af083468 100644 --- a/styles/components/_portfolio_layout.scss +++ b/styles/components/_portfolio_layout.scss @@ -95,7 +95,7 @@ } .portfolio-admin { - margin: $spacing-large 0; + margin: $large-spacing 0; max-width: $max-panel-width; } @@ -311,7 +311,7 @@ .portfolio-funding { max-width: $max-panel-width; - margin: $spacing-large 0; + margin: $large-spacing 0; .panel { @include shadow-panel; diff --git a/styles/components/_topbar.scss b/styles/components/_topbar.scss index c61872ae..6d84f426 100644 --- a/styles/components/_topbar.scss +++ b/styles/components/_topbar.scss @@ -12,7 +12,7 @@ flex-direction: row; align-items: stretch; justify-content: space-between; - max-width: 1180px; + max-width: 1190px; a { color: $color-white; diff --git a/styles/core/_variables.scss b/styles/core/_variables.scss index feb245ad..12657ca4 100644 --- a/styles/core/_variables.scss +++ b/styles/core/_variables.scss @@ -18,6 +18,7 @@ $sidenav-expanded-width: 25rem; $sidenav-collapsed-width: 10rem; $max-panel-width: 90rem; $home-pg-icon-width: 6rem; +$large-spacing: 4rem; /* * USWDS Variables diff --git a/styles/sections/_home.scss b/styles/sections/_home.scss index 23d9d2e1..52636a61 100644 --- a/styles/sections/_home.scss +++ b/styles/sections/_home.scss @@ -4,7 +4,7 @@ } &__content { - margin: $spacing-large 0; + margin: $large-spacing 0; max-width: $max-panel-width; &--descriptions { From 84d0a326943cbfd9a7d73e32e1719f0d7ba88a39 Mon Sep 17 00:00:00 2001 From: leigh-mil Date: Thu, 23 Jan 2020 16:25:03 -0500 Subject: [PATCH 10/24] Update TO form to account for new TO rules: alpha numeric, between 13 and 17 characters, dashes should be stripped, and coerce to uppercase --- atst/forms/task_order.py | 20 ++++++++++++++-- tests/domain/test_task_orders.py | 12 ++++++++-- tests/forms/test_task_order.py | 34 ++++++++++++++++++++++++++++ tests/routes/task_orders/test_new.py | 8 +++---- tests/test_access.py | 2 +- 5 files changed, 67 insertions(+), 9 deletions(-) diff --git a/atst/forms/task_order.py b/atst/forms/task_order.py index 6b209bf8..a1f82784 100644 --- a/atst/forms/task_order.py +++ b/atst/forms/task_order.py @@ -10,11 +10,13 @@ from wtforms.fields.html5 import DateField from wtforms.validators import ( Required, Length, + Optional, NumberRange, ValidationError, ) from flask_wtf import FlaskForm import numbers + from atst.forms.validators import Number, AlphaNumeric from .data import JEDI_CLIN_TYPES @@ -60,6 +62,20 @@ def validate_date_in_range(form, field): ) +def remove_dashes(value): + if value: + return value.replace("-", "") + else: + return None + + +def coerce_upper(value): + if value: + return value.upper() + else: + return None + + class CLINForm(FlaskForm): jedi_clin_type = SelectField( translate("task_orders.form.clin_type_label"), @@ -149,8 +165,8 @@ class AttachmentForm(BaseForm): class TaskOrderForm(BaseForm): number = StringField( label=translate("forms.task_order.number_description"), - filters=[remove_empty_string], - validators=[Number(), Length(max=13)], + filters=[remove_empty_string, remove_dashes, coerce_upper], + validators=[AlphaNumeric(), Length(min=13, max=17), Optional()], ) pdf = FormField( AttachmentForm, diff --git a/tests/domain/test_task_orders.py b/tests/domain/test_task_orders.py index 49b9bae6..42da74e6 100644 --- a/tests/domain/test_task_orders.py +++ b/tests/domain/test_task_orders.py @@ -71,7 +71,7 @@ def test_update_adds_clins(): def test_update_does_not_duplicate_clins(): task_order = TaskOrderFactory.create( - number="3453453456", create_clins=[{"number": "123"}, {"number": "456"}] + number="3453453456123", create_clins=[{"number": "123"}, {"number": "456"}] ) clins = [ { @@ -93,7 +93,7 @@ def test_update_does_not_duplicate_clins(): ] task_order = TaskOrders.update( task_order_id=task_order.id, - number="0000000000", + number="0000000000000", clins=clins, pdf={"filename": "sample.pdf", "object_name": "1234567"}, ) @@ -170,3 +170,11 @@ def test_update_enforces_unique_number(): dupe_task_order = TaskOrderFactory.create() with pytest.raises(AlreadyExistsError): TaskOrders.update(dupe_task_order.id, task_order.number, [], None) + + +def test_allows_alphanumeric_number(): + portfolio = PortfolioFactory.create() + valid_to_numbers = ["1234567890123", "ABC1234567890"] + + for number in valid_to_numbers: + assert TaskOrders.create(portfolio.id, number, [], None) diff --git a/tests/forms/test_task_order.py b/tests/forms/test_task_order.py index 97759c81..ae4fd3c6 100644 --- a/tests/forms/test_task_order.py +++ b/tests/forms/test_task_order.py @@ -112,3 +112,37 @@ def test_no_number(): http_request_form_data = {} form = TaskOrderForm(http_request_form_data) assert form.data["number"] is None + + +def test_number_allows_alphanumeric(): + valid_to_numbers = ["1234567890123", "ABC1234567890"] + + for number in valid_to_numbers: + form = TaskOrderForm({"number": number}) + assert form.validate() + + +def test_number_allows_between_13_and_17_characters(): + valid_to_numbers = ["123456789012345", "ABCDEFG1234567890"] + + for number in valid_to_numbers: + form = TaskOrderForm({"number": number}) + assert form.validate() + + +def test_number_strips_dashes(): + valid_to_numbers = ["123-456789-012345", "ABCD-EFG12345-67890"] + + for number in valid_to_numbers: + form = TaskOrderForm({"number": number}) + assert form.validate() + assert not "-" in form.number.data + + +def test_number_case_coerces_all_caps(): + valid_to_numbers = ["12345678012345", "AbcEFg1234567890"] + + for number in valid_to_numbers: + form = TaskOrderForm({"number": number}) + assert form.validate() + assert form.number.data == number.upper() diff --git a/tests/routes/task_orders/test_new.py b/tests/routes/task_orders/test_new.py index 0aef88ed..8390e187 100644 --- a/tests/routes/task_orders/test_new.py +++ b/tests/routes/task_orders/test_new.py @@ -158,7 +158,7 @@ def test_task_orders_form_step_two_add_number(client, user_session, task_order): def test_task_orders_submit_form_step_two_add_number(client, user_session, task_order): user_session(task_order.portfolio.owner) - form_data = {"number": "1234567890"} + form_data = {"number": "abc-1234567890"} response = client.post( url_for( "task_orders.submit_form_step_two_add_number", task_order_id=task_order.id @@ -167,7 +167,7 @@ def test_task_orders_submit_form_step_two_add_number(client, user_session, task_ ) assert response.status_code == 302 - assert task_order.number == "1234567890" + assert task_order.number == "ABC1234567890" # pragma: allowlist secret def test_task_orders_submit_form_step_two_enforces_unique_number( @@ -194,7 +194,7 @@ def test_task_orders_submit_form_step_two_add_number_existing_to( client, user_session, task_order ): user_session(task_order.portfolio.owner) - form_data = {"number": "0000000000"} + form_data = {"number": "0000000000000"} original_number = task_order.number response = client.post( url_for( @@ -203,7 +203,7 @@ def test_task_orders_submit_form_step_two_add_number_existing_to( data=form_data, ) assert response.status_code == 302 - assert task_order.number == "0000000000" + assert task_order.number == "0000000000000" assert task_order.number != original_number diff --git a/tests/test_access.py b/tests/test_access.py index b0dac527..f8879024 100644 --- a/tests/test_access.py +++ b/tests/test_access.py @@ -663,7 +663,7 @@ def test_task_orders_new_get_routes(get_url_assert_status): def test_task_orders_new_post_routes(post_url_assert_status): post_routes = [ ("task_orders.submit_form_step_one_add_pdf", {"pdf": ""}), - ("task_orders.submit_form_step_two_add_number", {"number": "1234567890"}), + ("task_orders.submit_form_step_two_add_number", {"number": "1234567890123"}), ( "task_orders.submit_form_step_three_add_clins", { From b20e2971d7b839bd1b9e38d9f737dc68238eecda Mon Sep 17 00:00:00 2001 From: leigh-mil Date: Thu, 23 Jan 2020 16:41:09 -0500 Subject: [PATCH 11/24] Update TO number validator to account for dashes and variable character length --- js/components/__tests__/text_input.test.js | 98 ++++++++++++++++++++++ js/lib/input_validations.js | 6 +- tests/render_vue_component.py | 14 ++++ 3 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 js/components/__tests__/text_input.test.js diff --git a/js/components/__tests__/text_input.test.js b/js/components/__tests__/text_input.test.js new file mode 100644 index 00000000..c290b23a --- /dev/null +++ b/js/components/__tests__/text_input.test.js @@ -0,0 +1,98 @@ +import { mount } from '@vue/test-utils' + +import textinput from '../text_input' + +import { makeTestWrapper } from '../../test_utils/component_test_helpers' + +const ToNumberWrapperComponent = makeTestWrapper({ + components: { + textinput, + }, + templatePath: 'text_input_to_number.html', + data: function() { + const { validation, initialValue } = this.initialData + return { validation, initialValue } + }, +}) + +describe('TextInput Validates Correctly', () => { + describe('taskOrderNumber validator', () => { + it('Should initialize with the validator and no validation icon', () => { + const wrapper = mount(ToNumberWrapperComponent, { + propsData: { + name: 'testTextInput', + initialData: { + validation: 'taskOrderNumber', + }, + }, + }) + expect(wrapper.contains('.usa-input--success')).toBe(false) + expect(wrapper.contains('.usa-input--error')).toBe(false) + expect(wrapper.contains('.usa-input--validation--taskOrderNumber')).toBe( + true + ) + }) + + it('Should allow valid TO numbers', () => { + const wrapper = mount(ToNumberWrapperComponent, { + propsData: { + name: 'testTextInput', + initialData: { + validation: 'taskOrderNumber', + }, + }, + }) + + var textInputField = wrapper.find('input[id="number"]') + var hiddenField = wrapper.find('input[name="number"]') + const validToNumbers = [ + '12345678901234567', + '1234567890123', + 'abc1234567890', // pragma: allowlist secret + 'abc-1234567890', + 'DC12-123-1234567890', + 'fg34-987-1234567890', + ] + + for (const number of validToNumbers) { + // set value to be a valid TO number + textInputField.setValue(number) + // manually trigger change event in hidden fields + hiddenField.trigger('change') + // check for validation classes + expect(wrapper.contains('.usa-input--success')).toBe(true) + expect(wrapper.contains('.usa-input--error')).toBe(false) + } + }) + + it('Should not allow invalid TO numbers', () => { + const wrapper = mount(ToNumberWrapperComponent, { + propsData: { + name: 'testTextInput', + initialData: { + validation: 'taskOrderNumber', + }, + }, + }) + + var textInputField = wrapper.find('input[id="number"]') + var hiddenField = wrapper.find('input[name="number"]') + const invalidToNumbers = [ + '1234567890', + '12345678901234567890', // pragma: allowlist secret + '123:4567890123', + '123_1234567890', + ] + + for (const number of invalidToNumbers) { + // set value to be a valid TO number + textInputField.setValue(number) + // manually trigger change event in hidden fields + hiddenField.trigger('change') + // check for validation classes + expect(wrapper.contains('.usa-input--success')).toBe(false) + expect(wrapper.contains('.usa-input--error')).toBe(true) + } + }) + }) +}) diff --git a/js/lib/input_validations.js b/js/lib/input_validations.js index e2dc03b7..9f113aa6 100644 --- a/js/lib/input_validations.js +++ b/js/lib/input_validations.js @@ -106,9 +106,9 @@ export default { }, taskOrderNumber: { mask: false, - match: /^.{13}$/, - unmask: [], - validationError: 'TO number must be 13 digits', + match: /(^[0-9a-zA-Z]{13,17}$)/, + unmask: ['-'], + validationError: 'TO number must be between 13 and 17 characters', }, usPhone: { mask: [ diff --git a/tests/render_vue_component.py b/tests/render_vue_component.py index 62106a67..49fb6ee9 100644 --- a/tests/render_vue_component.py +++ b/tests/render_vue_component.py @@ -35,6 +35,7 @@ class TaskOrderPdfForm(Form): class TaskOrderForm(Form): pdf = FormField(TaskOrderPdfForm, label="task_order_pdf") + number = StringField(label="task_order_number", default="number") @pytest.fixture @@ -63,6 +64,12 @@ def multi_checkbox_input_macro(env): return getattr(multi_checkbox_template.module, "MultiCheckboxInput") +@pytest.fixture +def text_input_macro(env): + text_input_template = env.get_template("components/text_input.html") + return getattr(text_input_template.module, "TextInput") + + @pytest.fixture def initial_value_form(scope="function"): return InitialValueForm() @@ -170,3 +177,10 @@ def test_make_pop_date_range(env, app): index=1, ) write_template(pop_date_range, "pop_date_range.html") + + +def test_make_text_input_template(text_input_macro, task_order_form): + text_input_to_number = text_input_macro( + task_order_form.number, validation="taskOrderNumber" + ) + write_template(text_input_to_number, "text_input_to_number.html") From 660717017261faa9397898c537dd133d4c852d1f Mon Sep 17 00:00:00 2001 From: leigh-mil Date: Fri, 24 Jan 2020 09:25:17 -0500 Subject: [PATCH 12/24] Refactor to use enums --- atst/forms/task_order.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/atst/forms/task_order.py b/atst/forms/task_order.py index a1f82784..8d40c015 100644 --- a/atst/forms/task_order.py +++ b/atst/forms/task_order.py @@ -63,17 +63,11 @@ def validate_date_in_range(form, field): def remove_dashes(value): - if value: - return value.replace("-", "") - else: - return None + return value.replace("-", "") if value else None def coerce_upper(value): - if value: - return value.upper() - else: - return None + return value.upper() if value else None class CLINForm(FlaskForm): From 08610ffde2ba322d5e411723eef7fe9cf73768c6 Mon Sep 17 00:00:00 2001 From: "Jay R. Newlin (PromptWorks)" Date: Fri, 24 Jan 2020 09:52:19 -0500 Subject: [PATCH 13/24] Added new tests to account for changes to Portfolio Manager (Member) UI --- uitests/Resend_Portfolio_Member_Invite.html | 639 ++++++++++++++++++++ uitests/Revoke_Portfolio_Member_Invite.html | 624 +++++++++++++++++++ 2 files changed, 1263 insertions(+) create mode 100644 uitests/Resend_Portfolio_Member_Invite.html create mode 100644 uitests/Revoke_Portfolio_Member_Invite.html diff --git a/uitests/Resend_Portfolio_Member_Invite.html b/uitests/Resend_Portfolio_Member_Invite.html new file mode 100644 index 00000000..b369438f --- /dev/null +++ b/uitests/Resend_Portfolio_Member_Invite.html @@ -0,0 +1,639 @@ + + + + + + +Resend Portfolio Member Invite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Resend Portfolio Member Invite
waitForPageToLoad
open/login-dev?username=brandon
waitForPageToLoad
waitForElementPresentcss=a[href="/user"] > .topbar__link-label
assertTextcss=a[href="/user"] > .topbar__link-label*Brandon Buchannan*
waitForPageToLoad
waitForElementPresentcss=a[href="/logout"] > .topbar__link-label
clickcss=a[href="/logout"] > .topbar__link-label
waitForPageToLoad
waitForElementPresentcss=.col > .usa-alert.usa-alert-info:nth-of-type(2) > .usa-alert-body > h3.usa-alert-heading
assertTextcss=.col > .usa-alert.usa-alert-info:nth-of-type(2) > .usa-alert-body > h3.usa-alert-heading*Logged out*
waitForPageToLoad
open/login-dev
waitForPageToLoad
waitForElementPresentcss=.home__content > h1
assertTextcss=.home__content > h1JEDI Cloud Services
waitForPageToLoad
waitForElementPresentcss=a[href="/portfolios/new"]
clickcss=a[href="/portfolios/new"]
waitForPageToLoad
waitForElementPresentcss=.portfolio-header__name > h1
assertTextcss=.portfolio-header__name > h1*New Portfolio*
waitForPageToLoad
waitForElementPresentcss=.sticky-cta-text > h3
assertTextcss=.sticky-cta-text > h3*Name and Describe Portfolio*
waitForPageToLoad
waitForElementPresentcss=#name
typecss=#nameTatooine Energy Maintenance Systems ${alphanumeric}
waitForPageToLoad
waitForElementPresentcss=fieldset.usa-input__choices > ul > li:nth-of-type(5) > label
clickcss=fieldset.usa-input__choices > ul > li:nth-of-type(5) > label
waitForPageToLoad
waitForElementPresentcss=input[type="submit"]
clickcss=input[type="submit"]
waitForPageToLoad
waitForElementPresentcss=.empty-state > h3
assertTextcss=.empty-state > h3*You don't have any Applications yet*
waitForPageToLoad
waitForElementPresentcss=.icon.icon--cog > svg
clickcss=.icon.icon--cog > svg
waitForPageToLoad
waitForElementPresentcss=.portfolio-header__name > h1
assertTextcss=.portfolio-header__name > h1*Tatooine Energy Maintenance Systems*
waitForPageToLoad
waitForElementPresentcss=th.table-cell--third
assertElementPresentcss=th.table-cell--third
waitForPageToLoad
waitForElementPresentcss=button.usa-button.usa-button-primary.usa-button-big
assertTextcss=button.usa-button.usa-button-primary.usa-button-bigSave Changes
waitForPageToLoad
waitForElementPresentcss=a.usa-button.usa-button-secondary.add-new-button
clickcss=a.usa-button.usa-button-secondary.add-new-button
waitForPageToLoad
waitForElementPresentcss=#add-portfolio-manager > div > div > div.member-form > h2
assertTextcss=#add-portfolio-manager > div > div > div.member-form > h2*Add Manager*
waitForPageToLoad
waitForElementPresentcss=#user_data-first_name
typecss=#user_data-first_nameBrandon
waitForPageToLoad
waitForElementPresentcss=#user_data-last_name
typecss=#user_data-last_nameBuchannan
waitForPageToLoad
waitForElementPresentcss=#user_data-email
typecss=#user_data-emailjay+brandon@promptworks.com
waitForPageToLoad
waitForElementPresentcss=#user_data-dod_id
typecss=#user_data-dod_id3456789012
waitForPageToLoad
waitForElementPresentcss=input[type="button"]
clickcss=input[type="button"]
waitForPageToLoad
waitForElementPresentcss=#add-portfolio-manager > div > div > div.member-form > h2
assertTextcss=#add-portfolio-manager > div > div > div.member-form > h2*Set Portfolio Permissions*
waitForPageToLoad
waitForElementPresentcss=#perms_app_mgmt-None
clickcss=#perms_app_mgmt-None
waitForPageToLoad
waitForElementPresentcss=#perms_funding-None
clickcss=#perms_funding-None
waitForPageToLoad
waitForElementPresentcss=#perms_reporting-None
clickcss=#perms_reporting-None
waitForPageToLoad
waitForElementPresentcss=#perms_portfolio_mgmt-None
typecss=#perms_portfolio_mgmt-Noneedit_portfolio_admin
waitForPageToLoad
waitForElementPresentcss=input[type="submit"].action-group__action
clickcss=input[type="submit"].action-group__action
waitForPageToLoad
waitForElementPresentcss=table.atat-table > tbody > tr > td > span.label.label--success.label--below
assertTextcss=table.atat-table > tbody > tr > td > span.label.label--success.label--below*invite pending*
waitForPageToLoad
waitForElementPresentcss=.usa-alert-body
assertTextcss=.usa-alert-body*Brandon Buchannan's invitation has been sent + +Brandon Buchannan's access to this Portfolio is pending until they sign in for the first time.*
waitForPageToLoad
waitForElementPresentcss=table.atat-table > tbody > tr:nth-of-type(2) > td.toggle-menu__container > .toggle-menu > .accordion-table__item__toggler > .icon.icon--ellipsis > svg.svg-inline--fa.fa-ellipsis-h.fa-w-16 > path
clickcss=table.atat-table > tbody > tr:nth-of-type(2) > td.toggle-menu__container > .toggle-menu > .accordion-table__item__toggler > .icon.icon--ellipsis > svg.svg-inline--fa.fa-ellipsis-h.fa-w-16 > path
waitForPageToLoad
waitForElementPresentcss=table.atat-table > tbody > tr:nth-of-type(2) > td.toggle-menu__container > .toggle-menu > .accordion-table__item-toggle-content.toggle-menu__toggle > a:nth-of-type(2)
clickcss=table.atat-table > tbody > tr:nth-of-type(2) > td.toggle-menu__container > .toggle-menu > .accordion-table__item-toggle-content.toggle-menu__toggle > a:nth-of-type(2)
waitForPageToLoad
waitForElementPresentcss=.portfolio-content > div:nth-of-type(4) > .modal.form-content--app-mem > .modal__container > .modal__dialog > .modal__body > .modal__form--header > h1
assertTextcss=.portfolio-content > div:nth-of-type(4) > .modal.form-content--app-mem > .modal__container > .modal__dialog > .modal__body > .modal__form--header > h1*Verify Member Information*
waitForPageToLoad
waitForElementPresentcss=.action-group__action.usa-button
clickcss=.action-group__action.usa-button
waitForPageToLoad
waitForElementPresentcss=.usa-alert-text
assertTextcss=.usa-alert-text*jay+brandon@promptworks.com has been sent an invitation to access this Portfolio*
+ + \ No newline at end of file diff --git a/uitests/Revoke_Portfolio_Member_Invite.html b/uitests/Revoke_Portfolio_Member_Invite.html new file mode 100644 index 00000000..947bf526 --- /dev/null +++ b/uitests/Revoke_Portfolio_Member_Invite.html @@ -0,0 +1,624 @@ + + + + + + +Revoke Portfolio Member Invite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Revoke Portfolio Member Invite
waitForPageToLoad
open/login-dev?username=brandon
waitForPageToLoad
waitForElementPresentcss=a[href="/user"] > .topbar__link-label
assertTextcss=a[href="/user"] > .topbar__link-label*Brandon Buchannan*
waitForPageToLoad
waitForElementPresentcss=a[href="/logout"] > .topbar__link-label
clickcss=a[href="/logout"] > .topbar__link-label
waitForPageToLoad
waitForElementPresentcss=.col > .usa-alert.usa-alert-info:nth-of-type(2) > .usa-alert-body > h3.usa-alert-heading
assertTextcss=.col > .usa-alert.usa-alert-info:nth-of-type(2) > .usa-alert-body > h3.usa-alert-heading*Logged out*
waitForPageToLoad
open/login-dev
waitForPageToLoad
waitForElementPresentcss=.home__content > h1
assertTextcss=.home__content > h1JEDI Cloud Services
waitForPageToLoad
waitForElementPresentcss=a[href="/portfolios/new"]
clickcss=a[href="/portfolios/new"]
waitForPageToLoad
waitForElementPresentcss=.portfolio-header__name > h1
assertTextcss=.portfolio-header__name > h1*New Portfolio*
waitForPageToLoad
waitForElementPresentcss=.sticky-cta-text > h3
assertTextcss=.sticky-cta-text > h3*Name and Describe Portfolio*
waitForPageToLoad
waitForElementPresentcss=#name
typecss=#nameTatooine Energy Maintenance Systems ${alphanumeric}
waitForPageToLoad
waitForElementPresentcss=fieldset.usa-input__choices > ul > li:nth-of-type(5) > label
clickcss=fieldset.usa-input__choices > ul > li:nth-of-type(5) > label
waitForPageToLoad
waitForElementPresentcss=input[type="submit"]
clickcss=input[type="submit"]
waitForPageToLoad
waitForElementPresentcss=.empty-state > h3
assertTextcss=.empty-state > h3*You don't have any Applications yet*
waitForPageToLoad
waitForElementPresentcss=.icon.icon--cog > svg
clickcss=.icon.icon--cog > svg
waitForPageToLoad
waitForElementPresentcss=.portfolio-header__name > h1
assertTextcss=.portfolio-header__name > h1*Tatooine Energy Maintenance Systems*
waitForPageToLoad
waitForElementPresentcss=th.table-cell--third
assertElementPresentcss=th.table-cell--third
waitForPageToLoad
waitForElementPresentcss=button.usa-button.usa-button-primary.usa-button-big
assertTextcss=button.usa-button.usa-button-primary.usa-button-bigSave Changes
waitForPageToLoad
waitForElementPresentcss=a.usa-button.usa-button-secondary.add-new-button
clickcss=a.usa-button.usa-button-secondary.add-new-button
waitForPageToLoad
waitForElementPresentcss=#add-portfolio-manager > div > div > div.member-form > h2
assertTextcss=#add-portfolio-manager > div > div > div.member-form > h2*Add Manager*
waitForPageToLoad
waitForElementPresentcss=#user_data-first_name
typecss=#user_data-first_nameBrandon
waitForPageToLoad
waitForElementPresentcss=#user_data-last_name
typecss=#user_data-last_nameBuchannan
waitForPageToLoad
waitForElementPresentcss=#user_data-email
typecss=#user_data-emailjay+brandon@promptworks.com
waitForPageToLoad
waitForElementPresentcss=#user_data-dod_id
typecss=#user_data-dod_id3456789012
waitForPageToLoad
waitForElementPresentcss=input[type="button"]
clickcss=input[type="button"]
waitForPageToLoad
waitForElementPresentcss=#add-portfolio-manager > div > div > div.member-form > h2
assertTextcss=#add-portfolio-manager > div > div > div.member-form > h2*Set Portfolio Permissions*
waitForPageToLoad
waitForElementPresentcss=#perms_app_mgmt-None
clickcss=#perms_app_mgmt-None
waitForPageToLoad
waitForElementPresentcss=#perms_funding-None
clickcss=#perms_funding-None
waitForPageToLoad
waitForElementPresentcss=#perms_reporting-None
clickcss=#perms_reporting-None
waitForPageToLoad
waitForElementPresentcss=#perms_portfolio_mgmt-None
typecss=#perms_portfolio_mgmt-Noneedit_portfolio_admin
waitForPageToLoad
waitForElementPresentcss=input[type="submit"].action-group__action
clickcss=input[type="submit"].action-group__action
waitForPageToLoad
waitForElementPresentcss=table.atat-table > tbody > tr > td > span.label.label--success.label--below
assertTextcss=table.atat-table > tbody > tr > td > span.label.label--success.label--below*invite pending*
waitForPageToLoad
waitForElementPresentcss=.usa-alert-body
assertTextcss=.usa-alert-body*Brandon Buchannan's invitation has been sent + +Brandon Buchannan's access to this Portfolio is pending until they sign in for the first time.*
waitForPageToLoad
waitForElementPresentcss=table.atat-table > tbody > tr:nth-of-type(2) > td.toggle-menu__container > .toggle-menu > .accordion-table__item__toggler > .icon.icon--ellipsis > svg.svg-inline--fa.fa-ellipsis-h.fa-w-16
clickcss=table.atat-table > tbody > tr:nth-of-type(2) > td.toggle-menu__container > .toggle-menu > .accordion-table__item__toggler > .icon.icon--ellipsis > svg.svg-inline--fa.fa-ellipsis-h.fa-w-16
waitForPageToLoad
waitForElementPresentcss=.accordion-table__item-toggle-content > a:nth-of-type(3)
clickcss=.accordion-table__item-toggle-content > a:nth-of-type(3)
waitForPageToLoad
waitForElementPresentcss=form[action] > h1
assertTextcss=form[action] > h1*Revoke Invite*
waitForPageToLoad
waitForElementPresentcss=button[type="submit"].action-group__action
clickcss=button[type="submit"].action-group__action
+ + \ No newline at end of file From cd0081050d7a17ed2a0c09b3c6dd83f0710b4373 Mon Sep 17 00:00:00 2001 From: "Jay R. Newlin (PromptWorks)" Date: Fri, 24 Jan 2020 09:52:56 -0500 Subject: [PATCH 14/24] Regular test updates due to app UI changes --- uitests/Application_Index_with_App.html | 22 +- uitests/Create_New_Application.html | 21 +- uitests/Create_New_TO.html | 8 +- uitests/Edit_App_Member.html | 45 +-- uitests/Edit_Portfolio_Member.html | 372 +++++++----------- uitests/New_App_Step_1.html | 2 +- uitests/New_App_Step_2.html | 2 +- uitests/New_App_Step_2_-_Add_Env.html | 2 +- uitests/New_App_Step_3.html | 21 +- uitests/New_Portfolio.html | 2 +- uitests/New_Portfolio_Member.html | 38 +- uitests/Portfolio_Settings.html | 32 +- uitests/Reports_-_Basics.html | 8 +- uitests/Reports_-_Empty_State.html | 2 +- uitests/Reports_-_Follow_Add_App_Button.html | 8 +- uitests/Reports_-_Follow_TO_link.html | 12 +- ...orts_-_with_TO,_App,_and_Environments.html | 28 +- uitests/Reports_-_with_expired_TO.html | 28 +- uitests/Resend_App_Member_Invite.html | 51 +-- uitests/Revoke_App_Member_Invite.html | 22 +- uitests/Revoke_Environment_Access.html | 34 +- ...TO_Index_(Landing)_Page_-_Empty_State.html | 17 +- uitests/TO_Index_with_Draft_TO.html | 8 +- uitests/TO_Index_with_TO.html | 8 +- uitests/TO_Index_with_Unsigned_TO.html | 8 +- uitests/TO_Index_with_expired_TO.html | 8 +- uitests/TO_Index_with_future_TO.html | 8 +- uitests/TO_Step_1.html | 2 +- uitests/TO_Step_2.html | 2 +- uitests/TO_Step_3.html | 2 +- uitests/TO_Step_3_-_Add_CLIN.html | 2 +- uitests/TO_Step_4.html | 6 +- uitests/TO_Step_5.html | 6 +- 33 files changed, 246 insertions(+), 591 deletions(-) diff --git a/uitests/Application_Index_with_App.html b/uitests/Application_Index_with_App.html index 2c2c120c..c7efd48a 100644 --- a/uitests/Application_Index_with_App.html +++ b/uitests/Application_Index_with_App.html @@ -169,7 +169,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -439,29 +439,13 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -click -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -waitForPageToLoad - - - - - -waitForElementPresent css=#environment_roles-0-role-None type css=#environment_roles-0-role-None -Basic Access +ADMIN waitForPageToLoad @@ -477,7 +461,7 @@ Imported from: AT-AT CI - New Portfolio--> type css=#environment_roles-1-role-None -Network Admin +BILLING_READ waitForPageToLoad diff --git a/uitests/Create_New_Application.html b/uitests/Create_New_Application.html index 24ee7094..564c1886 100644 --- a/uitests/Create_New_Application.html +++ b/uitests/Create_New_Application.html @@ -160,7 +160,7 @@ Imported from: AT-AT CI - login--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -413,28 +413,13 @@ Imported from: AT-AT CI - login--> waitForElementPresent -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -click -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -waitForPageToLoad - - - - -waitForElementPresent css=#environment_roles-0-role-None type css=#environment_roles-0-role-None -Basic Access +ADMIN waitForPageToLoad @@ -449,7 +434,7 @@ Imported from: AT-AT CI - login--> type css=#environment_roles-1-role-None -Network Admin +BILLING_READ waitForPageToLoad diff --git a/uitests/Create_New_TO.html b/uitests/Create_New_TO.html index 460026cd..1d85c2bc 100644 --- a/uitests/Create_New_TO.html +++ b/uitests/Create_New_TO.html @@ -101,7 +101,7 @@ Imported from: AT-AT CI - login--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -189,12 +189,12 @@ Imported from: AT-AT CI - login--> waitForElementPresent -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary - + click -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary diff --git a/uitests/Edit_App_Member.html b/uitests/Edit_App_Member.html index b3af2f7e..e4e92fa8 100644 --- a/uitests/Edit_App_Member.html +++ b/uitests/Edit_App_Member.html @@ -169,7 +169,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -439,29 +439,13 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -click -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -waitForPageToLoad - - - - - -waitForElementPresent css=#environment_roles-0-role-None type css=#environment_roles-0-role-None -Basic Access +ADMIN waitForPageToLoad @@ -477,7 +461,7 @@ Imported from: AT-AT CI - New Portfolio--> type css=#environment_roles-1-role-None -Network Admin +BILLING_READ waitForPageToLoad @@ -656,28 +640,13 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -click -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -waitForPageToLoad - - - - -waitForElementPresent css=.environment_roles.environment-roles-new > .form-row:nth-of-type(1) > .form-col.form-col--third > fieldset.usa-input__choices > select[name="environment_roles-2-role"] type css=.environment_roles.environment-roles-new > .form-row:nth-of-type(1) > .form-col.form-col--third > fieldset.usa-input__choices > select[name="environment_roles-2-role"] -Business Read-only +CONTRIBUTOR waitForPageToLoad @@ -761,13 +730,13 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=table.atat-table > tbody > tr:nth-of-type(1) > td.env_role--td > .row:nth-of-type(3) > .env-role__role +css=table.atat-table > tbody > tr:nth-of-type(1) > td.toggle-menu__container > .row:nth-of-type(3) > .env-role__role assertText -css=table.atat-table > tbody > tr:nth-of-type(1) > td.env_role--td > .row:nth-of-type(3) > .env-role__role -*Business Read-only* +css=table.atat-table > tbody > tr:nth-of-type(1) > td.toggle-menu__container > .row:nth-of-type(3) > .env-role__role +*Contributor* diff --git a/uitests/Edit_Portfolio_Member.html b/uitests/Edit_Portfolio_Member.html index 71d82e8f..3fd58cee 100644 --- a/uitests/Edit_Portfolio_Member.html +++ b/uitests/Edit_Portfolio_Member.html @@ -16,7 +16,7 @@ - + @@ -174,7 +174,7 @@ Imported from: AT-AT CI - New Portfolio--> - + @@ -192,7 +192,7 @@ Imported from: AT-AT CI - New Portfolio--> - + @@ -291,29 +291,12 @@ Imported from: AT-AT CI - Portfolio Settings--> Imported from: AT-AT CI - Portfolio Settings--> - + - - - - - - - - - - - - - - - - - + @@ -331,41 +314,7 @@ Imported from: AT-AT CI - Portfolio Settings--> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -375,12 +324,12 @@ Imported from: AT-AT CI - Portfolio Settings--> - + - + @@ -391,13 +340,13 @@ Imported from: AT-AT CI - Portfolio Settings--> - + - - + + @@ -487,13 +436,13 @@ Imported from: AT-AT CI - Portfolio Settings--> - + - - + + @@ -503,12 +452,12 @@ Imported from: AT-AT CI - Portfolio Settings--> - + - + @@ -519,12 +468,12 @@ Imported from: AT-AT CI - Portfolio Settings--> - + - + @@ -535,12 +484,12 @@ Imported from: AT-AT CI - Portfolio Settings--> - + - + @@ -551,60 +500,12 @@ Imported from: AT-AT CI - Portfolio Settings--> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + @@ -615,22 +516,6 @@ Imported from: AT-AT CI - Portfolio Settings--> - - - - - - - - - - - - - - - - @@ -647,12 +532,75 @@ Imported from: AT-AT CI - Portfolio Settings--> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -660,105 +608,59 @@ Imported from: AT-AT CI - Portfolio Settings--> - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -768,13 +670,13 @@ Imported from: AT-AT CI - Portfolio Settings--> - + - - + +
assertText css=.sticky-cta-text > h3*Create New Portfolio**Name and Describe Portfolio*
waitForPageToLoad
type css=#nameTatooine Energy Maintenance SystemsTatooine Energy Maintenance Systems ${alphanumeric}
waitForPageToLoad
waitForElementPresentcss=.panel__content > p:nth-of-type(2)css=th.table-cell--third
assertElementPresentcss=.panel__content > p:nth-of-type(2)
waitForPageToLoad
waitForElementPresentcss=td.name
assertElementPresentcss=td.namecss=th.table-cell--third
assertText css=button.usa-button.usa-button-primary.usa-button-bigSave
waitForPageToLoad
waitForElementPresentcss=button.usa-button.usa-button-primary
assertTextcss=button.usa-button.usa-button-primary*Update*
waitForPageToLoad
waitForElementPresentcss=input.usa-button.usa-button-primary
assertTextcss=input.usa-button.usa-button-primarySaveSave Changes
waitForPageToLoad
waitForElementPresentcss=a.icon-link.modal-linkcss=a.usa-button.usa-button-secondary.add-new-button
clickcss=a.icon-link.modal-linkcss=a.usa-button.usa-button-secondary.add-new-button
waitForElementPresentcss=#add-port-mem > div > div:nth-of-type(1) > h1css=#add-portfolio-manager > div > div > div.member-form > h2
assertTextcss=#add-port-mem > div > div:nth-of-type(1) > h1*Invite new portfolio member*css=#add-portfolio-manager > div > div > div.member-form > h2*Add Manager*
waitForPageToLoad
waitForElementPresentcss=#add-port-mem > div > div:nth-of-type(2) > h1css=#add-portfolio-manager > div > div > div.member-form > h2
assertTextcss=#add-port-mem > div > div:nth-of-type(2) > h1*Assign member permissions*css=#add-portfolio-manager > div > div > div.member-form > h2*Set Portfolio Permissions*
waitForPageToLoad
waitForElementPresentcss=#permission_sets-perms_app_mgmtcss=#perms_app_mgmt-None
clickcss=#permission_sets-perms_app_mgmtcss=#perms_app_mgmt-None
waitForElementPresentcss=#permission_sets-perms_app_mgmt > option:nth-of-type(1)css=#perms_funding-None
clickcss=#permission_sets-perms_app_mgmt > option:nth-of-type(1)css=#perms_funding-None
waitForElementPresentcss=#permission_sets-perms_fundingcss=#perms_reporting-None
clickcss=#permission_sets-perms_fundingcss=#perms_reporting-None
waitForElementPresentcss=#permission_sets-perms_funding > option:nth-of-type(1)
clickcss=#permission_sets-perms_funding > option:nth-of-type(1)
waitForPageToLoad
waitForElementPresentcss=#permission_sets-perms_reporting
clickcss=#permission_sets-perms_reporting
waitForPageToLoad
waitForElementPresentcss=#permission_sets-perms_reporting > option:nth-of-type(1)
clickcss=#permission_sets-perms_reporting > option:nth-of-type(1)
waitForPageToLoad
waitForElementPresentcss=#permission_sets-perms_portfolio_mgmtcss=#perms_portfolio_mgmt-None
typecss=#permission_sets-perms_portfolio_mgmtcss=#perms_portfolio_mgmt-None edit_portfolio_admin
waitForElementPresentcss=#permission_sets-perms_portfolio_mgmt > option:nth-of-type(2)
clickcss=#permission_sets-perms_portfolio_mgmt > option:nth-of-type(2)
waitForPageToLoad
waitForElementPresent css=input[type="submit"].action-group__action
waitForElementPresentcss=table.atat-table > tbody > tr:nth-of-type(2) > td.namecss=table.atat-table > tbody > tr > td > span.label.label--success.label--below
assertTextcss=table.atat-table > tbody > tr > td > span.label.label--success.label--below*invite pending*
waitForPageToLoad
waitForElementPresentcss=.usa-alert-body
assertTextcss=.usa-alert-body*Brandon Buchannan's invitation has been sent + +Brandon Buchannan's access to this Portfolio is pending until they sign in for the first time.*
waitForPageToLoad
waitForElementPresentcss=table.atat-table > tbody > tr:nth-of-type(2) > td.toggle-menu__container > .toggle-menu > .accordion-table__item__toggler > .icon.icon--ellipsis > svg.svg-inline--fa.fa-ellipsis-h.fa-w-16
clickcss=table.atat-table > tbody > tr:nth-of-type(2) > td.toggle-menu__container > .toggle-menu > .accordion-table__item__toggler > .icon.icon--ellipsis > svg.svg-inline--fa.fa-ellipsis-h.fa-w-16
waitForPageToLoad
waitForElementPresentcss=table.atat-table > tbody > tr:nth-of-type(2) > td.toggle-menu__container > .toggle-menu > .accordion-table__item-toggle-content.toggle-menu__toggle > a:nth-of-type(1)
clickcss=table.atat-table > tbody > tr:nth-of-type(2) > td.toggle-menu__container > .toggle-menu > .accordion-table__item-toggle-content.toggle-menu__toggle > a:nth-of-type(1)
waitForPageToLoad
waitForElementPresentcss=.portfolio-content > div:nth-of-type(3) > .modal.form-content--app-mem > .modal__container > .modal__dialog > .modal__body > .modal__form--header > h1
assertElementPresentcss=table.atat-table > tbody > tr:nth-of-type(2) > td.namecss=.portfolio-content > div:nth-of-type(3) > .modal.form-content--app-mem > .modal__container > .modal__dialog > .modal__body > .modal__form--header > h1
waitForElementPresentcss=.usa-alert-body > p:nth-of-type(2)css=.portfolio-perms > div:nth-of-type(2) > .usa-input.input__inline-fields.checked > fieldset.usa-input__choices > legend > label
clickcss=.portfolio-perms > div:nth-of-type(2) > .usa-input.input__inline-fields.checked > fieldset.usa-input__choices > legend > label
waitForPageToLoad
waitForElementPresentcss=.portfolio-perms > div:nth-of-type(4) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label
clickcss=.portfolio-perms > div:nth-of-type(4) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label
waitForPageToLoad
waitForElementPresentcss=.action-group__action.usa-button
clickcss=.action-group__action.usa-button
waitForPageToLoad
waitForElementPresentcss=h3.usa-alert-heading
assertTextcss=.usa-alert-body > p:nth-of-type(2)*You have successfully invited Brandon Buchannan to the portfolio.*
waitForPageToLoad
waitForElementPresentcss=select[name="members_permissions-1-perms_app_mgmt"]
typecss=select[name="members_permissions-1-perms_app_mgmt"]edit_portfolio_application_management
waitForPageToLoad
waitForElementPresentcss=select[name="members_permissions-1-perms_app_mgmt"] > option:nth-of-type(2)
clickcss=select[name="members_permissions-1-perms_app_mgmt"] > option:nth-of-type(2)
waitForPageToLoad
waitForElementPresentcss=select[name="members_permissions-1-perms_reporting"]
typecss=select[name="members_permissions-1-perms_reporting"]edit_portfolio_reports
waitForPageToLoad
waitForElementPresentcss=select[name="members_permissions-1-perms_reporting"] > option:nth-of-type(2)
clickcss=select[name="members_permissions-1-perms_reporting"] > option:nth-of-type(2)
waitForPageToLoad
waitForElementPresentcss=input[type="submit"]
clickcss=input[type="submit"]
waitForPageToLoad
waitForElementPresentcss=.usa-alert.usa-alert-success > .usa-alert-body > h3.usa-alert-heading
assertTextcss=.usa-alert.usa-alert-success > .usa-alert-body > h3.usa-alert-headingcss=h3.usa-alert-heading *Success!*
waitForElementPresentcss=.usa-alert-body > p:nth-of-type(2)css=.usa-alert-text
assertTextcss=.usa-alert-body > p:nth-of-type(2)*You have successfully updated access permissions for members of Tatooine Energy Maintenance Systems.*css=.usa-alert-text*You have successfully updated access permissions for*
diff --git a/uitests/New_App_Step_1.html b/uitests/New_App_Step_1.html index 05f25f84..83f70ab6 100644 --- a/uitests/New_App_Step_1.html +++ b/uitests/New_App_Step_1.html @@ -101,7 +101,7 @@ Imported from: AT-AT CI - login--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad diff --git a/uitests/New_App_Step_2.html b/uitests/New_App_Step_2.html index 3deecee8..50338788 100644 --- a/uitests/New_App_Step_2.html +++ b/uitests/New_App_Step_2.html @@ -106,7 +106,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad diff --git a/uitests/New_App_Step_2_-_Add_Env.html b/uitests/New_App_Step_2_-_Add_Env.html index a2ed4f8d..7450d2e3 100644 --- a/uitests/New_App_Step_2_-_Add_Env.html +++ b/uitests/New_App_Step_2_-_Add_Env.html @@ -111,7 +111,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad diff --git a/uitests/New_App_Step_3.html b/uitests/New_App_Step_3.html index 2371a8a4..f8e4948c 100644 --- a/uitests/New_App_Step_3.html +++ b/uitests/New_App_Step_3.html @@ -170,7 +170,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -640,28 +640,13 @@ Imported from: AT-AT CI - New App Step 1--> waitForElementPresent -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -click -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -waitForPageToLoad - - - - -waitForElementPresent css=[name=environment_roles-0-role] type css=[name=environment_roles-0-role] -Basic Access +ADMIN waitForPageToLoad @@ -676,7 +661,7 @@ Imported from: AT-AT CI - New App Step 1--> type css=[name=environment_roles-1-role] -Network Admin +BILLING_READ waitForPageToLoad diff --git a/uitests/New_Portfolio.html b/uitests/New_Portfolio.html index ea3aee7d..cb3f3c26 100644 --- a/uitests/New_Portfolio.html +++ b/uitests/New_Portfolio.html @@ -96,7 +96,7 @@ assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad diff --git a/uitests/New_Portfolio_Member.html b/uitests/New_Portfolio_Member.html index 35c052df..ab4480ee 100644 --- a/uitests/New_Portfolio_Member.html +++ b/uitests/New_Portfolio_Member.html @@ -165,7 +165,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -275,22 +275,6 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.panel__content > p:nth-of-type(2) - - - -assertElementPresent -css=.panel__content > p:nth-of-type(2) - - - -waitForPageToLoad - - - - - -waitForElementPresent css=th.table-cell--third @@ -320,22 +304,6 @@ Imported from: AT-AT CI - New Portfolio--> - - -waitForElementPresent -css=button.usa-button.usa-button-primary - - - -assertText -css=button.usa-button.usa-button-primary -*Update* - - -waitForPageToLoad - - - waitForElementPresent css=a.usa-button.usa-button-secondary.add-new-button @@ -554,7 +522,9 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.usa-alert-body -*You have successfully invited Brandon Buchannan to the portfolio.* +*Brandon Buchannan's invitation has been sent + +Brandon Buchannan's access to this Portfolio is pending until they sign in for the first time.* diff --git a/uitests/Portfolio_Settings.html b/uitests/Portfolio_Settings.html index 4996fdbb..4c3ea61d 100644 --- a/uitests/Portfolio_Settings.html +++ b/uitests/Portfolio_Settings.html @@ -101,7 +101,7 @@ Imported from: AT-AT CI - login--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -204,21 +204,6 @@ Imported from: AT-AT CI - login--> waitForElementPresent -css=.panel__content > p:nth-of-type(2) - - - -assertElementPresent -css=.panel__content > p:nth-of-type(2) - - - -waitForPageToLoad - - - - -waitForElementPresent css=th.table-cell--third @@ -242,21 +227,6 @@ Imported from: AT-AT CI - login--> css=button.usa-button.usa-button-primary.usa-button-big Save Changes - -waitForPageToLoad - - - - -waitForElementPresent -css=button.usa-button.usa-button-primary - - - -assertText -css=button.usa-button.usa-button-primary -*Update* - diff --git a/uitests/Reports_-_Basics.html b/uitests/Reports_-_Basics.html index 84d65469..ecb8e962 100644 --- a/uitests/Reports_-_Basics.html +++ b/uitests/Reports_-_Basics.html @@ -106,7 +106,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -200,12 +200,12 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary - + click -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary diff --git a/uitests/Reports_-_Empty_State.html b/uitests/Reports_-_Empty_State.html index d0ae8235..448a3cb0 100644 --- a/uitests/Reports_-_Empty_State.html +++ b/uitests/Reports_-_Empty_State.html @@ -101,7 +101,7 @@ Imported from: AT-AT CI - login--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad diff --git a/uitests/Reports_-_Follow_Add_App_Button.html b/uitests/Reports_-_Follow_Add_App_Button.html index 1b4658bd..c1607b2f 100644 --- a/uitests/Reports_-_Follow_Add_App_Button.html +++ b/uitests/Reports_-_Follow_Add_App_Button.html @@ -111,7 +111,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -211,12 +211,12 @@ Imported from: AT-AT CI - Create New TO--> Imported from: AT-AT CI - Create New TO--> waitForElementPresent -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary - + click -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary diff --git a/uitests/Reports_-_Follow_TO_link.html b/uitests/Reports_-_Follow_TO_link.html index 627838b2..7c3d2e6d 100644 --- a/uitests/Reports_-_Follow_TO_link.html +++ b/uitests/Reports_-_Follow_TO_link.html @@ -111,7 +111,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -211,12 +211,12 @@ Imported from: AT-AT CI - Create New TO--> Imported from: AT-AT CI - Create New TO--> waitForElementPresent -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary - + click -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary @@ -841,7 +841,7 @@ Imported from: AT-AT CI - Create New TO--> assertText css=.row > .col.col--grow.summary-item:nth-of-type(1) > .summary-item__value--large -*$100,000.00* +*$800,000.00* waitForPageToLoad @@ -856,7 +856,7 @@ Imported from: AT-AT CI - Create New TO--> assertText css=.row > .col.col--grow.summary-item:nth-of-type(2) > .summary-item__value--large -*$800,000.00* +*$100,000.00* diff --git a/uitests/Reports_-_with_TO,_App,_and_Environments.html b/uitests/Reports_-_with_TO,_App,_and_Environments.html index 9bb67a36..6fbc96e2 100644 --- a/uitests/Reports_-_with_TO,_App,_and_Environments.html +++ b/uitests/Reports_-_with_TO,_App,_and_Environments.html @@ -169,7 +169,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -439,29 +439,13 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -click -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -waitForPageToLoad - - - - - -waitForElementPresent css=#environment_roles-0-role-None type css=#environment_roles-0-role-None -Basic Access +ADMIN waitForPageToLoad @@ -477,7 +461,7 @@ Imported from: AT-AT CI - New Portfolio--> type css=#environment_roles-1-role-None -Network Admin +BILLING_READ waitForPageToLoad @@ -583,12 +567,12 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary - + click -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary diff --git a/uitests/Reports_-_with_expired_TO.html b/uitests/Reports_-_with_expired_TO.html index 8970b8b8..df76aa00 100644 --- a/uitests/Reports_-_with_expired_TO.html +++ b/uitests/Reports_-_with_expired_TO.html @@ -169,7 +169,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -439,29 +439,13 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -click -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -waitForPageToLoad - - - - - -waitForElementPresent css=#environment_roles-0-role-None type css=#environment_roles-0-role-None -Basic Access +ADMIN waitForPageToLoad @@ -477,7 +461,7 @@ Imported from: AT-AT CI - New Portfolio--> type css=#environment_roles-1-role-None -Network Admin +BILLING_READ waitForPageToLoad @@ -583,12 +567,12 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary - + click -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary diff --git a/uitests/Resend_App_Member_Invite.html b/uitests/Resend_App_Member_Invite.html index 2fb72573..def438b5 100644 --- a/uitests/Resend_App_Member_Invite.html +++ b/uitests/Resend_App_Member_Invite.html @@ -169,7 +169,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -439,29 +439,13 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -click -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -waitForPageToLoad - - - - - -waitForElementPresent css=#environment_roles-0-role-None type css=#environment_roles-0-role-None -Basic Access +ADMIN waitForPageToLoad @@ -477,7 +461,7 @@ Imported from: AT-AT CI - New Portfolio--> type css=#environment_roles-1-role-None -Network Admin +BILLING_READ waitForPageToLoad @@ -626,12 +610,12 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.user-info > .usa-input.usa-input--validation--requiredField:nth-of-type(1) > input[id="first_name"][type="text"] +css=.user-info > .usa-input.usa-input--validation--name:nth-of-type(1) > input[id="first_name"][type="text"] assertText -css=.user-info > .usa-input.usa-input--validation--requiredField:nth-of-type(1) > input[id="first_name"][type="text"] +css=.user-info > .usa-input.usa-input--validation--name:nth-of-type(1) > input[id="first_name"][type="text"] *Brandon* @@ -641,12 +625,12 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.panel > div:nth-of-type(2) > .modal.form-content--app-mem > .modal__container > .modal__dialog > .modal__body > form[action] > .action-group > button[type="submit"] +css=.panel > div:nth-of-type(2) > .modal.form-content--app-mem > .modal__container > .modal__dialog > .modal__body > form[action] > .action-group > input[type="submit"] assertText -css=.panel > div:nth-of-type(2) > .modal.form-content--app-mem > .modal__container > .modal__dialog > .modal__body > form[action] > .action-group > button[type="submit"] +css=.panel > div:nth-of-type(2) > .modal.form-content--app-mem > .modal__container > .modal__dialog > .modal__body > form[action] > .action-group > input[type="submit"] *Resend Invite* @@ -656,12 +640,12 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.panel > div:nth-of-type(2) > .modal.form-content--app-mem > .modal__container > .modal__dialog > .modal__body > form[action] > .action-group > button[type="submit"] +css=.panel > div:nth-of-type(2) > .modal.form-content--app-mem > .modal__container > .modal__dialog > .modal__body > form[action] > .action-group > input[type="submit"] click -css=.panel > div:nth-of-type(2) > .modal.form-content--app-mem > .modal__container > .modal__dialog > .modal__body > form[action] > .action-group > button[type="submit"] +css=.panel > div:nth-of-type(2) > .modal.form-content--app-mem > .modal__container > .modal__dialog > .modal__body > form[action] > .action-group > input[type="submit"] @@ -671,28 +655,13 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.usa-alert.usa-alert-success > .usa-alert-body > h3.usa-alert-heading - - - -assertText -css=.usa-alert.usa-alert-success > .usa-alert-body > h3.usa-alert-heading -*Application invitation resent* - - -waitForPageToLoad - - - - -waitForElementPresent css=.usa-alert.usa-alert-success > .usa-alert-body > .usa-alert-text assertText css=.usa-alert.usa-alert-success > .usa-alert-body > .usa-alert-text -*You have successfully resent the invite for Brandon Buchannan* +*jay+brandon@promptworks.com has been sent an invitation to access this Application* diff --git a/uitests/Revoke_App_Member_Invite.html b/uitests/Revoke_App_Member_Invite.html index c0055261..847afe97 100644 --- a/uitests/Revoke_App_Member_Invite.html +++ b/uitests/Revoke_App_Member_Invite.html @@ -169,7 +169,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -439,29 +439,13 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -click -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -waitForPageToLoad - - - - - -waitForElementPresent css=#environment_roles-0-role-None type css=#environment_roles-0-role-None -Basic Access +ADMIN waitForPageToLoad @@ -477,7 +461,7 @@ Imported from: AT-AT CI - New Portfolio--> type css=#environment_roles-1-role-None -Network Admin +BILLING_READ waitForPageToLoad diff --git a/uitests/Revoke_Environment_Access.html b/uitests/Revoke_Environment_Access.html index abb4d1dc..6506733b 100644 --- a/uitests/Revoke_Environment_Access.html +++ b/uitests/Revoke_Environment_Access.html @@ -169,7 +169,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -439,29 +439,13 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -click -css=.application-perms > div:nth-of-type(3) > .usa-input.input__inline-fields > fieldset.usa-input__choices > legend > label - - - -waitForPageToLoad - - - - - -waitForElementPresent css=#environment_roles-0-role-None type css=#environment_roles-0-role-None -Basic Access +ADMIN waitForPageToLoad @@ -477,7 +461,7 @@ Imported from: AT-AT CI - New Portfolio--> type css=#environment_roles-1-role-None -Network Admin +BILLING_READ waitForPageToLoad @@ -581,12 +565,12 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.accordion-table__item-toggle-content.app-member-menu__toggle > a:nth-of-type(1) +css=.accordion-table__item-toggle-content.toggle-menu__toggle > a:nth-of-type(1) click -css=.accordion-table__item-toggle-content.app-member-menu__toggle > a:nth-of-type(1) +css=.accordion-table__item-toggle-content.toggle-menu__toggle > a:nth-of-type(1) @@ -671,12 +655,12 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.action-group > input[type="submit"].usa-button.usa-button-primary.action-group__action +css=.action-group > input[type="submit"].usa-button.action-group__action click -css=.action-group > input[type="submit"].usa-button.usa-button-primary.action-group__action +css=.action-group > input[type="submit"].usa-button.action-group__action @@ -686,12 +670,12 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=table.atat-table > tbody > tr:nth-of-type(1) > td.env_role--td > .row:nth-of-type(1) > .env-role__role +css=table.atat-table > tbody > tr:nth-of-type(1) > td.toggle-menu__container > .row:nth-of-type(1) > .env-role__role assertText -css=table.atat-table > tbody > tr:nth-of-type(1) > td.env_role--td > .row:nth-of-type(1) > .env-role__role +css=table.atat-table > tbody > tr:nth-of-type(1) > td.toggle-menu__container > .row:nth-of-type(1) > .env-role__role *None* diff --git a/uitests/TO_Index_(Landing)_Page_-_Empty_State.html b/uitests/TO_Index_(Landing)_Page_-_Empty_State.html index 15dae03e..bc0e7d5a 100644 --- a/uitests/TO_Index_(Landing)_Page_-_Empty_State.html +++ b/uitests/TO_Index_(Landing)_Page_-_Empty_State.html @@ -101,7 +101,7 @@ Imported from: AT-AT CI - login--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -237,21 +237,6 @@ Imported from: AT-AT CI - login--> css=.empty-state__footer > a.usa-button.usa-button-primary - -waitForPageToLoad - - - - -waitForElementPresent -css=.sticky-cta-buttons > a.usa-button.usa-button-primary - - - -assertElementPresent -css=.sticky-cta-buttons > a.usa-button.usa-button-primary - - diff --git a/uitests/TO_Index_with_Draft_TO.html b/uitests/TO_Index_with_Draft_TO.html index 77a6e543..6e34eb31 100644 --- a/uitests/TO_Index_with_Draft_TO.html +++ b/uitests/TO_Index_with_Draft_TO.html @@ -106,7 +106,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -200,12 +200,12 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary - + click -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary diff --git a/uitests/TO_Index_with_TO.html b/uitests/TO_Index_with_TO.html index 8997f6b0..8065848c 100644 --- a/uitests/TO_Index_with_TO.html +++ b/uitests/TO_Index_with_TO.html @@ -106,7 +106,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -200,12 +200,12 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary - + click -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary diff --git a/uitests/TO_Index_with_Unsigned_TO.html b/uitests/TO_Index_with_Unsigned_TO.html index 3b3f1786..49998dbe 100644 --- a/uitests/TO_Index_with_Unsigned_TO.html +++ b/uitests/TO_Index_with_Unsigned_TO.html @@ -106,7 +106,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -200,12 +200,12 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary - + click -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary diff --git a/uitests/TO_Index_with_expired_TO.html b/uitests/TO_Index_with_expired_TO.html index 9bccba7e..47459209 100644 --- a/uitests/TO_Index_with_expired_TO.html +++ b/uitests/TO_Index_with_expired_TO.html @@ -106,7 +106,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -200,12 +200,12 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary - + click -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary diff --git a/uitests/TO_Index_with_future_TO.html b/uitests/TO_Index_with_future_TO.html index 3401bd3e..d04b0530 100644 --- a/uitests/TO_Index_with_future_TO.html +++ b/uitests/TO_Index_with_future_TO.html @@ -106,7 +106,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -200,12 +200,12 @@ Imported from: AT-AT CI - New Portfolio--> waitForElementPresent -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary - + click -css=.sticky-cta-buttons > .usa-button.usa-button-primary +css=.empty-state__footer > .usa-button.usa-button-primary diff --git a/uitests/TO_Step_1.html b/uitests/TO_Step_1.html index 53e0c1b2..ac031608 100644 --- a/uitests/TO_Step_1.html +++ b/uitests/TO_Step_1.html @@ -101,7 +101,7 @@ Imported from: AT-AT CI - login--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad diff --git a/uitests/TO_Step_2.html b/uitests/TO_Step_2.html index 1bd56535..464d0f51 100644 --- a/uitests/TO_Step_2.html +++ b/uitests/TO_Step_2.html @@ -106,7 +106,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad diff --git a/uitests/TO_Step_3.html b/uitests/TO_Step_3.html index 84ba584d..ffdf0ae4 100644 --- a/uitests/TO_Step_3.html +++ b/uitests/TO_Step_3.html @@ -111,7 +111,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad diff --git a/uitests/TO_Step_3_-_Add_CLIN.html b/uitests/TO_Step_3_-_Add_CLIN.html index c5ab24a1..4617ebdd 100644 --- a/uitests/TO_Step_3_-_Add_CLIN.html +++ b/uitests/TO_Step_3_-_Add_CLIN.html @@ -116,7 +116,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad diff --git a/uitests/TO_Step_4.html b/uitests/TO_Step_4.html index 1968c48d..8bf2f648 100644 --- a/uitests/TO_Step_4.html +++ b/uitests/TO_Step_4.html @@ -116,7 +116,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -748,7 +748,7 @@ Imported from: AT-AT CI - TO Step 2--> assertText css=.row > .col.col--grow.summary-item:nth-of-type(1) > .summary-item__value--large -*$100,000.00* +*$800,000.00* waitForPageToLoad @@ -763,7 +763,7 @@ Imported from: AT-AT CI - TO Step 2--> assertText css=.row > .col.col--grow.summary-item:nth-of-type(2) > .summary-item__value--large -*$800,000.00* +*$100,000.00* waitForPageToLoad diff --git a/uitests/TO_Step_5.html b/uitests/TO_Step_5.html index d5d5d7ee..4eb53ab9 100644 --- a/uitests/TO_Step_5.html +++ b/uitests/TO_Step_5.html @@ -121,7 +121,7 @@ Imported from: AT-AT CI - New Portfolio--> assertText css=.sticky-cta-text > h3 -*Create New Portfolio* +*Name and Describe Portfolio* waitForPageToLoad @@ -791,7 +791,7 @@ Imported from: AT-AT CI - TO Step 3--> assertText css=.row > .col.col--grow.summary-item:nth-of-type(1) > .summary-item__value--large -*$100,000.00* +*$800,000.00* waitForPageToLoad @@ -807,7 +807,7 @@ Imported from: AT-AT CI - TO Step 3--> assertText css=.row > .col.col--grow.summary-item:nth-of-type(2) > .summary-item__value--large -*$800,000.00* +*$100,000.00* waitForPageToLoad From e6291ad8506132e9609f3fbb09581b0cb3e8454e Mon Sep 17 00:00:00 2001 From: leigh-mil Date: Fri, 24 Jan 2020 10:51:45 -0500 Subject: [PATCH 15/24] Refactor EmptyState macro and update styling for view only empty state based on new designs --- templates/applications/index.html | 5 +-- templates/components/empty_state.html | 24 +++++++---- .../reports/application_and_env_spending.html | 9 +--- templates/task_orders/index.html | 5 +-- translations.yaml | 41 +++++++++++-------- 5 files changed, 44 insertions(+), 40 deletions(-) diff --git a/templates/applications/index.html b/templates/applications/index.html index 00a9b0e8..fd5a5fa7 100644 --- a/templates/applications/index.html +++ b/templates/applications/index.html @@ -24,11 +24,8 @@ {% if not portfolio.applications %} {{ EmptyState( - header="portfolios.applications.empty_state.header"|translate, - message="portfolios.applications.empty_state.message"|translate, - button_text="portfolios.applications.empty_state.button_text"|translate, + resource='applications', button_link=url_for("applications.view_new_application_step_1", portfolio_id=portfolio.id), - view_only_text="portfolios.applications.empty_state.view_only_text"|translate, user_can_create=can_create_applications, ) }} diff --git a/templates/components/empty_state.html b/templates/components/empty_state.html index 9989e4f8..8357252e 100644 --- a/templates/components/empty_state.html +++ b/templates/components/empty_state.html @@ -1,14 +1,22 @@ -{% macro EmptyState(header, message, button_text, button_link, view_only_text, user_can_create=True) %} +{% macro EmptyState(resource, button_link, user_can_create=False) %} + {% if user_can_create %} + {% set perms = 'edit' %} + {% else %} + {% set perms = 'view' %} + {% endif %} + + {% set header = "empty_state.{}.header.{}".format(resource, perms) | translate | safe %} + {% set message = "empty_state.{}.message.{}".format(resource, perms) | translate | safe %} + {% set button_text = "empty_state.{}.button_text".format(resource) | translate | safe %} +

{{ header }}

{{ message }}

-
- + {%- endif %}
{% endmacro %} diff --git a/templates/portfolios/reports/application_and_env_spending.html b/templates/portfolios/reports/application_and_env_spending.html index 783b29ac..44efd76e 100644 --- a/templates/portfolios/reports/application_and_env_spending.html +++ b/templates/portfolios/reports/application_and_env_spending.html @@ -6,17 +6,10 @@ {% if not portfolio.applications %} {% set can_create_applications = user_can(permissions.CREATE_APPLICATION) %} - {% set message = ('portfolios.reports.empty_state.sub_message.can_create_applications' | translate) - if can_create_applications - else ('portfolios.reports.empty_state.sub_message.cannot_create_applications' | translate) - %} {{ EmptyState( - header='portfolios.reports.empty_state.message' | translate, - message=message, - button_text="portfolios.applications.empty_state.button_text"|translate, + resource='applications_reporting', button_link=url_for("applications.view_new_application_step_1", portfolio_id=portfolio.id), - view_only_text="portfolios.applications.empty_state.view_only_text"|translate, user_can_create=can_create_applications, ) }} diff --git a/templates/task_orders/index.html b/templates/task_orders/index.html index a720c789..8caeeab2 100644 --- a/templates/task_orders/index.html +++ b/templates/task_orders/index.html @@ -85,11 +85,8 @@ {% endcall %} {% else %} {{ EmptyState( - header="task_orders.empty_state.header"|translate, - message="task_orders.empty_state.message"|translate, + resource="task_orders", button_link=url_for('task_orders.form_step_one_add_pdf', portfolio_id=portfolio.id), - button_text="task_orders.empty_state.button_text"|translate, - view_only_text="task_orders.empty_state.view_only_text"|translate, user_can_create=user_can(permissions.CREATE_TASK_ORDER), ) }} {% endif %} diff --git a/translations.yaml b/translations.yaml index d9615c4d..8c4c194f 100644 --- a/translations.yaml +++ b/translations.yaml @@ -84,6 +84,31 @@ email: application_invite: "{inviter_name} has invited you to a JEDI cloud application" portfolio_invite: "{inviter_name} has invited you to a JEDI cloud portfolio" environment_ready: JEDI cloud environment ready +empty_state: + applications: + header: + edit: You don’t have any Applications yet + view: This portfolio has no Applications + message: + edit: You can manage multiple Applications within a single Portfolio as long as the funding sources are the same. + view: A Portfolio member with Edit Application permissions can add Applications to this Portfolio. + button_text: Create Your First Application + applications_reporting: + header: + edit: Nothing to report. + view: Nothing to report. + message: + edit: This portfolio has no cloud environments set up, so there is no spending data to report. Create an application with some cloud environments to get started. + view: This portfolio has no cloud environments set up, so there is no spending data to report. Contact the portfolio owner to set up some cloud environments. + button_text: Add a new application + task_orders: + header: + edit: Add approved task orders + view: This Portfolio has no Task Orders + message: + edit: Upload your approved Task Order here. You are required to confirm you have the appropriate signature. You will have the ability to add additional approved Task Orders with more funding to this Portfolio in the future. + view: A Portfolio member with Edit Funding permissions can fund this Portfolio with approved Task Orders. + button_text: Add Task Order flash: application: created: @@ -370,11 +395,6 @@ portfolios: add_member: Add Team Member add_another_environment: Add another environment create_button: Create Application - empty_state: - header: You don't have any Applications yet - message: You can manage multiple Applications within a single Portfolio as long as the funding sources are the same. - button_text: Create Your First Application - view_only_text: Contact your portfolio administrator to add an application. new: step_1_header: Name and Describe New Application step_1_button_text: "Next: Add Environments" @@ -482,12 +502,6 @@ portfolios: header: Funding Duration tooltip: Funding duration is the period of time that there is a valid task order funding the portfolio. estimate_warning: Reports displayed in JEDI are estimates and not a system of record. - empty_state: - message: Nothing to report. - sub_message: - can_create_applications: This portfolio has no cloud environments set up, so there is no spending data to report. Create an application with some cloud environments to get started. - cannot_create_applications: This portfolio has no cloud environments set up, so there is no spending data to report. Contact the portfolio owner to set up some cloud environments. - action_label: "Add a new application" total_value: header: Total Portfolio Value tooltip: Total portfolio value is all obligated and projected funds for all task orders in this portfolio. @@ -549,11 +563,6 @@ task_orders: sticky_header_text: "Add a Task Order" sticky_header_review_text: Review Changes sticky_header_context: "Step {step} of 5" - empty_state: - header: Add approved task orders - message: Upload your approved Task Order here. You are required to confirm you have the appropriate signature. You will have the ability to add additional approved Task Orders with more funding to this Portfolio in the future. - button_text: Add Task Order - view_only_text: Contact your portfolio administrator to add a Task Order. sign: digital_signature_description: I confirm the uploaded Task Order is signed by the appropriate, duly warranted Agency Contracting Officer who authorized me to upload the Task Order. confirmation_description: I confirm that the information entered here in matches that of the submitted Task Order. From 7857fffc1c5b625ca9a5c41a50ef8c4f57d5d690 Mon Sep 17 00:00:00 2001 From: leigh-mil Date: Fri, 24 Jan 2020 11:53:29 -0500 Subject: [PATCH 16/24] Add alert for when portfolio isn't funded, Update styling for env pending label --- static/icons/clock.svg | 1 + styles/elements/_labels.scss | 2 +- .../applications/fragments/environments.html | 37 +++++++++++-------- templates/components/label.html | 5 +++ translations.yaml | 1 + 5 files changed, 30 insertions(+), 16 deletions(-) create mode 100644 static/icons/clock.svg diff --git a/static/icons/clock.svg b/static/icons/clock.svg new file mode 100644 index 00000000..ef1d84a1 --- /dev/null +++ b/static/icons/clock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/styles/elements/_labels.scss b/styles/elements/_labels.scss index 8c044f8d..1e431957 100644 --- a/styles/elements/_labels.scss +++ b/styles/elements/_labels.scss @@ -21,7 +21,7 @@ text-transform: uppercase; &--default { - background-color: $color-gray-dark; + background-color: $color-gray; } &--info { diff --git a/templates/applications/fragments/environments.html b/templates/applications/fragments/environments.html index fa4e5959..d0934268 100644 --- a/templates/applications/fragments/environments.html +++ b/templates/applications/fragments/environments.html @@ -1,3 +1,4 @@ +{% from "components/alert.html" import Alert %} {% from "components/icon.html" import Icon %} {% from "components/label.html" import Label %} {% from 'components/save_button.html' import SaveButton %} @@ -10,10 +11,13 @@ new_env_form) %}

{{ "portfolios.applications.settings.environments" | translate }}

+ {% if portfolio.num_task_orders == 0 -%} + {{ Alert(message="portfolios.applications.environments.funding_alert"|translate({'name': portfolio.name})) }} + {%- endif %} + {% if g.matchesPath("application-environments") -%} + {% include "fragments/flash.html" %} + {%- endif %}
- {% if g.matchesPath("application-environments") -%} - {% include "fragments/flash.html" %} - {%- endif %} {% if 0 == environments_obj | length -%}

@@ -30,14 +34,21 @@

  • - - - {{ env['name'] }} {{ Icon('link', classes='icon--medium icon--primary') }} - - + {% if not env["pending"] -%} + + + {{ env['name'] }} {{ Icon('link', classes='icon--medium icon--primary') }} + + + {% else -%} + + {{ env['name'] }} + + {{ Label(type="pending_creation", classes='label--below')}} + {%- endif %} {% if user_can(permissions.EDIT_ENVIRONMENT) -%} {{ ToggleButton( @@ -57,10 +68,6 @@ classes="environment-list__item__members" ) }} -
    - {% if env['pending'] -%} - {{ Label(type="changes_pending", classes='label--below')}} - {%- endif %}
    diff --git a/templates/components/label.html b/templates/components/label.html index 27f1c1b1..4d2679f1 100644 --- a/templates/components/label.html +++ b/templates/components/label.html @@ -9,6 +9,11 @@ "text": "changes pending", "color": "default", }, + "pending_creation": { + "icon": "clock", + "text": "pending creation", + "color": "default", + }, "ppoc": {"text": "primary point of contact"} } %} diff --git a/translations.yaml b/translations.yaml index d9615c4d..9f85ac63 100644 --- a/translations.yaml +++ b/translations.yaml @@ -417,6 +417,7 @@ portfolios: add_subscription: Add new subscription blank_slate: This Application has no environments disabled: ": Access Suspended" + funding_alert: "Application environments will not be created until the {name} portfolio is funded." environments_heading: Application Environments existing_application_title: "{application_name} Application Settings" member_count: "{count} Members" From 8093edbf0396c7a384ac91b16ecfce7654ac1810 Mon Sep 17 00:00:00 2001 From: hmbrink Date: Mon, 27 Jan 2020 13:02:06 -0500 Subject: [PATCH 17/24] User icon Added user icon from designs for top navigation --- static/icons/user.svg | 1 + templates/navigation/topbar.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 static/icons/user.svg diff --git a/static/icons/user.svg b/static/icons/user.svg new file mode 100644 index 00000000..a0da4770 --- /dev/null +++ b/static/icons/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/navigation/topbar.html b/templates/navigation/topbar.html index 2715c86f..f48f04ea 100644 --- a/templates/navigation/topbar.html +++ b/templates/navigation/topbar.html @@ -11,7 +11,7 @@
    {% if g.current_user %} - {{ Icon('avatar', classes='topbar__link-icon') }} + {{ Icon('user', classes='topbar__link-icon') }} {{ g.current_user.first_name + " " + g.current_user.last_name }} From 49a1a219ae36d23ca59239eaf1139e16464070dd Mon Sep 17 00:00:00 2001 From: dandds Date: Thu, 23 Jan 2020 06:25:35 -0500 Subject: [PATCH 18/24] Script for setting up database user, schema, and seed data. This script is for bootstrapping the initial database. It can be run via a container, but requires that a Postgres superuser's credentials be provided via our normal config. That way the superuser can provision a less-privileged user for the application's database connection. --- atst/domain/users.py | 7 +++- script/database_setup.py | 80 ++++++++++++++++++++++++++++++++++++++++ script/reset_database.py | 4 +- 3 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 script/database_setup.py diff --git a/atst/domain/users.py b/atst/domain/users.py index 5e09ce22..e5fdbad7 100644 --- a/atst/domain/users.py +++ b/atst/domain/users.py @@ -93,10 +93,13 @@ class Users(object): return user @classmethod - def give_ccpo_perms(cls, user): + def give_ccpo_perms(cls, user, commit=True): user.permission_sets = PermissionSets.get_all() db.session.add(user) - db.session.commit() + + if commit: + db.session.commit() + return user @classmethod diff --git a/script/database_setup.py b/script/database_setup.py new file mode 100644 index 00000000..bab95890 --- /dev/null +++ b/script/database_setup.py @@ -0,0 +1,80 @@ +# Add root application dir to the python path +import os +import sys +from contextlib import contextmanager + +parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +sys.path.append(parent_dir) + +import sqlalchemy +from alembic import config as alembic_config +import yaml + +from atst.app import make_config, make_app +from atst.database import db +from atst.domain.users import Users +from atst.models import User +from reset_database import reset_database + + +def database_setup(username, password, dbname, ccpo_users): + """docstring for database_setup""" + print( + f"Creating Postgres user role for '{username}' and granting all privileges to database '{dbname}'." + ) + try: + _create_database_user(username, password, dbname) + except sqlalchemy.exc.ProgrammingError as err: + raise err + print(f"Postgres user role '{username}' already exists.") + + print("Applying schema and seeding roles and permissions.") + reset_database() + print("Creating initial set of CCPO users.") + _add_ccpo_users(ccpo_users) + + +def _create_database_user(username, password, dbname): + conn = db.engine.connect() + + meta = sqlalchemy.MetaData(bind=conn) + meta.reflect() + + trans = conn.begin() + engine = trans.connection.engine + + engine.execute( + f"CREATE ROLE {username} WITH LOGIN NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION PASSWORD '{password}';\n" + + f"GRANT ALL PRIVILEGES ON DATABASE {dbname} TO {username};\n" + + f"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO {username}; \n" + + f"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON SEQUENCES TO {username}; \n" + + f"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON FUNCTIONS TO {username}; \n" + ) + + trans.commit() + + +def _add_ccpo_users(ccpo_users): + for user_data in ccpo_users: + user = User(**user_data) + Users.give_ccpo_perms(user, commit=False) + db.session.add(user) + + db.session.commit() + + +def _load_yaml(file_): + with open(file_) as f: + return yaml.safe_load(f) + + +if __name__ == "__main__": + config = make_config({"DISABLE_CRL_CHECK": True, "DEBUG": False}) + app = make_app(config) + with app.app_context(): + dbname = config.get("PGDATABASE", "atat") + username = sys.argv[1] + password = sys.argv[2] + ccpo_user_file = sys.argv[3] + ccpo_users = _load_yaml(ccpo_user_file) + database_setup(username, password, dbname, ccpo_users) diff --git a/script/reset_database.py b/script/reset_database.py index cfa63298..dda1c1ba 100644 --- a/script/reset_database.py +++ b/script/reset_database.py @@ -16,7 +16,9 @@ from atst.app import make_config, make_app def reset_database(): conn = db.engine.connect() - meta = sqlalchemy.MetaData(bind=conn, reflect=True) + meta = sqlalchemy.MetaData(bind=conn) + meta.reflect() + trans = conn.begin() # drop all tables From a8f6befc178b3367646d65d0b585a5e4ada4b637 Mon Sep 17 00:00:00 2001 From: dandds Date: Thu, 23 Jan 2020 15:35:35 -0500 Subject: [PATCH 19/24] secrets-tool command for bootstrapping database. This additional secrets-tool command can be used to run the database bootsrapping script (`script/database_setup.py`) inside an ATAT docker container against the Azure database. It sources the necessary keys from Key Vault. --- script/database_setup.py | 3 - terraform/secrets-tool/README.md | 38 ++++- terraform/secrets-tool/commands/database.py | 134 ++++++++++++++++++ terraform/secrets-tool/postgres-user.yaml | 4 + terraform/secrets-tool/secrets-tool | 8 +- .../secrets-tool/utils/keyvault/secrets.py | 11 +- 6 files changed, 185 insertions(+), 13 deletions(-) create mode 100644 terraform/secrets-tool/commands/database.py create mode 100644 terraform/secrets-tool/postgres-user.yaml diff --git a/script/database_setup.py b/script/database_setup.py index bab95890..623dfd8b 100644 --- a/script/database_setup.py +++ b/script/database_setup.py @@ -1,13 +1,11 @@ # Add root application dir to the python path import os import sys -from contextlib import contextmanager parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) sys.path.append(parent_dir) import sqlalchemy -from alembic import config as alembic_config import yaml from atst.app import make_config, make_app @@ -25,7 +23,6 @@ def database_setup(username, password, dbname, ccpo_users): try: _create_database_user(username, password, dbname) except sqlalchemy.exc.ProgrammingError as err: - raise err print(f"Postgres user role '{username}' already exists.") print("Applying schema and seeding roles and permissions.") diff --git a/terraform/secrets-tool/README.md b/terraform/secrets-tool/README.md index 28b44817..9ce07497 100644 --- a/terraform/secrets-tool/README.md +++ b/terraform/secrets-tool/README.md @@ -15,7 +15,7 @@ With both usernames and passwords generated, the application only needs to make Ex. ``` { - 'postgres_root_user': 'EzTEzSNLKQPHuJyPdPloIDCAlcibbl', + 'postgres_root_user': 'EzTEzSNLKQPHuJyPdPloIDCAlcibbl', 'postgres_root_password': "2+[A@E4:C=ubb/#R#'n Date: Sat, 25 Jan 2020 12:21:52 -0500 Subject: [PATCH 20/24] Create database with separate script. Creating the ATAT database requires a separate connection to one of the default Postgres databases, like `postgres`. This updates the scripts and secrets-tool command to handle creating the database. It also removes database creation from Terraform and updates the documentation. --- .dockerignore | 7 +--- notes.md | 6 +++ script/create_database.py | 41 +++++++++++++++++++++ terraform/README.md | 31 +++++++++++++--- terraform/modules/postgres/main.tf | 8 ---- terraform/modules/postgres/outputs.tf | 3 -- terraform/secrets-tool/README.md | 11 ++++++ terraform/secrets-tool/commands/database.py | 23 ++++++++---- users.yml | 3 ++ 9 files changed, 105 insertions(+), 28 deletions(-) create mode 100644 notes.md create mode 100644 script/create_database.py create mode 100644 users.yml diff --git a/.dockerignore b/.dockerignore index 7b9644ad..5674e27e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -21,11 +21,8 @@ LICENSE # Skip envrc .envrc -# Skip ansible-container stuff -ansible* -container.yml -meta.yml -requirements.yml +# Skip terraform +terraform # Skip kubernetes and Docker config stuff deploy diff --git a/notes.md b/notes.md new file mode 100644 index 00000000..4c1dd84f --- /dev/null +++ b/notes.md @@ -0,0 +1,6 @@ +- for setting up the database: + - create database + - create postgres user password? could we do this as a key? + - create user secret in application key vault + - execute SQL to create user +- we need an initial image to seed ACR with diff --git a/script/create_database.py b/script/create_database.py new file mode 100644 index 00000000..f21a857e --- /dev/null +++ b/script/create_database.py @@ -0,0 +1,41 @@ +# Add root application dir to the python path +import os +import sys + +parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +sys.path.append(parent_dir) + +import sqlalchemy + +from atst.app import make_config + + +def _root_connection(config, root_db): + # Assemble DATABASE_URI value + database_uri = "postgresql://{}:{}@{}:{}/{}".format( # pragma: allowlist secret + config.get("PGUSER"), + config.get("PGPASSWORD"), + config.get("PGHOST"), + config.get("PGPORT"), + root_db, + ) + engine = sqlalchemy.create_engine(database_uri) + return engine.connect() + + +def create_database(conn, dbname): + conn.execute("commit") + conn.execute(f"CREATE DATABASE {dbname};") + conn.close() + + return True + + +if __name__ == "__main__": + dbname = sys.argv[1] + config = make_config() + + conn = _root_connection(config, "postgres") + + print(f"Creating database {dbname}") + create_database(conn, dbname) diff --git a/terraform/README.md b/terraform/README.md index ec0fbdeb..8c8e7beb 100644 --- a/terraform/README.md +++ b/terraform/README.md @@ -1,11 +1,11 @@ # ATAT Terraform Welcome! You've found the ATAT IaC configurations. -ATAT is configured using terraform and a wrapper script called `secrets-tool`. With `terraform` we can configure infrastructure in a programatic way and ensure consistency across environments. +ATAT is configured using terraform and a wrapper script called `secrets-tool`. With `terraform` we can configure infrastructure in a programatic way and ensure consistency across environments. ## Directory Structure -**modules/** - Terraform modules. These are modules that can be re-used for multiple environments. +**modules/** - Terraform modules. These are modules that can be re-used for multiple environments. **providers/** - Specific environment configurations. (dev,production, etc) @@ -92,7 +92,7 @@ Check the output for errors. Sometimes the syntax is valid, but some of the conf # After running TF (Manual Steps) -## VM Scale Set +## VM Scale Set After running terraform, we need to make a manual change to the VM Scale Set that is used in the kubernetes. Terraform has a bug that is not applying this as of `v1.40` of the `azurerm` provider. In order to get the `SystemAssigned` identity to be set, it needs to be set manually in the console. @@ -253,7 +253,7 @@ Uncomment the `backend {}` section in the `provider.tf` file. Once uncommented, *Say `yes` to the question* -Now we need to update the Update `variables.tf` with the principals for the users in `admin_users` variable map. If these are not defined yet, just leave it as an empty set. +Now we need to update the Update `variables.tf` with the principals for the users in `admin_users` variable map. If these are not defined yet, just leave it as an empty set. Next, we'll create the operator keyvault. @@ -281,4 +281,25 @@ secrets-tool secrets --keyvault https://ops-jedidev-keyvault.vault.azure.net/ cr `terraform apply` -*[Configure AD for MFA](https://docs.microsoft.com/en-us/azure/vpn-gateway/openvpn-azure-ad-mfa)* \ No newline at end of file +*[Configure AD for MFA](https://docs.microsoft.com/en-us/azure/vpn-gateway/openvpn-azure-ad-mfa)* + +*Then we need an instance of the container* + +Change directories to the repo root. Ensure that you've checked out the staging or master branch: + +`docker build . --build-arg CSP=azure -f ./Dockerfile -t atat:latest` + +*Create secrets for ATAT database user* + +Change directories back to terraform/secrets-tool. There is a sample file there. Make sure you know the URL for the aplication Key Vault (distinct from the operator Key Vault). Run: + +`secrets-tool secrets --keyvault [application key vault URL] load -f ./postgres-user.yaml + +*Create the database, database user, schema, and initial data set* + + +This is discussed in more detail [here](https://github.com/dod-ccpo/atst/tree/staging/terraform/secrets-tool#setting-up-the-initial-atat-database). Be sure to read the requirements section. + +``` +secrets-tool database --keyvault [operator key vault URL] provision --app-keyvault [application key vault URL] --dbname jedidev-atat --dbhost [database host name] --ccpo-users /full/path/to/users.yml +``` diff --git a/terraform/modules/postgres/main.tf b/terraform/modules/postgres/main.tf index c3252264..29b6cc53 100644 --- a/terraform/modules/postgres/main.tf +++ b/terraform/modules/postgres/main.tf @@ -35,11 +35,3 @@ resource "azurerm_postgresql_virtual_network_rule" "sql" { subnet_id = var.subnet_id ignore_missing_vnet_service_endpoint = true } - -resource "azurerm_postgresql_database" "db" { - name = "${var.name}-${var.environment}-atat" - resource_group_name = azurerm_resource_group.sql.name - server_name = azurerm_postgresql_server.sql.name - charset = "UTF8" - collation = "en-US" -} diff --git a/terraform/modules/postgres/outputs.tf b/terraform/modules/postgres/outputs.tf index 1ff1dd65..e69de29b 100644 --- a/terraform/modules/postgres/outputs.tf +++ b/terraform/modules/postgres/outputs.tf @@ -1,3 +0,0 @@ -output "db_name" { - value = azurerm_postgresql_database.db.name -} diff --git a/terraform/secrets-tool/README.md b/terraform/secrets-tool/README.md index 9ce07497..bd407607 100644 --- a/terraform/secrets-tool/README.md +++ b/terraform/secrets-tool/README.md @@ -45,6 +45,17 @@ Requirements: - docker - A copy of the ATAT docker image. This can be built in the repo root with: `docker build . --build-arg CSP=azure -f ./Dockerfile -t atat:latest` - You need to know the hostname for the Postgres database. Your IP must either be whitelisted in its firewall rules or you must be behind the VPN. +- You will need a YAML file listing all the CCPO users to be added to the database, with the format: + +``` +- dod_id: "2323232323" + first_name: "Luke" + last_name: "Skywalker" +- dod_id: "5656565656" + first_name: "Han" + last_name: "Solo" +``` + - There should be a password for the ATAT database user in the application Key Vault, preferably named `PGPASSWORD`. You can load this by running `secrets-tool --keyvault [operator key vault url] load -f postgres-user.yml` and supplying YAML like: ``` diff --git a/terraform/secrets-tool/commands/database.py b/terraform/secrets-tool/commands/database.py index e181741c..98f404a5 100644 --- a/terraform/secrets-tool/commands/database.py +++ b/terraform/secrets-tool/commands/database.py @@ -116,19 +116,28 @@ def provision( logger.info("starting docker process") - cmd = ( - f"docker run -e PGHOST={dbhost}" - +f" -e PGPASSWORD=\"{root_password}\"" + create_database_cmd = ( + f"docker run -e PGHOST='{dbhost}'" + +f" -e PGPASSWORD='{root_password}'" +f" -e PGUSER='{root_name}@{dbhost}'" - +f" -e PGDATABASE=\"{dbname}\"" - +f" -e REDIS_HOST=host.docker.internal" + +f" -e PGDATABASE='{dbname}'" + +f" -e PGSSLMODE=require" + +f" {container}" + +f" .venv/bin/python script/create_database.py {dbname}" + ) + _run_cmd(create_database_cmd) + + seed_database_cmd = ( + f"docker run -e PGHOST='{dbhost}'" + +f" -e PGPASSWORD='{root_password}'" + +f" -e PGUSER='{root_name}@{dbhost}'" + +f" -e PGDATABASE='{dbname}'" +f" -e PGSSLMODE=require" +f" -v {ccpo_users}:/opt/atat/atst/users.yml" +f" {container}" +f" .venv/bin/python script/database_setup.py {user_username} '{user_password}' users.yml" ) - print(cmd) - _run_cmd(cmd) + _run_cmd(seed_database_cmd) database.add_command(provision) diff --git a/users.yml b/users.yml new file mode 100644 index 00000000..561031f2 --- /dev/null +++ b/users.yml @@ -0,0 +1,3 @@ +- dod_id: "2323232323" + first_name: "hi" + last_name: "bye" From adacb6ff1913a4c56e79d893922cae64d292b16a Mon Sep 17 00:00:00 2001 From: dandds Date: Mon, 27 Jan 2020 13:16:56 -0500 Subject: [PATCH 21/24] Cleanup cruft --- notes.md | 6 ----- script/database_setup.py | 9 ++++--- terraform/secrets-tool/commands/database.py | 26 ++++++++++----------- users.yml | 3 --- 4 files changed, 17 insertions(+), 27 deletions(-) delete mode 100644 notes.md delete mode 100644 users.yml diff --git a/notes.md b/notes.md deleted file mode 100644 index 4c1dd84f..00000000 --- a/notes.md +++ /dev/null @@ -1,6 +0,0 @@ -- for setting up the database: - - create database - - create postgres user password? could we do this as a key? - - create user secret in application key vault - - execute SQL to create user -- we need an initial image to seed ACR with diff --git a/script/database_setup.py b/script/database_setup.py index 623dfd8b..7784be05 100644 --- a/script/database_setup.py +++ b/script/database_setup.py @@ -16,7 +16,6 @@ from reset_database import reset_database def database_setup(username, password, dbname, ccpo_users): - """docstring for database_setup""" print( f"Creating Postgres user role for '{username}' and granting all privileges to database '{dbname}'." ) @@ -42,10 +41,10 @@ def _create_database_user(username, password, dbname): engine.execute( f"CREATE ROLE {username} WITH LOGIN NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION PASSWORD '{password}';\n" - + f"GRANT ALL PRIVILEGES ON DATABASE {dbname} TO {username};\n" - + f"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO {username}; \n" - + f"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON SEQUENCES TO {username}; \n" - + f"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON FUNCTIONS TO {username}; \n" + f"GRANT ALL PRIVILEGES ON DATABASE {dbname} TO {username};\n" + f"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO {username}; \n" + f"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON SEQUENCES TO {username}; \n" + f"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON FUNCTIONS TO {username}; \n" ) trans.commit() diff --git a/terraform/secrets-tool/commands/database.py b/terraform/secrets-tool/commands/database.py index 98f404a5..144ceee6 100644 --- a/terraform/secrets-tool/commands/database.py +++ b/terraform/secrets-tool/commands/database.py @@ -118,24 +118,24 @@ def provision( create_database_cmd = ( f"docker run -e PGHOST='{dbhost}'" - +f" -e PGPASSWORD='{root_password}'" - +f" -e PGUSER='{root_name}@{dbhost}'" - +f" -e PGDATABASE='{dbname}'" - +f" -e PGSSLMODE=require" - +f" {container}" - +f" .venv/bin/python script/create_database.py {dbname}" + f" -e PGPASSWORD='{root_password}'" + f" -e PGUSER='{root_name}@{dbhost}'" + f" -e PGDATABASE='{dbname}'" + f" -e PGSSLMODE=require" + f" {container}" + f" .venv/bin/python script/create_database.py {dbname}" ) _run_cmd(create_database_cmd) seed_database_cmd = ( f"docker run -e PGHOST='{dbhost}'" - +f" -e PGPASSWORD='{root_password}'" - +f" -e PGUSER='{root_name}@{dbhost}'" - +f" -e PGDATABASE='{dbname}'" - +f" -e PGSSLMODE=require" - +f" -v {ccpo_users}:/opt/atat/atst/users.yml" - +f" {container}" - +f" .venv/bin/python script/database_setup.py {user_username} '{user_password}' users.yml" + f" -e PGPASSWORD='{root_password}'" + f" -e PGUSER='{root_name}@{dbhost}'" + f" -e PGDATABASE='{dbname}'" + f" -e PGSSLMODE=require" + f" -v {ccpo_users}:/opt/atat/atst/users.yml" + f" {container}" + f" .venv/bin/python script/database_setup.py {user_username} '{user_password}' users.yml" ) _run_cmd(seed_database_cmd) diff --git a/users.yml b/users.yml deleted file mode 100644 index 561031f2..00000000 --- a/users.yml +++ /dev/null @@ -1,3 +0,0 @@ -- dod_id: "2323232323" - first_name: "hi" - last_name: "bye" From 15ac65752ff9f1246141693b0bad043a0744b0ed Mon Sep 17 00:00:00 2001 From: hmbrink Date: Mon, 27 Jan 2020 13:46:56 -0500 Subject: [PATCH 22/24] New portfolio header adjustments --- styles/components/_empty_state.scss | 2 +- styles/components/_portfolio_layout.scss | 4 ++++ templates/portfolios/new/step_1.html | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/styles/components/_empty_state.scss b/styles/components/_empty_state.scss index 71c9e742..e18a2faf 100644 --- a/styles/components/_empty_state.scss +++ b/styles/components/_empty_state.scss @@ -1,6 +1,6 @@ .empty-state { max-width: $max-panel-width; - background-color: #f6f6f7; + background-color: $color-gray-lightest; &--white { background-color: $color-white; diff --git a/styles/components/_portfolio_layout.scss b/styles/components/_portfolio_layout.scss index b5be6090..77b8b179 100644 --- a/styles/components/_portfolio_layout.scss +++ b/styles/components/_portfolio_layout.scss @@ -5,6 +5,10 @@ } } +.portfolio-header-new .portfolio-header__name { + padding: 1.6rem 0; +} + .portfolio-header { flex-direction: column; margin: $gap * 2 0; diff --git a/templates/portfolios/new/step_1.html b/templates/portfolios/new/step_1.html index dddc9047..3305d924 100644 --- a/templates/portfolios/new/step_1.html +++ b/templates/portfolios/new/step_1.html @@ -13,7 +13,7 @@

    {{ "portfolios.header" | translate }}

    -

    {{ "New Portfolio" }}

    +

    {{ 'portfolios.new.title' | translate }}

    {{ StickyCTA(text="portfolios.new.cta_step_1"|translate, context=("portfolios.new.sticky_header_context"|translate({"step": "1"}) )) }} From f0122c794d5b78578784e5765ad03940164858dc Mon Sep 17 00:00:00 2001 From: hmbrink Date: Mon, 27 Jan 2020 14:09:42 -0500 Subject: [PATCH 23/24] New portfolio header padding --- styles/components/_portfolio_layout.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles/components/_portfolio_layout.scss b/styles/components/_portfolio_layout.scss index 77b8b179..4a45cc5f 100644 --- a/styles/components/_portfolio_layout.scss +++ b/styles/components/_portfolio_layout.scss @@ -6,7 +6,7 @@ } .portfolio-header-new .portfolio-header__name { - padding: 1.6rem 0; + padding: 1.6rem 0; } .portfolio-header { From b630433aa80c41a7e72dc6a0036c21a1a74a370f Mon Sep 17 00:00:00 2001 From: dandds Date: Tue, 28 Jan 2020 14:10:55 -0500 Subject: [PATCH 24/24] Disable container privilege escalation. Per Azure best practice, disable a container's ability to escalate its privileges. https://docs.microsoft.com/en-us/azure/aks/developer-best-practices-pod-security#secure-pod-access-to-resources --- deploy/azure/azure.yml | 8 ++++++++ deploy/azure/crls-sync.yaml | 2 ++ deploy/shared/migration.yaml | 2 ++ 3 files changed, 12 insertions(+) diff --git a/deploy/azure/azure.yml b/deploy/azure/azure.yml index f988d5fc..d58f77a7 100644 --- a/deploy/azure/azure.yml +++ b/deploy/azure/azure.yml @@ -29,6 +29,8 @@ spec: containers: - name: atst image: $CONTAINER_IMAGE + securityContext: + allowPrivilegeEscalation: false env: - name: UWSGI_PROCESSES value: "2" @@ -64,6 +66,8 @@ spec: cpu: 940m - name: nginx image: nginx:alpine + securityContext: + allowPrivilegeEscalation: false ports: - containerPort: 8342 name: main-upgrade @@ -189,6 +193,8 @@ spec: containers: - name: atst-worker image: $CONTAINER_IMAGE + securityContext: + allowPrivilegeEscalation: false args: [ "/opt/atat/atst/.venv/bin/python", @@ -261,6 +267,8 @@ spec: containers: - name: atst-beat image: $CONTAINER_IMAGE + securityContext: + allowPrivilegeEscalation: false args: [ "/opt/atat/atst/.venv/bin/python", diff --git a/deploy/azure/crls-sync.yaml b/deploy/azure/crls-sync.yaml index 5fdcd7b8..221a0d8c 100644 --- a/deploy/azure/crls-sync.yaml +++ b/deploy/azure/crls-sync.yaml @@ -20,6 +20,8 @@ spec: containers: - name: crls image: $CONTAINER_IMAGE + securityContext: + allowPrivilegeEscalation: false command: [ "/bin/sh", "-c" ] diff --git a/deploy/shared/migration.yaml b/deploy/shared/migration.yaml index b5161114..4944aa0c 100644 --- a/deploy/shared/migration.yaml +++ b/deploy/shared/migration.yaml @@ -16,6 +16,8 @@ spec: containers: - name: migration image: $CONTAINER_IMAGE + securityContext: + allowPrivilegeEscalation: false command: [ "/bin/sh", "-c" ]