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

Implement API endpoints for Categories and Products #4

Merged
merged 53 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
4f6be3d
chore: Switch from jbuilder to jsonapi-serializer
nanafox Sep 8, 2024
96085c4
feat: Update schema to make category_id optional on products
nanafox Sep 8, 2024
4f0374f
test: Add tests for updates and deletion for products and category
nanafox Sep 8, 2024
79e41bb
chore: Add default URLs to test and development environments
nanafox Sep 8, 2024
c564fe4
feat: Add helper to retrieve response body
nanafox Sep 8, 2024
6fb3e6d
test: Add test for controller routing to endpoints
nanafox Sep 8, 2024
d3aa6c0
chore: Include RequestsHelper in spec_helper.rb file
nanafox Sep 8, 2024
bc9df7d
feat: Add routes for version 1 of categories and unmatched endpoints
nanafox Sep 8, 2024
fe94d7a
feat: Add error handling and JsonResponse helper for API responses
nanafox Sep 8, 2024
153a472
chore: Add coverage for tests
nanafox Sep 9, 2024
9ee311f
chore: Ignore coverage directory
nanafox Sep 9, 2024
bddb336
chore: Add 'simplecov' configuration to spec_helper.rb
nanafox Sep 9, 2024
2b49c17
refactor: Update error handling for controllers
nanafox Sep 9, 2024
26bf3fe
feat: Add serializer for Category model
nanafox Sep 9, 2024
57bf179
feat: Add JsonResponse and PaginationHelper for API responses
nanafox Sep 9, 2024
2bf07bc
test: Add unit tests for CategoriesController to validate all actions
nanafox Sep 9, 2024
9cf3a9c
feat: Add controller for category API operations
nanafox Sep 9, 2024
e1c6de5
style: Update code style
nanafox Sep 9, 2024
ed3498d
test: Add unit tests for validating filtering by name and search
nanafox Sep 9, 2024
b1d81cb
feat: Implement filtering based on name and search keywords
nanafox Sep 9, 2024
a62c7eb
refactor: Move authentication validation to application controller
nanafox Sep 9, 2024
550f5c8
refactor: Update error handling responses and include Authentication
nanafox Sep 9, 2024
a707993
feat: Add an authentication module to validate dev tokens and user IDs
nanafox Sep 9, 2024
28f3d5e
feat: Add endpoints for products API operations
nanafox Sep 9, 2024
9e94fe8
chore: Add database cleaner for active record
nanafox Sep 11, 2024
28c439d
refactor: Update application_controller.rb to handle validation error
nanafox Sep 11, 2024
97689a6
refactor: Update developer token and user ID retrieval
nanafox Sep 11, 2024
690190b
refactor: Add status code success metadata for successful JSON responses
nanafox Sep 11, 2024
cfa2ca3
refactor: Update to mock the valid_developer_token to return true always
nanafox Sep 11, 2024
3d4bce2
feat: Add redis and HTTParty
nanafox Sep 14, 2024
78de640
test: Fix test cases for categories_controller.rb
nanafox Sep 14, 2024
62abeff
feat: Update schema to include app ID
nanafox Sep 14, 2024
b169a15
feat: Update authentication.rb to use the user service for validations
nanafox Sep 14, 2024
2cf489c
refactor: Improve pagination response
nanafox Sep 14, 2024
df0609a
feat: Implement a method to handle bad requests.
nanafox Sep 14, 2024
a04d232
feat: Add Redis as the caching store
nanafox Sep 14, 2024
5c7441e
feat: Add caching for single results
nanafox Sep 14, 2024
054b0c1
test: Add tests for route matching for products API endpoints
nanafox Sep 14, 2024
c666d4b
feat: Implement user service client to validate user, app and developer
nanafox Sep 14, 2024
0448f0d
test: Add tests for UserServiceClient
nanafox Sep 14, 2024
9f69273
feat: Add database_cleaner and shared_context.rb files
nanafox Sep 14, 2024
ad798c9
feat: Fix failing tests after adding mandatory app_id field
nanafox Sep 14, 2024
2af268c
feat: Add authentication helper for request to spec_helper.rb
nanafox Sep 16, 2024
23f89ff
refactor: Move authentication helper to a separate module
nanafox Sep 16, 2024
138d036
feat: Update shared_contexts.rb to retrieve valid data
nanafox Sep 16, 2024
3814ae0
style: Rubocop style fixes
nanafox Sep 16, 2024
53faf03
feat: Add logic for filtering products
nanafox Sep 16, 2024
9dc6e66
feat: Add the AuthenticationHelper for request type tests
nanafox Sep 16, 2024
98cb505
test: Add tests for product operation endpoints
nanafox Sep 16, 2024
8bb5eb4
feat: Add controller actions for Product endpoints
nanafox Sep 16, 2024
0d53119
feat: Add serializer for products
nanafox Sep 16, 2024
02daaf8
style: Rubocop style fixes
nanafox Sep 16, 2024
690ec09
Merge branch 'main' into feature/api-endpoints-products-categories
nanafox Sep 16, 2024
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@
# Ignore master key for decrypting credentials and more.
/config/master.key
.idea/
/coverage/
16 changes: 13 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ gem 'rails', '~> 7.2.1'
gem 'pg', '~> 1.1'
# Use the Puma web server [https://github.com/puma/puma]
gem 'puma', '>= 5.0'
# Build JSON APIs with ease [https://github.com/rails/jbuilder]
gem 'jbuilder'
# Use Redis adapter to run Action Cable in production
# gem "redis", ">= 4.0.1"
gem 'redis', '>= 4.0.1'

# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis]
# gem "kredis"
Expand Down Expand Up @@ -46,9 +44,21 @@ group :development, :test do
gem 'factory_bot_rails'

gem 'dotenv-rails'

# code coverage
gem 'simplecov', require: false
end

gem 'uuid7', '~> 0.2.0'

# for pagination
gem 'kaminari'

# for JSON response serialization
gem 'jsonapi-serializer'

group :test do
gem 'database_cleaner-active_record'
end

gem 'httparty', '~> 0.22.0'
35 changes: 30 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,17 @@ GEM
concurrent-ruby (1.3.4)
connection_pool (2.4.1)
crass (1.0.6)
csv (3.3.0)
database_cleaner-active_record (2.2.0)
activerecord (>= 5.a)
database_cleaner-core (~> 2.0.0)
database_cleaner-core (2.0.1)
date (3.3.4)
debug (1.9.2)
irb (~> 1.10)
reline (>= 0.3.8)
diff-lcs (1.5.1)
docile (1.4.1)
dotenv (3.1.2)
dotenv-rails (3.1.2)
dotenv (= 3.1.2)
Expand All @@ -100,16 +106,19 @@ GEM
railties (>= 5.0.0)
globalid (1.2.1)
activesupport (>= 6.1)
i18n (1.14.6)
httparty (0.22.0)
csv
mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2)
i18n (1.14.5)
concurrent-ruby (~> 1.0)
io-console (0.7.2)
irb (1.14.0)
rdoc (>= 4.0.0)
reline (>= 0.4.2)
jbuilder (2.13.0)
actionview (>= 5.0.0)
activesupport (>= 5.0.0)
json (2.7.2)
jsonapi-serializer (2.2.0)
activesupport (>= 4.2)
kaminari (1.2.2)
activesupport (>= 4.1.0)
kaminari-actionview (= 1.2.2)
Expand All @@ -136,6 +145,8 @@ GEM
mini_mime (1.1.5)
minitest (5.25.1)
msgpack (1.7.2)
multi_xml (0.7.1)
bigdecimal (~> 3.1)
net-imap (0.4.16)
date
net-protocol
Expand Down Expand Up @@ -209,6 +220,10 @@ GEM
rake (13.2.1)
rdoc (6.7.0)
psych (>= 4.0.0)
redis (5.3.0)
redis-client (>= 0.22.0)
redis-client (0.22.2)
connection_pool
regexp_parser (2.9.2)
reline (0.5.10)
io-console (~> 0.5)
Expand Down Expand Up @@ -259,6 +274,12 @@ GEM
rubocop-rails
ruby-progressbar (1.13.0)
securerandom (0.3.1)
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
stringio (3.1.1)
thor (1.3.2)
timeout (0.4.1)
Expand All @@ -285,16 +306,20 @@ PLATFORMS
DEPENDENCIES
bootsnap
brakeman
database_cleaner-active_record
debug
dotenv-rails
factory_bot_rails
jbuilder
httparty (~> 0.22.0)
jsonapi-serializer
kaminari
pg (~> 1.1)
puma (>= 5.0)
rails (~> 7.2.1)
redis (>= 4.0.1)
rspec-rails (~> 7.0)
rubocop-rails-omakase
simplecov
tzinfo-data
uuid7 (~> 0.2.0)

