From 685adba8dba9ca848101476a3887698ee945abc3 Mon Sep 17 00:00:00 2001 From: Tom Tuddenham Date: Tue, 25 Jul 2023 21:40:39 +0930 Subject: [PATCH] working under wsl, ruby 3.0.6 fix i18n fix selenium specs --- .gitignore | 3 +- .ruby-version | 2 +- Gemfile | 1 + Gemfile.lock | 6 +- ...0230526212613_convert_to_active_storage.rb | 38 +++++++--- db/schema.rb | 69 ++++++++++--------- lib/fat_free_crm/errors.rb | 12 +--- lib/fat_free_crm/i18n.rb | 2 +- spec/features/support/browser.rb | 14 ++-- 9 files changed, 81 insertions(+), 66 deletions(-) diff --git a/.gitignore b/.gitignore index 065e9487ff..6ba0b9feb7 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,5 @@ Design .passenger .vagrant -storage/ \ No newline at end of file +storage/ +.byebug_history diff --git a/.ruby-version b/.ruby-version index a603bb50a2..818bd47abf 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.7.5 +3.0.6 diff --git a/Gemfile b/Gemfile index ee15d9ed13..e94fa586c3 100644 --- a/Gemfile +++ b/Gemfile @@ -72,6 +72,7 @@ group :development, :test do end group :test do + gem 'webrick' gem 'capybara' gem 'selenium-webdriver' gem 'webdrivers' diff --git a/Gemfile.lock b/Gemfile.lock index b3b6b721e0..eb7733a8af 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -159,7 +159,7 @@ GEM devise-i18n (1.11.0) devise (>= 4.9.0) diff-lcs (1.5.0) - dynamic_form (1.1.4) + dynamic_form (1.2.0) email_reply_parser_ffcrm (0.5.0) erubi (1.12.0) execjs (2.8.1) @@ -403,7 +403,7 @@ GEM sprockets-rails tilt select2-rails (4.0.13) - selenium-webdriver (4.9.0) + selenium-webdriver (4.10.0) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) @@ -439,6 +439,7 @@ GEM nokogiri (~> 1.6) rubyzip (>= 1.3.0) selenium-webdriver (~> 4.0) + webrick (1.8.1) websocket (1.2.9) websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) @@ -529,6 +530,7 @@ DEPENDENCIES tzinfo-data uglifier webdrivers + webrick will_paginate zeus diff --git a/db/migrate/20230526212613_convert_to_active_storage.rb b/db/migrate/20230526212613_convert_to_active_storage.rb index b51d269b43..b2fa8d38c5 100644 --- a/db/migrate/20230526212613_convert_to_active_storage.rb +++ b/db/migrate/20230526212613_convert_to_active_storage.rb @@ -15,17 +15,33 @@ def up 'LASTVAL()' end - ActiveRecord::Base.connection.raw_connection.prepare(<<-SQL) - INSERT INTO active_storage_blobs ( - `key`, filename, content_type, metadata, byte_size, checksum, created_at - ) VALUES (?, ?, ?, '{}', ?, ?, ?) - SQL - - ActiveRecord::Base.connection.raw_connection.prepare(<<-SQL) - INSERT INTO active_storage_attachments ( - name, record_type, record_id, blob_id, created_at - ) VALUES (?, ?, ?, #{get_blob_id}, ?) - SQL + ActiveRecord::Base.connection.raw_connection.then do |conn| + if conn.is_a?(PG::Connection) + conn.prepare('active_storage_blobs', <<-SQL) + INSERT INTO active_storage_blobs ( + key, filename, content_type, metadata, byte_size, checksum, created_at + ) VALUES ($1, $2, $3, '{}', $4, $5, $6) + SQL + + conn.prepare('active_storage_attachments', <<-SQL) + INSERT INTO active_storage_attachments ( + name, record_type, record_id, blob_id, created_at + ) VALUES ($1, $2, $3, #{get_blob_id}, $4) + SQL + else + conn.raw_connection.prepare(<<-SQL) + INSERT INTO active_storage_blobs ( + `key`, filename, content_type, metadata, byte_size, checksum, created_at + ) VALUES (?, ?, ?, '{}', ?, ?, ?) + SQL + + conn.raw_connection.prepare(<<-SQL) + INSERT INTO active_storage_attachments ( + name, record_type, record_id, blob_id, created_at + ) VALUES (?, ?, ?, #{get_blob_id}, ?) + SQL + end + end Rails.application.eager_load! models = ActiveRecord::Base.descendants.reject { |model| model.abstract_class? || model == ActionMailbox::InboundEmail || model == ActionText::RichText } diff --git a/db/schema.rb b/db/schema.rb index 5472b66f0f..840768ed4b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -12,7 +12,10 @@ ActiveRecord::Schema.define(version: 2023_05_26_212613) do - create_table "account_contacts", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "account_contacts", id: :serial, force: :cascade do |t| t.integer "account_id" t.integer "contact_id" t.datetime "deleted_at" @@ -21,7 +24,7 @@ t.index ["account_id", "contact_id"], name: "index_account_contacts_on_account_id_and_contact_id" end - create_table "account_opportunities", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "account_opportunities", id: :serial, force: :cascade do |t| t.integer "account_id" t.integer "opportunity_id" t.datetime "deleted_at" @@ -30,7 +33,7 @@ t.index ["account_id", "opportunity_id"], name: "index_account_opportunities_on_account_id_and_opportunity_id" end - create_table "accounts", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "accounts", id: :serial, force: :cascade do |t| t.integer "user_id" t.integer "assigned_to" t.string "name", limit: 64, default: "", null: false @@ -53,7 +56,7 @@ t.index ["user_id", "name", "deleted_at"], name: "index_accounts_on_user_id_and_name_and_deleted_at", unique: true end - create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false t.string "record_type", null: false t.bigint "record_id", null: false @@ -63,7 +66,7 @@ t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true end - create_table "active_storage_blobs", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "active_storage_blobs", force: :cascade do |t| t.string "key", null: false t.string "filename", null: false t.string "content_type" @@ -75,13 +78,13 @@ t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true end - create_table "active_storage_variant_records", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "active_storage_variant_records", force: :cascade do |t| t.bigint "blob_id", null: false t.string "variation_digest", null: false t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true end - create_table "activities", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "activities", id: :serial, force: :cascade do |t| t.integer "user_id" t.string "subject_type" t.integer "subject_id" @@ -94,7 +97,7 @@ t.index ["user_id"], name: "index_activities_on_user_id" end - create_table "addresses", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "addresses", id: :serial, force: :cascade do |t| t.string "street1" t.string "street2" t.string "city", limit: 64 @@ -111,7 +114,7 @@ t.index ["addressable_id", "addressable_type"], name: "index_addresses_on_addressable_id_and_addressable_type" end - create_table "avatars", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "avatars", id: :serial, force: :cascade do |t| t.integer "user_id" t.string "entity_type" t.integer "entity_id" @@ -122,7 +125,7 @@ t.datetime "updated_at" end - create_table "campaigns", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "campaigns", id: :serial, force: :cascade do |t| t.integer "user_id" t.integer "assigned_to" t.string "name", limit: 64, default: "", null: false @@ -147,7 +150,7 @@ t.index ["user_id", "name", "deleted_at"], name: "index_campaigns_on_user_id_and_name_and_deleted_at", unique: true end - create_table "comments", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "comments", id: :serial, force: :cascade do |t| t.integer "user_id" t.string "commentable_type" t.integer "commentable_id" @@ -159,7 +162,7 @@ t.string "state", limit: 16, default: "Expanded", null: false end - create_table "contact_opportunities", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "contact_opportunities", id: :serial, force: :cascade do |t| t.integer "contact_id" t.integer "opportunity_id" t.string "role", limit: 32 @@ -169,7 +172,7 @@ t.index ["contact_id", "opportunity_id"], name: "index_contact_opportunities_on_contact_id_and_opportunity_id" end - create_table "contacts", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "contacts", id: :serial, force: :cascade do |t| t.integer "user_id" t.integer "lead_id" t.integer "assigned_to" @@ -201,7 +204,7 @@ t.index ["user_id", "last_name", "deleted_at"], name: "id_last_name_deleted", unique: true end - create_table "emails", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "emails", id: :serial, force: :cascade do |t| t.string "imap_message_id", null: false t.integer "user_id" t.string "mediator_type" @@ -222,7 +225,7 @@ t.index ["mediator_id", "mediator_type"], name: "index_emails_on_mediator_id_and_mediator_type" end - create_table "field_groups", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "field_groups", id: :serial, force: :cascade do |t| t.string "name", limit: 64 t.string "label", limit: 128 t.integer "position" @@ -233,7 +236,7 @@ t.string "klass_name", limit: 32 end - create_table "fields", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "fields", id: :serial, force: :cascade do |t| t.string "type" t.integer "field_group_id" t.integer "position" @@ -260,13 +263,13 @@ t.index ["name"], name: "index_fields_on_name" end - create_table "groups", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "groups", id: :serial, force: :cascade do |t| t.string "name" t.datetime "created_at" t.datetime "updated_at" end - create_table "groups_users", id: false, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "groups_users", id: false, force: :cascade do |t| t.integer "group_id" t.integer "user_id" t.index ["group_id", "user_id"], name: "index_groups_users_on_group_id_and_user_id" @@ -274,7 +277,7 @@ t.index ["user_id"], name: "index_groups_users_on_user_id" end - create_table "leads", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "leads", id: :serial, force: :cascade do |t| t.integer "user_id" t.integer "campaign_id" t.integer "assigned_to" @@ -306,7 +309,7 @@ t.index ["user_id", "last_name", "deleted_at"], name: "index_leads_on_user_id_and_last_name_and_deleted_at", unique: true end - create_table "lists", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "lists", id: :serial, force: :cascade do |t| t.string "name" t.text "url" t.datetime "created_at" @@ -315,7 +318,7 @@ t.index ["user_id"], name: "index_lists_on_user_id" end - create_table "opportunities", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "opportunities", id: :serial, force: :cascade do |t| t.integer "user_id" t.integer "campaign_id" t.integer "assigned_to" @@ -336,7 +339,7 @@ t.index ["user_id", "name", "deleted_at"], name: "id_name_deleted", unique: true end - create_table "permissions", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "permissions", id: :serial, force: :cascade do |t| t.integer "user_id" t.string "asset_type" t.integer "asset_id" @@ -348,7 +351,7 @@ t.index ["user_id"], name: "index_permissions_on_user_id" end - create_table "preferences", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "preferences", id: :serial, force: :cascade do |t| t.integer "user_id" t.string "name", limit: 32, default: "", null: false t.text "value" @@ -357,7 +360,7 @@ t.index ["user_id", "name"], name: "index_preferences_on_user_id_and_name" end - create_table "sessions", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "sessions", id: :serial, force: :cascade do |t| t.string "session_id", null: false t.text "data" t.datetime "created_at" @@ -366,7 +369,7 @@ t.index ["updated_at"], name: "index_sessions_on_updated_at" end - create_table "settings", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "settings", id: :serial, force: :cascade do |t| t.string "name", limit: 32, default: "", null: false t.text "value" t.datetime "created_at" @@ -374,7 +377,7 @@ t.index ["name"], name: "index_settings_on_name" end - create_table "taggings", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "taggings", id: :serial, force: :cascade do |t| t.integer "tag_id" t.integer "taggable_id" t.integer "tagger_id" @@ -386,13 +389,13 @@ t.index ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context" end - create_table "tags", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "tags", id: :serial, force: :cascade do |t| t.string "name" t.integer "taggings_count", default: 0 t.index ["name"], name: "index_tags_on_name", unique: true end - create_table "tasks", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "tasks", id: :serial, force: :cascade do |t| t.integer "user_id" t.integer "assigned_to" t.integer "completed_by" @@ -413,7 +416,7 @@ t.index ["user_id", "name", "deleted_at"], name: "index_tasks_on_user_id_and_name_and_deleted_at", unique: true end - create_table "users", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "users", id: :serial, force: :cascade do |t| t.string "username", limit: 32, default: "", null: false t.string "email", limit: 254, default: "", null: false t.string "first_name", limit: 32 @@ -445,9 +448,9 @@ t.string "remember_token" t.datetime "remember_created_at" t.string "authentication_token" - t.string "confirmation_token" - t.timestamp "confirmed_at" - t.timestamp "confirmation_sent_at" + t.string "confirmation_token", limit: 255 + t.datetime "confirmed_at" + t.datetime "confirmation_sent_at" t.index ["authentication_token"], name: "index_users_on_authentication_token", unique: true t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true t.index ["email"], name: "index_users_on_email" @@ -456,7 +459,7 @@ t.index ["username", "deleted_at"], name: "index_users_on_username_and_deleted_at", unique: true end - create_table "versions", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "versions", id: :serial, force: :cascade do |t| t.string "item_type", null: false t.integer "item_id", null: false t.string "event", limit: 512, null: false diff --git a/lib/fat_free_crm/errors.rb b/lib/fat_free_crm/errors.rb index e7e3fb52e6..39fffa279a 100644 --- a/lib/fat_free_crm/errors.rb +++ b/lib/fat_free_crm/errors.rb @@ -21,16 +21,8 @@ def self.included(base) end end - def each_with_explicit_error - attribute_names.each do |attribute| - self[attribute].each do |error| - if error.start_with?('^') - yield :base, error[1..-1] # Drop the attribute. - else - yield attribute, error # This is default Rails3 behavior. - end - end - end + def each_with_explicit_error(&block) + @errors.each(&block) end end end diff --git a/lib/fat_free_crm/i18n.rb b/lib/fat_free_crm/i18n.rb index 3261fe9e61..f3cd817d89 100644 --- a/lib/fat_free_crm/i18n.rb +++ b/lib/fat_free_crm/i18n.rb @@ -14,7 +14,7 @@ def t(*args) if args.size == 1 super(args.first, default: args.first.to_s) elsif args.second.is_a?(Hash) - super(*args) + super(args.first, **args.second) elsif args.second.is_a?(Integer) super(args.first, count: args.second) else diff --git a/spec/features/support/browser.rb b/spec/features/support/browser.rb index e5235b4c7b..cbf9c4681d 100644 --- a/spec/features/support/browser.rb +++ b/spec/features/support/browser.rb @@ -11,18 +11,18 @@ if ENV['BROWSER'] == 'chrome' Capybara.register_driver :selenium do |app| - capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(chromeOptions: { args: %w[no-sandbox headless disable-gpu] }) - Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities) + options = Selenium::WebDriver::Remote::Capabilities.chrome(chromeOptions: { args: %w[no-sandbox headless disable-gpu] }) + Capybara::Selenium::Driver.new(app, browser: :chrome, options: options) end else # For local testing in an environment with a display or remote X server configured # such as WSL2, use NO_HEADLESS=1 bundle exec rspec spec/features # - # For modern firefox, use MARIONETTE=1 bundle exec rspec spec/features + # NB the marionette setting is deprecated. For modern firefox, install the geckodriver. Capybara.register_driver :selenium do |app| - options = Selenium::WebDriver::Firefox::Options.new - options.args << '--headless' unless ENV['NO_HEADLESS'].present? - capabilities = Selenium::WebDriver::Remote::Capabilities.firefox(marionette: ENV['MARIONETTE'].present?) - Capybara::Selenium::Driver.new(app, browser: :firefox, options: options, desired_capabilities: capabilities) + options = Selenium::WebDriver::Options.firefox + options.add_argument('-headless') unless ENV['NO_HEADLESS'].present? + + Capybara::Selenium::Driver.new(app, browser: :firefox, options: options) end end