Add swagger along with api/v1/points swagger doc

This commit is contained in:
Eugene Burmakin 2024-05-18 13:35:48 +02:00
parent 5e46168cf8
commit e488dc9e4a
14 changed files with 285 additions and 7 deletions

View file

@ -2,3 +2,12 @@ require: rubocop-rails
Style/Documentation:
Enabled: false
Style/ClassAndModuleChildren:
Enabled: false
Layout/HashAlignment:
Enabled: false
Metrics/BlockLength:
Enabled: false

View file

@ -13,6 +13,8 @@ gem 'pg'
gem 'puma'
gem 'pundit'
gem 'rails'
gem 'rswag-api'
gem 'rswag-ui'
gem 'shrine', '~> 3.6'
gem 'sidekiq'
gem 'sidekiq-cron'
@ -30,6 +32,7 @@ group :development, :test do
gem 'pry-byebug'
gem 'pry-rails'
gem 'rspec-rails'
gem 'rswag-specs'
end
group :test do

View file

@ -145,6 +145,8 @@ GEM
rdoc (>= 4.0.0)
reline (>= 0.4.2)
json (2.7.2)
json-schema (4.3.0)
addressable (>= 2.8)
language_server-protocol (3.17.0.3)
loofah (2.22.0)
crass (~> 1.0.2)
@ -277,6 +279,17 @@ GEM
rspec-mocks (~> 3.13)
rspec-support (~> 3.13)
rspec-support (3.13.1)
rswag-api (2.13.0)
activesupport (>= 3.1, < 7.2)
railties (>= 3.1, < 7.2)
rswag-specs (2.13.0)
activesupport (>= 3.1, < 7.2)
json-schema (>= 2.2, < 5.0)
railties (>= 3.1, < 7.2)
rspec-core (>= 2.14)
rswag-ui (2.13.0)
actionpack (>= 3.1, < 7.2)
railties (>= 3.1, < 7.2)
rubocop (1.62.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
@ -390,6 +403,9 @@ DEPENDENCIES
rails
redis
rspec-rails
rswag-api
rswag-specs
rswag-ui
rubocop-rails
shoulda-matchers
shrine (~> 3.6)

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class Api::V1::PointsController < ApplicationController
skip_forgery_protection

View file

@ -1,9 +1,11 @@
# frozen_string_literal: true
class Owntracks::PointCreatingJob < ApplicationJob
queue_as :default
def perform(point_params)
parsed_params = OwnTracks::Params.new(point_params).call
point = Point.create(parsed_params)
Point.create(parsed_params)
end
end

View file

@ -0,0 +1,14 @@
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,16 @@
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-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,6 +1,8 @@
# frozen_string_literal: true
Rails.application.routes.draw do
mount Rswag::Api::Engine => '/api-docs'
mount Rswag::Ui::Engine => '/api-docs'
get 'settings/theme', to: 'settings#theme'
get 'export', to: 'export#index'
get 'export/download', to: 'export#download'

8
lib/tasks/rswag.rake Normal file
View file

@ -0,0 +1,8 @@
# frozen_string_literal: true
namespace :rswag do
desc 'Generate Swagger docs'
task generate: [:environment] do
system 'bundle exec rake rswag:specs:swaggerize PATTERN="spec/swagger/**/*_spec.rb"'
end
end

View file

@ -6,6 +6,11 @@ require_relative '../config/environment'
abort('The Rails environment is running in production mode!') if Rails.env.production?
require 'rspec/rails'
require 'rswag/specs'
require 'rake'
Rails.application.load_tasks
# Add additional requires below this line. Rails is not loaded until this point!
Dir[Rails.root.join('spec/support/**/*.rb')].sort.each { |f| require f }
@ -27,9 +32,15 @@ RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
config.include Devise::Test::IntegrationHelpers, type: :request
config.rswag_dry_run = false
config.before do
ActiveJob::Base.queue_adapter = :test
end
config.after(:suite) do
Rake::Task['rswag:generate'].invoke
end
end
Shoulda::Matchers.configure do |config|

View file

@ -1,22 +1,24 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe "Api::V1::Points", type: :request do
describe "POST /api/v1/points" do
RSpec.describe 'Api::V1::Points', type: :request do
describe 'POST /api/v1/points' do
context 'with valid params' do
let(:params) do
{ lat: 1.0, lon: 1.0, tid: 'test', tst: Time.now.to_i, topic: 'iPhone 12 pro' }
{ lat: 1.0, lon: 1.0, tid: 'test', tst: Time.current.to_i, topic: 'iPhone 12 pro' }
end
it "returns http success" do
it 'returns http success' do
post api_v1_points_path, params: params
expect(response).to have_http_status(:success)
end
it 'enqueues a job' do
expect {
expect do
post api_v1_points_path, params: params
}.to have_enqueued_job(Owntracks::PointCreatingJob)
end.to have_enqueued_job(Owntracks::PointCreatingJob)
end
end
end

View file

@ -0,0 +1,60 @@
# frozen_string_literal: true
require 'swagger_helper'
describe 'Points API', type: :request do
path '/api/v1/points' do
post 'Creates a point' do
request_body_example value: {
lat: 52.502397,
lon: 13.356718,
tid: 'Swagger',
tst: Time.current.to_i
}
tags 'Points'
consumes 'application/json'
parameter name: :point, in: :body, schema: {
type: :object,
properties: {
acc: { type: :number },
alt: { type: :number },
batt: { type: :number },
bs: { type: :number },
cog: { type: :number },
lat: { type: :string, format: :decimal },
lon: { type: :string, format: :decimal },
rad: { type: :number },
t: { type: :string },
tid: { type: :string },
tst: { type: :number },
vac: { type: :number },
vel: { type: :number },
p: { type: :string, format: :decimal },
poi: { type: :string },
conn: { type: :string },
tag: { type: :string },
topic: { type: :string },
inregions: { type: :array },
SSID: { type: :string },
BSSID: { type: :string },
created_at: { type: :string },
inrids: { type: :array },
m: { type: :number }
},
required: %w[lat lon tid tst]
}
response '200', 'point created' do
let(:point) { { lat: 1.0, lon: 2.0, tid: 3, tst: 4 } }
run_test!
end
response '200', 'invalid request' do
let(:point) { { lat: 1.0 } }
run_test!
end
end
end
end

43
spec/swagger_helper.rb Normal file
View file

@ -0,0 +1,43 @@
# frozen_string_literal: true
require 'rails_helper'
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://{defaultHost}',
variables: {
defaultHost: {
default: 'localhost:3000'
}
}
}
]
}
}
# 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

90
swagger/v1/swagger.yaml Normal file
View file

@ -0,0 +1,90 @@
---
openapi: 3.0.1
info:
title: API V1
version: v1
paths:
"/api/v1/points":
post:
summary: Creates a point
tags:
- Points
parameters: []
responses:
'200':
description: invalid request
requestBody:
content:
application/json:
schema:
type: object
properties:
acc:
type: number
alt:
type: number
batt:
type: number
bs:
type: number
cog:
type: number
lat:
type: string
format: decimal
lon:
type: string
format: decimal
rad:
type: number
t:
type: string
tid:
type: string
tst:
type: number
vac:
type: number
vel:
type: number
p:
type: string
format: decimal
poi:
type: string
conn:
type: string
tag:
type: string
topic:
type: string
inregions:
type: array
SSID:
type: string
BSSID:
type: string
created_at:
type: string
inrids:
type: array
m:
type: number
required:
- lat
- lon
- tid
- tst
examples:
'0':
summary: Creates a point
value:
lat: 52.502397
lon: 13.356718
tid: Swagger
tst: 1716032145
servers:
- url: http://{defaultHost}
variables:
defaultHost:
default: localhost:3000