diff --git a/.github/workflows/specs.yml b/.github/workflows/specs.yml new file mode 100644 index 000000000..3d33384fe --- /dev/null +++ b/.github/workflows/specs.yml @@ -0,0 +1,36 @@ +name: Specs + +on: push + +jobs: + specs: + runs-on: ubuntu-24.04 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install libvips and pdftoppm + run: | + sudo apt-get update -qq -o Acquire::Retries=3 + sudo apt-get install -y --fix-missing -qq -o Acquire::Retries=3 libvips poppler-utils + + - name: Install Ruby and run Bundler install with cache + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + + - name: Set timezone + uses: szenius/set-timezone@v2.0 + with: + timezoneLinux: Europe/Zurich + + - name: Run specs + env: + RAILS_ENV: test + RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }} + run: | + bin/rails db:setup + bin/rails test:prepare + bin/rspec + diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 128ce7760..271f2449d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,7 +3,7 @@ name: Tests on: push jobs: - test: + tests: runs-on: ubuntu-24.04 steps: @@ -25,11 +25,9 @@ jobs: with: timezoneLinux: Europe/Zurich - - name: Rails tests + - name: Run tests env: RAILS_ENV: test RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }} run: | - bin/rails db:setup - bin/rails test:prepare - bin/rspec + bin/rails test:all diff --git a/Aptfile b/Aptfile deleted file mode 100644 index e297bd2a6..000000000 --- a/Aptfile +++ /dev/null @@ -1,2 +0,0 @@ -libvips -libvips-dev diff --git a/Gemfile b/Gemfile index 0b39febe6..0ffdd8728 100644 --- a/Gemfile +++ b/Gemfile @@ -65,7 +65,7 @@ gem "hexapdf" gem "public_suffix" gem "rubyXL" gem "rexml" -gem "rubyzip", require: "zip" +gem "rubyzip", "~> 2.4.rc1", require: "zip" gem "parallel" gem "postmark-rails" @@ -94,7 +94,6 @@ group :development, :test do gem "rspec-rails" gem "faker" gem "factory_bot_rails" - gem "brakeman" end group :development do @@ -114,8 +113,10 @@ group :development do gem "rubocop-rails-omakase", require: false gem "rubocop-slim", require: false - gem "cloudflare" - gem "resolv" + gem "brakeman", require: false + + gem "cloudflare", require: false + gem "resolv", require: false gem "prosopite" gem "pg_query" diff --git a/Gemfile.lock b/Gemfile.lock index b1a8c5215..9dd494f3b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -376,12 +376,12 @@ GEM net-smtp (0.5.0) net-ssh (7.3.0) nio4r (2.7.4) - nokogiri (1.18.0) + nokogiri (1.18.1) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.18.0-arm64-darwin) + nokogiri (1.18.1-arm64-darwin) racc (~> 1.4) - nokogiri (1.18.0-x86_64-linux-gnu) + nokogiri (1.18.1-x86_64-linux-gnu) racc (~> 1.4) openssl (3.3.0) optimist (3.2.0) @@ -506,7 +506,7 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) - rbs (3.8.0) + rbs (3.8.1) logger rchardet19 (1.3.7) rdoc (6.10.0) @@ -590,7 +590,7 @@ GEM rubyXL (3.4.33) nokogiri (>= 1.10.8) rubyzip (>= 1.3.0) - rubyzip (2.3.2) + rubyzip (2.4.rc1) securerandom (0.4.1) simple_form (5.3.1) actionpack (>= 5.2) @@ -603,7 +603,7 @@ GEM temple thor tilt - solid_queue (1.1.0) + solid_queue (1.1.2) activejob (>= 7.1) activerecord (>= 7.1) concurrent-ruby (>= 1.3.1) @@ -629,7 +629,7 @@ GEM attr_extras (>= 6.2.4) diff-lcs patience_diff - tailwindcss-rails (3.0.0) + tailwindcss-rails (3.1.0) railties (>= 7.0.0) tailwindcss-ruby tailwindcss-ruby (3.4.17) @@ -746,7 +746,7 @@ DEPENDENCIES ruby-lsp-rails ruby-lsp-rspec rubyXL - rubyzip + rubyzip (~> 2.4.rc1) simple_form slim solid_queue diff --git a/app/models/invoice.rb b/app/models/invoice.rb index ac3623032..4e6e91cff 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -170,12 +170,11 @@ def send! # Leave some time for the invoice PDF to be uploaded MailTemplate.deliver_later(:invoice_created, invoice: self) update!(sent_at: Time.current) - close_or_open! - rescue => e - Error.report(e, - invoice_id: id, - emails: member.emails, - member_id: member_id) + rescue => e + Error.report(e, + invoice_id: id, + emails: member.emails, + member_id: member_id) end def mark_as_sent! diff --git a/app/models/organization.rb b/app/models/organization.rb index 5722ec09f..68c18ac11 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -24,17 +24,18 @@ class Organization < ApplicationRecord INPUT_FORM_MODES = %w[hidden visible required] DELIVERY_PDF_MEMBER_INFOS = %w[none phones food_note] MEMBERS_SUBDOMAINS = %w[membres mitglieder soci members] + ACTIVITY_PARTICIPATIONS_DEMANDED_LOGIC_DEFAULT = <<-LIQUID + {% if member.salary_basket %} + 0 + {% else %} + {{ membership.baskets | divided_by: membership.full_year_deliveries | times: membership.full_year_activity_participations | round }} + {% endif %} + LIQUID attribute :shop_delivery_open_last_day_end_time, :time_only attribute :icalendar_auth_token, :string, default: -> { SecureRandom.hex(16) } attribute :activity_participations_demanded_logic, :string, default: -> { - <<~LIQUID - {% if member.salary_basket %} - 0 - {% else %} - {{ membership.baskets | divided_by: membership.full_year_deliveries | times: membership.full_year_activity_participations | round }} - {% endif %} - LIQUID + ACTIVITY_PARTICIPATIONS_DEMANDED_LOGIC_DEFAULT } translated_attributes :invoice_info, :invoice_footer diff --git a/app/models/permission.rb b/app/models/permission.rb index 90f450577..29e0aa190 100644 --- a/app/models/permission.rb +++ b/app/models/permission.rb @@ -5,7 +5,6 @@ class Permission < ApplicationRecord RIGHTS = %i[read write].freeze SUPERADMIN_ID = 1 - SUPERADMIN_FEATURES = translated_attributes :name, required: true diff --git a/app/views/active_admin/_site_footer.html.slim b/app/views/active_admin/_site_footer.html.slim index 6bcb0e9ec..881d6ca68 100644 --- a/app/views/active_admin/_site_footer.html.slim +++ b/app/views/active_admin/_site_footer.html.slim @@ -1,11 +1,11 @@ footer class="pt-40" ul class="flex justify-center" role="group" - li = link_to updates_path, class: "inline-flex items-center px-2 py-1 no-underline text-sm font-medium text-gray-400 dark:text-gray-600 bg-white border border-gray-200 rounded-s-lg hover:bg-gray-100 hover:text-green-600 focus:z-10 focus:ring-2 focus:ring-green-700 focus:text-green-700 dark:bg-transparent dark:border-gray-800 dark:hover:text-green-500 dark:hover:bg-gray-700 dark:focus:ring-green-500 dark:focus:text-white" do + li = link_to updates_path, class: "action-item-button px-2 py-1 rounded-e-none text-gray-400 dark:text-gray-500" do = icon "gift", class: "w-5 h-5 me-2" = t(".updates") - li = link_to handbook_path, class: "inline-flex items-center px-2 py-1 no-underline text-sm font-medium text-gray-400 dark:text-gray-600 bg-white border border-l-0 border-gray-200 rounded-e-lg hover:bg-gray-100 hover:text-green-600 focus:z-10 focus:ring-2 focus:ring-green-700 focus:text-green-700 dark:bg-transparent dark:border-gray-800 dark:hover:text-green-500 dark:hover:bg-gray-700 dark:focus:ring-green-500 dark:focus:text-white" do + li = link_to handbook_path, class: "action-item-button px-2 py-1 border-s-0 rounded-s-none text-gray-400 dark:text-gray-500" do = icon "book-open", class: "w-5 h-5 me-2" = t(".handbook") diff --git a/app/views/admin_mailer/new_activity_participation_email.en.liquid b/app/views/admin_mailer/new_activity_participation_email.en.liquid index 9131973c2..8e41b8848 100644 --- a/app/views/admin_mailer/new_activity_participation_email.en.liquid +++ b/app/views/admin_mailer/new_activity_participation_email.en.liquid @@ -4,7 +4,7 @@ {% highlight_list %} Date: {{ activity.date_long }} - Time: {{ activity.period }} + Schedule: {{ activity.period }} Activity: {{ activity.title }} {% if activity.description %} Description: {{ activity.description }} diff --git a/app/views/admin_mailer/new_registration_email.en.liquid b/app/views/admin_mailer/new_registration_email.en.liquid index 5bb9caf8a..f9b894dc1 100644 --- a/app/views/admin_mailer/new_registration_email.en.liquid +++ b/app/views/admin_mailer/new_registration_email.en.liquid @@ -8,5 +8,5 @@ {% endif %} {% button member.admin_url %} - Access the member's page + Access member page {% endbutton %} diff --git a/app/views/mail_templates/activity_participation_rejected.en.liquid b/app/views/mail_templates/activity_participation_rejected.en.liquid index 7884d374d..9204af3a7 100644 --- a/app/views/mail_templates/activity_participation_rejected.en.liquid +++ b/app/views/mail_templates/activity_participation_rejected.en.liquid @@ -2,7 +2,7 @@ {% highlight_list %} Date: {{ activity.date_long }} - Time: {{ activity.period }} + Schedule: {{ activity.period }} Activity: {{ activity.title }} {% if activity.description %} Description: {{ activity.description }} diff --git a/app/views/mail_templates/invoice_overdue_notice.en.liquid b/app/views/mail_templates/invoice_overdue_notice.en.liquid index 7ede6844a..d95ec747d 100644 --- a/app/views/mail_templates/invoice_overdue_notice.en.liquid +++ b/app/views/mail_templates/invoice_overdue_notice.en.liquid @@ -12,6 +12,6 @@
You can view your invoices and payments at any time from your member page.
{% button member.billing_url %} - Access My Member Page + Access my member page {% endbutton %} {% endunless %} diff --git a/bin/update b/bin/update deleted file mode 100755 index 58bfaed51..000000000 --- a/bin/update +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env ruby -require 'fileutils' -include FileUtils - -# path to your application root. -APP_ROOT = File.expand_path('..', __dir__) - -def system!(*args) - system(*args) || abort("\n== Command #{args} failed ==") -end - -chdir APP_ROOT do - # This script is a way to update your development environment automatically. - # Add necessary update steps to this file. - - puts '== Installing dependencies ==' - system! 'gem install bundler --conservative' - system('bundle check') || system!('bundle install') - - # Install JavaScript dependencies if using Yarn - # system('bin/yarn') - - puts "\n== Updating database ==" - system! 'bin/rails db:migrate' - - puts "\n== Removing old logs and tempfiles ==" - system! 'bin/rails log:clear tmp:clear' - - puts "\n== Restarting application server ==" - system! 'bin/rails restart' -end diff --git a/config/application.rb b/config/application.rb index 894693949..8e00a9c53 100644 --- a/config/application.rb +++ b/config/application.rb @@ -29,7 +29,7 @@ class Application < Rails::Application config.time_zone = "Europe/Zurich" config.i18n.available_locales = %w[en fr de it] - config.i18n.default_locale = :fr + config.i18n.default_locale = :en config.i18n.fallbacks = true # :time must not be included here because of the tod gem diff --git a/config/locales/mail_template.yml b/config/locales/mail_template.yml index 0be0ee911..0e658ca24 100644 --- a/config/locales/mail_template.yml +++ b/config/locales/mail_template.yml @@ -3,32 +3,32 @@ _: default_subjects: activity_participation_rejected: _de: "Abgelehnte Aktivität \U0001F62C" - _en: "Activity Rejected \U0001F62C" + _en: "Activity rejected \U0001F62C" _fr: "Activité refusée \U0001F62C" _it: "Attività rifiutata \U0001F62C" activity_participation_reminder: _de: Bevorstehende Aktivität ({{ activity.date }}) - _en: Upcoming Activity ({{ activity.date }}) + _en: Upcoming activity ({{ activity.date }}) _fr: Activité à venir ({{ activity.date }}) _it: Attività futura ({{ activity.date }}) activity_participation_validated: _de: "Bestätigte Aktivität \U0001F389" - _en: "Activity Confirmed \U0001F389" + _en: "Activity confirmed \U0001F389" _fr: "Activité validée \U0001F389" _it: "Attività confermata \U0001F389" invoice_cancelled: _de: 'Stornierte Rechnung #{{ invoice.number }}' - _en: 'Cancelled Invoice #{{ invoice.number }}' + _en: 'Cancelled invoice #{{ invoice.number }}' _fr: 'Facture annulée #{{ invoice.number }}' _it: 'Fattura annullata #{{ invoice.number }}' invoice_created: _de: 'Neue Rechnung #{{ invoice.number }}' - _en: 'New Invoice #{{ invoice.number }}' + _en: 'New invoice #{{ invoice.number }}' _fr: 'Nouvelle facture #{{ invoice.number }}' _it: 'Nuova fattura #{{ invoice.number }}' invoice_overdue_notice: _de: "Mahnung #{{ invoice.overdue_notices_count }} der Rechnung #{{ invoice.number }} \U0001F62C" - _en: "Overdue Notice #{{ invoice.overdue_notices_count }} for Invoice #{{ invoice.number }} \U0001F62C" + _en: "Overdue notice #{{ invoice.overdue_notices_count }} for invoice #{{ invoice.number }} \U0001F62C" _fr: "Rappel #{{ invoice.overdue_notices_count }} de la facture #{{ invoice.number }} \U0001F62C" _it: "Promemoria #{{ invoice.overdue_notices_count }} della fattura #{{ invoice.number }} \U0001F62C" member_activated: @@ -38,42 +38,42 @@ _: _it: Benvenuto/a! member_validated: _de: Registrierung validiert! - _en: Registration Validated! + _en: Registration validated! _fr: Inscription validée! _it: Iscrizione confermata! membership_final_basket: _de: Letzte Tasche! - _en: Last Basket! + _en: Last basket! _fr: Dernier panier! _it: Ultimo cestino! membership_first_basket: _de: Erste Tasche des Jahres! - _en: First Basket of the Year! + _en: First basket of the year! _fr: Premier panier de l'année! _it: Primo cestino dell'anno! membership_initial_basket: _de: Erste Tasche! - _en: First Basket! + _en: First basket! _fr: Premier panier! _it: Primo cestino! membership_last_basket: _de: Letzte Tasche des Jahres! - _en: Last Basket of the Year! + _en: Last basket of the year! _fr: Dernier panier de l'année! _it: Ultimo cestino dell'anno! membership_last_trial_basket: _de: Letzte Probe Tasche! - _en: Last Trial Basket! + _en: Last trial basket! _fr: Dernier panier à l'essai! _it: Ultimo cestino da provare! membership_renewal: _de: Ihr Abonnement verlängern - _en: Renew Your Membership + _en: Renew your membership _fr: Renouvellement de votre abonnement _it: Rinnovo del vostro abbonamento membership_renewal_reminder: _de: Ihr Abonnement verlängern (Mahnung) - _en: Renew Your Membership (Reminder) + _en: Renew your membership (reminder) _fr: Renouvellement de votre abonnement (Rappel) _it: Rinnovo del vostro abbonamento (promemoria) description: diff --git a/lib/tasks/hostname.rake b/lib/tasks/hostname.rake index 088c2abf6..4b8b957ba 100644 --- a/lib/tasks/hostname.rake +++ b/lib/tasks/hostname.rake @@ -1,5 +1,6 @@ # frozen_string_literal: true +require "cloudflare" require "cloudflare-rails" namespace :hostname do diff --git a/lib/tenant.rb b/lib/tenant.rb index 5049551a8..7fb1e028c 100644 --- a/lib/tenant.rb +++ b/lib/tenant.rb @@ -66,7 +66,7 @@ def switch(tenant) end def connect(tenant) - raise "Only for use in Rails console" unless defined?(Rails::Console) + ensure_test_env_or_rails_console! enter(tenant) ActiveRecord::Base.connecting_to(shard: tenant.to_sym) @@ -74,7 +74,7 @@ def connect(tenant) # Only for use in console def disconnect - raise "Only for use in Rails console" unless defined?(Rails::Console) + ensure_test_env_or_rails_console! leave ActiveRecord::Base.connecting_to(shard: :default) @@ -112,4 +112,11 @@ def relevant_domain(domain) # Ignore tld locally Rails.env.local? ? domain.sld : domain.domain end + + def ensure_test_env_or_rails_console! + return if Rails.env.test? + return if defined?(Rails::Console) + + raise "Only for use in Rails console or test environment" + end end diff --git a/spec/jobs/billing/missing_activity_participations_invoicer_job_spec.rb b/spec/jobs/billing/missing_activity_participations_invoicer_job_spec.rb deleted file mode 100644 index d02d8502c..000000000 --- a/spec/jobs/billing/missing_activity_participations_invoicer_job_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe Billing::MissingActivityParticipationsInvoicerJob do - before { Current.org.update!(activity_price: 90, trial_baskets_count: 0) } - - specify "noop if no activty price" do - Current.org.update!(activity_price: 0) - - membership = create(:membership, activity_participations_demanded_annually: 2) - - expect { described_class.perform_later(membership) } - .not_to change(Invoice, :count) - end - - specify "noop if no missing activity participations" do - membership = create(:membership, activity_participations_demanded_annually: 0) - - expect { described_class.perform_later(membership) } - .not_to change(Invoice, :count) - end - - specify "create invoice and send invoice" do - membership = create(:membership, activity_participations_demanded_annually: 2) - - expect { - perform_enqueued_jobs { described_class.perform_later(membership) } - } - .to change(Invoice, :count).by(1) - .and change { membership.reload.activity_participations_missing }.to(0) - .and change { InvoiceMailer.deliveries.size }.by(1) - - invoice = Invoice.last - expect(invoice).to have_attributes( - member_id: membership.member_id, - date: Date.today, - missing_activity_participations_count: 2, - missing_activity_participations_fiscal_year: membership.fiscal_year, - entity_type: "ActivityParticipation", - entity_id: nil, - amount: 2 * 90) - expect(invoice).to be_sent - end - - specify "create invoice for previous year membership" do - Current.org.update!(fiscal_year_start_month: 5) - membership = travel_to "2021-01-06" do - create(:membership, activity_participations_demanded_annually: 2) - end - - expect { - perform_enqueued_jobs { described_class.perform_later(membership) } - }.to change(Invoice, :count).by(1) - - invoice = Invoice.last - expect(invoice).to have_attributes( - member_id: membership.member_id, - date: Date.today, - missing_activity_participations_fiscal_year: Current.org.fiscal_year_for(2020), - entity_type: "ActivityParticipation", - entity_id: nil) - expect(invoice).to be_sent - end -end diff --git a/spec/jobs/concerns/tenant_context_spec.rb b/spec/jobs/concerns/tenant_context_spec.rb deleted file mode 100644 index 9be3cb175..000000000 --- a/spec/jobs/concerns/tenant_context_spec.rb +++ /dev/null @@ -1,76 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe TenantContext do - specify "add current attributes and tenant last arguments" do - class DummyJob < ActiveJob::Base - include TenantContext - def perform(admin, name: nil) - admin.update!(name: name) - end - end - - admin = create(:admin, name: "Admin") - Current.session = create(:session, id: 42) - DummyJob.perform_later(admin, name: "Admin!") - - expect(enqueued_jobs.size).to eq(1) - job = enqueued_jobs.first - expect(job["arguments"]).to eq([ - { "_aj_globalid" => "gid://csa-admin/Admin/1" }, - { "name" => "Admin!", "_aj_ruby2_keywords" => [ "name" ] }, - { - "tenant" => "acme", - "current" => { "session" => { "_aj_globalid" => "gid://csa-admin/Session/42" }, "_aj_symbol_keys" => [ "session" ] }, "_aj_symbol_keys" => [] - } - ]) - - perform_enqueued_jobs - expect(enqueued_jobs.size).to eq(0) - expect(admin.reload.name).to eq("Admin!") - end - - specify "retry with the same current attributes and tenant last arguments" do - class DummyExceptionJob < ActiveJob::Base - include TenantContext - retry_on Exception, wait: :polynomially_longer, attempts: 2 - - def perform(foo) - raise Exception - end - end - - Current.session = create(:session, id: 42) - DummyExceptionJob.perform_later("bar") - - expect(enqueued_jobs.size).to eq(1) - job = enqueued_jobs.first - expect(job["arguments"]).to eq([ - "bar", - { - "tenant" => "acme", - "current" => { "session" => { "_aj_globalid" => "gid://csa-admin/Session/42" }, "_aj_symbol_keys" => [ "session" ] }, "_aj_symbol_keys" => [] - } - ]) - - # rescue Exception one time - perform_enqueued_jobs - - expect(enqueued_jobs.size).to eq(1) - job = enqueued_jobs.first - expect(job["arguments"]).to eq([ - "bar", - { - "tenant" => "acme", - "current" => { "session" => { "_aj_globalid" => "gid://csa-admin/Session/42" }, "_aj_symbol_keys" => [ "session" ] }, "_aj_symbol_keys" => [] - } - ]) - - begin - perform_enqueued_jobs - rescue Exception - end - expect(enqueued_jobs.size).to eq(0) - end -end diff --git a/spec/jobs/membership_renewal_job_spec.rb b/spec/jobs/membership_renewal_job_spec.rb deleted file mode 100644 index c1d19e9f6..000000000 --- a/spec/jobs/membership_renewal_job_spec.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe MembershipRenewalJob, freeze: "2022-01-01" do - let(:next_fy) { Current.org.fiscal_year_for(Date.today.year + 1) } - - it "raises when no next year deliveries" do - membership = create(:membership) - - expect(Delivery.between(next_fy.range).count).to be_zero - expect { - MembershipRenewalJob.perform_later(membership) - perform_enqueued_jobs - }.to raise_error(MembershipRenewal::MissingDeliveriesError) - end - - it "renews a membership without complements" do - create(:delivery, date: next_fy.beginning_of_year) - membership = create(:membership, - basket_quantity: 2, - basket_price: 42, - baskets_annual_price_change: 130, - depot_price: 3, - activity_participations_demanded_annually: 5, - activity_participations_annual_price_change: -60) - - membership.basket_size.update!(price: 41) - membership.depot.update!(price: 4) - - expect { - MembershipRenewalJob.perform_later(membership) - perform_enqueued_jobs - }.to change(Membership, :count).by(1) - - expect(Membership.last).to have_attributes( - member_id: membership.member_id, - basket_size_id: membership.basket_size_id, - basket_price: 41, - basket_quantity: 2, - baskets_annual_price_change: 130, - depot_id: membership.depot_id, - depot_price: 4, - activity_participations_demanded_annually: 5, - activity_participations_annual_price_change: -60, - started_on: next_fy.beginning_of_year, - ended_on: next_fy.end_of_year) - end -end diff --git a/spec/lib/tenant_spec.rb b/spec/lib/tenant_spec.rb deleted file mode 100644 index ee1f6695b..000000000 --- a/spec/lib/tenant_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe Tenant do - specify ".find_by host" do - expect(Tenant.find_by(host: "admin.acme.test")).to eq "acme" - expect(Tenant.find_by(host: "foo.acme.test")).to eq "acme" - expect(Tenant.find_by(host: "admin.unknown.test")).to be nil - end - - specify ".domain" do - expect(Tenant.current).to eq "acme" - expect(Tenant.domain).to eq "acme.test" - end - - specify ".inside? / .outside?" do - expect(Tenant.current).to eq "acme" - expect(Tenant).to be_inside - expect(Tenant).not_to be_outside - end - - specify ".exists?" do - expect(Tenant.exists?("acme")).to be true - expect(Tenant.exists?("unknown")).to be false - end - - specify ".connect to unknown tenant" do - expect(Tenant.current).to eq "acme" - expect { - Tenant.switch("unknown") { } - }.to raise_error("Unknown tenant 'unknown'") - end -end diff --git a/spec/mailers/activity_mailer_spec.rb b/spec/mailers/activity_mailer_spec.rb deleted file mode 100644 index 830de98aa..000000000 --- a/spec/mailers/activity_mailer_spec.rb +++ /dev/null @@ -1,99 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe ActivityMailer do - before { Current.org.update!(activity_phone: "+41 77 333 44 55") } - let(:member) { create(:member, emails: "example@csa-admin.org") } - let(:activity) { - create(:activity, - date: "24.03.2020", - start_time: Time.zone.parse("8:30"), - end_time: Time.zone.parse("12:00"), - place: "Thielle", - title: "Aide aux champs", - description: "Que du bonheur") - } - let(:participation) { - create(:activity_participation, - member: member, - activity: activity, - participants_count: 2) - } - - specify "#participation_reminder_email" do - template = MailTemplate.find_by(title: "activity_participation_reminder") - create(:activity_participation, :carpooling, - activity: activity, - member: create(:member, name: "Elea Asah"), - carpooling_phone: "+41765431243", - carpooling_city: "La Chaux-de-Fonds") - group = ActivityParticipationGroup.group([ participation ]).first - - mail = ActivityMailer.with( - template: template, - activity_participation_ids: group.ids, - ).participation_reminder_email - - expect(mail.subject).to eq("Activité à venir (24 mars 2020)") - expect(mail.to).to eq([ "example@csa-admin.org" ]) - expect(mail.tag).to eq("activity-participation-reminder") - expect(mail.body).to include("Date: mardi 24 mars 2020") - expect(mail.body).to include("Horaire: 8:30-12:00") - expect(mail.body).to include("Lieu: Thielle") - expect(mail.body).to include("Activité: Aide aux champs") - expect(mail.body).to include("Description: Que du bonheur") - expect(mail.body).to include("Participants: 2") - expect(mail.body).to include("+41 77 333 44 55") - expect(mail.body).to include("Elea Asah: +41 76 543 12 43 (La Chaux-de-Fonds)") - expect(mail.body).to include("https://membres.acme.test/activity_participations") - expect(mail[:from].decoded).to eq "Rage de VertHello Thibaud,
\n\nThe email john@doe.com was rejected during the last message delivery due to the following reason: HardBounce"
+ assert_includes body, "Member: John Doe"
+ assert_includes body, "https://admin.acme.test/members/#{members(:john).id}"
+ assert_includes body, "https://admin.acme.test/admins/#{admins(:super).id}/edit#notifications"
+ assert_includes body, "Manage my notifications"
+ end
+
+ test "new_registration_email" do
+ mail = AdminMailer.with(
+ admin: admins(:super),
+ member: members(:john),
+ ).new_registration_email
+
+ assert_equal "New registration", mail.subject
+ assert_equal [ "info@csa-admin.org" ], mail.to
+ assert_equal "admin-member-created", mail.tag
+ assert_equal "Acme Content Title
'
+ assert_includes body, "Example Text John Doe"
+ assert_match %r{https://members.acme.test/newsletters/unsubscribe/\w{32}}, body
+ assert_equal "List-Unsubscribe=One-Click", mail["List-Unsubscribe-Post"].to_s
+ assert_match %r{