Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

HMRC-447 Implement SPIMM FAQ Feedback Functionality #2047

Merged
merged 13 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ RUN rm -rf node_modules log tmp && \
# Build runtime image
FROM ruby:3.3.6-alpine3.20 as production

# Install PostgreSQL client tools
RUN apk add --no-cache postgresql-client

RUN apk add --update --no-cache postgresql-dev curl shared-mime-info tzdata && \
cp /usr/share/zoneinfo/Europe/London /etc/localtime && \
echo "Europe/London" > /etc/timezone
Expand Down
47 changes: 47 additions & 0 deletions app/controllers/api/admin/green_lanes/faq_feedback_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module Api
module Admin
module GreenLanes
class FaqFeedbackController < AdminController
# before_action :authenticate_user!

def create
faq_feedback = ::GreenLanes::FaqFeedback.new(faq_feedback_params)
Rails.logger.info("FAQ feedback valid?: #{faq_feedback.valid?}")
if faq_feedback.valid? && faq_feedback.save
Rails.logger.info("FAQ feedback created: #{faq_feedback.id}")
render json: serialize(faq_feedback),
location: api_green_lanes_faq_feedback_url(faq_feedback.id),
status: :created
else
render json: serialize_errors(faq_feedback),
status: :unprocessable_entity
end
end

def index
faq_feedback = ::GreenLanes::FaqFeedback.all
render json: serialize(faq_feedback)
end

private

def faq_feedback_params
params.require(:data).require(:attributes).permit(
:session_id,
:category_id,
:question_id,
:useful,
)
end

def serialize(*args)
Api::Admin::GreenLanes::FaqFeedbackSerializer.new(*args).serializable_hash
end

def serialize_errors(exemption)
Api::Admin::ErrorSerializationService.new(exemption).call
end
end
end
end
end
12 changes: 12 additions & 0 deletions app/models/green_lanes/faq_feedback.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module GreenLanes
class FaqFeedback < Sequel::Model(:green_lanes_faq_feedback)
plugin :timestamps, update_on_create: true
plugin :auto_validations, not_null: :presence

# Ensure uniqueness of the composite key
def validate
super
validates_unique(%i[session_id category_id question_id])
end
end
end
18 changes: 18 additions & 0 deletions app/serializers/api/admin/green_lanes/faq_feedback_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module Api
module Admin
module GreenLanes
class FaqFeedbackSerializer
include JSONAPI::Serializer

set_type :green_lanes_faq_feedback

set_id :id

attributes :session_id,
:category_id,
:question_id,
:useful
end
end
end
end
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@
resources :category_assessments, only: %i[index]

resources :themes, only: %i[index]

resources :faq_feedback, only: %i[create index show], controller: '/api/admin/green_lanes/faq_feedback'
end
end

Expand Down
18 changes: 10 additions & 8 deletions db/migrate/20241210100900_add_green_lanes_faq_feedback_table.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

Sequel.migration do
change do
create_table :green_lanes_faq_feedback do
primary_key :id
String :session_id, null: false
Integer :category_id, null: false
Integer :question_id, null: false
Boolean :useful, null: false
DateTime :created_at
DateTime :updated_at
unless table_exists?(:green_lanes_faq_feedback)
create_table :green_lanes_faq_feedback do
primary_key :id
String :session_id, null: false
Integer :category_id, null: false
Integer :question_id, null: false
Boolean :useful, null: false
DateTime :created_at
DateTime :updated_at
end
end

alter_table :green_lanes_faq_feedback do
Expand Down
8 changes: 8 additions & 0 deletions spec/factories/green_lanes/faq_feedback_factory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FactoryBot.define do
factory :green_lanes_faq_feedback, class: 'GreenLanes::FaqFeedback' do
session_id { SecureRandom.uuid }
category_id { 1 }
question_id { 1 }
useful { true }
end
end
34 changes: 34 additions & 0 deletions spec/models/green_lanes/faq_feedback_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
RSpec.describe GreenLanes::FaqFeedback do
describe 'attributes' do
it { is_expected.to respond_to :session_id }
it { is_expected.to respond_to :category_id }
it { is_expected.to respond_to :question_id }
it { is_expected.to respond_to :useful }
end

describe 'validations' do
subject(:errors) { instance.tap(&:valid?).errors }

let(:instance) { described_class.new }

it { is_expected.to include session_id: ['is not present'] }
it { is_expected.to include category_id: ['is not present'] }
it { is_expected.to include question_id: ['is not present'] }
it { is_expected.to include useful: ['is not present'] }

context 'with duplicate entry' do
let(:session_id) { SecureRandom.uuid }
let(:category_id) { 1 }
let(:question_id) { 1 }

before do
create(:green_lanes_faq_feedback, session_id:, category_id:, question_id:)
end

it 'fails validation' do
duplicate = build(:green_lanes_faq_feedback, session_id:, category_id:, question_id:)
expect(duplicate.valid?).to be false
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
RSpec.describe Api::Admin::GreenLanes::FaqFeedbackController do
subject(:page_response) { make_request && response }

let(:json_response) { JSON.parse(page_response.body) }
let(:faq_feedback) { create :green_lanes_faq_feedback }

describe 'POST to #create' do
let(:make_request) do
authenticated_post api_green_lanes_faq_feedback_index_path(format: :json), params: faq_feedback_data
end
let :faq_feedback_data do
{
data: {
type: :green_lanes_faq_feedback,
attributes: ex_attrs,
},
}
end

context 'with valid params' do
let(:ex_attrs) { build(:green_lanes_faq_feedback).to_hash }

it { is_expected.to have_http_status :created }
it { is_expected.to have_attributes location: api_green_lanes_faq_feedback_url(GreenLanes::FaqFeedback.last.id) }
end

context 'with invalid params' do
let(:ex_attrs) { build(:green_lanes_faq_feedback, session_id: nil).to_hash }

it { is_expected.to have_http_status :unprocessable_entity }

it 'returns errors for faq_feedback' do
expect(json_response).to include('errors')
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
RSpec.describe Api::Admin::GreenLanes::FaqFeedbackSerializer do
subject(:serialized) do
described_class.new(faq_feedback).serializable_hash
end

let(:faq_feedback) { create :green_lanes_faq_feedback }

let :expected do
{
data: {
id: faq_feedback.id.to_s,
type: :green_lanes_faq_feedback,
attributes: {
session_id: faq_feedback.session_id,
category_id: faq_feedback.category_id,
question_id: faq_feedback.question_id,
useful: faq_feedback.useful,
},
},
}
end

describe '#serializable_hash' do
it 'matches the expected hash' do
expect(serialized).to eq(expected)
end
end
end