Browse Source

Review apps on AWS (#2062)

* CLDC-2812: update app config to run from relative root

* Deploy to staging on pushes to branch

* Add action mailer relative root config for review envs

* Temporary pipeline to deploy this branch for testing

* Update aws deploy pipeline to allow different prefixes for roles and tasks

* Prepare database when deploying review apps

* Update app nav and sentry to take account of relative root

* Update more fixed paths

* Update header root link path

* Rack attack path

* Revert "Deploy to staging on pushes to branch"

This reverts commit b05f13d474.

* Start updating workflows

* Update teardown pipeline to drop database

* Ensure destroy infra step runs after drop database

* Remove user_password_path because it can't be found

* Don't override path helpers in navigation items helper tests

* Checkout infra code to run workflow

* Try separating workflow call to job

* Sync with infra repo updates

* Use workflow on dev

* Don't trigger on push to branch

* Avoid rack attack path helper issue

* Update review apps teardown pipeline

* Update infra repo reference to main

* Fix linting

* Fix /logs redirect

* Fix lettings_logs_current and sales_logs_current checks in navigation items helper

* Fix existing bug in schemes nav item highlighting

* Use starts with rather than == in logs nav items current checks

* Split off non-support schemes current nav item checks

---------

Co-authored-by: Sam Seed <sam.seed@softwire.com>
test-merge-dpo-emails v0.3.82
Rachael Booth 1 year ago committed by GitHub
parent
commit
048e4c339b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 44
      .github/workflows/aws_deploy.yml
  2. 3
      .github/workflows/production_pipeline.yml
  3. 166
      .github/workflows/review_pipeline.yml
  4. 120
      .github/workflows/review_teardown_pipeline.yml
  5. 3
      .github/workflows/staging_pipeline.yml
  6. 2
      app/helpers/filters_helper.rb
  7. 36
      app/helpers/navigation_items_helper.rb
  8. 2
      app/views/layouts/application.html.erb
  9. 2
      app/views/organisations/index.html.erb
  10. 6
      config.ru
  11. 2
      config/application.rb
  12. 2
      config/environments/review.rb
  13. 1
      config/initializers/sentry.rb
  14. 2
      config/routes.rb
  15. 45
      spec/helpers/navigation_items_helper_spec.rb

44
.github/workflows/aws_deploy.yml

@ -6,7 +6,10 @@ on:
aws_account_id:
required: true
type: string
aws_resource_prefix:
aws_role_prefix:
required: true
type: string
aws_task_prefix:
required: true
type: string
environment:
@ -104,12 +107,12 @@ jobs:
uses: aws-actions/configure-aws-credentials@v3
with:
aws-region: ${{ env.aws_region }}
role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.aws_resource_prefix }}-deployment
role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.aws_role_prefix }}-deployment
role-chaining: true
- name: Download ad hoc task definition
env:
ad_hoc_task_definition: ${{ inputs.aws_resource_prefix }}-ad-hoc
ad_hoc_task_definition: ${{ inputs.aws_task_prefix }}-ad-hoc
run: |
aws ecs describe-task-definition --task-definition $ad_hoc_task_definition --query taskDefinition > ad-hoc-task-definition.json
@ -126,11 +129,28 @@ jobs:
with:
task-definition: ${{ steps.ad-hoc-task-def.outputs.task-definition }}
- name: Setup Database
if: ${{ inputs.environment == 'review' }}
env:
ad_hoc_task_definition: ${{ inputs.aws_task_prefix }}-ad-hoc
cluster: ${{ inputs.aws_task_prefix }}-app
service: ${{ inputs.aws_task_prefix }}-app
run: |
network=$(aws ecs describe-services --cluster $cluster --services $service --query services[0].networkConfiguration)
overrides='{ "containerOverrides" : [{ "name" : "app", "command" : ["bundle", "exec", "rake", "db:prepare"]}]}'
arn=$(aws ecs run-task --cluster $cluster --task-definition $ad_hoc_task_definition --network-configuration "$network" --overrides "$overrides" --group migrations --launch-type FARGATE --query tasks[0].taskArn)
echo "Waiting for db prepare task to complete"
temp=${arn##*/}
id=${temp%*\"}
aws ecs wait tasks-stopped --cluster $cluster --tasks $id
succeeded=$(aws ecs describe-tasks --cluster $cluster --tasks $id --query "tasks[0].stopCode == 'EssentialContainerExited' && to_string(tasks[0].containers[0].exitCode) == '0'")
if [ $succeeded == true ]; then exit 0; else exit 1; fi
- name: Run migrations task
env:
ad_hoc_task_definition: ${{ inputs.aws_resource_prefix }}-ad-hoc
cluster: ${{ inputs.aws_resource_prefix }}-app
service: ${{ inputs.aws_resource_prefix }}-app
ad_hoc_task_definition: ${{ inputs.aws_task_prefix }}-ad-hoc
cluster: ${{ inputs.aws_task_prefix }}-app
service: ${{ inputs.aws_task_prefix }}-app
run: |
network=$(aws ecs describe-services --cluster $cluster --services $service --query services[0].networkConfiguration)
overrides='{ "containerOverrides" : [{ "name" : "app", "command" : ["bundle", "exec", "rake", "db:migrate"]}]}'
@ -144,7 +164,7 @@ jobs:
- name: Download app service task definition
env:
app_task_definition: ${{ inputs.aws_resource_prefix }}-app
app_task_definition: ${{ inputs.aws_task_prefix }}-app
run: |
aws ecs describe-task-definition --task-definition $app_task_definition --query taskDefinition > app-task-definition.json
@ -159,14 +179,14 @@ jobs:
- name: Deploy updated application
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
cluster: ${{ inputs.aws_resource_prefix }}-app
service: ${{ inputs.aws_resource_prefix }}-app
cluster: ${{ inputs.aws_task_prefix }}-app
service: ${{ inputs.aws_task_prefix }}-app
task-definition: ${{ steps.app-task-def.outputs.task-definition }}
wait-for-service-stability: true
- name: Download sidekiq service task definition
env:
sidekiq_task_definition: ${{ inputs.aws_resource_prefix }}-sidekiq
sidekiq_task_definition: ${{ inputs.aws_task_prefix }}-sidekiq
run: |
aws ecs describe-task-definition --task-definition $sidekiq_task_definition --query taskDefinition > sidekiq-task-definition.json
@ -181,7 +201,7 @@ jobs:
- name: Deploy updated sidekiq
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
cluster: ${{ inputs.aws_resource_prefix }}-app
service: ${{ inputs.aws_resource_prefix }}-sidekiq
cluster: ${{ inputs.aws_task_prefix }}-app
service: ${{ inputs.aws_task_prefix }}-sidekiq
task-definition: ${{ steps.sidekiq-task-def.outputs.task-definition }}
wait-for-service-stability: true

3
.github/workflows/production_pipeline.yml

@ -215,7 +215,8 @@ jobs:
uses: ./.github/workflows/aws_deploy.yml
with:
aws_account_id: 977287343304
aws_resource_prefix: core-prod
aws_task_prefix: core-prod
aws_role_prefix: core-prod
environment: production
release_tag: ${{ needs.test.outputs.releasetag }}
permissions:

166
.github/workflows/review_pipeline.yml

@ -1,6 +1,7 @@
name: Review app pipeline
concurrency: ${{ github.workflow }}-${{ github.event.pull_request.number }}
concurrency:
group: review-${{ github.event.pull_request.number }}
on:
pull_request:
@ -15,160 +16,41 @@ defaults:
shell: bash
jobs:
postgres:
name: Provision postgres
runs-on: ubuntu-latest
environment: review
steps:
- name: Install Cloud Foundry CLI
run: |
wget --user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Safari/605.1.15" -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add -
echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list
sudo apt-get update
sudo apt-get install cf8-cli
- name: Provision postgres
env:
CF_USERNAME: ${{ secrets.CF_USERNAME }}
CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
CF_API_ENDPOINT: ${{ secrets.CF_API_ENDPOINT }}
CF_SPACE: dev
CF_ORG: ${{ secrets.CF_ORG }}
run: |
cf api $CF_API_ENDPOINT
cf auth
cf target -o $CF_ORG -s $CF_SPACE
cf create-service postgres tiny-unencrypted-13 dluhc-core-review-${{ github.event.pull_request.number }}-postgres --wait
infra:
name: Deploy review app infrastructure
uses: communitiesuk/submit-social-housing-lettings-and-sales-data-infrastructure/.github/workflows/create_review_app_infra.yml@main
with:
key: ${{ github.event.pull_request.number }}
app_repo_role: arn:aws:iam::815624722760:role/core-application-repo
permissions:
id-token: write
redis:
name: Provision redis
runs-on: ubuntu-latest
code:
name: Deploy review app code
needs: [infra]
uses: ./.github/workflows/aws_deploy.yml
with:
aws_account_id: 837698168072
aws_role_prefix: core-dev
aws_task_prefix: core-review-${{ github.event.pull_request.number }}
environment: review
permissions:
id-token: write
steps:
- name: Install Cloud Foundry CLI
run: |
wget --user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Safari/605.1.15" -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add -
echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list
sudo apt-get update
sudo apt-get install cf8-cli
- name: Provision redis
env:
CF_USERNAME: ${{ secrets.CF_USERNAME }}
CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
CF_API_ENDPOINT: ${{ secrets.CF_API_ENDPOINT }}
CF_SPACE: dev
CF_ORG: ${{ secrets.CF_ORG }}
run: |
cf api $CF_API_ENDPOINT
cf auth
cf target -o $CF_ORG -s $CF_SPACE
cf create-service redis micro-6.x dluhc-core-review-${{ github.event.pull_request.number }}-redis --wait
deploy:
name: Deploy review app
comment:
name: Add link to PR
needs: [code]
runs-on: ubuntu-latest
environment: review
needs: [postgres, redis]
permissions:
issues: write
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install Cloud Foundry CLI
run: |
wget --user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Safari/605.1.15" -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add -
echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list
sudo apt-get update
sudo apt-get install cf8-cli
- name: Setup review app without starting
env:
CF_USERNAME: ${{ secrets.CF_USERNAME }}
CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
CF_API_ENDPOINT: ${{ secrets.CF_API_ENDPOINT }}
CF_SPACE: dev
CF_ORG: ${{ secrets.CF_ORG }}
APP_NAME: dluhc-core-review-${{ github.event.pull_request.number }}
run: |
cf api $CF_API_ENDPOINT
cf auth
cf target -o $CF_ORG -s $CF_SPACE
cf push $APP_NAME \
--manifest ./config/cloud_foundry/review_manifest.yml \
--no-start
- name: Set environment variables
env:
APP_NAME: dluhc-core-review-${{ github.event.pull_request.number }}
API_USER: ${{ secrets.API_USER }}
API_KEY: ${{ secrets.API_KEY }}
GOVUK_NOTIFY_API_KEY: ${{ secrets.GOVUK_NOTIFY_API_KEY }}
RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
OS_DATA_KEY: ${{ secrets.OS_DATA_KEY }}
IMPORT_PAAS_INSTANCE: ${{ secrets.IMPORT_PAAS_INSTANCE }}
EXPORT_PAAS_INSTANCE: ${{ secrets.EXPORT_PAAS_INSTANCE }}
S3_CONFIG: ${{ secrets.S3_CONFIG }}
CSV_DOWNLOAD_PAAS_INSTANCE: ${{ secrets.CSV_DOWNLOAD_PAAS_INSTANCE }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
run: |
cf set-env $APP_NAME API_USER $API_USER
cf set-env $APP_NAME API_KEY $API_KEY
cf set-env $APP_NAME GOVUK_NOTIFY_API_KEY $GOVUK_NOTIFY_API_KEY
cf set-env $APP_NAME RAILS_MASTER_KEY $RAILS_MASTER_KEY
cf set-env $APP_NAME OS_DATA_KEY $OS_DATA_KEY
cf set-env $APP_NAME IMPORT_PAAS_INSTANCE $IMPORT_PAAS_INSTANCE
cf set-env $APP_NAME EXPORT_PAAS_INSTANCE "dluhc-core-review-export-bucket"
cf set-env $APP_NAME S3_CONFIG $S3_CONFIG
cf set-env $APP_NAME CSV_DOWNLOAD_PAAS_INSTANCE "dluhc-core-review-csv-bucket"
cf set-env $APP_NAME SENTRY_DSN $SENTRY_DSN
cf set-env $APP_NAME APP_HOST "https://dluhc-core-review-${{ github.event.pull_request.number }}.london.cloudapps.digital"
- name: Bind postgres service
env:
APP_NAME: dluhc-core-review-${{ github.event.pull_request.number }}
SERVICE_NAME: dluhc-core-review-${{ github.event.pull_request.number }}-postgres
run: |
cf bind-service $APP_NAME $SERVICE_NAME --wait
- name: Bind redis service
env:
APP_NAME: dluhc-core-review-${{ github.event.pull_request.number }}
SERVICE_NAME: dluhc-core-review-${{ github.event.pull_request.number }}-redis
run: |
cf bind-service $APP_NAME $SERVICE_NAME --wait
- name: Bind logit drain service
env:
APP_NAME: dluhc-core-review-${{ github.event.pull_request.number }}
SERVICE_NAME: logit-ssl-drain
run: |
cf bind-service $APP_NAME $SERVICE_NAME --wait
- name: Bind S3 buckets services
env:
APP_NAME: dluhc-core-review-${{ github.event.pull_request.number }}
run: |
cf bind-service $APP_NAME dluhc-core-review-csv-bucket --wait
cf bind-service $APP_NAME dluhc-core-review-export-bucket --wait
cf bind-service $APP_NAME dluhc-core-review-import-bucket --wait
- name: Start review app
env:
APP_NAME: dluhc-core-review-${{ github.event.pull_request.number }}
run: |
cf restage $APP_NAME
- name: Comment on PR with URL
uses: unsplash/comment-on-pr@v1.3.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
msg: "Created review app at https://dluhc-core-review-${{ github.event.pull_request.number }}.london.cloudapps.digital"
msg: "Created review app at https://review.submit-social-housing-data.levellingup.gov.uk/${{ github.event.pull_request.number }}"
check_for_duplicate_msg: true
duplicate_msg_pattern: Created review app at*

120
.github/workflows/review_teardown_pipeline.yml

@ -1,92 +1,64 @@
name: Review app teardown pipeline
concurrency:
group: review-${{ github.event.pull_request.number }}
on:
pull_request:
types:
- closed
workflow_dispatch:
defaults:
run:
shell: bash
env:
app_repo_role: arn:aws:iam::815624722760:role/core-application-repo
aws_account_id: 837698168072
aws_region: eu-west-2
aws_role_prefix: core-dev
aws_task_prefix: core-review-${{ github.event.pull_request.number }}
jobs:
app:
name: Teardown app
database:
name: Drop database
runs-on: ubuntu-latest
environment: review
permissions:
id-token: write
steps:
- name: Install Cloud Foundry CLI
run: |
wget --user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Safari/605.1.15" -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add -
echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list
sudo apt-get update
sudo apt-get install cf8-cli
- name: Teardown app
env:
CF_USERNAME: ${{ secrets.CF_USERNAME }}
CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
CF_API_ENDPOINT: ${{ secrets.CF_API_ENDPOINT }}
CF_SPACE: dev
CF_ORG: ${{ secrets.CF_ORG }}
run: |
cf api $CF_API_ENDPOINT
cf auth
cf target -o $CF_ORG -s $CF_SPACE
cf delete dluhc-core-review-${{ github.event.pull_request.number }} -f -r
postgres:
name: Teardown postgres
runs-on: ubuntu-latest
environment: review
needs: [app]
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v3
with:
aws-region: ${{ env.aws_region }}
role-to-assume: ${{ env.app_repo_role }}
steps:
- name: Install Cloud Foundry CLI
run: |
wget --user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Safari/605.1.15" -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add -
echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list
sudo apt-get update
sudo apt-get install cf8-cli
- name: Configure AWS credentials for review environment
uses: aws-actions/configure-aws-credentials@v3
with:
aws-region: ${{ env.aws_region }}
role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role_prefix }}-deployment
role-chaining: true
- name: Teardown postgres
- name: Drop Database
env:
CF_USERNAME: ${{ secrets.CF_USERNAME }}
CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
CF_API_ENDPOINT: ${{ secrets.CF_API_ENDPOINT }}
CF_SPACE: dev
CF_ORG: ${{ secrets.CF_ORG }}
run: |
cf api $CF_API_ENDPOINT
cf auth
cf target -o $CF_ORG -s $CF_SPACE
cf delete-service dluhc-core-review-${{ github.event.pull_request.number }}-postgres --wait -f
redis:
name: Teardown redis
runs-on: ubuntu-latest
environment: review
needs: [app]
steps:
- name: Install Cloud Foundry CLI
ad_hoc_task_definition: ${{ env.aws_task_prefix }}-ad-hoc
cluster: ${{ env.aws_task_prefix }}-app
service: ${{ env.aws_task_prefix }}-app
run: |
wget --user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Safari/605.1.15" -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add -
echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list
sudo apt-get update
sudo apt-get install cf8-cli
network=$(aws ecs describe-services --cluster $cluster --services $service --query services[0].networkConfiguration)
overrides='{ "containerOverrides" : [{ "name" : "app", "command" : ["bundle", "exec", "rake", "db:drop"]}]}'
arn=$(aws ecs run-task --cluster $cluster --task-definition $ad_hoc_task_definition --network-configuration "$network" --overrides "$overrides" --group migrations --launch-type FARGATE --query tasks[0].taskArn)
echo "Waiting for db prepare task to complete"
temp=${arn##*/}
id=${temp%*\"}
aws ecs wait tasks-stopped --cluster $cluster --tasks $id
succeeded=$(aws ecs describe-tasks --cluster $cluster --tasks $id --query "tasks[0].stopCode == 'EssentialContainerExited' && to_string(tasks[0].containers[0].exitCode) == '0'")
if [ $succeeded == true ]; then exit 0; else exit 1; fi
- name: Teardown redis
env:
CF_USERNAME: ${{ secrets.CF_USERNAME }}
CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
CF_API_ENDPOINT: ${{ secrets.CF_API_ENDPOINT }}
CF_SPACE: dev
CF_ORG: ${{ secrets.CF_ORG }}
run: |
cf api $CF_API_ENDPOINT
cf auth
cf target -o $CF_ORG -s $CF_SPACE
cf delete-service dluhc-core-review-${{ github.event.pull_request.number }}-redis --wait -f
infra:
name: Teardown review app
needs: [database]
uses: communitiesuk/submit-social-housing-lettings-and-sales-data-infrastructure/.github/workflows/destroy_review_app_infra.yml@main
with:
key: ${{ github.event.pull_request.number }}
app_repo_role: arn:aws:iam::815624722760:role/core-application-repo
permissions:
id-token: write

3
.github/workflows/staging_pipeline.yml

@ -238,7 +238,8 @@ jobs:
uses: ./.github/workflows/aws_deploy.yml
with:
aws_account_id: 107155005276
aws_resource_prefix: core-staging
aws_role_prefix: core-staging
aws_task_prefix: core-staging
environment: staging
permissions:
id-token: write

2
app/helpers/filters_helper.rb

@ -132,7 +132,7 @@ module FiltersHelper
end
def user_lettings_path?
request.path == "/lettings-logs"
request.path == lettings_logs_path
end
def user_or_org_lettings_path?

36
app/helpers/navigation_items_helper.rb

@ -5,18 +5,18 @@ module NavigationItemsHelper
if current_user.support?
[
NavigationItem.new("Organisations", organisations_path, organisations_current?(path)),
NavigationItem.new("Users", "/users", users_current?(path)),
NavigationItem.new("Users", users_path, users_current?(path)),
NavigationItem.new("Lettings logs", lettings_logs_path, lettings_logs_current?(path)),
NavigationItem.new("Sales logs", sales_logs_path, sales_logs_current?(path)),
NavigationItem.new("Schemes", "/schemes", supported_housing_schemes_current?(path)),
NavigationItem.new("Schemes", schemes_path, supported_housing_schemes_current?(path)),
].compact
else
[
NavigationItem.new("Lettings logs", lettings_logs_path, lettings_logs_current?(path)),
NavigationItem.new("Sales logs", sales_logs_path, sales_logs_current?(path)),
(NavigationItem.new("Schemes", "/schemes", supported_housing_schemes_current?(path)) if current_user.organisation.holds_own_stock? || current_user.organisation.stock_owners.present?),
(NavigationItem.new("Schemes", schemes_path, non_support_supported_housing_schemes_current?(path)) if current_user.organisation.holds_own_stock? || current_user.organisation.stock_owners.present?),
NavigationItem.new("Users", users_organisation_path(current_user.organisation), subnav_users_path?(path)),
NavigationItem.new("About your organisation", "/organisations/#{current_user.organisation.id}", subnav_details_path?(path)),
NavigationItem.new("About your organisation", organisation_path(current_user.organisation.id), subnav_details_path?(path)),
NavigationItem.new("Stock owners", stock_owners_organisation_path(current_user.organisation), stock_owners_path?(path)),
NavigationItem.new("Managing agents", managing_agents_organisation_path(current_user.organisation), managing_agents_path?(path)),
].compact
@ -25,11 +25,11 @@ module NavigationItemsHelper
def secondary_items(path, current_organisation_id)
[
NavigationItem.new("Lettings logs", "/organisations/#{current_organisation_id}/lettings-logs", subnav_lettings_logs_path?(path)),
NavigationItem.new("Sales logs", "/organisations/#{current_organisation_id}/sales-logs", subnav_sales_logs_path?(path)),
(NavigationItem.new("Schemes", "/organisations/#{current_organisation_id}/schemes", subnav_supported_housing_schemes_path?(path)) if current_user.organisation.holds_own_stock? || current_user.organisation.stock_owners.present?),
NavigationItem.new("Users", "/organisations/#{current_organisation_id}/users", subnav_users_path?(path)),
NavigationItem.new("About this organisation", "/organisations/#{current_organisation_id}", subnav_details_path?(path)),
NavigationItem.new("Lettings logs", lettings_logs_organisation_path(current_organisation_id), subnav_lettings_logs_path?(path)),
NavigationItem.new("Sales logs", sales_logs_organisation_path(current_organisation_id), subnav_sales_logs_path?(path)),
(NavigationItem.new("Schemes", schemes_organisation_path(current_organisation_id), subnav_supported_housing_schemes_path?(path)) if current_user.organisation.holds_own_stock? || current_user.organisation.stock_owners.present?),
NavigationItem.new("Users", users_organisation_path(current_organisation_id), subnav_users_path?(path)),
NavigationItem.new("About this organisation", organisation_path(current_organisation_id), subnav_details_path?(path)),
NavigationItem.new("Stock owners", stock_owners_organisation_path(current_organisation_id), stock_owners_path?(path)),
NavigationItem.new("Managing agents", managing_agents_organisation_path(current_organisation_id), managing_agents_path?(path)),
].compact
@ -37,31 +37,35 @@ module NavigationItemsHelper
def scheme_items(path, current_scheme_id, title)
[
NavigationItem.new("Scheme", "/schemes/#{current_scheme_id}", !path.include?("locations")),
NavigationItem.new(title, "/schemes/#{current_scheme_id}/locations", path.include?("locations")),
NavigationItem.new("Scheme", scheme_path(current_scheme_id), !path.include?("locations")),
NavigationItem.new(title, scheme_locations_path(current_scheme_id), path.include?("locations")),
]
end
private
def lettings_logs_current?(path)
path.starts_with?("/lettings-logs")
path.starts_with?(lettings_logs_path)
end
def sales_logs_current?(path)
path.starts_with?("/sales-logs")
path.starts_with?(sales_logs_path)
end
def users_current?(path)
path == "/users" || path.include?("/users/")
path == users_path || path.include?("/users/")
end
def supported_housing_schemes_current?(path)
path == "/schemes" || path.include?("/schemes/")
path == schemes_path || path.include?("/schemes/")
end
def non_support_supported_housing_schemes_current?(path)
path.starts_with?(organisations_path) && path.include?("/schemes") || path.include?("/schemes/")
end
def organisations_current?(path)
path == "/organisations" || path.include?("/organisations/")
path == organisations_path || path.include?("/organisations/")
end
def subnav_supported_housing_schemes_path?(path)

2
app/views/layouts/application.html.erb

@ -87,7 +87,7 @@
<%= govuk_header(
classes: govuk_header_classes(current_user),
service_url: current_user.nil? ? "/" : "/logs",
service_url: current_user.nil? ? root_path : logs_path,
navigation_classes: "govuk-header__navigation--end",
) do |component|
component.product_name(name: t("service_name"))

2
app/views/organisations/index.html.erb

@ -3,7 +3,7 @@
<% content_for :title, title %>
<%= render partial: "organisations/headings", locals: request.path == "/organisations" ? { main: "Organisations", sub: nil } : { main: @organisation.name, sub: "Organisations" } %>
<%= render partial: "organisations/headings", locals: request.path == organisations_path ? { main: "Organisations", sub: nil } : { main: @organisation.name, sub: "Organisations" } %>
<% if current_user.support? %>
<%= govuk_button_link_to "Create a new organisation", new_organisation_path, html: { method: :get } %>

6
config.ru

@ -2,5 +2,7 @@
require_relative "config/environment"
run Rails.application
Rails.application.load_server
map DataCollector::Application.config.relative_url_root || "/" do
run Rails.application
Rails.application.load_server
end

2
config/application.rb

@ -50,5 +50,7 @@ module DataCollector
helper_specs: false,
controller_specs: false
end
config.relative_url_root = ENV["RAILS_RELATIVE_URL_ROOT"]
end
end

2
config/environments/review.rb

@ -58,7 +58,7 @@ Rails.application.configure do
config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = { host: ENV["APP_HOST"] }
config.action_mailer.default_url_options = { host: ENV["APP_HOST"], script_name: Rails.application.config.relative_url_root }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",

1
config/initializers/sentry.rb

@ -24,3 +24,4 @@ Sentry.init do |config|
end
Sentry.set_tags("app_host": ENV["APP_HOST"])
Sentry.set_tags("url_root": ENV["RAILS_RELATIVE_URL_ROOT"])

2
config/routes.rb

@ -31,7 +31,7 @@ Rails.application.routes.draw do
root to: "start#index"
get "/logs", to: redirect("/lettings-logs")
get "/logs", to: redirect("lettings-logs")
get "/accessibility-statement", to: "content#accessibility_statement"
get "/privacy-notice", to: "content#privacy_notice"
get "/data-sharing-agreement", to: "content#data_sharing_agreement"

45
spec/helpers/navigation_items_helper_spec.rb

@ -3,9 +3,6 @@ require "rails_helper"
RSpec.describe NavigationItemsHelper do
let(:current_user) { create(:user, :data_coordinator) }
let(:users_path) { "/organisations/#{current_user.organisation.id}/users" }
let(:organisation_path) { "/organisations/#{current_user.organisation.id}" }
describe "#primary_items" do
context "when the user is a data coordinator" do
context "when the user's org does not own stock" do
@ -17,8 +14,8 @@ RSpec.describe NavigationItemsHelper do
[
NavigationItemsHelper::NavigationItem.new("Lettings logs", "/lettings-logs", true),
NavigationItemsHelper::NavigationItem.new("Sales logs", "/sales-logs", false),
NavigationItemsHelper::NavigationItem.new("Users", users_path, false),
NavigationItemsHelper::NavigationItem.new("About your organisation", organisation_path, false),
NavigationItemsHelper::NavigationItem.new("Users", "/organisations/#{current_user.organisation.id}/users", false),
NavigationItemsHelper::NavigationItem.new("About your organisation", "/organisations/#{current_user.organisation.id}", false),
NavigationItemsHelper::NavigationItem.new("Stock owners", "/organisations/#{current_user.organisation.id}/stock-owners", false),
NavigationItemsHelper::NavigationItem.new("Managing agents", "/organisations/#{current_user.organisation.id}/managing-agents", false),
]
@ -40,8 +37,8 @@ RSpec.describe NavigationItemsHelper do
NavigationItemsHelper::NavigationItem.new("Lettings logs", "/lettings-logs", true),
NavigationItemsHelper::NavigationItem.new("Sales logs", "/sales-logs", false),
NavigationItemsHelper::NavigationItem.new("Schemes", "/schemes", false),
NavigationItemsHelper::NavigationItem.new("Users", users_path, false),
NavigationItemsHelper::NavigationItem.new("About your organisation", organisation_path, false),
NavigationItemsHelper::NavigationItem.new("Users", "/organisations/#{current_user.organisation.id}/users", false),
NavigationItemsHelper::NavigationItem.new("About your organisation", "/organisations/#{current_user.organisation.id}", false),
NavigationItemsHelper::NavigationItem.new("Stock owners", "/organisations/#{current_user.organisation.id}/stock-owners", false),
NavigationItemsHelper::NavigationItem.new("Managing agents", "/organisations/#{current_user.organisation.id}/managing-agents", false),
]
@ -59,8 +56,8 @@ RSpec.describe NavigationItemsHelper do
NavigationItemsHelper::NavigationItem.new("Lettings logs", "/lettings-logs", true),
NavigationItemsHelper::NavigationItem.new("Sales logs", "/sales-logs", false),
NavigationItemsHelper::NavigationItem.new("Schemes", "/schemes", false),
NavigationItemsHelper::NavigationItem.new("Users", users_path, false),
NavigationItemsHelper::NavigationItem.new("About your organisation", organisation_path, false),
NavigationItemsHelper::NavigationItem.new("Users", "/organisations/#{current_user.organisation.id}/users", false),
NavigationItemsHelper::NavigationItem.new("About your organisation", "/organisations/#{current_user.organisation.id}", false),
NavigationItemsHelper::NavigationItem.new("Stock owners", "/organisations/#{current_user.organisation.id}/stock-owners", false),
NavigationItemsHelper::NavigationItem.new("Managing agents", "/organisations/#{current_user.organisation.id}/managing-agents", false),
]
@ -77,8 +74,8 @@ RSpec.describe NavigationItemsHelper do
NavigationItemsHelper::NavigationItem.new("Lettings logs", "/lettings-logs", false),
NavigationItemsHelper::NavigationItem.new("Sales logs", "/sales-logs", true),
NavigationItemsHelper::NavigationItem.new("Schemes", "/schemes", false),
NavigationItemsHelper::NavigationItem.new("Users", users_path, false),
NavigationItemsHelper::NavigationItem.new("About your organisation", organisation_path, false),
NavigationItemsHelper::NavigationItem.new("Users", "/organisations/#{current_user.organisation.id}/users", false),
NavigationItemsHelper::NavigationItem.new("About your organisation", "/organisations/#{current_user.organisation.id}", false),
NavigationItemsHelper::NavigationItem.new("Stock owners", "/organisations/#{current_user.organisation.id}/stock-owners", false),
NavigationItemsHelper::NavigationItem.new("Managing agents", "/organisations/#{current_user.organisation.id}/managing-agents", false),
]
@ -95,15 +92,15 @@ RSpec.describe NavigationItemsHelper do
NavigationItemsHelper::NavigationItem.new("Lettings logs", "/lettings-logs", false),
NavigationItemsHelper::NavigationItem.new("Sales logs", "/sales-logs", false),
NavigationItemsHelper::NavigationItem.new("Schemes", "/schemes", false),
NavigationItemsHelper::NavigationItem.new("Users", users_path, true),
NavigationItemsHelper::NavigationItem.new("About your organisation", organisation_path, false),
NavigationItemsHelper::NavigationItem.new("Users", "/organisations/#{current_user.organisation.id}/users", true),
NavigationItemsHelper::NavigationItem.new("About your organisation", "/organisations/#{current_user.organisation.id}", false),
NavigationItemsHelper::NavigationItem.new("Stock owners", "/organisations/#{current_user.organisation.id}/stock-owners", false),
NavigationItemsHelper::NavigationItem.new("Managing agents", "/organisations/#{current_user.organisation.id}/managing-agents", false),
]
end
it "returns navigation items with the users item set as current" do
expect(primary_items(users_path, current_user)).to eq(expected_navigation_items)
expect(primary_items("/organisations/#{current_user.organisation.id}/users", current_user)).to eq(expected_navigation_items)
end
end
@ -113,15 +110,15 @@ RSpec.describe NavigationItemsHelper do
NavigationItemsHelper::NavigationItem.new("Lettings logs", "/lettings-logs", false),
NavigationItemsHelper::NavigationItem.new("Sales logs", "/sales-logs", false),
NavigationItemsHelper::NavigationItem.new("Schemes", "/schemes", false),
NavigationItemsHelper::NavigationItem.new("Users", users_path, false),
NavigationItemsHelper::NavigationItem.new("About your organisation", organisation_path, true),
NavigationItemsHelper::NavigationItem.new("Users", "/organisations/#{current_user.organisation.id}/users", false),
NavigationItemsHelper::NavigationItem.new("About your organisation", "/organisations/#{current_user.organisation.id}", true),
NavigationItemsHelper::NavigationItem.new("Stock owners", "/organisations/#{current_user.organisation.id}/stock-owners", false),
NavigationItemsHelper::NavigationItem.new("Managing agents", "/organisations/#{current_user.organisation.id}/managing-agents", false),
]
end
it "returns navigation items with the users item set as current" do
expect(primary_items("#{organisation_path}/details", current_user)).to eq(expected_navigation_items)
expect(primary_items("/organisations/#{current_user.organisation.id}/details", current_user)).to eq(expected_navigation_items)
end
end
@ -132,7 +129,7 @@ RSpec.describe NavigationItemsHelper do
NavigationItemsHelper::NavigationItem.new("Sales logs", "/sales-logs", false),
NavigationItemsHelper::NavigationItem.new("Schemes", "/schemes", false),
NavigationItemsHelper::NavigationItem.new("Users", "/organisations/#{current_user.organisation.id}/users", false),
NavigationItemsHelper::NavigationItem.new("About your organisation", organisation_path, false),
NavigationItemsHelper::NavigationItem.new("About your organisation", "/organisations/#{current_user.organisation.id}", false),
NavigationItemsHelper::NavigationItem.new("Stock owners", "/organisations/#{current_user.organisation.id}/stock-owners", false),
NavigationItemsHelper::NavigationItem.new("Managing agents", "/organisations/#{current_user.organisation.id}/managing-agents", false),
]
@ -150,7 +147,7 @@ RSpec.describe NavigationItemsHelper do
NavigationItemsHelper::NavigationItem.new("Sales logs", "/sales-logs", false),
NavigationItemsHelper::NavigationItem.new("Schemes", "/schemes", false),
NavigationItemsHelper::NavigationItem.new("Users", "/organisations/#{current_user.organisation.id}/users", true),
NavigationItemsHelper::NavigationItem.new("About your organisation", organisation_path, false),
NavigationItemsHelper::NavigationItem.new("About your organisation", "/organisations/#{current_user.organisation.id}", false),
NavigationItemsHelper::NavigationItem.new("Stock owners", "/organisations/#{current_user.organisation.id}/stock-owners", false),
NavigationItemsHelper::NavigationItem.new("Managing agents", "/organisations/#{current_user.organisation.id}/managing-agents", false),
]
@ -168,7 +165,7 @@ RSpec.describe NavigationItemsHelper do
NavigationItemsHelper::NavigationItem.new("Sales logs", "/sales-logs", false),
NavigationItemsHelper::NavigationItem.new("Schemes", "/schemes", true),
NavigationItemsHelper::NavigationItem.new("Users", "/organisations/#{current_user.organisation.id}/users", false),
NavigationItemsHelper::NavigationItem.new("About your organisation", organisation_path, false),
NavigationItemsHelper::NavigationItem.new("About your organisation", "/organisations/#{current_user.organisation.id}", false),
NavigationItemsHelper::NavigationItem.new("Stock owners", "/organisations/#{current_user.organisation.id}/stock-owners", false),
NavigationItemsHelper::NavigationItem.new("Managing agents", "/organisations/#{current_user.organisation.id}/managing-agents", false),
]
@ -196,8 +193,8 @@ RSpec.describe NavigationItemsHelper do
[
NavigationItemsHelper::NavigationItem.new("Lettings logs", "/lettings-logs", true),
NavigationItemsHelper::NavigationItem.new("Sales logs", "/sales-logs", false),
NavigationItemsHelper::NavigationItem.new("Users", users_path, false),
NavigationItemsHelper::NavigationItem.new("About your organisation", organisation_path, false),
NavigationItemsHelper::NavigationItem.new("Users", "/organisations/#{current_user.organisation.id}/users", false),
NavigationItemsHelper::NavigationItem.new("About your organisation", "/organisations/#{current_user.organisation.id}", false),
NavigationItemsHelper::NavigationItem.new("Stock owners", "/organisations/#{current_user.organisation.id}/stock-owners", false),
NavigationItemsHelper::NavigationItem.new("Managing agents", "/organisations/#{current_user.organisation.id}/managing-agents", false),
]
@ -219,8 +216,8 @@ RSpec.describe NavigationItemsHelper do
NavigationItemsHelper::NavigationItem.new("Lettings logs", "/lettings-logs", true),
NavigationItemsHelper::NavigationItem.new("Sales logs", "/sales-logs", false),
NavigationItemsHelper::NavigationItem.new("Schemes", "/schemes", false),
NavigationItemsHelper::NavigationItem.new("Users", users_path, false),
NavigationItemsHelper::NavigationItem.new("About your organisation", organisation_path, false),
NavigationItemsHelper::NavigationItem.new("Users", "/organisations/#{current_user.organisation.id}/users", false),
NavigationItemsHelper::NavigationItem.new("About your organisation", "/organisations/#{current_user.organisation.id}", false),
NavigationItemsHelper::NavigationItem.new("Stock owners", "/organisations/#{current_user.organisation.id}/stock-owners", false),
NavigationItemsHelper::NavigationItem.new("Managing agents", "/organisations/#{current_user.organisation.id}/managing-agents", false),
]

Loading…
Cancel
Save