Skip to content

Commit

Permalink
feat: add expire_at field to domain reservation responses
Browse files Browse the repository at this point in the history
Add expiration time information to domain reservation responses across all endpoints:
- Add FREE_RESERVATION_EXPIRY (7 days) and PAID_RESERVATION_EXPIRY (1 year) constants
- Update ReservedDomain model to set expire_at on creation
- Modify ReserveDomainInvoice#build_reserved_domains_output to include expire_at
- Update API responses to include expire_at in reserved_domains data
- Add comprehensive tests for expiration time handling

This change ensures consistent expiration time handling across both free and paid
domain reservations, with proper validation in the test suite.
  • Loading branch information
OlegPhenomenon committed Nov 29, 2024
1 parent 4f21dc7 commit 2c34ac2
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ class LongReserveDomainsStatusController < BaseController
def show
result = @reserved_domain_invoice.invoice_state

puts "result: #{result.inspect}"

if result.paid?
@reserved_domain_invoice.create_reserved_domains
@reserved_domain_invoice.create_paid_reserved_domains
render json: { status: 'paid', message: result.message, reserved_domains: @reserved_domain_invoice.build_reserved_domains_output }
else
render json: { status: result.status, message: result.message, names: @reserved_domain_invoice.domain_names }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ def create
if result.success
render_success({
message: "Domains reserved successfully",
reserved_domains: result.reserved_domains.map { |domain| { name: domain.name, password: domain.password } }
reserved_domains: result.reserved_domains.map do |domain|
{
name: domain.name,
password: domain.password,
expire_at: domain.expire_at
}
end
}, :created)
else
render_error(result.errors, :unprocessable_entity)
Expand Down
24 changes: 20 additions & 4 deletions app/models/reserve_domain_invoice.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def check_state_of_intersecting_invoices(domain_names)
if invoice.pending? && result.paid?

invoice.paid!
invoice.create_reserved_domains
invoice.create_paid_reserved_domains
ReserveDomainInvoice.cancel_intersecting_invoices(domain_names)

return true
Expand Down Expand Up @@ -180,11 +180,27 @@ def invoice_state
EisBilling::GetReservedDomainsInvoiceStatus.call(invoice_number: invoice_number, user_unique_id: metainfo)
end

def create_reserved_domains
domain_names.map { |name| ReservedDomain.create(name: name) if ReservedDomain.find_by(name: name).nil? }
def create_paid_reserved_domains
domain_names.map do |name|
next if ReservedDomain.find_by(name: name).present?

ReservedDomain.create(
name: name,
expire_at: Time.current + ReservedDomain::PAID_RESERVATION_EXPIRY
)
end
end

def build_reserved_domains_output
domain_names.map { |name| ReservedDomain.where(name: name).pluck(:name, :password).to_h }
domain_names.map do |name|
domain = ReservedDomain.find_by(name: name)
next unless domain

{
name: domain.name,
password: domain.password,
expire_at: domain.expire_at
}
end.compact
end
end
8 changes: 7 additions & 1 deletion app/models/reserved_domain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class ReservedDomain < ApplicationRecord

MAX_DOMAIN_NAME_PER_REQUEST = 20

FREE_RESERVATION_EXPIRY = 7.days
PAID_RESERVATION_EXPIRY = 1.year

class << self
def ransackable_associations(*)
authorizable_ransackable_associations
Expand Down Expand Up @@ -53,7 +56,10 @@ def reserve_domains_without_payment(domain_names)

reserved_domains = []
available_domains.each do |domain_name|
reserved_domain = ReservedDomain.new(name: domain_name)
reserved_domain = ReservedDomain.new(
name: domain_name,
expire_at: Time.current + FREE_RESERVATION_EXPIRY
)
reserved_domain.regenerate_password
reserved_domain.save
reserved_domains << reserved_domain
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ def setup
body: {
message: 'Payment received',
invoice_status: 'paid',
invoice_number: @invoice.invoice_number
invoice_number: @invoice.invoice_number,
reserved_domain_names: @invoice.domain_names
},
user_unique_id: @invoice.metainfo
)
Expand Down Expand Up @@ -83,6 +84,41 @@ def setup
assert_equal 'Error occurred', json_response['message']
end

