From 0a5060c07e9610f99bf371b2fe099b654b5c80af Mon Sep 17 00:00:00 2001 From: Nick Jackson Date: Tue, 27 Apr 2021 11:09:15 +0100 Subject: [PATCH 01/30] Update return to task list button on task views This makes the return action behave as expected, plus clarifies the language used. --- app/views/tasks/show.html.erb | 3 +-- config/locales/en.yml | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/views/tasks/show.html.erb b/app/views/tasks/show.html.erb index 81ae2753d..b08d34eb3 100644 --- a/app/views/tasks/show.html.erb +++ b/app/views/tasks/show.html.erb @@ -28,5 +28,4 @@ <% end %> -<%= link_to I18n.t("journey.specification.button"), journey_specification_path(@journey), class: "govuk-button" %> - +<%= link_to I18n.t("task.buttons.back"), journey_path(@journey), class: "govuk-button" %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 8ea1dcf2a..5efbed2e4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -86,6 +86,9 @@ en: status: not_started: Not started completed: Completed + task: + buttons: + back: Back to all questions journey_map: page_title: "Contentful entry map" edit_step_link_text: "Edit step in Contentful" From aa3feeaa3e5943fe05b38fd8d10c1e614be863b5 Mon Sep 17 00:00:00 2001 From: Nick Jackson Date: Tue, 27 Apr 2021 11:13:27 +0100 Subject: [PATCH 02/30] Remove duplicate task list title --- app/views/tasks/show.html.erb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/views/tasks/show.html.erb b/app/views/tasks/show.html.erb index b08d34eb3..cb3d6bd94 100644 --- a/app/views/tasks/show.html.erb +++ b/app/views/tasks/show.html.erb @@ -4,7 +4,6 @@

<%= @task.title %>

    -

    <%= @task.title %>

    • <% @steps.each do |step| %> From 3ca14d419bfbe9702d323177c970555d9da6666e Mon Sep 17 00:00:00 2001 From: Nick Jackson Date: Tue, 27 Apr 2021 11:13:47 +0100 Subject: [PATCH 03/30] Fix incorrect loop nesting in task view The incorrect looping was causing elements to terminate early, breaking formatting. This now correctly closes elements where expected. --- app/views/tasks/show.html.erb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/tasks/show.html.erb b/app/views/tasks/show.html.erb index cb3d6bd94..d67050a78 100644 --- a/app/views/tasks/show.html.erb +++ b/app/views/tasks/show.html.erb @@ -22,9 +22,9 @@ <% end %> <% end %> -
    -
  1. - <% end %> + <% end %> + +
