2017-09-09 1 views
0

J'ai un site Web avec plusieurs types de clients (par exemple, Administrateur, Directeur, Marketing, etc.)Rails - cadre pour envoyer des e-mails de test et de désactiver DB écrire

En utilisant Rails, on me demande d'envoyer des e-mails de test à ceux les gens pour qu'ils puissent prévisualiser les e-mails sur leur propre e-mail + restrictions de pare-feu + voir si l'e-mail va dans le dossier de promotion ou non. Je dois pouvoir envoyer un ensemble spécifique de courriels à chaque type d'utilisateur (de tels tests sont très rares, mais en fin de compte, tous les administrateurs de notre société devraient être en mesure d'envoyer des courriels de test en utilisant l'interface frontend). Ce que je vais faire, c'est d'écrire une classe par type d'utilisateur, qui enregistrerait les emails que cet utilisateur est susceptible de recevoir à un moment donné, et utiliser (par exemple FactoryGirl) en mode build-only (non Écrit à DB !!) pour construire les modèles nécessaires pour envoyer les emails en utilisant deliver_now (donc j'évite les problèmes de sérialisation/désérialisation). J'espérais être en mesure d'exécuter ce système dans mon environnement de production réel (afin que je puisse utiliser ma réputation d'email REAL, signatures, etc.)

Y at-il un moyen facile de désactiver les écritures de DB (donc je m'assure que tous mes exemples de modèles sont détruits après leur utilisation pour envoyer un email?)? Une option facile serait de démarrer le serveur en utilisant les informations d'identification de base de données en lecture seule, mais il y a peut-être quelque chose de sûr qui éviterait trop de problèmes.

Voici comment mon code ressemble

module Testing 
    module Emails 
    class UserTypeAdmin < Base 
     attr_accessor, :new_user, :admin 
     register_email :created_new_user, type: :user_management do 
     UserManagementMailer.user_created(new_user, creator: admin) 
     end 

     def prepare_models 
     self.admin = FactoryGirl.build(:admin) 
     self.new_user = FactoryGirl.build(:user) 
     end 
    end 
    end 
end 

module Testing 
    module Emails 
    class Base 
     class < self 
     # my logic to register emails, definitions of #register_email, etc. 
     end 

     def initialize(tester_emails, ccs = []) 
     @tester_emails = tester_emails 
     @ccs = ccs 
     prepare_models 
     end 

     def send_email(email_name) 
     email = instance_eval(registered_emails(email_name)) 
     email.to = @tester_emails 
     email.cc = @ccs 
     email.deliver_now 
     end 

Mes usines de FactoryGirls sont tout à fait en désordre et même si je suis en utilisant les :build méthodes, certaines usines ont été écrites à l'aide des associations avec la stratégie :create si juste pour vous assurer, je aimerais verrouiller la DB écrit afin que je puisse facilement éviter le mauvais bruit sur ma base de données (j'utilise Mongoid donc je n'ai pas un mécanisme de transaction facile pour annuler toutes mes écritures)

+0

Vous pouvez utiliser un environnement distinct qui reflète la base de données de production périodiquement à la place. Je serais très prudent de faire quelque chose comme ça dans la production. Vous pouvez utiliser le même environnement de transfert que les parties prenantes pour prévisualiser les nouvelles fonctionnalités. – max

Répondre

0

Donc une solution très simple est de écrire une spécification qui vérifie que rien n'est écrit dans la base de données. En utilisant cela, j'ai été capable de déboguer quelques cas où un modèle a été conservé.

require 'rails_helper' 

describe Testing::Email::UserTypeAdmin do 
    let(:tos) { ['[email protected]'] } 
    let(:ccs) { ['[email protected]'] } 
    let(:tested_models) {[ 
    User, Admin, 
    Conversation, Message, # etc. 
    ]} 

    subject do 
    described_class.new(tos, ccs) 
    end 

    context 'testing all emails' do 
    it 'does nothing with the DB' do 
     subject.send_all_emails 
     aggregate_failures 'no persistence' do 
     tested_models.each do |model| 
      expect(model.count).to eq(0), "#{model.name} was persisted" 
     end 
     end 
    end 
    end 
end 

Je suis toujours à la recherche de meilleures solutions :-)