test "shows paid status with expire_at for reserved domains" do
stub_billing_request(
status: 200,
body: {
message: 'Payment received',
invoice_status: 'paid',
invoice_number: @invoice.invoice_number,
reserved_domain_names: @invoice.domain_names
},
user_unique_id: @invoice.metainfo
)

get api_v1_business_registry_long_reserve_domains_status_path(
invoice_number: @invoice.invoice_number,
user_unique_id: @invoice.metainfo
),
headers: { 'Origin' => @allowed_origins.first, 'REMOTE_ADDR' => @valid_ip }

assert_response :success
json_response = JSON.parse(response.body)

assert_equal 'paid', json_response['status']
assert_equal 'Payment received', json_response['message']

# Проверяем структуру reserved_domains
reserved_domain = json_response['reserved_domains'].first
assert_not_nil reserved_domain['name']
assert_not_nil reserved_domain['password']
assert_not_nil reserved_domain['expire_at']

# Проверяем, что expire_at установлен на 1 год
expire_at = Time.parse(reserved_domain['expire_at'])
assert_in_delta Time.current + ReservedDomain::PAID_RESERVATION_EXPIRY, expire_at, 5.seconds
end

private

def stub_billing_request(status:, body:, user_unique_id: nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,43 @@ def setup
json_response = JSON.parse(response.body)
assert_includes json_response['error'], "The maximum number of domain names per request is #{ReservedDomain::MAX_DOMAIN_NAME_PER_REQUEST}"
end

test "should reserve multiple domains successfully with correct expiration" do
domain_names = ["new1.test", "new2.test"]

assert_difference 'ReservedDomain.count', 2 do
post api_v1_business_registry_reserve_domains_path,
params: { domain_names: domain_names },
headers: { 'Origin' => @allowed_origins.first, 'REMOTE_ADDR' => @valid_ip }
end

assert_response :created
json_response = JSON.parse(response.body)
assert_equal "Domains reserved successfully", json_response['message']
assert_equal 2, json_response['reserved_domains'].length

json_response['reserved_domains'].each do |domain|
assert domain_names.include?(domain['name'])
assert_not_nil domain['password']
assert_not_nil domain['expire_at']

expire_at = Time.parse(domain['expire_at'])
assert_in_delta Time.current + ReservedDomain::FREE_RESERVATION_EXPIRY, expire_at, 5.seconds
end
end

test "should set correct expiration time for free reservations" do
domain_name = "new1.test"

post api_v1_business_registry_reserve_domains_path,
params: { domain_names: [domain_name] },
headers: { 'Origin' => @allowed_origins.first, 'REMOTE_ADDR' => @valid_ip }

assert_response :created
json_response = JSON.parse(response.body)
domain = json_response['reserved_domains'].first

expire_at = Time.parse(domain['expire_at'])
assert_in_delta Time.current + ReservedDomain::FREE_RESERVATION_EXPIRY, expire_at, 5.seconds
end
end
14 changes: 10 additions & 4 deletions test/models/reserve_domain_invoice_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,23 @@ def teardown
invoice = ReserveDomainInvoice.create(invoice_number: '12345', domain_names: @domain_names, metainfo: TEST_USER_UNIQUE_ID)

assert_difference 'ReservedDomain.count', 2 do
invoice.create_reserved_domains
invoice.create_paid_reserved_domains
end
end

test "builds correct output for reserved domains" do
invoice = ReserveDomainInvoice.create(invoice_number: '12345', domain_names: @domain_names, metainfo: TEST_USER_UNIQUE_ID)
ReservedDomain.create(name: @domain_names.first, password: 'test123')
ReservedDomain.create(
name: @domain_names.first,
password: 'test123',
expire_at: Time.current + ReservedDomain::PAID_RESERVATION_EXPIRY
)

output = invoice.build_reserved_domains_output
assert_equal @domain_names.count, output.length
assert_equal 'test123', output.first[@domain_names.first]
assert_equal @domain_names.count - 1, output.length
domain_output = output.find { |d| d[:name] == @domain_names.first }
assert_equal 'test123', domain_output[:password]
assert_not_nil domain_output[:expire_at]
end

test "handles intersecting domains" do
Expand Down

0 comments on commit 2c34ac2

Please sign in to comment.