<%= link_to I18n.t("task.buttons.back"), journey_path(@journey), class: "govuk-button" %> From 16b2a81fe81c74fd17dc1072a73b93d3be5d06eb Mon Sep 17 00:00:00 2001 From: Tom Hipkin Date: Tue, 27 Apr 2021 12:09:08 +0100 Subject: [PATCH 04/30] Cache CI runs to reduce run times by ~5 minutes This work is being copied across from our Rails Template. It was added after this project was created [1]. We are already using Docker Compose in CI on this project. However for context there is another pending change on the Rails Template[2] that includes a screenshot of how caching can behave. The approach here is that we create a shared area on disk called /tmp/docker-save. We load this in at the start of every test run. It will make a past docker image for this app available to the build context. Docker can then use this image and it's layers to optimise the build steps, opting for the cached version rather than rebuilding from scratch. If the cache is not hit (meaning the Dockerfile or gem.lock file changed) then it will add a new image into the cache at the end of the run. In this situation the builds will still take as long as they do now however this should be much less frequent. [1] https://github.com/dxw/rails-template/pull/147 [2] https://github.com/dxw/rails-template/pull/213 --- .github/workflows/continuous-integration.yml | 17 ++- CHANGELOG.md | 1 + Dockerfile | 125 ++++++++++++------- docker-compose.ci.yml | 5 +- docker-compose.test.yml | 2 +- docker-compose.yml | 2 +- 6 files changed, 102 insertions(+), 50 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index da57487dc..0adb800a2 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -13,7 +13,22 @@ jobs: steps: - name: Check out code uses: actions/checkout@v2 + - id: cache-docker + uses: actions/cache@v2 + with: + path: /tmp/docker-save + key: + docker-save-${{ hashFiles('Dockerfile', 'Gemfile.lock', + 'package-lock.json') }} + - name: Load cached Docker image + run: docker load -i /tmp/docker-save/snapshot.tar || true + if: steps.cache-docker.outputs.cache-hit == 'true' - name: Build - run: docker-compose -f docker-compose.ci.yml build + run: docker-compose -f docker-compose.ci.yml -p app build - name: Test run: docker-compose -f docker-compose.ci.yml run --rm test script/test + - name: Prepare Docker cache + run: + mkdir -p /tmp/docker-save && docker save app_test:latest -o + /tmp/docker-save/snapshot.tar && ls -lh /tmp/docker-save + if: always() && steps.cache-docker.outputs.cache-hit != 'true' diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c550876d..b0d74107b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ The format is based on [Keep a Changelog 1.0.0]. - existing specification page displays useful message when no specs exist - fix text input field width to fit full screen width - document where to find the service in the readme +- cache CI builds to reduce build times ## [release-009] - 2021-05-21 diff --git a/Dockerfile b/Dockerfile index ffd1c31eb..5e95b2bf4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,69 +1,89 @@ -# BUILD STAGE # -FROM ruby:2.6.6 AS build +# ------------------------------------------------------------------------------ +# Base +# ------------------------------------------------------------------------------ +FROM ruby:2.6.6 as base MAINTAINER dxw -ENV INSTALL_PATH /srv/app -ARG RAILS_ENV -ENV RAILS_ENV=${RAILS_ENV:-production} -ENV RACK_ENV=${RAILS_ENV:-production} - -WORKDIR $INSTALL_PATH +RUN curl -sL https://deb.nodesource.com/setup_10.x | bash +RUN curl https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - +RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list RUN apt-get update && apt-get install -qq -y \ build-essential \ libpq-dev \ --fix-missing --no-install-recommends -RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \ - && apt-get install -y nodejs -COPY package.json ./package.json -COPY package-lock.json ./package-lock.json +ENV APP_HOME /srv/app +ENV DEPS_HOME /deps + +ARG RAILS_ENV +ENV RAILS_ENV ${RAILS_ENV:-production} +ENV NODE_ENV ${RAILS_ENV:-production} + +# ------------------------------------------------------------------------------ +# Dependencies +# ------------------------------------------------------------------------------ +FROM base AS dependencies + +RUN mkdir -p ${DEPS_HOME} +WORKDIR $DEPS_HOME +RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \ + && apt-get install -y nodejs \ + && npm install --global yarn + +# Install Javascript dependencies +COPY package-lock.json $DEPS_HOME/package-lock.json +COPY package.json $DEPS_HOME/package.json RUN npm install -COPY Gemfile* ./ -RUN gem install bundler:2.1.4 --no-document +# Install Ruby dependencies +COPY Gemfile $DEPS_HOME/Gemfile +COPY Gemfile.lock $DEPS_HOME/Gemfile.lock +RUN gem update --system +RUN gem install bundler -v 2.2.16 -ARG BUNDLE_EXTRA_GEM_GROUPS -ENV BUNDLE_GEM_GROUPS=${BUNDLE_EXTRA_GEM_GROUPS:-"production"} +ENV BUNDLE_GEM_GROUPS=$RAILS_ENV +RUN bundle config set frozen "true" RUN bundle config set no-cache "true" RUN bundle config set with $BUNDLE_GEM_GROUPS -RUN bundle install --no-binstubs --retry=3 --jobs=4 +RUN bundle install --no-binstubs --retry=10 --jobs=4 -# Copy app code (sorted by vague frequency of change for caching) -RUN mkdir -p ${INSTALL_PATH}/log -RUN mkdir -p ${INSTALL_PATH}/tmp - -COPY config.ru ${INSTALL_PATH}/config.ru -COPY Rakefile ${INSTALL_PATH}/Rakefile - -COPY public ${INSTALL_PATH}/public -COPY vendor ${INSTALL_PATH}/vendor -COPY bin ${INSTALL_PATH}/bin -COPY lib ${INSTALL_PATH}/lib -COPY config ${INSTALL_PATH}/config -COPY db ${INSTALL_PATH}/db -COPY script ${INSTALL_PATH}/script -COPY spec ${INSTALL_PATH}/spec -COPY app ${INSTALL_PATH}/app -# End - -# RELEASE STAGE # -FROM ruby:2.6.6 AS release +# ------------------------------------------------------------------------------ +# Web +# ------------------------------------------------------------------------------ +FROM dependencies AS web -ENV INSTALL_PATH /srv/app -ARG RAILS_ENV -ENV RAILS_ENV=${RAILS_ENV:-production} -ENV RACK_ENV=${RAILS_ENV:-production} +RUN mkdir -p ${APP_HOME} +WORKDIR ${APP_HOME} -WORKDIR $INSTALL_PATH +# Copy app code (sorted by vague frequency of change for caching) +RUN mkdir -p ${APP_HOME}/log +RUN mkdir -p ${APP_HOME}/tmp + +COPY config.ru ${APP_HOME}/config.ru +COPY Rakefile ${APP_HOME}/Rakefile + +COPY Gemfile $APP_HOME/Gemfile +COPY Gemfile.lock $APP_HOME/Gemfile.lock + +COPY public ${APP_HOME}/public +COPY vendor ${APP_HOME}/vendor +COPY bin ${APP_HOME}/bin +COPY lib ${APP_HOME}/lib +COPY config ${APP_HOME}/config +COPY db ${APP_HOME}/db +COPY script ${APP_HOME}/script +COPY app ${APP_HOME}/app +# End -RUN gem install bundler:2.1.4 --no-document +# Create tmp/pids +RUN mkdir -p tmp/pids -COPY --from=build /usr/local/bundle/ /usr/local/bundle/ -COPY --from=build $INSTALL_PATH $INSTALL_PATH +# This must be ordered before rake assets:precompile +RUN cp -R $DEPS_HOME/node_modules $APP_HOME/node_modules +RUN cp -R $DEPS_HOME/node_modules/govuk-frontend/govuk/assets $APP_HOME/app/assets -# Compiling assets requires a key to exist: https://github.com/rails/rails/issues/32947 RUN if [ "$RAILS_ENV" = "production" ]; then \ RAILS_ENV=production SECRET_KEY_BASE="key" bundle exec rake assets:precompile; \ fi @@ -75,3 +95,16 @@ ENTRYPOINT ["/docker-entrypoint.sh"] EXPOSE 3000 CMD ["bundle", "exec", "rails", "server"] + +# ------------------------------------------------------------------------------ +# Test +# ------------------------------------------------------------------------------ +FROM web as test + +RUN apt-get install -qq -y shellcheck + +COPY package.json ${APP_HOME}/package.json +COPY package-lock.json ${APP_HOME}/package-lock.json + +COPY .rspec ${APP_HOME}/.rspec +COPY spec ${APP_HOME}/spec diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml index 97865e5c3..8615636fd 100644 --- a/docker-compose.ci.yml +++ b/docker-compose.ci.yml @@ -3,9 +3,12 @@ services: test: build: context: . + target: test args: RAILS_ENV: "test" - BUNDLE_EXTRA_GEM_GROUPS: "test" + cache_from: + - app_test:latest + image: app_test command: bundle exec rake ports: - "3000:3000" diff --git a/docker-compose.test.yml b/docker-compose.test.yml index 841f123ec..48b9c5692 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -3,9 +3,9 @@ services: test: build: context: . + target: test args: RAILS_ENV: "test" - BUNDLE_EXTRA_GEM_GROUPS: "test" command: bundle exec rake ports: - "3000:3000" diff --git a/docker-compose.yml b/docker-compose.yml index 4e6d8ed59..d0ed5c53d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,9 +3,9 @@ services: web: build: context: . + target: web args: RAILS_ENV: "development" - BUNDLE_EXTRA_GEM_GROUPS: "development test" command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" ports: - "3000:3000" From 25d33b6137c40f8be199d4451686a39bcfca66aa Mon Sep 17 00:00:00 2001 From: Tom Hipkin Date: Tue, 27 Apr 2021 16:35:20 +0100 Subject: [PATCH 05/30] Always precompile assets on CI so we can catch problems before deployments Because pull requests run CI in RAILS_ENV=test the image builds and the tests pass fine. However, when the same happens for deployment with RAILS_ENV=production then it can fail to precomplile and we have to start a new pull request to fix it whilst the deployment pipeline is stuck. It's not ideal to add every new critical variable to this file. Doing this ensures that the app can always load in order for running this rake command. No actual values are necessasry. --- Dockerfile | 16 +++++++++++++--- doc/managing-environment-variables.md | 2 ++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5e95b2bf4..bc8118c26 100644 --- a/Dockerfile +++ b/Dockerfile @@ -84,9 +84,19 @@ RUN mkdir -p tmp/pids RUN cp -R $DEPS_HOME/node_modules $APP_HOME/node_modules RUN cp -R $DEPS_HOME/node_modules/govuk-frontend/govuk/assets $APP_HOME/app/assets -RUN if [ "$RAILS_ENV" = "production" ]; then \ - RAILS_ENV=production SECRET_KEY_BASE="key" bundle exec rake assets:precompile; \ - fi +RUN RAILS_ENV=production \ + SECRET_KEY_BASE="key" \ + APPLICATION_URL= \ + CONTENTFUL_URL= \ + CONTENTFUL_SPACE= \ + CONTENTFUL_ENVIRONMENT= \ + CONTENTFUL_ACCESS_TOKEN= \ + CONTENTFUL_DEFAULT_CATEGORY_ENTRY_ID= \ + CONTENTFUL_PREVIEW_APP= \ + CONTENTFUL_ENTRY_CACHING= \ + SUPPORT_EMAIL= \ + REDIS_URL= \ + bundle exec rake assets:precompile COPY ./docker-entrypoint.sh / RUN chmod +x /docker-entrypoint.sh diff --git a/doc/managing-environment-variables.md b/doc/managing-environment-variables.md index 2da653fb3..fb65e9479 100644 --- a/doc/managing-environment-variables.md +++ b/doc/managing-environment-variables.md @@ -8,3 +8,5 @@ To manage sensitive environment variables: 1. Add the new key and safe default value to the `/.env.example` file eg. `ROLLBAR_TOKEN=ROLLBAR_TOKEN` 2. Add the new key and real value to your local `/.env.development.local` file, which should never be checked into Git. This file will look something like `ROLLBAR_TOKEN=123456789` + +Add critical environment variable keys to the Dockerfile where `rake assets:precompile` is run. From 1a3578157ffb963a73b4eb510e9edcc429d78edc Mon Sep 17 00:00:00 2001 From: Tom Hipkin Date: Tue, 27 Apr 2021 18:12:20 +0100 Subject: [PATCH 06/30] Fix production builds by removing Yarn By installing yarn up front, when we run `rake assets:precompile` it will first call yarn [1]. This is problematic because it seems to effectively install a fresh and uninstall node_modules that have been copied across. I don't know what the answer is to adding Yarn. Perhaps when also using wepbacker would solve this issue. For now, we remove this accidental install to get builds working again. Without this fix the following error occurs: ``` Step 48/59 : RUN if [ "$RAILS_ENV" = "***" ]; then RAILS_ENV=*** SECRET_KEY_BASE="key" bundle exec rake assets:precompile; fi ---> Running in 2ea2d122cfbd yarn install v1.22.10 info No lockfile found. [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh packages... Done in 0.13s. rake aborted! Sprockets::FileNotFound: couldn't find file 'govuk-frontend/govuk/all.js' with type 'application/javascript' Checked in these paths: /srv/app/app/assets/assets /srv/app/app/assets/config /srv/app/app/assets/images /srv/app/app/assets/javascripts /srv/app/app/assets/stylesheets /usr/local/bundle/gems/jquery-rails-4.4.0/vendor/assets/javascripts /usr/local/bundle/gems/coffee-rails-5.0.0/lib/assets/javascripts /usr/local/bundle/gems/actioncable-6.1.3.1/app/assets/javascripts /usr/local/bundle/gems/activestorage-6.1.3.1/app/assets/javascripts /usr/local/bundle/gems/actionview-6.1.3.1/lib/assets/compiled /usr/local/bundle/gems/turbolinks-source-5.2.0/lib/assets/javascripts /srv/app/node_modules/govuk-frontend/govuk/assets/images /srv/app/node_modules/govuk-frontend/govuk/assets/fonts /srv/app/node_modules /srv/app/app/assets/javascripts/application.js:13 ``` [1] https://github.com/rails/rails/blob/v5.2.2.1/railties/lib/rails/tasks/yarn.rake --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index bc8118c26..3e18e9aa5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,8 +29,7 @@ RUN mkdir -p ${DEPS_HOME} WORKDIR $DEPS_HOME RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \ - && apt-get install -y nodejs \ - && npm install --global yarn + && apt-get install -y nodejs # Install Javascript dependencies COPY package-lock.json $DEPS_HOME/package-lock.json From e8884de34627d09d66cc193d53ddb8bc377251ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Apr 2021 10:03:01 +0000 Subject: [PATCH 07/30] Bump brakeman from 5.0.0 to 5.0.1 Bumps [brakeman](https://github.com/presidentbeef/brakeman) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/presidentbeef/brakeman/releases) - [Changelog](https://github.com/presidentbeef/brakeman/blob/main/CHANGES.md) - [Commits](https://github.com/presidentbeef/brakeman/compare/v5.0.0...v5.0.1) Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index b9f09ba0a..e7b91ea8b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -73,7 +73,7 @@ GEM bindex (0.8.1) bootsnap (1.7.4) msgpack (~> 1.0) - brakeman (5.0.0) + brakeman (5.0.1) builder (3.2.4) bullet (6.1.4) activesupport (>= 3.0.0) From c581689aead75c3c915876d9cdf19208c8f79a79 Mon Sep 17 00:00:00 2001 From: Lorna Date: Wed, 28 Apr 2021 17:26:49 +0100 Subject: [PATCH 08/30] Inline scripts now use nonce's When we switched on the content security policy, we didn't allow inline scripts. We now use the built in helper to generate a nonce for these so the scripts can be loaded. Co-authored-by: Nick Jackson --- app/views/layouts/application.html.erb | 10 ++++++---- config/initializers/content_security_policy.rb | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index c27cff712..d952ea5d7 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -23,12 +23,14 @@ <%= csrf_meta_tags %> + + <%= csp_meta_tag %> - + <% end -%> Skip to main content @@ -99,9 +101,9 @@ <%= javascript_include_tag "application", "data-turbolinks-track" => "reload" %> - + <% end -%> diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 731b1d880..e82dfcaa4 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -20,6 +20,8 @@ # policy.report_uri "/csp-violation-report-endpoint" end +Rails.application.config.content_security_policy_nonce_generator = ->(request) { SecureRandom.base64(16) } + # If you are using UJS then enable automatic nonce generation # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } From 36d013c0223371b01a10e0bdc18bcb6f3235983b Mon Sep 17 00:00:00 2001 From: Tom Hipkin Date: Tue, 27 Apr 2021 16:25:02 +0100 Subject: [PATCH 09/30] Error pages are styled The default Rails errors were still being served on live environments because they were in public/500.html etc. Make these error pages styled. In future we could make static files that are self contained with styles to be served by a CDN if the application becomes unavailable. --- CHANGELOG.md | 2 + app/controllers/application_controller.rb | 2 +- app/controllers/errors_controller.rb | 18 +++++ app/controllers/preview/entries_controller.rb | 2 +- .../errors/internal_server_error.html.erb | 16 +++++ app/views/errors/not_found.html.erb | 16 +++++ app/views/errors/unacceptable.html.erb | 16 +++++ config/locales/en.yml | 10 +++ config/routes.rb | 5 ++ public/404.html | 67 ------------------- public/422.html | 67 ------------------- public/500.html | 66 ------------------ spec/requests/errors_spec.rb | 30 +++++++++ 13 files changed, 115 insertions(+), 202 deletions(-) create mode 100644 app/controllers/errors_controller.rb create mode 100644 app/views/errors/internal_server_error.html.erb create mode 100644 app/views/errors/not_found.html.erb create mode 100644 app/views/errors/unacceptable.html.erb delete mode 100644 public/404.html delete mode 100644 public/422.html delete mode 100644 public/500.html create mode 100644 spec/requests/errors_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index b0d74107b..3abccfe68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog 1.0.0]. ## [Unreleased] +- error pages are styled + ## [release-010] - 2021-05-27 - add header and footer information for feedback and data requests diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ab911d644..e2ad2d0c2 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -37,6 +37,6 @@ def current_journey def check_user_belongs_to_journey? return true if current_journey.user == current_user - render file: "public/404.html", status: :not_found, layout: false + render "errors/not_found", status: 404 end end diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb new file mode 100644 index 000000000..615431d63 --- /dev/null +++ b/app/controllers/errors_controller.rb @@ -0,0 +1,18 @@ +class ErrorsController < ApplicationController + skip_before_action :authenticate_user! + + def internal_server_error + render "errors/internal_server_error", + status: 500 + end + + def not_found + render "errors/not_found", + status: 404 + end + + def unacceptable + render "errors/unacceptable", + status: 422 + end +end diff --git a/app/controllers/preview/entries_controller.rb b/app/controllers/preview/entries_controller.rb index faaad3f99..5e2fbb1b4 100644 --- a/app/controllers/preview/entries_controller.rb +++ b/app/controllers/preview/entries_controller.rb @@ -26,6 +26,6 @@ def entry_id def check_app_is_running_in_preview_env return if ENV["CONTENTFUL_PREVIEW_APP"].eql?("true") - render file: "public/404.html", status: :not_found, layout: false + render "errors/not_found", status: 404 end end diff --git a/app/views/errors/internal_server_error.html.erb b/app/views/errors/internal_server_error.html.erb new file mode 100644 index 000000000..bfebe5005 --- /dev/null +++ b/app/views/errors/internal_server_error.html.erb @@ -0,0 +1,16 @@ +<%= content_for :page_title_prefix, t("errors.internal_server_error.page_title") %> +
+
+
+

+ <%= t("errors.internal_server_error.page_title") %> +

+

+ <%= t("errors.internal_server_error.page_body") %> +

+

+ <%= link_to t("errors.go_home"), root_path, class: "govuk-link" %> +

+
+
+
diff --git a/app/views/errors/not_found.html.erb b/app/views/errors/not_found.html.erb new file mode 100644 index 000000000..78d0e4f58 --- /dev/null +++ b/app/views/errors/not_found.html.erb @@ -0,0 +1,16 @@ +<%= content_for :page_title_prefix, t("errors.not_found.page_title") %> +
+
+
+

+ <%= t("errors.not_found.page_title") %> +

+

+ <%= t("errors.not_found.page_body") %> +

+

+ <%= link_to t("errors.go_home"), root_path, class: "govuk-link" %> +

+
+
+
diff --git a/app/views/errors/unacceptable.html.erb b/app/views/errors/unacceptable.html.erb new file mode 100644 index 000000000..23ea85f2a --- /dev/null +++ b/app/views/errors/unacceptable.html.erb @@ -0,0 +1,16 @@ +<%= content_for :page_title_prefix, t("errors.unacceptable.page_title") %> +
+
+
+

+ <%= t("errors.unacceptable.page_title") %> +

+

+ <%= t("errors.unacceptable.page_body") %> +

+

+ <%= link_to t("errors.go_home"), root_path, class: "govuk-link" %> +

+
+
+
diff --git a/config/locales/en.yml b/config/locales/en.yml index 5efbed2e4..990bff116 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -95,6 +95,16 @@ en: preview_step_link_text: "Preview step in service" spec_template_tag_title: "Specification tag" errors: + go_home: "Back to the service" + internal_server_error: + page_title: "Internal server error" + page_body: "Sorry, there is a problem with the service. Please try again later." + not_found: + page_title: "Page not found" + page_body: "Page not found. If you typed the web address, check it is correct. If you pasted the web address, check you copied the entire address." + unacceptable: + page_title: "Unacceptable request" + page_body: "There was a problem with your request." contentful_entry_not_found: page_title: "An unexpected error occurred" page_body: "The service has had a problem trying to retrieve the required step. The team have been notified of this problem and you should be able to retry shortly." diff --git a/config/routes.rb b/config/routes.rb index 83b497b30..16013d55b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -27,4 +27,9 @@ end get "dashboard", to: "dashboard#show" + + # Errors + get "/404", to: "errors#not_found" + get "/422", to: "errors#unacceptable" + get "/500", to: "errors#internal_server_error" end diff --git a/public/404.html b/public/404.html deleted file mode 100644 index 2be3af26f..000000000 --- a/public/404.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - The page you were looking for doesn't exist (404) - - - - - - -
-
-

The page you were looking for doesn't exist.

-

You may have mistyped the address or the page may have moved.

-
-

If you are the application owner check the logs for more information.

-
- - diff --git a/public/422.html b/public/422.html deleted file mode 100644 index c08eac0d1..000000000 --- a/public/422.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - The change you wanted was rejected (422) - - - - - - -
-
-

The change you wanted was rejected.

-

Maybe you tried to change something you didn't have access to.

-
-

If you are the application owner check the logs for more information.

-
- - diff --git a/public/500.html b/public/500.html deleted file mode 100644 index 78a030af2..000000000 --- a/public/500.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - We're sorry, but something went wrong (500) - - - - - - -
-
-

We're sorry, but something went wrong.

-
-

If you are the application owner check the logs for more information.

-
- - diff --git a/spec/requests/errors_spec.rb b/spec/requests/errors_spec.rb new file mode 100644 index 000000000..0bd0489ee --- /dev/null +++ b/spec/requests/errors_spec.rb @@ -0,0 +1,30 @@ +require "rails_helper" + +RSpec.describe "Errors", type: :request do + describe "internal_server_error" do + it "the 500 endpoint returns the expected status and error message" do + get "/500" + expect(response).to have_http_status(:internal_server_error) + expect(response.body).to include(I18n.t("errors.internal_server_error.page_title")) + expect(response.body).to include(I18n.t("errors.internal_server_error.page_body")) + end + end + + describe "not_found" do + it "the 404 endpoint returns the expected status and error message" do + get "/404" + expect(response).to have_http_status(:not_found) + expect(response.body).to include(I18n.t("errors.not_found.page_title")) + expect(response.body).to include(I18n.t("errors.not_found.page_body")) + end + end + + describe "unacceptable" do + it "the 422 endpoint returns the expected status and error message" do + get "/422" + expect(response).to have_http_status(:unprocessable_entity) + expect(response.body).to include(I18n.t("errors.unacceptable.page_title")) + expect(response.body).to include(I18n.t("errors.unacceptable.page_body")) + end + end +end From 8a0b1921647b42b4091f90d5cf251b37cc65eb53 Mon Sep 17 00:00:00 2001 From: Lorna Date: Thu, 29 Apr 2021 12:04:42 +0100 Subject: [PATCH 10/30] Remove line duplication for security nonce generator --- config/initializers/content_security_policy.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index e82dfcaa4..d42d2573a 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -20,10 +20,8 @@ # policy.report_uri "/csp-violation-report-endpoint" end -Rails.application.config.content_security_policy_nonce_generator = ->(request) { SecureRandom.base64(16) } - # If you are using UJS then enable automatic nonce generation -# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } +Rails.application.config.content_security_policy_nonce_generator = ->(request) { SecureRandom.base64(16) } # Set the nonce only to specific directives # Rails.application.config.content_security_policy_nonce_directives = %w(script-src) From 9fab296bfcfa9fbac941fca8ce0b957bb40a7c83 Mon Sep 17 00:00:00 2001 From: Tom Hipkin Date: Tue, 27 Apr 2021 15:59:54 +0100 Subject: [PATCH 11/30] Always log info about Contentful webhook receipts This was useful for debugging our Contentful webhooks as they weren't working correctly. In this case the Contentful webhook didn't have the right content type set. Instead of removing this logging, let's make it permenant so we can quickly review basic data on how the service is performing. We don't want a unique Rollbar event to occur for every entry id so we remove it from the title and move it to the payload. This will mean there should only be a single rollbar item per environment with many occurences, much easier to manage. --- CHANGELOG.md | 1 + .../api/contentful/entries_controller.rb | 2 +- spec/requests/cache_invalidation_spec.rb | 26 +++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3abccfe68..bc0be7b19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ The format is based on [Keep a Changelog 1.0.0]. - fix text input field width to fit full screen width - document where to find the service in the readme - cache CI builds to reduce build times +- log information about contentful cache busting webhooks for debugging ## [release-009] - 2021-05-21 diff --git a/app/controllers/api/contentful/entries_controller.rb b/app/controllers/api/contentful/entries_controller.rb index 867848e77..b568a0fe5 100644 --- a/app/controllers/api/contentful/entries_controller.rb +++ b/app/controllers/api/contentful/entries_controller.rb @@ -5,7 +5,7 @@ class Api::Contentful::EntriesController < ApplicationController skip_before_action :verify_authenticity_token def changed - Rollbar.info("Accepted request to cache bust key: #{cache_key}", params: params) + Rollbar.info("Accepted request to cache bust Contentful Entry", cache_key: cache_key) Cache.delete(key: cache_key) render json: {status: "OK"}, status: :ok diff --git a/spec/requests/cache_invalidation_spec.rb b/spec/requests/cache_invalidation_spec.rb index 86607c668..953ea088a 100644 --- a/spec/requests/cache_invalidation_spec.rb +++ b/spec/requests/cache_invalidation_spec.rb @@ -34,6 +34,32 @@ expect(RedisCache.redis.get("contentful:entry:6zeSz4F4YtD66gT5SFpnSB")).to eq(nil) end + it "logs information of the event in Rollbar for debugging" do + fake_contentful_webook_payload = { + "entityId": "6zeSz4F4YtD66gT5SFpnSB", + "spaceId": "rwl7tyzv9sys", + "parameters": { + "text": "Entity version: 62" + } + } + + credentials = ActionController::HttpAuthentication::Token + .encode_credentials(ENV["CONTENTFUL_WEBHOOK_API_KEY"]) + headers = {"AUTHORIZATION" => credentials} + + expect(Rollbar).to receive(:info) + .with( + "Accepted request to cache bust Contentful Entry", + cache_key: "contentful:entry:6zeSz4F4YtD66gT5SFpnSB" + ).and_call_original + + post "/api/contentful/entry_updated", { + params: fake_contentful_webook_payload, + headers: headers, + as: :json + } + end + context "when no basic auth was provided" do it "does not delete anything from the cache and returns 401" do RedisCache.redis.set("contentful:entry:6zeSz4F4YtD66gT5SFpnSB", "a dummy value") From 43ad1c385fc26f359cd4315daa354b139e44b3a5 Mon Sep 17 00:00:00 2001 From: Tom Hipkin Date: Thu, 22 Apr 2021 10:49:37 +0100 Subject: [PATCH 12/30] Document the need to add critical env vars to the dotenv initialiser This will give us better error messages if it's missing locally or on a live environment. --- doc/managing-environment-variables.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/managing-environment-variables.md b/doc/managing-environment-variables.md index fb65e9479..d5aaf8784 100644 --- a/doc/managing-environment-variables.md +++ b/doc/managing-environment-variables.md @@ -1,5 +1,7 @@ # Managing environment variables +## Locally + We use [Dotenv](https://github.com/bkeepers/dotenv) to manage our environment variables locally. The repository will include safe defaults for development in `/.env.example` and for test in `/.env.test`. We use 'example' instead of 'development' (from the Dotenv docs) to be consistent with current dxw conventions and to make it more explicit that these values are not to be committed. @@ -9,4 +11,7 @@ To manage sensitive environment variables: 1. Add the new key and safe default value to the `/.env.example` file eg. `ROLLBAR_TOKEN=ROLLBAR_TOKEN` 2. Add the new key and real value to your local `/.env.development.local` file, which should never be checked into Git. This file will look something like `ROLLBAR_TOKEN=123456789` -Add critical environment variable keys to the Dockerfile where `rake assets:precompile` is run. +If the environment variable is critical whereby it is required to start the application: + +- Add it to [the Dotenv initialiser](../config/initializers/_dotenv.rb). +- Add it to the Dockerfile where `rake assets:precompile` is run. From 785d07ce84b86b940e042c981be5fe88a22350aa Mon Sep 17 00:00:00 2001 From: Tom Hipkin Date: Mon, 26 Apr 2021 16:09:59 +0100 Subject: [PATCH 13/30] Document how to manage live environment variables using Github Secrets --- CHANGELOG.md | 1 + doc/managing-environment-variables.md | 49 +++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc0be7b19..7a02864d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog 1.0.0]. ## [Unreleased] - error pages are styled +- document how to manage live environment variables ## [release-010] - 2021-05-27 diff --git a/doc/managing-environment-variables.md b/doc/managing-environment-variables.md index d5aaf8784..ee8bef68f 100644 --- a/doc/managing-environment-variables.md +++ b/doc/managing-environment-variables.md @@ -15,3 +15,52 @@ If the environment variable is critical whereby it is required to start the appl - Add it to [the Dotenv initialiser](../config/initializers/_dotenv.rb). - Add it to the Dockerfile where `rake assets:precompile` is run. + +## Live environments + +We use [GitHub Secrets as the canonical source of our environment variables](https://github.com/DFE-Digital/buy-for-your-school/settings/secrets/actions). + +Environment variables are all managed in the same way. Secrets are kept secret by taking advantage of the protection GitHub Secrets offers. Configuration options which don't necessarily need to be kept secret are still managed through environment variables as part of being [a 12 factor app](https://12factor.net/config). + +### Adding a variable + +#### Application + +A variable will usually be required to be added into each environment through [a new repository secret](https://github.com/DFE-Digital/buy-for-your-school/settings/secrets/actions/new). For this we use prefixes in our environment variable names: + +``` +APP_ENV_PROD_ +APP_ENV_STAGING_ +APP_ENV_RESEARCH_ +APP_ENV_PREVIEW_ +``` + +For instance if the app needed to access `ENV["RAILS_ENV"]` in production we would add this as the key: + +``` +APP_ENV_PROD_RAILS_ENV +``` + + +**Important!** +To propagate these new environment variables to the live environments we must finally deploy them manually. [Find the most recent passing deploy](https://github.com/DFE-Digital/buy-for-your-school/actions/workflows/deploy.yml) for the environment you want to provision the new variable on, view it and select "re-run jobs". + +### Infrastructure + +We can also make variables available for Terraform so that it can be configured. + +Here's an example of how `_TF_VAR` is used together with environment prefixes to pass `SYSLOG_DRAIN_URL` information. In this case it configures where logs should be forwarded to at the infrastructure level: + +``` +PREVIEW_TF_VAR_SYSLOG_DRAIN_URL +``` + +## Viewing a variable + +There is no way to view variables through GitHub Secrets once set. + +Though the GitHub secret API could be used, the easiest way to get application variables is to [access the console for the environment you want](console-access.md) and ask Rails for it over the console. + +``` +$irb> ENV["RAILS_ENV"] +``` From ed0d1da2335160d61fa9b880e01bb84d7aaabff9 Mon Sep 17 00:00:00 2001 From: Tom Hipkin Date: Mon, 26 Apr 2021 16:11:47 +0100 Subject: [PATCH 14/30] Brakeman runs without interactive --- script/test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/test b/script/test index dab93225a..d6321420f 100755 --- a/script/test +++ b/script/test @@ -31,5 +31,5 @@ else bundle exec rspec echo "==> Running Brakeman" - bundle exec brakeman + bundle exec brakeman -o /dev/stdout fi From eb8c477479f9630a5f77f7360ae1a28d5d91a2c6 Mon Sep 17 00:00:00 2001 From: Tom Hipkin Date: Mon, 26 Apr 2021 18:07:33 +0100 Subject: [PATCH 15/30] Fix intermittent spec failure Without this change the following fails[1]: ``` bundle exec rspec spec/models/user_session_spec.rb spec/requests/authentication_spec.rb --seed=5010 ``` This is because a request spec is not tidying up after itself. It's allowed to sign in and add an entry to the RedisSession caches. Instead of also running before(:each) {flush} before the failing test we catch future problems by tidying up across the whole authentication spec file. [1] https://github.com/DFE-Digital/buy-for-your-school/runs/2440019997?check_suite_focus=true --- spec/requests/authentication_spec.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/requests/authentication_spec.rb b/spec/requests/authentication_spec.rb index 500ecc255..2afc02996 100644 --- a/spec/requests/authentication_spec.rb +++ b/spec/requests/authentication_spec.rb @@ -1,6 +1,11 @@ require "rails_helper" RSpec.describe "Authentication", type: :request do + after(:each) do + RedisSessions.redis.flushdb + RedisSessionLookup.redis.flushdb + end + describe "Endpoints that don't require authentication" do it "the health_check endpoint is not authenticated" do get health_check_path From 086eadbf03ffa057df0428bf7945670e2e9de2e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Apr 2021 10:03:51 +0000 Subject: [PATCH 16/30] Bump contentful from 2.16.0 to 2.16.1 Bumps [contentful](https://github.com/contentful/contentful.rb) from 2.16.0 to 2.16.1. - [Release notes](https://github.com/contentful/contentful.rb/releases) - [Changelog](https://github.com/contentful/contentful.rb/blob/master/CHANGELOG.md) - [Commits](https://github.com/contentful/contentful.rb/compare/v2.16.0...v2.16.1) Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index e7b91ea8b..eee4f8ecc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -99,7 +99,7 @@ GEM coffee-script-source (1.12.2) concurrent-ruby (1.1.8) connection_pool (2.2.3) - contentful (2.16.0) + contentful (2.16.1) http (> 0.8, < 5.0) multi_json (~> 1) crack (0.4.5) From 9c4a933a3ba89bf79b6e462bfc90507e1eed145b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 May 2021 09:05:56 +0000 Subject: [PATCH 17/30] Bump mock_redis from 0.27.3 to 0.28.0 Bumps [mock_redis](https://github.com/sds/mock_redis) from 0.27.3 to 0.28.0. - [Release notes](https://github.com/sds/mock_redis/releases) - [Changelog](https://github.com/sds/mock_redis/blob/master/CHANGELOG.md) - [Commits](https://github.com/sds/mock_redis/compare/v0.27.3...v0.28.0) Signed-off-by: dependabot[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index eee4f8ecc..6530c763b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -194,7 +194,7 @@ GEM mini_racer (0.4.0) libv8-node (~> 15.14.0.0) minitest (5.14.4) - mock_redis (0.27.3) + mock_redis (0.28.0) ruby2_keywords msgpack (1.4.2) multi_json (1.15.0) @@ -330,7 +330,7 @@ GEM rubocop (>= 0.90.0, < 2.0) rubocop-ast (>= 0.4.0) ruby-progressbar (1.11.0) - ruby2_keywords (0.0.2) + ruby2_keywords (0.0.4) rubyzip (2.3.0) sass-rails (6.0.0) sassc-rails (~> 2.1, >= 2.1.1) From f108d2eeb0d356a00b113be306e2085f63c77977 Mon Sep 17 00:00:00 2001 From: Laura Porter Date: Tue, 27 Apr 2021 15:06:41 +0100 Subject: [PATCH 18/30] Add tasks to all fixtures All fixtures now contain tasks as a Contentful entity, sitting between section and step. This commit also fixes some erroneous ids in the fixtures. --- CHANGELOG.md | 1 + .../sections/checkboxes-section.json | 4 +- .../contentful/sections/currency-section.json | 4 +- .../sections/extended-checkboxes-section.json | 4 +- ...tended-long-answer-checkboxes-section.json | 4 +- .../extended-long-answer-radio-section.json | 4 +- .../sections/extended-radio-section.json | 4 +- .../contentful/sections/hidden-section.json | 6 +- .../sections/hidden-task-section.json | 2 +- ...journey-with-multiple-entries-section.json | 18 +----- .../journey-with-repeat-entries-section.json | 19 ++---- .../sections/long-text-section.json | 4 +- .../sections/markdown-help-text-section.json | 4 +- .../sections/multiple-long-text-section.json | 6 +- .../sections/multiple-radio-section.json | 6 +- .../sections/multiple-tasks-section.json | 15 ++--- ...iple-visible-and-hidden-tasks-section.json | 2 +- .../nil-help-text-radios-section.json | 4 +- .../nil-help-text-short-text-section.json | 4 +- .../contentful/sections/number-section.json | 4 +- .../contentful/sections/radio-section.json | 4 +- .../radio-with-separator-section.json | 4 +- .../sections/short-text-section.json | 4 +- .../show-one-additional-question-section.json | 8 +-- .../sections/single-date-section.json | 4 +- .../skippable-checkboxes-section.json | 4 +- .../sections/static-content-section.json | 4 +- ...cted-contentful-question-type-section.json | 4 +- .../unexpected-contentful-type-section.json | 4 +- .../tasks/checkboxes-and-radio-task.json | 20 ++++++- .../contentful/tasks/currency-task.json | 46 ++++++++++++++ .../tasks/extended-checkboxes-task.json | 46 ++++++++++++++ .../extended-long-answer-checkboxes-task.json | 46 ++++++++++++++ .../extended-long-answer-radio-task.json | 46 ++++++++++++++ .../contentful/tasks/extended-radio-task.json | 46 ++++++++++++++ ...idden-task.json => hidden-field-task.json} | 2 +- ...hat-shows-an-additional-question-task.json | 46 ++++++++++++++ .../contentful/tasks/long-text-task.json | 46 ++++++++++++++ .../tasks/markdown-help-text-task.json | 46 ++++++++++++++ .../tasks/nil-help-text-radios-task.json | 46 ++++++++++++++ .../tasks/nil-help-text-short-text-task.json | 46 ++++++++++++++ .../tasks/no-hidden-field-task.json | 46 ++++++++++++++ .../tasks/no-primary-button-task.json | 46 ++++++++++++++ .../contentful/tasks/number-task.json | 46 ++++++++++++++ .../contentful/tasks/primary-button-task.json | 46 ++++++++++++++ .../tasks/radio-and-hidden-task.json | 2 +- .../fixtures/contentful/tasks/radio-task.json | 46 ++++++++++++++ .../tasks/radio-with-separator-task.json | 46 ++++++++++++++ .../contentful/tasks/repeat-entries-task.json | 60 +++++++++++++++++++ .../contentful/tasks/short-text-task.json | 46 ++++++++++++++ ...ow-multiple-additional-questions-task.json | 46 ++++++++++++++ .../show-one-additional-question-task.json | 46 ++++++++++++++ .../contentful/tasks/shown-field-task.json | 46 ++++++++++++++ .../contentful/tasks/single-date-task.json | 46 ++++++++++++++ .../tasks/skippable-checkboxes-task.json | 46 ++++++++++++++ .../contentful/tasks/static-content-task.json | 46 ++++++++++++++ ...xpected-contentful-question-type-task.json | 46 ++++++++++++++ .../unexpected-contentful-type-task.json | 46 ++++++++++++++ 58 files changed, 1299 insertions(+), 94 deletions(-) create mode 100644 spec/fixtures/contentful/tasks/currency-task.json create mode 100644 spec/fixtures/contentful/tasks/extended-checkboxes-task.json create mode 100644 spec/fixtures/contentful/tasks/extended-long-answer-checkboxes-task.json create mode 100644 spec/fixtures/contentful/tasks/extended-long-answer-radio-task.json create mode 100644 spec/fixtures/contentful/tasks/extended-radio-task.json rename spec/fixtures/contentful/tasks/{hidden-task.json => hidden-field-task.json} (96%) create mode 100644 spec/fixtures/contentful/tasks/hidden-field-that-shows-an-additional-question-task.json create mode 100644 spec/fixtures/contentful/tasks/long-text-task.json create mode 100644 spec/fixtures/contentful/tasks/markdown-help-text-task.json create mode 100644 spec/fixtures/contentful/tasks/nil-help-text-radios-task.json create mode 100644 spec/fixtures/contentful/tasks/nil-help-text-short-text-task.json create mode 100644 spec/fixtures/contentful/tasks/no-hidden-field-task.json create mode 100644 spec/fixtures/contentful/tasks/no-primary-button-task.json create mode 100644 spec/fixtures/contentful/tasks/number-task.json create mode 100644 spec/fixtures/contentful/tasks/primary-button-task.json create mode 100644 spec/fixtures/contentful/tasks/radio-task.json create mode 100644 spec/fixtures/contentful/tasks/radio-with-separator-task.json create mode 100644 spec/fixtures/contentful/tasks/repeat-entries-task.json create mode 100644 spec/fixtures/contentful/tasks/short-text-task.json create mode 100644 spec/fixtures/contentful/tasks/show-multiple-additional-questions-task.json create mode 100644 spec/fixtures/contentful/tasks/show-one-additional-question-task.json create mode 100644 spec/fixtures/contentful/tasks/shown-field-task.json create mode 100644 spec/fixtures/contentful/tasks/single-date-task.json create mode 100644 spec/fixtures/contentful/tasks/skippable-checkboxes-task.json create mode 100644 spec/fixtures/contentful/tasks/static-content-task.json create mode 100644 spec/fixtures/contentful/tasks/unexpected-contentful-question-type-task.json create mode 100644 spec/fixtures/contentful/tasks/unexpected-contentful-type-task.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a02864d1..9f2ea7199 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog 1.0.0]. - error pages are styled - document how to manage live environment variables +- Update all fixtures to include tasks ## [release-010] - 2021-05-27 diff --git a/spec/fixtures/contentful/sections/checkboxes-section.json b/spec/fixtures/contentful/sections/checkboxes-section.json index e2668ad17..2f51ce50a 100644 --- a/spec/fixtures/contentful/sections/checkboxes-section.json +++ b/spec/fixtures/contentful/sections/checkboxes-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "checkboxes-question" + "id": "checkboxes-task" } } ] diff --git a/spec/fixtures/contentful/sections/currency-section.json b/spec/fixtures/contentful/sections/currency-section.json index e73ea86f0..8f32bf589 100644 --- a/spec/fixtures/contentful/sections/currency-section.json +++ b/spec/fixtures/contentful/sections/currency-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "currency-question" + "id": "currency-task" } } ] diff --git a/spec/fixtures/contentful/sections/extended-checkboxes-section.json b/spec/fixtures/contentful/sections/extended-checkboxes-section.json index d3f612812..dd2a27e7a 100644 --- a/spec/fixtures/contentful/sections/extended-checkboxes-section.json +++ b/spec/fixtures/contentful/sections/extended-checkboxes-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "extended-checkboxes-question" + "id": "extended-checkboxes-task" } } ] diff --git a/spec/fixtures/contentful/sections/extended-long-answer-checkboxes-section.json b/spec/fixtures/contentful/sections/extended-long-answer-checkboxes-section.json index e364a8487..02f8368c2 100644 --- a/spec/fixtures/contentful/sections/extended-long-answer-checkboxes-section.json +++ b/spec/fixtures/contentful/sections/extended-long-answer-checkboxes-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "extended-long-answer-checkboxes-question" + "id": "extended-long-answer-checkboxes-task" } } ] diff --git a/spec/fixtures/contentful/sections/extended-long-answer-radio-section.json b/spec/fixtures/contentful/sections/extended-long-answer-radio-section.json index 08f4d4555..79747c27c 100644 --- a/spec/fixtures/contentful/sections/extended-long-answer-radio-section.json +++ b/spec/fixtures/contentful/sections/extended-long-answer-radio-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "extended-long-answer-radio-question" + "id": "extended-long-answer-radio-task" } } ] diff --git a/spec/fixtures/contentful/sections/extended-radio-section.json b/spec/fixtures/contentful/sections/extended-radio-section.json index 0547e9fe3..94e4a27f7 100644 --- a/spec/fixtures/contentful/sections/extended-radio-section.json +++ b/spec/fixtures/contentful/sections/extended-radio-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "extended-radio-question" + "id": "extended-radio-task" } } ] diff --git a/spec/fixtures/contentful/sections/hidden-section.json b/spec/fixtures/contentful/sections/hidden-section.json index e6776e1b4..e781915c4 100644 --- a/spec/fixtures/contentful/sections/hidden-section.json +++ b/spec/fixtures/contentful/sections/hidden-section.json @@ -30,19 +30,19 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "hidden-field" + "id": "hidden-field-task" } }, { "sys": { "type": "Link", "linkType": "Entry", - "id": "shown-field" + "id": "shown-field-task" } } ] diff --git a/spec/fixtures/contentful/sections/hidden-task-section.json b/spec/fixtures/contentful/sections/hidden-task-section.json index d4add894d..2173f77a1 100644 --- a/spec/fixtures/contentful/sections/hidden-task-section.json +++ b/spec/fixtures/contentful/sections/hidden-task-section.json @@ -34,7 +34,7 @@ "sys": { "type": "Link", "linkType": "Entry", - "id": "hidden-task" + "id": "hidden-field-task" } }] } diff --git a/spec/fixtures/contentful/sections/journey-with-multiple-entries-section.json b/spec/fixtures/contentful/sections/journey-with-multiple-entries-section.json index 63a6a0612..dbc9b34fd 100644 --- a/spec/fixtures/contentful/sections/journey-with-multiple-entries-section.json +++ b/spec/fixtures/contentful/sections/journey-with-multiple-entries-section.json @@ -30,26 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "radio-question" - } - }, - { - "sys": { - "type": "Link", - "linkType": "Entry", - "id": "short-text-question" - } - }, - { - "sys": { - "type": "Link", - "linkType": "Entry", - "id": "long-text-question" + "id": "checkboxes-and-radio-task" } } ] diff --git a/spec/fixtures/contentful/sections/journey-with-repeat-entries-section.json b/spec/fixtures/contentful/sections/journey-with-repeat-entries-section.json index 14b9ea73e..778179658 100644 --- a/spec/fixtures/contentful/sections/journey-with-repeat-entries-section.json +++ b/spec/fixtures/contentful/sections/journey-with-repeat-entries-section.json @@ -30,20 +30,13 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { - "sys": { - "type": "Link", - "linkType": "Entry", - "id": "radio-question" - } - }, - { - "sys": { - "type": "Link", - "linkType": "Entry", - "id": "radio-question" - } + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "repeat-entries-task" + } } ] } diff --git a/spec/fixtures/contentful/sections/long-text-section.json b/spec/fixtures/contentful/sections/long-text-section.json index 3ad55bccd..07fdba9fc 100644 --- a/spec/fixtures/contentful/sections/long-text-section.json +++ b/spec/fixtures/contentful/sections/long-text-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section B", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "long-text-question" + "id": "long-text-task" } } ] diff --git a/spec/fixtures/contentful/sections/markdown-help-text-section.json b/spec/fixtures/contentful/sections/markdown-help-text-section.json index 77e5cbf13..16c0dfcf5 100644 --- a/spec/fixtures/contentful/sections/markdown-help-text-section.json +++ b/spec/fixtures/contentful/sections/markdown-help-text-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "markdown-help-text" + "id": "markdown-help-text-task" } } ] diff --git a/spec/fixtures/contentful/sections/multiple-long-text-section.json b/spec/fixtures/contentful/sections/multiple-long-text-section.json index 49ddfd5b6..1d198a6a8 100644 --- a/spec/fixtures/contentful/sections/multiple-long-text-section.json +++ b/spec/fixtures/contentful/sections/multiple-long-text-section.json @@ -30,19 +30,19 @@ }, "fields": { "title": "Section B", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "long-text-question" + "id": "long-text-task" } }, { "sys": { "type": "Link", "linkType": "Entry", - "id": "short-text-question" + "id": "short-text-task" } } ] diff --git a/spec/fixtures/contentful/sections/multiple-radio-section.json b/spec/fixtures/contentful/sections/multiple-radio-section.json index ecad2304a..986415c9b 100644 --- a/spec/fixtures/contentful/sections/multiple-radio-section.json +++ b/spec/fixtures/contentful/sections/multiple-radio-section.json @@ -30,19 +30,19 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "radio-question" + "id": "radio-task" } }, { "sys": { "type": "Link", "linkType": "Entry", - "id": "single-date-question" + "id": "single-date-task" } } ] diff --git a/spec/fixtures/contentful/sections/multiple-tasks-section.json b/spec/fixtures/contentful/sections/multiple-tasks-section.json index b37814c63..a706ca66f 100644 --- a/spec/fixtures/contentful/sections/multiple-tasks-section.json +++ b/spec/fixtures/contentful/sections/multiple-tasks-section.json @@ -37,13 +37,14 @@ "linkType": "Entry", "id": "checkboxes-task" } - }, - { - "sys": { - "type": "Link", - "linkType": "Entry", - "id": "checkboxes-and-radio-task" + }, + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "checkboxes-and-radio-task" + } } - }] + ] } } diff --git a/spec/fixtures/contentful/sections/multiple-visible-and-hidden-tasks-section.json b/spec/fixtures/contentful/sections/multiple-visible-and-hidden-tasks-section.json index 3e57a581e..829535eab 100644 --- a/spec/fixtures/contentful/sections/multiple-visible-and-hidden-tasks-section.json +++ b/spec/fixtures/contentful/sections/multiple-visible-and-hidden-tasks-section.json @@ -7,7 +7,7 @@ "id": "rwl7tyzv9sys" } }, - "id": "tasks-section", + "id": "multiple-visible-and-hidden-tasks-section", "type": "Entry", "createdAt": "2021-04-12T10:41:36.073Z", "updatedAt": "2021-04-12T10:42:51.119Z", diff --git a/spec/fixtures/contentful/sections/nil-help-text-radios-section.json b/spec/fixtures/contentful/sections/nil-help-text-radios-section.json index 6ed3d42eb..81d146558 100644 --- a/spec/fixtures/contentful/sections/nil-help-text-radios-section.json +++ b/spec/fixtures/contentful/sections/nil-help-text-radios-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "nil-help-text-radios" + "id": "nil-help-text-radios-task" } } ] diff --git a/spec/fixtures/contentful/sections/nil-help-text-short-text-section.json b/spec/fixtures/contentful/sections/nil-help-text-short-text-section.json index a2b62bb78..ae4d9d488 100644 --- a/spec/fixtures/contentful/sections/nil-help-text-short-text-section.json +++ b/spec/fixtures/contentful/sections/nil-help-text-short-text-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "nil-help-text-short-text" + "id": "nil-help-text-short-text-task" } } ] diff --git a/spec/fixtures/contentful/sections/number-section.json b/spec/fixtures/contentful/sections/number-section.json index ddba3ea4a..ae825bb1b 100644 --- a/spec/fixtures/contentful/sections/number-section.json +++ b/spec/fixtures/contentful/sections/number-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "number-question" + "id": "number-task" } } ] diff --git a/spec/fixtures/contentful/sections/radio-section.json b/spec/fixtures/contentful/sections/radio-section.json index 027cbf571..2444c5ea6 100644 --- a/spec/fixtures/contentful/sections/radio-section.json +++ b/spec/fixtures/contentful/sections/radio-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "radio-question" + "id": "radio-task" } } ] diff --git a/spec/fixtures/contentful/sections/radio-with-separator-section.json b/spec/fixtures/contentful/sections/radio-with-separator-section.json index 216461309..771c78109 100644 --- a/spec/fixtures/contentful/sections/radio-with-separator-section.json +++ b/spec/fixtures/contentful/sections/radio-with-separator-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "radio-with-separator-question" + "id": "radio-with-separator-task" } } ] diff --git a/spec/fixtures/contentful/sections/short-text-section.json b/spec/fixtures/contentful/sections/short-text-section.json index a64641194..5b1cb1b50 100644 --- a/spec/fixtures/contentful/sections/short-text-section.json +++ b/spec/fixtures/contentful/sections/short-text-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "short-text-question" + "id": "short-text-task" } } ] diff --git a/spec/fixtures/contentful/sections/show-one-additional-question-section.json b/spec/fixtures/contentful/sections/show-one-additional-question-section.json index e907521ad..7e8686723 100644 --- a/spec/fixtures/contentful/sections/show-one-additional-question-section.json +++ b/spec/fixtures/contentful/sections/show-one-additional-question-section.json @@ -30,26 +30,26 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "show-one-additional-question" + "id": "show-one-additional-question-task" } }, { "sys": { "type": "Link", "linkType": "Entry", - "id": "hidden-field-that-shows-an-additional-question" + "id": "hidden-field-that-shows-an-additional-question-task" } }, { "sys": { "type": "Link", "linkType": "Entry", - "id": "hidden-field" + "id": "hidden-field-task" } } ] diff --git a/spec/fixtures/contentful/sections/single-date-section.json b/spec/fixtures/contentful/sections/single-date-section.json index 8cd9ef8a9..aeef77d95 100644 --- a/spec/fixtures/contentful/sections/single-date-section.json +++ b/spec/fixtures/contentful/sections/single-date-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "single-date-question" + "id": "single-date-task" } } ] diff --git a/spec/fixtures/contentful/sections/skippable-checkboxes-section.json b/spec/fixtures/contentful/sections/skippable-checkboxes-section.json index 27cb9fb5f..c8a8c5b43 100644 --- a/spec/fixtures/contentful/sections/skippable-checkboxes-section.json +++ b/spec/fixtures/contentful/sections/skippable-checkboxes-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "skippable-checkboxes-question" + "id": "skippable-checkboxes-task" } } ] diff --git a/spec/fixtures/contentful/sections/static-content-section.json b/spec/fixtures/contentful/sections/static-content-section.json index c340bc3f7..d7038382e 100644 --- a/spec/fixtures/contentful/sections/static-content-section.json +++ b/spec/fixtures/contentful/sections/static-content-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "static-content" + "id": "static-content-task" } } ] diff --git a/spec/fixtures/contentful/sections/unexpected-contentful-question-type-section.json b/spec/fixtures/contentful/sections/unexpected-contentful-question-type-section.json index bdec0acc9..6325eea49 100644 --- a/spec/fixtures/contentful/sections/unexpected-contentful-question-type-section.json +++ b/spec/fixtures/contentful/sections/unexpected-contentful-question-type-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "unexpected-contentful-question-type" + "id": "unexpected-contentful-question-type-task" } } ] diff --git a/spec/fixtures/contentful/sections/unexpected-contentful-type-section.json b/spec/fixtures/contentful/sections/unexpected-contentful-type-section.json index 9cd4e6b19..fd8c77f0f 100644 --- a/spec/fixtures/contentful/sections/unexpected-contentful-type-section.json +++ b/spec/fixtures/contentful/sections/unexpected-contentful-type-section.json @@ -30,12 +30,12 @@ }, "fields": { "title": "Section A", - "steps": [ + "tasks": [ { "sys": { "type": "Link", "linkType": "Entry", - "id": "unexpected-contentful-type" + "id": "unexpected-contentful-type-task" } } ] diff --git a/spec/fixtures/contentful/tasks/checkboxes-and-radio-task.json b/spec/fixtures/contentful/tasks/checkboxes-and-radio-task.json index aa70ce43b..9763c749c 100644 --- a/spec/fixtures/contentful/tasks/checkboxes-and-radio-task.json +++ b/spec/fixtures/contentful/tasks/checkboxes-and-radio-task.json @@ -10,7 +10,7 @@ "id": "rwl7tyzv9sys" } }, - "id": "checkboxes-task", + "id": "checkboxes-and-radio-task", "type": "Entry", "createdAt": "2021-04-12T09:38:48.990Z", "updatedAt": "2021-04-12T10:11:05.670Z", @@ -38,14 +38,28 @@ "sys": { "type": "Link", "linkType": "Entry", - "id": "checkboxes-question" + "id": "radio-question" } }, { "sys": { "type": "Link", "linkType": "Entry", - "id": "radio-question" + "id": "short-text-question" + } + }, + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "long-text-question" + } + }, + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "checkboxes-question" } } ] diff --git a/spec/fixtures/contentful/tasks/currency-task.json b/spec/fixtures/contentful/tasks/currency-task.json new file mode 100644 index 000000000..da471eea9 --- /dev/null +++ b/spec/fixtures/contentful/tasks/currency-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "currency-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Currency task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "currency-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/extended-checkboxes-task.json b/spec/fixtures/contentful/tasks/extended-checkboxes-task.json new file mode 100644 index 000000000..bf596836a --- /dev/null +++ b/spec/fixtures/contentful/tasks/extended-checkboxes-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "extended-checkboxes-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Extended checkboxes task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "extended-checkboxes-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/extended-long-answer-checkboxes-task.json b/spec/fixtures/contentful/tasks/extended-long-answer-checkboxes-task.json new file mode 100644 index 000000000..a797c806b --- /dev/null +++ b/spec/fixtures/contentful/tasks/extended-long-answer-checkboxes-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "extended-long-answer-checkboxes-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Extended long answer checkboxes task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "extended-long-answer-checkboxes-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/extended-long-answer-radio-task.json b/spec/fixtures/contentful/tasks/extended-long-answer-radio-task.json new file mode 100644 index 000000000..09033fe0e --- /dev/null +++ b/spec/fixtures/contentful/tasks/extended-long-answer-radio-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "extended-long-answer-radio-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Extended long answer radio task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "extended-long-answer-radio-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/extended-radio-task.json b/spec/fixtures/contentful/tasks/extended-radio-task.json new file mode 100644 index 000000000..dafdd5439 --- /dev/null +++ b/spec/fixtures/contentful/tasks/extended-radio-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "extended-radio-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Extended radio task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "extended-radio-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/hidden-task.json b/spec/fixtures/contentful/tasks/hidden-field-task.json similarity index 96% rename from spec/fixtures/contentful/tasks/hidden-task.json rename to spec/fixtures/contentful/tasks/hidden-field-task.json index f9ae5bdf0..4139cf076 100644 --- a/spec/fixtures/contentful/tasks/hidden-task.json +++ b/spec/fixtures/contentful/tasks/hidden-field-task.json @@ -10,7 +10,7 @@ "id": "rwl7tyzv9sys" } }, - "id": "checkboxes-task", + "id": "hidden-field-task", "type": "Entry", "createdAt": "2021-04-12T09:38:48.990Z", "updatedAt": "2021-04-12T10:11:05.670Z", diff --git a/spec/fixtures/contentful/tasks/hidden-field-that-shows-an-additional-question-task.json b/spec/fixtures/contentful/tasks/hidden-field-that-shows-an-additional-question-task.json new file mode 100644 index 000000000..7a6fe1866 --- /dev/null +++ b/spec/fixtures/contentful/tasks/hidden-field-that-shows-an-additional-question-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "hidden-field-that-shows-an-additional-question-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Hidden field with additional question task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "hidden-field-that-shows-an-additional-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/long-text-task.json b/spec/fixtures/contentful/tasks/long-text-task.json new file mode 100644 index 000000000..7389f47be --- /dev/null +++ b/spec/fixtures/contentful/tasks/long-text-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "long-text-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Long text task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "long-text-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/markdown-help-text-task.json b/spec/fixtures/contentful/tasks/markdown-help-text-task.json new file mode 100644 index 000000000..1d28a5b1e --- /dev/null +++ b/spec/fixtures/contentful/tasks/markdown-help-text-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "markdown-help-text-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Markdown help text task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "markdown-help-text" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/nil-help-text-radios-task.json b/spec/fixtures/contentful/tasks/nil-help-text-radios-task.json new file mode 100644 index 000000000..cae965456 --- /dev/null +++ b/spec/fixtures/contentful/tasks/nil-help-text-radios-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "nil-help-text-radios-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Nil help text radios task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "nil-help-text-radios" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/nil-help-text-short-text-task.json b/spec/fixtures/contentful/tasks/nil-help-text-short-text-task.json new file mode 100644 index 000000000..94178b457 --- /dev/null +++ b/spec/fixtures/contentful/tasks/nil-help-text-short-text-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "nil-help-text-short-text-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Nil help text short text task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "nil-help-text-short-text" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/no-hidden-field-task.json b/spec/fixtures/contentful/tasks/no-hidden-field-task.json new file mode 100644 index 000000000..dfb28f613 --- /dev/null +++ b/spec/fixtures/contentful/tasks/no-hidden-field-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "no-hidden-field-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "No hidden field task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "no-hidden-field" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/no-primary-button-task.json b/spec/fixtures/contentful/tasks/no-primary-button-task.json new file mode 100644 index 000000000..1147bb150 --- /dev/null +++ b/spec/fixtures/contentful/tasks/no-primary-button-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "no-primary-button-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "No primary button task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "no-primary-button" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/number-task.json b/spec/fixtures/contentful/tasks/number-task.json new file mode 100644 index 000000000..2c19595f0 --- /dev/null +++ b/spec/fixtures/contentful/tasks/number-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "number-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Number task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "number-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/primary-button-task.json b/spec/fixtures/contentful/tasks/primary-button-task.json new file mode 100644 index 000000000..b8221d7b7 --- /dev/null +++ b/spec/fixtures/contentful/tasks/primary-button-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "primary-button-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Primary button task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "primary-button" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/radio-and-hidden-task.json b/spec/fixtures/contentful/tasks/radio-and-hidden-task.json index 6442b9777..c361bd891 100644 --- a/spec/fixtures/contentful/tasks/radio-and-hidden-task.json +++ b/spec/fixtures/contentful/tasks/radio-and-hidden-task.json @@ -10,7 +10,7 @@ "id": "rwl7tyzv9sys" } }, - "id": "checkboxes-task", + "id": "radio-and-hidden-task", "type": "Entry", "createdAt": "2021-04-12T09:38:48.990Z", "updatedAt": "2021-04-12T10:11:05.670Z", diff --git a/spec/fixtures/contentful/tasks/radio-task.json b/spec/fixtures/contentful/tasks/radio-task.json new file mode 100644 index 000000000..c0045e199 --- /dev/null +++ b/spec/fixtures/contentful/tasks/radio-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "radio-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Radio task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "radio-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/radio-with-separator-task.json b/spec/fixtures/contentful/tasks/radio-with-separator-task.json new file mode 100644 index 000000000..e4b48a2d8 --- /dev/null +++ b/spec/fixtures/contentful/tasks/radio-with-separator-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "radio-with-separator-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Radio with separator task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "radio-with-separator-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/repeat-entries-task.json b/spec/fixtures/contentful/tasks/repeat-entries-task.json new file mode 100644 index 000000000..fee2b0e27 --- /dev/null +++ b/spec/fixtures/contentful/tasks/repeat-entries-task.json @@ -0,0 +1,60 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "repeat-entries-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Repeat entries task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "radio-question" + } + }, + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "radio-question" + } + }, + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "radio-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/short-text-task.json b/spec/fixtures/contentful/tasks/short-text-task.json new file mode 100644 index 000000000..903aa24bb --- /dev/null +++ b/spec/fixtures/contentful/tasks/short-text-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "short-text-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Short text task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "short-text-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/show-multiple-additional-questions-task.json b/spec/fixtures/contentful/tasks/show-multiple-additional-questions-task.json new file mode 100644 index 000000000..c485cf5b1 --- /dev/null +++ b/spec/fixtures/contentful/tasks/show-multiple-additional-questions-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "show-multiple-additional-questions-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Multiple additional questions task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "show-multiple-additional-questions" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/show-one-additional-question-task.json b/spec/fixtures/contentful/tasks/show-one-additional-question-task.json new file mode 100644 index 000000000..4ec5a100d --- /dev/null +++ b/spec/fixtures/contentful/tasks/show-one-additional-question-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "show-one-additional-question-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "One additional question task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "show-one-additional-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/shown-field-task.json b/spec/fixtures/contentful/tasks/shown-field-task.json new file mode 100644 index 000000000..d93983515 --- /dev/null +++ b/spec/fixtures/contentful/tasks/shown-field-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "shown-field-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Shown field task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "shown-field" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/single-date-task.json b/spec/fixtures/contentful/tasks/single-date-task.json new file mode 100644 index 000000000..b39c8e83c --- /dev/null +++ b/spec/fixtures/contentful/tasks/single-date-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "single-date-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Single date task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "single-date-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/skippable-checkboxes-task.json b/spec/fixtures/contentful/tasks/skippable-checkboxes-task.json new file mode 100644 index 000000000..43d1fce5d --- /dev/null +++ b/spec/fixtures/contentful/tasks/skippable-checkboxes-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "skippable-checkboxes-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Skippable checkboxes task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "skippable-checkboxes-question" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/static-content-task.json b/spec/fixtures/contentful/tasks/static-content-task.json new file mode 100644 index 000000000..77372f200 --- /dev/null +++ b/spec/fixtures/contentful/tasks/static-content-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "static-content-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Static content task", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "static-content" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/unexpected-contentful-question-type-task.json b/spec/fixtures/contentful/tasks/unexpected-contentful-question-type-task.json new file mode 100644 index 000000000..a3dea22a4 --- /dev/null +++ b/spec/fixtures/contentful/tasks/unexpected-contentful-question-type-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "unexpected-contentful-question-type-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Unexpected Contentful question type", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "unexpected-contentful-question-type" + } + } + ] + } +} diff --git a/spec/fixtures/contentful/tasks/unexpected-contentful-type-task.json b/spec/fixtures/contentful/tasks/unexpected-contentful-type-task.json new file mode 100644 index 000000000..635665878 --- /dev/null +++ b/spec/fixtures/contentful/tasks/unexpected-contentful-type-task.json @@ -0,0 +1,46 @@ +{ + "metadata": { + "tags": [] + }, + "sys": { + "space": { + "sys": { + "type": "Link", + "linkType": "Space", + "id": "rwl7tyzv9sys" + } + }, + "id": "unexpected-contentful-type-task", + "type": "Entry", + "createdAt": "2021-04-12T09:38:48.990Z", + "updatedAt": "2021-04-12T10:11:05.670Z", + "environment": { + "sys": { + "id": "develop", + "type": "Link", + "linkType": "Environment" + } + }, + "revision": 3, + "contentType": { + "sys": { + "type": "Link", + "linkType": "ContentType", + "id": "task" + } + }, + "locale": "en-US" + }, + "fields": { + "title": "Unexpected Contentful type", + "steps": [ + { + "sys": { + "type": "Link", + "linkType": "Entry", + "id": "unexpected-contentful-type" + } + } + ] + } +} From f52b8920d07bdf448362a84aeedfc85d21868c84 Mon Sep 17 00:00:00 2001 From: Laura Porter Date: Tue, 27 Apr 2021 16:39:57 +0100 Subject: [PATCH 19/30] Update specs to work with the new task-enabled fixtures Now that all journey fixtures include tasks, we need to update the specs to remove any references to stubbing steps. Steps are now stubbed as part of stubbing the tasks. --- CHANGELOG.md | 2 ++ .../see_the_map_of_journey_steps_page_spec.rb | 3 +-- spec/jobs/warm_entry_cache_job_spec.rb | 6 ++--- spec/requests/contentful_caching_spec.rb | 3 +++ spec/services/create_journey_spec.rb | 15 ++++------- .../get_sections_from_category_spec.rb | 3 +-- spec/services/get_steps_from_section_spec.rb | 1 - spec/services/get_steps_from_task_spec.rb | 2 +- spec/support/contentful_helpers.rb | 26 ++++++++++++------- spec/support/journey_helpers.rb | 1 - 10 files changed, 31 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f2ea7199..192500a25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ The format is based on [Keep a Changelog 1.0.0]. - error pages are styled - document how to manage live environment variables - Update all fixtures to include tasks +- Update all fixtures to include tasks +- Update the specs to work with the new task-enabled fixtures ## [release-010] - 2021-05-27 diff --git a/spec/features/school_buying_professionals/see_the_map_of_journey_steps_page_spec.rb b/spec/features/school_buying_professionals/see_the_map_of_journey_steps_page_spec.rb index 4365369b6..9798c88ba 100644 --- a/spec/features/school_buying_professionals/see_the_map_of_journey_steps_page_spec.rb +++ b/spec/features/school_buying_professionals/see_the_map_of_journey_steps_page_spec.rb @@ -95,8 +95,7 @@ it "returns an error message" do stub_contentful_category( - fixture_filename: "journey-with-repeat-entries.json", - stub_steps: false + fixture_filename: "journey-with-repeat-entries.json" ) visit new_journey_map_path diff --git a/spec/jobs/warm_entry_cache_job_spec.rb b/spec/jobs/warm_entry_cache_job_spec.rb index 2fd8dd8fc..38751c156 100644 --- a/spec/jobs/warm_entry_cache_job_spec.rb +++ b/spec/jobs/warm_entry_cache_job_spec.rb @@ -44,8 +44,7 @@ context "when the journey order cannot be built" do it "does not add new items to the cache" do stub_contentful_category( - fixture_filename: "journey-with-multiple-entries.json", - stub_steps: false + fixture_filename: "journey-with-multiple-entries.json" ) allow_any_instance_of(GetStepsFromSection) @@ -62,8 +61,7 @@ RedisCache.redis.set("contentful:entry:contentful-starting-step", "\"{\\}\"") stub_contentful_category( - fixture_filename: "journey-with-multiple-entries.json", - stub_steps: false + fixture_filename: "journey-with-multiple-entries.json" ) allow_any_instance_of(GetStepsFromSection) diff --git a/spec/requests/contentful_caching_spec.rb b/spec/requests/contentful_caching_spec.rb index 5cfe49bae..ea58a48be 100644 --- a/spec/requests/contentful_caching_spec.rb +++ b/spec/requests/contentful_caching_spec.rb @@ -29,6 +29,9 @@ raw_section_response = File.read("#{Rails.root}/spec/fixtures/contentful/sections/radio-section.json") RedisCache.redis.set("contentful:entry:radio-section", JSON.dump(raw_section_response)) + raw_step_response = File.read("#{Rails.root}/spec/fixtures/contentful/tasks/radio-task.json") + RedisCache.redis.set("contentful:entry:radio-task", JSON.dump(raw_step_response)) + raw_step_response = File.read("#{Rails.root}/spec/fixtures/contentful/steps/radio-question.json") RedisCache.redis.set("contentful:entry:radio-question", JSON.dump(raw_step_response)) diff --git a/spec/services/create_journey_spec.rb b/spec/services/create_journey_spec.rb index 74a7082e4..ea5720f37 100644 --- a/spec/services/create_journey_spec.rb +++ b/spec/services/create_journey_spec.rb @@ -12,8 +12,7 @@ describe "#call" do it "creates a new journey" do stub_contentful_category( - fixture_filename: "category-with-no-steps.json", - stub_steps: false + fixture_filename: "category-with-no-steps.json" ) expect { described_class.new(category_name: "catering", user: build(:user)).call } .to change { Journey.count }.by(1) @@ -22,8 +21,7 @@ it "associates the new journey with the given user" do stub_contentful_category( - fixture_filename: "category-with-no-steps.json", - stub_steps: false + fixture_filename: "category-with-no-steps.json" ) user = create(:user) @@ -34,8 +32,7 @@ it "sets started to true (until questions have been answered)" do stub_contentful_category( - fixture_filename: "category-with-no-steps.json", - stub_steps: false + fixture_filename: "category-with-no-steps.json" ) described_class.new(category_name: "catering", user: build(:user)).call expect(Journey.last.started).to eq(true) @@ -44,8 +41,7 @@ it "sets last_worked_on to now" do travel_to Time.zone.local(2004, 11, 24, 1, 4, 44) stub_contentful_category( - fixture_filename: "category-with-no-steps.json", - stub_steps: false + fixture_filename: "category-with-no-steps.json" ) described_class.new(category_name: "catering", user: build(:user)).call @@ -97,8 +93,7 @@ it "raises an error" do stub_contentful_category( fixture_filename: "category-with-liquid-template.json", - stub_sections: true, - stub_steps: false + stub_sections: true ) # Force a validation error by not providing a category_name diff --git a/spec/services/get_sections_from_category_spec.rb b/spec/services/get_sections_from_category_spec.rb index 33c602b4d..a6ede93a4 100644 --- a/spec/services/get_sections_from_category_spec.rb +++ b/spec/services/get_sections_from_category_spec.rb @@ -4,8 +4,7 @@ describe "#call" do it "returns an array of sections" do category = stub_contentful_category( - fixture_filename: "radio-question.json", - stub_steps: false + fixture_filename: "radio-question.json" ) result = described_class.new(category: category).call diff --git a/spec/services/get_steps_from_section_spec.rb b/spec/services/get_steps_from_section_spec.rb index 557eb2a53..a0251317a 100644 --- a/spec/services/get_steps_from_section_spec.rb +++ b/spec/services/get_steps_from_section_spec.rb @@ -6,7 +6,6 @@ section = fake_contentful_section( contentful_fixture_filename: "sections/journey-with-multiple-entries-section.json" ) - stub_contentful_section_steps(sections: [section]) result = described_class.new(section: section).call diff --git a/spec/services/get_steps_from_task_spec.rb b/spec/services/get_steps_from_task_spec.rb index 6c60ddc21..8db1588b9 100644 --- a/spec/services/get_steps_from_task_spec.rb +++ b/spec/services/get_steps_from_task_spec.rb @@ -3,7 +3,7 @@ RSpec.describe GetStepsFromTask do describe "#call" do it "returns the list of entry objects referenced by the step list" do - task = fake_contentful_section( + task = fake_contentful_task( contentful_fixture_filename: "tasks/checkboxes-task.json" ) stub_contentful_task_steps(tasks: [task]) diff --git a/spec/support/contentful_helpers.rb b/spec/support/contentful_helpers.rb index e8ccd4bd3..a02b2c6ea 100644 --- a/spec/support/contentful_helpers.rb +++ b/spec/support/contentful_helpers.rb @@ -13,8 +13,7 @@ def stub_contentful_entry( def stub_contentful_category( fixture_filename:, stub_sections: true, - stub_steps: true, - stub_tasks: false, + stub_tasks: true, contentful_connector: instance_double(ContentfulConnector) # TODO: I suspect the double doesn't do anything and we need stub_contentful_connector ) category = fake_contentful_category(contentful_fixture_filename: fixture_filename) @@ -28,9 +27,6 @@ def stub_contentful_category( if stub_sections sections = stub_contentful_sections(category: category, contentful_connector: contentful_connector) - if stub_steps - stub_contentful_section_steps(sections: sections, contentful_connector: contentful_connector) - end if stub_tasks stub_contentful_section_tasks(sections: sections, contentful_connector: contentful_connector) end @@ -104,7 +100,7 @@ def stub_contentful_section_tasks( sections.each do |section| fake_tasks = section.tasks.map { |task| fake_task = fake_contentful_task(contentful_fixture_filename: "tasks/#{task.id}.json") - expect(contentful_connector).to receive(:get_entry_by_id) + allow(contentful_connector).to receive(:get_entry_by_id) .with(fake_task.id) .and_return(fake_task) fake_task @@ -179,17 +175,27 @@ def fake_contentful_category(contentful_fixture_filename:) def fake_contentful_section(contentful_fixture_filename:) raw_response = File.read("#{Rails.root}/spec/fixtures/contentful/#{contentful_fixture_filename}") hash_response = JSON.parse(raw_response) + contentful_connector = instance_double(ContentfulConnector) - steps = hash_response.dig("fields", "steps") tasks = hash_response.dig("fields", "tasks") - double( + section = double( Contentful::Entry, id: hash_response.dig("sys", "id"), title: hash_response.dig("fields", "title"), - steps: steps.nil? ? {} : steps.map { |step_hash| double(id: step_hash.dig("sys", "id")) }, - tasks: tasks.nil? ? {} : tasks.map { |task_hash| double(id: task_hash.dig("sys", "id")) } + tasks: tasks.map { |task_hash| double(id: task_hash.dig("sys", "id")) } ) + + fake_tasks = section.tasks.map { |task| + fake_task = fake_contentful_task(contentful_fixture_filename: "tasks/#{task.id}.json") + allow(contentful_connector).to receive(:get_entry_by_id) + .with(fake_task.id) + .and_return(fake_task) + fake_task + } + allow(section).to receive(:tasks).and_return(fake_tasks) + stub_contentful_task_steps(tasks: fake_tasks, contentful_connector: contentful_connector) + section end def fake_contentful_task(contentful_fixture_filename:) diff --git a/spec/support/journey_helpers.rb b/spec/support/journey_helpers.rb index b0d71d939..020c1c10b 100644 --- a/spec/support/journey_helpers.rb +++ b/spec/support/journey_helpers.rb @@ -17,7 +17,6 @@ def start_journey_with_tasks_from_category(category:) stub_contentful_category( fixture_filename: category, stub_sections: true, - stub_steps: false, stub_tasks: true ) From 10a70bd5ae0ca6f5a41da8a0b7c8fe1ad52fb89b Mon Sep 17 00:00:00 2001 From: Laura Porter Date: Tue, 27 Apr 2021 16:43:42 +0100 Subject: [PATCH 20/30] Alter GetStepsFromSection to iterate down through tasks to get steps Now that steps are enclosed within tasks, we need to iterate through an extra layer of tasks to create a list of steps within a section. --- app/services/get_steps_from_section.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/services/get_steps_from_section.rb b/app/services/get_steps_from_section.rb index 33dd1d47b..ec20989b1 100644 --- a/app/services/get_steps_from_section.rb +++ b/app/services/get_steps_from_section.rb @@ -8,12 +8,14 @@ def initialize(section:) def call question_entry_ids = [] - section.steps.each do |step| - if question_entry_ids.include?(step.id) - send_rollbar_error(message: "A repeated Contentful entry was found in the same section", entry_id: step.id) - raise RepeatEntryDetected.new(step.id) - else - question_entry_ids << step.id + section.tasks.each do |task| + task.steps.each do |step| + if question_entry_ids.include?(step.id) + send_rollbar_error(message: "A repeated Contentful entry was found in the same section", entry_id: step.id) + raise RepeatEntryDetected.new(step.id) + else + question_entry_ids << step.id + end end end From d4dc93b3a42ae421c5d6536c39cfa1d5f90ed1de Mon Sep 17 00:00:00 2001 From: Laura Porter Date: Tue, 27 Apr 2021 16:55:07 +0100 Subject: [PATCH 21/30] Remove Journey#section_groups json blob Now that Sections exist as a model, we do not need to keep a json representation of a Journey's section structure in the database. We can get all the information we need about a Journey's sections, tasks and steps from the db models. --- CHANGELOG.md | 2 +- app/helpers/journey_helper.rb | 15 --- app/services/create_journey.rb | 13 --- ...238_remove_section_groups_from_journeys.rb | 5 + db/schema.rb | 3 +- spec/factories/journey.rb | 1 - .../edit_their_answers_spec.rb | 16 +-- .../view_a_list_of_tasks_spec.rb | 19 +--- spec/helpers/journey_helper_spec.rb | 100 ------------------ spec/services/create_journey_spec.rb | 29 ----- 10 files changed, 11 insertions(+), 192 deletions(-) delete mode 100644 app/helpers/journey_helper.rb create mode 100644 db/migrate/20210427154238_remove_section_groups_from_journeys.rb delete mode 100644 spec/helpers/journey_helper_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 192500a25..4c37b9afd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,8 @@ The format is based on [Keep a Changelog 1.0.0]. - error pages are styled - document how to manage live environment variables - Update all fixtures to include tasks -- Update all fixtures to include tasks - Update the specs to work with the new task-enabled fixtures +- Remove `Journey#section_groups` and sever the direct Journey -> Steps association ## [release-010] - 2021-05-27 diff --git a/app/helpers/journey_helper.rb b/app/helpers/journey_helper.rb deleted file mode 100644 index 87e6dbf12..000000000 --- a/app/helpers/journey_helper.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module JourneyHelper - def section_group_with_steps(journey:, steps:) - step_lookup = steps.group_by(&:contentful_id) - - journey.section_groups.each do |section| - ordered_step_objects = section["steps"].each_with_object([]) { |step, result| - next unless step_lookup[step["contentful_id"]] - result[step["order"]] = step_lookup[step["contentful_id"]].first - } - section["steps"] = ordered_step_objects.compact - end - end -end diff --git a/app/services/create_journey.rb b/app/services/create_journey.rb index 6b3d15946..e01842c00 100644 --- a/app/services/create_journey.rb +++ b/app/services/create_journey.rb @@ -17,7 +17,6 @@ def call liquid_template: category.combined_specification_template ) - journey.section_groups = build_section_groupings(sections: contentful_sections) journey.save! contentful_sections.each do |contentful_section| @@ -53,16 +52,4 @@ def call journey end - - private def build_section_groupings(sections:) - sections.each_with_object([]).with_index { |(section, result), index| - result[index] = { - order: index, - title: section.title, - steps: section.steps.each_with_object([]).with_index { |(step, result), index| - result << {contentful_id: step.id, order: index} - } - } - } - end end diff --git a/db/migrate/20210427154238_remove_section_groups_from_journeys.rb b/db/migrate/20210427154238_remove_section_groups_from_journeys.rb new file mode 100644 index 000000000..7a7931a86 --- /dev/null +++ b/db/migrate/20210427154238_remove_section_groups_from_journeys.rb @@ -0,0 +1,5 @@ +class RemoveSectionGroupsFromJourneys < ActiveRecord::Migration[6.1] + def change + remove_column :journeys, :section_groups, :jsonb + end +end diff --git a/db/schema.rb b/db/schema.rb index 42d48e356..8a9155438 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_04_19_082411) do +ActiveRecord::Schema.define(version: 2021_04_27_154238) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" @@ -40,7 +40,6 @@ t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.jsonb "liquid_template", null: false - t.jsonb "section_groups" t.uuid "user_id" t.boolean "started", default: true t.datetime "last_worked_on" diff --git a/spec/factories/journey.rb b/spec/factories/journey.rb index dbae336c7..4f0e6e6f4 100644 --- a/spec/factories/journey.rb +++ b/spec/factories/journey.rb @@ -2,7 +2,6 @@ factory :journey do category { "catering" } liquid_template { "Your answer was {{ answer_47EI2X2T5EDTpJX9WjRR9p }}" } - section_groups { [] } started { true } last_worked_on { Time.zone.now } diff --git a/spec/features/school_buying_professionals/edit_their_answers_spec.rb b/spec/features/school_buying_professionals/edit_their_answers_spec.rb index 8ca1b549d..903250ca8 100644 --- a/spec/features/school_buying_professionals/edit_their_answers_spec.rb +++ b/spec/features/school_buying_professionals/edit_their_answers_spec.rb @@ -6,21 +6,7 @@ before do journey = answer.step.journey - journey.update( - user: user, - section_groups: [ - { - "order" => 0, - "title" => "Section A", - "steps" => [ - { - "contentful_id" => answer.step.contentful_id, - "order" => 0 - } - ] - } - ] - ) + journey.update(user: user) end let(:answer) { create(:short_text_answer, response: "answer") } diff --git a/spec/features/school_buying_professionals/view_a_list_of_tasks_spec.rb b/spec/features/school_buying_professionals/view_a_list_of_tasks_spec.rb index 69547d9db..33aa4b130 100644 --- a/spec/features/school_buying_professionals/view_a_list_of_tasks_spec.rb +++ b/spec/features/school_buying_professionals/view_a_list_of_tasks_spec.rb @@ -36,25 +36,12 @@ stub_contentful_category(fixture_filename: "multiple-sections.json") answer = create(:short_text_answer, response: "answer") - answer.step.journey.update( - user: user, - section_groups: [ - { - "order" => 0, - "title" => "Section A", - "steps" => [ - { - "contentful_id" => answer.step.contentful_id, - "order" => 0 - } - ] - } - ] - ) + journey = answer.step.journey + journey.update(user: user) user_starts_the_journey - visit journey_path(answer.step.journey) + visit journey_path(journey) expect(page).to have_content(I18n.t("task_list.status.completed")) end diff --git a/spec/helpers/journey_helper_spec.rb b/spec/helpers/journey_helper_spec.rb deleted file mode 100644 index 27ab24c60..000000000 --- a/spec/helpers/journey_helper_spec.rb +++ /dev/null @@ -1,100 +0,0 @@ -require "rails_helper" - -RSpec.describe JourneyHelper, type: :helper do - describe "#section_group_with_steps" do - it "returns an ordered array of steps" do - journey = create(:journey, section_groups: "") - section = create(:section, journey: journey) - task = create(:task, section: section) - step_1 = StepPresenter.new(create(:step, :radio, task: task)) - step_2 = StepPresenter.new(create(:step, :long_text, task: task)) - step_3 = StepPresenter.new(create(:step, :short_text, task: task)) - - section_groups = [ - { - "order" => 0, - "title" => "Objectives", - "steps" => [ - { - "contentful_id" => step_1.contentful_id, - "order" => 0 - }, - { - "contentful_id" => step_2.contentful_id, - "order" => 1 - } - ] - }, - { - "order" => 1, - "title" => "Social value", - "steps" => [ - { - "contentful_id" => step_3.contentful_id, - "order" => 0 - } - ] - } - ] - journey.update(section_groups: section_groups) - - result = helper.section_group_with_steps( - journey: journey, steps: [step_1, step_2, step_3] - ) - - expect(result.first["steps"]).to eq([step_1, step_2]) - expect(result.second["steps"]).to eq([step_3]) - end - end - - context "when the ordering we want does not match the order saved in the database" do - it "the ordering defined by 'order' is preserved" do - journey = create(:journey, section_groups: "") - section = create(:section, journey: journey) - task = create(:task, section: section) - step_1 = StepPresenter.new(create(:step, :radio, title: "First question", task: task)) - step_2 = StepPresenter.new(create(:step, :long_text, title: "Second question", task: task)) - step_3 = StepPresenter.new(create(:step, :short_text, title: "Third question", task: task)) - step_4 = StepPresenter.new(create(:step, :short_text, title: "Fourth question", task: task)) - - section_groups = [ - { - "order" => 1, - "title" => "Objectives", - "steps" => [ - { - "contentful_id" => step_2.contentful_id, - "order" => 2 - }, - { - "contentful_id" => step_1.contentful_id, - "order" => 1 - }, - { - "contentful_id" => step_3.contentful_id, - "order" => 3 - } - ] - }, - { - "order" => 0, - "title" => "Social value", - "steps" => [ - { - "contentful_id" => step_4.contentful_id, - "order" => 0 - } - ] - } - ] - journey.update(section_groups: section_groups) - - result = helper.section_group_with_steps( - journey: journey, steps: [step_1, step_2, step_3, step_4] - ) - - expect(result.first["steps"]).to eq([step_1, step_2, step_3]) - expect(result.second["steps"]).to eq([step_4]) - end - end -end diff --git a/spec/services/create_journey_spec.rb b/spec/services/create_journey_spec.rb index ea5720f37..75992a123 100644 --- a/spec/services/create_journey_spec.rb +++ b/spec/services/create_journey_spec.rb @@ -60,35 +60,6 @@ .to eql("

