Created
January 22, 2025 05:32
-
-
Save lesm/3705ceeb505ae751dea8c52fb0db2deb to your computer and use it in GitHub Desktop.
EasyBroker API
This file contains hidden or 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
| # 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