-
-
Notifications
You must be signed in to change notification settings - Fork 195
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch '5990-single-guess-redeliver' into develop
- Loading branch information
Showing
9 changed files
with
366 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
require 'text' | ||
|
||
## | ||
# A guess at which info request a incoming message should be associated to | ||
# | ||
class Guess | ||
attr_reader :info_request, :components | ||
|
||
# The percentage similarity the id or idhash much fulfil | ||
THRESHOLD = 0.8 | ||
|
||
## | ||
# Return InfoRequest which we guess should receive an incoming message based | ||
# on a threshold. | ||
# | ||
def self.guessed_info_requests(email) | ||
# Match the email address in the message without matching the hash | ||
email_addresses = MailHandler.get_all_addresses(email) | ||
guesses = InfoRequest.guess_by_incoming_email(email_addresses) | ||
|
||
guesses_reaching_threshold = guesses.select do |ir_guess| | ||
id_score = ir_guess.id_score | ||
idhash_score = ir_guess.idhash_score | ||
|
||
(id_score == 1 && idhash_score >= THRESHOLD) || | ||
(id_score >= THRESHOLD && idhash_score == 1) | ||
end | ||
|
||
guesses_reaching_threshold.map(&:info_request).uniq | ||
end | ||
|
||
def initialize(info_request, **components) | ||
@info_request = info_request | ||
@components = components | ||
end | ||
|
||
def [](key) | ||
components[key] | ||
end | ||
|
||
def id_score | ||
return 1 unless self[:id] | ||
similarity(self[:id], info_request.id) | ||
end | ||
|
||
def idhash_score | ||
return 1 unless self[:idhash] | ||
similarity(self[:idhash], info_request.idhash) | ||
end | ||
|
||
def ==(other) | ||
info_request == other.info_request && components == other.components | ||
end | ||
|
||
def match_method | ||
components.keys.first | ||
end | ||
|
||
private | ||
|
||
def similarity(a, b) | ||
Text::WhiteSimilarity.similarity(a.to_s, b.to_s) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -127,26 +127,6 @@ | |
expect(page).to have_content "Only the authority can reply to this request" | ||
end | ||
end | ||
|
||
it "guesses a misdirected request" do | ||
info_request = FactoryBot.create(:info_request, | ||
allow_new_responses_from: 'authority_only', | ||
handle_rejected_responses: 'holding_pen') | ||
mail_to = "request-#{info_request.id}[email protected]" | ||
receive_incoming_mail('incoming-request-plain.email', email_to: mail_to) | ||
interesting_email = last_holding_pen_mail | ||
|
||
# now we add another message to the queue, which we're not interested in | ||
receive_incoming_mail('incoming-request-plain.email', | ||
email_to: info_request.incoming_email, | ||
email_from: "") | ||
expect(holding_pen_messages.length).to eq(2) | ||
using_session(@admin) do | ||
visit admin_raw_email_path interesting_email | ||
expect(page).to have_content "Could not identify the request" | ||
expect(page).to have_content info_request.title | ||
end | ||
end | ||
end | ||
|
||
describe 'generating an upload url' do | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
require 'spec_helper' | ||
|
||
RSpec.describe Guess do | ||
let(:info_request) do | ||
FactoryBot.create(:info_request, id: 100, idhash: '4e637388') | ||
end | ||
|
||
describe '.guessed_info_requests' do | ||
subject(:guesses) { described_class.guessed_info_requests(email) } | ||
|
||
let(:email) do | ||
mail = Mail.new | ||
mail.to address | ||
end | ||
|
||
let(:info_request) { FactoryBot.create(:info_request, id: 4566) } | ||
let!(:other_info_request) { FactoryBot.create(:info_request) } | ||
|
||
let(:id) { info_request.id } | ||
let(:hash) { info_request.idhash } | ||
|
||
context 'with email matching ID and ID hash' do | ||
let(:address) { info_request.incoming_email } | ||
|
||
it 'return matching InfoRequest' do | ||
is_expected.to match_array([info_request]) | ||
end | ||
end | ||
|
||
context 'with email matching ID and almost ID hash' do | ||
let(:address) { "request-#{id}-#{hash[0...-1]}}z@localhost" } | ||
|
||
it 'return guessed InfoRequest' do | ||
is_expected.to match_array([info_request]) | ||
end | ||
end | ||
|
||
context 'with email matching ID hash and almost ID' do | ||
let(:address) { "request-#{id.to_s[0...-1]}-#{hash}@localhost" } | ||
|
||
it 'return guessed InfoRequest' do | ||
is_expected.to match_array([info_request]) | ||
end | ||
end | ||
end | ||
|
||
describe 'with a subject line given' do | ||
let(:guess) { described_class.new(info_request, subject: 'subject_line') } | ||
|
||
it 'returns an id_score of 1' do | ||
expect(guess.id_score).to eq(1) | ||
end | ||
|
||
it 'returns an idhash_score of 1' do | ||
expect(guess.idhash_score).to eq(1) | ||
end | ||
end | ||
|
||
describe 'with an id given' do | ||
let(:guess_1) { described_class.new(info_request, id: 100) } | ||
let(:guess_2) { described_class.new(info_request, id: 456) } | ||
let(:guess_3) { described_class.new(info_request, id: 109) } | ||
|
||
it 'returns an id_score of 1 when it is correct' do | ||
expect(guess_1.id_score).to eq(1.0) | ||
end | ||
|
||
it 'returns an id_score of 0 when there is no similarity' do | ||
expect(guess_2.id_score).to eq(0.0) | ||
end | ||
|
||
it 'returns a value between 0 and 1 when there is some similarity' do | ||
expect(guess_3.id_score).to be_between(0, 1).exclusive | ||
end | ||
end | ||
|
||
describe 'with an idhash given' do | ||
let(:guess_1) { described_class.new(info_request, idhash: '4e637388') } | ||
let(:guess_2) { described_class.new(info_request, idhash: '12345678') } | ||
let(:guess_3) { described_class.new(info_request, idhash: '4e637399') } | ||
|
||
it 'returns an idhash_score of 1 when it is correct' do | ||
expect(guess_1.idhash_score).to eq(1.0) | ||
end | ||
|
||
it 'returns an idhash_score of 0 when there is no similarity' do | ||
expect(guess_2.idhash_score).to eq(0.0) | ||
end | ||
|
||
it 'returns a value between 0 and 1 when there is some similarity' do | ||
expect(guess_3.idhash_score).to be_between(0, 1).exclusive | ||
end | ||
end | ||
end |
Oops, something went wrong.