Liquid {{templating}}

") end - it "stores the section grouping on the journey in the expected order" do - stub_contentful_category( - fixture_filename: "multiple-sections-and-steps.json" - ) - - described_class.new(category_name: "catering", user: build(:user)).call - - journey = Journey.last - - expect(journey.reload.section_groups).to eq([ - { - "order" => 0, - "title" => "Section A", - "steps" => [ - {"contentful_id" => "radio-question", "order" => 0}, - {"contentful_id" => "single-date-question", "order" => 1} - ] - }, - { - "order" => 1, - "title" => "Section B", - "steps" => [ - {"contentful_id" => "long-text-question", "order" => 0}, - {"contentful_id" => "short-text-question", "order" => 1} - ] - } - ]) - end - context "when the journey cannot be saved" do it "raises an error" do stub_contentful_category( From dffa020e1c4661bf602746167b4f1b33d3a373e3 Mon Sep 17 00:00:00 2001 From: Laura Porter Date: Tue, 27 Apr 2021 17:12:05 +0100 Subject: [PATCH 22/30] Remove block that only existed to cover for missing tasks in fixtures Previously we did not have tasks in most fixtures, so this block was needed to "get around" this fact and keep the test suite running. However, now that all fixtures include tasks and therefore reflect what Contentful actually looks like, we can remove the workaround. --- app/services/create_journey.rb | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/app/services/create_journey.rb b/app/services/create_journey.rb index e01842c00..68e5c26f6 100644 --- a/app/services/create_journey.rb +++ b/app/services/create_journey.rb @@ -22,31 +22,16 @@ def call contentful_sections.each do |contentful_section| section = CreateSection.new(journey: journey, contentful_section: contentful_section).call - # The entire `if` block here exists to support our fixtures which do not nest steps - # within tasks. Once we update our fixtures to the "new way" of doing things, this - # entire `if` block can be discarded. - if contentful_section.respond_to?(:tasks) && !contentful_section.tasks.any? - question_entries = GetStepsFromSection.new(section: contentful_section).call - question_entries.each do |entry| - fake_contentful_task = OpenStruct.new(title: entry.title, id: entry.id) - task = CreateTask.new(section: section, contentful_task: fake_contentful_task).call + contentful_tasks = GetTasksFromSection.new(section: contentful_section).call + contentful_tasks.each do |contentful_task| + task = CreateTask.new(section: section, contentful_task: contentful_task).call + question_entries = GetStepsFromTask.new(task: contentful_task).call + question_entries.each do |entry| CreateJourneyStep.new( - task: task, contentful_entry: entry + contentful_entry: entry, task: task ).call end - else - contentful_tasks = GetTasksFromSection.new(section: contentful_section).call - contentful_tasks.each do |contentful_task| - task = CreateTask.new(section: section, contentful_task: contentful_task).call - - question_entries = GetStepsFromTask.new(task: contentful_task).call - question_entries.each do |entry| - CreateJourneyStep.new( - contentful_entry: entry, task: task - ).call - end - end end end From b14e11140d7a3fafb21579259fee5b48c07a5323 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 May 2021 10:03:33 +0000 Subject: [PATCH 23/30] Bump bootsnap from 1.7.4 to 1.7.5 Bumps [bootsnap](https://github.com/Shopify/bootsnap) from 1.7.4 to 1.7.5. - [Release notes](https://github.com/Shopify/bootsnap/releases) - [Changelog](https://github.com/Shopify/bootsnap/blob/master/CHANGELOG.md) - [Commits](https://github.com/Shopify/bootsnap/compare/v1.7.4...v1.7.5) Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 6530c763b..576671517 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -71,7 +71,7 @@ GEM rack (>= 0.9.0) bindata (2.4.8) bindex (0.8.1) - bootsnap (1.7.4) + bootsnap (1.7.5) msgpack (~> 1.0) brakeman (5.0.1) builder (3.2.4) From fbacbde162b0a5069db5fe094450a59449aab36e Mon Sep 17 00:00:00 2001 From: Nick Jackson Date: Tue, 27 Apr 2021 14:42:33 +0100 Subject: [PATCH 24/30] Add display of task completion to task list This adds display of "not started", "in progress" or "completed" labels to task groups on the task list. --- CHANGELOG.md | 1 + app/models/step.rb | 4 +++ app/models/task.rb | 36 ++++++++++++++++++- app/views/journeys/show.html.erb | 7 ++++ config/locales/en.yml | 1 + spec/models/task_spec.rb | 60 ++++++++++++++++++++++++++++++++ 6 files changed, 108 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c37b9afd..73dc0cf4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog 1.0.0]. - Update all fixtures to include tasks - Update the specs to work with the new task-enabled fixtures - Remove `Journey#section_groups` and sever the direct Journey -> Steps association +- tasks now have their completion status indicated on the task list ## [release-010] - 2021-05-27 diff --git a/app/models/step.rb b/app/models/step.rb index d27f8e0d1..575d816cd 100644 --- a/app/models/step.rb +++ b/app/models/step.rb @@ -25,6 +25,10 @@ def answer end end + def answered? + !answer.nil? + end + def primary_call_to_action_text return I18n.t("generic.button.next") unless super.present? super diff --git a/app/models/task.rb b/app/models/task.rb index de484c626..ffbf6b5d0 100644 --- a/app/models/task.rb +++ b/app/models/task.rb @@ -5,11 +5,45 @@ class Task < ApplicationRecord validates :title, :contentful_id, presence: true + attr_accessor + + NOT_STARTED = 0 + IN_PROGRESS = 1 + COMPLETED = 2 + def visible_steps steps.where(hidden: false) end + def visible_steps_count + visible_steps.count + end + def has_single_visible_step? - visible_steps.count == 1 + visible_steps_count == 1 + end + + def answered_questions_count + visible_steps.includes([ + :short_text_answer, + :long_text_answer, + :radio_answer, + :checkbox_answers, + :currency_answer, + :number_answer, + :single_date_answer + ]).count { |step| step.answered? } + end + + def status + if answered_questions_count == visible_steps_count + return COMPLETED + end + + if answered_questions_count > 0 + return IN_PROGRESS + end + + NOT_STARTED end end diff --git a/app/views/journeys/show.html.erb b/app/views/journeys/show.html.erb index 572b11d12..3ce611405 100644 --- a/app/views/journeys/show.html.erb +++ b/app/views/journeys/show.html.erb @@ -31,6 +31,13 @@ <%= link_to task.title, journey_task_path(@journey, task), class: "govuk-link", 'aria-describedby': task.id + "-status"%> + <% if task.status == Task::COMPLETED %> + "><%= I18n.t("task_list.status.completed") %> + <% elsif task.status == Task::IN_PROGRESS %> + "><%= I18n.t("task_list.status.in_progress") %> + <% elsif task.status == Task::NOT_STARTED %> + "><%= I18n.t("task_list.status.not_started") %> + <% end %> <% end %> <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 990bff116..cf7b3dfea 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -85,6 +85,7 @@ en: task_list: status: not_started: Not started + in_progress: In progress completed: Completed task: buttons: diff --git a/spec/models/task_spec.rb b/spec/models/task_spec.rb index 641e4fcf9..529c347f9 100644 --- a/spec/models/task_spec.rb +++ b/spec/models/task_spec.rb @@ -19,6 +19,16 @@ end end + describe "#visible_steps_count" do + it "returns the number of visible steps" do + task = create(:task) + create(:step, :radio, hidden: false, task: task) + create(:step, :radio, hidden: true, task: task) + + expect(task.visible_steps_count).to eq 1 + end + end + describe "#has_single_visible_step?" do context "when the task has one visible step" do it "returns true" do @@ -40,4 +50,54 @@ end end end + + describe "#answered_questions_count" do + it "returns the number of visible questions which have been answered" do + task = create(:task) + step_1 = create(:step, :radio, hidden: false, task: task) + create(:radio_answer, step: step_1) + step_2 = create(:step, :radio, hidden: true, task: task) + create(:radio_answer, step: step_2) + create(:step, :radio, hidden: false, task: task) + create(:step, :radio, hidden: true, task: task) + + expect(task.answered_questions_count).to eq 1 + end + end + + describe "#status" do + it "returns NOT_STARTED when no visible questions have been answered" do + task = create(:task) + create(:step, :radio, hidden: false, task: task) + step_2 = create(:step, :radio, hidden: true, task: task) + create(:radio_answer, step: step_2) + + expect(task.status).to eq Task::NOT_STARTED + end + + it "returns IN_PROGRESS when some but not all visible questions have been answered" do + task = create(:task) + step_1 = create(:step, :radio, hidden: false, task: task) + create(:radio_answer, step: step_1) + step_2 = create(:step, :radio, hidden: true, task: task) + create(:radio_answer, step: step_2) + create(:step, :radio, hidden: true, task: task) + create(:step, :radio, hidden: false, task: task) + + expect(task.status).to eq Task::IN_PROGRESS + end + + it "returns COMPLETED when all visible questions have been answered" do + task = create(:task) + step_1 = create(:step, :radio, hidden: false, task: task) + create(:radio_answer, step: step_1) + step_2 = create(:step, :radio, hidden: true, task: task) + create(:radio_answer, step: step_2) + step_3 = create(:step, :radio, hidden: false, task: task) + create(:radio_answer, step: step_3) + create(:step, :radio, hidden: true, task: task) + + expect(task.status).to eq Task::COMPLETED + end + end end From 891469f3720d0e02948ff538e56e4d207ea0a541 Mon Sep 17 00:00:00 2001 From: Lorna Harwood Date: Thu, 6 May 2021 10:43:06 +0100 Subject: [PATCH 25/30] Make breadcrumb journey match the user journey Back buttons now take the user back to the last logical step in the journey. --- app/views/journeys/show.html.erb | 2 +- .../view_a_list_of_tasks_spec.rb | 52 ++++++++++++++++++- .../view_existing_journeys_spec.rb | 1 - 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/app/views/journeys/show.html.erb b/app/views/journeys/show.html.erb index 3ce611405..358b9118f 100644 --- a/app/views/journeys/show.html.erb +++ b/app/views/journeys/show.html.erb @@ -1,6 +1,6 @@ <%= content_for :title, @journey.category.capitalize %> -<%= link_to I18n.t("generic.button.back"), dashboard_path, class: "govuk-back-link" %> +<%= link_to I18n.t("generic.button.back"), journeys_path, class: "govuk-back-link" %>

