From 2a6da54320e63e6c1540368aebd2cb2effd9359c Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 22 Feb 2016 19:42:47 +0100 Subject: [PATCH 1/6] add gem api-pie Error : stack level too deep --- Gemfile | 3 + Gemfile.lock | 5 ++ app/controllers/api/v1/dossiers_controller.rb | 27 ++++++++ .../api/v1/procedures_controller.rb | 13 ++++ config/initializers/apipie.rb | 18 +++++ config/routes.rb | 2 + .../api/v1/dossiers_controller_spec.rb | 68 ++++++++++--------- .../api/v1/procedures_controller_spec.rb | 9 ++- spec/spec_helper.rb | 2 + 9 files changed, 113 insertions(+), 34 deletions(-) create mode 100644 config/initializers/apipie.rb diff --git a/Gemfile b/Gemfile index 708cf04ce..980dda77b 100644 --- a/Gemfile +++ b/Gemfile @@ -79,6 +79,9 @@ gem 'bootstrap-wysihtml5-rails', '~> 0.3.3.8' gem 'as_csv' +gem 'apipie-rails', '=0.3.1' +gem "maruku" # for Markdown support in apipie + group :test do gem 'capybara' gem 'factory_girl' diff --git a/Gemfile.lock b/Gemfile.lock index 5dc12198f..e3431f839 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -47,6 +47,8 @@ GEM thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) addressable (2.3.8) + apipie-rails (0.3.1) + json arel (6.0.2) as_csv (2.0.2) actionpack (>= 3.0) @@ -211,6 +213,7 @@ GEM activesupport (>= 3.1.0) rack (>= 1.4.0) rest-client + maruku (0.7.2) method_source (0.8.2) mime-types (2.6.1) mini_portile (0.6.2) @@ -453,6 +456,7 @@ PLATFORMS DEPENDENCIES active_model_serializers + apipie-rails (= 0.3.1) as_csv bootstrap-datepicker-rails bootstrap-sass (~> 3.3.5) @@ -480,6 +484,7 @@ DEPENDENCIES leaflet-rails logstasher mailjet + maruku mina! nyan-cat-formatter openid_connect diff --git a/app/controllers/api/v1/dossiers_controller.rb b/app/controllers/api/v1/dossiers_controller.rb index 6234b6046..543e70a0d 100644 --- a/app/controllers/api/v1/dossiers_controller.rb +++ b/app/controllers/api/v1/dossiers_controller.rb @@ -1,5 +1,18 @@ class API::V1::DossiersController < APIController + api :GET, '/procedures/:procedure_id/dossiers/', 'Liste de tous les dossiers d\'une procédure' + param :procedure_id, Integer, desc: "L'identifiant de la procédure", required: true + error code: 401, desc: "Non authorisé" + error code: 404, desc: "Procédure inconnue" + + description <<-EOS + Plop + EOS + + meta champs: { + + } + def index procedure = current_administrateur.procedures.find(params[:procedure_id]) dossiers = procedure.dossiers.where.not(state: :draft).paginate(page: params[:page]) @@ -8,6 +21,20 @@ class API::V1::DossiersController < APIController render json: {}, status: 404 end + api :GET, '/procedures/:procedure_id/dossiers/:id', 'Informations du dossier d\'une procédure' + param :procedure_id, Integer, desc: "L'identifiant de la procédure", required: true + param :dossier_id, Integer, desc: "L'identifiant de la procédure", required: true + error code: 401, desc: "Non authorisé" + error code: 404, desc: "Procédure ou dossier inconnu" + + description <<-EOS + Plop + EOS + + meta champs: { + + } + def show procedure = current_administrateur.procedures.find(params[:procedure_id]) dossier = procedure.dossiers.find(params[:id]) diff --git a/app/controllers/api/v1/procedures_controller.rb b/app/controllers/api/v1/procedures_controller.rb index b3360ed2d..8cd157b62 100644 --- a/app/controllers/api/v1/procedures_controller.rb +++ b/app/controllers/api/v1/procedures_controller.rb @@ -1,4 +1,17 @@ class API::V1::ProceduresController < APIController + api :GET, '/procedures/:id', 'Informations concernant une procédure' + param :id, Integer, desc: "L'identifiant de la procédure", required: true + error code: 401, desc: "Non authorisé" + error code: 404, desc: "Procédure inconnue" + + description <<-EOS + Plop + EOS + + meta champs: { + + } + def show @procedure = current_administrateur.procedures.find(params[:id]).decorate diff --git a/config/initializers/apipie.rb b/config/initializers/apipie.rb new file mode 100644 index 000000000..92f93c63d --- /dev/null +++ b/config/initializers/apipie.rb @@ -0,0 +1,18 @@ +Apipie.configure do |config| + config.app_name = "API TPS" + config.api_base_url = "/api/v1" + config.doc_base_url = "/docs" + config.api_controllers_matcher = File.join(Rails.root, "app", "controllers","api","v1", "**","*.rb") + config.markup = Apipie::Markup::Markdown.new + config.default_version = '1.0' + config.validate = false + config.copyright = "© SGMAP" + config.namespaced_resources = true + config.show_all_examples = true + + config.app_info = <<-EOS +Description + + EOS + +end diff --git a/config/routes.rb b/config/routes.rb index db5e5f748..ffd931792 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -113,4 +113,6 @@ Rails.application.routes.draw do end end end + + apipie end diff --git a/spec/controllers/api/v1/dossiers_controller_spec.rb b/spec/controllers/api/v1/dossiers_controller_spec.rb index 82fdbc300..7c1dcacc4 100644 --- a/spec/controllers/api/v1/dossiers_controller_spec.rb +++ b/spec/controllers/api/v1/dossiers_controller_spec.rb @@ -28,7 +28,9 @@ describe API::V1::DossiersController do let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') } } let(:body) { JSON.parse(response.body, symbolize_names: true) } - it { expect(response.code).to eq('200') } + it 'return REST code 200', :show_in_doc do + expect(response.code).to eq('200') + end it { expect(body).to have_key :pagination } @@ -117,7 +119,9 @@ describe API::V1::DossiersController do let(:field_list) { [:id, :nom_projet, :created_at, :updated_at, :description, :archived, :entreprise, :etablissement] } subject { body[:dossier] } - it { expect(response.code).to eq('200') } + it 'return REST code 200', :show_in_doc do + expect(response.code).to eq('200') + end it { expect(subject[:id]).to eq(dossier.id) } it { expect(subject[:nom_projet]).to eq(dossier.nom_projet) } it { expect(subject[:created_at]).to eq('2008-09-01T08:05:00.000Z') } @@ -128,24 +132,24 @@ describe API::V1::DossiersController do describe 'entreprise' do let(:field_list) { [ - :siren, - :capital_social, - :numero_tva_intracommunautaire, - :forme_juridique, - :forme_juridique_code, - :nom_commercial, - :raison_sociale, - :siret_siege_social, - :code_effectif_entreprise, - :date_creation, - :nom, - :prenom] } - subject { super()[:entreprise]} + :siren, + :capital_social, + :numero_tva_intracommunautaire, + :forme_juridique, + :forme_juridique_code, + :nom_commercial, + :raison_sociale, + :siret_siege_social, + :code_effectif_entreprise, + :date_creation, + :nom, + :prenom] } + subject { super()[:entreprise] } - it { expect(subject[:siren]).to eq('440117620')} - it { expect(subject[:capital_social]).to eq(537_100_000)} - it { expect(subject[:numero_tva_intracommunautaire]).to eq('FR27440117620')} - it { expect(subject[:forme_juridique]).to eq('SA à conseil d\'administration (s.a.i.)')} + it { expect(subject[:siren]).to eq('440117620') } + it { expect(subject[:capital_social]).to eq(537_100_000) } + it { expect(subject[:numero_tva_intracommunautaire]).to eq('FR27440117620') } + it { expect(subject[:forme_juridique]).to eq('SA à conseil d\'administration (s.a.i.)') } it { expect(subject[:forme_juridique_code]).to eq('5599') } it { expect(subject[:nom_commercial]).to eq('GRTGAZ') } it { expect(subject[:raison_sociale]).to eq('GRTGAZ') } @@ -157,20 +161,20 @@ describe API::V1::DossiersController do describe 'etablissement' do let(:field_list) { [ - :siret, - :siege_social, - :naf, - :libelle_naf, - :adresse, - :numero_voie, - :type_voie, - :nom_voie, - :complement_adresse, - :code_postal, - :localite, - :code_insee_localite + :siret, + :siege_social, + :naf, + :libelle_naf, + :adresse, + :numero_voie, + :type_voie, + :nom_voie, + :complement_adresse, + :code_postal, + :localite, + :code_insee_localite ] } - subject { super()[:etablissement]} + subject { super()[:etablissement] } it { expect(subject[:siret]).to eq('44011762001530') } it { expect(subject[:siege_social]).to eq(true) } diff --git a/spec/controllers/api/v1/procedures_controller_spec.rb b/spec/controllers/api/v1/procedures_controller_spec.rb index f3a080c6c..e2b1af6b0 100644 --- a/spec/controllers/api/v1/procedures_controller_spec.rb +++ b/spec/controllers/api/v1/procedures_controller_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' describe API::V1::ProceduresController do let(:admin) { create(:administrateur) } it { expect(described_class).to be < APIController } + describe 'GET show' do context 'when procedure does not exist' do subject { get :show, id: 999_999_999, token: admin.api_token } @@ -16,9 +17,13 @@ describe API::V1::ProceduresController do context 'when procedure exist' do let(:procedure) { create(:procedure, administrateur: admin) } subject { get :show, id: procedure, token: admin.api_token } - it { expect(subject.status).to eq(200) } + + it 'return REST code 200', :show_in_doc do + expect(subject.status).to eq(200) + end + describe 'body' do - let(:module_api_carto) { create(:module_api_carto, use_api_carto: true, quartiers_prioritaires: true, cadastre: true)} + let(:module_api_carto) { create(:module_api_carto, use_api_carto: true, quartiers_prioritaires: true, cadastre: true) } let(:procedure) { create(:procedure, :with_type_de_champ, :with_two_type_de_piece_justificative, module_api_carto: module_api_carto, administrateur: admin) } let(:response) { get :show, id: procedure.id, token: admin.api_token } subject { JSON.parse(response.body, symbolize_names: true)[:procedure] } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 258db8c48..1cf5d4d05 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -80,6 +80,8 @@ RSpec.configure do |config| config.infer_base_class_for_anonymous_controllers = false + config.filter_run :show_in_doc => true if ENV['APIPIE_RECORD'] + config.order = 'random' config.include Devise::TestHelpers, type: :view From 16c72e7478e610e1fcc76f459213e6b0e598595d Mon Sep 17 00:00:00 2001 From: Xavier J Date: Fri, 26 Feb 2016 12:17:41 +0100 Subject: [PATCH 2/6] Complete API Dossier --- app/serializers/cerfa_serializer.rb | 6 + app/serializers/champ_serializer.rb | 5 + app/serializers/dossier_serializer.rb | 6 +- .../piece_justificative_serializer.rb | 5 + app/serializers/type_de_champ_serializer.rb | 2 +- .../api/v1/dossiers_controller_spec.rb | 124 +++++++++++++----- spec/factories/type_de_champ.rb | 2 +- 7 files changed, 115 insertions(+), 35 deletions(-) create mode 100644 app/serializers/cerfa_serializer.rb create mode 100644 app/serializers/champ_serializer.rb create mode 100644 app/serializers/piece_justificative_serializer.rb diff --git a/app/serializers/cerfa_serializer.rb b/app/serializers/cerfa_serializer.rb new file mode 100644 index 000000000..54fccc911 --- /dev/null +++ b/app/serializers/cerfa_serializer.rb @@ -0,0 +1,6 @@ +class CerfaSerializer < ActiveModel::Serializer + + attributes :content_url => :url + + has_one :type_de_champ +end \ No newline at end of file diff --git a/app/serializers/champ_serializer.rb b/app/serializers/champ_serializer.rb new file mode 100644 index 000000000..5a0ba0bf3 --- /dev/null +++ b/app/serializers/champ_serializer.rb @@ -0,0 +1,5 @@ +class ChampSerializer < ActiveModel::Serializer + attributes :value + + has_one :type_de_champ +end \ No newline at end of file diff --git a/app/serializers/dossier_serializer.rb b/app/serializers/dossier_serializer.rb index dd68a55b0..b3f56395b 100644 --- a/app/serializers/dossier_serializer.rb +++ b/app/serializers/dossier_serializer.rb @@ -4,8 +4,12 @@ class DossierSerializer < ActiveModel::Serializer :description, :created_at, :updated_at, - :archived + :archived, + :mandataire_social has_one :entreprise has_one :etablissement + has_one :cerfa + has_many :champs + has_many :pieces_justificatives end \ No newline at end of file diff --git a/app/serializers/piece_justificative_serializer.rb b/app/serializers/piece_justificative_serializer.rb new file mode 100644 index 000000000..0fe9d0e10 --- /dev/null +++ b/app/serializers/piece_justificative_serializer.rb @@ -0,0 +1,5 @@ +class PieceJustificativeSerializer < ActiveModel::Serializer + attributes :content_url => :url + + has_one :type_de_piece_justificative +end \ No newline at end of file diff --git a/app/serializers/type_de_champ_serializer.rb b/app/serializers/type_de_champ_serializer.rb index 32f10627c..bbe2cb7dc 100644 --- a/app/serializers/type_de_champ_serializer.rb +++ b/app/serializers/type_de_champ_serializer.rb @@ -1,7 +1,7 @@ class TypeDeChampSerializer < ActiveModel::Serializer attributes :id, :libelle, - :type_champ, + {:type_champ => :type}, :order_place, :description end \ No newline at end of file diff --git a/spec/controllers/api/v1/dossiers_controller_spec.rb b/spec/controllers/api/v1/dossiers_controller_spec.rb index 82fdbc300..d463fcaea 100644 --- a/spec/controllers/api/v1/dossiers_controller_spec.rb +++ b/spec/controllers/api/v1/dossiers_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe API::V1::DossiersController do let(:admin) { create(:administrateur) } - let(:procedure) { create(:procedure, administrateur: admin) } + let(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ, administrateur: admin) } let(:wrong_procedure) { create(:procedure) } it { expect(described_class).to be < APIController } @@ -114,7 +114,7 @@ describe API::V1::DossiersController do let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure) } } let(:dossier_id) { dossier.id } let(:body) { JSON.parse(response.body, symbolize_names: true) } - let(:field_list) { [:id, :nom_projet, :created_at, :updated_at, :description, :archived, :entreprise, :etablissement] } + let(:field_list) { [:id, :nom_projet, :created_at, :updated_at, :description, :archived, :mandataire_social, :entreprise, :etablissement] } subject { body[:dossier] } it { expect(response.code).to eq('200') } @@ -124,28 +124,30 @@ describe API::V1::DossiersController do it { expect(subject[:updated_at]).to eq('2008-09-01T08:05:00.000Z') } it { expect(subject[:description]).to eq(dossier.description) } it { expect(subject[:archived]).to eq(dossier.archived) } + it { expect(subject[:mandataire_social]).to eq(dossier.mandataire_social) } + it { expect(subject.keys).to match_array(field_list) } describe 'entreprise' do let(:field_list) { [ - :siren, - :capital_social, - :numero_tva_intracommunautaire, - :forme_juridique, - :forme_juridique_code, - :nom_commercial, - :raison_sociale, - :siret_siege_social, - :code_effectif_entreprise, - :date_creation, - :nom, - :prenom] } - subject { super()[:entreprise]} + :siren, + :capital_social, + :numero_tva_intracommunautaire, + :forme_juridique, + :forme_juridique_code, + :nom_commercial, + :raison_sociale, + :siret_siege_social, + :code_effectif_entreprise, + :date_creation, + :nom, + :prenom] } + subject { super()[:entreprise] } - it { expect(subject[:siren]).to eq('440117620')} - it { expect(subject[:capital_social]).to eq(537_100_000)} - it { expect(subject[:numero_tva_intracommunautaire]).to eq('FR27440117620')} - it { expect(subject[:forme_juridique]).to eq('SA à conseil d\'administration (s.a.i.)')} + it { expect(subject[:siren]).to eq('440117620') } + it { expect(subject[:capital_social]).to eq(537_100_000) } + it { expect(subject[:numero_tva_intracommunautaire]).to eq('FR27440117620') } + it { expect(subject[:forme_juridique]).to eq('SA à conseil d\'administration (s.a.i.)') } it { expect(subject[:forme_juridique_code]).to eq('5599') } it { expect(subject[:nom_commercial]).to eq('GRTGAZ') } it { expect(subject[:raison_sociale]).to eq('GRTGAZ') } @@ -155,22 +157,80 @@ describe API::V1::DossiersController do it { expect(subject.keys).to match_array(field_list) } end + describe 'pieces_justificatives' do + let(:field_list) { [ + :url] } + subject { super()[:pieces_justificatives] } + + it { expect(subject.length).to eq 2 } + + describe 'first piece justificative' do + subject { super().first } + + it { expect(subject.keys.include?(:url)).to be_truthy } + it { expect(subject.keys.include?(:type_de_piece_justificative)).to be_truthy } + + describe 'type de piece justificative' do + let(:field_list) { [ + :id, + :libelle, + :description] } + subject { super()[:type_de_piece_justificative] } + + it { expect(subject.keys.include?(:id)).to be_truthy } + it { expect(subject[:libelle]).to eq('RIB') } + it { expect(subject[:description]).to eq('Releve identité bancaire') } + end + end + end + + describe 'champs' do + let(:field_list) { [ + :url] } + subject { super()[:champs] } + + it { expect(subject.length).to eq 1 } + + describe 'first champs' do + subject { super().first } + + it { expect(subject.keys.include?(:value)).to be_truthy } + it { expect(subject.keys.include?(:type_de_champ)).to be_truthy } + + describe 'type de champ' do + let(:field_list) { [ + :id, + :libelle, + :description, + :order_place, + :type] } + subject { super()[:type_de_champ] } + + it { expect(subject.keys.include?(:id)).to be_truthy } + it { expect(subject[:libelle]).to eq('Description') } + it { expect(subject[:description]).to eq('description de votre projet') } + it { expect(subject.keys.include?(:order_place)).to be_truthy } + it { expect(subject[:type]).to eq('textarea') } + end + end + end + describe 'etablissement' do let(:field_list) { [ - :siret, - :siege_social, - :naf, - :libelle_naf, - :adresse, - :numero_voie, - :type_voie, - :nom_voie, - :complement_adresse, - :code_postal, - :localite, - :code_insee_localite + :siret, + :siege_social, + :naf, + :libelle_naf, + :adresse, + :numero_voie, + :type_voie, + :nom_voie, + :complement_adresse, + :code_postal, + :localite, + :code_insee_localite ] } - subject { super()[:etablissement]} + subject { super()[:etablissement] } it { expect(subject[:siret]).to eq('44011762001530') } it { expect(subject[:siege_social]).to eq(true) } diff --git a/spec/factories/type_de_champ.rb b/spec/factories/type_de_champ.rb index 2eee3b273..45b0f69e2 100644 --- a/spec/factories/type_de_champ.rb +++ b/spec/factories/type_de_champ.rb @@ -1,6 +1,6 @@ FactoryGirl.define do factory :type_de_champ do - libelle 'Libellé' + libelle 'Description' description 'description de votre projet' type_champ 'textarea' order_place 1 From 4993abf5f2027e04a2889d679ca37540a932206e Mon Sep 17 00:00:00 2001 From: Xavier J Date: Fri, 26 Feb 2016 13:59:03 +0100 Subject: [PATCH 3/6] Create fonction content_url to make public download link for cerfa and pj --- app/models/cerfa.rb | 8 +++++++- app/models/piece_justificative.rb | 8 +++++++- app/views/dossiers/_pieces_justificatives.html.haml | 4 ++-- spec/controllers/api/v1/dossiers_controller_spec.rb | 2 +- spec/controllers/api/v1/procedures_controller_spec.rb | 2 +- 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/app/models/cerfa.rb b/app/models/cerfa.rb index 8cf41d61e..bc06b2654 100644 --- a/app/models/cerfa.rb +++ b/app/models/cerfa.rb @@ -2,9 +2,15 @@ class Cerfa < ActiveRecord::Base belongs_to :dossier mount_uploader :content, CerfaUploader - validates :content, :file_size => { :maximum => 3.megabytes } + validates :content, :file_size => {:maximum => 3.megabytes} def empty? content.blank? end + + def content_url + unless content.url.nil? + (Downloader.new content, 'CERFA').url + end + end end \ No newline at end of file diff --git a/app/models/piece_justificative.rb b/app/models/piece_justificative.rb index 2b0780f1f..8cd6d2a80 100644 --- a/app/models/piece_justificative.rb +++ b/app/models/piece_justificative.rb @@ -7,9 +7,15 @@ class PieceJustificative < ActiveRecord::Base alias_attribute :type, :type_de_piece_justificative_id mount_uploader :content, PieceJustificativeUploader - validates :content, :file_size => { :maximum => 3.megabytes } + validates :content, :file_size => {:maximum => 3.megabytes} def empty? content.blank? end + + def content_url + unless content.url.nil? + (Downloader.new content, type_de_piece_justificative.libelle).url + end + end end diff --git a/app/views/dossiers/_pieces_justificatives.html.haml b/app/views/dossiers/_pieces_justificatives.html.haml index 943ff4a26..88ddbf7cc 100644 --- a/app/views/dossiers/_pieces_justificatives.html.haml +++ b/app/views/dossiers/_pieces_justificatives.html.haml @@ -12,7 +12,7 @@ - if user_signed_in? = 'Pièce fournie' - elsif gestionnaire_signed_in? - %a{ href: "#{(Downloader.new @facade.dossier.cerfa.content, 'CERFA').url}", target: '_blank' } Consulter + %a{ href: "#{@facade.dossier.cerfa.content_url}", target: '_blank' } Consulter - else = 'Pièce non fournie' @@ -27,7 +27,7 @@ - if user_signed_in? = 'Pièce fournie' - elsif gestionnaire_signed_in? - %a{ href: "#{(Downloader.new piece_justificative.content, piece_justificative.type_de_piece_justificative.libelle).url}", target: '_blank' } Consulter + %a{ href: "#{piece_justificative.content_url}", target: '_blank' } Consulter - else = 'Pièce non fournie' diff --git a/spec/controllers/api/v1/dossiers_controller_spec.rb b/spec/controllers/api/v1/dossiers_controller_spec.rb index d463fcaea..0ad2d3f4a 100644 --- a/spec/controllers/api/v1/dossiers_controller_spec.rb +++ b/spec/controllers/api/v1/dossiers_controller_spec.rb @@ -114,7 +114,7 @@ describe API::V1::DossiersController do let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure) } } let(:dossier_id) { dossier.id } let(:body) { JSON.parse(response.body, symbolize_names: true) } - let(:field_list) { [:id, :nom_projet, :created_at, :updated_at, :description, :archived, :mandataire_social, :entreprise, :etablissement] } + let(:field_list) { [:id, :nom_projet, :created_at, :updated_at, :description, :archived, :mandataire_social, :entreprise, :etablissement, :cerfa, :pieces_justificatives, :champs] } subject { body[:dossier] } it { expect(response.code).to eq('200') } diff --git a/spec/controllers/api/v1/procedures_controller_spec.rb b/spec/controllers/api/v1/procedures_controller_spec.rb index f3a080c6c..475bd44bf 100644 --- a/spec/controllers/api/v1/procedures_controller_spec.rb +++ b/spec/controllers/api/v1/procedures_controller_spec.rb @@ -37,7 +37,7 @@ describe API::V1::ProceduresController do let(:champ) { procedure.types_de_champ.first } it { expect(subject[:id]).to eq(champ.id) } it { expect(subject[:libelle]).to eq(champ.libelle) } - it { expect(subject[:type_champ]).to eq(champ.type_champ) } + it { expect(subject[:type]).to eq(champ.type_champ) } it { expect(subject[:order_place]).to eq(champ.order_place) } it { expect(subject[:description]).to eq(champ.description) } end From 3e62dd01fbcb785f3e1bff18ea43f7d1a144bbdc Mon Sep 17 00:00:00 2001 From: Xavier J Date: Fri, 26 Feb 2016 14:16:17 +0100 Subject: [PATCH 4/6] Pre-doc APIs --- app/controllers/api/v1/dossiers_controller.rb | 4 +- .../api/v1/procedures_controller.rb | 1 + doc/apipie_examples.json | 165 ++++++++++++++++++ .../api/v1/dossiers_controller_spec.rb | 18 +- .../api/v1/procedures_controller_spec.rb | 4 +- 5 files changed, 180 insertions(+), 12 deletions(-) create mode 100644 doc/apipie_examples.json diff --git a/app/controllers/api/v1/dossiers_controller.rb b/app/controllers/api/v1/dossiers_controller.rb index 543e70a0d..c05bdfaed 100644 --- a/app/controllers/api/v1/dossiers_controller.rb +++ b/app/controllers/api/v1/dossiers_controller.rb @@ -2,6 +2,7 @@ class API::V1::DossiersController < APIController api :GET, '/procedures/:procedure_id/dossiers/', 'Liste de tous les dossiers d\'une procédure' param :procedure_id, Integer, desc: "L'identifiant de la procédure", required: true + param :token, String, desc: "Token administrateur", required: true error code: 401, desc: "Non authorisé" error code: 404, desc: "Procédure inconnue" @@ -23,7 +24,8 @@ class API::V1::DossiersController < APIController api :GET, '/procedures/:procedure_id/dossiers/:id', 'Informations du dossier d\'une procédure' param :procedure_id, Integer, desc: "L'identifiant de la procédure", required: true - param :dossier_id, Integer, desc: "L'identifiant de la procédure", required: true + param :dossier_id, Integer, desc: "L'identifiant du dossier", required: true + param :token, String, desc: "Token administrateur", required: true error code: 401, desc: "Non authorisé" error code: 404, desc: "Procédure ou dossier inconnu" diff --git a/app/controllers/api/v1/procedures_controller.rb b/app/controllers/api/v1/procedures_controller.rb index 8cd157b62..5a76daa30 100644 --- a/app/controllers/api/v1/procedures_controller.rb +++ b/app/controllers/api/v1/procedures_controller.rb @@ -1,6 +1,7 @@ class API::V1::ProceduresController < APIController api :GET, '/procedures/:id', 'Informations concernant une procédure' param :id, Integer, desc: "L'identifiant de la procédure", required: true + param :token, String, desc: "Token administrateur", required: true error code: 401, desc: "Non authorisé" error code: 404, desc: "Procédure inconnue" diff --git a/doc/apipie_examples.json b/doc/apipie_examples.json new file mode 100644 index 000000000..968788243 --- /dev/null +++ b/doc/apipie_examples.json @@ -0,0 +1,165 @@ +{ + "dossiers#index": [ + { + "verb": "GET", + "path": "/api/v1/procedures/2/dossiers", + "versions": [ + "1.0" + ], + "query": "token=92cf04673cb66ab57a0c45e085b5140398ab4b6c", + "request_data": null, + "response_data": { + "dossiers": [ + { + "id": 2, + "nom_projet": "Demande de subvention dans le cadre d'accompagnement d'enfant à l'étranger", + "updated_at": "2008-09-01T08:05:00.000Z" + } + ], + "pagination": { + "page": 1, + "resultats_par_page": 12, + "nombre_de_page": 1 + } + }, + "code": "200", + "show_in_doc": 1, + "recorded": true + } + ], + "dossiers#show": [ + { + "verb": "GET", + "path": "/api/v1/procedures/1/dossiers/1", + "versions": [ + "1.0" + ], + "query": "token=7cba5df87cf134d07c3c467eb21b4f2a2b2605be", + "request_data": null, + "response_data": { + "dossier": { + "id": 1, + "nom_projet": "Demande de subvention dans le cadre d'accompagnement d'enfant à l'étranger", + "description": "Ma super description", + "created_at": "2008-09-01T08:05:00.000Z", + "updated_at": "2008-09-01T08:05:00.000Z", + "archived": false, + "mandataire_social": false, + "entreprise": { + "siren": "440117620", + "capital_social": 537100000, + "numero_tva_intracommunautaire": "FR27440117620", + "forme_juridique": "SA à conseil d'administration (s.a.i.)", + "forme_juridique_code": "5599", + "nom_commercial": "GRTGAZ", + "raison_sociale": "GRTGAZ", + "siret_siege_social": "44011762001530", + "code_effectif_entreprise": "51", + "date_creation": "2016-01-28T10:16:29.000Z", + "nom": null, + "prenom": null + }, + "etablissement": { + "siret": "44011762001530", + "siege_social": true, + "naf": "4950Z", + "libelle_naf": "Transports par conduites", + "adresse": "GRTGAZ\r IMMEUBLE BORA\r 6 RUE RAOUL NORDLING\r 92270 BOIS COLOMBES\r", + "numero_voie": "6", + "type_voie": "RUE", + "nom_voie": "RAOUL NORDLING", + "complement_adresse": "IMMEUBLE BORA", + "code_postal": "92270", + "localite": "BOIS COLOMBES", + "code_insee_localite": "92009" + }, + "cerfa": null, + "champs": [ + { + "value": null, + "type_de_champ": { + "id": 1, + "libelle": "Description", + "type": "textarea", + "order_place": 1, + "description": "description de votre projet" + } + } + ], + "pieces_justificatives": [ + { + "url": null, + "type_de_piece_justificative": { + "id": 1, + "libelle": "RIB", + "description": "Releve identité bancaire" + } + }, + { + "url": null, + "type_de_piece_justificative": { + "id": 2, + "libelle": "Attestation MSA", + "description": "recuperation automatique" + } + } + ] + } + }, + "code": "200", + "show_in_doc": 1, + "recorded": true + } + ], + "procedures#show": [ + { + "verb": "GET", + "path": "/api/v1/procedures/3", + "versions": [ + "1.0" + ], + "query": "token=cc00dc59ddc89f64c6310bb4e25c55eeb63ee89c", + "request_data": null, + "response_data": { + "procedure": { + "label": "Demande de subvention", + "link": "http://localhost", + "id": 3, + "description": "Demande de subvention à l'intention des associations", + "organisation": "Orga SGMAP", + "direction": "direction SGMAP", + "archived": false, + "geographic_information": { + "use_api_carto": false, + "quartiers_prioritaires": false, + "cadastre": false + }, + "types_de_champ": [ + { + "id": 3, + "libelle": "Description", + "type": "textarea", + "order_place": 1, + "description": "description de votre projet" + } + ], + "types_de_piece_justificative": [ + { + "id": 5, + "libelle": "RIB", + "description": "Releve identité bancaire" + }, + { + "id": 6, + "libelle": "Attestation MSA", + "description": "recuperation automatique" + } + ] + } + }, + "code": "200", + "show_in_doc": 1, + "recorded": true + } + ] +} \ No newline at end of file diff --git a/spec/controllers/api/v1/dossiers_controller_spec.rb b/spec/controllers/api/v1/dossiers_controller_spec.rb index 6cd51e41e..93cba35bd 100644 --- a/spec/controllers/api/v1/dossiers_controller_spec.rb +++ b/spec/controllers/api/v1/dossiers_controller_spec.rb @@ -8,9 +8,9 @@ describe API::V1::DossiersController do it { expect(described_class).to be < APIController } describe 'GET index' do - let(:response) { get :index, token: admin.api_token, procedure_id: procedure_id } + let(:retour) { get :index, token: admin.api_token, procedure_id: procedure_id } - subject { response } + subject { retour } context 'when procedure is not found' do let(:procedure_id) { 99_999_999 } @@ -26,10 +26,10 @@ describe API::V1::DossiersController do let(:procedure_id) { procedure.id } let(:date_creation) { Time.local(2008, 9, 1, 10, 5, 0) } let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') } } - let(:body) { JSON.parse(response.body, symbolize_names: true) } + let(:body) { JSON.parse(retour.body, symbolize_names: true) } it 'return REST code 200', :show_in_doc do - expect(response.code).to eq('200') + expect(retour.code).to eq('200') end it { expect(body).to have_key :pagination } @@ -59,7 +59,7 @@ describe API::V1::DossiersController do end context 'when there are multiple pages' do - let(:response) { get :index, token: admin.api_token, procedure_id: procedure_id, page: 2 } + let(:retour) { get :index, token: admin.api_token, procedure_id: procedure_id, page: 2 } let!(:dossier1) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') } let!(:dossier2) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') } @@ -80,8 +80,8 @@ describe API::V1::DossiersController do end describe 'GET show' do - let(:response) { get :show, token: admin.api_token, procedure_id: procedure_id, id: dossier_id } - subject { response } + let(:retour) { get :show, token: admin.api_token, procedure_id: procedure_id, id: dossier_id } + subject { retour } context 'when procedure is not found' do let(:procedure_id) { 99_999_999 } @@ -115,12 +115,12 @@ describe API::V1::DossiersController do let(:date_creation) { Time.local(2008, 9, 1, 10, 5, 0) } let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure) } } let(:dossier_id) { dossier.id } - let(:body) { JSON.parse(response.body, symbolize_names: true) } + let(:body) { JSON.parse(retour.body, symbolize_names: true) } let(:field_list) { [:id, :nom_projet, :created_at, :updated_at, :description, :archived, :mandataire_social, :entreprise, :etablissement, :cerfa, :pieces_justificatives, :champs] } subject { body[:dossier] } it 'return REST code 200', :show_in_doc do - expect(response.code).to eq('200') + expect(retour.code).to eq('200') end it { expect(subject[:id]).to eq(dossier.id) } it { expect(subject[:nom_projet]).to eq(dossier.nom_projet) } diff --git a/spec/controllers/api/v1/procedures_controller_spec.rb b/spec/controllers/api/v1/procedures_controller_spec.rb index f6b88bfee..0fe9a5dcb 100644 --- a/spec/controllers/api/v1/procedures_controller_spec.rb +++ b/spec/controllers/api/v1/procedures_controller_spec.rb @@ -15,7 +15,7 @@ describe API::V1::ProceduresController do it { expect(subject.status).to eq(404) } end context 'when procedure exist' do - let(:procedure) { create(:procedure, administrateur: admin) } + let(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ, administrateur: admin) } subject { get :show, id: procedure, token: admin.api_token } it 'return REST code 200', :show_in_doc do @@ -32,7 +32,7 @@ describe API::V1::ProceduresController do it { expect(subject[:label]).to eq(procedure.libelle) } it { expect(subject[:description]).to eq(procedure.description) } it { expect(subject[:organisation]).to eq(procedure.organisation) } - it { expect(subject[:direction]).to eq(procedure.direction) } + it { expect(subject[:direction]).to eq(proced,ure.direction) } it { expect(subject[:link]).to eq(procedure.lien_demarche) } it { expect(subject[:archived]).to eq(procedure.archived) } it { is_expected.to have_key(:types_de_champ) } From 9c1268fdd5f66ad2ce8d564c231edefaf83f6a48 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 29 Feb 2016 15:15:44 +0100 Subject: [PATCH 5/6] Add statistiques API for dashboard --- Gemfile | 1 + .../api/statistiques_controller.rb | 19 +++++++++++++++++++ config/routes.rb | 4 ++++ spec/controllers/api/statistiques_spec.rb | 12 ++++++++++++ 4 files changed, 36 insertions(+) create mode 100644 app/controllers/api/statistiques_controller.rb create mode 100644 spec/controllers/api/statistiques_spec.rb diff --git a/Gemfile b/Gemfile index 980dda77b..3c2d815a9 100644 --- a/Gemfile +++ b/Gemfile @@ -49,6 +49,7 @@ gem 'draper' #Gestion des comptes utilisateurs gem 'devise' gem 'openid_connect' + gem 'rest-client' gem 'carrierwave' diff --git a/app/controllers/api/statistiques_controller.rb b/app/controllers/api/statistiques_controller.rb new file mode 100644 index 000000000..e8263aac5 --- /dev/null +++ b/app/controllers/api/statistiques_controller.rb @@ -0,0 +1,19 @@ +class API::StatistiquesController < ApplicationController + + def dossiers_stats + render json: { + total: total_dossiers, + mois: dossiers_mois + } + end + + private + + def total_dossiers + Dossier.all.size + end + + def dossiers_mois + Dossier.where(created_at: (1.month.ago)..Time.now).size + end +end diff --git a/config/routes.rb b/config/routes.rb index 3048e0e9f..93183e0c7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -116,6 +116,10 @@ Rails.application.routes.draw do resources :dossiers, only: [:index, :show] end end + + namespace :statistiques do + get 'dossiers' => '/api/statistiques#dossiers_stats' + end end apipie diff --git a/spec/controllers/api/statistiques_spec.rb b/spec/controllers/api/statistiques_spec.rb new file mode 100644 index 000000000..0f3a85c39 --- /dev/null +++ b/spec/controllers/api/statistiques_spec.rb @@ -0,0 +1,12 @@ +require 'spec_helper' + +describe API::StatistiquesController, type: :controller do + describe '#GET dossiers_stats' do + + before do + get :dossiers_stats + end + + it { expect(response.status).to eq 200 } + end +end From 4282ab11be1b31b6e574aa2e4f3ed807991df634 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 29 Feb 2016 15:48:58 +0100 Subject: [PATCH 6/6] Exclude draft dossier on statistiques --- app/controllers/api/statistiques_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/statistiques_controller.rb b/app/controllers/api/statistiques_controller.rb index e8263aac5..b920f47c6 100644 --- a/app/controllers/api/statistiques_controller.rb +++ b/app/controllers/api/statistiques_controller.rb @@ -10,10 +10,10 @@ class API::StatistiquesController < ApplicationController private def total_dossiers - Dossier.all.size + Dossier.where.not(state: :draft).size end def dossiers_mois - Dossier.where(created_at: (1.month.ago)..Time.now).size + Dossier.where.not(state: :draft).where(created_at: (1.month.ago)..Time.now).size end end