diff --git a/app/jobs/domain_expiration_email_job.rb b/app/jobs/domain_expiration_email_job.rb
new file mode 100644
index 000000000..1066d3f35
--- /dev/null
+++ b/app/jobs/domain_expiration_email_job.rb
@@ -0,0 +1,11 @@
+class DomainExpirationEmailJob < ActiveJob::Base
+ queue_as :default
+
+ def perform(domain_id:)
+ domain = Domain.find(domain_id)
+
+ return if domain.registered?
+
+ DomainMailer.expiration(domain).deliver!
+ end
+end
diff --git a/app/mailers/domain_mailer.rb b/app/mailers/domain_mailer.rb
index afdfe89fc..e53c6d596 100644
--- a/app/mailers/domain_mailer.rb
+++ b/app/mailers/domain_mailer.rb
@@ -117,17 +117,6 @@ class DomainMailer < ApplicationMailer
name: @domain.name)} [#{@domain.name}]")
end
- def expiration_reminder(domain_id)
- @domain = Domain.find_by(id: domain_id)
- return if @domain.nil? || !@domain.statuses.include?(DomainStatus::EXPIRED) || whitelist_blocked?(@domain.registrant.email)
- return if whitelist_blocked?(@domain.registrant.email)
-
- mail(to: format(@domain.registrant.email),
- subject: "#{I18n.t(:expiration_remind_subject,
- name: @domain.name)} [#{@domain.name}]")
- end
-
-
def force_delete(domain_id, should_deliver)
@domain = Domain.find_by(id: domain_id)
return if delivery_off?(@domain, should_deliver)
@@ -140,6 +129,16 @@ class DomainMailer < ApplicationMailer
)
end
+ def expiration(domain:)
+ @domain = DomainPresenter.new(domain: domain, view: view_context)
+ @registrar = RegistrarPresenter.new(registrar: domain.registrar, view: view_context)
+
+ recipients = domain.admin_contact_emails << domain.registrant_email
+
+ subject = default_i18n_subject(domain_name: domain.name)
+ mail(to: recipients, subject: subject)
+ end
+
private
# app/models/DomainMailModel provides the data for mail that can be composed_from
# which ensures that values of objects are captured when they are valid, not later when this method is executed
diff --git a/app/models/concerns/domain/expirable.rb b/app/models/concerns/domain/expirable.rb
new file mode 100644
index 000000000..237bdfd34
--- /dev/null
+++ b/app/models/concerns/domain/expirable.rb
@@ -0,0 +1,31 @@
+module Concerns::Domain::Expirable
+ extend ActiveSupport::Concern
+
+ included do
+ alias_attribute :expire_time, :valid_to
+ end
+
+ class_methods do
+ def expired
+ where("#{attribute_alias(:expire_time)} <= ?", Time.zone.now)
+ end
+ end
+
+ def registered?
+ valid_to >= Time.zone.now
+ end
+
+ def expired?
+ statuses.include?(DomainStatus::EXPIRED)
+ end
+
+ def expirable?
+ return false if valid_to > Time.zone.now
+
+ if expired? && outzone_at.present? && delete_at.present?
+ return false
+ end
+
+ true
+ end
+end
diff --git a/app/models/contact.rb b/app/models/contact.rb
index 50e78ef54..822394d22 100644
--- a/app/models/contact.rb
+++ b/app/models/contact.rb
@@ -250,6 +250,13 @@ class Contact < ActiveRecord::Base
kit.to_pdf
end
+ def names
+ pluck(:name)
+ end
+
+ def emails
+ pluck(:email)
+ end
end
def roid
diff --git a/app/models/domain.rb b/app/models/domain.rb
index 1d96dbfde..7b7087dd9 100644
--- a/app/models/domain.rb
+++ b/app/models/domain.rb
@@ -3,12 +3,16 @@ class Domain < ActiveRecord::Base
include UserEvents
include Versions # version/domain_version.rb
include Statuses
+ include Concerns::Domain::Expirable
has_paper_trail class_name: "DomainVersion", meta: { children: :children_log }
attr_accessor :roles
attr_accessor :legal_document_id
+ alias_attribute :on_hold_time, :outzone_at
+ alias_attribute :delete_time, :delete_at
+
# TODO: whois requests ip whitelist for full info for own domains and partial info for other domains
# TODO: most inputs should be trimmed before validatation, probably some global logic?
@@ -746,6 +750,21 @@ class Domain < ActiveRecord::Base
DomainMailer.send(action, DomainMailModel.new(self).send(action)).deliver
end
+ def admin_contact_names
+ admin_contacts.names
+ end
+
+ def admin_contact_emails
+ admin_contacts.emails
+ end
+
+ def tech_contact_names
+ tech_contacts.names
+ end
+
+ def nameserver_hostnames
+ nameservers.hostnames
+ end
def self.to_csv
CSV.generate do |csv|
diff --git a/app/models/nameserver.rb b/app/models/nameserver.rb
index 7b4daab3d..fb56f1198 100644
--- a/app/models/nameserver.rb
+++ b/app/models/nameserver.rb
@@ -18,7 +18,7 @@ class Nameserver < ActiveRecord::Base
before_validation :normalize_attributes
before_validation :check_puny_symbols
before_validation :check_label_length
-
+
delegate :name, to: :domain, prefix: true
def epp_code_map
@@ -117,5 +117,9 @@ class Nameserver < ActiveRecord::Base
# ignoring ips
rel
end
+
+ def hostnames
+ pluck(:hostname)
+ end
end
end
diff --git a/app/presenters/domain_presenter.rb b/app/presenters/domain_presenter.rb
new file mode 100644
index 000000000..ea8b0ba22
--- /dev/null
+++ b/app/presenters/domain_presenter.rb
@@ -0,0 +1,33 @@
+class DomainPresenter
+ delegate :name, :registrant_name, to: :domain
+
+ def initialize(domain:, view:)
+ @domain = domain
+ @view = view
+ end
+
+ def on_hold_date
+ view.l(domain.on_hold_time, format: :date) if domain.on_hold_time
+ end
+
+ def delete_date
+ view.l(domain.delete_time, format: :date) if domain.delete_time
+ end
+
+ def admin_contact_names
+ domain.admin_contact_names.join(', ')
+ end
+
+ def tech_contact_names
+ domain.tech_contact_names.join(', ')
+ end
+
+ def nameserver_names
+ domain.nameserver_hostnames.join(', ')
+ end
+
+ private
+
+ attr_reader :domain
+ attr_reader :view
+end
diff --git a/app/presenters/registrar_presenter.rb b/app/presenters/registrar_presenter.rb
new file mode 100644
index 000000000..1fe415feb
--- /dev/null
+++ b/app/presenters/registrar_presenter.rb
@@ -0,0 +1,27 @@
+class RegistrarPresenter
+ def initialize(registrar:, view:)
+ @registrar = registrar
+ @view = view
+ end
+
+ def name
+ registrar.name
+ end
+
+ def email
+ registrar.email
+ end
+
+ def phone
+ registrar.phone
+ end
+
+ def url
+ registrar.url
+ end
+
+ private
+
+ attr_reader :registrar
+ attr_reader :view
+end
diff --git a/app/views/mailers/domain_mailer/expiration.html.erb b/app/views/mailers/domain_mailer/expiration.html.erb
new file mode 100644
index 000000000..d06a8803e
--- /dev/null
+++ b/app/views/mailers/domain_mailer/expiration.html.erb
@@ -0,0 +1,67 @@
+Domeen <%= @domain.name %> on aegunud
+Lugupeetud .ee domeeni kasutaja
+
+Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= @domain.on_hold_date %> internetis kättesaadav. Alates <%= @domain.delete_date %> on domeen <%= @domain.name %> avatud registreerimiseks kõigile huvilistele.
+
+Domeeni registreeringu pikendamiseks pöörduge palun oma registripidaja <%= @registrar.name %> poole. Registripidajate kontaktid leiate aadressilt www.internet.ee/registripidajad.
+
+Domeeni <%= @domain.name %> kohta on registris järgmised andmed:
+
+Registreerija: <%= @domain.registrant_name %>
+Halduskontakt: <%= @domain.admin_contact_names %>
+Tehniline kontakt: <%= @domain.tech_contact_names %>
+Registripidaja: <%= @registrar.name %>
+Nimeserverid: <%= @domain.nameserver_names %>
+Ülevaate kõikidest endaga seotud domeenidest saate registreerija portaalist. <%= ENV['registrant_url'] %>.
+
+Lugupidamisega
+Eesti Interneti Sihtasutus
+
+
+
+The <%= @domain.name %> domain has expired
+Dear user of .ee domain,
+
+The domain name <%= @domain.name %> has expired and will not be available on the Internet from <%= @domain.on_hold_date %>. From <%= @domain.delete_date %>, the <%= @domain.name %> domain will be available for registration on a first come first served basis.
+
+To renew the domain registration, please contact your registrar <%= @registrar.name %>. You can find the registrar's contacts at http://internet.ee/registrars.
+
+The following data for the <%= @domain.name %> domain have been entered into the registry:
+
+Registrant: <%= @domain.registrant_name %>
+Administrative contact: <%= @domain.admin_contact_names %>
+Technical contact: <%= @domain.tech_contact_names %>
+Registrar: <%= @registrar.name %>
+Name servers: <%= @domain.nameserver_names %>
+You can find an overview of all your domains at the registrant's portal. <%= ENV['registrant_url'] %>.
+
+Best Regards,
+Estonian Internet Foundation
+
+
+
+Домен <%= @domain.name %> устарел
+Уважаемый пользователь домена .ee
+
+
+Доменное имя <%= @domain.name %> устарело и с <%= @domain.on_hold_date %> недоступно в Интернете. С <%= @domain.delete_date %> домен <%= @domain.name %> доступен для регистрации всем желающим по принципу "first come, first served".
+
+
+
+Для продления регистрации домена просим обратиться к своему регистратору <%= @registrar.name %>. Контактные данные регистраторов можно найти по адресу http://internet.ee/registratory.
+
+
+Относительно домена <%= @domain.name %> в реестр внесены следующие данные:
+
+
+Регистрант: <%= @domain.registrant_name %>
+Административный контакт: <%= @domain.admin_contact_names %>
+Технический контакт: <%= @domain.tech_contact_names %>
+Регистратор: <%= @registrar.name %>
+Серверы доменных имен: <%= @domain.nameserver_names %>
+Обзор всех связанных с Вами доменов можете получить на портале регистранта. <%= ENV['registrant_url'] %>.
+
+
+
+С наилучшими пожеланиями
+Целевое учреждение Eesti Internet
diff --git a/app/views/mailers/domain_mailer/expiration.text.erb b/app/views/mailers/domain_mailer/expiration.text.erb
new file mode 100644
index 000000000..7cfa9a9fc
--- /dev/null
+++ b/app/views/mailers/domain_mailer/expiration.text.erb
@@ -0,0 +1,60 @@
+Domeen <%= @domain.name %> on aegunud
+Lugupeetud .ee domeeni kasutaja
+
+Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= @domain.on_hold_date %> internetis kättesaadav. Alates <%= @domain.delete_date %> on domeen <%= @domain.name %> avatud registreerimiseks kõigile huvilistele.
+
+Domeeni registreeringu pikendamiseks pöörduge palun oma registripidaja <%= @registrar.name %> poole. Registripidajate kontaktid leiate aadressilt www.internet.ee/registripidajad.
+
+Domeeni <%= @domain.name %> kohta on registris järgmised andmed:
+
+Registreerija: <%= @domain.registrant_name %>
+Halduskontakt: <%= @domain.admin_contact_names %>
+Tehniline kontakt: <%= @domain.tech_contact_names %>
+Registripidaja: <%= @registrar.name %>
+Nimeserverid: <%= @domain.nameserver_names %>
+Ülevaate kõikidest endaga seotud domeenidest saate registreerija portaalist. <%= ENV['registrant_url'] %>.
+
+Parimate soovidega
+Eesti Interneti Sihtasutus
+
+--------------------------------------
+
+The <%= @domain.name %> domain has expired
+Dear user of .ee domain,
+
+The domain name <%= @domain.name %> has expired and will not be available on the Internet from <%= @domain.on_hold_date %>. From <%= @domain.delete_date %>, the <%= @domain.name %> domain will be available for registration on a first come first served basis.
+
+To renew the domain registration, please contact your registrar <%= @registrar.name %>. You can find the registrar's contacts at http://internet.ee/registrars.
+
+The following data for the <%= @domain.name %> domain have been entered into the registry:
+
+Registrant: <%= @domain.registrant_name %>
+Administrative contact: <%= @domain.admin_contact_names %>
+Technical contact: <%= @domain.tech_contact_names %>
+Registrar: <%= @registrar.name %>
+Name servers: <%= @domain.nameserver_names %>
+You can find an overview of all your domains at the registrant's portal. <%= ENV['registrant_url'] %>.
+
+Best Regards,
+Estonian Internet Foundation
+
+--------------------------------------
+
+Домен <%= @domain.name %> устарел
+Уважаемый пользователь домена .ee
+
+Доменное имя <%= @domain.name %> устарело и с <%= @domain.on_hold_date %> недоступно в Интернете. С <%= @domain.delete_date %> домен <%= @domain.name %> доступен для регистрации всем желающим по принципу "first come, first served".
+
+Для продления регистрации домена просим обратиться к своему регистратору <%= @registrar.name %>. Контактные данные регистраторов можно найти по адресу http://internet.ee/registratory.
+
+Относительно домена <%= @domain %> в реестр внесены следующие данные:
+
+Регистрант: <%= @domain.registrant_name %>
+Административный контакт: <%= @domain.admin_contact_names %>
+Технический контакт: <%= @domain.tech_contact_names %>
+Регистратор: <%= @registrar.name %>
+Серверы доменных имен: <%= @domain.nameserver_names %>
+Обзор всех связанных с Вами доменов можете получить на портале регистранта. <%= ENV['registrant_url'] %>.
+
+С наилучшими пожеланиями
+Целевое учреждение Eesti Internet
diff --git a/config/locales/en.yml b/config/locales/en.yml
index a5bf12885..264502adf 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -945,7 +945,6 @@ en:
list_format_is_in_yaml: 'List format is in YAML'
if_auth_info_is_left_empty_it_will_be_auto_generated: 'If auth info is left empty, it will be auto generated.'
each_domain_name_must_end_with_colon_sign: 'Each domain name must end with colon (:) sign.'
- expiration_remind_subject: 'The %{name} domain has expired'
next: 'Next'
previous: 'Previous'
personal_domain_verification_url: 'Personal domain verification url'
diff --git a/config/locales/mailers/domain.en.yml b/config/locales/mailers/domain.en.yml
new file mode 100644
index 000000000..99dc33a5a
--- /dev/null
+++ b/config/locales/mailers/domain.en.yml
@@ -0,0 +1,4 @@
+en:
+ domain_mailer:
+ expiration:
+ subject: The %{domain_name} domain has expired
diff --git a/spec/factories/admin_domain_contact.rb b/spec/factories/admin_domain_contact.rb
new file mode 100644
index 000000000..786825214
--- /dev/null
+++ b/spec/factories/admin_domain_contact.rb
@@ -0,0 +1,5 @@
+FactoryGirl.define do
+ factory :admin_domain_contact, parent: :domain_contact, class: AdminDomainContact do
+
+ end
+end
diff --git a/spec/factories/contact.rb b/spec/factories/contact.rb
new file mode 100644
index 000000000..5218da399
--- /dev/null
+++ b/spec/factories/contact.rb
@@ -0,0 +1,16 @@
+FactoryGirl.define do
+ factory :contact do
+ name 'test'
+ sequence(:code) { |n| "test#{n}" }
+ phone '+123.456789'
+ email 'test@test.com'
+ street 'test'
+ city 'test'
+ zip 12345
+ country_code 'EE'
+ ident '37605030299'
+ ident_type 'priv'
+ ident_country_code 'EE'
+ registrar
+ end
+end
diff --git a/spec/factories/dnskey.rb b/spec/factories/dnskey.rb
new file mode 100644
index 000000000..e06387487
--- /dev/null
+++ b/spec/factories/dnskey.rb
@@ -0,0 +1,15 @@
+FactoryGirl.define do
+ factory :dnskey do
+ alg Dnskey::ALGORITHMS.first
+ flags Dnskey::FLAGS.first
+ protocol Dnskey::PROTOCOLS.first
+ ds_digest_type 2
+ domain
+ public_key 'AwEAAaOf5+lz3ftsL+0CCvfJbhUF/NVsNh8BKo61oYs5fXVbuWDiH872 '\
+ 'LC8uKDO92TJy7Q4TF9XMAKMMlf1GMAxlRspD749SOCTN00sqfWx1OMTu '\
+ 'a28L1PerwHq7665oDJDKqR71btcGqyLKhe2QDvCdA0mENimF1NudX1BJ '\
+ 'DDFi6oOZ0xE/0CuveB64I3ree7nCrwLwNs56kXC4LYoX3XdkOMKiJLL/ '\
+ 'MAhcxXa60CdZLoRtTEW3z8/oBq4hEAYMCNclpbd6y/exScwBxFTdUfFk '\
+ 'KsdNcmvai1lyk9vna0WQrtpYpHKMXvY9LFHaJxCOLR4umfeQ42RuTd82 lqfU6ClMeXs='
+ end
+end
diff --git a/spec/factories/domain.rb b/spec/factories/domain.rb
new file mode 100644
index 000000000..5a396362d
--- /dev/null
+++ b/spec/factories/domain.rb
@@ -0,0 +1,15 @@
+FactoryGirl.define do
+ factory :domain do
+ sequence(:name) { |n| "test#{n}.com" }
+ period 1
+ period_unit 'y' # Year
+ registrar
+ registrant
+
+ after :build do |domain|
+ domain.nameservers << FactoryGirl.build_pair(:nameserver)
+ domain.admin_domain_contacts << FactoryGirl.build(:admin_domain_contact)
+ domain.tech_domain_contacts << FactoryGirl.build(:tech_domain_contact)
+ end
+ end
+end
diff --git a/spec/factories/domain_contact.rb b/spec/factories/domain_contact.rb
new file mode 100644
index 000000000..ae05fd293
--- /dev/null
+++ b/spec/factories/domain_contact.rb
@@ -0,0 +1,5 @@
+FactoryGirl.define do
+ factory :domain_contact do
+ contact
+ end
+end
diff --git a/spec/factories/nameserver.rb b/spec/factories/nameserver.rb
new file mode 100644
index 000000000..ebe7a7909
--- /dev/null
+++ b/spec/factories/nameserver.rb
@@ -0,0 +1,6 @@
+FactoryGirl.define do
+ factory :nameserver do
+ sequence(:hostname) { |n| "ns.test#{n}.ee" }
+ ipv4 '192.168.1.1'
+ end
+end
diff --git a/spec/factories/registrant.rb b/spec/factories/registrant.rb
new file mode 100644
index 000000000..c4846fcd4
--- /dev/null
+++ b/spec/factories/registrant.rb
@@ -0,0 +1,5 @@
+FactoryGirl.define do
+ factory :registrant, parent: :contact, class: Registrant do
+ name 'test'
+ end
+end
diff --git a/spec/factories/registrar.rb b/spec/factories/registrar.rb
new file mode 100644
index 000000000..dd581a1d1
--- /dev/null
+++ b/spec/factories/registrar.rb
@@ -0,0 +1,13 @@
+FactoryGirl.define do
+ factory :registrar do
+ sequence(:name) { |n| "test#{n}" }
+ sequence(:code) { |n| "test#{n}" }
+ sequence(:reg_no) { |n| "test#{n}" }
+ street 'test'
+ city 'test'
+ state 'test'
+ zip 'test'
+ email 'test@test.com'
+ country_code 'EE'
+ end
+end
diff --git a/spec/factories/tech_domain_contact.rb b/spec/factories/tech_domain_contact.rb
new file mode 100644
index 000000000..e407474a3
--- /dev/null
+++ b/spec/factories/tech_domain_contact.rb
@@ -0,0 +1,5 @@
+FactoryGirl.define do
+ factory :tech_domain_contact, parent: :domain_contact, class: TechDomainContact do
+
+ end
+end
diff --git a/spec/jobs/domain_expiration_email_job_spec.rb b/spec/jobs/domain_expiration_email_job_spec.rb
new file mode 100644
index 000000000..f435b1f0b
--- /dev/null
+++ b/spec/jobs/domain_expiration_email_job_spec.rb
@@ -0,0 +1,40 @@
+require 'rails_helper'
+
+RSpec.describe DomainExpirationEmailJob do
+ it 'queues the job' do
+ expect { described_class.perform_later }.to have_enqueued_job(described_class)
+ end
+
+ describe '#perform' do
+ let(:domain) { instance_double(Domain) }
+
+ before :example do
+ expect(Domain).to receive(:find).and_return(domain)
+ end
+
+ context 'when domain is expired' do
+ let(:message) { instance_double(ActionMailer::MessageDelivery) }
+
+ before :example do
+ allow(domain).to receive(:registered?).and_return(false)
+ end
+
+ it 'sends email notification' do
+ expect(DomainMailer).to receive(:expiration).with(domain: domain).and_return(message)
+ expect(message).to receive(:deliver!)
+ described_class.perform_now(domain_id: 1)
+ end
+ end
+
+ context 'when domain is registered' do
+ before :example do
+ allow(domain).to receive(:registered?).and_return(true)
+ end
+
+ it 'does not send email notification' do
+ expect(DomainMailer).to_not receive(:expiration)
+ described_class.perform_now(domain_id: 1)
+ end
+ end
+ end
+end
diff --git a/spec/mailers/domain_mailer_spec.rb b/spec/mailers/domain_mailer_spec.rb
new file mode 100644
index 000000000..c3679f116
--- /dev/null
+++ b/spec/mailers/domain_mailer_spec.rb
@@ -0,0 +1,38 @@
+require 'rails_helper'
+
+RSpec.describe DomainMailer do
+ describe '#expiration' do
+ let(:domain) { instance_spy(Domain,
+ name: 'test.com',
+ registrant_email: 'registrant@test.com',
+ admin_contact_emails: ['admin.contact.email@test.com']
+ ) }
+ let(:domain_presenter) { instance_spy(DomainPresenter) }
+ let(:registrar_presenter) { instance_spy(RegistrarPresenter) }
+ subject(:message) { described_class.expiration(domain: domain) }
+
+ before :example do
+ expect(DomainPresenter).to receive(:new).and_return(domain_presenter)
+ expect(RegistrarPresenter).to receive(:new).and_return(registrar_presenter)
+ end
+
+ it 'has valid sender' do
+ message.deliver!
+ expect(message.from).to eq(['noreply@internet.ee'])
+ end
+
+ it 'has registrant and administrative contacts as recipient' do
+ message.deliver!
+ expect(message.to).to match_array(['registrant@test.com', 'admin.contact.email@test.com'])
+ end
+
+ it 'has valid subject' do
+ message.deliver!
+ expect(message.subject).to eq('The test.com domain has expired')
+ end
+
+ it 'sends message' do
+ expect { message.deliver! }.to change { ActionMailer::Base.deliveries.count }.by(1)
+ end
+ end
+end
diff --git a/spec/models/concerns/domain/expirable_spec.rb b/spec/models/concerns/domain/expirable_spec.rb
new file mode 100644
index 000000000..72fde82ab
--- /dev/null
+++ b/spec/models/concerns/domain/expirable_spec.rb
@@ -0,0 +1,57 @@
+require 'rails_helper'
+
+RSpec.describe Domain, db: false do
+ it { is_expected.to alias_attribute(:expire_time, :valid_to) }
+
+ describe '::expired', db: true do
+ before :example do
+ travel_to Time.zone.parse('05.07.2010 00:00')
+
+ FactoryGirl.create(:domain, id: 1, expire_time: Time.zone.parse('04.07.2010 23:59'))
+ FactoryGirl.create(:domain, id: 2, expire_time: Time.zone.parse('05.07.2010 00:00'))
+ FactoryGirl.create(:domain, id: 3, expire_time: Time.zone.parse('05.07.2010 00:01'))
+ end
+
+ it 'returns expired domains' do
+ expect(described_class.expired.ids).to eq([1, 2])
+ end
+ end
+
+ describe '#registered?' do
+ before :example do
+ travel_to Time.zone.parse('05.07.2010 00:00')
+ end
+
+ context 'when :valid_to is in the future' do
+ let(:domain) { described_class.new(expire_time: Time.zone.parse('06.07.2010 00:01')) }
+
+ specify { expect(domain).to be_registered }
+ end
+
+ context 'when :valid_to is the same as current time' do
+ let(:domain) { described_class.new(expire_time: Time.zone.parse('05.07.2010 00:00')) }
+
+ specify { expect(domain).to_not be_registered }
+ end
+
+ context 'when :valid_to is in the past' do
+ let(:domain) { described_class.new(expire_time: Time.zone.parse('04.07.2010 23:59')) }
+
+ specify { expect(domain).to_not be_registered }
+ end
+ end
+
+ describe '#expired?' do
+ context 'when :statuses contains expired status' do
+ let(:domain) { described_class.new(statuses: [DomainStatus::EXPIRED]) }
+
+ specify { expect(domain).to be_expired }
+ end
+
+ context 'when :statuses does not contain expired status' do
+ let(:domain) { described_class.new(statuses: [DomainStatus::CLIENT_HOLD]) }
+
+ specify { expect(domain).to_not be_expired }
+ end
+ end
+end
diff --git a/spec/models/contact_spec.rb b/spec/models/contact_spec.rb
index b54c5a47f..b20f4bf60 100644
--- a/spec/models/contact_spec.rb
+++ b/spec/models/contact_spec.rb
@@ -1,28 +1,8 @@
require 'rails_helper'
-describe Contact do
+RSpec.describe Contact do
before :example do
- Setting.ds_algorithm = 2
- Setting.ds_data_allowed = true
- Setting.ds_data_with_key_allowed = true
- Setting.key_data_allowed = true
-
- Setting.dnskeys_min_count = 0
- Setting.dnskeys_max_count = 9
- Setting.ns_min_count = 2
- Setting.ns_max_count = 11
-
- Setting.transfer_wait_time = 0
-
- Setting.admin_contacts_min_count = 1
- Setting.admin_contacts_max_count = 10
- Setting.tech_contacts_min_count = 0
- Setting.tech_contacts_max_count = 10
-
- Setting.client_side_status_editing_enabled = true
-
Fabricate(:zonefile_setting, origin: 'ee')
- @api_user = Fabricate(:api_user)
end
context 'about class' do
diff --git a/spec/models/domain_spec.rb b/spec/models/domain_spec.rb
index 1d6a63fb8..a8384372c 100644
--- a/spec/models/domain_spec.rb
+++ b/spec/models/domain_spec.rb
@@ -928,29 +928,4 @@ RSpec.describe Domain, db: false do
expect(domain.nameserver_hostnames).to eq('hostnames')
end
end
-
- describe '#registered?' do
- before :example do
- travel_to Time.zone.parse('05.07.2010 00:00:01')
- end
-
- context 'when :valid_to is in the future' do
- let(:domain) { described_class.new(valid_to: Time.zone.parse('06.07.2010')) }
-
- specify { expect(domain).to be_registered }
- end
-
- context 'when :valid_to is the same as current time' do
- let(:domain) { described_class.new(valid_to: Time.zone.parse('05.07.2010 00:00:01')) }
-
-
- specify { expect(domain).to be_registered }
- end
-
- context 'when :valid_to is in the past' do
- let(:domain) { described_class.new(valid_to: Time.zone.parse('04.07.2010 23:59:59')) }
-
- specify { expect(domain).to_not be_registered }
- end
- end
end
diff --git a/spec/presenters/domain_presenter_spec.rb b/spec/presenters/domain_presenter_spec.rb
new file mode 100644
index 000000000..a6799095b
--- /dev/null
+++ b/spec/presenters/domain_presenter_spec.rb
@@ -0,0 +1,96 @@
+require 'rails_helper'
+
+RSpec.describe DomainPresenter do
+ let(:presenter) { described_class.new(domain: domain, view: view) }
+
+ describe '#on_hold_date' do
+ subject(:on_hold_date) { presenter.on_hold_date }
+
+ context 'when present' do
+ let(:domain) { instance_double(Domain, on_hold_time: '05.07.2010') }
+
+ it 'returns localized date' do
+ expect(view).to receive(:l).with('05.07.2010', format: :date).and_return('on hold date')
+ expect(on_hold_date).to eq('on hold date')
+ end
+ end
+
+ context 'when absent' do
+ let(:domain) { instance_double(Domain, on_hold_time: nil) }
+
+ specify { expect(on_hold_date).to be_nil }
+ end
+ end
+
+ describe '#delete_date' do
+ subject(:delete_date) { presenter.delete_date }
+
+ context 'when present' do
+ let(:domain) { instance_double(Domain, delete_time: '05.07.2010') }
+
+ it 'returns localized date' do
+ expect(view).to receive(:l).with('05.07.2010', format: :date).and_return('delete date')
+ expect(delete_date).to eq('delete date')
+ end
+ end
+
+ context 'when absent' do
+ let(:domain) { instance_double(Domain, delete_time: nil) }
+
+ specify { expect(delete_date).to be_nil }
+ end
+ end
+
+ describe '#admin_contact_names' do
+ let(:domain) { instance_double(Domain) }
+
+ before :example do
+ expect(domain).to receive(:admin_contact_names).and_return(%w(test1 test2 test3))
+ end
+
+ it 'returns admin contact names' do
+ expect(presenter.admin_contact_names).to eq('test1, test2, test3')
+ end
+ end
+
+ describe '#tech_contact_names' do
+ let(:domain) { instance_double(Domain) }
+
+ before :example do
+ expect(domain).to receive(:tech_contact_names).and_return(%w(test1 test2 test3))
+ end
+
+ it 'returns technical contact names' do
+ expect(presenter.tech_contact_names).to eq('test1, test2, test3')
+ end
+ end
+
+ describe '#nameserver_names' do
+ let(:domain) { instance_double(Domain) }
+
+ before :example do
+ expect(domain).to receive(:nameserver_hostnames).and_return(%w(test1 test2 test3))
+ end
+
+ it 'returns nameserver names' do
+ expect(presenter.nameserver_names).to eq('test1, test2, test3')
+ end
+ end
+
+
+ domain_delegatable_attributes = %i(
+ name
+ registrant_name
+ )
+
+ domain_delegatable_attributes.each do |attribute_name|
+ describe "##{attribute_name}" do
+ let(:domain) { instance_spy(Domain) }
+
+ it 'delegates to domain' do
+ presenter.send(attribute_name)
+ expect(domain).to have_received(attribute_name)
+ end
+ end
+ end
+end
diff --git a/spec/presenters/registrar_presenter_spec.rb b/spec/presenters/registrar_presenter_spec.rb
new file mode 100644
index 000000000..462f8049c
--- /dev/null
+++ b/spec/presenters/registrar_presenter_spec.rb
@@ -0,0 +1,34 @@
+require 'rails_helper'
+
+RSpec.describe RegistrarPresenter do
+ let(:registrar) { instance_double(Registrar) }
+ let(:presenter) { described_class.new(registrar: registrar, view: nil) }
+
+ describe '#name' do
+ it 'returns name' do
+ expect(registrar).to receive(:name).and_return('test name')
+ expect(presenter.name).to eq('test name')
+ end
+ end
+
+ describe '#email' do
+ it 'returns email' do
+ expect(registrar).to receive(:email).and_return('test email')
+ expect(presenter.email).to eq('test email')
+ end
+ end
+
+ describe '#phone' do
+ it 'returns phone' do
+ expect(registrar).to receive(:phone).and_return('test phone')
+ expect(presenter.phone).to eq('test phone')
+ end
+ end
+
+ describe '#url' do
+ it 'returns url' do
+ expect(registrar).to receive(:url).and_return('test url')
+ expect(presenter.url).to eq('test url')
+ end
+ end
+end
diff --git a/spec/views/mailers/domain_mailer/expiration.html.erb_spec.rb b/spec/views/mailers/domain_mailer/expiration.html.erb_spec.rb
new file mode 100644
index 000000000..fc1e18e61
--- /dev/null
+++ b/spec/views/mailers/domain_mailer/expiration.html.erb_spec.rb
@@ -0,0 +1,36 @@
+require 'rails_helper'
+
+RSpec.describe 'mailers/domain_mailer/expiration.html.erb' do
+ let(:domain) { instance_spy(DomainPresenter) }
+ let(:registrar) { instance_spy(RegistrarPresenter) }
+ let(:lang_count) { 3 }
+
+ before :example do
+ assign(:domain, domain)
+ assign(:registrar, registrar)
+ end
+
+ it 'has registrar name' do
+ mention_count = 2 * lang_count
+ expect(registrar).to receive(:name).exactly(mention_count).times.and_return('test registrar name')
+ render
+ expect(rendered).to have_text('test registrar name', count: mention_count)
+ end
+
+ attributes = %i(
+ on_hold_date
+ delete_date
+ registrant_name
+ admin_contact_names
+ tech_contact_names
+ nameserver_names
+ )
+
+ attributes.each do |attr_name|
+ it "has :#{attr_name}" do
+ expect(domain).to receive(attr_name).exactly(lang_count).times.and_return(attr_name.to_s)
+ render
+ expect(rendered).to have_text(attr_name.to_s, count: lang_count)
+ end
+ end
+end
diff --git a/spec/views/mailers/domain_mailer/expiration.text.erb_spec.rb b/spec/views/mailers/domain_mailer/expiration.text.erb_spec.rb
new file mode 100644
index 000000000..39a36cdb7
--- /dev/null
+++ b/spec/views/mailers/domain_mailer/expiration.text.erb_spec.rb
@@ -0,0 +1,36 @@
+require 'rails_helper'
+
+RSpec.describe 'mailers/domain_mailer/expiration.text.erb' do
+ let(:domain) { instance_spy(DomainPresenter) }
+ let(:registrar) { instance_spy(RegistrarPresenter) }
+ let(:lang_count) { 3 }
+
+ before :example do
+ assign(:domain, domain)
+ assign(:registrar, registrar)
+ end
+
+ it 'has registrar name' do
+ mention_count = 2 * lang_count
+ expect(registrar).to receive(:name).exactly(mention_count).times.and_return('test registrar name')
+ render
+ expect(rendered).to have_text('test registrar name', count: mention_count)
+ end
+
+ attributes = %i(
+ on_hold_date
+ delete_date
+ registrant_name
+ admin_contact_names
+ tech_contact_names
+ nameserver_names
+ )
+
+ attributes.each do |attr_name|
+ it "has :#{attr_name}" do
+ expect(domain).to receive(attr_name).exactly(lang_count).times.and_return(attr_name.to_s)
+ render
+ expect(rendered).to have_text(attr_name.to_s, count: lang_count)
+ end
+ end
+end