Skip to content

Instantly share code, notes, and snippets.

@lesm
Created January 22, 2025 05:32
Show Gist options
  • Save lesm/3705ceeb505ae751dea8c52fb0db2deb to your computer and use it in GitHub Desktop.
Save lesm/3705ceeb505ae751dea8c52fb0db2deb to your computer and use it in GitHub Desktop.
EasyBroker API
# frozen_string_literal: true
require 'debug'
require 'faraday'
require 'rspec'
############## Entities ###############################################
class Property
attr_reader :agent, :public_id, :title, :operations
def initialize(attributes = {})
@agent = attributes['agent']
@public_id = attributes['public_id']
@title = attributes['title']
@operations = attributes['operations'].map { |attrs| Operation.new(attrs) }
end
end
############### test file ###################################
# RSpec.describe Property do
# let(:subject) { described_class.new(attrs) }
# let(:attrs) do
# {
# 'agent' => 'Luis Silva',
# 'public_id' => 'EB-B5007',
# 'title' => 'Casa en Venta en Terranova Residencial en Oaxaca',
# 'operations' => [
# {
# 'type' => 'sale',
# 'amount' => 650000.0,
# 'currency' => 'MXN',
# 'formatted_amount' => '$650,000',
# 'commission' => {'type' => 'percentage'},
# 'unit' => 'total'
# }
# ]
# }
# end
#
# describe '#initialize' do
# it 'sets the agent attribute' do
# expect(subject.agent).to eq('Luis Silva')
# end
#
# it 'sets the public_id attribute' do
# expect(subject.public_id).to eq('EB-B5007')
# end
#
# it 'sets the title attribute' do
# expect(subject.title).to eq('Casa en Venta en Terranova Residencial en Oaxaca')
# end
#
# it 'sets the operations relations' do
# expect(subject.operations.first).to be_a Operation
# end
# end
# end
class Operation
attr_reader :type, :amount, :commission
def initialize(attributes = {})
@type = attributes['type']
@amount = attributes['amount']
@commission = attributes['commission'] ? Commission.new(attributes['commission']) : nil
end
end
############### test file ###################################
# RSpec.describe Operation do
# let(:subject) { described_class.new(attrs) }
# let(:attrs) do
# {
# 'type' => 'sale',
# 'amount' => 600_000,
# 'commission' => {
# 'type' => 'percentage',
# 'value' => 650.0,
# 'currency' => 'MXN',
# }
# }
# end
#
# describe '#initialize' do
# it 'sets the type attribute' do
# expect(subject.type).to eq('sale')
# end
#
# it 'sets the amount attribute' do
# expect(subject.amount).to eq(600_000)
# end
#
# it 'sets the commission relation' do
# expect(subject.commission).to be_a Commission
# end
# end
# end
class Commission
attr_reader :type, :value, :currency
def initialize(attributes = {})
@type = attributes['type']
@value = attributes['value']
@currency = attributes['currency']
end
end
############### test file ###################################
# RSpec.describe Commission do
# let(:subject) { described_class.new(attrs) }
# let(:attrs) do
# {
# 'type' => 'percentage',
# 'value' => 650.0,
# 'currency' => 'MXN',
# }
# end
#
# describe '#initialize' do
# it 'sets the type attribute' do
# expect(subject.type).to eq('percentage')
# end
#
# it 'sets the value attribute' do
# expect(subject.value).to eq(650.0)
# end
#
# it 'sets the currency attribute' do
# expect(subject.currency).to eq('MXN')
# end
# end
# end
############## Client ###############################################
class Client
def initialize(config = {})
@http = Faraday.new(config[:url]) do |conn|
conn.headers = config[:headers]
conn.request :json
conn.response :json
conn.adapter Faraday.default_adapter
end
end
def properties(params = nil)
request :get, "v1/properties#{params ? "?#{params}" : ''}"
end
private
attr_reader :last_response
def request(method, *args)
@last_response = @http.public_send(method, *args)
handle_response(last_response)
end
def handle_response(response)
# TODO Handler API errores like
# raise Errors::NotFoundError, response.body, if not_found?(response)
last_response.body
end
end
############### test file ###################################
# RSpec.describe Client do
# let(:subject) { described_class.new(config) }
# let(:config) do
# {
# url: 'https://api.stagingeb.com/',
# headers: { 'X-Authorization' => 'l7u502p8v46ba3ppgvj5y2aad50lb9' }
# }
# end
#
# describe '#initialize' do
# it 'sets a Faraday instance' do
# allow(Faraday).to receive(:new)
# subject
# expect(Faraday).to have_received(:new).with(config[:url])
# end
# end
#
# describe '#properties' do
# let(:stub_response) do
# {
# 'pagination' => {
# 'limit' => 20, 'page' => 1, 'total' => 1107, 'next_page' => 'url'
# },
# 'content' => [
# {
# 'public_id' => 'EB-B0425',
# 'title' => 'Casa bien bonita',
# 'title_image_full' => 'url',
# 'title_image_thumb' => 'url',
# 'location' => 'San Antonio El Grande, Aquiles Serdán, Chihuahua',
# 'operations' => [
# {
# 'type' => 'sale',
# 'amount' => 8000.0,
# 'currency' => 'MXN',
# 'formatted_amount' => '$8,000',
# 'commission' => {
# 'type' => 'percentage',
# 'value' => '5.0'
# },
# 'unit' => 'square_meter'
# }
# ],
# 'bedrooms' => 4,
# 'bathrooms' => 4,
# 'parking_spaces' => 3,
# 'property_type' => 'Casa',
# 'lot_size' => 300.0,
# 'construction_size' => 220.0,
# 'updated_at' => '2024-08-12T23:33:24-06:00',
# 'agent' => 'Alejandro Blanco Zivec',
# 'show_prices' => true,
# 'share_commission' => true
# }
# ]
# }
# end
#
# before do
# stub_request(:get, %r{v1\/properties})
# .to_return_json(status: 200, body: stub_response, headers: {})
# end
#
# it 'returns a Hash' do
# expect(subject.properties).to be_a Hash
# end
#
# it "has the 'pagination' and 'content' keys" do
# expect(subject.properties.keys).to eq(['pagination', 'content'])
# end
# end
# end
############## List EasyBroker properties ###############################################
class EasyBroker
def list_properties
# NOTE Here we just simulate users click
puts "========= Properties from page 1 ========="
properties.each do |property|
puts "ID: #{property.public_id}, Title: #{property.title}"
end
(2..(rand(15) + 2)).to_a.each do |page|
puts "========= Properties from page #{page} ========="
properties("page=#{page}").each do |property|
puts "ID: #{property.public_id}, Title: #{property.title}"
end
end
end
private
def properties(page = nil)
client.properties(page)['content'].map do |attrs|
Property.new(attrs)
end
end
def client
# TODO These values need to be store in an ENV they're here just an example
Client.new(
url: 'https://api.stagingeb.com/',
headers: { 'X-Authorization' => 'l7u502p8v46ba3ppgvj5y2aad50lb9' }
)
end
end
EasyBroker.new.list_properties
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment