test(faqs): service & controller specs
This commit is contained in:
parent
d05aee0c67
commit
21507cf524
2 changed files with 151 additions and 0 deletions
65
spec/controllers/faq_controller_spec.rb
Normal file
65
spec/controllers/faq_controller_spec.rb
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
RSpec.describe FAQController, type: :controller do
|
||||||
|
describe "GET #index" do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
it "displays titles and render links for all entries" do
|
||||||
|
get :index
|
||||||
|
|
||||||
|
# Usager
|
||||||
|
expect(response.body).to include("Gestion de mon compte")
|
||||||
|
expect(response.body).to include("Je veux changer mon adresse email")
|
||||||
|
expect(response.body).to include(faq_path(category: "usager", slug: "je-veux-changer-mon-adresse-email"))
|
||||||
|
|
||||||
|
# Instructeur
|
||||||
|
expect(response.body).to include("Je dois confirmer mon compte à chaque connexion")
|
||||||
|
|
||||||
|
# Instructeur
|
||||||
|
expect(response.body).to include("Les blocs répétables")
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with invalid subcategory" do
|
||||||
|
before do
|
||||||
|
service = instance_double(FAQsLoaderService, all: faqs)
|
||||||
|
allow(FAQsLoaderService).to receive(:new).and_return(service)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:faqs) do
|
||||||
|
{
|
||||||
|
'usager' => {
|
||||||
|
'oops' => [{ category: 'usager', subcategory: 'oops', title: 'FAQ Title 1', slug: 'faq1' }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "fails so we can't make a typo and publish non translated subcategories" do
|
||||||
|
expect { get :index }.to raise_error(ActionView::Template::Error)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "GET #show" do
|
||||||
|
before do
|
||||||
|
allow(Current).to receive(:application_name).and_return('demarches.gouv.fr')
|
||||||
|
end
|
||||||
|
|
||||||
|
render_views
|
||||||
|
|
||||||
|
context "when the FAQ exists" do
|
||||||
|
it "renders the show template with the FAQ content and metadata" do
|
||||||
|
get :show, params: { category: 'usager', slug: 'je-veux-changer-mon-adresse-email' }
|
||||||
|
expect(response.body).to include('Si vous disposez d’un compte usager sur demarches.gouv.fr')
|
||||||
|
|
||||||
|
# link to siblings
|
||||||
|
expect(response.body).to include(faq_path(category: 'usager', slug: 'je-veux-changer-mon-mot-de-passe'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when the FAQ does not exist" do
|
||||||
|
it "raises a routing error for a missing FAQ" do
|
||||||
|
expect {
|
||||||
|
get :show, params: { category: 'nonexistent', slug: 'nofaq' }
|
||||||
|
}.to raise_error(ActionController::RoutingError)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
86
spec/services/faqs_loader_service_spec.rb
Normal file
86
spec/services/faqs_loader_service_spec.rb
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe FAQsLoaderService do
|
||||||
|
let(:substitutions) { { application_name: "demarches.gouv.fr", application_base_url: APPLICATION_BASE_URL, contact_email: CONTACT_EMAIL } }
|
||||||
|
let(:service) { FAQsLoaderService.new(substitutions) }
|
||||||
|
|
||||||
|
context "behavior with stubbed markdown files" do
|
||||||
|
before do
|
||||||
|
allow(Dir).to receive(:glob).and_return(['path/to/faq1.md', 'path/to/faq2.md'])
|
||||||
|
|
||||||
|
# Mock File.read calls to fake md files
|
||||||
|
# but call original otherwise (rspec or debuggning uses File.read to load some files)
|
||||||
|
allow(File).to receive(:read).and_wrap_original do |original_method, *args|
|
||||||
|
case args.first
|
||||||
|
when 'path/to/faq1.md'
|
||||||
|
<<~MD
|
||||||
|
---
|
||||||
|
title: FAQ1
|
||||||
|
slug: faq1
|
||||||
|
category: usager
|
||||||
|
subcategory: account
|
||||||
|
---
|
||||||
|
Welcome to %{application_name}
|
||||||
|
MD
|
||||||
|
when 'path/to/faq2.md'
|
||||||
|
<<~MD
|
||||||
|
---
|
||||||
|
title: FAQ2
|
||||||
|
slug: faq2
|
||||||
|
category: admin
|
||||||
|
subcategory: general
|
||||||
|
---
|
||||||
|
This is for %{application_base_url}
|
||||||
|
MD
|
||||||
|
else
|
||||||
|
original_method.call(*args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#find' do
|
||||||
|
it 'returns a file with variable substitutions' do
|
||||||
|
expect(service.find('usager/faq1').content).to include('Welcome to demarches.gouv.fr')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#all' do
|
||||||
|
it 'returns all FAQs' do
|
||||||
|
expect(service.all).to eq({
|
||||||
|
"usager" => { "account" => [{ category: "usager", file_path: "path/to/faq1.md", slug: "faq1", subcategory: "account", title: "FAQ1" }] },
|
||||||
|
"admin" => { "general" => [{ category: "admin", file_path: "path/to/faq2.md", slug: "faq2", subcategory: "general", title: "FAQ2" }] }
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#faqs_for_category' do
|
||||||
|
it 'returns FAQs grouped by subcategory for a given category' do
|
||||||
|
result = service.faqs_for_category('usager')
|
||||||
|
expect(result).to eq({
|
||||||
|
'account' => [{ category: 'usager', subcategory: 'account', title: 'FAQ1', slug: 'faq1', file_path: 'path/to/faq1.md' }]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'caching' do
|
||||||
|
it 'works', caching: true do
|
||||||
|
2.times {
|
||||||
|
service = FAQsLoaderService.new(substitutions)
|
||||||
|
service.all
|
||||||
|
expect(Dir).to have_received(:glob).once
|
||||||
|
}
|
||||||
|
|
||||||
|
# depends on substitutions
|
||||||
|
service = FAQsLoaderService.new(substitutions.merge(application_name: "other name"))
|
||||||
|
service.all
|
||||||
|
expect(Dir).to have_received(:glob).twice
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with actual files" do
|
||||||
|
it 'load, perform substitutions and returns all FAQs' do
|
||||||
|
expect(service.all.keys).to match_array(["administrateur", "instructeur", "usager"])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue