Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[97] Search interface - last name #55

Merged
merged 7 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ group :test do
end

group :test, :development do
gem "factory_bot_rails"
gem "launchy"
gem "rspec"
gem "rspec-rails"
end
9 changes: 9 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ GEM
diff-lcs (1.5.0)
e2mmap (0.1.0)
erubi (1.12.0)
factory_bot (6.2.1)
activesupport (>= 5.0.0)
factory_bot_rails (6.2.0)
factory_bot (~> 6.2.0)
railties (>= 5.0.0)
ferrum (0.13)
addressable (~> 2.5)
concurrent-ruby (~> 1.1)
Expand Down Expand Up @@ -142,6 +147,8 @@ GEM
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
language_server-protocol (3.17.0.3)
launchy (2.5.2)
addressable (~> 2.8)
loofah (2.21.3)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
Expand Down Expand Up @@ -353,10 +360,12 @@ DEPENDENCIES
cssbundling-rails
cuprite
debug
factory_bot_rails
govuk-components
govuk_design_system_formbuilder
govuk_feature_flags!
jsbundling-rails
launchy
okcomputer
pg (~> 1.1)
prettier_print
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class ApplicationController < ActionController::Base
default_form_builder(GOVUKDesignSystemFormBuilder::FormBuilder)

before_action :authenticate
before_action :authenticate, unless: -> { FeatureFlags::FeatureFlag.active?("service_open") }

def authenticate
valid_credentials = [
Expand Down
4 changes: 0 additions & 4 deletions app/controllers/pages_controller.rb

This file was deleted.

29 changes: 29 additions & 0 deletions app/controllers/searches_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

class SearchesController < ApplicationController
def new
@search_form = SearchForm.new
end

def show
@search_form = SearchForm.new(search_params)

if @search_form.valid?
render :no_record unless any_records?
else
render :new
end
end

private

def search_params
params.require(:search_form).permit(:last_name)
end

def any_records?
ChildrensBarredListEntry.includes_record?(
last_name: search_params[:last_name],
)
end
end
8 changes: 8 additions & 0 deletions app/forms/search_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

class SearchForm
include ActiveModel::Model
attr_accessor :last_name

validates :last_name, presence: true
end
4 changes: 4 additions & 0 deletions app/models/childrens_barred_list_entry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ class ChildrensBarredListEntry < ApplicationRecord
validates :first_names, presence: true
validates :last_name, presence: true
validates :date_of_birth, presence: true

def self.includes_record?(last_name:)
where("lower(last_name) = ?", last_name.downcase).any?
end
end
4 changes: 3 additions & 1 deletion app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@

<div class="govuk-width-container">
<%= govuk_phase_banner(tag: { text: "Beta" }) do %>
This is a new service – <%= govuk_link_to("your feedback will help us to improve it.", t('service.feedback_form')) %>
This is a new service – your
<%= govuk_link_to("feedback", t('service.feedback_form')) %>
will help us to improve it.
<% end %>
<%= govuk_back_link(href: yield(:back_link_url)) if content_for?(:back_link_url) %>
<%= yield(:breadcrumbs) if content_for?(:breadcrumbs) %>
Expand Down
15 changes: 15 additions & 0 deletions app/views/searches/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<% content_for :page_title, "#{'Error: ' if @search_form.errors.any?}Check the Children’s Barred List" %>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-l">Check the Children’s Barred List</h1>

<%= form_with(model: @search_form, url: result_path, method: :get) do |f| %>
<%= f.govuk_error_summary %>

<%= f.govuk_text_field :last_name, class: "govuk-input--width-20", label: { text: "Last name", size: "s" } %>

<%= f.govuk_submit "Search" %>
<% end %>
</div>
</div>
17 changes: 17 additions & 0 deletions app/views/searches/no_record.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<% content_for :page_title, "No record found" %>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-l">No record found</h1>

<%= govuk_summary_list(
rows: [
{ key: { text: "Last name" }, value: { text: @search_form.last_name } }
])
%>

<p class="govuk_body">
<%= govuk_link_to "Try another search", search_path %>
</p>
</div>
</div>
17 changes: 17 additions & 0 deletions app/views/searches/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<% content_for :page_title, "Record found" %>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-l">Record found</h1>

<%= govuk_summary_list(
rows: [
{ key: { text: "Last name" }, value: { text: @search_form.last_name } }
])
%>

<p class="govuk-body">
Contact DBS at <%= govuk_mail_to t('service.dbs_email'), t('service.dbs_email') %> for more details.
</p>
</div>
</div>
10 changes: 9 additions & 1 deletion config/locales/en.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
en:
service:
name: Check the Childen's Barred List
email: my-service@email
email: [email protected]
dbs_email: [email protected]
activemodel:
errors:
models:
search_form:
attributes:
last_name:
blank: Enter a last name
5 changes: 4 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
Rails.application.routes.draw do
root to: "pages#home"
root to: "searches#new"

get "/search", to: "searches#new"
get "/result", to: "searches#show"

mount FeatureFlags::Engine => "/features"
end
7 changes: 7 additions & 0 deletions spec/factories/childrens_barred_list_entries.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FactoryBot.define do
factory :childrens_barred_list_entry do
first_names { "John" }
last_name { "Doe" }
date_of_birth { 25.years.ago }
end
end
30 changes: 30 additions & 0 deletions spec/models/childrens_barred_list_entry_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,34 @@
it { is_expected.to validate_presence_of(:first_names) }
it { is_expected.to validate_presence_of(:last_name) }
it { is_expected.to validate_presence_of(:date_of_birth) }

describe "#self.includes_record?" do
let(:record) { create(:childrens_barred_list_entry) }

context "with an exact match" do
it "returns true" do
expect(
described_class.includes_record?(last_name: record.last_name),
).to be_truthy
end
end

context "with a case-insensitive match" do
it "returns true" do
expect(
described_class.includes_record?(
last_name: record.last_name.downcase,
),
).to be_truthy
end
end

context "with no matching record" do
it "returns false" do
expect(
described_class.includes_record?(last_name: "Random name"),
).to be_falsey
end
end
end
end
43 changes: 3 additions & 40 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,12 @@
app,
timeout: 10,
process_timeout: 30,
window_size: [1200, 800]
window_size: [1200, 800],
)
end
Capybara.default_driver = :cuprite
Capybara.javascript_driver = :cuprite

# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
# run as spec files by default. This means that files in spec/support that end
# in _spec.rb will both be required and run as specs, causing the specs to be
# run twice. It is recommended that you do not name files matching this glob to
# end with _spec.rb. You can configure this pattern with the --pattern
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
#
# The following line is provided for convenience purposes. It has the downside
# of increasing the boot-up time by auto-requiring all files in the support
# directory. Alternatively, in the individual `*_spec.rb` files, manually
# require only the support files necessary.
#
Dir[Rails.root.join("spec/support/**/*.rb")].sort.each { |f| require f }

# Checks for pending migrations and applies them before tests are run.
Expand All @@ -44,36 +31,12 @@
abort e.to_s.strip
end
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.include FactoryBot::Syntax::Methods
config.fixture_path = Rails.root.join("spec/fixtures")

# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true

# You can uncomment this line to turn off ActiveRecord support entirely.
# config.use_active_record = false

# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.
#
# You can disable this behaviour by removing the line below, and instead
# explicitly tag your specs with their type, e.g.:
#
# RSpec.describe UsersController, type: :controller do
# # ...
# end
#
# The different available types are documented in the features, such as in
# https://rspec.info/features/6-0/rspec-rails
config.infer_spec_type_from_file_location!

# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via:
# config.filter_gems_from_backtrace("gem name")
config.before(:each, type: :system) { driven_by(:cuprite) }
end

Shoulda::Matchers.configure do |config|
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require "rails_helper"

RSpec.describe "Pages", type: :request do
describe "GET /home" do
RSpec.describe "Authentication", type: :request do
describe "GET /" do
it "requires authentication" do
get "/"
expect(response).to have_http_status(:unauthorized)
Expand All @@ -11,7 +11,7 @@
let(:credentials) do
ActionController::HttpAuthentication::Basic.encode_credentials(
ENV.fetch("SUPPORT_USERNAME", "support"),
ENV.fetch("SUPPORT_PASSWORD", "support")
ENV.fetch("SUPPORT_PASSWORD", "support"),
)
end

Expand Down
5 changes: 5 additions & 0 deletions spec/support/system/activate_features_steps.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module ActivateFeaturesSteps
def given_the_service_is_open
FeatureFlags::FeatureFlag.activate(:service_open)
end
end
35 changes: 35 additions & 0 deletions spec/system/user_searches_with_matching_record_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe "Valid search", type: :system do
include ActivateFeaturesSteps

scenario "User searches with a last name" do
given_the_service_is_open
and_there_is_a_record
and_i_visit_the_search_page
and_i_search_for_their_last_name
then_i_see_a_result
end

private

def and_there_is_a_record
@record = create(:childrens_barred_list_entry)
end

def and_i_visit_the_search_page
visit search_path
end

def and_i_search_for_their_last_name
fill_in "Last name", with: @record.last_name
click_button "Search"
end

def then_i_see_a_result
expect(page).to have_content "Record found"
expect(page).to have_content @record.last_name
end
end
28 changes: 28 additions & 0 deletions spec/system/user_searches_with_missing_params_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe "Invalid search", type: :system do
include ActivateFeaturesSteps

scenario "User searches without a last name" do
given_the_service_is_open
and_i_visit_the_search_page
and_i_click_search
then_i_see_an_error
end

private

def and_i_visit_the_search_page
visit search_path
end

def and_i_click_search
click_button "Search"
end

def then_i_see_an_error
expect(page).to have_content("Enter a last name")
end
end
Loading