From e0fe4c9ecc7b3374f89f1c6525bef0757223fef2 Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Wed, 15 Feb 2017 12:19:18 +0000 Subject: [PATCH 01/27] Generate 'contact' format Ran 'bundle exec rails generate format contact' --- app/assets/stylesheets/application.scss | 1 + app/assets/stylesheets/views/_contact.scss | 3 +++ app/presenters/contact_presenter.rb | 2 ++ app/views/content_items/contact.html.erb | 11 +++++++++++ test/integration/contact_test.rb | 4 ++++ test/presenters/contact_presenter_test.rb | 13 +++++++++++++ 6 files changed, 34 insertions(+) create mode 100644 app/assets/stylesheets/views/_contact.scss create mode 100644 app/presenters/contact_presenter.rb create mode 100644 app/views/content_items/contact.html.erb create mode 100644 test/integration/contact_test.rb create mode 100644 test/presenters/contact_presenter_test.rb diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 92d2bfd18..17d862117 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -44,3 +44,4 @@ @import 'views/news-article'; @import 'views/corporate-information-page'; @import 'views/travel-advice'; +@import "views/contact"; diff --git a/app/assets/stylesheets/views/_contact.scss b/app/assets/stylesheets/views/_contact.scss new file mode 100644 index 000000000..87bbb9d27 --- /dev/null +++ b/app/assets/stylesheets/views/_contact.scss @@ -0,0 +1,3 @@ +.contact { + +} diff --git a/app/presenters/contact_presenter.rb b/app/presenters/contact_presenter.rb new file mode 100644 index 000000000..77c7cf0c5 --- /dev/null +++ b/app/presenters/contact_presenter.rb @@ -0,0 +1,2 @@ +class ContactPresenter < ContentItemPresenter +end diff --git a/app/views/content_items/contact.html.erb b/app/views/content_items/contact.html.erb new file mode 100644 index 000000000..abb9bfb5c --- /dev/null +++ b/app/views/content_items/contact.html.erb @@ -0,0 +1,11 @@ +<%= content_for :title, @content_item.title %> + +
+
+ <%= render 'govuk_component/title', + context: t("content_item.format.#{@content_item.document_type}", count: 1), + title: @content_item.title %> +
+
+ +<%= render 'shared/description', description: @content_item.description %> diff --git a/test/integration/contact_test.rb b/test/integration/contact_test.rb new file mode 100644 index 000000000..830326ccd --- /dev/null +++ b/test/integration/contact_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class ContactTest < ActionDispatch::IntegrationTest +end diff --git a/test/presenters/contact_presenter_test.rb b/test/presenters/contact_presenter_test.rb new file mode 100644 index 000000000..882b53a8e --- /dev/null +++ b/test/presenters/contact_presenter_test.rb @@ -0,0 +1,13 @@ +require 'presenter_test_helper' + +class ContactPresenterTest + class PresentedContact < PresenterTestCase + def format_name + "contact" + end + + test 'presents the format' do + assert_equal schema_item['format'], presented_item.format + end + end +end From 7aeb4c1652eda99fca0ac1743974f21c51922d26 Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Wed, 15 Feb 2017 14:50:43 +0000 Subject: [PATCH 02/27] Add related items to contact format - Added CSS to balance the related links component correctly, potentially we could avoid this by spiking unidrectional vertical rhythm. --- app/assets/stylesheets/views/_contact.scss | 4 ++- app/presenters/contact_presenter.rb | 32 ++++++++++++++++++++++ app/views/content_items/contact.html.erb | 13 +++++++-- test/presenters/contact_presenter_test.rb | 16 +++++++++++ 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/views/_contact.scss b/app/assets/stylesheets/views/_contact.scss index 87bbb9d27..30853e764 100644 --- a/app/assets/stylesheets/views/_contact.scss +++ b/app/assets/stylesheets/views/_contact.scss @@ -1,3 +1,5 @@ .contact { - + .add-title-margin { + @include responsive-top-margin; + } } diff --git a/app/presenters/contact_presenter.rb b/app/presenters/contact_presenter.rb index 77c7cf0c5..b25cc2866 100644 --- a/app/presenters/contact_presenter.rb +++ b/app/presenters/contact_presenter.rb @@ -1,2 +1,34 @@ class ContactPresenter < ContentItemPresenter + def related_items + [ + { + title: "Elsewhere on GOV.UK", + items: quick_links + }, + { + title: "Other contacts", + items: related_contacts_links + } + ] + end + +private + + def related_contacts_links + content_item["links"]["related"].map do |link| + { + title: link["title"], + url: link["base_path"] + } + end + end + + def quick_links + content_item["details"]["quick_links"].map do |link| + { + title: link["title"], + url: link["url"] + } + end + end end diff --git a/app/views/content_items/contact.html.erb b/app/views/content_items/contact.html.erb index abb9bfb5c..f17d507f2 100644 --- a/app/views/content_items/contact.html.erb +++ b/app/views/content_items/contact.html.erb @@ -1,11 +1,18 @@ -<%= content_for :title, @content_item.title %> +<% + content_for :title, @content_item.title + content_for :simple_header, true +%>
<%= render 'govuk_component/title', context: t("content_item.format.#{@content_item.document_type}", count: 1), title: @content_item.title %> + <%= render 'shared/description', description: @content_item.description %> +
+
+ <%= render partial: 'govuk_component/related_items', locals: { + sections: @content_item.related_items + } %>
- -<%= render 'shared/description', description: @content_item.description %> diff --git a/test/presenters/contact_presenter_test.rb b/test/presenters/contact_presenter_test.rb index 882b53a8e..e90bc1dc9 100644 --- a/test/presenters/contact_presenter_test.rb +++ b/test/presenters/contact_presenter_test.rb @@ -9,5 +9,21 @@ def format_name test 'presents the format' do assert_equal schema_item['format'], presented_item.format end + + test 'presents the quick links in related items' do + first_quick_link = schema_item['details']['quick_links'].first + first_presented_quick_link = presented_item.related_items.first[:items].first + + assert_equal first_quick_link['title'], first_presented_quick_link[:title] + assert_equal 'Elsewhere on GOV.UK', presented_item.related_items.first[:title] + end + + test 'presents the related contacts links in related items' do + first_related_contact_link = schema_item['links']['related'].first + first_presented_contact_link = presented_item.related_items.last[:items].first + + assert_equal first_related_contact_link['title'], first_presented_contact_link[:title] + assert_equal 'Other contacts', presented_item.related_items.last[:title] + end end end From f435f7c69e60fa3fd917b62a97ed9dc75ee2b4a9 Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Wed, 15 Feb 2017 15:55:32 +0000 Subject: [PATCH 03/27] Add online form govspeak content - Adds links for online forms - Adds more info content for online forms --- app/presenters/contact_presenter.rb | 18 ++++++++++++++++++ app/views/content_items/contact.html.erb | 14 +++++++++++++- test/integration/contact_test.rb | 15 +++++++++++++++ test/presenters/contact_presenter_test.rb | 8 ++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/app/presenters/contact_presenter.rb b/app/presenters/contact_presenter.rb index b25cc2866..6dfa297e4 100644 --- a/app/presenters/contact_presenter.rb +++ b/app/presenters/contact_presenter.rb @@ -12,6 +12,24 @@ def related_items ] end + def online_form_links + content_item["details"]["contact_form_links"].map do |link| + { + url: link['link'], + title: link['title'], + description: link['description'].html_safe + } + end + end + + def online_form_body + content_item["details"]["more_info_contact_form"].html_safe + end + + def online_forms? + online_form_links.any? + end + private def related_contacts_links diff --git a/app/views/content_items/contact.html.erb b/app/views/content_items/contact.html.erb index f17d507f2..2befc828e 100644 --- a/app/views/content_items/contact.html.erb +++ b/app/views/content_items/contact.html.erb @@ -8,7 +8,19 @@ <%= render 'govuk_component/title', context: t("content_item.format.#{@content_item.document_type}", count: 1), title: @content_item.title %> - <%= render 'shared/description', description: @content_item.description %> + <% @body = capture do %> + <% if @content_item.online_forms? %> +

Online forms

+ <% @content_item.online_form_links.each do |link| %> +

+ <%= link_to(link[:title], link[:url]) %> +

+ <%= link[:description] %> + <% end %> + <%= @content_item.online_form_body %> + <% end %> + <% end %> + <%= render 'govuk_component/govspeak', content: @body %>
<%= render partial: 'govuk_component/related_items', locals: { diff --git a/test/integration/contact_test.rb b/test/integration/contact_test.rb index 830326ccd..062bab718 100644 --- a/test/integration/contact_test.rb +++ b/test/integration/contact_test.rb @@ -1,4 +1,19 @@ require 'test_helper' class ContactTest < ActionDispatch::IntegrationTest + test "online forms are rendered" do + setup_and_visit_content_item('contact') + within_component_govspeak do |component_args| + content = component_args.fetch("content") + + assert content.include? @content_item["details"]["more_info_contact_form"] + first_contact_form_link = @content_item["details"]["contact_form_links"].first + + assert content.include? first_contact_form_link['description'] + + html = Nokogiri::HTML.parse(content) + assert_not_nil html.at_css("h2#online-forms") + assert_not_nil html.at_css("a[href='#{first_contact_form_link['link']}']") + end + end end diff --git a/test/presenters/contact_presenter_test.rb b/test/presenters/contact_presenter_test.rb index e90bc1dc9..62af7733c 100644 --- a/test/presenters/contact_presenter_test.rb +++ b/test/presenters/contact_presenter_test.rb @@ -25,5 +25,13 @@ def format_name assert_equal first_related_contact_link['title'], first_presented_contact_link[:title] assert_equal 'Other contacts', presented_item.related_items.last[:title] end + + test 'presents online form links' do + assert_equal schema_item['details']['contact_form_links'].first['link'], presented_item.online_form_links.first[:url] + end + + test 'presents online form body' do + assert_equal schema_item['details']['more_info_contact_form'], presented_item.online_form_body + end end end From 98f0d02a2a16cf748db730dfd4f9ce68a19778d0 Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Wed, 15 Feb 2017 16:01:51 +0000 Subject: [PATCH 04/27] Update related items so it has sections --- app/presenters/contact_presenter.rb | 22 ++++++++++++---------- app/views/content_items/contact.html.erb | 4 +--- test/presenters/contact_presenter_test.rb | 8 ++++---- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app/presenters/contact_presenter.rb b/app/presenters/contact_presenter.rb index 6dfa297e4..0960a907d 100644 --- a/app/presenters/contact_presenter.rb +++ b/app/presenters/contact_presenter.rb @@ -1,15 +1,17 @@ class ContactPresenter < ContentItemPresenter def related_items - [ - { - title: "Elsewhere on GOV.UK", - items: quick_links - }, - { - title: "Other contacts", - items: related_contacts_links - } - ] + { + sections: [ + { + title: "Elsewhere on GOV.UK", + items: quick_links + }, + { + title: "Other contacts", + items: related_contacts_links + } + ] + } end def online_form_links diff --git a/app/views/content_items/contact.html.erb b/app/views/content_items/contact.html.erb index 2befc828e..0a613b7b3 100644 --- a/app/views/content_items/contact.html.erb +++ b/app/views/content_items/contact.html.erb @@ -23,8 +23,6 @@ <%= render 'govuk_component/govspeak', content: @body %>
- <%= render partial: 'govuk_component/related_items', locals: { - sections: @content_item.related_items - } %> + <%= render 'govuk_component/related_items', @content_item.related_items %>
diff --git a/test/presenters/contact_presenter_test.rb b/test/presenters/contact_presenter_test.rb index 62af7733c..2f8332872 100644 --- a/test/presenters/contact_presenter_test.rb +++ b/test/presenters/contact_presenter_test.rb @@ -12,18 +12,18 @@ def format_name test 'presents the quick links in related items' do first_quick_link = schema_item['details']['quick_links'].first - first_presented_quick_link = presented_item.related_items.first[:items].first + first_presented_quick_link = presented_item.related_items[:sections].first[:items].first assert_equal first_quick_link['title'], first_presented_quick_link[:title] - assert_equal 'Elsewhere on GOV.UK', presented_item.related_items.first[:title] + assert_equal 'Elsewhere on GOV.UK', presented_item.related_items[:sections].first[:title] end test 'presents the related contacts links in related items' do first_related_contact_link = schema_item['links']['related'].first - first_presented_contact_link = presented_item.related_items.last[:items].first + first_presented_contact_link = presented_item.related_items[:sections].last[:items].first assert_equal first_related_contact_link['title'], first_presented_contact_link[:title] - assert_equal 'Other contacts', presented_item.related_items.last[:title] + assert_equal 'Other contacts', presented_item.related_items[:sections].last[:title] end test 'presents online form links' do From 30f6f51a5f5d30a4a66e532db289e204e0a0e5e6 Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Wed, 15 Feb 2017 16:02:26 +0000 Subject: [PATCH 05/27] Update body variable so it is local --- app/views/content_items/contact.html.erb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/views/content_items/contact.html.erb b/app/views/content_items/contact.html.erb index 0a613b7b3..77436f90a 100644 --- a/app/views/content_items/contact.html.erb +++ b/app/views/content_items/contact.html.erb @@ -8,7 +8,8 @@ <%= render 'govuk_component/title', context: t("content_item.format.#{@content_item.document_type}", count: 1), title: @content_item.title %> - <% @body = capture do %> + + <% body = capture do %> <% if @content_item.online_forms? %>

Online forms

<% @content_item.online_form_links.each do |link| %> @@ -20,7 +21,8 @@ <%= @content_item.online_form_body %> <% end %> <% end %> - <%= render 'govuk_component/govspeak', content: @body %> + + <%= render 'govuk_component/govspeak', content: body %>
<%= render 'govuk_component/related_items', @content_item.related_items %> From 90f5c306e8d54bcafb3ad7795593a93858749939 Mon Sep 17 00:00:00 2001 From: Andrew Hilton Date: Fri, 17 Feb 2017 16:31:33 +0000 Subject: [PATCH 06/27] Don't render related item groups with no items - Test example which has no other contact items - Don't blow up when no data --- app/presenters/contact_presenter.rb | 28 +++++++++++++---------- test/presenters/contact_presenter_test.rb | 13 +++++++++-- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/app/presenters/contact_presenter.rb b/app/presenters/contact_presenter.rb index 0960a907d..bc184091e 100644 --- a/app/presenters/contact_presenter.rb +++ b/app/presenters/contact_presenter.rb @@ -1,16 +1,18 @@ class ContactPresenter < ContentItemPresenter def related_items + sections = [] + sections << { + title: "Elsewhere on GOV.UK", + items: quick_links + } if quick_links.any? + + sections << { + title: "Other contacts", + items: related_contacts_links + } if related_contacts_links.any? + { - sections: [ - { - title: "Elsewhere on GOV.UK", - items: quick_links - }, - { - title: "Other contacts", - items: related_contacts_links - } - ] + sections: sections } end @@ -35,7 +37,8 @@ def online_forms? private def related_contacts_links - content_item["links"]["related"].map do |link| + related = content_item["links"]["related"] || [] + related.map do |link| { title: link["title"], url: link["base_path"] @@ -44,7 +47,8 @@ def related_contacts_links end def quick_links - content_item["details"]["quick_links"].map do |link| + quick = content_item["details"]["quick_links"] || [] + quick.map do |link| { title: link["title"], url: link["url"] diff --git a/test/presenters/contact_presenter_test.rb b/test/presenters/contact_presenter_test.rb index 2f8332872..ea22a4d9d 100644 --- a/test/presenters/contact_presenter_test.rb +++ b/test/presenters/contact_presenter_test.rb @@ -10,7 +10,16 @@ def format_name assert_equal schema_item['format'], presented_item.format end - test 'presents the quick links in related items' do + + test 'only presents related item sections when section has items' do + schema = schema_item('contact_with_email_and_no_other_contacts') + presented = presented_item('contact_with_email_and_no_other_contacts') + + refute schema['links']['related'] + assert_empty presented.related_items[:sections].select { |section| section[:title] == 'Other contacts' } + end + + test 'presents quick links in related items' do first_quick_link = schema_item['details']['quick_links'].first first_presented_quick_link = presented_item.related_items[:sections].first[:items].first @@ -18,7 +27,7 @@ def format_name assert_equal 'Elsewhere on GOV.UK', presented_item.related_items[:sections].first[:title] end - test 'presents the related contacts links in related items' do + test 'presents related contacts links in related items' do first_related_contact_link = schema_item['links']['related'].first first_presented_contact_link = presented_item.related_items[:sections].last[:items].first From 3c5e68201b0720f99bc168dd8e12e3fe0f5c9dfd Mon Sep 17 00:00:00 2001 From: Andrew Hilton Date: Fri, 17 Feb 2017 16:32:11 +0000 Subject: [PATCH 07/27] Render title for contacts using module Keep contacts in sync with other formats --- app/presenters/contact_presenter.rb | 9 +++++++++ app/views/content_items/contact.html.erb | 4 +--- test/presenters/contact_presenter_test.rb | 3 +++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/app/presenters/contact_presenter.rb b/app/presenters/contact_presenter.rb index bc184091e..32e965708 100644 --- a/app/presenters/contact_presenter.rb +++ b/app/presenters/contact_presenter.rb @@ -1,4 +1,13 @@ class ContactPresenter < ContentItemPresenter + include TitleAndContext + + def title_and_context + super.tap do |t| + t.delete(:average_title_length) + t.delete(:context) + end + end + def related_items sections = [] sections << { diff --git a/app/views/content_items/contact.html.erb b/app/views/content_items/contact.html.erb index 77436f90a..100321e81 100644 --- a/app/views/content_items/contact.html.erb +++ b/app/views/content_items/contact.html.erb @@ -5,9 +5,7 @@
- <%= render 'govuk_component/title', - context: t("content_item.format.#{@content_item.document_type}", count: 1), - title: @content_item.title %> + <%= render 'govuk_component/title', @content_item.title_and_context %> <% body = capture do %> <% if @content_item.online_forms? %> diff --git a/test/presenters/contact_presenter_test.rb b/test/presenters/contact_presenter_test.rb index ea22a4d9d..6163ea0a5 100644 --- a/test/presenters/contact_presenter_test.rb +++ b/test/presenters/contact_presenter_test.rb @@ -10,6 +10,9 @@ def format_name assert_equal schema_item['format'], presented_item.format end + test 'presents the title' do + assert_equal schema_item['title'], presented_item.title + end test 'only presents related item sections when section has items' do schema = schema_item('contact_with_email_and_no_other_contacts') From bdcd03c6cf3e55b6df8cedf2e07151093fada38e Mon Sep 17 00:00:00 2001 From: Andrew Hilton Date: Fri, 17 Feb 2017 16:36:36 +0000 Subject: [PATCH 08/27] Remove helper method to see if online_form_links are present --- app/presenters/contact_presenter.rb | 2 -- app/views/content_items/contact.html.erb | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/presenters/contact_presenter.rb b/app/presenters/contact_presenter.rb index 32e965708..aa9200cdd 100644 --- a/app/presenters/contact_presenter.rb +++ b/app/presenters/contact_presenter.rb @@ -39,8 +39,6 @@ def online_form_body content_item["details"]["more_info_contact_form"].html_safe end - def online_forms? - online_form_links.any? end private diff --git a/app/views/content_items/contact.html.erb b/app/views/content_items/contact.html.erb index 100321e81..4183531bc 100644 --- a/app/views/content_items/contact.html.erb +++ b/app/views/content_items/contact.html.erb @@ -8,8 +8,8 @@ <%= render 'govuk_component/title', @content_item.title_and_context %> <% body = capture do %> - <% if @content_item.online_forms? %> -

Online forms

+ <% if @content_item.online_form_links.any? %> +

Online forms

<% @content_item.online_form_links.each do |link| %>

<%= link_to(link[:title], link[:url]) %> From 9ddfd7dd96f2ee59057ebf54d27a866d50cda1b1 Mon Sep 17 00:00:00 2001 From: Andrew Hilton Date: Fri, 17 Feb 2017 16:40:55 +0000 Subject: [PATCH 09/27] Add phone contact to contacts --- app/presenters/contact_presenter.rb | 38 +++++++++++++++++++++++ app/views/content_items/contact.html.erb | 35 +++++++++++++++++++++ test/integration/contact_test.rb | 13 ++++++++ test/presenters/contact_presenter_test.rb | 13 ++++++++ 4 files changed, 99 insertions(+) diff --git a/app/presenters/contact_presenter.rb b/app/presenters/contact_presenter.rb index aa9200cdd..7a638852d 100644 --- a/app/presenters/contact_presenter.rb +++ b/app/presenters/contact_presenter.rb @@ -39,10 +39,48 @@ def online_form_body content_item["details"]["more_info_contact_form"].html_safe end + def phone + phone_number_groups.map do |group| + details = { + numbers: [ + { + label: 'Telephone', + number: group['number'] + }, + { + label: 'Textphone', + number: group['textphone'] + }, + { + label: 'Outside UK', + number: group['international_phone'] + }, + { + label: 'Fax', + number: group['fax'] + } + ], + title: group['title'], + description: group['description'].strip.html_safe, + opening_times: group['open_hours'].strip.html_safe, + best_time_to_call: group['best_time_to_call'].strip.html_safe + } + + details[:numbers].select! { |n| n[:number].present? } + details + end + end + + def phone_body + content_item["details"]["more_info_phone_number"].html_safe end private + def phone_number_groups + content_item["details"]["phone_numbers"] || [] + end + def related_contacts_links related = content_item["links"]["related"] || [] related.map do |link| diff --git a/app/views/content_items/contact.html.erb b/app/views/content_items/contact.html.erb index 4183531bc..2f0c7eac7 100644 --- a/app/views/content_items/contact.html.erb +++ b/app/views/content_items/contact.html.erb @@ -18,6 +18,41 @@ <% end %> <%= @content_item.online_form_body %> <% end %> + + <% if @content_item.phone.any? %> +

Phone

+ <% @content_item.phone.each do |phone_group| %> +

<%= phone_group[:title] %>

+ + <% if phone_group[:numbers].any? %> +
+
+ <% phone_group[:numbers].each do |number| %> +

<%= number[:label] %>:
<%= number[:number] %>

+ <% end%> +
+
+ <% end %> + + <%= phone_group[:description] %> + + <% if phone_group[:opening_times].present? %> +

Opening times

+ <%= phone_group[:opening_times] %> + <% end %> + + <% if phone_group[:best_time_to_call].present? %> +

Best time to call

+ <%= phone_group[:best_time_to_call] %> + <% end %> + <% end %> + + <%= @content_item.phone_body %> + +

+ <%= link_to "Find out about call charges", "/call-charges" %> +

+ <% end %> <% end %> <%= render 'govuk_component/govspeak', content: body %> diff --git a/test/integration/contact_test.rb b/test/integration/contact_test.rb index 062bab718..632dd4ed5 100644 --- a/test/integration/contact_test.rb +++ b/test/integration/contact_test.rb @@ -16,4 +16,17 @@ class ContactTest < ActionDispatch::IntegrationTest assert_not_nil html.at_css("a[href='#{first_contact_form_link['link']}']") end end + + test "phones are rendered" do + setup_and_visit_content_item('contact') + within_component_govspeak do |component_args| + content = component_args.fetch("content") + first_phone = @content_item["details"]["phone_numbers"].first["number"] + + html = Nokogiri::HTML.parse(content) + assert_not_nil html.at_css("h2#phone-title") + assert_not_nil html.at("p:contains(\"#{first_phone}\")") + assert_not_nil html.at("p:contains(\"24 hours a day, 7 days a week\")") + end + end end diff --git a/test/presenters/contact_presenter_test.rb b/test/presenters/contact_presenter_test.rb index 6163ea0a5..d4542645e 100644 --- a/test/presenters/contact_presenter_test.rb +++ b/test/presenters/contact_presenter_test.rb @@ -45,5 +45,18 @@ def format_name test 'presents online form body' do assert_equal schema_item['details']['more_info_contact_form'], presented_item.online_form_body end + + test 'phone returns correctly' do + assert_equal schema_item['details']['phone_numbers'][0]["number"], presented_item.phone[0][:numbers][0][:number] + assert_equal schema_item['details']['phone_numbers'][0]["textphone"].blank?, presented_item.phone[0][:numbers][0][:textphone].nil? + assert_equal schema_item['details']['phone_numbers'][0]["title"], presented_item.phone[0][:title] + assert_equal schema_item['details']['phone_numbers'][0]["description"].strip, presented_item.phone[0][:description] + assert_equal schema_item['details']['phone_numbers'][0]["open_hours"].strip, presented_item.phone[0][:opening_times] + assert_equal schema_item['details']['phone_numbers'][0]["best_time_to_call"].strip, presented_item.phone[0][:best_time_to_call] + end + + test 'phone_body returns correctly' do + assert_equal schema_item['details']['more_info_phone_number'], presented_item.phone_body + end end end From 9f91aa72dacaaf939def9d9d055de94152e3f7a3 Mon Sep 17 00:00:00 2001 From: Andrew Hilton Date: Fri, 17 Feb 2017 16:42:01 +0000 Subject: [PATCH 10/27] Update online form title test --- test/integration/contact_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/contact_test.rb b/test/integration/contact_test.rb index 632dd4ed5..e56833f52 100644 --- a/test/integration/contact_test.rb +++ b/test/integration/contact_test.rb @@ -12,7 +12,7 @@ class ContactTest < ActionDispatch::IntegrationTest assert content.include? first_contact_form_link['description'] html = Nokogiri::HTML.parse(content) - assert_not_nil html.at_css("h2#online-forms") + assert_not_nil html.at_css("h2#online-forms-title") assert_not_nil html.at_css("a[href='#{first_contact_form_link['link']}']") end end From c06f48a840e22229426265234456506a04db7660 Mon Sep 17 00:00:00 2001 From: Andrew Hilton Date: Fri, 17 Feb 2017 16:43:23 +0000 Subject: [PATCH 11/27] Add post content to contacts --- app/presenters/contact_presenter.rb | 34 +++++++++++++++++++++++ app/views/content_items/contact.html.erb | 17 ++++++++++++ test/integration/contact_test.rb | 12 ++++++++ test/presenters/contact_presenter_test.rb | 10 +++++++ 4 files changed, 73 insertions(+) diff --git a/app/presenters/contact_presenter.rb b/app/presenters/contact_presenter.rb index 7a638852d..17df1dcb2 100644 --- a/app/presenters/contact_presenter.rb +++ b/app/presenters/contact_presenter.rb @@ -75,8 +75,42 @@ def phone_body content_item["details"]["more_info_phone_number"].html_safe end + def post + post_address_groups.map do |group| + details = { + description: group['description'].strip.html_safe, + v_card: [ + v_card_part('fn', group['title']), + v_card_part('street-address', group['street_address']), + v_card_part('locality', group['locality']), + v_card_part('postal-code', group['postal_code']), + v_card_part('region', group['region']), + v_card_part('country-name', group['world_location']), + ] + } + + details[:v_card].select! { |v| v[:value].present? } + details + end + end + + def post_body + content_item["details"]["more_info_post_address"].html_safe + end + private + def v_card_part(v_card_class, value) + { + v_card_class: v_card_class, + value: value.strip.html_safe + } + end + + def post_address_groups + content_item["details"]["post_addresses"] || [] + end + def phone_number_groups content_item["details"]["phone_numbers"] || [] end diff --git a/app/views/content_items/contact.html.erb b/app/views/content_items/contact.html.erb index 2f0c7eac7..624c0a406 100644 --- a/app/views/content_items/contact.html.erb +++ b/app/views/content_items/contact.html.erb @@ -53,6 +53,23 @@ <%= link_to "Find out about call charges", "/call-charges" %>

<% end %> + + <% if @content_item.post.any? %> +

Post

+ <% @content_item.post.each do |post_group| %> + <%= post_group[:description] %> +
+

+ <% post_group[:v_card].each do |v_card_part| %> + + <%= v_card_part[:value] %> +
+ <% end %> +

+
+ <% end %> + <%= @content_item.post_body %> + <% end %> <% end %> <%= render 'govuk_component/govspeak', content: body %> diff --git a/test/integration/contact_test.rb b/test/integration/contact_test.rb index e56833f52..9a1abfc8e 100644 --- a/test/integration/contact_test.rb +++ b/test/integration/contact_test.rb @@ -29,4 +29,16 @@ class ContactTest < ActionDispatch::IntegrationTest assert_not_nil html.at("p:contains(\"24 hours a day, 7 days a week\")") end end + + + test "post are rendered" do + setup_and_visit_content_item('contact') + within_component_govspeak do |component_args| + content = component_args.fetch("content") + html = Nokogiri::HTML.parse(content) + + assert_not_nil html.at_css("h2#post-title") + assert_not_nil html.at_css(".street-address") + end + end end diff --git a/test/presenters/contact_presenter_test.rb b/test/presenters/contact_presenter_test.rb index d4542645e..1f678577c 100644 --- a/test/presenters/contact_presenter_test.rb +++ b/test/presenters/contact_presenter_test.rb @@ -58,5 +58,15 @@ def format_name test 'phone_body returns correctly' do assert_equal schema_item['details']['more_info_phone_number'], presented_item.phone_body end + + test 'post' do + assert_equal schema_item['details']['post_addresses'][0]['description'].strip, presented_item.post[0][:description] + assert_equal schema_item['details']['post_addresses'][0]['title'].strip, presented_item.post[0][:v_card][0][:value] + assert_equal presented_item.post[0][:v_card][0][:v_card_class], 'fn' + end + + test 'post_body returns correctly' do + assert_equal schema_item['details']['more_info_post_address'], presented_item.post_body + end end end From 52e86edc571d041359d058fdb41c9b0b9630d3c7 Mon Sep 17 00:00:00 2001 From: Andrew Hilton Date: Fri, 17 Feb 2017 16:43:41 +0000 Subject: [PATCH 12/27] Add email content to contacts --- app/presenters/contact_presenter.rb | 21 +++++++++++++++++++++ app/views/content_items/contact.html.erb | 17 +++++++++++++++++ test/integration/contact_test.rb | 11 +++++++++++ test/presenters/contact_presenter_test.rb | 9 +++++++++ 4 files changed, 58 insertions(+) diff --git a/app/presenters/contact_presenter.rb b/app/presenters/contact_presenter.rb index 17df1dcb2..09b9c6a84 100644 --- a/app/presenters/contact_presenter.rb +++ b/app/presenters/contact_presenter.rb @@ -98,6 +98,23 @@ def post_body content_item["details"]["more_info_post_address"].html_safe end + def email + email_address_groups.map do |group| + details = { + description: group['description'] ? group['description'].strip.html_safe : '', + email: group['email'].strip, + v_card: [v_card_part('fn', group['title'])], + } + + details[:v_card].select! { |v| v[:value].present? } + details + end + end + + def email_body + content_item["details"]["more_info_email_address"].html_safe + end + private def v_card_part(v_card_class, value) @@ -107,6 +124,10 @@ def v_card_part(v_card_class, value) } end + def email_address_groups + content_item["details"]["email_addresses"] || [] + end + def post_address_groups content_item["details"]["post_addresses"] || [] end diff --git a/app/views/content_items/contact.html.erb b/app/views/content_items/contact.html.erb index 624c0a406..71c1ee1b7 100644 --- a/app/views/content_items/contact.html.erb +++ b/app/views/content_items/contact.html.erb @@ -19,6 +19,23 @@ <%= @content_item.online_form_body %> <% end %> + <% if @content_item.email.any? %> +

Email

+ <% @content_item.email.each do |email_group| %> +

+ <% email_group[:v_card].each do |v_card_part| %> + + <%= v_card_part[:value] %> +
+ <% end %> + <%= mail_to email_group[:email], email_group[:email], class: 'email' %> +

+ + <%= email_group[:description] %> + <% end %> + <%= @content_item.email_body %> + <% end %> + <% if @content_item.phone.any? %>

Phone

<% @content_item.phone.each do |phone_group| %> diff --git a/test/integration/contact_test.rb b/test/integration/contact_test.rb index 9a1abfc8e..e680c462a 100644 --- a/test/integration/contact_test.rb +++ b/test/integration/contact_test.rb @@ -17,6 +17,17 @@ class ContactTest < ActionDispatch::IntegrationTest end end + test "emails are rendered" do + setup_and_visit_content_item('contact') + within_component_govspeak do |component_args| + content = component_args.fetch("content") + + html = Nokogiri::HTML.parse(content) + assert_not_nil html.at_css("h2#email-title") + assert_not_nil html.at_css(".email:first-of-type") + end + end + test "phones are rendered" do setup_and_visit_content_item('contact') within_component_govspeak do |component_args| diff --git a/test/presenters/contact_presenter_test.rb b/test/presenters/contact_presenter_test.rb index 1f678577c..b0821d567 100644 --- a/test/presenters/contact_presenter_test.rb +++ b/test/presenters/contact_presenter_test.rb @@ -68,5 +68,14 @@ def format_name test 'post_body returns correctly' do assert_equal schema_item['details']['more_info_post_address'], presented_item.post_body end + + test 'email' do + assert_equal schema_item['details']['email_addresses'][0]['email'].strip, presented_item.email[0][:email] + assert_equal schema_item['details']['email_addresses'][0]['title'].strip, presented_item.email[0][:v_card][0][:value] + end + + test 'email_body' do + assert_equal schema_item['details']['more_info_email_address'], presented_item.email_body + end end end From 1311a358fdd8050006df9503e957dbc16330bd55 Mon Sep 17 00:00:00 2001 From: Andrew Hilton Date: Fri, 17 Feb 2017 16:44:29 +0000 Subject: [PATCH 13/27] Update govspeak to use rich mode Adds bold behaviour --- app/views/content_items/contact.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/content_items/contact.html.erb b/app/views/content_items/contact.html.erb index 71c1ee1b7..445796eca 100644 --- a/app/views/content_items/contact.html.erb +++ b/app/views/content_items/contact.html.erb @@ -89,7 +89,7 @@ <% end %> <% end %> - <%= render 'govuk_component/govspeak', content: body %> + <%= render 'govuk_component/govspeak', content: body, rich_govspeak: true %>
<%= render 'govuk_component/related_items', @content_item.related_items %> From 9385af84853e4fcfbc1797b7d938c36252904cf1 Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Mon, 20 Feb 2017 15:23:31 +0000 Subject: [PATCH 14/27] Update wraith tests to include contacts pages --- README.md | 2 ++ test/wraith/config-examples.yaml | 1 + test/wraith/config-staging-vs-production.yaml | 12 ++++++++++++ test/wraith/config.yaml | 12 ++++++++++++ 4 files changed, 27 insertions(+) diff --git a/README.md b/README.md index 67b9036ee..913c983b4 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,8 @@ gallery of the output, located at `test/wraith/shots/gallery.html`. #### Compare examples on master with examples on branch +Examples are referencing https://github.com/alphagov/govuk-content-schemas + With government-frontend running master on the development VM and while [pointing at the dummy content store](https://github.com/alphagov/govuk-content-schemas/blob/master/docs/running-frontend-against-examples.md), create a set of historical screenshots using: ``` cd test/wraith diff --git a/test/wraith/config-examples.yaml b/test/wraith/config-examples.yaml index 9ad527adf..b5350d865 100644 --- a/test/wraith/config-examples.yaml +++ b/test/wraith/config-examples.yaml @@ -17,6 +17,7 @@ domains: # (required) The paths to capture. paths: + contact: /government/organisations/hm-revenue-customs/contact/customs-excise-and-vat-fraud-reporting detailed_guide_england-2014-to-2020-european-structural-and-investment-funds: /guidance/england-2014-to-2020-european-structural-and-investment-funds detailed_guide_detailed_guide: /guidance/salary-sacrifice-and-the-effects-on-paye detailed_guide_translated_detailed_guide: /guidance/prepare-a-charity-annual-return diff --git a/test/wraith/config-staging-vs-production.yaml b/test/wraith/config-staging-vs-production.yaml index b92568b81..04f2528d7 100644 --- a/test/wraith/config-staging-vs-production.yaml +++ b/test/wraith/config-staging-vs-production.yaml @@ -48,6 +48,18 @@ paths: case_study_9: '/government/case-studies/ktp-programme-helps-northern-ireland-generate-business-growth' case_study_10: '/government/case-studies/uk-china-cooperation-on-intellectual-property' + # Most popular from https://docs.publishing.service.gov.uk/document-types/contact.html (20 February 2017) + contact_1: /government/organisations/hm-revenue-customs/contact/income-tax-enquiries-for-individuals-pensioners-and-employees + contact_2: /government/organisations/hm-revenue-customs/contact/self-assessment + contact_3: /government/organisations/hm-revenue-customs/contact/employer-enquiries + contact_4: /government/organisations/hm-revenue-customs/contact/probate-and-inheritance-tax-enquiries + contact_5: /government/organisations/hm-revenue-customs/contact/income-tax-and-capital-gains-tax-enquiries-for-non-uk-residents + contact_6: /government/organisations/hm-revenue-customs/contact/stamp-duty-enquiries-shares-and-land + contact_7: /government/organisations/hm-revenue-customs/contact/self-assessment-forms-ordering + contact_8: /government/organisations/hm-revenue-customs/contact/trusts + contact_9: /government/organisations/hm-revenue-customs/contact/gambling-duties + contact_10: /government/organisations/hm-revenue-customs/contact/welsh-language-helpline-for-debt-management + statistics_announcement_national: '/government/statistics/announcements/uk-armed-forces-quarterly-personnel-report-october-2015' statistics_announcement_cancelled: '/government/statistics/announcements/diagnostic-imaging-dataset-for-september-2015' # Most visited statistics_announcement pages (2nd September 2016) diff --git a/test/wraith/config.yaml b/test/wraith/config.yaml index a15373f78..6cdc5cd0f 100644 --- a/test/wraith/config.yaml +++ b/test/wraith/config.yaml @@ -48,6 +48,18 @@ paths: case_study_9: '/government/case-studies/ktp-programme-helps-northern-ireland-generate-business-growth' case_study_10: '/government/case-studies/uk-china-cooperation-on-intellectual-property' + # Most popular from https://docs.publishing.service.gov.uk/document-types/contact.html (20 February 2017) + contact_1: /government/organisations/hm-revenue-customs/contact/income-tax-enquiries-for-individuals-pensioners-and-employees + contact_2: /government/organisations/hm-revenue-customs/contact/self-assessment + contact_3: /government/organisations/hm-revenue-customs/contact/employer-enquiries + contact_4: /government/organisations/hm-revenue-customs/contact/probate-and-inheritance-tax-enquiries + contact_5: /government/organisations/hm-revenue-customs/contact/income-tax-and-capital-gains-tax-enquiries-for-non-uk-residents + contact_6: /government/organisations/hm-revenue-customs/contact/stamp-duty-enquiries-shares-and-land + contact_7: /government/organisations/hm-revenue-customs/contact/self-assessment-forms-ordering + contact_8: /government/organisations/hm-revenue-customs/contact/trusts + contact_9: /government/organisations/hm-revenue-customs/contact/gambling-duties + contact_10: /government/organisations/hm-revenue-customs/contact/welsh-language-helpline-for-debt-management + statistics_announcement_national: '/government/statistics/announcements/uk-armed-forces-quarterly-personnel-report-october-2015' statistics_announcement_cancelled: '/government/statistics/announcements/diagnostic-imaging-dataset-for-september-2015' # Most visited statistics_announcement pages (2nd September 2016) From 3b06b601b7596a1b8ca2d023d8fdeeb606a8327c Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Mon, 20 Feb 2017 16:47:57 +0000 Subject: [PATCH 15/27] Port webchat from contacts-frontend to contact Initial commit, just to make sure the tests pass when ported. The original Webchat work was originally completed by Theodore Vararu, he documented some of this here: https://docs.google.com/document/d/1sXPauPRnMT-kxBBCafDy5T4uVDAoLA1CF0ZEOmtYYuk/edit --- app/assets/javascripts/application.js | 10 + app/assets/javascripts/webchat.js | 143 +++ app/presenters/contact_presenter.rb | 19 + app/views/content_items/contact.html.erb | 20 + spec/javascripts/helpers/SpecHelper.js | 23 + spec/javascripts/helpers/cookie-functions.js | 61 ++ .../helpers/jasmine-jquery-2.0.5.js | 813 ++++++++++++++++++ spec/javascripts/support/jasmine.yml | 3 + spec/javascripts/webchat.spec.js | 139 +++ 9 files changed, 1231 insertions(+) create mode 100644 app/assets/javascripts/webchat.js create mode 100644 spec/javascripts/helpers/SpecHelper.js create mode 100644 spec/javascripts/helpers/cookie-functions.js create mode 100644 spec/javascripts/helpers/jasmine-jquery-2.0.5.js create mode 100644 spec/javascripts/webchat.spec.js diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 079e5abc2..fc1107da4 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -1 +1,11 @@ //= require_tree ./modules +//= require webchat.js + +$(document).ready(function () { + var GOVUK = window.GOVUK; + if (GOVUK.Webchat) { + $('.js-webchat').map(function () { + return new GOVUK.Webchat({ $el: $(this) }); + }); + } +}); diff --git a/app/assets/javascripts/webchat.js b/app/assets/javascripts/webchat.js new file mode 100644 index 000000000..23c997816 --- /dev/null +++ b/app/assets/javascripts/webchat.js @@ -0,0 +1,143 @@ +(function (global) { + 'use strict'; + var $ = global.jQuery; + var windowLocationPathname = global.location.pathname; + var windowOpen = global.open; + if (typeof global.GOVUK === 'undefined') { global.GOVUK = {}; } + var GOVUK = global.GOVUK; + + // Each page will have a different entryPointID, which is a queue id. + // Don't enable this plugin on pages that don't exist in this map, and + // uncomment the additional routes as we obtain them. + // Whether the actual template is displayed is in `contact_presenter#show_webchat?`. + var entryPointIDs = {}; + entryPointIDs['/government/organisations/hm-revenue-customs/contact/child-benefit'] = 1027; + entryPointIDs['/government/organisations/hm-revenue-customs/contact/income-tax-enquiries-for-individuals-pensioners-and-employees'] = 1030; + entryPointIDs['/government/organisations/hm-revenue-customs/contact/vat-online-services-helpdesk'] = 1026; + entryPointIDs['/government/organisations/hm-revenue-customs/contact/national-insurance-numbers'] = 1021; + entryPointIDs['/government/organisations/hm-revenue-customs/contact/self-assessment-online-services-helpdesk'] = 1003; + entryPointIDs['/government/organisations/hm-revenue-customs/contact/self-assessment'] = 1004; + entryPointIDs['/government/organisations/hm-revenue-customs/contact/tax-credits-enquiries'] = 1016; + entryPointIDs['/government/organisations/hm-revenue-customs/contact/vat-enquiries'] = 1028; + entryPointIDs['/government/organisations/hm-revenue-customs/contact/customs-international-trade-and-excise-enquiries'] = 1034; + entryPointIDs['/government/organisations/hm-revenue-customs/contact/trusts'] = 1036; + entryPointIDs['/government/organisations/hm-revenue-customs/contact/employer-enquiries'] = 1023 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/construction-industry-scheme'] = 1048 + + var API_URL = 'https://online.hmrc.gov.uk/webchatprod/egain/chat/entrypoint/checkEligibility/'; + var OPEN_CHAT_URL = function (entryPointID) { + return 'https://online.hmrc.gov.uk/webchatprod/templates/chat/hmrc7/chat.html?entryPointId=' + entryPointID + '&templateName=hmrc7&languageCode=en&countryCode=US&ver=v11'; + }; + var CODE_AGENTS_AVAILABLE = 0; + var CODE_AGENTS_UNAVAILABLE = 1; + var CODE_AGENTS_BUSY = 2; + var POLL_INTERVAL = 15 * 1000; + var AJAX_TIMEOUT = 5 * 1000; + + function Webchat (options) { + var $el = $(options.$el); + var location = options.location || windowLocationPathname; + + var $advisersUnavailable = $el.find('.js-webchat-advisers-unavailable'); + var $advisersBusy = $el.find('.js-webchat-advisers-busy'); + var $advisersAvailable = $el.find('.js-webchat-advisers-available'); + var $advisersError = $el.find('.js-webchat-advisers-error'); + var $openButton = $el.find('.js-webchat-open-button'); + + var entryPointID = entryPointIDs[location]; + var pollingEnabled = true; + + if (entryPointID) { + pollAvailability(); + + $openButton.on('click', handleOpenChat); + } + + function pollAvailability () { + checkAvailability(); + + setTimeout(function () { + if (pollingEnabled) { + pollAvailability(); + } + }, POLL_INTERVAL); + } + + function checkAvailability () { + $.ajax({ + url: API_URL + entryPointID, + type: 'GET', + timeout: AJAX_TIMEOUT, + success: handleApiCallSuccess, + error: handleApiCallError + }); + } + + function handleApiCallSuccess (result) { + var $xml = $(result); + var response = parseInt($xml.find('checkEligibility').attr('responseType'), 10); + + switch (response) { + case CODE_AGENTS_UNAVAILABLE: handleAdvisersUnavailable(); break; + case CODE_AGENTS_BUSY: handleAdvisersBusy(); break; + case CODE_AGENTS_AVAILABLE: handleAdvisersAvailable(); break; + default: handleApiCallError(); break; + } + } + + function handleApiCallError () { + pollingEnabled = false; + handleAdvisersError(); + } + + function handleOpenChat (evt) { + evt.preventDefault(); + var url = OPEN_CHAT_URL(entryPointID); + windowOpen(url, 'newwin', 'width=200,height=100'); + + GOVUK.analytics.trackEvent('webchat', 'accepted'); + } + + function handleAdvisersError () { + $advisersError.removeClass('hidden'); + + $advisersAvailable.addClass('hidden'); + $advisersBusy.addClass('hidden'); + $advisersUnavailable.addClass('hidden'); + + GOVUK.analytics.trackEvent('webchat', 'error'); + } + + function handleAdvisersUnavailable () { + $advisersUnavailable.removeClass('hidden'); + + $advisersAvailable.addClass('hidden'); + $advisersBusy.addClass('hidden'); + $advisersError.addClass('hidden'); + + GOVUK.analytics.trackEvent('webchat', 'unavailable'); + } + + function handleAdvisersBusy () { + $advisersBusy.removeClass('hidden'); + + $advisersUnavailable.addClass('hidden'); + $advisersAvailable.addClass('hidden'); + $advisersError.addClass('hidden'); + + GOVUK.analytics.trackEvent('webchat', 'busy'); + } + + function handleAdvisersAvailable () { + $advisersAvailable.removeClass('hidden'); + + $advisersBusy.addClass('hidden'); + $advisersError.addClass('hidden'); + $advisersUnavailable.addClass('hidden'); + + GOVUK.analytics.trackEvent('webchat', 'offered'); + } + } + + GOVUK.Webchat = Webchat; +})(window); diff --git a/app/presenters/contact_presenter.rb b/app/presenters/contact_presenter.rb index 09b9c6a84..251a3d5c7 100644 --- a/app/presenters/contact_presenter.rb +++ b/app/presenters/contact_presenter.rb @@ -115,6 +115,25 @@ def email_body content_item["details"]["more_info_email_address"].html_safe end + def show_webchat? + # These are the routes on which we plan to roll out webchat, in stages. + whitelisted_paths = [ + '/government/organisations/hm-revenue-customs/contact/child-benefit', + '/government/organisations/hm-revenue-customs/contact/income-tax-enquiries-for-individuals-pensioners-and-employees', + '/government/organisations/hm-revenue-customs/contact/vat-online-services-helpdesk', + '/government/organisations/hm-revenue-customs/contact/national-insurance-numbers', + '/government/organisations/hm-revenue-customs/contact/self-assessment-online-services-helpdesk', + '/government/organisations/hm-revenue-customs/contact/self-assessment', + '/government/organisations/hm-revenue-customs/contact/tax-credits-enquiries', + '/government/organisations/hm-revenue-customs/contact/vat-enquiries', + '/government/organisations/hm-revenue-customs/contact/customs-international-trade-and-excise-enquiries', + '/government/organisations/hm-revenue-customs/contact/trusts', + '/government/organisations/hm-revenue-customs/contact/employer-enquiries', + '/government/organisations/hm-revenue-customs/contact/construction-industry-scheme', + ] + whitelisted_paths.include?(content_item["base_path"]) + end + private def v_card_part(v_card_class, value) diff --git a/app/views/content_items/contact.html.erb b/app/views/content_items/contact.html.erb index 445796eca..b278a38a4 100644 --- a/app/views/content_items/contact.html.erb +++ b/app/views/content_items/contact.html.erb @@ -36,6 +36,26 @@ <%= @content_item.email_body %> <% end %> + <% if @content_item.show_webchat? %> +

Webchat

+
+
+

+ Webchat is unavailable at the moment because of technical problems. +

+ + + +
+
+ <% end %> + <% if @content_item.phone.any? %>

Phone

<% @content_item.phone.each do |phone_group| %> diff --git a/spec/javascripts/helpers/SpecHelper.js b/spec/javascripts/helpers/SpecHelper.js new file mode 100644 index 000000000..a345225cf --- /dev/null +++ b/spec/javascripts/helpers/SpecHelper.js @@ -0,0 +1,23 @@ +beforeEach(function () { + jasmine.addMatchers({ + toBeEqualAsJSON: function (util, customEqualityTesters) { + return { + compare: function (actual, expected) { + var actualAsJSON = JSON.stringify(actual); + var expectedAsJSON = JSON.stringify(expected); + + var result = {}; + + result.pass = actualAsJSON === expectedAsJSON; + + if (result.pass) + result.message = "Expected " + actualAsJSON + " not to be equal to " + expectedAsJSON + " once converted to JSON"; + else + result.message = "Expected " + actualAsJSON + " to be equal to " + expectedAsJSON + " once converted to JSON"; + + return result; + } + } + } + }); +}); diff --git a/spec/javascripts/helpers/cookie-functions.js b/spec/javascripts/helpers/cookie-functions.js new file mode 100644 index 000000000..c5eb09199 --- /dev/null +++ b/spec/javascripts/helpers/cookie-functions.js @@ -0,0 +1,61 @@ +(function () { + "use strict" + var root = this; + if(typeof root.GOVUK === 'undefined') { root.GOVUK = {}; } + + /* + Cookie methods + ============== + + Usage: + + Setting a cookie: + GOVUK.cookie('hobnob', 'tasty', { days: 30 }); + + Reading a cookie: + GOVUK.cookie('hobnob'); + + Deleting a cookie: + GOVUK.cookie('hobnob', null); + */ + GOVUK.cookie = function (name, value, options) { + if(typeof value !== 'undefined'){ + if(value === false || value === null) { + return GOVUK.setCookie(name, '', { days: -1 }); + } else { + return GOVUK.setCookie(name, value, options); + } + } else { + return GOVUK.getCookie(name); + } + }; + GOVUK.setCookie = function (name, value, options) { + if(typeof options === 'undefined') { + options = {}; + } + var cookieString = name + "=" + value + "; path=/"; + if (options.days) { + var date = new Date(); + date.setTime(date.getTime() + (options.days * 24 * 60 * 60 * 1000)); + cookieString = cookieString + "; expires=" + date.toGMTString(); + } + if (document.location.protocol == 'https:'){ + cookieString = cookieString + "; Secure"; + } + document.cookie = cookieString; + }; + GOVUK.getCookie = function (name) { + var nameEQ = name + "="; + var cookies = document.cookie.split(';'); + for(var i = 0, len = cookies.length; i < len; i++) { + var cookie = cookies[i]; + while (cookie.charAt(0) == ' ') { + cookie = cookie.substring(1, cookie.length); + } + if (cookie.indexOf(nameEQ) === 0) { + return decodeURIComponent(cookie.substring(nameEQ.length)); + } + } + return null; + }; +}).call(this); diff --git a/spec/javascripts/helpers/jasmine-jquery-2.0.5.js b/spec/javascripts/helpers/jasmine-jquery-2.0.5.js new file mode 100644 index 000000000..89071b063 --- /dev/null +++ b/spec/javascripts/helpers/jasmine-jquery-2.0.5.js @@ -0,0 +1,813 @@ +/*! +Jasmine-jQuery: a set of jQuery helpers for Jasmine tests. + +Version 2.0.5 + +https://github.com/velesin/jasmine-jquery + +Copyright (c) 2010-2014 Wojciech Zawistowski, Travis Jeffery + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + ++function (window, jasmine, $) { "use strict"; + + jasmine.spiedEventsKey = function (selector, eventName) { + return [$(selector).selector, eventName].toString() + } + + jasmine.getFixtures = function () { + return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures() + } + + jasmine.getStyleFixtures = function () { + return jasmine.currentStyleFixtures_ = jasmine.currentStyleFixtures_ || new jasmine.StyleFixtures() + } + + jasmine.Fixtures = function () { + this.containerId = 'jasmine-fixtures' + this.fixturesCache_ = {} + this.fixturesPath = 'spec/javascripts/fixtures' + } + + jasmine.Fixtures.prototype.set = function (html) { + this.cleanUp() + return this.createContainer_(html) + } + + jasmine.Fixtures.prototype.appendSet= function (html) { + this.addToContainer_(html) + } + + jasmine.Fixtures.prototype.preload = function () { + this.read.apply(this, arguments) + } + + jasmine.Fixtures.prototype.load = function () { + this.cleanUp() + this.createContainer_(this.read.apply(this, arguments)) + } + + jasmine.Fixtures.prototype.appendLoad = function () { + this.addToContainer_(this.read.apply(this, arguments)) + } + + jasmine.Fixtures.prototype.read = function () { + var htmlChunks = [] + , fixtureUrls = arguments + + for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) { + htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex])) + } + + return htmlChunks.join('') + } + + jasmine.Fixtures.prototype.clearCache = function () { + this.fixturesCache_ = {} + } + + jasmine.Fixtures.prototype.cleanUp = function () { + $('#' + this.containerId).remove() + } + + jasmine.Fixtures.prototype.sandbox = function (attributes) { + var attributesToSet = attributes || {} + return $('
').attr(attributesToSet) + } + + jasmine.Fixtures.prototype.createContainer_ = function (html) { + var container = $('
') + .attr('id', this.containerId) + .html(html) + + $(document.body).append(container) + return container + } + + jasmine.Fixtures.prototype.addToContainer_ = function (html){ + var container = $(document.body).find('#'+this.containerId).append(html) + + if (!container.length) { + this.createContainer_(html) + } + } + + jasmine.Fixtures.prototype.getFixtureHtml_ = function (url) { + if (typeof this.fixturesCache_[url] === 'undefined') { + this.loadFixtureIntoCache_(url) + } + return this.fixturesCache_[url] + } + + jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function (relativeUrl) { + var self = this + , url = this.makeFixtureUrl_(relativeUrl) + , htmlText = '' + , request = $.ajax({ + async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded + cache: false, + url: url, + success: function (data, status, $xhr) { + htmlText = $xhr.responseText + } + }).fail(function ($xhr, status, err) { + throw new Error('Fixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + err.message + ')') + }) + + var scripts = $($.parseHTML(htmlText, true)).find('script[src]') || []; + + scripts.each(function(){ + $.ajax({ + async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded + cache: false, + dataType: 'script', + url: $(this).attr('src'), + success: function (data, status, $xhr) { + htmlText += '' + }, + error: function ($xhr, status, err) { + throw new Error('Script could not be loaded: ' + scriptSrc + ' (status: ' + status + ', message: ' + err.message + ')') + } + }); + }) + + self.fixturesCache_[relativeUrl] = htmlText; + } + + jasmine.Fixtures.prototype.makeFixtureUrl_ = function (relativeUrl){ + return this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl + } + + jasmine.Fixtures.prototype.proxyCallTo_ = function (methodName, passedArguments) { + return this[methodName].apply(this, passedArguments) + } + + + jasmine.StyleFixtures = function () { + this.fixturesCache_ = {} + this.fixturesNodes_ = [] + this.fixturesPath = 'spec/javascripts/fixtures' + } + + jasmine.StyleFixtures.prototype.set = function (css) { + this.cleanUp() + this.createStyle_(css) + } + + jasmine.StyleFixtures.prototype.appendSet = function (css) { + this.createStyle_(css) + } + + jasmine.StyleFixtures.prototype.preload = function () { + this.read_.apply(this, arguments) + } + + jasmine.StyleFixtures.prototype.load = function () { + this.cleanUp() + this.createStyle_(this.read_.apply(this, arguments)) + } + + jasmine.StyleFixtures.prototype.appendLoad = function () { + this.createStyle_(this.read_.apply(this, arguments)) + } + + jasmine.StyleFixtures.prototype.cleanUp = function () { + while(this.fixturesNodes_.length) { + this.fixturesNodes_.pop().remove() + } + } + + jasmine.StyleFixtures.prototype.createStyle_ = function (html) { + var styleText = $('
').html(html).text() + , style = $('') + + this.fixturesNodes_.push(style) + $('head').append(style) + } + + jasmine.StyleFixtures.prototype.clearCache = jasmine.Fixtures.prototype.clearCache + jasmine.StyleFixtures.prototype.read_ = jasmine.Fixtures.prototype.read + jasmine.StyleFixtures.prototype.getFixtureHtml_ = jasmine.Fixtures.prototype.getFixtureHtml_ + jasmine.StyleFixtures.prototype.loadFixtureIntoCache_ = jasmine.Fixtures.prototype.loadFixtureIntoCache_ + jasmine.StyleFixtures.prototype.makeFixtureUrl_ = jasmine.Fixtures.prototype.makeFixtureUrl_ + jasmine.StyleFixtures.prototype.proxyCallTo_ = jasmine.Fixtures.prototype.proxyCallTo_ + + jasmine.getJSONFixtures = function () { + return jasmine.currentJSONFixtures_ = jasmine.currentJSONFixtures_ || new jasmine.JSONFixtures() + } + + jasmine.JSONFixtures = function () { + this.fixturesCache_ = {} + this.fixturesPath = 'spec/javascripts/fixtures/json' + } + + jasmine.JSONFixtures.prototype.load = function () { + this.read.apply(this, arguments) + return this.fixturesCache_ + } + + jasmine.JSONFixtures.prototype.read = function () { + var fixtureUrls = arguments + + for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) { + this.getFixtureData_(fixtureUrls[urlIndex]) + } + + return this.fixturesCache_ + } + + jasmine.JSONFixtures.prototype.clearCache = function () { + this.fixturesCache_ = {} + } + + jasmine.JSONFixtures.prototype.getFixtureData_ = function (url) { + if (!this.fixturesCache_[url]) this.loadFixtureIntoCache_(url) + return this.fixturesCache_[url] + } + + jasmine.JSONFixtures.prototype.loadFixtureIntoCache_ = function (relativeUrl) { + var self = this + , url = this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl + + $.ajax({ + async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded + cache: false, + dataType: 'json', + url: url, + success: function (data) { + self.fixturesCache_[relativeUrl] = data + }, + error: function ($xhr, status, err) { + throw new Error('JSONFixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + err.message + ')') + } + }) + } + + jasmine.JSONFixtures.prototype.proxyCallTo_ = function (methodName, passedArguments) { + return this[methodName].apply(this, passedArguments) + } + + jasmine.jQuery = function () {} + + jasmine.jQuery.browserTagCaseIndependentHtml = function (html) { + return $('
').append(html).html() + } + + jasmine.jQuery.elementToString = function (element) { + return $(element).map(function () { return this.outerHTML; }).toArray().join(', ') + } + + var data = { + spiedEvents: {} + , handlers: [] + } + + jasmine.jQuery.events = { + spyOn: function (selector, eventName) { + var handler = function (e) { + data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] = jasmine.util.argsToArray(arguments) + } + + $(selector).on(eventName, handler) + data.handlers.push(handler) + + return { + selector: selector, + eventName: eventName, + handler: handler, + reset: function (){ + delete data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] + } + } + }, + + args: function (selector, eventName) { + var actualArgs = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] + + if (!actualArgs) { + throw "There is no spy for " + eventName + " on " + selector.toString() + ". Make sure to create a spy using spyOnEvent." + } + + return actualArgs + }, + + wasTriggered: function (selector, eventName) { + return !!(data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)]) + }, + + wasTriggeredWith: function (selector, eventName, expectedArgs, util, customEqualityTesters) { + var actualArgs = jasmine.jQuery.events.args(selector, eventName).slice(1) + + if (Object.prototype.toString.call(expectedArgs) !== '[object Array]') + actualArgs = actualArgs[0] + + return util.equals(expectedArgs, actualArgs, customEqualityTesters) + }, + + wasPrevented: function (selector, eventName) { + var args = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] + , e = args ? args[0] : undefined + + return e && e.isDefaultPrevented() + }, + + wasStopped: function (selector, eventName) { + var args = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] + , e = args ? args[0] : undefined + return e && e.isPropagationStopped() + }, + + cleanUp: function () { + data.spiedEvents = {} + data.handlers = [] + } + } + + var hasProperty = function (actualValue, expectedValue) { + if (expectedValue === undefined) + return actualValue !== undefined + + return actualValue === expectedValue + } + + beforeEach(function () { + jasmine.addMatchers({ + toHaveClass: function () { + return { + compare: function (actual, className) { + return { pass: $(actual).hasClass(className) } + } + } + }, + + toHaveCss: function () { + return { + compare: function (actual, css) { + for (var prop in css){ + var value = css[prop] + // see issue #147 on gh + ;if (value === 'auto' && $(actual).get(0).style[prop] === 'auto') continue + if ($(actual).css(prop) !== value) return { pass: false } + } + return { pass: true } + } + } + }, + + toBeVisible: function () { + return { + compare: function (actual) { + return { pass: $(actual).is(':visible') } + } + } + }, + + toBeHidden: function () { + return { + compare: function (actual) { + return { pass: $(actual).is(':hidden') } + } + } + }, + + toBeSelected: function () { + return { + compare: function (actual) { + return { pass: $(actual).is(':selected') } + } + } + }, + + toBeChecked: function () { + return { + compare: function (actual) { + return { pass: $(actual).is(':checked') } + } + } + }, + + toBeEmpty: function () { + return { + compare: function (actual) { + return { pass: $(actual).is(':empty') } + } + } + }, + + toBeInDOM: function () { + return { + compare: function (actual) { + return { pass: $.contains(document.documentElement, $(actual)[0]) } + } + } + }, + + toExist: function () { + return { + compare: function (actual) { + return { pass: $(actual).length } + } + } + }, + + toHaveLength: function () { + return { + compare: function (actual, length) { + return { pass: $(actual).length === length } + } + } + }, + + toHaveAttr: function () { + return { + compare: function (actual, attributeName, expectedAttributeValue) { + return { pass: hasProperty($(actual).attr(attributeName), expectedAttributeValue) } + } + } + }, + + toHaveProp: function () { + return { + compare: function (actual, propertyName, expectedPropertyValue) { + return { pass: hasProperty($(actual).prop(propertyName), expectedPropertyValue) } + } + } + }, + + toHaveId: function () { + return { + compare: function (actual, id) { + return { pass: $(actual).attr('id') == id } + } + } + }, + + toHaveHtml: function () { + return { + compare: function (actual, html) { + return { pass: $(actual).html() == jasmine.jQuery.browserTagCaseIndependentHtml(html) } + } + } + }, + + toContainHtml: function () { + return { + compare: function (actual, html) { + var actualHtml = $(actual).html() + , expectedHtml = jasmine.jQuery.browserTagCaseIndependentHtml(html) + + return { pass: (actualHtml.indexOf(expectedHtml) >= 0) } + } + } + }, + + toHaveText: function () { + return { + compare: function (actual, text) { + var actualText = $(actual).text() + var trimmedText = $.trim(actualText) + + if (text && $.isFunction(text.test)) { + return { pass: text.test(actualText) || text.test(trimmedText) } + } else { + return { pass: (actualText == text || trimmedText == text) } + } + } + } + }, + + toContainText: function () { + return { + compare: function (actual, text) { + var trimmedText = $.trim($(actual).text()) + + if (text && $.isFunction(text.test)) { + return { pass: text.test(trimmedText) } + } else { + return { pass: trimmedText.indexOf(text) != -1 } + } + } + } + }, + + toHaveValue: function () { + return { + compare: function (actual, value) { + return { pass: $(actual).val() === value } + } + } + }, + + toHaveData: function () { + return { + compare: function (actual, key, expectedValue) { + return { pass: hasProperty($(actual).data(key), expectedValue) } + } + } + }, + + toContainElement: function () { + return { + compare: function (actual, selector) { + if (window.debug) debugger + return { pass: $(actual).find(selector).length } + } + } + }, + + toBeMatchedBy: function () { + return { + compare: function (actual, selector) { + return { pass: $(actual).filter(selector).length } + } + } + }, + + toBeDisabled: function () { + return { + compare: function (actual, selector) { + return { pass: $(actual).is(':disabled') } + } + } + }, + + toBeFocused: function (selector) { + return { + compare: function (actual, selector) { + return { pass: $(actual)[0] === $(actual)[0].ownerDocument.activeElement } + } + } + }, + + toHandle: function () { + return { + compare: function (actual, event) { + var events = $._data($(actual).get(0), "events") + + if (!events || !event || typeof event !== "string") { + return { pass: false } + } + + var namespaces = event.split(".") + , eventType = namespaces.shift() + , sortedNamespaces = namespaces.slice(0).sort() + , namespaceRegExp = new RegExp("(^|\\.)" + sortedNamespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") + + if (events[eventType] && namespaces.length) { + for (var i = 0; i < events[eventType].length; i++) { + var namespace = events[eventType][i].namespace + + if (namespaceRegExp.test(namespace)) + return { pass: true } + } + } else { + return { pass: (events[eventType] && events[eventType].length > 0) } + } + + return { pass: false } + } + } + }, + + toHandleWith: function () { + return { + compare: function (actual, eventName, eventHandler) { + var normalizedEventName = eventName.split('.')[0] + , stack = $._data($(actual).get(0), "events")[normalizedEventName] + + for (var i = 0; i < stack.length; i++) { + if (stack[i].handler == eventHandler) return { pass: true } + } + + return { pass: false } + } + } + }, + + toHaveBeenTriggeredOn: function () { + return { + compare: function (actual, selector) { + var result = { pass: jasmine.jQuery.events.wasTriggered(selector, actual) } + + result.message = result.pass ? + "Expected event " + $(actual) + " not to have been triggered on " + selector : + "Expected event " + $(actual) + " to have been triggered on " + selector + + return result; + } + } + }, + + toHaveBeenTriggered: function (){ + return { + compare: function (actual) { + var eventName = actual.eventName + , selector = actual.selector + , result = { pass: jasmine.jQuery.events.wasTriggered(selector, eventName) } + + result.message = result.pass ? + "Expected event " + eventName + " not to have been triggered on " + selector : + "Expected event " + eventName + " to have been triggered on " + selector + + return result + } + } + }, + + toHaveBeenTriggeredOnAndWith: function (j$, customEqualityTesters) { + return { + compare: function (actual, selector, expectedArgs) { + var wasTriggered = jasmine.jQuery.events.wasTriggered(selector, actual) + , result = { pass: wasTriggered && jasmine.jQuery.events.wasTriggeredWith(selector, actual, expectedArgs, j$, customEqualityTesters) } + + if (wasTriggered) { + var actualArgs = jasmine.jQuery.events.args(selector, actual, expectedArgs)[1] + result.message = result.pass ? + "Expected event " + actual + " not to have been triggered with " + jasmine.pp(expectedArgs) + " but it was triggered with " + jasmine.pp(actualArgs) : + "Expected event " + actual + " to have been triggered with " + jasmine.pp(expectedArgs) + " but it was triggered with " + jasmine.pp(actualArgs) + + } else { + // todo check on this + result.message = result.pass ? + "Expected event " + actual + " not to have been triggered on " + selector : + "Expected event " + actual + " to have been triggered on " + selector + } + + return result + } + } + }, + + toHaveBeenPreventedOn: function () { + return { + compare: function (actual, selector) { + var result = { pass: jasmine.jQuery.events.wasPrevented(selector, actual) } + + result.message = result.pass ? + "Expected event " + actual + " not to have been prevented on " + selector : + "Expected event " + actual + " to have been prevented on " + selector + + return result + } + } + }, + + toHaveBeenPrevented: function () { + return { + compare: function (actual) { + var eventName = actual.eventName + , selector = actual.selector + , result = { pass: jasmine.jQuery.events.wasPrevented(selector, eventName) } + + result.message = result.pass ? + "Expected event " + eventName + " not to have been prevented on " + selector : + "Expected event " + eventName + " to have been prevented on " + selector + + return result + } + } + }, + + toHaveBeenStoppedOn: function () { + return { + compare: function (actual, selector) { + var result = { pass: jasmine.jQuery.events.wasStopped(selector, actual) } + + result.message = result.pass ? + "Expected event " + actual + " not to have been stopped on " + selector : + "Expected event " + actual + " to have been stopped on " + selector + + return result; + } + } + }, + + toHaveBeenStopped: function () { + return { + compare: function (actual) { + var eventName = actual.eventName + , selector = actual.selector + , result = { pass: jasmine.jQuery.events.wasStopped(selector, eventName) } + + result.message = result.pass ? + "Expected event " + eventName + " not to have been stopped on " + selector : + "Expected event " + eventName + " to have been stopped on " + selector + + return result + } + } + } + }) + + jasmine.getEnv().addCustomEqualityTester(function(a, b) { + if (a && b) { + if (a instanceof $ || jasmine.isDomNode(a)) { + var $a = $(a) + + if (b instanceof $) + return $a.length == b.length && a.is(b) + + return $a.is(b); + } + + if (b instanceof $ || jasmine.isDomNode(b)) { + var $b = $(b) + + if (a instanceof $) + return a.length == $b.length && $b.is(a) + + return $(b).is(a); + } + } + }) + + jasmine.getEnv().addCustomEqualityTester(function (a, b) { + if (a instanceof $ && b instanceof $ && a.size() == b.size()) + return a.is(b) + }) + }) + + afterEach(function () { + jasmine.getFixtures().cleanUp() + jasmine.getStyleFixtures().cleanUp() + jasmine.jQuery.events.cleanUp() + }) + + window.readFixtures = function () { + return jasmine.getFixtures().proxyCallTo_('read', arguments) + } + + window.preloadFixtures = function () { + jasmine.getFixtures().proxyCallTo_('preload', arguments) + } + + window.loadFixtures = function () { + jasmine.getFixtures().proxyCallTo_('load', arguments) + } + + window.appendLoadFixtures = function () { + jasmine.getFixtures().proxyCallTo_('appendLoad', arguments) + } + + window.setFixtures = function (html) { + return jasmine.getFixtures().proxyCallTo_('set', arguments) + } + + window.appendSetFixtures = function () { + jasmine.getFixtures().proxyCallTo_('appendSet', arguments) + } + + window.sandbox = function (attributes) { + return jasmine.getFixtures().sandbox(attributes) + } + + window.spyOnEvent = function (selector, eventName) { + return jasmine.jQuery.events.spyOn(selector, eventName) + } + + window.preloadStyleFixtures = function () { + jasmine.getStyleFixtures().proxyCallTo_('preload', arguments) + } + + window.loadStyleFixtures = function () { + jasmine.getStyleFixtures().proxyCallTo_('load', arguments) + } + + window.appendLoadStyleFixtures = function () { + jasmine.getStyleFixtures().proxyCallTo_('appendLoad', arguments) + } + + window.setStyleFixtures = function (html) { + jasmine.getStyleFixtures().proxyCallTo_('set', arguments) + } + + window.appendSetStyleFixtures = function (html) { + jasmine.getStyleFixtures().proxyCallTo_('appendSet', arguments) + } + + window.loadJSONFixtures = function () { + return jasmine.getJSONFixtures().proxyCallTo_('load', arguments) + } + + window.getJSONFixture = function (url) { + return jasmine.getJSONFixtures().proxyCallTo_('read', arguments)[url] + } +}(window, window.jasmine, window.jQuery); diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml index 7aa3a53a7..9839028c9 100644 --- a/spec/javascripts/support/jasmine.yml +++ b/spec/javascripts/support/jasmine.yml @@ -17,6 +17,9 @@ css_dir: "app/assets/stylesheets" # list of file expressions to include as source files # relative path from src_dir src_files: + - "../../../spec/javascripts/helpers/jquery-1.12.4.js" + - "../../../spec/javascripts/helpers/jasmine-jquery-2.0.5.js" + - "../../../spec/javascripts/helpers/cookie-functions.js" - "application.{js.coffee,js,coffee}" # list of file expressions to include as css files diff --git a/spec/javascripts/webchat.spec.js b/spec/javascripts/webchat.spec.js new file mode 100644 index 000000000..389e5aa2c --- /dev/null +++ b/spec/javascripts/webchat.spec.js @@ -0,0 +1,139 @@ +/* globals + describe, + it, + expect, + $, + beforeEach, + setFixtures, + spyOn, + GOVUK, + jasmine +*/ + +describe('Webchat', function () { + // Stub analytics. + GOVUK.analytics = { trackEvent: function () {} }; + + var INSERTION_HOOK = '
' + + '
Error
' + + '' + + '' + + '' + + '
'; + var $webchat, $advisersUnavailable, $advisersBusy, $advisersAvailable, $advisersError; + + var CHILD_BENEFIT_API_URL = 'https://online.hmrc.gov.uk/webchatprod/egain/chat/entrypoint/checkEligibility/' + 1027; + + var xmlResponse = function (responseType) { + return $.parseXML(''); + }; + var xmlResponseAvailable = xmlResponse(0); + var xmlResponseUnavailable = xmlResponse(1); + var xmlResponseBusy = xmlResponse(2); + var xmlResponseError = '404 not found'; + + beforeEach(function () { + setFixtures(INSERTION_HOOK); + $webchat = $('.js-webchat'); + $advisersUnavailable = $webchat.find('.js-webchat-advisers-unavailable'); + $advisersBusy = $webchat.find('.js-webchat-advisers-busy'); + $advisersAvailable = $webchat.find('.js-webchat-advisers-available'); + $advisersError = $webchat.find('.js-webchat-advisers-error'); + }); + + describe('on valid application locations', function () { + function mount () { + $webchat.map(function () { + return new GOVUK.Webchat({ + $el: $(this), + location: '/government/organisations/hm-revenue-customs/contact/child-benefit' + }); + }); + } + + it('should poll for availability', function () { + spyOn($, 'ajax'); + mount(); + expect($.ajax).toHaveBeenCalledWith({ + url: CHILD_BENEFIT_API_URL, + type: 'GET', + timeout: jasmine.any(Number), + success: jasmine.any(Function), + error: jasmine.any(Function) + }); + }); + + it('should inform user whether advisors are available', function () { + spyOn($, 'ajax').and.callFake(function (options) { + options.success(xmlResponseAvailable); + }); + mount(); + expect($advisersAvailable.hasClass('hidden')).toBe(false); + + expect($advisersBusy.hasClass('hidden')).toBe(true); + expect($advisersError.hasClass('hidden')).toBe(true); + expect($advisersUnavailable.hasClass('hidden')).toBe(true); + }); + + it('should inform user whether advisors are unavailable', function () { + spyOn($, 'ajax').and.callFake(function (options) { + options.success(xmlResponseUnavailable); + }); + mount(); + expect($advisersUnavailable.hasClass('hidden')).toBe(false); + + expect($advisersAvailable.hasClass('hidden')).toBe(true); + expect($advisersBusy.hasClass('hidden')).toBe(true); + expect($advisersError.hasClass('hidden')).toBe(true); + }); + + it('should inform user whether advisors are busy', function () { + spyOn($, 'ajax').and.callFake(function (options) { + options.success(xmlResponseBusy); + }); + mount(); + expect($advisersBusy.hasClass('hidden')).toBe(false); + + expect($advisersAvailable.hasClass('hidden')).toBe(true); + expect($advisersError.hasClass('hidden')).toBe(true); + expect($advisersUnavailable.hasClass('hidden')).toBe(true); + }); + + it('should inform user whether there was an error', function () { + spyOn($, 'ajax').and.callFake(function (options) { + options.success(xmlResponseError); + }); + mount(); + expect($advisersError.hasClass('hidden')).toBe(false); + + expect($advisersAvailable.hasClass('hidden')).toBe(true); + expect($advisersBusy.hasClass('hidden')).toBe(true); + expect($advisersUnavailable.hasClass('hidden')).toBe(true); + }); + }); + + describe('on invalid locations', function () { + function mount () { + $webchat.map(function () { + return new GOVUK.Webchat({ + $el: $(this), + location: '/' + }); + }); + } + + it('should not poll', function () { + spyOn($, 'ajax'); + mount(); + expect($.ajax).not.toHaveBeenCalled(); + }); + }); +}); From 7f7aa8d5d02ee5424eed43c7e2cd6d71ff1d9457 Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Mon, 20 Feb 2017 16:56:18 +0000 Subject: [PATCH 16/27] Update analytics stubbing to not conflict --- spec/javascripts/track-share-button-clicks.spec.js | 3 ++- spec/javascripts/webchat.spec.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/javascripts/track-share-button-clicks.spec.js b/spec/javascripts/track-share-button-clicks.spec.js index a43954190..06f8d9bf6 100644 --- a/spec/javascripts/track-share-button-clicks.spec.js +++ b/spec/javascripts/track-share-button-clicks.spec.js @@ -9,7 +9,8 @@ describe('A share button click tracker', function () { var tracker var element - GOVUK.analytics = GOVUK.analytics || {trackShare: function () {}} + GOVUK.analytics = GOVUK.analytics || {} + GOVUK.analytics.trackShare = function () {} beforeEach(function () { tracker = new GOVUK.Modules.TrackShareButtonClicks() diff --git a/spec/javascripts/webchat.spec.js b/spec/javascripts/webchat.spec.js index 389e5aa2c..aea5345c0 100644 --- a/spec/javascripts/webchat.spec.js +++ b/spec/javascripts/webchat.spec.js @@ -12,7 +12,8 @@ describe('Webchat', function () { // Stub analytics. - GOVUK.analytics = { trackEvent: function () {} }; + GOVUK.analytics = GOVUK.analytics || {}; + GOVUK.analytics.trackEvent = function () {}; var INSERTION_HOOK = '
' + '
Error
' + From 29bda3d40e490ef7b1d8198ff2a7a098e8050823 Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Mon, 20 Feb 2017 17:03:40 +0000 Subject: [PATCH 17/27] Lint and format test specs to standardjs --- app/assets/javascripts/application.js | 12 +- app/assets/javascripts/webchat.js | 156 +++++++-------- .../track-share-button-clicks.spec.js | 14 +- spec/javascripts/webchat.spec.js | 177 +++++++++--------- 4 files changed, 184 insertions(+), 175 deletions(-) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index fc1107da4..a3ea0f8a0 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -1,11 +1,15 @@ +/* eslint-disable */ //= require_tree ./modules //= require webchat.js +/*eslint-enable */ + +var $ = window.$ $(document).ready(function () { - var GOVUK = window.GOVUK; + var GOVUK = window.GOVUK if (GOVUK.Webchat) { $('.js-webchat').map(function () { - return new GOVUK.Webchat({ $el: $(this) }); - }); + return new GOVUK.Webchat({ $el: $(this) }) + }) } -}); +}) diff --git a/app/assets/javascripts/webchat.js b/app/assets/javascripts/webchat.js index 23c997816..449f3b6a2 100644 --- a/app/assets/javascripts/webchat.js +++ b/app/assets/javascripts/webchat.js @@ -1,66 +1,66 @@ (function (global) { - 'use strict'; - var $ = global.jQuery; - var windowLocationPathname = global.location.pathname; - var windowOpen = global.open; - if (typeof global.GOVUK === 'undefined') { global.GOVUK = {}; } - var GOVUK = global.GOVUK; + 'use strict' + var $ = global.jQuery + var windowLocationPathname = global.location.pathname + var windowOpen = global.open + if (typeof global.GOVUK === 'undefined') { global.GOVUK = {} } + var GOVUK = global.GOVUK // Each page will have a different entryPointID, which is a queue id. // Don't enable this plugin on pages that don't exist in this map, and // uncomment the additional routes as we obtain them. // Whether the actual template is displayed is in `contact_presenter#show_webchat?`. - var entryPointIDs = {}; - entryPointIDs['/government/organisations/hm-revenue-customs/contact/child-benefit'] = 1027; - entryPointIDs['/government/organisations/hm-revenue-customs/contact/income-tax-enquiries-for-individuals-pensioners-and-employees'] = 1030; - entryPointIDs['/government/organisations/hm-revenue-customs/contact/vat-online-services-helpdesk'] = 1026; - entryPointIDs['/government/organisations/hm-revenue-customs/contact/national-insurance-numbers'] = 1021; - entryPointIDs['/government/organisations/hm-revenue-customs/contact/self-assessment-online-services-helpdesk'] = 1003; - entryPointIDs['/government/organisations/hm-revenue-customs/contact/self-assessment'] = 1004; - entryPointIDs['/government/organisations/hm-revenue-customs/contact/tax-credits-enquiries'] = 1016; - entryPointIDs['/government/organisations/hm-revenue-customs/contact/vat-enquiries'] = 1028; - entryPointIDs['/government/organisations/hm-revenue-customs/contact/customs-international-trade-and-excise-enquiries'] = 1034; - entryPointIDs['/government/organisations/hm-revenue-customs/contact/trusts'] = 1036; + var entryPointIDs = {} + entryPointIDs['/government/organisations/hm-revenue-customs/contact/child-benefit'] = 1027 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/income-tax-enquiries-for-individuals-pensioners-and-employees'] = 1030 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/vat-online-services-helpdesk'] = 1026 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/national-insurance-numbers'] = 1021 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/self-assessment-online-services-helpdesk'] = 1003 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/self-assessment'] = 1004 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/tax-credits-enquiries'] = 1016 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/vat-enquiries'] = 1028 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/customs-international-trade-and-excise-enquiries'] = 1034 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/trusts'] = 1036 entryPointIDs['/government/organisations/hm-revenue-customs/contact/employer-enquiries'] = 1023 entryPointIDs['/government/organisations/hm-revenue-customs/contact/construction-industry-scheme'] = 1048 - var API_URL = 'https://online.hmrc.gov.uk/webchatprod/egain/chat/entrypoint/checkEligibility/'; + var API_URL = 'https://online.hmrc.gov.uk/webchatprod/egain/chat/entrypoint/checkEligibility/' var OPEN_CHAT_URL = function (entryPointID) { - return 'https://online.hmrc.gov.uk/webchatprod/templates/chat/hmrc7/chat.html?entryPointId=' + entryPointID + '&templateName=hmrc7&languageCode=en&countryCode=US&ver=v11'; - }; - var CODE_AGENTS_AVAILABLE = 0; - var CODE_AGENTS_UNAVAILABLE = 1; - var CODE_AGENTS_BUSY = 2; - var POLL_INTERVAL = 15 * 1000; - var AJAX_TIMEOUT = 5 * 1000; + return 'https://online.hmrc.gov.uk/webchatprod/templates/chat/hmrc7/chat.html?entryPointId=' + entryPointID + '&templateName=hmrc7&languageCode=en&countryCode=US&ver=v11' + } + var CODE_AGENTS_AVAILABLE = 0 + var CODE_AGENTS_UNAVAILABLE = 1 + var CODE_AGENTS_BUSY = 2 + var POLL_INTERVAL = 15 * 1000 + var AJAX_TIMEOUT = 5 * 1000 function Webchat (options) { - var $el = $(options.$el); - var location = options.location || windowLocationPathname; + var $el = $(options.$el) + var location = options.location || windowLocationPathname - var $advisersUnavailable = $el.find('.js-webchat-advisers-unavailable'); - var $advisersBusy = $el.find('.js-webchat-advisers-busy'); - var $advisersAvailable = $el.find('.js-webchat-advisers-available'); - var $advisersError = $el.find('.js-webchat-advisers-error'); - var $openButton = $el.find('.js-webchat-open-button'); + var $advisersUnavailable = $el.find('.js-webchat-advisers-unavailable') + var $advisersBusy = $el.find('.js-webchat-advisers-busy') + var $advisersAvailable = $el.find('.js-webchat-advisers-available') + var $advisersError = $el.find('.js-webchat-advisers-error') + var $openButton = $el.find('.js-webchat-open-button') - var entryPointID = entryPointIDs[location]; - var pollingEnabled = true; + var entryPointID = entryPointIDs[location] + var pollingEnabled = true if (entryPointID) { - pollAvailability(); + pollAvailability() - $openButton.on('click', handleOpenChat); + $openButton.on('click', handleOpenChat) } function pollAvailability () { - checkAvailability(); + checkAvailability() setTimeout(function () { if (pollingEnabled) { - pollAvailability(); + pollAvailability() } - }, POLL_INTERVAL); + }, POLL_INTERVAL) } function checkAvailability () { @@ -70,74 +70,82 @@ timeout: AJAX_TIMEOUT, success: handleApiCallSuccess, error: handleApiCallError - }); + }) } function handleApiCallSuccess (result) { - var $xml = $(result); - var response = parseInt($xml.find('checkEligibility').attr('responseType'), 10); + var $xml = $(result) + var response = parseInt($xml.find('checkEligibility').attr('responseType'), 10) switch (response) { - case CODE_AGENTS_UNAVAILABLE: handleAdvisersUnavailable(); break; - case CODE_AGENTS_BUSY: handleAdvisersBusy(); break; - case CODE_AGENTS_AVAILABLE: handleAdvisersAvailable(); break; - default: handleApiCallError(); break; + case CODE_AGENTS_UNAVAILABLE: + handleAdvisersUnavailable() + break + case CODE_AGENTS_BUSY: + handleAdvisersBusy() + break + case CODE_AGENTS_AVAILABLE: + handleAdvisersAvailable() + break + default: + handleApiCallError() + break } } function handleApiCallError () { - pollingEnabled = false; - handleAdvisersError(); + pollingEnabled = false + handleAdvisersError() } function handleOpenChat (evt) { - evt.preventDefault(); - var url = OPEN_CHAT_URL(entryPointID); - windowOpen(url, 'newwin', 'width=200,height=100'); + evt.preventDefault() + var url = OPEN_CHAT_URL(entryPointID) + windowOpen(url, 'newwin', 'width=200,height=100') - GOVUK.analytics.trackEvent('webchat', 'accepted'); + GOVUK.analytics.trackEvent('webchat', 'accepted') } function handleAdvisersError () { - $advisersError.removeClass('hidden'); + $advisersError.removeClass('hidden') - $advisersAvailable.addClass('hidden'); - $advisersBusy.addClass('hidden'); - $advisersUnavailable.addClass('hidden'); + $advisersAvailable.addClass('hidden') + $advisersBusy.addClass('hidden') + $advisersUnavailable.addClass('hidden') - GOVUK.analytics.trackEvent('webchat', 'error'); + GOVUK.analytics.trackEvent('webchat', 'error') } function handleAdvisersUnavailable () { - $advisersUnavailable.removeClass('hidden'); + $advisersUnavailable.removeClass('hidden') - $advisersAvailable.addClass('hidden'); - $advisersBusy.addClass('hidden'); - $advisersError.addClass('hidden'); + $advisersAvailable.addClass('hidden') + $advisersBusy.addClass('hidden') + $advisersError.addClass('hidden') - GOVUK.analytics.trackEvent('webchat', 'unavailable'); + GOVUK.analytics.trackEvent('webchat', 'unavailable') } function handleAdvisersBusy () { - $advisersBusy.removeClass('hidden'); + $advisersBusy.removeClass('hidden') - $advisersUnavailable.addClass('hidden'); - $advisersAvailable.addClass('hidden'); - $advisersError.addClass('hidden'); + $advisersUnavailable.addClass('hidden') + $advisersAvailable.addClass('hidden') + $advisersError.addClass('hidden') - GOVUK.analytics.trackEvent('webchat', 'busy'); + GOVUK.analytics.trackEvent('webchat', 'busy') } function handleAdvisersAvailable () { - $advisersAvailable.removeClass('hidden'); + $advisersAvailable.removeClass('hidden') - $advisersBusy.addClass('hidden'); - $advisersError.addClass('hidden'); - $advisersUnavailable.addClass('hidden'); + $advisersBusy.addClass('hidden') + $advisersError.addClass('hidden') + $advisersUnavailable.addClass('hidden') - GOVUK.analytics.trackEvent('webchat', 'offered'); + GOVUK.analytics.trackEvent('webchat', 'offered') } } - GOVUK.Webchat = Webchat; -})(window); + GOVUK.Webchat = Webchat +})(window) diff --git a/spec/javascripts/track-share-button-clicks.spec.js b/spec/javascripts/track-share-button-clicks.spec.js index 06f8d9bf6..01117d664 100644 --- a/spec/javascripts/track-share-button-clicks.spec.js +++ b/spec/javascripts/track-share-button-clicks.spec.js @@ -1,5 +1,5 @@ -/* global describe it expect beforeEach spyOn */ -/* eslint-disable no-multi-str */ +/* global describe beforeEach it spyOn expect */ + var $ = window.jQuery describe('A share button click tracker', function () { @@ -18,10 +18,12 @@ describe('A share button click tracker', function () { it('tracks click events on share buttons', function () { spyOn(GOVUK.analytics, 'trackShare') - element = $('
\ - Share\ - Share\ -
') + element = $( + '
' + + 'Share' + + 'Share' + + '
' + ) tracker.start(element) element.find('.js-share-facebook').trigger('click') diff --git a/spec/javascripts/webchat.spec.js b/spec/javascripts/webchat.spec.js index aea5345c0..ebd8d3ffe 100644 --- a/spec/javascripts/webchat.spec.js +++ b/spec/javascripts/webchat.spec.js @@ -1,19 +1,13 @@ -/* globals - describe, - it, - expect, - $, - beforeEach, - setFixtures, - spyOn, - GOVUK, - jasmine -*/ +/* global describe beforeEach setFixtures it spyOn expect jasmine */ + +var $ = window.jQuery describe('Webchat', function () { + var GOVUK = window.GOVUK + // Stub analytics. - GOVUK.analytics = GOVUK.analytics || {}; - GOVUK.analytics.trackEvent = function () {}; + GOVUK.analytics = GOVUK.analytics || {} + GOVUK.analytics.trackEvent = function () {} var INSERTION_HOOK = '
' + '
Error
' + @@ -22,33 +16,41 @@ describe('Webchat', function () { '' + - '
'; - var $webchat, $advisersUnavailable, $advisersBusy, $advisersAvailable, $advisersError; + '
' + var $webchat + var $advisersUnavailable + var $advisersBusy + var $advisersAvailable + var $advisersError - var CHILD_BENEFIT_API_URL = 'https://online.hmrc.gov.uk/webchatprod/egain/chat/entrypoint/checkEligibility/' + 1027; + var CHILD_BENEFIT_API_URL = 'https://online.hmrc.gov.uk/webchatprod/egain/chat/entrypoint/checkEligibility/' + + 1027 var xmlResponse = function (responseType) { - return $.parseXML(''); - }; - var xmlResponseAvailable = xmlResponse(0); - var xmlResponseUnavailable = xmlResponse(1); - var xmlResponseBusy = xmlResponse(2); - var xmlResponseError = '404 not found'; + return $.parseXML( + '' + ) + } + var xmlResponseAvailable = xmlResponse(0) + var xmlResponseUnavailable = xmlResponse(1) + var xmlResponseBusy = xmlResponse(2) + var xmlResponseError = '404 not found' beforeEach(function () { - setFixtures(INSERTION_HOOK); - $webchat = $('.js-webchat'); - $advisersUnavailable = $webchat.find('.js-webchat-advisers-unavailable'); - $advisersBusy = $webchat.find('.js-webchat-advisers-busy'); - $advisersAvailable = $webchat.find('.js-webchat-advisers-available'); - $advisersError = $webchat.find('.js-webchat-advisers-error'); - }); + setFixtures(INSERTION_HOOK) + $webchat = $('.js-webchat') + $advisersUnavailable = $webchat.find('.js-webchat-advisers-unavailable') + $advisersBusy = $webchat.find('.js-webchat-advisers-busy') + $advisersAvailable = $webchat.find('.js-webchat-advisers-available') + $advisersError = $webchat.find('.js-webchat-advisers-error') + }) describe('on valid application locations', function () { function mount () { @@ -56,85 +58,78 @@ describe('Webchat', function () { return new GOVUK.Webchat({ $el: $(this), location: '/government/organisations/hm-revenue-customs/contact/child-benefit' - }); - }); + }) + }) } it('should poll for availability', function () { - spyOn($, 'ajax'); - mount(); - expect($.ajax).toHaveBeenCalledWith({ - url: CHILD_BENEFIT_API_URL, - type: 'GET', - timeout: jasmine.any(Number), - success: jasmine.any(Function), - error: jasmine.any(Function) - }); - }); + spyOn($, 'ajax') + mount() + expect( + $.ajax + ).toHaveBeenCalledWith({ url: CHILD_BENEFIT_API_URL, type: 'GET', timeout: jasmine.any(Number), success: jasmine.any(Function), error: jasmine.any(Function) }) + }) it('should inform user whether advisors are available', function () { spyOn($, 'ajax').and.callFake(function (options) { - options.success(xmlResponseAvailable); - }); - mount(); - expect($advisersAvailable.hasClass('hidden')).toBe(false); + options.success(xmlResponseAvailable) + }) + mount() + expect($advisersAvailable.hasClass('hidden')).toBe(false) - expect($advisersBusy.hasClass('hidden')).toBe(true); - expect($advisersError.hasClass('hidden')).toBe(true); - expect($advisersUnavailable.hasClass('hidden')).toBe(true); - }); + expect($advisersBusy.hasClass('hidden')).toBe(true) + expect($advisersError.hasClass('hidden')).toBe(true) + expect($advisersUnavailable.hasClass('hidden')).toBe(true) + }) it('should inform user whether advisors are unavailable', function () { spyOn($, 'ajax').and.callFake(function (options) { - options.success(xmlResponseUnavailable); - }); - mount(); - expect($advisersUnavailable.hasClass('hidden')).toBe(false); + options.success(xmlResponseUnavailable) + }) + mount() + expect($advisersUnavailable.hasClass('hidden')).toBe(false) - expect($advisersAvailable.hasClass('hidden')).toBe(true); - expect($advisersBusy.hasClass('hidden')).toBe(true); - expect($advisersError.hasClass('hidden')).toBe(true); - }); + expect($advisersAvailable.hasClass('hidden')).toBe(true) + expect($advisersBusy.hasClass('hidden')).toBe(true) + expect($advisersError.hasClass('hidden')).toBe(true) + }) it('should inform user whether advisors are busy', function () { spyOn($, 'ajax').and.callFake(function (options) { - options.success(xmlResponseBusy); - }); - mount(); - expect($advisersBusy.hasClass('hidden')).toBe(false); + options.success(xmlResponseBusy) + }) + mount() + expect($advisersBusy.hasClass('hidden')).toBe(false) - expect($advisersAvailable.hasClass('hidden')).toBe(true); - expect($advisersError.hasClass('hidden')).toBe(true); - expect($advisersUnavailable.hasClass('hidden')).toBe(true); - }); + expect($advisersAvailable.hasClass('hidden')).toBe(true) + expect($advisersError.hasClass('hidden')).toBe(true) + expect($advisersUnavailable.hasClass('hidden')).toBe(true) + }) it('should inform user whether there was an error', function () { spyOn($, 'ajax').and.callFake(function (options) { - options.success(xmlResponseError); - }); - mount(); - expect($advisersError.hasClass('hidden')).toBe(false); + options.success(xmlResponseError) + }) + mount() + expect($advisersError.hasClass('hidden')).toBe(false) - expect($advisersAvailable.hasClass('hidden')).toBe(true); - expect($advisersBusy.hasClass('hidden')).toBe(true); - expect($advisersUnavailable.hasClass('hidden')).toBe(true); - }); - }); + expect($advisersAvailable.hasClass('hidden')).toBe(true) + expect($advisersBusy.hasClass('hidden')).toBe(true) + expect($advisersUnavailable.hasClass('hidden')).toBe(true) + }) + }) describe('on invalid locations', function () { function mount () { $webchat.map(function () { - return new GOVUK.Webchat({ - $el: $(this), - location: '/' - }); - }); + return new GOVUK.Webchat({ $el: $(this), location: '/' }) + }) } it('should not poll', function () { - spyOn($, 'ajax'); - mount(); - expect($.ajax).not.toHaveBeenCalled(); - }); - }); -}); + spyOn($, 'ajax') + mount() + expect($.ajax).not.toHaveBeenCalled() + }) + }) +}) From da9cf517de734dc6ed4f6f16789e63c7149e74b3 Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Tue, 21 Feb 2017 11:46:46 +0000 Subject: [PATCH 18/27] Update webchat markup to remove keep only what is needed --- app/views/content_items/contact.html.erb | 29 ++++++++++++------------ 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/app/views/content_items/contact.html.erb b/app/views/content_items/contact.html.erb index b278a38a4..4d01d0089 100644 --- a/app/views/content_items/contact.html.erb +++ b/app/views/content_items/contact.html.erb @@ -37,23 +37,24 @@ <% end %> <% if @content_item.show_webchat? %> -

Webchat

-
-
-

+

Webchat

+

+ + Webchat is unavailable at the moment because of technical problems. -

- - - -
-
+ + + +

<% end %> <% if @content_item.phone.any? %> From 836b1b5ac08d5ea1426a6908798185a3e6663e30 Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Thu, 23 Feb 2017 10:40:33 +0000 Subject: [PATCH 19/27] Remove unneeded presenter test --- test/presenters/contact_presenter_test.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/presenters/contact_presenter_test.rb b/test/presenters/contact_presenter_test.rb index b0821d567..2c7be2404 100644 --- a/test/presenters/contact_presenter_test.rb +++ b/test/presenters/contact_presenter_test.rb @@ -6,10 +6,6 @@ def format_name "contact" end - test 'presents the format' do - assert_equal schema_item['format'], presented_item.format - end - test 'presents the title' do assert_equal schema_item['title'], presented_item.title end From a208c975d8dad3c317a3438eb357d3e548e5d4f2 Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Thu, 23 Feb 2017 10:54:36 +0000 Subject: [PATCH 20/27] Update presenter tests so they're DRYer --- test/presenters/contact_presenter_test.rb | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/test/presenters/contact_presenter_test.rb b/test/presenters/contact_presenter_test.rb index 2c7be2404..c816c3c39 100644 --- a/test/presenters/contact_presenter_test.rb +++ b/test/presenters/contact_presenter_test.rb @@ -43,12 +43,14 @@ def format_name end test 'phone returns correctly' do - assert_equal schema_item['details']['phone_numbers'][0]["number"], presented_item.phone[0][:numbers][0][:number] - assert_equal schema_item['details']['phone_numbers'][0]["textphone"].blank?, presented_item.phone[0][:numbers][0][:textphone].nil? - assert_equal schema_item['details']['phone_numbers'][0]["title"], presented_item.phone[0][:title] - assert_equal schema_item['details']['phone_numbers'][0]["description"].strip, presented_item.phone[0][:description] - assert_equal schema_item['details']['phone_numbers'][0]["open_hours"].strip, presented_item.phone[0][:opening_times] - assert_equal schema_item['details']['phone_numbers'][0]["best_time_to_call"].strip, presented_item.phone[0][:best_time_to_call] + phone_number = schema_item['details']['phone_numbers'][0] + presented_phone_number = presented_item.phone[0] + assert_equal phone_number["number"], presented_phone_number[:numbers][0][:number] + assert_equal phone_number["textphone"].blank?, presented_phone_number[:numbers][0][:textphone].nil? + assert_equal phone_number["title"], presented_phone_number[:title] + assert_equal phone_number["description"].strip, presented_phone_number[:description] + assert_equal phone_number["open_hours"].strip, presented_phone_number[:opening_times] + assert_equal phone_number["best_time_to_call"].strip, presented_phone_number[:best_time_to_call] end test 'phone_body returns correctly' do @@ -56,9 +58,11 @@ def format_name end test 'post' do - assert_equal schema_item['details']['post_addresses'][0]['description'].strip, presented_item.post[0][:description] - assert_equal schema_item['details']['post_addresses'][0]['title'].strip, presented_item.post[0][:v_card][0][:value] - assert_equal presented_item.post[0][:v_card][0][:v_card_class], 'fn' + post_address = schema_item['details']['post_addresses'][0] + presented_post_address = presented_item.post[0] + assert_equal post_address['description'].strip, presented_post_address[:description] + assert_equal post_address['title'].strip, presented_post_address[:v_card][0][:value] + assert_equal 'fn', presented_post_address[:v_card][0][:v_card_class] end test 'post_body returns correctly' do From c335ad50ab238b721839e243126bc867ffd19ee0 Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Mon, 27 Feb 2017 15:26:04 +0000 Subject: [PATCH 21/27] Update test so they're plural and consistent --- test/integration/contact_test.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/integration/contact_test.rb b/test/integration/contact_test.rb index e680c462a..15dbb4ef9 100644 --- a/test/integration/contact_test.rb +++ b/test/integration/contact_test.rb @@ -41,8 +41,7 @@ class ContactTest < ActionDispatch::IntegrationTest end end - - test "post are rendered" do + test "posts are rendered" do setup_and_visit_content_item('contact') within_component_govspeak do |component_args| content = component_args.fetch("content") From 11328511df4cd6306e3af18caed4b43b26cd590a Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Mon, 27 Feb 2017 15:27:47 +0000 Subject: [PATCH 22/27] Add test to check related links are rendered --- test/integration/contact_test.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/integration/contact_test.rb b/test/integration/contact_test.rb index 15dbb4ef9..9b170355f 100644 --- a/test/integration/contact_test.rb +++ b/test/integration/contact_test.rb @@ -51,4 +51,17 @@ class ContactTest < ActionDispatch::IntegrationTest assert_not_nil html.at_css(".street-address") end end + + test "related links are rendered" do + setup_and_visit_content_item('contact') + within shared_component_selector("related_items") do + quick_links = @content_item["details"]["quick_links"] + assert_equal quick_links, JSON.parse(page.text).fetch("sections").first["items"] + + first_related_contacts_links = @content_item["links"]["related"].first + first_parsed_related_contacts_links = JSON.parse(page.text).fetch("sections").last["items"].first + assert_equal first_related_contacts_links["title"], first_parsed_related_contacts_links["title"] + assert_equal first_related_contacts_links["base_path"], first_parsed_related_contacts_links["url"] + end + end end From 01f0a7b5731495ee659ac9977759130162dd0f4c Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Mon, 27 Feb 2017 15:28:06 +0000 Subject: [PATCH 23/27] Add note in tests on how to check what's rendered --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 913c983b4..cf26badaf 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,11 @@ Or to specify the location explicitly: `GOVUK_CONTENT_SCHEMAS_PATH=/some/dir/govuk-content-schemas bundle exec rake` +#### Debugging Integration tests +If you want to see the page that is being tested in our integration tests, you can use +`save_and_open_page` to see what's rendered. This is helpful when a page is mostly comprised of +GOV.UK Publishing Components + ### Visual regression tests Use [Wraith](http://bbc-news.github.io/wraith/) ("A responsive screenshot From 640dac1cc1b039e4b14cd7dd669536d7be39687c Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Mon, 27 Feb 2017 15:57:01 +0000 Subject: [PATCH 24/27] Conditionally load Webchat only when it's needed --- app/assets/javascripts/application.js | 14 +- app/assets/javascripts/modules/webchat.js | 151 ++++++++++++++++++++ app/assets/javascripts/webchat.js | 163 ++-------------------- app/views/content_items/contact.html.erb | 18 +-- app/views/shared/_webchat.html.erb | 17 +++ config/initializers/assets.rb | 1 + spec/javascripts/support/jasmine.yml | 3 +- 7 files changed, 186 insertions(+), 181 deletions(-) create mode 100644 app/assets/javascripts/modules/webchat.js create mode 100644 app/views/shared/_webchat.html.erb diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index a3ea0f8a0..fe4e88144 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -1,15 +1,3 @@ /* eslint-disable */ -//= require_tree ./modules -//= require webchat.js +//= require ./modules/track-share-button-clicks.js /*eslint-enable */ - -var $ = window.$ - -$(document).ready(function () { - var GOVUK = window.GOVUK - if (GOVUK.Webchat) { - $('.js-webchat').map(function () { - return new GOVUK.Webchat({ $el: $(this) }) - }) - } -}) diff --git a/app/assets/javascripts/modules/webchat.js b/app/assets/javascripts/modules/webchat.js new file mode 100644 index 000000000..449f3b6a2 --- /dev/null +++ b/app/assets/javascripts/modules/webchat.js @@ -0,0 +1,151 @@ +(function (global) { + 'use strict' + var $ = global.jQuery + var windowLocationPathname = global.location.pathname + var windowOpen = global.open + if (typeof global.GOVUK === 'undefined') { global.GOVUK = {} } + var GOVUK = global.GOVUK + + // Each page will have a different entryPointID, which is a queue id. + // Don't enable this plugin on pages that don't exist in this map, and + // uncomment the additional routes as we obtain them. + // Whether the actual template is displayed is in `contact_presenter#show_webchat?`. + var entryPointIDs = {} + entryPointIDs['/government/organisations/hm-revenue-customs/contact/child-benefit'] = 1027 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/income-tax-enquiries-for-individuals-pensioners-and-employees'] = 1030 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/vat-online-services-helpdesk'] = 1026 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/national-insurance-numbers'] = 1021 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/self-assessment-online-services-helpdesk'] = 1003 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/self-assessment'] = 1004 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/tax-credits-enquiries'] = 1016 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/vat-enquiries'] = 1028 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/customs-international-trade-and-excise-enquiries'] = 1034 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/trusts'] = 1036 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/employer-enquiries'] = 1023 + entryPointIDs['/government/organisations/hm-revenue-customs/contact/construction-industry-scheme'] = 1048 + + var API_URL = 'https://online.hmrc.gov.uk/webchatprod/egain/chat/entrypoint/checkEligibility/' + var OPEN_CHAT_URL = function (entryPointID) { + return 'https://online.hmrc.gov.uk/webchatprod/templates/chat/hmrc7/chat.html?entryPointId=' + entryPointID + '&templateName=hmrc7&languageCode=en&countryCode=US&ver=v11' + } + var CODE_AGENTS_AVAILABLE = 0 + var CODE_AGENTS_UNAVAILABLE = 1 + var CODE_AGENTS_BUSY = 2 + var POLL_INTERVAL = 15 * 1000 + var AJAX_TIMEOUT = 5 * 1000 + + function Webchat (options) { + var $el = $(options.$el) + var location = options.location || windowLocationPathname + + var $advisersUnavailable = $el.find('.js-webchat-advisers-unavailable') + var $advisersBusy = $el.find('.js-webchat-advisers-busy') + var $advisersAvailable = $el.find('.js-webchat-advisers-available') + var $advisersError = $el.find('.js-webchat-advisers-error') + var $openButton = $el.find('.js-webchat-open-button') + + var entryPointID = entryPointIDs[location] + var pollingEnabled = true + + if (entryPointID) { + pollAvailability() + + $openButton.on('click', handleOpenChat) + } + + function pollAvailability () { + checkAvailability() + + setTimeout(function () { + if (pollingEnabled) { + pollAvailability() + } + }, POLL_INTERVAL) + } + + function checkAvailability () { + $.ajax({ + url: API_URL + entryPointID, + type: 'GET', + timeout: AJAX_TIMEOUT, + success: handleApiCallSuccess, + error: handleApiCallError + }) + } + + function handleApiCallSuccess (result) { + var $xml = $(result) + var response = parseInt($xml.find('checkEligibility').attr('responseType'), 10) + + switch (response) { + case CODE_AGENTS_UNAVAILABLE: + handleAdvisersUnavailable() + break + case CODE_AGENTS_BUSY: + handleAdvisersBusy() + break + case CODE_AGENTS_AVAILABLE: + handleAdvisersAvailable() + break + default: + handleApiCallError() + break + } + } + + function handleApiCallError () { + pollingEnabled = false + handleAdvisersError() + } + + function handleOpenChat (evt) { + evt.preventDefault() + var url = OPEN_CHAT_URL(entryPointID) + windowOpen(url, 'newwin', 'width=200,height=100') + + GOVUK.analytics.trackEvent('webchat', 'accepted') + } + + function handleAdvisersError () { + $advisersError.removeClass('hidden') + + $advisersAvailable.addClass('hidden') + $advisersBusy.addClass('hidden') + $advisersUnavailable.addClass('hidden') + + GOVUK.analytics.trackEvent('webchat', 'error') + } + + function handleAdvisersUnavailable () { + $advisersUnavailable.removeClass('hidden') + + $advisersAvailable.addClass('hidden') + $advisersBusy.addClass('hidden') + $advisersError.addClass('hidden') + + GOVUK.analytics.trackEvent('webchat', 'unavailable') + } + + function handleAdvisersBusy () { + $advisersBusy.removeClass('hidden') + + $advisersUnavailable.addClass('hidden') + $advisersAvailable.addClass('hidden') + $advisersError.addClass('hidden') + + GOVUK.analytics.trackEvent('webchat', 'busy') + } + + function handleAdvisersAvailable () { + $advisersAvailable.removeClass('hidden') + + $advisersBusy.addClass('hidden') + $advisersError.addClass('hidden') + $advisersUnavailable.addClass('hidden') + + GOVUK.analytics.trackEvent('webchat', 'offered') + } + } + + GOVUK.Webchat = Webchat +})(window) diff --git a/app/assets/javascripts/webchat.js b/app/assets/javascripts/webchat.js index 449f3b6a2..5d44e3847 100644 --- a/app/assets/javascripts/webchat.js +++ b/app/assets/javascripts/webchat.js @@ -1,151 +1,14 @@ -(function (global) { - 'use strict' - var $ = global.jQuery - var windowLocationPathname = global.location.pathname - var windowOpen = global.open - if (typeof global.GOVUK === 'undefined') { global.GOVUK = {} } - var GOVUK = global.GOVUK - - // Each page will have a different entryPointID, which is a queue id. - // Don't enable this plugin on pages that don't exist in this map, and - // uncomment the additional routes as we obtain them. - // Whether the actual template is displayed is in `contact_presenter#show_webchat?`. - var entryPointIDs = {} - entryPointIDs['/government/organisations/hm-revenue-customs/contact/child-benefit'] = 1027 - entryPointIDs['/government/organisations/hm-revenue-customs/contact/income-tax-enquiries-for-individuals-pensioners-and-employees'] = 1030 - entryPointIDs['/government/organisations/hm-revenue-customs/contact/vat-online-services-helpdesk'] = 1026 - entryPointIDs['/government/organisations/hm-revenue-customs/contact/national-insurance-numbers'] = 1021 - entryPointIDs['/government/organisations/hm-revenue-customs/contact/self-assessment-online-services-helpdesk'] = 1003 - entryPointIDs['/government/organisations/hm-revenue-customs/contact/self-assessment'] = 1004 - entryPointIDs['/government/organisations/hm-revenue-customs/contact/tax-credits-enquiries'] = 1016 - entryPointIDs['/government/organisations/hm-revenue-customs/contact/vat-enquiries'] = 1028 - entryPointIDs['/government/organisations/hm-revenue-customs/contact/customs-international-trade-and-excise-enquiries'] = 1034 - entryPointIDs['/government/organisations/hm-revenue-customs/contact/trusts'] = 1036 - entryPointIDs['/government/organisations/hm-revenue-customs/contact/employer-enquiries'] = 1023 - entryPointIDs['/government/organisations/hm-revenue-customs/contact/construction-industry-scheme'] = 1048 - - var API_URL = 'https://online.hmrc.gov.uk/webchatprod/egain/chat/entrypoint/checkEligibility/' - var OPEN_CHAT_URL = function (entryPointID) { - return 'https://online.hmrc.gov.uk/webchatprod/templates/chat/hmrc7/chat.html?entryPointId=' + entryPointID + '&templateName=hmrc7&languageCode=en&countryCode=US&ver=v11' +/* eslint-disable */ +//= require ./modules/webchat.js +/*eslint-enable */ + +var $ = window.$ + +$(document).ready(function () { + var GOVUK = window.GOVUK + if (GOVUK.Webchat) { + $('.js-webchat').map(function () { + return new GOVUK.Webchat({ $el: $(this) }) + }) } - var CODE_AGENTS_AVAILABLE = 0 - var CODE_AGENTS_UNAVAILABLE = 1 - var CODE_AGENTS_BUSY = 2 - var POLL_INTERVAL = 15 * 1000 - var AJAX_TIMEOUT = 5 * 1000 - - function Webchat (options) { - var $el = $(options.$el) - var location = options.location || windowLocationPathname - - var $advisersUnavailable = $el.find('.js-webchat-advisers-unavailable') - var $advisersBusy = $el.find('.js-webchat-advisers-busy') - var $advisersAvailable = $el.find('.js-webchat-advisers-available') - var $advisersError = $el.find('.js-webchat-advisers-error') - var $openButton = $el.find('.js-webchat-open-button') - - var entryPointID = entryPointIDs[location] - var pollingEnabled = true - - if (entryPointID) { - pollAvailability() - - $openButton.on('click', handleOpenChat) - } - - function pollAvailability () { - checkAvailability() - - setTimeout(function () { - if (pollingEnabled) { - pollAvailability() - } - }, POLL_INTERVAL) - } - - function checkAvailability () { - $.ajax({ - url: API_URL + entryPointID, - type: 'GET', - timeout: AJAX_TIMEOUT, - success: handleApiCallSuccess, - error: handleApiCallError - }) - } - - function handleApiCallSuccess (result) { - var $xml = $(result) - var response = parseInt($xml.find('checkEligibility').attr('responseType'), 10) - - switch (response) { - case CODE_AGENTS_UNAVAILABLE: - handleAdvisersUnavailable() - break - case CODE_AGENTS_BUSY: - handleAdvisersBusy() - break - case CODE_AGENTS_AVAILABLE: - handleAdvisersAvailable() - break - default: - handleApiCallError() - break - } - } - - function handleApiCallError () { - pollingEnabled = false - handleAdvisersError() - } - - function handleOpenChat (evt) { - evt.preventDefault() - var url = OPEN_CHAT_URL(entryPointID) - windowOpen(url, 'newwin', 'width=200,height=100') - - GOVUK.analytics.trackEvent('webchat', 'accepted') - } - - function handleAdvisersError () { - $advisersError.removeClass('hidden') - - $advisersAvailable.addClass('hidden') - $advisersBusy.addClass('hidden') - $advisersUnavailable.addClass('hidden') - - GOVUK.analytics.trackEvent('webchat', 'error') - } - - function handleAdvisersUnavailable () { - $advisersUnavailable.removeClass('hidden') - - $advisersAvailable.addClass('hidden') - $advisersBusy.addClass('hidden') - $advisersError.addClass('hidden') - - GOVUK.analytics.trackEvent('webchat', 'unavailable') - } - - function handleAdvisersBusy () { - $advisersBusy.removeClass('hidden') - - $advisersUnavailable.addClass('hidden') - $advisersAvailable.addClass('hidden') - $advisersError.addClass('hidden') - - GOVUK.analytics.trackEvent('webchat', 'busy') - } - - function handleAdvisersAvailable () { - $advisersAvailable.removeClass('hidden') - - $advisersBusy.addClass('hidden') - $advisersError.addClass('hidden') - $advisersUnavailable.addClass('hidden') - - GOVUK.analytics.trackEvent('webchat', 'offered') - } - } - - GOVUK.Webchat = Webchat -})(window) +}) diff --git a/app/views/content_items/contact.html.erb b/app/views/content_items/contact.html.erb index 4d01d0089..1bd2997ba 100644 --- a/app/views/content_items/contact.html.erb +++ b/app/views/content_items/contact.html.erb @@ -38,23 +38,7 @@ <% if @content_item.show_webchat? %>

Webchat

-

- - - Webchat is unavailable at the moment because of technical problems. - - - - - -

+

<%= render 'shared/webchat' %>

<% end %> <% if @content_item.phone.any? %> diff --git a/app/views/shared/_webchat.html.erb b/app/views/shared/_webchat.html.erb new file mode 100644 index 000000000..f99906dcf --- /dev/null +++ b/app/views/shared/_webchat.html.erb @@ -0,0 +1,17 @@ + + + Webchat is unavailable at the moment because of technical problems. + + + + + +<% # This is inline in the source however slimmer will optimize this. %> +<%= javascript_include_tag "webchat" %> diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 4a0b62850..bf9b3c716 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -12,4 +12,5 @@ application-ie6.css application-ie7.css application-ie8.css + webchat.js ) diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml index 9839028c9..365cdb0b4 100644 --- a/spec/javascripts/support/jasmine.yml +++ b/spec/javascripts/support/jasmine.yml @@ -20,7 +20,8 @@ src_files: - "../../../spec/javascripts/helpers/jquery-1.12.4.js" - "../../../spec/javascripts/helpers/jasmine-jquery-2.0.5.js" - "../../../spec/javascripts/helpers/cookie-functions.js" - - "application.{js.coffee,js,coffee}" + - "application.js" + - "webchat.js" # list of file expressions to include as css files # relative path from css_dir From 358c89527c10fe0f5bc1e472c3e12da48810e53b Mon Sep 17 00:00:00 2001 From: Andrew Hilton Date: Wed, 1 Mar 2017 11:45:44 +0000 Subject: [PATCH 25/27] Remove unneeded cookie-functions as pointed out by @fofr these are not needed --- spec/javascripts/helpers/cookie-functions.js | 61 -------------------- spec/javascripts/support/jasmine.yml | 1 - 2 files changed, 62 deletions(-) delete mode 100644 spec/javascripts/helpers/cookie-functions.js diff --git a/spec/javascripts/helpers/cookie-functions.js b/spec/javascripts/helpers/cookie-functions.js deleted file mode 100644 index c5eb09199..000000000 --- a/spec/javascripts/helpers/cookie-functions.js +++ /dev/null @@ -1,61 +0,0 @@ -(function () { - "use strict" - var root = this; - if(typeof root.GOVUK === 'undefined') { root.GOVUK = {}; } - - /* - Cookie methods - ============== - - Usage: - - Setting a cookie: - GOVUK.cookie('hobnob', 'tasty', { days: 30 }); - - Reading a cookie: - GOVUK.cookie('hobnob'); - - Deleting a cookie: - GOVUK.cookie('hobnob', null); - */ - GOVUK.cookie = function (name, value, options) { - if(typeof value !== 'undefined'){ - if(value === false || value === null) { - return GOVUK.setCookie(name, '', { days: -1 }); - } else { - return GOVUK.setCookie(name, value, options); - } - } else { - return GOVUK.getCookie(name); - } - }; - GOVUK.setCookie = function (name, value, options) { - if(typeof options === 'undefined') { - options = {}; - } - var cookieString = name + "=" + value + "; path=/"; - if (options.days) { - var date = new Date(); - date.setTime(date.getTime() + (options.days * 24 * 60 * 60 * 1000)); - cookieString = cookieString + "; expires=" + date.toGMTString(); - } - if (document.location.protocol == 'https:'){ - cookieString = cookieString + "; Secure"; - } - document.cookie = cookieString; - }; - GOVUK.getCookie = function (name) { - var nameEQ = name + "="; - var cookies = document.cookie.split(';'); - for(var i = 0, len = cookies.length; i < len; i++) { - var cookie = cookies[i]; - while (cookie.charAt(0) == ' ') { - cookie = cookie.substring(1, cookie.length); - } - if (cookie.indexOf(nameEQ) === 0) { - return decodeURIComponent(cookie.substring(nameEQ.length)); - } - } - return null; - }; -}).call(this); diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml index 365cdb0b4..7d3ea60e4 100644 --- a/spec/javascripts/support/jasmine.yml +++ b/spec/javascripts/support/jasmine.yml @@ -19,7 +19,6 @@ css_dir: "app/assets/stylesheets" src_files: - "../../../spec/javascripts/helpers/jquery-1.12.4.js" - "../../../spec/javascripts/helpers/jasmine-jquery-2.0.5.js" - - "../../../spec/javascripts/helpers/cookie-functions.js" - "application.js" - "webchat.js" From 7070caa6ea46b822e50562ec5297ce89ec691d43 Mon Sep 17 00:00:00 2001 From: Andrew Hilton Date: Wed, 1 Mar 2017 11:56:38 +0000 Subject: [PATCH 26/27] Move webchat to a legacy module folder webchat is a legacy module that is not written in the standard GOV.UK module pattern. This module is going to be looked at being rewritten in firebreak. while just calling it legacy and been done with it is not ideal, we are looking at it in short order. Also add contacts to readme and revert the change to application.js back to just include the modules directory --- README.md | 1 + app/assets/javascripts/application.js | 4 +--- app/assets/javascripts/{modules => legacy-modules}/webchat.js | 0 app/assets/javascripts/webchat.js | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) rename app/assets/javascripts/{modules => legacy-modules}/webchat.js (100%) diff --git a/README.md b/README.md index cf26badaf..ca3d272fd 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Not all formats that this app can handle are rendered by it in production. | Case study | [View on GOV.UK](https://www.gov.uk/government/case-studies/2013-elections-in-swaziland) | Migrated | | Coming soon | | Rendered by Whitehall | | Consultation | [View on GOV.UK](https://www.gov.uk/government/consultations/soft-drinks-industry-levy) | Migrated | +| contacts | [View on GOV.UK](https://www.gov.uk/government/organisations/hm-revenue-customs/contact/alcohol-duties-national-registration-unit) | Currently rendered by Contacts frontend | | Detailed guide | [View on GOV.UK](https://www.gov.uk/guidance/waste-exemption-nwfd-2-temporary-storage-at-the-place-of-production--2) | Migrated | | Document collection | [View on GOV.UK](https://www.gov.uk/government/collections/statutory-guidance-schools) | Migrated on live. Draft rendered by Whitehall. | | Fatality notice | [View on GOV.UK](https://www.gov.uk/government/fatalities/corporal-lee-churcher-dies-in-iraq) | Migrated | diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index fe4e88144..079e5abc2 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -1,3 +1 @@ -/* eslint-disable */ -//= require ./modules/track-share-button-clicks.js -/*eslint-enable */ +//= require_tree ./modules diff --git a/app/assets/javascripts/modules/webchat.js b/app/assets/javascripts/legacy-modules/webchat.js similarity index 100% rename from app/assets/javascripts/modules/webchat.js rename to app/assets/javascripts/legacy-modules/webchat.js diff --git a/app/assets/javascripts/webchat.js b/app/assets/javascripts/webchat.js index 5d44e3847..914aa501b 100644 --- a/app/assets/javascripts/webchat.js +++ b/app/assets/javascripts/webchat.js @@ -1,5 +1,5 @@ /* eslint-disable */ -//= require ./modules/webchat.js +//= require ./legacy-modules/webchat.js /*eslint-enable */ var $ = window.$ From b646ef2b4872c920ecd12441ea889d53b13a84eb Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Thu, 2 Mar 2017 13:29:37 +0000 Subject: [PATCH 27/27] Capitialise contacts so it's consistent --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca3d272fd..606851b89 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Not all formats that this app can handle are rendered by it in production. | Case study | [View on GOV.UK](https://www.gov.uk/government/case-studies/2013-elections-in-swaziland) | Migrated | | Coming soon | | Rendered by Whitehall | | Consultation | [View on GOV.UK](https://www.gov.uk/government/consultations/soft-drinks-industry-levy) | Migrated | -| contacts | [View on GOV.UK](https://www.gov.uk/government/organisations/hm-revenue-customs/contact/alcohol-duties-national-registration-unit) | Currently rendered by Contacts frontend | +| Contacts | [View on GOV.UK](https://www.gov.uk/government/organisations/hm-revenue-customs/contact/alcohol-duties-national-registration-unit) | Currently rendered by Contacts frontend | | Detailed guide | [View on GOV.UK](https://www.gov.uk/guidance/waste-exemption-nwfd-2-temporary-storage-at-the-place-of-production--2) | Migrated | | Document collection | [View on GOV.UK](https://www.gov.uk/government/collections/statutory-guidance-schools) | Migrated on live. Draft rendered by Whitehall. | | Fatality notice | [View on GOV.UK](https://www.gov.uk/government/fatalities/corporal-lee-churcher-dies-in-iraq) | Migrated |