Passage de RulseSet/Rule/Action à Filter/Condition/Operation
This commit is contained in:
parent
2d62e7d9d1
commit
c923f75332
3
Gemfile
3
Gemfile
|
@ -33,9 +33,10 @@ gem 'chronic'
|
|||
# Use Nokogiri to transform HTML to text
|
||||
gem 'nokogiri', "1.11.0"
|
||||
|
||||
# rexml is no longer default gem in Ruby 3.0
|
||||
# some libraries is no longer default gems in Ruby 3.0
|
||||
# https://github.com/rails/rails/commit/c23533ee0b50fdc67cc73b579674637ba6f34cb4
|
||||
gem 'rexml'
|
||||
gem 'open3'
|
||||
|
||||
# Use Elasticsearch as Search database
|
||||
gem 'elasticsearch-model'
|
||||
|
|
|
@ -150,6 +150,7 @@ GEM
|
|||
nokogiri (1.11.0)
|
||||
mini_portile2 (~> 2.5.0)
|
||||
racc (~> 1.4)
|
||||
open3 (0.1.1)
|
||||
orm_adapter (0.5.0)
|
||||
pry (0.13.1)
|
||||
coderay (~> 1.1)
|
||||
|
@ -271,6 +272,7 @@ DEPENDENCIES
|
|||
listen (~> 3.2)
|
||||
net-ldap
|
||||
nokogiri (= 1.11.0)
|
||||
open3
|
||||
pry
|
||||
puma (~> 5.1)
|
||||
rails (~> 6.1.0)
|
||||
|
|
23
IDEAS.md
23
IDEAS.md
|
@ -1,24 +1 @@
|
|||
# Idées
|
||||
|
||||
RuleSet
|
||||
* name
|
||||
* description
|
||||
* enabled?
|
||||
* rule_set_id (pour imbriquer des règles)
|
||||
* rules_logic (AND, OR, XOR…)
|
||||
|
||||
Rule
|
||||
* rule_set_id
|
||||
* name
|
||||
* enabled?
|
||||
* criteria_type (Header, Body…)
|
||||
* criteria_value
|
||||
* operator (match, equal, start, end, contain, exist, empty)
|
||||
* operator_inverted?
|
||||
* value
|
||||
|
||||
Action
|
||||
* rule_set_id
|
||||
* name
|
||||
* enabled?
|
||||
* klass (EmailAction::MetadataMapping, EmailAction::TicketMapping…)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
// Place all the styles related to the conditions controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: https://sass-lang.com/
|
|
@ -0,0 +1,7 @@
|
|||
// Place all the styles related to the filters controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: https://sass-lang.com/
|
||||
|
||||
#conditions, #operations {
|
||||
border: 1px solid blue;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
// Place all the styles related to the actions controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: https://sass-lang.com/
|
|
@ -0,0 +1,62 @@
|
|||
class ConditionsController < ApplicationController
|
||||
before_action :set_filter
|
||||
before_action :set_condition, only: [:show, :edit, :update, :destroy]
|
||||
|
||||
# GET /conditions
|
||||
def index
|
||||
@conditions = @filter.conditions.all
|
||||
end
|
||||
|
||||
# GET /conditions/1
|
||||
def show
|
||||
end
|
||||
|
||||
# GET /conditions/new
|
||||
def new
|
||||
@condition = @filter.conditions.new
|
||||
end
|
||||
|
||||
# GET /conditions/1/edit
|
||||
def edit
|
||||
end
|
||||
|
||||
# POST /conditions
|
||||
def create
|
||||
@condition = @filter.conditions.new(condition_params)
|
||||
|
||||
if @condition.save
|
||||
redirect_to @filter, notice: 'Filter was successfully created.'
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
# PATCH/PUT /conditions/1
|
||||
def update
|
||||
if @condition.update(condition_params)
|
||||
redirect_to @filter, notice: 'Filter was successfully updated.'
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /conditions/1
|
||||
def destroy
|
||||
@condition.destroy
|
||||
redirect_to @filter, notice: 'Filter was successfully destroyed.'
|
||||
end
|
||||
|
||||
private
|
||||
# Use callbacks to share common setup or constraints between conditions.
|
||||
def set_filter
|
||||
@filter = Filter.find(params[:filter_id])
|
||||
end
|
||||
def set_condition
|
||||
@condition = @filter.conditions.find(params[:id])
|
||||
end
|
||||
|
||||
# Only allow a list of trusted parameters through.
|
||||
def condition_params
|
||||
params.require(:condition).permit(:enabled, :property_type, :property_value, :test_method, :test_value, :inverted)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,58 @@
|
|||
class FiltersController < ApplicationController
|
||||
before_action :set_filter, only: [:show, :edit, :update, :destroy]
|
||||
|
||||
# GET /filters
|
||||
def index
|
||||
@filters = Filter.all
|
||||
end
|
||||
|
||||
# GET /filters/1
|
||||
def show
|
||||
end
|
||||
|
||||
# GET /filters/new
|
||||
def new
|
||||
@filter = Filter.new
|
||||
end
|
||||
|
||||
# GET /filters/1/edit
|
||||
def edit
|
||||
end
|
||||
|
||||
# POST /filters
|
||||
def create
|
||||
@filter = Filter.new(filter_params)
|
||||
|
||||
if @filter.save
|
||||
redirect_to @filter, notice: 'Filter was successfully created.'
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
# PATCH/PUT /filters/1
|
||||
def update
|
||||
if @filter.update(filter_params)
|
||||
redirect_to @filter, notice: 'Filter was successfully updated.'
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /filters/1
|
||||
def destroy
|
||||
@filter.destroy
|
||||
redirect_to filters_url, notice: 'Filter was successfully destroyed.'
|
||||
end
|
||||
|
||||
private
|
||||
# Use callbacks to share common setup or constraints between actions.
|
||||
def set_filter
|
||||
@filter = Filter.find(params[:id])
|
||||
end
|
||||
|
||||
# Only allow a list of trusted parameters through.
|
||||
def filter_params
|
||||
params.require(:filter).permit(:description, :enabled, :operator, :inverted)
|
||||
end
|
||||
end
|
|
@ -23,23 +23,19 @@ class MetadataMappingsController < ApplicationController
|
|||
def create
|
||||
@metadata_mapping = MetadataMapping.new(metadata_mapping_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @metadata_mapping.save
|
||||
redirect_to @metadata_mapping, notice: 'Metadata mapping was successfully created.'
|
||||
else
|
||||
render :new
|
||||
end
|
||||
if @metadata_mapping.save
|
||||
redirect_to @metadata_mapping, notice: 'Metadata mapping was successfully created.'
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
# PATCH/PUT /metadata_mappings/1
|
||||
def update
|
||||
respond_to do |format|
|
||||
if @metadata_mapping.update(metadata_mapping_params)
|
||||
redirect_to @metadata_mapping, notice: 'Metadata mapping was successfully updated.'
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
if @metadata_mapping.update(metadata_mapping_params)
|
||||
redirect_to @metadata_mapping, notice: 'Metadata mapping was successfully updated.'
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -47,10 +43,7 @@ class MetadataMappingsController < ApplicationController
|
|||
# DELETE /metadata_mappings/1.json
|
||||
def destroy
|
||||
@metadata_mapping.destroy
|
||||
respond_to do |format|
|
||||
format.html { redirect_to metadata_mappings_url, notice: 'Metadata mapping was successfully destroyed.' }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
redirect_to metadata_mappings_url, notice: 'Metadata mapping was successfully destroyed.'
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
class OperationsController < ApplicationController
|
||||
before_action :set_filter
|
||||
before_action :set_operation, only: [:show, :edit, :update, :destroy]
|
||||
|
||||
# GET /operations
|
||||
def index
|
||||
@operations = @filter.operations.all
|
||||
end
|
||||
|
||||
# GET /operations/1
|
||||
def show
|
||||
end
|
||||
|
||||
# GET /operations/new
|
||||
def new
|
||||
@operation = @filter.operations.new
|
||||
end
|
||||
|
||||
# GET /operations/1/edit
|
||||
def edit
|
||||
end
|
||||
|
||||
# POST /operations
|
||||
def create
|
||||
@operation = @filter.operations.new(operation_params)
|
||||
|
||||
if @operation.save
|
||||
redirect_to @filter, notice: 'Operation was successfully created.'
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
# PATCH/PUT /operations/1
|
||||
def update
|
||||
if @operation.update(operation_params)
|
||||
redirect_to @filter, notice: 'Operation was successfully updated.'
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /operations/1
|
||||
def destroy
|
||||
@operation.destroy
|
||||
redirect_to @filter, notice: 'Operation was successfully destroyed.'
|
||||
end
|
||||
|
||||
private
|
||||
# Use callbacks to share common setup or constraints between operations.
|
||||
def set_filter
|
||||
@filter = Filter.find(params[:filter_id])
|
||||
end
|
||||
def set_operation
|
||||
@operation = @filter.operations.find(params[:id])
|
||||
end
|
||||
|
||||
# Only allow a list of trusted parameters through.
|
||||
def operation_params
|
||||
params.require(:operation).permit(:enabled, :class_name, :argument)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
module ConditionsHelper
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
module FiltersHelper
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
module OperationsHelper
|
||||
end
|
|
@ -4,8 +4,8 @@ class InMailbox < ApplicationMailbox
|
|||
|
||||
email = email_importer.import(mail)
|
||||
|
||||
processor = RuleSetProcessor.new
|
||||
email = processor.process_all(RuleSet.enabled, email)
|
||||
processor = FilterProcessor.new
|
||||
email = processor.process_all(Filter.enabled, email)
|
||||
|
||||
# repository = EmailRepository.new
|
||||
# repository.save(email)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Action < ApplicationRecord
|
||||
belongs_to :rule_set
|
||||
class Condition < ApplicationRecord
|
||||
belongs_to :filter
|
||||
|
||||
scope :enabled, -> { where(enabled: true) }
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Filter < ApplicationRecord
|
||||
has_many :conditions, dependent: :destroy
|
||||
has_many :operations, dependent: :destroy
|
||||
|
||||
scope :enabled, -> { where(enabled: true) }
|
||||
end
|
|
@ -1,8 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RuleSet < ApplicationRecord
|
||||
has_many :rules
|
||||
has_many :actions
|
||||
class Operation < ApplicationRecord
|
||||
belongs_to :filter
|
||||
|
||||
scope :enabled, -> { where(enabled: true) }
|
||||
end
|
|
@ -1,8 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Rule < ApplicationRecord
|
||||
belongs_to :rule_set
|
||||
has_many :actions
|
||||
|
||||
scope :enabled, -> { where(enabled: true) }
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module EmailAction
|
||||
class Postpone < Base
|
||||
|
||||
def process(email)
|
||||
if date = Chronic.parse(action.argument)
|
||||
email.postponed_until = date
|
||||
else
|
||||
Rails.logger.warn "Skipped action##{action.id} '#{action.name}' - Unparsable argument for Chronic : '#{action.argument}'"
|
||||
end
|
||||
|
||||
email
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -1,16 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module EmailAction
|
||||
module EmailOperation
|
||||
|
||||
class Error < ::StandardError
|
||||
end
|
||||
|
||||
class Base
|
||||
|
||||
attr_reader :action
|
||||
attr_reader :operation
|
||||
|
||||
def initialize(action:)
|
||||
@action = action
|
||||
def initialize(operation:)
|
||||
@operation = operation
|
||||
end
|
||||
|
||||
def process(email)
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module EmailAction
|
||||
module EmailOperation
|
||||
class CronMapping < Base
|
||||
|
||||
def process(email)
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module EmailAction
|
||||
module EmailOperation
|
||||
class IssueMapping < Base
|
||||
|
||||
def process(email)
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module EmailAction
|
||||
module EmailOperation
|
||||
class Junk < Base
|
||||
|
||||
def process(email)
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module EmailAction
|
||||
module EmailOperation
|
||||
class MailingListMapping < Base
|
||||
|
||||
def process(email)
|
|
@ -1,14 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module EmailAction
|
||||
module EmailOperation
|
||||
class MetadataMapping < Base
|
||||
|
||||
attr_accessor :metadata_mapping_class
|
||||
|
||||
def initialize(action:, metadata_mapping_class: ::MetadataMapping)
|
||||
def initialize(operation:, metadata_mapping_class: ::MetadataMapping)
|
||||
|
||||
@metadata_mapping_class = metadata_mapping_class
|
||||
super(action: action)
|
||||
super(operation: operation)
|
||||
end
|
||||
|
||||
def process(email)
|
||||
|
@ -20,7 +20,7 @@ module EmailAction
|
|||
|
||||
email
|
||||
rescue => ex
|
||||
binding.pry
|
||||
byebug
|
||||
end
|
||||
|
||||
private
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module EmailOperation
|
||||
class Postpone < Base
|
||||
|
||||
def process(email)
|
||||
if date = Chronic.parse(operation.argument)
|
||||
email.postponed_until = date
|
||||
else
|
||||
Rails.logger.warn "Skipped operation##{operation.id} '#{operation.class_name}' - Unparsable argument for Chronic : '#{operation.argument}'"
|
||||
end
|
||||
|
||||
email
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,139 @@
|
|||
class FilterProcessor
|
||||
|
||||
class InvalidFilter < ::ArgumentError
|
||||
end
|
||||
|
||||
def process_all(filters, email)
|
||||
filters.each { |filter|
|
||||
email = process(filter, email)
|
||||
}
|
||||
|
||||
email
|
||||
end
|
||||
|
||||
def process(filter, email)
|
||||
return email unless filter.enabled?
|
||||
|
||||
if evaluate_conditions(filter, email)
|
||||
email = execute_operations(filter.operations, email)
|
||||
end
|
||||
|
||||
email
|
||||
end
|
||||
|
||||
def evaluate_conditions(filter, email)
|
||||
filter_result = true
|
||||
|
||||
filter_result = catch(:done) {
|
||||
filter.conditions.each do |condition|
|
||||
next unless condition.enabled?
|
||||
|
||||
properties = prepare_properties(condition, email)
|
||||
condition_result = apply_condition(properties, condition)
|
||||
condition_result = !condition_result if filter.inverted?
|
||||
filter_result = apply_operator(filter_result, filter.operator, condition_result)
|
||||
rescue InvalidFilter => ex
|
||||
Rails.logger.error "Skipped filter##{filter.id} '#{filter.description}' - #{ex.inspect}"
|
||||
next
|
||||
end
|
||||
}
|
||||
|
||||
filter_result
|
||||
end
|
||||
|
||||
def execute_operations(operations, email)
|
||||
operations.each do |operation|
|
||||
next unless operation.enabled?
|
||||
|
||||
klass = operation.class_name.constantize
|
||||
email_operation = klass.new(operation: operation)
|
||||
email = email_operation.process(email)
|
||||
rescue NameError => ex
|
||||
Rails.logger.error "Skipped operation##{operation.id} '#{operation.class_name}' - #{ex.inspect}"
|
||||
raise InvalidFilter, ex.inspect
|
||||
end
|
||||
|
||||
email
|
||||
end
|
||||
|
||||
def prepare_properties(filter, email)
|
||||
case filter.property_type.downcase
|
||||
when "header"
|
||||
Array(email.header_values(filter.property_value))
|
||||
when "subject"
|
||||
Array(email.subject)
|
||||
when "body"
|
||||
Array(email.plain_body)
|
||||
else
|
||||
raise InvalidFilter, "Unrecognized property type '#{filter.property_type}'"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def apply_condition(properties, condition)
|
||||
case condition.test_method.downcase
|
||||
when "match", "matches"
|
||||
properties.any? { |property|
|
||||
pattern = Regexp.new(condition.test_value)
|
||||
property.match? pattern
|
||||
}
|
||||
when "equal", "equals"
|
||||
properties.any? { |property|
|
||||
property == condition.test_value
|
||||
}
|
||||
when "start", "starts"
|
||||
properties.any? { |property|
|
||||
property.starts_with? condition.test_value
|
||||
}
|
||||
when "end", "ends"
|
||||
properties.any? { |property|
|
||||
property.ends_with? condition.test_value
|
||||
}
|
||||
when "contain", "contains"
|
||||
properties.any? { |property|
|
||||
property.include? condition.test_value
|
||||
}
|
||||
when "exist", "exists"
|
||||
properties.any? { |property|
|
||||
property.exists?
|
||||
}
|
||||
when "empty"
|
||||
properties.all? { |property|
|
||||
property.empty?
|
||||
}
|
||||
when "date_before"
|
||||
# properties.all? { |property|
|
||||
# property.empty?
|
||||
# }
|
||||
when "date_after"
|
||||
# properties.all? { |property|
|
||||
# property.empty?
|
||||
# }
|
||||
else
|
||||
raise InvalidFilter, "Unrecognized test method '#{condition.test_method}'"
|
||||
end
|
||||
end
|
||||
|
||||
def apply_operator(state, operator, result)
|
||||
case operator.upcase
|
||||
when "AND"
|
||||
if result
|
||||
(state and result)
|
||||
else
|
||||
throw :done, false
|
||||
end
|
||||
when "OR"
|
||||
if result
|
||||
throw :done, true
|
||||
else
|
||||
(state or result)
|
||||
end
|
||||
# when "XOR"
|
||||
# (state or result) and !(conditions_state and result)
|
||||
else
|
||||
raise InvalidFilter, "Unrecognized operator '#{operator}'"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -10,7 +10,7 @@ module HtmlToText
|
|||
end
|
||||
|
||||
def convert(html_input)
|
||||
output, error, status = Open3.capture3("#{elinks_path} -dump -force-html", stdin_data: html_input)
|
||||
output, error, status = ::Open3.capture3("#{elinks_path} -dump -force-html", stdin_data: html_input)
|
||||
if status.success?
|
||||
output
|
||||
else
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
class RuleSetProcessor
|
||||
|
||||
class InvalidRule < ::ArgumentError
|
||||
end
|
||||
|
||||
def process_all(rule_sets, email)
|
||||
rule_sets.each { |rule_set|
|
||||
email = process(rule_set, email)
|
||||
}
|
||||
|
||||
email
|
||||
end
|
||||
|
||||
def process(rule_set, email)
|
||||
return email unless rule_set.enabled?
|
||||
|
||||
if evaluate_rules(rule_set, email)
|
||||
email = execute_actions(rule_set.actions, email)
|
||||
end
|
||||
|
||||
email
|
||||
end
|
||||
|
||||
def evaluate_rules(rule_set, email)
|
||||
rule_set_result = true
|
||||
|
||||
rule_set_result = catch(:done) {
|
||||
rule_set.rules.each do |rule|
|
||||
next unless rule.enabled?
|
||||
|
||||
subjects = prepare_subjects(rule, email)
|
||||
rule_result = apply_rule(subjects, rule)
|
||||
rule_result = !rule_result if rule.inverted?
|
||||
rule_set_result = apply_operator(rule_set_result, rule_set.operator, rule_result)
|
||||
rescue InvalidRule => ex
|
||||
Rails.logger.error "Skipped rule##{rule.id} '#{rule.name}' - #{ex.inspect}"
|
||||
next
|
||||
end
|
||||
}
|
||||
|
||||
rule_set_result
|
||||
end
|
||||
|
||||
def execute_actions(actions, email)
|
||||
actions.each do |action|
|
||||
next unless action.enabled?
|
||||
|
||||
klass = action.class_name.constantize
|
||||
email_action = klass.new(action: action)
|
||||
email = email_action.process(email)
|
||||
rescue NameError => ex
|
||||
Rails.logger.error "Skipped action##{action.id} '#{action.name}' - #{ex.inspect}"
|
||||
raise InvalidRule, ex.inspect
|
||||
end
|
||||
|
||||
email
|
||||
end
|
||||
|
||||
def prepare_subjects(rule, email)
|
||||
case rule.subject_type.downcase
|
||||
when "header"
|
||||
Array(email.header_values(rule.subject_value))
|
||||
when "subject"
|
||||
Array(email.subject)
|
||||
when "body"
|
||||
Array(email.plain_body)
|
||||
else
|
||||
raise InvalidRule, "Unrecognized subject type '#{rule.subject_type}'"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def apply_rule(subjects, rule)
|
||||
case rule.condition_type.downcase
|
||||
when "match", "matches"
|
||||
subjects.any? { |subject|
|
||||
pattern = Regexp.new(rule.condition_value)
|
||||
subject.match? pattern
|
||||
}
|
||||
when "equal", "equals"
|
||||
subjects.any? { |subject|
|
||||
subject == rule.condition_value
|
||||
}
|
||||
when "start", "starts"
|
||||
subjects.any? { |subject|
|
||||
subject.starts_with? rule.condition_value
|
||||
}
|
||||
when "end", "ends"
|
||||
subjects.any? { |subject|
|
||||
subject.ends_with? rule.condition_value
|
||||
}
|
||||
when "contain", "contains"
|
||||
subjects.any? { |subject|
|
||||
subject.include? rule.condition_value
|
||||
}
|
||||
when "exist", "exists"
|
||||
subjects.any? { |subject|
|
||||
subject.exists?
|
||||
}
|
||||
when "empty"
|
||||
subjects.all? { |subject|
|
||||
subject.empty?
|
||||
}
|
||||
when "date_before"
|
||||
# subjects.all? { |subject|
|
||||
# subject.empty?
|
||||
# }
|
||||
when "date_after"
|
||||
# subjects.all? { |subject|
|
||||
# subject.empty?
|
||||
# }
|
||||
else
|
||||
raise InvalidRule, "Unrecognized condition type '#{rule. condition_type}'"
|
||||
end
|
||||
end
|
||||
|
||||
def apply_operator(state, operator, result)
|
||||
case operator.upcase
|
||||
when "AND"
|
||||
if result
|
||||
(state and result)
|
||||
else
|
||||
throw :done, false
|
||||
end
|
||||
when "OR"
|
||||
if result
|
||||
throw :done, true
|
||||
else
|
||||
(state or result)
|
||||
end
|
||||
# when "XOR"
|
||||
# (state or result) and !(rules_state and result)
|
||||
else
|
||||
raise InvalidRule, "Unrecognized operator '#{operator}'"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
<div id="<%= dom_id condition %>">
|
||||
|
||||
<p>
|
||||
<strong>Enabled:</strong>
|
||||
<%= condition.enabled %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Property type:</strong>
|
||||
<%= condition.property_type %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Property value:</strong>
|
||||
<%= condition.property_value %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Test method:</strong>
|
||||
<%= condition.test_method %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Test value:</strong>
|
||||
<%= condition.test_value %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Inverted:</strong>
|
||||
<%= condition.inverted %>
|
||||
</p>
|
||||
</div>
|
|
@ -0,0 +1,48 @@
|
|||
<%= form_with(model: [ condition.filter, condition ],
|
||||
data: { controller: "reset_form", action: "turbo:submit-end->reset_form#reset" }) do |form| %>
|
||||
<% if condition.errors.any? %>
|
||||
<div id="error_explanation">
|
||||
<h2><%= pluralize(condition.errors.count, "error") %> prohibited this condition from being saved:</h2>
|
||||
|
||||
<ul>
|
||||
<% condition.errors.each do |error| %>
|
||||
<li><%= error.full_message %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="field">
|
||||
<%= form.label :enabled %>
|
||||
<%= form.check_box :enabled %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= form.label :property_type %>
|
||||
<%= form.text_field :property_type %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= form.label :property_value %>
|
||||
<%= form.text_field :property_value %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= form.label :test_method %>
|
||||
<%= form.text_field :test_method %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= form.label :test_value %>
|
||||
<%= form.text_field :test_value %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= form.label :inverted %>
|
||||
<%= form.check_box :inverted %>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<%= form.submit %>
|
||||
</div>
|
||||
<% end %>
|
|
@ -0,0 +1,6 @@
|
|||
<h1>Editing Condition</h1>
|
||||
|
||||
<%= render 'form', condition: @condition %>
|
||||
|
||||
<%= link_to 'Show', @condition %> |
|
||||
<%= link_to 'Back', @condition.filter %>
|
|
@ -0,0 +1,37 @@
|
|||
<p id="notice"><%= notice %></p>
|
||||
|
||||
<h1>Conditions</h1>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Enabled</th>
|
||||
<th>Property type</th>
|
||||
<th>Property value</th>
|
||||
<th>Test method</th>
|
||||
<th>Test value</th>
|
||||
<th>Inverted</th>
|
||||
<th colspan="3"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<% @conditions.each do |condition| %>
|
||||
<tr>
|
||||
<td><%= condition.enabled %></td>
|
||||
<td><%= condition.property_type %></td>
|
||||
<td><%= condition.property_value %></td>
|
||||
<td><%= condition.test_method %></td>
|
||||
<td><%= condition.test_value %></td>
|
||||
<td><%= condition.inverted %></td>
|
||||
<td><%= link_to 'Show', condition %></td>
|
||||
<td><%= link_to 'Edit', edit_condition_path(condition) %></td>
|
||||
<td><%= link_to 'Destroy', condition, method: :delete, data: { confirm: 'Are you sure?' } %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
|
||||
<%= link_to 'New Condition', new_condition_path %>
|
|
@ -0,0 +1,7 @@
|
|||
<h1>New Condition</h1>
|
||||
|
||||
<%= turbo_frame_tag "new_condition", target: "_top" do %>
|
||||
<%= render 'form', condition: @condition %>
|
||||
<% end %>
|
||||
|
||||
<%= link_to 'Back', @condition.filter %>
|
|
@ -0,0 +1,6 @@
|
|||
<p id="notice"><%= notice %></p>
|
||||
|
||||
<%= render @condition %>
|
||||
|
||||
<%= link_to 'Edit', edit_condition_path(@condition) %> |
|
||||
<%= link_to 'Back', @condition.filter %>
|
|
@ -0,0 +1,22 @@
|
|||
<div id="<%= dom_id filter %>">
|
||||
|
||||
<p>
|
||||
<strong>Description:</strong>
|
||||
<%= filter.description %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Enabled:</strong>
|
||||
<%= filter.enabled %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Operator:</strong>
|
||||
<%= filter.operator %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Inverted:</strong>
|
||||
<%= filter.inverted %>
|
||||
</p>
|
||||
</div>
|
|
@ -0,0 +1,37 @@
|
|||
<%= form_with(model: filter) do |form| %>
|
||||
<% if filter.errors.any? %>
|
||||
<div id="error_explanation">
|
||||
<h2><%= pluralize(filter.errors.count, "error") %> prohibited this filter from being saved:</h2>
|
||||
|
||||
<ul>
|
||||
<% filter.errors.each do |error| %>
|
||||
<li><%= error.full_message %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="field">
|
||||
<%= form.label :description %>
|
||||
<%= form.text_field :description %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= form.label :enabled %>
|
||||
<%= form.check_box :enabled %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= form.label :operator %>
|
||||
<%= form.text_field :operator %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= form.label :inverted %>
|
||||
<%= form.check_box :inverted %>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<%= form.submit %>
|
||||
</div>
|
||||
<% end %>
|
|
@ -0,0 +1,6 @@
|
|||
<h1>Editing Filter</h1>
|
||||
|
||||
<%= render 'form', filter: @filter %>
|
||||
|
||||
<%= link_to 'Show', @filter %> |
|
||||
<%= link_to 'Back', filters_path %>
|
|
@ -0,0 +1,33 @@
|
|||
<p id="notice"><%= notice %></p>
|
||||
|
||||
<h1>Filters</h1>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<th>Enabled</th>
|
||||
<th>Operator</th>
|
||||
<th>Inverted</th>
|
||||
<th colspan="3"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<% @filters.each do |filter| %>
|
||||
<tr>
|
||||
<td><%= filter.description %></td>
|
||||
<td><%= filter.enabled %></td>
|
||||
<td><%= filter.operator %></td>
|
||||
<td><%= filter.inverted %></td>
|
||||
<td><%= link_to 'Show', filter %></td>
|
||||
<td><%= link_to 'Edit', edit_filter_path(filter) %></td>
|
||||
<td><%= link_to 'Destroy', filter, method: :delete, data: { confirm: 'Are you sure?' } %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
|
||||
<%= link_to 'New Filter', new_filter_path %>
|
|
@ -0,0 +1,5 @@
|
|||
<h1>New Filter</h1>
|
||||
|
||||
<%= render 'form', filter: @filter %>
|
||||
|
||||
<%= link_to 'Back', filters_path %>
|
|
@ -0,0 +1,25 @@
|
|||
<p id="notice"><%= notice %></p>
|
||||
|
||||
|
||||
<%= turbo_frame_tag "filter" do %>
|
||||
<%= render @filter %>
|
||||
|
||||
<p>
|
||||
<%= link_to 'Edit', edit_filter_path(@filter) %> |
|
||||
<%= link_to 'Back', filters_path, "data-turbo-frame": "_top" %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<div id="conditions">
|
||||
<h2>Conditions</h2>
|
||||
<%= render(@filter.conditions) || "No conditions yet" %>
|
||||
</div>
|
||||
|
||||
<%= turbo_frame_tag "new_condition", src: new_filter_condition_path(@filter), target: "_top" %>
|
||||
|
||||
<div id="operations">
|
||||
<h2>Operations</h2>
|
||||
<%= render(@filter.operations) || "No operations yet" %>
|
||||
</div>
|
||||
|
||||
<%= turbo_frame_tag "new_operation", src: new_filter_operation_path(@filter), target: "_top" %>
|
|
@ -0,0 +1,33 @@
|
|||
<%= form_with(model: [ operation.filter, operation ],
|
||||
data: { controller: "reset_form", operation: "turbo:submit-end->reset_form#reset" }) do |form| %>
|
||||
<% if operation.errors.any? %>
|
||||
<div id="error_explanation">
|
||||
<h2><%= pluralize(operation.errors.count, "error") %> prohibited this operation from being saved:</h2>
|
||||
|
||||
<ul>
|
||||
<% operation.errors.each do |error| %>
|
||||
<li><%= error.full_message %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="field">
|
||||
<%= form.label :enabled %>
|
||||
<%= form.check_box :enabled %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= form.label :class_name %>
|
||||
<%= form.text_field :class_name %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= form.label :argument %>
|
||||
<%= form.text_field :argument %>
|
||||
</div>
|
||||
|
||||
<div class="operations">
|
||||
<%= form.submit %>
|
||||
</div>
|
||||
<% end %>
|
|
@ -0,0 +1,17 @@
|
|||
<div id="<%= dom_id operation %>">
|
||||
|
||||
<p>
|
||||
<strong>Enabled:</strong>
|
||||
<%= operation.enabled %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Class name:</strong>
|
||||
<%= operation.class_name %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Argument:</strong>
|
||||
<%= operation.argument %>
|
||||
</p>
|
||||
</div>
|
|
@ -0,0 +1,6 @@
|
|||
<h1>Editing Operation</h1>
|
||||
|
||||
<%= render 'form', operation: @operation %>
|
||||
|
||||
<%= link_to 'Show', @operation %> |
|
||||
<%= link_to 'Back', @operation.filter %>
|
|
@ -0,0 +1,31 @@
|
|||
<p id="notice"><%= notice %></p>
|
||||
|
||||
<h1>Operations</h1>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Enabled</th>
|
||||
<th>Class name</th>
|
||||
<th>Argument</th>
|
||||
<th colspan="3"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<% @operations.each do |operation| %>
|
||||
<tr>
|
||||
<td><%= operation.enabled %></td>
|
||||
<td><%= operation.class_name %></td>
|
||||
<td><%= operation.argument %></td>
|
||||
<td><%= link_to 'Show', operation %></td>
|
||||
<td><%= link_to 'Edit', edit_operation_path(operation) %></td>
|
||||
<td><%= link_to 'Destroy', operation, method: :delete, data: { confirm: 'Are you sure?' } %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
|
||||
<%= link_to 'New Operation', new_operation_path %>
|
|
@ -0,0 +1,7 @@
|
|||
<h1>New Operation</h1>
|
||||
|
||||
<%= turbo_frame_tag "new_operation", target: "_top" do %>
|
||||
<%= render 'form', operation: @operation %>
|
||||
<% end %>
|
||||
|
||||
<%= link_to 'Back', @operation.filter %>
|
|
@ -0,0 +1,6 @@
|
|||
<p id="notice"><%= notice %></p>
|
||||
|
||||
<%= render @operation %>
|
||||
|
||||
<%= link_to 'Edit', edit_operation_path(@operation) %> |
|
||||
<%= link_to 'Back', @operation.filter %>
|
|
@ -3,11 +3,14 @@ require 'sidekiq/web'
|
|||
Rails.application.routes.draw do
|
||||
devise_for :users
|
||||
|
||||
resources :metadata_mappings
|
||||
resources :emails
|
||||
resources :metadata_mappings
|
||||
resources :filters do
|
||||
resources :conditions
|
||||
resources :operations
|
||||
end
|
||||
|
||||
root to: "emails#index"
|
||||
|
||||
mount Sidekiq::Web => '/sidekiq'
|
||||
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
|
||||
end
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
class CreateRuleSets < ActiveRecord::Migration[6.1]
|
||||
class CreateFilters < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
create_table :rule_sets do |t|
|
||||
t.string :name, null: false
|
||||
t.text :description
|
||||
create_table :filters do |t|
|
||||
t.string :description, null: false
|
||||
t.boolean :enabled, default: true, null: false
|
||||
t.string :operator, default: "AND", limit: 3, null: false
|
||||
t.boolean :inverted, default: false, null: false
|
|
@ -0,0 +1,15 @@
|
|||
class CreateConditions < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
create_table :conditions do |t|
|
||||
t.references :filter, null: false, foreign_key: true
|
||||
t.boolean :enabled, default: true, null: false
|
||||
t.string :property_type, null: false
|
||||
t.string :property_value
|
||||
t.string :test_method, default: "contain", null: false
|
||||
t.string :test_value
|
||||
t.boolean :inverted, default: false, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,16 +0,0 @@
|
|||
class CreateRules < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
create_table :rules do |t|
|
||||
t.references :rule_set, null: false, foreign_key: true
|
||||
t.string :name, null: false
|
||||
t.boolean :enabled, default: true, null: false
|
||||
t.string :subject_type, null: false
|
||||
t.string :subject_value
|
||||
t.string :condition_type, default: "contain", null: false
|
||||
t.string :condition_value
|
||||
t.boolean :inverted, default: false, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,13 +0,0 @@
|
|||
class CreateActions < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
create_table :actions do |t|
|
||||
t.references :rule_set, null: false, foreign_key: true
|
||||
t.string :name, null: false
|
||||
t.boolean :enabled, default: true, null: false
|
||||
t.string :class_name, null: false
|
||||
t.string :argument
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
class CreateOperations < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
create_table :operations do |t|
|
||||
t.references :filter, null: false, foreign_key: true
|
||||
t.boolean :enabled, default: true, null: false
|
||||
t.string :class_name, null: false
|
||||
t.string :argument
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
61
db/schema.rb
61
db/schema.rb
|
@ -21,17 +21,6 @@ ActiveRecord::Schema.define(version: 2021_01_29_124143) do
|
|||
t.index ["message_id", "message_checksum"], name: "index_action_mailbox_inbound_emails_uniqueness", unique: true
|
||||
end
|
||||
|
||||
create_table "actions", force: :cascade do |t|
|
||||
t.integer "rule_set_id", null: false
|
||||
t.string "name", null: false
|
||||
t.boolean "enabled", default: true, null: false
|
||||
t.string "class_name", null: false
|
||||
t.string "argument"
|
||||
t.datetime "created_at", precision: 6, null: false
|
||||
t.datetime "updated_at", precision: 6, null: false
|
||||
t.index ["rule_set_id"], name: "index_actions_on_rule_set_id"
|
||||
end
|
||||
|
||||
create_table "active_storage_attachments", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.string "record_type", null: false
|
||||
|
@ -60,6 +49,19 @@ ActiveRecord::Schema.define(version: 2021_01_29_124143) do
|
|||
t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
|
||||
end
|
||||
|
||||
create_table "conditions", force: :cascade do |t|
|
||||
t.integer "filter_id", null: false
|
||||
t.boolean "enabled", default: true, null: false
|
||||
t.string "property_type", null: false
|
||||
t.string "property_value"
|
||||
t.string "test_method", default: "contain", null: false
|
||||
t.string "test_value"
|
||||
t.boolean "inverted", default: false, null: false
|
||||
t.datetime "created_at", precision: 6, null: false
|
||||
t.datetime "updated_at", precision: 6, null: false
|
||||
t.index ["filter_id"], name: "index_conditions_on_filter_id"
|
||||
end
|
||||
|
||||
create_table "emails", force: :cascade do |t|
|
||||
t.string "message_id"
|
||||
t.string "subject"
|
||||
|
@ -80,6 +82,15 @@ ActiveRecord::Schema.define(version: 2021_01_29_124143) do
|
|||
t.datetime "updated_at", precision: 6, null: false
|
||||
end
|
||||
|
||||
create_table "filters", force: :cascade do |t|
|
||||
t.string "description", null: false
|
||||
t.boolean "enabled", default: true, null: false
|
||||
t.string "operator", limit: 3, default: "AND", null: false
|
||||
t.boolean "inverted", default: false, null: false
|
||||
t.datetime "created_at", precision: 6, null: false
|
||||
t.datetime "updated_at", precision: 6, null: false
|
||||
end
|
||||
|
||||
create_table "metadata_mappings", force: :cascade do |t|
|
||||
t.string "input"
|
||||
t.string "server"
|
||||
|
@ -90,28 +101,14 @@ ActiveRecord::Schema.define(version: 2021_01_29_124143) do
|
|||
t.index ["input"], name: "index_metadata_mappings_on_input"
|
||||
end
|
||||
|
||||
create_table "rule_sets", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.text "description"
|
||||
create_table "operations", force: :cascade do |t|
|
||||
t.integer "filter_id", null: false
|
||||
t.boolean "enabled", default: true, null: false
|
||||
t.string "operator", limit: 3, default: "AND", null: false
|
||||
t.boolean "inverted", default: false, null: false
|
||||
t.string "class_name", null: false
|
||||
t.string "argument"
|
||||
t.datetime "created_at", precision: 6, null: false
|
||||
t.datetime "updated_at", precision: 6, null: false
|
||||
end
|
||||
|
||||
create_table "rules", force: :cascade do |t|
|
||||
t.integer "rule_set_id", null: false
|
||||
t.string "name", null: false
|
||||
t.boolean "enabled", default: true, null: false
|
||||
t.string "subject_type", null: false
|
||||
t.string "subject_value"
|
||||
t.string "condition_type", default: "contain", null: false
|
||||
t.string "condition_value"
|
||||
t.boolean "inverted", default: false, null: false
|
||||
t.datetime "created_at", precision: 6, null: false
|
||||
t.datetime "updated_at", precision: 6, null: false
|
||||
t.index ["rule_set_id"], name: "index_rules_on_rule_set_id"
|
||||
t.index ["filter_id"], name: "index_operations_on_filter_id"
|
||||
end
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
|
@ -131,8 +128,8 @@ ActiveRecord::Schema.define(version: 2021_01_29_124143) do
|
|||
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
||||
end
|
||||
|
||||
add_foreign_key "actions", "rule_sets"
|
||||
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
||||
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
||||
add_foreign_key "rules", "rule_sets"
|
||||
add_foreign_key "conditions", "filters"
|
||||
add_foreign_key "operations", "filters"
|
||||
end
|
||||
|
|
30
db/seeds.rb
30
db/seeds.rb
|
@ -11,35 +11,29 @@ User.create(
|
|||
encrypted_password: Devise::Encryptor.digest(User, '123password')
|
||||
)
|
||||
|
||||
rule_set = RuleSet.create(
|
||||
name: "CronMapping",
|
||||
filter = Filter.create(
|
||||
description: "CronMapping",
|
||||
enabled: true
|
||||
)
|
||||
Action.create({
|
||||
rule_set: rule_set,
|
||||
name: "CronMapping",
|
||||
class_name: "EmailAction::CronMapping",
|
||||
filter.operations.create({
|
||||
class_name: "EmailOperation::CronMapping",
|
||||
enabled: true
|
||||
})
|
||||
|
||||
rule_set = RuleSet.create(
|
||||
name: "MailingListMapping",
|
||||
filter = Filter.create(
|
||||
description: "MailingListMapping",
|
||||
enabled: true
|
||||
)
|
||||
Action.create({
|
||||
rule_set: rule_set,
|
||||
name: "MailingListMapping",
|
||||
class_name: "EmailAction::MailingListMapping",
|
||||
filter.operations.create({
|
||||
class_name: "EmailOperation::MailingListMapping",
|
||||
enabled: true
|
||||
})
|
||||
|
||||
rule_set = RuleSet.create(
|
||||
name: "MetadataMapping",
|
||||
filter = Filter.create(
|
||||
description: "MetadataMapping",
|
||||
enabled: true
|
||||
)
|
||||
Action.create({
|
||||
rule_set: rule_set,
|
||||
name: "MetadataMapping",
|
||||
class_name: "EmailAction::MetadataMapping",
|
||||
filter.operations.create({
|
||||
class_name: "EmailOperation::MetadataMapping",
|
||||
enabled: true
|
||||
})
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
# require "test_helper"
|
||||
#
|
||||
# class ConditionsControllerTest < ActionDispatch::IntegrationTest
|
||||
# include Devise::Test::IntegrationHelpers
|
||||
#
|
||||
# setup do
|
||||
# sign_in users(:alice)
|
||||
# @condition = conditions(:one)
|
||||
# end
|
||||
#
|
||||
# test "should get index" do
|
||||
# get conditions_url
|
||||
# assert_response :success
|
||||
# end
|
||||
#
|
||||
# test "should get new" do
|
||||
# get new_condition_url
|
||||
# assert_response :success
|
||||
# end
|
||||
#
|
||||
# test "should create condition" do
|
||||
# assert_difference('Condition.count') do
|
||||
# post conditions_url, params: { condition: { test_method: @condition.test_method, test_value: @condition.test_value, enabled: @condition.enabled, inverted: @condition.inverted, property_type: @condition.property_type, property_value: @condition.property_value } }
|
||||
# end
|
||||
#
|
||||
# assert_redirected_to condition_url(Condition.last)
|
||||
# end
|
||||
#
|
||||
# test "should show condition" do
|
||||
# get condition_url(@condition)
|
||||
# assert_response :success
|
||||
# end
|
||||
#
|
||||
# test "should get edit" do
|
||||
# get edit_condition_url(@condition)
|
||||
# assert_response :success
|
||||
# end
|
||||
#
|
||||
# test "should update condition" do
|
||||
# patch condition_url(@condition), params: { condition: { test_method: @condition.test_method, test_value: @condition.test_value, enabled: @condition.enabled, inverted: @condition.inverted, property_type: @condition.property_type, property_value: @condition.property_value } }
|
||||
# assert_redirected_to condition_url(@condition)
|
||||
# end
|
||||
#
|
||||
# test "should destroy condition" do
|
||||
# assert_difference('Condition.count', -1) do
|
||||
# delete condition_url(@condition)
|
||||
# end
|
||||
#
|
||||
# assert_redirected_to conditions_url
|
||||
# end
|
||||
# end
|
|
@ -0,0 +1,51 @@
|
|||
require "test_helper"
|
||||
|
||||
class FilterControllerTest < ActionDispatch::IntegrationTest
|
||||
include Devise::Test::IntegrationHelpers
|
||||
|
||||
setup do
|
||||
sign_in users(:alice)
|
||||
@filter = filters(:one)
|
||||
end
|
||||
|
||||
test "should get index" do
|
||||
get filters_url
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "should get new" do
|
||||
get new_filter_url
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "should create filter" do
|
||||
assert_difference('Filter.count') do
|
||||
post filters_url, params: { filter: { description: @filter.description, enabled: @filter.enabled, inverted: @filter.inverted, operator: @filter.operator } }
|
||||
end
|
||||
|
||||
assert_redirected_to filter_url(Filter.last)
|
||||
end
|
||||
|
||||
test "should show filter" do
|
||||
get filter_url(@filter)
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "should get edit" do
|
||||
get edit_filter_url(@filter)
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "should update filter" do
|
||||
patch filter_url(@filter), params: { filter: { description: @filter.description, enabled: @filter.enabled, inverted: @filter.inverted, operator: @filter.operator } }
|
||||
assert_redirected_to filter_url(@filter)
|
||||
end
|
||||
|
||||
test "should destroy filter" do
|
||||
assert_difference('Filter.count', -1) do
|
||||
delete filter_url(@filter)
|
||||
end
|
||||
|
||||
assert_redirected_to filters_url
|
||||
end
|
||||
end
|
|
@ -0,0 +1,51 @@
|
|||
# require "test_helper"
|
||||
#
|
||||
# class OperationsControllerTest < ActionDispatch::IntegrationTest
|
||||
# include Devise::Test::IntegrationHelpers
|
||||
#
|
||||
# setup do
|
||||
# sign_in users(:alice)
|
||||
# @operation = operations(:one)
|
||||
# end
|
||||
#
|
||||
# test "should get index" do
|
||||
# get operations_url
|
||||
# assert_response :success
|
||||
# end
|
||||
#
|
||||
# test "should get new" do
|
||||
# get new_operation_url
|
||||
# assert_response :success
|
||||
# end
|
||||
#
|
||||
# test "should create operation" do
|
||||
# assert_difference('Operation.count') do
|
||||
# post operations_url, params: { operation: { argument: @operation.argument, class_name: @operation.class_name, enabled: @operation.enabled } }
|
||||
# end
|
||||
#
|
||||
# assert_redirected_to operation_url(Operation.last)
|
||||
# end
|
||||
#
|
||||
# test "should show operation" do
|
||||
# get operation_url(@operation)
|
||||
# assert_response :success
|
||||
# end
|
||||
#
|
||||
# test "should get edit" do
|
||||
# get edit_operation_url(@operation)
|
||||
# assert_response :success
|
||||
# end
|
||||
#
|
||||
# test "should update operation" do
|
||||
# patch operation_url(@operation), params: { operation: { argument: @operation.argument, class_name: @operation.class_name, enabled: @operation.enabled } }
|
||||
# assert_redirected_to operation_url(@operation)
|
||||
# end
|
||||
#
|
||||
# test "should destroy operation" do
|
||||
# assert_difference('Operation.count', -1) do
|
||||
# delete operation_url(@operation)
|
||||
# end
|
||||
#
|
||||
# assert_redirected_to operations_url
|
||||
# end
|
||||
# end
|
|
@ -1,64 +0,0 @@
|
|||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
rule_set: one
|
||||
name: MyString
|
||||
enabled: false
|
||||
class_name: MyString
|
||||
|
||||
two:
|
||||
rule_set: two
|
||||
name: MyString
|
||||
enabled: false
|
||||
class_name: MyString
|
||||
|
||||
issue:
|
||||
rule_set: issue
|
||||
name: Associate mail to issue(s)
|
||||
enabled: true
|
||||
class_name: EmailAction::IssueMapping
|
||||
|
||||
cron:
|
||||
rule_set: cron
|
||||
name: Mark mail from cron
|
||||
enabled: true
|
||||
class_name: EmailAction::CronMapping
|
||||
|
||||
mailing_list:
|
||||
rule_set: mailing_list
|
||||
name: Mark mail from mailing_list
|
||||
enabled: true
|
||||
class_name: EmailAction::MailingListMapping
|
||||
|
||||
metadata:
|
||||
rule_set: metadata
|
||||
name: Add metadata to mail
|
||||
enabled: true
|
||||
class_name: EmailAction::MetadataMapping
|
||||
|
||||
postpone_future_valid:
|
||||
rule_set: postpone_future_valid
|
||||
name: Postpone for 5 days
|
||||
enabled: true
|
||||
class_name: EmailAction::Postpone
|
||||
argument: <%= Chronic.parse "5 days from now" %>
|
||||
|
||||
postpone_past_valid:
|
||||
rule_set: postpone_past_valid
|
||||
name: Postpone in the past
|
||||
enabled: true
|
||||
class_name: EmailAction::Postpone
|
||||
argument: <%= Chronic.parse "2 days ago" %>
|
||||
|
||||
postpone_invalid:
|
||||
rule_set: postpone_invalid
|
||||
name: Postpone to invalid date
|
||||
enabled: true
|
||||
class_name: EmailAction::Postpone
|
||||
argument: Foo Bar Baz
|
||||
|
||||
junk:
|
||||
rule_set: junk
|
||||
name: Mark mail as junk
|
||||
enabled: true
|
||||
class_name: EmailAction::Junk
|
|
@ -0,0 +1,78 @@
|
|||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
filter: one
|
||||
enabled: true
|
||||
property_type: Header
|
||||
property_value: Subject
|
||||
test_method: contain
|
||||
test_value: MyString
|
||||
inverted: false
|
||||
|
||||
two:
|
||||
filter: two
|
||||
enabled: true
|
||||
property_type: Header
|
||||
property_value: Subject
|
||||
test_method: contain
|
||||
test_value: MyString
|
||||
inverted: true
|
||||
|
||||
invalid_subject:
|
||||
filter: invalid_subject
|
||||
enabled: true
|
||||
property_type: Invalid
|
||||
property_value: Subject
|
||||
test_method: contain
|
||||
test_value: MyString
|
||||
inverted: false
|
||||
|
||||
invalid_test_method:
|
||||
filter: invalid_test
|
||||
enabled: true
|
||||
property_type: Header
|
||||
property_value: Subject
|
||||
test_method: invalid
|
||||
test_value: MyString
|
||||
inverted: false
|
||||
|
||||
invalid_operator:
|
||||
filter: invalid_operator
|
||||
enabled: true
|
||||
property_type: Header
|
||||
property_value: Subject
|
||||
test_method: contain
|
||||
test_value: MyString
|
||||
inverted: false
|
||||
|
||||
postpone_future_valid:
|
||||
filter: postpone_future_valid
|
||||
enabled: true
|
||||
property_type: Subject
|
||||
test_method: match
|
||||
test_value: Postponable
|
||||
inverted: false
|
||||
|
||||
postpone_past_valid:
|
||||
filter: postpone_past_valid
|
||||
enabled: true
|
||||
property_type: Subject
|
||||
test_method: match
|
||||
test_value: Postponable
|
||||
inverted: false
|
||||
|
||||
postpone_invalid:
|
||||
filter: postpone_invalid
|
||||
enabled: true
|
||||
property_type: Subject
|
||||
test_method: match
|
||||
test_value: Postponable
|
||||
inverted: false
|
||||
|
||||
junk_subject:
|
||||
filter: junk
|
||||
enabled: true
|
||||
property_type: Subject
|
||||
test_method: match
|
||||
test_value: Junk
|
||||
inverted: false
|
|
@ -0,0 +1,69 @@
|
|||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
description: Default Filter
|
||||
enabled: true
|
||||
operator: "AND"
|
||||
inverted: false
|
||||
|
||||
and_filter:
|
||||
description: Filters with AND
|
||||
enabled: true
|
||||
operator: "AND"
|
||||
inverted: false
|
||||
|
||||
or_filter:
|
||||
description: Filters with OR
|
||||
enabled: true
|
||||
operator: "OR"
|
||||
inverted: false
|
||||
|
||||
invalid_subject:
|
||||
description: Filters with an invalid filter subject
|
||||
enabled: true
|
||||
operator: "AND"
|
||||
inverted: false
|
||||
|
||||
invalid_condition_type:
|
||||
description: Filters with an invalid filter Property type
|
||||
enabled: true
|
||||
operator: "AND"
|
||||
inverted: false
|
||||
|
||||
invalid_operator:
|
||||
description: Filters with an invalid filter operator
|
||||
enabled: true
|
||||
operator: "FOO"
|
||||
inverted: false
|
||||
|
||||
metadata:
|
||||
description: Metadata
|
||||
enabled: true
|
||||
|
||||
issue:
|
||||
description: Linked to issue(s)
|
||||
enabled: true
|
||||
|
||||
cron:
|
||||
description: FromCron
|
||||
enabled: true
|
||||
|
||||
mailing_list:
|
||||
description: FromMailingList
|
||||
enabled: true
|
||||
|
||||
postpone_future_valid:
|
||||
description: Postpone to valid date in the future
|
||||
enabled: true
|
||||
|
||||
postpone_past_valid:
|
||||
description: Postpone to valid date in the past
|
||||
enabled: true
|
||||
|
||||
postpone_invalid:
|
||||
description: Postpone to invalid date
|
||||
enabled: true
|
||||
|
||||
junk:
|
||||
description: Junk mail
|
||||
enabled: true
|
|
@ -0,0 +1,54 @@
|
|||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
filter: one
|
||||
enabled: false
|
||||
class_name: MyString
|
||||
|
||||
two:
|
||||
filter: two
|
||||
enabled: false
|
||||
class_name: MyString
|
||||
|
||||
issue:
|
||||
filter: issue
|
||||
enabled: true
|
||||
class_name: EmailOperation::IssueMapping
|
||||
|
||||
cron:
|
||||
filter: cron
|
||||
enabled: true
|
||||
class_name: EmailOperation::CronMapping
|
||||
|
||||
mailing_list:
|
||||
filter: mailing_list
|
||||
enabled: true
|
||||
class_name: EmailOperation::MailingListMapping
|
||||
|
||||
metadata:
|
||||
filter: metadata
|
||||
enabled: true
|
||||
class_name: EmailOperation::MetadataMapping
|
||||
|
||||
postpone_future_valid:
|
||||
filter: postpone_future_valid
|
||||
enabled: true
|
||||
class_name: EmailOperation::Postpone
|
||||
argument: <%= Chronic.parse "5 days from now" %>
|
||||
|
||||
postpone_past_valid:
|
||||
filter: postpone_past_valid
|
||||
enabled: true
|
||||
class_name: EmailOperation::Postpone
|
||||
argument: <%= Chronic.parse "2 days ago" %>
|
||||
|
||||
postpone_invalid:
|
||||
filter: postpone_invalid
|
||||
enabled: true
|
||||
class_name: EmailOperation::Postpone
|
||||
argument: Foo Bar Baz
|
||||
|
||||
junk:
|
||||
filter: junk
|
||||
enabled: true
|
||||
class_name: EmailOperation::Junk
|
|
@ -1,76 +0,0 @@
|
|||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
name: Default RuleSet
|
||||
description: MyText
|
||||
enabled: true
|
||||
operator: "AND"
|
||||
inverted: false
|
||||
|
||||
and_rules:
|
||||
name: Rules with AND
|
||||
description: MyText
|
||||
enabled: true
|
||||
operator: "AND"
|
||||
inverted: false
|
||||
|
||||
or_rules:
|
||||
name: Rules with OR
|
||||
description: MyText
|
||||
enabled: true
|
||||
operator: "OR"
|
||||
inverted: false
|
||||
|
||||
invalid_subject:
|
||||
name: Rules with an invalid rule subject
|
||||
enabled: true
|
||||
operator: "AND"
|
||||
inverted: false
|
||||
|
||||
invalid_condition_type:
|
||||
name: Rules with an invalid rule condition type
|
||||
enabled: true
|
||||
operator: "AND"
|
||||
inverted: false
|
||||
|
||||
invalid_operator:
|
||||
name: Rules with an invalid rule operator
|
||||
enabled: true
|
||||
operator: "FOO"
|
||||
inverted: false
|
||||
|
||||
metadata:
|
||||
name: Metadata
|
||||
description: Add metadata to mail (servers, clients…)
|
||||
enabled: true
|
||||
|
||||
issue:
|
||||
name: Linked to issue(s)
|
||||
description: Is this mail associated to one or multiple issues
|
||||
enabled: true
|
||||
|
||||
cron:
|
||||
name: FromCron
|
||||
description: Is this mail from cron?
|
||||
enabled: true
|
||||
|
||||
mailing_list:
|
||||
name: FromMailingList
|
||||
description: Is this mail from amailing list?
|
||||
enabled: true
|
||||
|
||||
postpone_future_valid:
|
||||
name: Postpone to valid date in the future
|
||||
enabled: true
|
||||
|
||||
postpone_past_valid:
|
||||
name: Postpone to valid date in the past
|
||||
enabled: true
|
||||
|
||||
postpone_invalid:
|
||||
name: Postpone to invalid date
|
||||
enabled: true
|
||||
|
||||
junk:
|
||||
name: Junk mail
|
||||
enabled: true
|
|
@ -1,87 +0,0 @@
|
|||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
rule_set: one
|
||||
name: Subject contains MyString
|
||||
enabled: true
|
||||
subject_type: Header
|
||||
subject_value: Subject
|
||||
condition_type: contain
|
||||
condition_value: MyString
|
||||
inverted: false
|
||||
|
||||
two:
|
||||
rule_set: two
|
||||
name: Subject doesn't contain MyString
|
||||
enabled: true
|
||||
subject_type: Header
|
||||
subject_value: Subject
|
||||
condition_type: contain
|
||||
condition_value: MyString
|
||||
inverted: true
|
||||
|
||||
invalid_subject:
|
||||
rule_set: invalid_subject
|
||||
name: Rule with invalid subject type
|
||||
enabled: true
|
||||
subject_type: Invalid
|
||||
subject_value: Subject
|
||||
condition_type: contain
|
||||
condition_value: MyString
|
||||
inverted: false
|
||||
|
||||
invalid_condition_type:
|
||||
rule_set: invalid_condition_type
|
||||
name: Rule with invalid condition type
|
||||
enabled: true
|
||||
subject_type: Header
|
||||
subject_value: Subject
|
||||
condition_type: invalid
|
||||
condition_value: MyString
|
||||
inverted: false
|
||||
|
||||
invalid_operator:
|
||||
rule_set: invalid_operator
|
||||
name: Rule with valid arguments
|
||||
enabled: true
|
||||
subject_type: Header
|
||||
subject_value: Subject
|
||||
condition_type: contain
|
||||
condition_value: MyString
|
||||
inverted: false
|
||||
|
||||
postpone_future_valid:
|
||||
rule_set: postpone_future_valid
|
||||
name: Match Postponable in Subject
|
||||
enabled: true
|
||||
subject_type: Subject
|
||||
condition_type: match
|
||||
condition_value: Postponable
|
||||
inverted: false
|
||||
|
||||
postpone_past_valid:
|
||||
rule_set: postpone_past_valid
|
||||
name: Match Postponable in Subject
|
||||
enabled: true
|
||||
subject_type: Subject
|
||||
condition_type: match
|
||||
condition_value: Postponable
|
||||
inverted: false
|
||||
|
||||
postpone_invalid:
|
||||
rule_set: postpone_invalid
|
||||
name: Match Postponable in Subject
|
||||
enabled: true
|
||||
subject_type: Subject
|
||||
condition_type: match
|
||||
condition_value: Postponable
|
||||
inverted: false
|
||||
|
||||
junk_subject:
|
||||
rule_set: junk
|
||||
name: Junk in subject
|
||||
enabled: true
|
||||
subject_type: Subject
|
||||
condition_type: match
|
||||
condition_value: Junk
|
||||
inverted: false
|
|
@ -1,6 +1,6 @@
|
|||
require "test_helper"
|
||||
|
||||
class RuleSetTest < ActiveSupport::TestCase
|
||||
class ConditionTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
|
@ -1,6 +1,6 @@
|
|||
require "test_helper"
|
||||
|
||||
class RuleTest < ActiveSupport::TestCase
|
||||
class FilterTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
|
@ -1,6 +1,6 @@
|
|||
require "test_helper"
|
||||
|
||||
class ActionTest < ActiveSupport::TestCase
|
||||
class OperationTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
|
@ -1,27 +1,27 @@
|
|||
require 'test_helper'
|
||||
|
||||
class RuleSetProcessorTest < ActiveSupport::TestCase
|
||||
class FilterProcessorTest < ActiveSupport::TestCase
|
||||
|
||||
test "mark cron from subject" do
|
||||
email = email_from_eml_with_rules("cron_subject.eml")
|
||||
email = email_from_eml_with_filters("cron_subject.eml")
|
||||
|
||||
assert_predicate email, :cron?
|
||||
end
|
||||
|
||||
test "mark cron from headers" do
|
||||
email = email_from_eml_with_rules("cron_headers.eml")
|
||||
email = email_from_eml_with_filters("cron_headers.eml")
|
||||
|
||||
assert_predicate email, :cron?
|
||||
end
|
||||
|
||||
test "mark not cron" do
|
||||
email = email_from_eml_with_rules("cron_not.eml")
|
||||
email = email_from_eml_with_filters("cron_not.eml")
|
||||
|
||||
assert_not_predicate email, :cron?
|
||||
end
|
||||
|
||||
test "single issue" do
|
||||
email = email_from_eml_with_rules("issues_single.eml")
|
||||
email = email_from_eml_with_filters("issues_single.eml")
|
||||
|
||||
expected = ["49123"]
|
||||
actual = email.issues
|
||||
|
@ -30,7 +30,7 @@ class RuleSetProcessorTest < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
test "multiple issues" do
|
||||
email = email_from_eml_with_rules("issues_multiple.eml")
|
||||
email = email_from_eml_with_filters("issues_multiple.eml")
|
||||
|
||||
expected = ["49123", "12345"]
|
||||
actual = email.issues
|
||||
|
@ -39,7 +39,7 @@ class RuleSetProcessorTest < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
test "single organisation" do
|
||||
email = email_from_eml_with_rules("organisations_single.eml")
|
||||
email = email_from_eml_with_filters("organisations_single.eml")
|
||||
|
||||
expected = ["quux"]
|
||||
actual = email.organisations
|
||||
|
@ -48,7 +48,7 @@ class RuleSetProcessorTest < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
test "multiple organisations" do
|
||||
email = email_from_eml_with_rules("organisations_multiple.eml")
|
||||
email = email_from_eml_with_filters("organisations_multiple.eml")
|
||||
|
||||
expected = ["quux", "foobar"]
|
||||
actual = email.organisations
|
||||
|
@ -56,34 +56,34 @@ class RuleSetProcessorTest < ActiveSupport::TestCase
|
|||
assert_equal expected, actual
|
||||
end
|
||||
|
||||
test "invalid subject type" do
|
||||
test "invalid Test" do
|
||||
email = Email.new
|
||||
processor = RuleSetProcessor.new
|
||||
email = processor.process(rule_sets(:invalid_subject), email)
|
||||
processor = FilterProcessor.new
|
||||
email = processor.process(filters(:invalid_subject), email)
|
||||
|
||||
assert_not_predicate email, :changed?
|
||||
end
|
||||
|
||||
test "invalid condition type" do
|
||||
test "invalid Property type" do
|
||||
email = Email.new
|
||||
processor = RuleSetProcessor.new
|
||||
email = processor.process(rule_sets(:invalid_condition_type), email)
|
||||
processor = FilterProcessor.new
|
||||
email = processor.process(filters(:invalid_condition_type), email)
|
||||
|
||||
assert_not_predicate email, :changed?
|
||||
end
|
||||
|
||||
test "invalid operator" do
|
||||
email = Email.new
|
||||
processor = RuleSetProcessor.new
|
||||
email = processor.process(rule_sets(:invalid_operator), email)
|
||||
processor = FilterProcessor.new
|
||||
email = processor.process(filters(:invalid_operator), email)
|
||||
|
||||
assert_not_predicate email, :changed?
|
||||
end
|
||||
|
||||
test "postponed to valid future date" do
|
||||
email = Email.new(subject: "Postponable")
|
||||
processor = RuleSetProcessor.new
|
||||
email = processor.process(rule_sets(:postpone_future_valid), email)
|
||||
processor = FilterProcessor.new
|
||||
email = processor.process(filters(:postpone_future_valid), email)
|
||||
|
||||
assert_not_nil email.postponed_until
|
||||
assert_predicate email, :postponed?
|
||||
|
@ -91,8 +91,8 @@ class RuleSetProcessorTest < ActiveSupport::TestCase
|
|||
|
||||
test "postponed to valid past date" do
|
||||
email = Email.new(subject: "Postponable")
|
||||
processor = RuleSetProcessor.new
|
||||
email = processor.process(rule_sets(:postpone_past_valid), email)
|
||||
processor = FilterProcessor.new
|
||||
email = processor.process(filters(:postpone_past_valid), email)
|
||||
|
||||
assert_not_nil email.postponed_until
|
||||
assert_not_predicate email, :postponed?
|
||||
|
@ -100,8 +100,8 @@ class RuleSetProcessorTest < ActiveSupport::TestCase
|
|||
|
||||
test "postponed to invalid date" do
|
||||
email = Email.new(subject: "Postponable")
|
||||
processor = RuleSetProcessor.new
|
||||
email = processor.process(rule_sets(:postpone_invalid), email)
|
||||
processor = FilterProcessor.new
|
||||
email = processor.process(filters(:postpone_invalid), email)
|
||||
|
||||
assert_nil email.postponed_until
|
||||
assert_not_predicate email, :postponed?
|
||||
|
@ -109,8 +109,8 @@ class RuleSetProcessorTest < ActiveSupport::TestCase
|
|||
|
||||
test "junk mail" do
|
||||
email = Email.new(subject: "Junk")
|
||||
processor = RuleSetProcessor.new
|
||||
email = processor.process(rule_sets(:junk), email)
|
||||
processor = FilterProcessor.new
|
||||
email = processor.process(filters(:junk), email)
|
||||
|
||||
assert_predicate email, :junk?
|
||||
end
|
|
@ -0,0 +1,53 @@
|
|||
# require "application_system_test_case"
|
||||
#
|
||||
# class ConditionsTest < ApplicationSystemTestCase
|
||||
# setup do
|
||||
# @condition = conditions(:one)
|
||||
# end
|
||||
#
|
||||
# test "visiting the index" do
|
||||
# visit conditions_url
|
||||
# assert_selector "h1", text: "Conditions"
|
||||
# end
|
||||
#
|
||||
# test "creating a Condition" do
|
||||
# visit conditions_url
|
||||
# click_on "New Condition"
|
||||
#
|
||||
# fill_in "Property type", with: @condition.property_type
|
||||
# fill_in "Property value", with: @condition.property_value
|
||||
# check "Enabled" if @condition.enabled
|
||||
# check "Inverted" if @condition.inverted
|
||||
# fill_in "Test method", with: @condition.test_method
|
||||
# fill_in "Test value", with: @condition.test_value
|
||||
# click_on "Create Condition"
|
||||
#
|
||||
# assert_text "Condition was successfully created"
|
||||
# click_on "Back"
|
||||
# end
|
||||
#
|
||||
# test "updating a Condition" do
|
||||
# visit conditions_url
|
||||
# click_on "Edit", match: :first
|
||||
#
|
||||
# fill_in "Property type", with: @condition.property_type
|
||||
# fill_in "Property value", with: @condition.property_value
|
||||
# check "Enabled" if @condition.enabled
|
||||
# check "Inverted" if @condition.inverted
|
||||
# fill_in "Test method", with: @condition.test_method
|
||||
# fill_in "Test value", with: @condition.test_value
|
||||
# click_on "Update Condition"
|
||||
#
|
||||
# assert_text "Condition was successfully updated"
|
||||
# click_on "Back"
|
||||
# end
|
||||
#
|
||||
# test "destroying a Condition" do
|
||||
# visit conditions_url
|
||||
# page.accept_confirm do
|
||||
# click_on "Destroy", match: :first
|
||||
# end
|
||||
#
|
||||
# assert_text "Condition was successfully destroyed"
|
||||
# end
|
||||
# end
|
|
@ -0,0 +1,49 @@
|
|||
require "application_system_test_case"
|
||||
|
||||
class FiltersTest < ApplicationSystemTestCase
|
||||
setup do
|
||||
@filter = filters(:one)
|
||||
end
|
||||
|
||||
test "visiting the index" do
|
||||
visit filters_url
|
||||
assert_selector "h1", text: "Filters"
|
||||
end
|
||||
|
||||
test "creating a Filter" do
|
||||
visit filters_url
|
||||
click_on "New Filter"
|
||||
|
||||
fill_in "Description", with: @filter.description
|
||||
check "Enabled" if @filter.enabled
|
||||
check "Inverted" if @filter.inverted
|
||||
fill_in "Operator", with: @filter.operator
|
||||
click_on "Create Filter"
|
||||
|
||||
assert_text "Filter was successfully created"
|
||||
click_on "Back"
|
||||
end
|
||||
|
||||
test "updating a Filter" do
|
||||
visit filters_url
|
||||
click_on "Edit", match: :first
|
||||
|
||||
fill_in "Description", with: @filter.description
|
||||
check "Enabled" if @filter.enabled
|
||||
check "Inverted" if @filter.inverted
|
||||
fill_in "Operator", with: @filter.operator
|
||||
click_on "Update Filter"
|
||||
|
||||
assert_text "Filter was successfully updated"
|
||||
click_on "Back"
|
||||
end
|
||||
|
||||
test "destroying a Filter" do
|
||||
visit filters_url
|
||||
page.accept_confirm do
|
||||
click_on "Destroy", match: :first
|
||||
end
|
||||
|
||||
assert_text "Filter was successfully destroyed"
|
||||
end
|
||||
end
|
|
@ -0,0 +1,47 @@
|
|||
# require "application_system_test_case"
|
||||
#
|
||||
# class OperationsTest < ApplicationSystemTestCase
|
||||
# setup do
|
||||
# @operation = operations(:one)
|
||||
# end
|
||||
#
|
||||
# test "visiting the index" do
|
||||
# visit operations_url
|
||||
# assert_selector "h1", text: "Operations"
|
||||
# end
|
||||
#
|
||||
# test "creating a Operation" do
|
||||
# visit operations_url
|
||||
# click_on "New Operation"
|
||||
#
|
||||
# fill_in "Argument", with: @operation.argument
|
||||
# fill_in "Class name", with: @operation.class_name
|
||||
# check "Enabled" if @operation.enabled
|
||||
# click_on "Create Operation"
|
||||
#
|
||||
# assert_text "Operation was successfully created"
|
||||
# click_on "Back"
|
||||
# end
|
||||
#
|
||||
# test "updating a Operation" do
|
||||
# visit operations_url
|
||||
# click_on "Edit", match: :first
|
||||
#
|
||||
# fill_in "Argument", with: @operation.argument
|
||||
# fill_in "Class name", with: @operation.class_name
|
||||
# check "Enabled" if @operation.enabled
|
||||
# click_on "Update Operation"
|
||||
#
|
||||
# assert_text "Operation was successfully updated"
|
||||
# click_on "Back"
|
||||
# end
|
||||
#
|
||||
# test "destroying a Operation" do
|
||||
# visit operations_url
|
||||
# page.accept_confirm do
|
||||
# click_on "Destroy", match: :first
|
||||
# end
|
||||
#
|
||||
# assert_text "Operation was successfully destroyed"
|
||||
# end
|
||||
# end
|
|
@ -4,7 +4,7 @@ require 'rails/test_help'
|
|||
|
||||
class ActiveSupport::TestCase
|
||||
# Run tests in parallel with specified workers
|
||||
parallelize(workers: :number_of_processors)
|
||||
# parallelize(workers: :number_of_processors)
|
||||
|
||||
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
|
||||
fixtures :all
|
||||
|
@ -19,10 +19,10 @@ class ActiveSupport::TestCase
|
|||
|
||||
email
|
||||
end
|
||||
def email_from_eml_with_rules(file_fixture_name)
|
||||
def email_from_eml_with_filters(file_fixture_name)
|
||||
email = email_from_eml(file_fixture_name)
|
||||
processor = RuleSetProcessor.new
|
||||
email = processor.process_all(RuleSet.enabled, email)
|
||||
processor = FilterProcessor.new
|
||||
email = processor.process_all(Filter.enabled, email)
|
||||
end
|
||||
|
||||
def assert_no_html(text)
|
||||
|
|
Loading…
Reference in New Issue