Expand Down
128 changes: 128 additions & 0 deletions app/controllers/api/v1/categories_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# frozen_string_literal: true

module Api
module V1
# Controller for version of Categories side of Product Management Service
# This controller handles CRUD operations for categories.
class CategoriesController < ApplicationController
# Before actions to set up authorization and category object
before_action :set_api_v1_category, only: %i[show update destroy]

# GET /api/v1/categories
# GET /api/v1/categories.json
# Retrieves a paginated list of categories filtered by developer token
def index
categories = Category.all

categories = perform_filtering(categories)

paginated_categories = categories.page(params[:page]).per(page_size)

render json: json_response(
paginated_categories, serializer:,
message: 'Categories retrieved successfully'
)
end

# GET /api/v1/categories/:id
# GET /api/v1/categories/:id.json
# Retrieves a specific category by ID
def show
# Render the JSON response with the category
render json: json_response(
category, serializer:,
message: 'Category retrieved successfully'
)
end

# POST /api/v1/categories
# POST /api/v1/categories.json
# Creates a new category
def create
@category = Category.new(api_v1_category_params)

@category.save! # Raise an error when the category could not be saved

# Render the JSON response with the created category
render json: json_response(@category,
message: 'Category created successfully',
serializer:), status: :created
end

# PATCH/PUT /api/v1/categories/:id
# PATCH/PUT /api/v1/categories/:id.json
# Updates an existing category
def update
if @category.update!(api_v1_category_params)
# Render the JSON response with the updated category
render json: json_response(@category,
serializer:,
message: 'Category updated successfully')
else
# Render an error response if the category could not be updated
render json: category.errors, status: :unprocessable_content
end
end

# DELETE /api/v1/categories/:id
# DELETE /api/v1/categories/:id.json
#
# Deletes a specific category by ID
def destroy
@category.destroy!
# Respond with no content status
head :no_content
end

private

# Reader method for the category instance variable
attr_reader :category

# Sets the category instance variable based on the ID and developer
# token
def set_api_v1_category
cache_key = "category/#{params[:id]}_#{developer_id}"
@category = Rails.cache.fetch(cache_key, expires_in: 12.hours) do
Category.find_by!(
id: params[:id],
developer_id:
)
end
end

# Only allow a list of trusted parameters through.
# Permits the name and description parameters and merges the developer
# token
def api_v1_category_params
params.require(:category)
.permit(:name, :description)
.merge(developer_id:)
end

# Returns the serializer class for the category
def serializer
CategorySerializer
end

def perform_filtering(categories)
# Filter categories by developer token
categories = categories.where(developer_id:)

# Filter categories by name
if params[:name].present?
categories = categories.where('name ILIKE ?', "%#{params[:name]}%")
end

# filter categories by the search term, so any category that
# has the search term in its name or description will be returned
return categories if params[:search].blank?

categories.where(
'name ILIKE :search OR description ILIKE :search',
search: "%#{params[:search]}%"
)
end
end
end
end
Loading