Compare commits

...

34 Commits

Author SHA1 Message Date
Renovate Bot
5f419c64e3 Update dependency factory_bot_rails to v6.4.4
Some checks failed
Add copyright notice / copyright_notice (pull_request) Successful in 4m44s
Run unit tests / unit_tests (pull_request) Failing after 1m54s
Check usage of free licenses / check-licenses (pull_request) Successful in 7m28s
2024-11-24 01:05:10 +00:00
300524956b Merge pull request 'Refine guest controller' (#140) from refine-guest-controller into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 1m57s
Run unit tests / unit_tests (push) Successful in 3m0s
Build Nginx-based docker image / build-static-assets (push) Failing after 12m9s
Reviewed-on: #140
2024-11-17 19:05:59 +00:00
80c1c9b99d Refine guest controller
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 1m26s
Add copyright notice / copyright_notice (pull_request) Successful in 2m19s
Run unit tests / unit_tests (pull_request) Successful in 3m39s
2024-11-17 20:02:08 +01:00
1f81dabff4 Merge pull request 'Define an endpoint to remove guests' (#139) from delete-guest-endpoint into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 1m4s
Run unit tests / unit_tests (push) Successful in 3m42s
Build Nginx-based docker image / build-static-assets (push) Failing after 17m24s
Reviewed-on: #139
2024-11-17 17:28:13 +00:00
f1d1ea825c Recalculate simulations after removing a guest
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 56s
Add copyright notice / copyright_notice (pull_request) Successful in 1m20s
Run unit tests / unit_tests (pull_request) Successful in 2m4s
2024-11-17 18:25:38 +01:00
7542c6361c Define an endpoint to destroy guests 2024-11-17 18:24:43 +01:00
7bdfb4f789 Merge pull request 'Remove unused bulk update endpoint' (#138) from remove-guest-bulk-update into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 52s
Run unit tests / unit_tests (push) Successful in 2m7s
Build Nginx-based docker image / build-static-assets (push) Failing after 11m29s
Reviewed-on: #138
2024-11-17 16:11:53 +00:00
31d41ea2ea Remove unused bulk update endpoint
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 1m39s
Add copyright notice / copyright_notice (pull_request) Successful in 2m48s
Run unit tests / unit_tests (pull_request) Successful in 3m46s
2024-11-17 17:07:29 +01:00
29c9764450 Merge pull request 'Define an endpoint to create new guests' (#137) from api-create-guest into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 1m1s
Run unit tests / unit_tests (push) Successful in 2m54s
Build Nginx-based docker image / build-static-assets (push) Failing after 15m35s
Reviewed-on: #137
2024-11-17 10:51:01 +00:00
1b2c0f0d0a Define an endpoint to create new guests
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 1m36s
Add copyright notice / copyright_notice (pull_request) Successful in 2m17s
Run unit tests / unit_tests (pull_request) Successful in 3m32s
2024-11-17 11:47:12 +01:00
08f7c1e584 Merge pull request 'Merge docker compose up and build into a single command' (#136) from readme-change into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 1m22s
Run unit tests / unit_tests (push) Successful in 3m43s
Build Nginx-based docker image / build-static-assets (push) Has been cancelled
Reviewed-on: #136
2024-11-17 10:32:14 +00:00
b3cfde445c Merge docker compose up and build into a single command
All checks were successful
Add copyright notice / copyright_notice (pull_request) Successful in 1m54s
Check usage of free licenses / check-licenses (pull_request) Successful in 2m41s
Run unit tests / unit_tests (pull_request) Successful in 4m7s
2024-11-17 11:27:38 +01:00
Renovate Bot
b008777c20 Update dependency solid_queue to v1.0.2
Some checks failed
Check usage of free licenses / check-licenses (pull_request) Successful in 2m57s
Run unit tests / unit_tests (pull_request) Successful in 4m39s
Add copyright notice / copyright_notice (pull_request) Successful in 26s
Check usage of free licenses / check-licenses (push) Successful in 42s
Run unit tests / unit_tests (push) Successful in 1m42s
Build Nginx-based docker image / build-static-assets (push) Has been cancelled
2024-11-17 01:08:15 +00:00
b0ee052b64 Merge pull request 'Remove / server from Swagger configuration' (#133) from remove-localhost-swagger-server into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 1m2s
Run unit tests / unit_tests (push) Successful in 3m0s
Build Nginx-based docker image / build-static-assets (push) Failing after 13m43s
Reviewed-on: #133
2024-11-16 11:32:32 +00:00
5f47b923d5 Remove / server from Swagger configuration
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 51s
Add copyright notice / copyright_notice (pull_request) Successful in 1m41s
Run unit tests / unit_tests (pull_request) Successful in 2m14s
2024-11-16 12:30:05 +01:00
17c796c375 Merge pull request 'Document expenses endpoint and add some specs' (#132) from document-expenses-controller into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 2m28s
Run unit tests / unit_tests (push) Successful in 6m46s
Build Nginx-based docker image / build-static-assets (push) Failing after 19m30s
Reviewed-on: #132
2024-11-16 09:32:36 +00:00
73e02a9d95 Add copyright notice
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 1m58s
Add copyright notice / copyright_notice (pull_request) Successful in 6m38s
Run unit tests / unit_tests (pull_request) Successful in 8m40s
2024-11-16 09:23:51 +00:00
86b9d0b56c Document expenses endpoint and add some specs
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 1m5s
Add copyright notice / copyright_notice (pull_request) Successful in 1m49s
Run unit tests / unit_tests (pull_request) Successful in 8m24s
2024-11-16 10:22:10 +01:00
8e799bfd2b Merge pull request 'Remove leftover code from Swagger-CSRF experiment' (#131) from remove-swagger-csrf into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 1m19s
Run unit tests / unit_tests (push) Successful in 2m58s
Build Nginx-based docker image / build-static-assets (push) Has been cancelled
Reviewed-on: #131
2024-11-16 09:12:35 +00:00
6e5bbb7b1b Remove leftover code from Swagger-CSRF experiment
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 2m25s
Run unit tests / unit_tests (pull_request) Successful in 4m54s
Add copyright notice / copyright_notice (pull_request) Successful in 1m16s
2024-11-16 09:59:19 +01:00
d73f59b05c Merge pull request 'Update format of guests API and document endpoints' (#130) from guests-api-changes into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 3m20s
Run unit tests / unit_tests (push) Successful in 8m10s
Build Nginx-based docker image / build-static-assets (push) Has been cancelled
Reviewed-on: #130
2024-11-16 08:56:38 +00:00
5ba1591b02 Merge branch 'main' into guests-api-changes
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 2m32s
Add copyright notice / copyright_notice (pull_request) Successful in 3m51s
Run unit tests / unit_tests (pull_request) Successful in 5m13s
2024-11-16 08:51:21 +00:00
b7714051e4 Merge pull request 'Update dependency pry to v0.15.0' (#129) from renovate/pry-0.x-lockfile into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 2m19s
Run unit tests / unit_tests (push) Successful in 4m34s
Build Nginx-based docker image / build-static-assets (push) Has been cancelled
Reviewed-on: #129
2024-11-16 08:51:02 +00:00
a8c9c051f0 Add copyright notice
Some checks failed
Add copyright notice / copyright_notice (pull_request) Failing after 8m14s
Check usage of free licenses / check-licenses (pull_request) Failing after 7m54s
Run unit tests / unit_tests (pull_request) Failing after 6m48s
2024-11-16 01:52:48 +00:00
6f6a6aaabf Update format of guests API and document endpoints
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 4m31s
Add copyright notice / copyright_notice (pull_request) Successful in 18m9s
Run unit tests / unit_tests (pull_request) Successful in 17m2s
2024-11-16 02:16:19 +01:00
Renovate Bot
6709c6b1f1 Update dependency pry to v0.15.0
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 8m43s
Add copyright notice / copyright_notice (pull_request) Successful in 11m8s
Run unit tests / unit_tests (pull_request) Successful in 15m23s
2024-11-16 01:08:16 +00:00
21d3aa5f4b Merge pull request 'Document the API using OpenAPI' (#127) from rswag-documentation into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 1m5s
Run unit tests / unit_tests (push) Successful in 3m9s
Build Nginx-based docker image / build-static-assets (push) Failing after 12m50s
Reviewed-on: #127
2024-11-15 18:49:11 +00:00
cc3c8fdd63 Improve documentation of groups endpoint
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 39s
Add copyright notice / copyright_notice (pull_request) Successful in 1m26s
Run unit tests / unit_tests (pull_request) Successful in 1m54s
2024-11-15 19:46:47 +01:00
94b1066c17 Include OpenAPI information in the README
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 55s
Add copyright notice / copyright_notice (pull_request) Successful in 1m58s
Run unit tests / unit_tests (pull_request) Successful in 2m34s
2024-11-15 19:09:55 +01:00
ca0b1b18d3 Use different server URLs for development and testing
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 41s
Add copyright notice / copyright_notice (pull_request) Successful in 1m33s
Run unit tests / unit_tests (pull_request) Successful in 2m9s
2024-11-15 19:04:30 +01:00
41cb719bf4 Add copyright notice
Some checks failed
Check usage of free licenses / check-licenses (pull_request) Successful in 1m38s
Add copyright notice / copyright_notice (pull_request) Successful in 2m0s
Run unit tests / unit_tests (pull_request) Failing after 2m39s
2024-11-15 17:29:56 +00:00
bcbcf9b469 MVP of swagger documentation
Some checks failed
Check usage of free licenses / check-licenses (pull_request) Successful in 40s
Add copyright notice / copyright_notice (pull_request) Successful in 1m23s
Run unit tests / unit_tests (pull_request) Failing after 3m5s
2024-11-15 18:28:45 +01:00
2bbcdfbd98 Merge pull request 'Update dependency factory_bot_rails to v6.4.4' (#125) from renovate/factory_bot_rails-6.x-lockfile into main
All checks were successful
Check usage of free licenses / check-licenses (push) Successful in 1m14s
Run unit tests / unit_tests (push) Successful in 2m26s
Build Nginx-based docker image / build-static-assets (push) Successful in 24m23s
Reviewed-on: #125
2024-11-15 07:47:45 +00:00
8a3469447b Install rswag gem with default configuration 2024-11-15 08:45:56 +01:00
21 changed files with 436 additions and 57 deletions

3
.gitignore vendored
View File

@ -33,3 +33,6 @@
# Ignore master key for decrypting credentials and more.
/config/master.key
# Ignore swagger generated documentation
swagger/v1/swagger.yaml

View File

@ -1,7 +1,7 @@
# syntax = docker/dockerfile:1
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.3.5
ARG RUBY_VERSION=3.3.6
FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base
# Rails app lives here

View File

@ -28,6 +28,7 @@ group :development, :test do
gem 'license_finder'
gem 'pry'
gem 'rspec-rails', '~> 7.1.0'
gem 'rswag'
gem 'shoulda-matchers', '~> 6.0'
end

View File

@ -72,6 +72,8 @@ GEM
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
uri (>= 0.13.1)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
annotaterb (4.13.0)
ast (2.4.2)
babel-source (5.8.35)
@ -127,6 +129,8 @@ GEM
actionview (>= 5.0.0)
activesupport (>= 5.0.0)
json (2.7.5)
json-schema (5.0.1)
addressable (~> 2.8)
jsonapi-deserializable (0.2.0)
jsonapi-parser (0.1.1)
jsonapi-rails (0.4.1)
@ -157,9 +161,9 @@ GEM
net-pop
net-smtp
marcel (1.0.4)
method_source (1.0.0)
method_source (1.1.0)
mini_mime (1.1.5)
minitest (5.25.1)
minitest (5.25.2)
money (6.19.0)
i18n (>= 0.6.4, <= 2)
msgpack (1.7.2)
@ -190,11 +194,12 @@ GEM
ast (~> 2.4.1)
racc
pg (1.5.9)
pry (0.14.2)
pry (0.15.0)
coderay (~> 1.1)
method_source (~> 1.0)
psych (5.2.0)
stringio
public_suffix (6.0.1)
puma (6.4.3)
nio4r (~> 2.0)
raabro (1.4.0)
@ -272,6 +277,21 @@ GEM
rspec-mocks (~> 3.13)
rspec-support (~> 3.13)
rspec-support (3.13.1)
rswag (2.16.0)
rswag-api (= 2.16.0)
rswag-specs (= 2.16.0)
rswag-ui (= 2.16.0)
rswag-api (2.16.0)
activesupport (>= 5.2, < 8.1)
railties (>= 5.2, < 8.1)
rswag-specs (2.16.0)
activesupport (>= 5.2, < 8.1)
json-schema (>= 2.2, < 6.0)
railties (>= 5.2, < 8.1)
rspec-core (>= 2.14)
rswag-ui (2.16.0)
actionpack (>= 5.2, < 8.1)
railties (>= 5.2, < 8.1)
rubocop (1.68.0)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
@ -291,7 +311,7 @@ GEM
securerandom (0.3.2)
shoulda-matchers (6.4.0)
activesupport (>= 5.2.0)
solid_queue (1.0.1)
solid_queue (1.0.2)
activejob (>= 7.1)
activerecord (>= 7.1)
concurrent-ruby (>= 1.3.1)
@ -362,6 +382,7 @@ DEPENDENCIES
react-rails
redis (>= 4.0.1)
rspec-rails (~> 7.1.0)
rswag
rubocop
rubytree
shoulda-matchers (~> 6.0)

View File

@ -42,8 +42,7 @@ projects <or anything else>
Docker compose is the recommended way to run Libre Wedding Planner for development purposes. After downloading both repositories, `cd` to the root of `wedding-planner` and run:
```bash
docker compose build
docker compose up
docker compose up --build
```
Several containers will be started:
@ -68,6 +67,16 @@ Unit tests can be executed with
bundle exec rspec
```
## API documentation
Generate the OpenAPI documentation with the command:
```
rake rswag:specs:swaggerize
```
The documentation is available in Swagger UI in http://libre-wedding-planner.app.localhost/api/api-docs/index.html. If testing the API through the UI, you will need to select the second server (which includes the `/api` path), intended for development.
## Contributing
Contributions of all kinds (code, UX/UI, testing, translations, etc.) are welcome. The procedures to contribute are still being defined, but don't hesitate to reach out in case you want to participate.

View File

@ -3,13 +3,41 @@
class ApplicationController < ActionController::Base
after_action :set_csrf_cookie
skip_before_action :verify_authenticity_token, if: :development_swagger?
rescue_from ActiveRecord::RecordInvalid do |exception|
render json: {
message: 'Record invalid',
errors: exception.record.errors.full_messages
}, status: :unprocessable_entity
end
rescue_from ActionController::ParameterMissing do |exception|
render json: {
message: 'Parameter missing',
errors: [exception.message]
}, status: :bad_request
end
rescue_from ActiveRecord::RecordNotFound do |exception|
render json: {
message: 'Record not found',
errors: [exception.message]
}, status: :not_found
end
private
def development_swagger?
Rails.env.test? ||
Rails.env.development? && request.headers['referer'].include?('/api-docs/index.html')
end
def set_csrf_cookie
cookies["csrf-token"] = {
cookies['csrf-token'] = {
value: form_authenticity_token,
secure: Rails.env.production?,
same_site: :strict,
same_site: :strict
}
end
end

View File

@ -4,20 +4,30 @@ require 'csv'
class GuestsController < ApplicationController
def index
@guests = Guest.all.includes(:group)
render json: Guest.all.includes(:group)
.joins(:group)
.order('groups.name' => :asc, name: :asc)
.as_json(only: %i[id name status], include: { group: { only: %i[id name] } })
end
render jsonapi: @guests
def create
Guest.create!(guest_params)
render json: {}, status: :created
end
def update
Guests::UpdateUseCase.new(guest_ids: [params[:id]], params: params.require(:guest).permit(:name)).call
Guest.find(params[:id]).update!(guest_params)
render json: {}, status: :ok
end
def bulk_update
Guests::UpdateUseCase.new(guest_ids: params[:guest_ids], params: params.require(:properties).permit(:status)).call
def destroy
Guest.find(params[:id]).destroy!
render json: {}, status: :ok
end
private
def guest_params
params.require(:guest).permit(:name, :group_id, :status)
end
end

View File

@ -12,4 +12,11 @@
# updated_at :datetime not null
#
class Expense < ApplicationRecord
enum :pricing_type,
fixed: 'fixed',
per_person: 'per_person'
validates :name, presence: true
validates :amount, presence: true, numericality: { greater_than: 0 }
validates :pricing_type, presence: true
end

View File

@ -29,7 +29,22 @@ class Guest < ApplicationRecord
confirmed: 20,
declined: 30,
tentative: 40
}
}, validate: true
validates :name, presence: true
scope :potential, -> { where.not(status: %i[declined considered]) }
after_save :recalculate_simulations, if: :saved_change_to_status?
after_destroy :recalculate_simulations
has_many :seats, dependent: :delete_all
private
def recalculate_simulations
TablesArrangement.delete_all
ActiveJob.perform_all_later(50.times.map { TableSimulatorJob.new })
end
end

View File

@ -10,7 +10,7 @@ module Groups
def query
<<~SQL.squish
SELECT#{' '}
SELECT
groups.id,
groups.name,
groups.icon,

View File

@ -1,22 +0,0 @@
# Copyright (C) 2024 Manuel Bustillo
module Guests
class UpdateUseCase
private attr_reader :guest_ids, :params
def initialize(guest_ids:, params:)
@guest_ids = guest_ids
@params = params
end
def call
Guest.where(id: guest_ids).update!(params)
# TODO: Not all status transitions may require a table re-arrangement
return unless params.key?(:status)
TablesArrangement.delete_all
ActiveJob.perform_all_later(50.times.map { TableSimulatorJob.new })
end
end
end

View File

@ -0,0 +1,16 @@
# Copyright (C) 2024 Manuel Bustillo
Rswag::Api.configure do |c|
# Specify a root folder where Swagger JSON files are located
# This is used by the Swagger middleware to serve requests for API descriptions
# NOTE: If you're using rswag-specs to generate Swagger, you'll need to ensure
# that it's configured to generate files in the same folder
c.openapi_root = Rails.root.to_s + '/swagger'
# Inject a lambda function to alter the returned Swagger prior to serialization
# The function will have access to the rack env for the current request
# For example, you could leverage this to dynamically assign the "host" property
#
#c.swagger_filter = lambda { |swagger, env| swagger['host'] = env['HTTP_HOST'] }
end

View File

@ -0,0 +1,18 @@
# Copyright (C) 2024 Manuel Bustillo
Rswag::Ui.configure do |c|
# List the Swagger endpoints that you want to be documented through the
# swagger-ui. The first parameter is the path (absolute or relative to the UI
# host) to the corresponding endpoint and the second is a title that will be
# displayed in the document selector.
# NOTE: If you're using rspec-api to expose Swagger files
# (under openapi_root) as JSON or YAML endpoints, then the list below should
# correspond to the relative paths for those endpoints.
c.swagger_endpoint '/api/api-docs/v1/swagger.yaml', 'API V1 Docs'
# Add Basic Auth in case your API is private
# c.basic_auth_enabled = true
# c.basic_auth_credentials 'username', 'password'
end

View File

@ -1,8 +1,10 @@
# Copyright (C) 2024 Manuel Bustillo
Rails.application.routes.draw do
mount Rswag::Ui::Engine => '/api-docs'
mount Rswag::Api::Engine => '/api-docs'
resources :groups, only: :index
resources :guests, only: %i[index update] do
resources :guests, only: %i[index create update destroy] do
post :bulk_update, on: :collection
end
resources :expenses, only: %i[index update] do

View File

@ -3,5 +3,10 @@
require 'rails_helper'
RSpec.describe Expense, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
describe 'validations' do
it { should validate_presence_of(:name) }
it { should validate_presence_of(:amount) }
it { should validate_numericality_of(:amount).is_greater_than(0) }
it { should validate_presence_of(:pricing_type) }
end
end

View File

@ -3,6 +3,8 @@
require 'rails_helper'
RSpec.describe Guest, type: :model do
describe 'validations' do
it { should validate_presence_of(:name) }
it do
should define_enum_for(:status).with_values(
considered: 0,
@ -12,6 +14,7 @@ RSpec.describe Guest, type: :model do
tentative: 40
)
end
end
it { should belong_to(:group) }

View File

@ -0,0 +1,49 @@
# Copyright (C) 2024 Manuel Bustillo
require 'swagger_helper'
RSpec.describe 'expenses', type: :request do
path '/expenses' do
get('list expenses') do
tags 'Expenses'
produces 'application/json'
response(200, 'successful') do
schema type: :array,
items: {
type: :object,
required: %i[id name amount pricing_type],
properties: {
id: { type: :string, format: :uuid },
name: { type: :string },
amount: { type: :number },
pricing_type: { type: :string, enum: Expense.pricing_types.keys }
}
}
xit
end
end
end
path '/expenses/{id}' do
patch('update expense') do
tags 'Expenses'
consumes 'application/json'
produces 'application/json'
parameter name: 'id', in: :path, type: :string, format: :uuid, description: 'id'
parameter name: :body, in: :body, schema: {
type: :object,
properties: {
name: { type: :string },
amount: { type: :number, minimum: 0 },
pricing_type: { type: :string, enum: Expense.pricing_types.keys }
}
}
response_empty_200
response_422
response_404
end
end
end

View File

@ -0,0 +1,33 @@
# Copyright (C) 2024 Manuel Bustillo
require 'swagger_helper'
RSpec.describe 'groups', type: :request do
path '/groups' do
get('list groups') do
tags 'Groups'
produces 'application/json'
response(200, 'successful') do
schema type: :array,
items: {
type: :object,
required: %i[id name icon parent_id color total considered invited confirmed declined tentative],
properties: {
id: { type: :string, format: :uuid, required: true },
name: { type: :string },
icon: { type: :string, example: 'pi pi-crown', description: 'The CSS classes used by the icon' },
parent_id: { type: :string, format: :uuid },
color: { type: :string, pattern: '^#(?:[0-9a-fA-F]{3}){1,2}$' },
total: { type: :integer, minimum: 0, description: 'Total number of guests in any status' },
considered: { type: :integer, minimum: 0 },
invited: { type: :integer, minimum: 0 },
confirmed: { type: :integer, minimum: 0 },
declined: { type: :integer, minimum: 0 },
tentative: { type: :integer, minimum: 0 }
}
}
xit
end
end
end
end

View File

@ -0,0 +1,91 @@
# Copyright (C) 2024 Manuel Bustillo
require 'swagger_helper'
RSpec.describe 'guests', type: :request do
path '/guests' do
get('list guests') do
tags 'Guests'
produces 'application/json'
response(200, 'successful') do
schema type: :array,
items: {
type: :object,
required: %i[id name status group],
properties: {
id: { type: :string, format: :uuid },
name: { type: :string },
status: { type: :string, enum: Guest.statuses.keys },
group: { type: :object,
required: %i[id name],
properties: {
id: { type: :string, format: :uuid },
name: { type: :string }
} }
}
}
xit
end
end
post('create guest') do
tags 'Guests'
consumes 'application/json'
produces 'application/json'
parameter name: :body, in: :body, schema: {
type: :object,
required: %i[guest],
properties: {
guest: {
type: :object,
required: %i[name group_id status],
properties: {
name: { type: :string },
group_id: { type: :string, format: :uuid },
status: { type: :string, enum: Guest.statuses.keys }
}
}
}
}
response_empty_201
response_422
end
end
path '/guests/{id}' do
patch('update guest') do
tags 'Guests'
consumes 'application/json'
produces 'application/json'
parameter name: 'id', in: :path, type: :string, format: :uuid
parameter name: :body, in: :body, schema: {
type: :object,
required: %i[guest],
properties: {
guest: {
type: :object,
properties: {
name: { type: :string },
group_id: { type: :string, format: :uuid },
status: { type: :string, enum: Guest.statuses.keys }
}
}
}
}
response_empty_200
response_422
response_404
end
delete('delete guest') do
tags 'Guests'
produces 'application/json'
parameter name: 'id', in: :path, type: :string, format: :uuid
response_empty_200
response_404
end
end
end

44
spec/swagger_helper.rb Normal file
View File

@ -0,0 +1,44 @@
# Copyright (C) 2024 Manuel Bustillo
# frozen_string_literal: true
require 'rails_helper'
require_relative './swagger_response_helper'
include SwaggerResponseHelper
RSpec.configure do |config|
# Specify a root folder where Swagger JSON files are generated
# NOTE: If you're using the rswag-api to serve API descriptions, you'll need
# to ensure that it's configured to serve Swagger from the same folder
config.openapi_root = Rails.root.join('swagger').to_s
# Define one or more Swagger documents and provide global metadata for each one
# When you run the 'rswag:specs:swaggerize' rake task, the complete Swagger will
# be generated at the provided relative path under openapi_root
# By default, the operations defined in spec files are added to the first
# document below. You can override this behavior by adding a openapi_spec tag to the
# the root example_group in your specs, e.g. describe '...', openapi_spec: 'v2/swagger.json'
config.openapi_specs = {
'v1/swagger.yaml' => {
openapi: '3.0.1',
info: {
title: 'API V1',
version: 'v1'
},
paths: {},
servers: [
{
url: 'http://libre-wedding-planner.app.localhost/api',
description: 'Suitable for development'
}
]
}
}
# Specify the format of the output Swagger file when running 'rswag:specs:swaggerize'.
# The openapi_specs configuration option has the filename including format in
# the key, this may want to be changed to avoid putting yaml in json files.
# Defaults to json. Accepts ':json' and ':yaml'.
config.openapi_format = :yaml
end

View File

@ -0,0 +1,46 @@
# Copyright (C) 2024 Manuel Bustillo
module SwaggerResponseHelper
def response_422
response(422, 'Validation errors in input parameters') do
produces 'application/json'
error_schema
xit
end
end
def response_empty_200
response(200, 'Success') do
produces 'application/json'
schema type: :object
xit
end
end
def response_empty_201
response(201, 'Created') do
produces 'application/json'
schema type: :object
xit
end
end
def response_404
response(404, 'Record not found') do
produces 'application/json'
error_schema
xit
end
end
private
def error_schema
schema type: :object,
required: %i[message errors],
properties: {
message: { type: :string },
errors: { type: :array, items: { type: :string } }
}
end
end