From 16f17e38d86ff1decd52b64fc7e04e294e87419f Mon Sep 17 00:00:00 2001 From: Karol Date: Mon, 5 Aug 2024 22:56:50 +0200 Subject: [PATCH] add proforma_version to account_link --- Gemfile.lock | 37 ++++++++++--------- app/controllers/account_links_controller.rb | 2 +- app/controllers/tasks_controller.rb | 32 ++++++++-------- app/models/account_link.rb | 2 + app/services/proforma_service/export_tasks.rb | 2 +- .../proforma_service/handle_export_confirm.rb | 3 +- app/services/proforma_service/import.rb | 2 +- app/views/account_links/_form.html.slim | 3 ++ app/views/account_links/show.html.slim | 3 ++ config/locales/de/common.yml | 2 +- config/locales/de/models.yml | 1 + config/locales/de/views/account_links.yml | 3 ++ config/locales/en/common.yml | 2 +- config/locales/en/models.yml | 1 + config/locales/en/views/account_links.yml | 3 ++ ...03_add_proforma_version_to_account_link.rb | 7 ++++ db/schema.rb | 3 +- .../collections_controller_spec.rb | 6 +-- spec/controllers/tasks_controller_spec.rb | 32 ++++++++++++++-- spec/models/account_link_spec.rb | 1 + .../proforma_service/export_tasks_spec.rb | 16 +++++++- .../handle_export_confirm_spec.rb | 27 ++++++++++++-- 22 files changed, 136 insertions(+), 54 deletions(-) create mode 100644 db/migrate/20240731205103_add_proforma_version_to_account_link.rb diff --git a/Gemfile.lock b/Gemfile.lock index edb4a5dbd..bfc60024c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -95,7 +95,7 @@ GEM bindex (0.8.1) binding_of_caller (1.0.1) debug_inspector (>= 1.2.0) - bootsnap (1.18.3) + bootsnap (1.18.4) msgpack (~> 1.2) bootstrap-will_paginate (1.0.0) will_paginate @@ -163,12 +163,12 @@ GEM factory_bot_rails (6.4.3) factory_bot (~> 6.4) railties (>= 5.0.0) - faraday (2.10.0) + faraday (2.10.1) faraday-net_http (>= 2.0, < 3.2) logger faraday-multipart (1.0.4) multipart-post (~> 2) - faraday-net_http (3.1.0) + faraday-net_http (3.1.1) net-http ffi (1.17.0) fugit (1.11.0) @@ -198,7 +198,7 @@ GEM rails-i18n rainbow (>= 2.2.2, < 4.0) terminal-table (>= 1.5.1) - image_processing (1.12.2) + image_processing (1.13.0) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) io-console (0.7.2) @@ -285,7 +285,7 @@ GEM net-smtp (0.5.0) net-protocol nio4r (2.7.3) - nokogiri (1.16.6) + nokogiri (1.16.7) mini_portile2 (~> 2.8.2) racc (~> 1.4) omniauth (2.1.2) @@ -304,7 +304,7 @@ GEM parser (3.3.4.0) ast (~> 2.4.1) racc - pg (1.5.6) + pg (1.5.7) proformaxml (1.5.0) activemodel (>= 5.2.3, < 8.0.0) activesupport (>= 5.2.3, < 8.0.0) @@ -332,7 +332,7 @@ GEM rspec-mocks (~> 3.12) rspec-support (~> 3.12) raabro (1.4.0) - racc (1.8.0) + racc (1.8.1) rack (3.1.7) rack-mini-profiler (3.3.1) rack (>= 1.2.0) @@ -408,7 +408,7 @@ GEM responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.3.2) + rexml (3.3.4) strscan rouge (4.3.0) rqrcode (2.2.0) @@ -436,7 +436,7 @@ GEM rspec-mocks (~> 3.13) rspec-support (~> 3.13) rspec-support (3.13.1) - rubocop (1.65.0) + rubocop (1.65.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -447,7 +447,7 @@ GEM rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.31.3) + rubocop-ast (1.32.0) parser (>= 3.3.1.0) rubocop-capybara (2.21.0) rubocop (~> 1.41) @@ -461,7 +461,7 @@ GEM rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rspec (3.0.3) + rubocop-rspec (3.0.4) rubocop (~> 1.61) rubocop-rspec_rails (2.30.0) rubocop (~> 1.61) @@ -474,8 +474,9 @@ GEM ruby-saml (1.16.0) nokogiri (>= 1.13.10) rexml - ruby-vips (2.2.1) + ruby-vips (2.2.2) ffi (~> 1.12) + logger rubyzip (2.3.2) sassc (2.4.0) ffi (~> 1.9) @@ -492,10 +493,10 @@ GEM rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) semantic_range (3.0.0) - sentry-rails (5.18.1) + sentry-rails (5.18.2) railties (>= 5.0) - sentry-ruby (~> 5.18.1) - sentry-ruby (5.18.1) + sentry-ruby (~> 5.18.2) + sentry-ruby (5.18.2) bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) set (1.1.0) @@ -527,7 +528,7 @@ GEM slim_lint (0.27.0) rubocop (>= 1.0, < 2.0) slim (>= 3.0, < 6.0) - solid_queue (0.3.3) + solid_queue (0.4.1) activejob (>= 7.1) activerecord (>= 7.1) concurrent-ruby (>= 1.3.1) @@ -539,7 +540,7 @@ GEM sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) - sprockets-rails (3.5.1) + sprockets-rails (3.5.2) actionpack (>= 6.1) activesupport (>= 6.1) sprockets (>= 3.0.0) @@ -586,7 +587,7 @@ GEM will_paginate (4.0.1) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.16) + zeitwerk (2.6.17) PLATFORMS ruby diff --git a/app/controllers/account_links_controller.rb b/app/controllers/account_links_controller.rb index 0d3afbd59..cfaed6d01 100644 --- a/app/controllers/account_links_controller.rb +++ b/app/controllers/account_links_controller.rb @@ -91,6 +91,6 @@ def set_user # Never trust parameters from the scary internet, only allow the following list through. def account_link_params - params.require(:account_link).permit(:push_url, :check_uuid_url, :api_key, :name) + params.require(:account_link).permit(:push_url, :check_uuid_url, :api_key, :name, :proforma_version) end end diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb index e64f3f88e..f770b6be5 100644 --- a/app/controllers/tasks_controller.rb +++ b/app/controllers/tasks_controller.rb @@ -85,7 +85,7 @@ def add_to_collection end def download - zip_file = ProformaService::ExportTask.call(task: @task, options: { version: params[:version] }) + zip_file = ProformaService::ExportTask.call(task: @task, options: {version: params[:version]}) send_data(zip_file.string, type: 'application/zip', filename: "task_#{@task.id}.zip", disposition: 'attachment') rescue ProformaXML::PostGenerateValidationError => e redirect_to :root, danger: JSON.parse(e.message).map {|msg| t("proforma_errors.#{msg}", default: msg) }.join('
') @@ -102,21 +102,21 @@ def import_start # rubocop:disable Metric/AbcSize, Metrics/MethodLength respond_to do |format| format.js { render layout: false } end - # rescue ProformaXML::ProformaError => e - # messages = prettify_import_errors(e) - # flash[:alert] = messages - # render json: { - # status: 'failure', - # message: t('.error', error: messages), - # actions: '', - # } - # rescue StandardError => e - # Sentry.capture_exception(e) - # render json: { - # status: 'failure', - # message: t('tasks.import.internal_error'), - # actions: '', - # } + rescue ProformaXML::ProformaError => e + messages = prettify_import_errors(e) + flash[:alert] = messages + render json: { + status: 'failure', + message: t('.error', error: messages), + actions: '', + } + rescue StandardError => e + Sentry.capture_exception(e) + render json: { + status: 'failure', + message: t('tasks.import.internal_error'), + actions: '', + } end def import_confirm # rubocop:disable Metric/AbcSize diff --git a/app/models/account_link.rb b/app/models/account_link.rb index beabdb760..7f3b51ba0 100644 --- a/app/models/account_link.rb +++ b/app/models/account_link.rb @@ -5,6 +5,8 @@ class AccountLink < ApplicationRecord validates :push_url, presence: true validates :api_key, presence: true validates :name, presence: true + validates :proforma_version, inclusion: {in: [*ProformaXML::SCHEMA_VERSIONS], allow_nil: true} + normalizes :proforma_version, with: ->(proforma_version) { proforma_version.presence } belongs_to :user diff --git a/app/services/proforma_service/export_tasks.rb b/app/services/proforma_service/export_tasks.rb index e1b7ecb4a..2db92be1f 100644 --- a/app/services/proforma_service/export_tasks.rb +++ b/app/services/proforma_service/export_tasks.rb @@ -2,7 +2,7 @@ module ProformaService class ExportTasks < ServiceBase - def initialize(tasks:, options:) + def initialize(tasks:, options: {}) super() @tasks = tasks @options = options diff --git a/app/services/proforma_service/handle_export_confirm.rb b/app/services/proforma_service/handle_export_confirm.rb index 9bcc2257c..d293ea2f8 100644 --- a/app/services/proforma_service/handle_export_confirm.rb +++ b/app/services/proforma_service/handle_export_confirm.rb @@ -18,7 +18,8 @@ def execute end account_link = AccountLink.find(@account_link_id) - zip_stream = ProformaService::ExportTask.call(task: @task, options: {description_format: 'md'}) + zip_stream = ProformaService::ExportTask.call(task: @task, + options: {description_format: 'md', version: account_link.proforma_version || ProformaXML::SCHEMA_VERSION_LATEST}) error = TaskService::PushExternal.call(zip: zip_stream, account_link:) [@task, error] diff --git a/app/services/proforma_service/import.rb b/app/services/proforma_service/import.rb index c03e4c058..88d703993 100644 --- a/app/services/proforma_service/import.rb +++ b/app/services/proforma_service/import.rb @@ -11,7 +11,7 @@ def initialize(zip:, user:) def execute if single_task? proforma_task = ProformaXML::Importer.call(zip: @zip) - ProformaService::ImportTask.call(proforma_task: proforma_task, user: @user) + ProformaService::ImportTask.call(proforma_task:, user: @user) else import_multi end diff --git a/app/views/account_links/_form.html.slim b/app/views/account_links/_form.html.slim index 881bea393..5e21ac804 100644 --- a/app/views/account_links/_form.html.slim +++ b/app/views/account_links/_form.html.slim @@ -15,6 +15,9 @@ .input-group = f.text_field :api_key, data: {toggle: 'tooltip', placement: 'bottom'}, title: t('.info.token'), class: 'form-control' = button_tag t('.button.generate'), type: 'button', class: 'generate-api-key-token btn btn-light' + .field-element.form-group + = f.label :proforma_version, AccountLink.human_attribute_name('proforma_version'), class: 'form-label' + = f.select :proforma_version, options_for_select(ProformaXML::SCHEMA_VERSIONS, @account_link.proforma_version), {include_blank: t('account_links.common.proforma_version.select_default', latest_version: ProformaXML::SCHEMA_VERSION_LATEST)}, {class: 'form-select'} .form-group .actions.btn-group role='group' = f.submit t('.button.save'), class: 'btn btn-important' diff --git a/app/views/account_links/show.html.slim b/app/views/account_links/show.html.slim index fed9837ce..dd5a40268 100644 --- a/app/views/account_links/show.html.slim +++ b/app/views/account_links/show.html.slim @@ -19,6 +19,9 @@ .row .col-auto.row-label = AccountLink.human_attribute_name('api_key') .col.row-value = @account_link.api_key + .row + .col-auto.row-label = AccountLink.human_attribute_name('proforma_version') + .col.row-value = @account_link.proforma_version.presence || t('account_links.common.proforma_version.select_default', latest_version: ProformaXML::SCHEMA_VERSION_LATEST) - if @account_link.shared_users.any? .row.vertical .col.row-label = t('account_links.show.shared_users') diff --git a/config/locales/de/common.yml b/config/locales/de/common.yml index 066dd3eed..da00ac9ea 100644 --- a/config/locales/de/common.yml +++ b/config/locales/de/common.yml @@ -4,6 +4,7 @@ de: app_name: CodeHarbor button: abort: Abbrechen + available_versions: Verfügbare ProFormA-XML Versionen back: Zurück cancel: Abbrechen close: Schließen @@ -27,7 +28,6 @@ de: sign_up: Registrieren update: Aktualisieren view: Ansehen - available_versions: "Verfügbare ProFormA-XML Versionen" 'yes': Ja created: Erstellt created_at: Erstellt am diff --git a/config/locales/de/models.yml b/config/locales/de/models.yml index fd73f77c7..74d966bf1 100644 --- a/config/locales/de/models.yml +++ b/config/locales/de/models.yml @@ -6,6 +6,7 @@ de: api_key: API-Schlüssel check_uuid_url: URL zum Überprüfen der UUID name: Name + proforma_version: Proforma Version push_url: Push-URL account_link_user: user: Benutzer:in diff --git a/config/locales/de/views/account_links.yml b/config/locales/de/views/account_links.yml index 8c2a1b839..1778ec143 100644 --- a/config/locales/de/views/account_links.yml +++ b/config/locales/de/views/account_links.yml @@ -1,6 +1,9 @@ --- de: account_links: + common: + proforma_version: + select_default: aktuellste Version (momentan %{latest_version}) edit: header: Bearbeiten des Account-Links form: diff --git a/config/locales/en/common.yml b/config/locales/en/common.yml index ba4fafe2b..0505ddb48 100644 --- a/config/locales/en/common.yml +++ b/config/locales/en/common.yml @@ -4,6 +4,7 @@ en: app_name: CodeHarbor button: abort: Abort + available_versions: Available ProFormA-XML versions back: Back cancel: Cancel close: Close @@ -28,7 +29,6 @@ en: update: Update view: View 'yes': 'yes' - available_versions: "Available ProFormA-XML versions" created: Created created_at: Created at created_by: Created by diff --git a/config/locales/en/models.yml b/config/locales/en/models.yml index be7c8a163..14390b5de 100644 --- a/config/locales/en/models.yml +++ b/config/locales/en/models.yml @@ -6,6 +6,7 @@ en: api_key: API key check_uuid_url: Check UUID URL name: Name + proforma_version: Proforma version push_url: Push URL account_link_user: user: User diff --git a/config/locales/en/views/account_links.yml b/config/locales/en/views/account_links.yml index 072deb9a9..65399883a 100644 --- a/config/locales/en/views/account_links.yml +++ b/config/locales/en/views/account_links.yml @@ -1,6 +1,9 @@ --- en: account_links: + common: + proforma_version: + select_default: latest (currently %{latest_version}) edit: header: Editing Account Link form: diff --git a/db/migrate/20240731205103_add_proforma_version_to_account_link.rb b/db/migrate/20240731205103_add_proforma_version_to_account_link.rb new file mode 100644 index 000000000..c47df1e7a --- /dev/null +++ b/db/migrate/20240731205103_add_proforma_version_to_account_link.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddProformaVersionToAccountLink < ActiveRecord::Migration[7.1] + def change + add_column :account_links, :proforma_version, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 542373e9c..b8f9e59b9 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_07_03_221801) do +ActiveRecord::Schema[7.1].define(version: 2024_07_31_205103) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -29,6 +29,7 @@ t.string "api_key" t.string "name" t.string "check_uuid_url" + t.string "proforma_version" t.index ["user_id"], name: "index_account_links_on_user_id" end diff --git a/spec/controllers/collections_controller_spec.rb b/spec/controllers/collections_controller_spec.rb index a8829a51d..8400ce022 100644 --- a/spec/controllers/collections_controller_spec.rb +++ b/spec/controllers/collections_controller_spec.rb @@ -380,10 +380,10 @@ let(:collection) { create(:collection, valid_attributes.merge(users: [user], tasks:)) } let(:tasks) { create_list(:task, 2) } let(:zip) { instance_double(StringIO, string: 'dummy') } + let(:proforma_version) { '2.1' } + let(:get_request) { get :download_all, params: {id: collection.id, version: proforma_version} } - let(:get_request) { get :download_all, params: {id: collection.id} } - - before { allow(ProformaService::ExportTasks).to receive(:call).with(tasks: collection.reload.tasks).and_return(zip) } + before { allow(ProformaService::ExportTasks).to receive(:call).with(tasks: collection.reload.tasks, options: {version: proforma_version}).and_return(zip) } it do get_request diff --git a/spec/controllers/tasks_controller_spec.rb b/spec/controllers/tasks_controller_spec.rb index 80be2427a..f6fffa21b 100644 --- a/spec/controllers/tasks_controller_spec.rb +++ b/spec/controllers/tasks_controller_spec.rb @@ -631,12 +631,13 @@ end describe 'GET #download' do - subject(:get_request) { get :download, params: {id: task.id} } + subject(:get_request) { get :download, params: {id: task.id, version: proforma_version} } let(:task) { create(:task, valid_attributes) } let(:zip) { instance_double(StringIO, string: 'dummy') } + let(:proforma_version) { '2.1' } - before { allow(ProformaService::ExportTask).to receive(:call).with(task:).and_return(zip) } + before { allow(ProformaService::ExportTask).to receive(:call).with(task:, options: {version: proforma_version}).and_return(zip) } context 'when not signed in' do it 'redirects to user sign in page' do @@ -1013,15 +1014,17 @@ before do sign_in user allow(ProformaService::ExportTask).to receive(:call) - .with(task: an_instance_of(Task), options: {description_format: 'md'}) + .with(task: an_instance_of(Task), options: {description_format: 'md', version: export_proforma_version}) .and_return('zip stream') allow(TaskService::PushExternal).to receive(:call) .with(zip: 'zip stream', account_link:) .and_return(error) end + let(:proforma_version) {} + let(:export_proforma_version) { '2.1' } let!(:task) { create(:task, valid_attributes) } - let(:account_link) { create(:account_link, user: account_link_user) } + let(:account_link) { create(:account_link, user: account_link_user, proforma_version:) } let(:account_link_user) { user } let(:post_request) do post :export_external_confirm, params: {push_type:, id: task.id, account_link: account_link.id}, format: :json, @@ -1082,6 +1085,27 @@ expect(response).to have_http_status(:internal_server_error) end end + + context 'when proforma_version is set' do + let(:proforma_version) { '2.1' } + + it 'renders correct response' do + post_request + + expect(response).to have_http_status(:success) + end + + context 'when proforma_version is 2.0' do + let(:proforma_version) { '2.0' } + let(:export_proforma_version) { '2.0' } + + it 'renders correct response' do + post_request + + expect(response).to have_http_status(:success) + end + end + end end describe 'POST #add_to_collection' do diff --git a/spec/models/account_link_spec.rb b/spec/models/account_link_spec.rb index 5c299534d..b816850e4 100644 --- a/spec/models/account_link_spec.rb +++ b/spec/models/account_link_spec.rb @@ -8,6 +8,7 @@ it { is_expected.to validate_presence_of(:push_url) } it { is_expected.to validate_presence_of(:api_key) } it { is_expected.to validate_presence_of(:name) } + it { is_expected.to validate_inclusion_of(:proforma_version).in_array(%w[2.1 2.0]).allow_nil } it { is_expected.to belong_to(:user) } end diff --git a/spec/services/proforma_service/export_tasks_spec.rb b/spec/services/proforma_service/export_tasks_spec.rb index 52843a3ee..559bc0926 100644 --- a/spec/services/proforma_service/export_tasks_spec.rb +++ b/spec/services/proforma_service/export_tasks_spec.rb @@ -4,8 +4,10 @@ RSpec.describe ProformaService::ExportTasks do describe '.new' do - subject(:export_service) { described_class.new(tasks:) } + subject(:export_service) { described_class.new(tasks:, options:) } + let(:options) { {version: proforma_version} } + let(:proforma_version) { '2.1' } let(:tasks) { build_list(:task, 2) } it 'assigns task' do @@ -14,8 +16,9 @@ end describe '#execute' do - subject(:export_service) { described_class.call(tasks:) } + subject(:export_service) { described_class.call(tasks:, options:) } + let(:options) { {version: nil} } let(:tasks) { create_list(:task, 2) } let(:user) { create(:user) } let(:zip_files) do @@ -57,5 +60,14 @@ expect(zip_files.count).to be 10 end end + + context 'when proforma_version is 2.0' do + let(:proforma_version) { '2.0' } + + it 'calls ExportTask with correct arguments' do + expect(ProformaService::ExportTask).to receive(:call).twice.and_call_original + export_service + end + end end end diff --git a/spec/services/proforma_service/handle_export_confirm_spec.rb b/spec/services/proforma_service/handle_export_confirm_spec.rb index bde38b586..0da55f373 100644 --- a/spec/services/proforma_service/handle_export_confirm_spec.rb +++ b/spec/services/proforma_service/handle_export_confirm_spec.rb @@ -38,7 +38,8 @@ let(:user) { create(:user) } let!(:task) { create(:task, user:).reload } let(:push_type) { 'export' } - let(:account_link) { create(:account_link, user:) } + let(:account_link) { create(:account_link, user:, proforma_version:) } + let(:proforma_version) {} before do allow(ProformaService::ExportTask).to(receive(:call)).and_return('zip_stream') @@ -51,7 +52,7 @@ it 'calls ExportTask-service with correct arguments' do handle_export_confirm - expect(ProformaService::ExportTask).to have_received(:call).with(task:, options: {description_format: 'md'}) + expect(ProformaService::ExportTask).to have_received(:call).with(task:, options: {description_format: 'md', version: '2.1'}) end it 'calls PushExternal-service with correct arguments' do @@ -77,14 +78,14 @@ it 'does not call ExportTask-service with old task' do handle_export_confirm expect(ProformaService::ExportTask).to have_received(:call).with( - task: not_have_attributes(uuid: task.uuid), options: {description_format: 'md'} + task: not_have_attributes(uuid: task.uuid), options: {description_format: 'md', version: '2.1'} ) end it 'only calls ExportTask-service after uuid has been set' do handle_export_confirm expect(ProformaService::ExportTask).to have_received(:call).with( - task: not_have_attributes(uuid: nil), options: {description_format: 'md'} + task: not_have_attributes(uuid: nil), options: {description_format: 'md', version: '2.1'} ) end @@ -93,5 +94,23 @@ expect(TaskService::PushExternal).to have_received(:call).with(zip: 'zip_stream', account_link:) end end + + context 'when account_link has a proforma_version' do + let(:proforma_version) { '2.1' } + + it 'calls ExportTask-service with correct arguments' do + handle_export_confirm + expect(ProformaService::ExportTask).to have_received(:call).with(task:, options: {description_format: 'md', version: '2.1'}) + end + + context 'when proforma_version is 2.0' do + let(:proforma_version) { '2.0' } + + it 'calls ExportTask-service with correct arguments' do + handle_export_confirm + expect(ProformaService::ExportTask).to have_received(:call).with(task:, options: {description_format: 'md', version: '2.0'}) + end + end + end end end