Skip to content

Commit

Permalink
Order copy cards (#139)
Browse files Browse the repository at this point in the history
* Order copy cards

https://eaflood.atlassian.net/browse/WC-248

Before they see the total cost to renew their registration, users are offered the chance to order laminated credit-card-sized copies of their registration. These are currently known as copy cards, but may be renamed to registration cards (or something else) in the future for clarity.

* Scaffold form and add to routing

* First draft of form content

Started filling in the form with content and a field (defaulting to a value of 0 for now).

This content will be fine-tuned in the future.

* Persist and validate number of cards to order

We have decided to hold off on implementing WorldPay for now and focus on getting as much of the journey done as possible for user testing first. So for now, we will just save the number of cards as a temporary attribute.

The field is populated with 0 by default but can be changed to any positive integer (or left blank).

* Update text and add image

Revise the copy card (or 'registration card') form to include new text from the content designer and an image of an example card.
  • Loading branch information
irisfaraway committed Apr 27, 2018
1 parent 7637b55 commit 7891963
Show file tree
Hide file tree
Showing 20 changed files with 462 additions and 14 deletions.
Binary file added app/assets/images/example_card.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,7 @@ main {
.strong {
font-weight: bold;
}

.text img {
max-width: 100%;
}
9 changes: 9 additions & 0 deletions app/controllers/cards_forms_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class CardsFormsController < FormsController
def new
super(CardsForm, "cards_form")
end

def create
super(CardsForm, "cards_form")
end
end
21 changes: 21 additions & 0 deletions app/forms/cards_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class CardsForm < BaseForm
attr_accessor :temp_cards

def initialize(transient_registration)
super
self.temp_cards = @transient_registration.temp_cards || 0
end

def submit(params)
# Assign the params for validation and pass them to the BaseForm method for updating
self.temp_cards = params[:temp_cards]
attributes = { temp_cards: temp_cards }

super(attributes, params[:reg_identifier])
end

# Must be a positive integer or 0
# Leaving it blank is also valid - this will automatically sub in a 0 since the field is marked as an Integer
validates :temp_cards, numericality: { only_integer: true, greater_than_or_equal_to: 0 },
allow_blank: true
end
9 changes: 8 additions & 1 deletion app/models/concerns/can_change_workflow_status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ module CanChangeWorkflowStatus

state :check_your_answers_form
state :declaration_form
state :cards_form
state :payment_summary_form
state :worldpay_form

Expand Down Expand Up @@ -239,6 +240,9 @@ module CanChangeWorkflowStatus
to: :declaration_form

transitions from: :declaration_form,
to: :cards_form

transitions from: :cards_form,
to: :payment_summary_form

transitions from: :payment_summary_form,
Expand Down Expand Up @@ -408,9 +412,12 @@ module CanChangeWorkflowStatus
transitions from: :declaration_form,
to: :check_your_answers_form

transitions from: :payment_summary_form,
transitions from: :cards_form,
to: :declaration_form

transitions from: :payment_summary_form,
to: :cards_form

transitions from: :worldpay_form,
to: :payment_summary_form

Expand Down
1 change: 1 addition & 0 deletions app/models/transient_registration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class TransientRegistration
after_initialize :copy_data_from_registration

# Attributes specific to the transient object - all others are in CanHaveRegistrationAttributes
field :temp_cards, type: Integer
field :temp_company_postcode, type: String
field :temp_contact_postcode, type: String
field :temp_os_places_error, type: Boolean
Expand Down
34 changes: 34 additions & 0 deletions app/views/cards_forms/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<%= render("shared/back", back_path: back_cards_forms_path(@cards_form.reg_identifier)) %>

<div class="text">
<%= form_for(@cards_form) do |f| %>
<%= render("shared/errors", object: @cards_form) %>

<h1 class="heading-large"><%= t(".heading") %></h1>

<p><%= t(".paragraph_1") %></p>
<%= image_tag "example_card.jpg", alt: t(".card_alt_text") %>
<p><%= t(".paragraph_2") %></p>
<p><%= t(".paragraph_3") %></p>

<% if @cards_form.errors[:temp_cards].any? %>
<div class="form-group form-group-error">
<% else %>
<div class="form-group">
<% end %>
<fieldset id="temp_cards">
<% if @cards_form.errors[:temp_cards].any? %>
<span class="error-message"><%= @cards_form.errors[:temp_cards].join(", ") %></span>
<% end %>
<%= f.label :temp_cards, t(".temp_cards_label"), class: "form-label" %>
<%= f.text_field :temp_cards, value: @cards_form.temp_cards, class: "form-control" %>
</fieldset>
</div>

<%= f.hidden_field :reg_identifier, value: @cards_form.reg_identifier %>
<div class="form-group">
<%= f.submit t(".next_button"), class: "button" %>
</div>
<% end %>
</div>
25 changes: 25 additions & 0 deletions config/locales/forms/cards_forms/en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
en:
cards_forms:
new:
title: Certificate and registration cards
heading: Certificate and registration cards
paragraph_1: A registration card (copy card) is a convenient way of keeping your waste carrier registration details to hand. A card costs £5, and you can buy more through your online account after you’ve registered.
paragraph_2: You automatically get a certificate with your registration details, which can be shown to the relevant authorities. You’ll get a link to download this after payment.
paragraph_3: Cards can take up to 10 working days to arrive, depending on the status of your registration.
card_alt_text: A photo of an example registration card, showing the details of the registered business
temp_cards_label: Cards to order
error_heading: Something is wrong
next_button: Continue
activemodel:
errors:
models:
cards_form:
attributes:
temp_cards:
not_a_number: "You must enter a number"
greater_than_or_equal_to: "You cannot order a negative number of cards"
not_an_integer: "You must enter a whole number, not a fraction"
reg_identifier:
invalid_format: "The registration ID is not in a valid format"
no_registration: "There is no registration matching this ID"
renewal_in_progress: "This renewal is already in progress"
10 changes: 10 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,16 @@
on: :collection
end

resources :cards_forms,
only: [:new, :create],
path: "cards",
path_names: { new: "/:reg_identifier" } do
get "back/:reg_identifier",
to: "cards_forms#go_back",
as: "back",
on: :collection
end

resources :payment_summary_forms,
only: [:new, :create],
path: "payment-summary",
Expand Down
2 changes: 1 addition & 1 deletion spec/cassettes/contact_postcode_form_modified_postcode.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions spec/cassettes/contact_postcode_form_no_matches_postcode.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions spec/cassettes/contact_postcode_form_valid_postcode.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions spec/factories/forms/cards_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FactoryBot.define do
factory :cards_form do
trait :has_required_data do
temp_cards 1

initialize_with { new(create(:transient_registration, :has_required_data, workflow_state: "cards_form")) }
end
end
end
124 changes: 124 additions & 0 deletions spec/forms/cards_forms_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
require "rails_helper"

RSpec.describe CardsForm, type: :model do
describe "#submit" do
context "when the form is valid" do
let(:cards_form) { build(:cards_form, :has_required_data) }
let(:valid_params) do
{
reg_identifier: cards_form.reg_identifier,
temp_cards: cards_form.temp_cards
}
end

it "should submit" do
expect(cards_form.submit(valid_params)).to eq(true)
end
end

context "when the form is not valid" do
let(:cards_form) { build(:cards_form, :has_required_data) }
let(:invalid_params) { { reg_identifier: "foo" } }

it "should not submit" do
expect(cards_form.submit(invalid_params)).to eq(false)
end
end
end

context "when a valid transient registration exists" do
let(:cards_form) { build(:cards_form, :has_required_data) }

describe "#reg_identifier" do
context "when a reg_identifier meets the requirements" do
it "is valid" do
expect(cards_form).to be_valid
end
end

context "when a reg_identifier is blank" do
before(:each) do
cards_form.reg_identifier = ""
end

it "is not valid" do
expect(cards_form).to_not be_valid
end
end
end

describe "#temp_cards" do
context "when a temp_cards meets the requirements" do
it "is valid" do
expect(cards_form).to be_valid
end
end

context "when a temp_cards is blank" do
before(:each) do
cards_form.temp_cards = ""
end

it "is valid" do
expect(cards_form).to be_valid
end
end

context "when a temp_cards is not a number" do
before(:each) do
cards_form.temp_cards = "foo"
end

it "is not valid" do
expect(cards_form).to_not be_valid
end
end

context "when a temp_cards is not an integer" do
before(:each) do
cards_form.temp_cards = 3.14
end

it "is not valid" do
expect(cards_form).to_not be_valid
end
end

context "when a temp_cards is a negative number" do
before(:each) do
cards_form.temp_cards = -3
end

it "is not valid" do
expect(cards_form).to_not be_valid
end
end
end
end

describe "#transient_registration" do
context "when the transient registration is invalid" do
let(:transient_registration) do
build(:transient_registration,
workflow_state: "cards_form")
end
# Don't use FactoryBot for this as we need to make sure it initializes with a specific object
let(:cards_form) { CardsForm.new(transient_registration) }

before(:each) do
# Make reg_identifier valid for the form, but not the transient object
cards_form.reg_identifier = transient_registration.reg_identifier
transient_registration.reg_identifier = "foo"
end

it "is not valid" do
expect(cards_form).to_not be_valid
end

it "inherits the errors from the transient_registration" do
cards_form.valid?
expect(cards_form.errors[:base]).to include(I18n.t("mongoid.errors.models.transient_registration.attributes.reg_identifier.invalid_format"))
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require "rails_helper"

RSpec.describe TransientRegistration, type: :model do
describe "#workflow_state" do
context "when a TransientRegistration's state is :cards_form" do
let(:transient_registration) do
create(:transient_registration,
:has_required_data,
workflow_state: "cards_form")
end

it "changes to :declaration_form after the 'back' event" do
expect(transient_registration).to transition_from(:cards_form).to(:declaration_form).on_event(:back)
end

it "changes to :payment_summary_form after the 'next' event" do
expect(transient_registration).to transition_from(:cards_form).to(:payment_summary_form).on_event(:next)
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
expect(transient_registration).to transition_from(:declaration_form).to(:check_your_answers_form).on_event(:back)
end

it "changes to :payment_summary_form after the 'next' event" do
expect(transient_registration).to transition_from(:declaration_form).to(:payment_summary_form).on_event(:next)
it "changes to :cards_form after the 'next' event" do
expect(transient_registration).to transition_from(:declaration_form).to(:cards_form).on_event(:next)
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
workflow_state: "payment_summary_form")
end

it "changes to :declaration_form after the 'back' event" do
expect(transient_registration).to transition_from(:payment_summary_form).to(:declaration_form).on_event(:back)
it "changes to :cards_form after the 'back' event" do
expect(transient_registration).to transition_from(:payment_summary_form).to(:cards_form).on_event(:back)
end

it "changes to :worldpay_form after the 'next' event" do
Expand Down
Loading

0 comments on commit 7891963

Please sign in to comment.