<%= I18n.t("specifying.start_page.page_title") %>

    diff --git a/spec/features/school_buying_professionals/view_a_list_of_tasks_spec.rb b/spec/features/school_buying_professionals/view_a_list_of_tasks_spec.rb index 33aa4b130..5811d3e85 100644 --- a/spec/features/school_buying_professionals/view_a_list_of_tasks_spec.rb +++ b/spec/features/school_buying_professionals/view_a_list_of_tasks_spec.rb @@ -23,11 +23,61 @@ end end - scenario "user can navigate back to the dashboard" do + scenario "user can navigate back to the task list from a task view" do + start_journey_with_tasks_from_category(category: "section-with-multiple-tasks.json") + + within(".app-task-list") do + click_on "Task with multiple steps" + end + + click_on(I18n.t("generic.button.back")) + + expect(page).to have_content(I18n.t("specifying.start_page.page_title")) + end + + scenario "user can navigate back to the list of journeys from a task list" do start_journey_from_category(category: "extended-radio-question.json") click_on(I18n.t("generic.button.back")) + expect(page).to have_content(I18n.t("journey.index.existing.header")) + end + + context "When a task has one question" do + scenario "user can navigate back to the task list from a question" do + start_journey_with_tasks_from_category(category: "section-with-single-task.json") + + within(".app-task-list") do + click_on "Everyday services that are required and need to be considered" + end + + click_on(I18n.t("generic.button.back")) + + expect(page).to have_content(I18n.t("specifying.start_page.page_title")) + end + end + + context "When a task has more than one question" do + scenario "user can navigate back to the task view from a question" do + start_journey_with_tasks_from_category(category: "section-with-multiple-tasks.json") + + within(".app-task-list") do + click_on "Task with multiple steps" + end + + click_on "Everyday services that are required and need to be considered" + click_on(I18n.t("generic.button.back")) + + expect(page).to have_content("Task with multiple steps") + end + end + + scenario "user can navigate back to the dashboard from a question" do + start_journey_from_category(category: "extended-radio-question.json") + + click_on(I18n.t("generic.button.back")) + click_on(I18n.t("generic.button.back")) + expect(page).to have_content(I18n.t("dashboard.header")) end diff --git a/spec/features/school_buying_professionals/view_existing_journeys_spec.rb b/spec/features/school_buying_professionals/view_existing_journeys_spec.rb index 268d77f6b..d5d4b1c93 100644 --- a/spec/features/school_buying_professionals/view_existing_journeys_spec.rb +++ b/spec/features/school_buying_professionals/view_existing_journeys_spec.rb @@ -36,7 +36,6 @@ start_journey_from_category(category: "radio-question.json") click_on(I18n.t("generic.button.back")) - click_on(I18n.t("dashboard.existing.link")) expect(page).to have_content("15 February 2021") expect(page).not_to have_content("20 March 2021") From 52198449a82faab8276a7a14dd9e4ba23dc8fcfc Mon Sep 17 00:00:00 2001 From: Nick Jackson Date: Tue, 4 May 2021 12:21:07 +0100 Subject: [PATCH 26/30] Add script/update and script/bootstrap To closer follow the Scripts To Rule Them All pattern, these scripts will automate updating dependencies and performing migrations. They are also run automatically as part of script/test. --- Brewfile | 3 +++ script/bootstrap | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ script/test | 1 + script/update | 16 ++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 Brewfile create mode 100755 script/bootstrap create mode 100755 script/update diff --git a/Brewfile b/Brewfile new file mode 100644 index 000000000..c885b8017 --- /dev/null +++ b/Brewfile @@ -0,0 +1,3 @@ +brew "postgresql" +brew "redis" +brew "rbenv" diff --git a/script/bootstrap b/script/bootstrap new file mode 100755 index 000000000..701c6d659 --- /dev/null +++ b/script/bootstrap @@ -0,0 +1,64 @@ +#!/bin/sh + +# script/bootstrap: Resolve all dependencies that the application requires to +# run. + +set -e + +cd "$(dirname "$0")/.." + +if [ -f .gitmodules ]; then + echo "==> Updating Git submodules..." + git submodule update --init +fi + +if [ -z "$CI" ]; then + if [ -f Brewfile ] && [ "$(uname -s)" = "Darwin" ]; then + if ! brew bundle check >/dev/null 2>&1; then + echo "==> Installing Homebrew dependencies..." + brew bundle install --verbose --no-lock + fi + fi + + if [ -f .ruby-version ]; then + eval "$(rbenv init -)" + + if [ -z "$(rbenv version-name 2>/dev/null)" ]; then + echo "==> Installing Ruby..." + rbenv install --skip-existing + rbenv rehash + fi + fi + + if [ -f .node-version ]; then + eval "$(nodenv init -)" + + if [ -z "$(nodenv version-name 2>/dev/null)" ]; then + echo "==> Installing Node..." + nodenv install --skip-existing + nodenv rehash + fi + fi +fi + +if ! command -v bundle >/dev/null 2>&1; then + echo "==> Installing Bundler..." + gem install bundler + + if [ -z "$CI" ]; then + rbenv rehash + fi +fi + +if ! bundle check >/dev/null 2>&1; then + echo "==> Installing Ruby dependencies..." + bundle config set path vendor/bundle + bundle install +fi + +# if [ -f package.json ]; then +# if ! yarn check --verify-tree >/dev/null 2>&1; then +# echo "==> Installing JS dependencies..." +# yarn install +# fi +# fi diff --git a/script/test b/script/test index d6321420f..f76732c34 100755 --- a/script/test +++ b/script/test @@ -12,6 +12,7 @@ if [ -n "$DEBUG" ]; then fi echo "==> Updating..." +script/update TEST_FILE=$1 diff --git a/script/update b/script/update new file mode 100755 index 000000000..78beb598c --- /dev/null +++ b/script/update @@ -0,0 +1,16 @@ +#!/bin/sh + +# script/update: Update application to run for its current checkout. + +set -e + +cd "$(dirname "$0")/.." + +echo "==> Bootstrapping..." +script/bootstrap + +echo "==> Running database migrations..." +bundle exec rails db:migrate + +echo "==> Running test database migrations..." +RAILS_ENV="test" bundle exec rails db:migrate From 24e625528d5cd2fdc97b452f70c734a4ee463925 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 May 2021 11:36:09 +0000 Subject: [PATCH 27/30] Bump rails from 6.1.3.1 to 6.1.3.2 Bumps [rails](https://github.com/rails/rails) from 6.1.3.1 to 6.1.3.2. - [Release notes](https://github.com/rails/rails/releases) - [Commits](https://github.com/rails/rails/compare/v6.1.3.1...v6.1.3.2) Signed-off-by: dependabot[bot] --- Gemfile.lock | 110 +++++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 576671517..1fd7b20d7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,60 +1,60 @@ GEM remote: https://rubygems.org/ specs: - actioncable (6.1.3.1) - actionpack (= 6.1.3.1) - activesupport (= 6.1.3.1) + actioncable (6.1.3.2) + actionpack (= 6.1.3.2) + activesupport (= 6.1.3.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.3.1) - actionpack (= 6.1.3.1) - activejob (= 6.1.3.1) - activerecord (= 6.1.3.1) - activestorage (= 6.1.3.1) - activesupport (= 6.1.3.1) + actionmailbox (6.1.3.2) + actionpack (= 6.1.3.2) + activejob (= 6.1.3.2) + activerecord (= 6.1.3.2) + activestorage (= 6.1.3.2) + activesupport (= 6.1.3.2) mail (>= 2.7.1) - actionmailer (6.1.3.1) - actionpack (= 6.1.3.1) - actionview (= 6.1.3.1) - activejob (= 6.1.3.1) - activesupport (= 6.1.3.1) + actionmailer (6.1.3.2) + actionpack (= 6.1.3.2) + actionview (= 6.1.3.2) + activejob (= 6.1.3.2) + activesupport (= 6.1.3.2) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.1.3.1) - actionview (= 6.1.3.1) - activesupport (= 6.1.3.1) + actionpack (6.1.3.2) + actionview (= 6.1.3.2) + activesupport (= 6.1.3.2) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.3.1) - actionpack (= 6.1.3.1) - activerecord (= 6.1.3.1) - activestorage (= 6.1.3.1) - activesupport (= 6.1.3.1) + actiontext (6.1.3.2) + actionpack (= 6.1.3.2) + activerecord (= 6.1.3.2) + activestorage (= 6.1.3.2) + activesupport (= 6.1.3.2) nokogiri (>= 1.8.5) - actionview (6.1.3.1) - activesupport (= 6.1.3.1) + actionview (6.1.3.2) + activesupport (= 6.1.3.2) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.3.1) - activesupport (= 6.1.3.1) + activejob (6.1.3.2) + activesupport (= 6.1.3.2) globalid (>= 0.3.6) - activemodel (6.1.3.1) - activesupport (= 6.1.3.1) - activerecord (6.1.3.1) - activemodel (= 6.1.3.1) - activesupport (= 6.1.3.1) - activestorage (6.1.3.1) - actionpack (= 6.1.3.1) - activejob (= 6.1.3.1) - activerecord (= 6.1.3.1) - activesupport (= 6.1.3.1) + activemodel (6.1.3.2) + activesupport (= 6.1.3.2) + activerecord (6.1.3.2) + activemodel (= 6.1.3.2) + activesupport (= 6.1.3.2) + activestorage (6.1.3.2) + actionpack (= 6.1.3.2) + activejob (= 6.1.3.2) + activerecord (= 6.1.3.2) + activesupport (= 6.1.3.2) marcel (~> 1.0.0) mini_mime (~> 1.0.2) - activesupport (6.1.3.1) + activesupport (6.1.3.2) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -187,10 +187,10 @@ GEM nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) - marcel (1.0.0) + marcel (1.0.1) method_source (1.0.0) mini_mime (1.0.3) - mini_portile2 (2.5.0) + mini_portile2 (2.5.1) mini_racer (0.4.0) libv8-node (~> 15.14.0.0) minitest (5.14.4) @@ -243,20 +243,20 @@ GEM rack (>= 2.1.0) rack-test (1.1.0) rack (>= 1.0, < 3) - rails (6.1.3.1) - actioncable (= 6.1.3.1) - actionmailbox (= 6.1.3.1) - actionmailer (= 6.1.3.1) - actionpack (= 6.1.3.1) - actiontext (= 6.1.3.1) - actionview (= 6.1.3.1) - activejob (= 6.1.3.1) - activemodel (= 6.1.3.1) - activerecord (= 6.1.3.1) - activestorage (= 6.1.3.1) - activesupport (= 6.1.3.1) + rails (6.1.3.2) + actioncable (= 6.1.3.2) + actionmailbox (= 6.1.3.2) + actionmailer (= 6.1.3.2) + actionpack (= 6.1.3.2) + actiontext (= 6.1.3.2) + actionview (= 6.1.3.2) + activejob (= 6.1.3.2) + activemodel (= 6.1.3.2) + activerecord (= 6.1.3.2) + activestorage (= 6.1.3.2) + activesupport (= 6.1.3.2) bundler (>= 1.15.0) - railties (= 6.1.3.1) + railties (= 6.1.3.2) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) @@ -264,9 +264,9 @@ GEM rails-html-sanitizer (1.3.0) loofah (~> 2.3) rails_layout (1.0.42) - railties (6.1.3.1) - actionpack (= 6.1.3.1) - activesupport (= 6.1.3.1) + railties (6.1.3.2) + actionpack (= 6.1.3.2) + activesupport (= 6.1.3.2) method_source rake (>= 0.8.7) thor (~> 1.0) From c76671e1c117b665bf5fd71d6f46a3863b5a281a Mon Sep 17 00:00:00 2001 From: Tom Hipkin Date: Wed, 5 May 2021 13:35:39 +0100 Subject: [PATCH 28/30] Prevent deployment failure when DOCKER_IMAGE contains a partial secret Github will obfuscate any output that contains a secret IF that secret has been/is being used. We move the global `GITHUB_SECRETS_JSON` variable down into the deploy step where it's needed. We don't need all variables loaded into json for the build stage. This doesn't get us all the way though since we had an echo in the build step: ``` echo "TF_VAR_docker_image=${{needs.build.outputs.tf_var_docker_image}}" >> $GITHUB_ENV ``` This line can set the `TF_VAR_DOCKER_IMAGE` to be a value that contains an obfuscating. Eg. with a GIT_SHA of 2387456***329487562. This doesn't exist when Terraform tries to deploy and it all goes badly. Instead of echoing, we try passing the docker image to the script directly, rather than trying to set a new environment variable. The hope will be, because we don't echo, github doesn't change the docker image to include the asterisks. --- .github/workflows/deploy.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5a175e6b2..5bbc44296 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -15,7 +15,6 @@ env: CF_PASSWORD: ${{ secrets.CF_PASSWORD }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - GITHUB_SECRETS_JSON: ${{ toJson(secrets) }} jobs: build: @@ -48,11 +47,12 @@ jobs: deploy: needs: build runs-on: ubuntu-latest + env: + TF_VAR_docker_image: ${{needs.build.outputs.tf_var_docker_image}} + GITHUB_SECRETS_JSON: ${{ toJson(secrets) }} steps: - name: Check out code uses: actions/checkout@v2 - - name: Set TFVAR Docker Image environment variable - run: echo "TF_VAR_docker_image=${{needs.build.outputs.tf_var_docker_image}}" >> $GITHUB_ENV - name: Deploy terraform to staging env: TF_VAR_environment: "staging" From ebc01cf1916e4ea3135aeaa99d0bf4bd25e5556c Mon Sep 17 00:00:00 2001 From: Nick Jackson Date: Mon, 10 May 2021 15:02:46 +0100 Subject: [PATCH 29/30] Fix time-travelling releases These releases are now correctly dated in April, instead of May. --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73dc0cf4f..1d418d006 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ The format is based on [Keep a Changelog 1.0.0]. - Remove `Journey#section_groups` and sever the direct Journey -> Steps association - tasks now have their completion status indicated on the task list -## [release-010] - 2021-05-27 +## [release-010] - 2021-04-27 - add header and footer information for feedback and data requests - force SSL in production to only accept HTTPS traffic, enable HSTS and secure tower cookies @@ -31,17 +31,17 @@ The format is based on [Keep a Changelog 1.0.0]. - cache CI builds to reduce build times - log information about contentful cache busting webhooks for debugging -## [release-009] - 2021-05-21 +## [release-009] - 2021-04-21 - fix multiple specification fields - content security policy - remove humans.txt -## [release-008] - 2021-05-19 +## [release-008] - 2021-04-19 - auto deploy research and preview environments -## [release-007] - 2021-05-19 +## [release-007] - 2021-04-19 - Add `noindex,nofollow` meta tag to all pages, as per Gov.UK guidance - fix API auth by switching mechanism from Basic to Token From eaef0cc66ce3d15898962f24066cf7d1111c6045 Mon Sep 17 00:00:00 2001 From: Nick Jackson Date: Mon, 10 May 2021 15:03:55 +0100 Subject: [PATCH 30/30] Release 011 - error pages are styled - document how to manage live environment variables - Update all fixtures to include tasks - Update the specs to work with the new task-enabled fixtures - Remove `Journey#section_groups` and sever the direct Journey -> Steps association - tasks now have their completion status indicated on the task list --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d418d006..d2be14466 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog 1.0.0]. ## [Unreleased] +## [release-011] - 2021-05-10 + - error pages are styled - document how to manage live environment variables - Update all fixtures to include tasks @@ -158,7 +160,8 @@ Contentful fixture - Contentful can redirect users to preview endpoints - users can be asked to answer a long text question -[unreleased]: https://github.com/DFE-Digital/buy-for-your-school/compare/release-010...HEAD +[unreleased]: https://github.com/DFE-Digital/buy-for-your-school/compare/release-011...HEAD +[release-011]: https://github.com/DFE-Digital/buy-for-your-school/compare/release-010...release-011 [release-010]: https://github.com/DFE-Digital/buy-for-your-school/compare/release-009...release-010 [release-009]: https://github.com/DFE-Digital/buy-for-your-school/compare/release-008...release-009 [release-008]: https://github.com/DFE-Digital/buy-for-your-school/compare/release-007...release-008