From 49bf1845aeaefc8d430e76c3dad80573a5e90df8 Mon Sep 17 00:00:00 2001 From: HenriqueMorato Date: Thu, 24 Feb 2022 18:35:08 -0300 Subject: [PATCH] Pull request --- Gemfile.lock | 10 +- app/controllers/api/v1/api_controller.rb | 26 ++ app/controllers/api/v1/customer_controller.rb | 40 ++ .../v1/customer_payment_method_controller.rb | 77 +++ app/models/boleto_setting.rb | 3 + app/models/company.rb | 12 + app/models/credit_card_setting.rb | 2 + app/models/customer.rb | 8 + app/models/customer_payment_method.rb | 35 ++ app/models/pix_setting.rb | 2 + config/routes.rb | 10 + ...20211124234405_add_token_to_pix_setting.rb | 5 + ...11124234501_add_token_to_boleto_setting.rb | 5 + ...234511_add_token_to_credit_card_setting.rb | 5 + db/migrate/20211125160101_create_customers.rb | 12 + ...5201854_create_customer_payment_methods.rb | 16 + ...0211126165220_add_status_to_pix_setting.rb | 5 + ...1127004210_add_status_to_boleto_setting.rb | 5 + ...04220_add_status_to_credit_card_setting.rb | 5 + db/schema.rb | 38 +- spec/factories/customer_payment_methods.rb | 22 + spec/factories/customerpaymentmethods.rb | 13 + spec/factories/customers.rb | 21 + spec/models/customer_payment_method_spec.rb | 5 + spec/rails_helper.rb | 1 + spec/requests/api/boleto_settings_api_spec.rb | 109 +++++ .../api/credit_card_settings_api_spec.rb | 107 +++++ spec/requests/api/customer_api_spec.rb | 242 ++++++++++ .../customer_choose_payment_method_spec.rb | 442 ++++++++++++++++++ spec/support/api_macro.rb | 5 + 30 files changed, 1282 insertions(+), 6 deletions(-) create mode 100644 app/controllers/api/v1/api_controller.rb create mode 100644 app/controllers/api/v1/customer_controller.rb create mode 100644 app/controllers/api/v1/customer_payment_method_controller.rb create mode 100644 app/models/customer.rb create mode 100644 app/models/customer_payment_method.rb create mode 100644 db/migrate/20211124234405_add_token_to_pix_setting.rb create mode 100644 db/migrate/20211124234501_add_token_to_boleto_setting.rb create mode 100644 db/migrate/20211124234511_add_token_to_credit_card_setting.rb create mode 100644 db/migrate/20211125160101_create_customers.rb create mode 100644 db/migrate/20211125201854_create_customer_payment_methods.rb create mode 100644 db/migrate/20211126165220_add_status_to_pix_setting.rb create mode 100644 db/migrate/20211127004210_add_status_to_boleto_setting.rb create mode 100644 db/migrate/20211127004220_add_status_to_credit_card_setting.rb create mode 100644 spec/factories/customer_payment_methods.rb create mode 100644 spec/factories/customerpaymentmethods.rb create mode 100644 spec/factories/customers.rb create mode 100644 spec/models/customer_payment_method_spec.rb create mode 100644 spec/requests/api/boleto_settings_api_spec.rb create mode 100644 spec/requests/api/credit_card_settings_api_spec.rb create mode 100644 spec/requests/api/customer_api_spec.rb create mode 100644 spec/requests/api/customer_choose_payment_method_spec.rb create mode 100644 spec/support/api_macro.rb diff --git a/Gemfile.lock b/Gemfile.lock index b79366f..32fa465 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -100,7 +100,7 @@ GEM activesupport (>= 5.0) i18n (1.8.11) concurrent-ruby (~> 1.0) - jbuilder (2.11.2) + jbuilder (2.11.3) activesupport (>= 5.0.0) listen (3.7.0) rb-fsevent (~> 0.10, >= 0.10.3) @@ -193,7 +193,7 @@ GEM rspec-mocks (~> 3.10) rspec-support (~> 3.10) rspec-support (3.10.3) - rubocop (1.22.3) + rubocop (1.23.0) parallel (~> 1.10) parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) @@ -228,11 +228,11 @@ GEM simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) simplecov_json_formatter (0.1.3) - spring (3.0.0) + spring (3.1.0) sprockets (4.0.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.3.0) + sprockets-rails (3.4.1) actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) @@ -247,7 +247,7 @@ GEM unicode-display_width (2.1.0) warden (1.2.9) rack (>= 2.0.9) - web-console (4.1.0) + web-console (4.2.0) actionview (>= 6.0.0) activemodel (>= 6.0.0) bindex (>= 0.4.0) diff --git a/app/controllers/api/v1/api_controller.rb b/app/controllers/api/v1/api_controller.rb new file mode 100644 index 0000000..b14d1d1 --- /dev/null +++ b/app/controllers/api/v1/api_controller.rb @@ -0,0 +1,26 @@ +class Api::V1::ApiController < ActionController::API + rescue_from ActiveRecord::ActiveRecordError, with: :render_generic_error + rescue_from ActiveRecord::RecordNotFound, with: :render_not_found + ActiveRecord::Base.include_root_in_json = true + before_action :authenticate_company! + + + private + + def authenticate_company! + @company = Company.find_by(token: request.headers['companyToken']) + render_not_authorized if @company.nil? + end + + def render_not_authorized + render status: 401, json: { message: 'Há algo errado com sua autenticação.' } + end + + def render_not_found(e) + render status: 404, json: { message: 'Objeto não encontrado' } + end + + def render_generic_error(e) + render status: 500, json: { message: 'Erro geral' } + end +end diff --git a/app/controllers/api/v1/customer_controller.rb b/app/controllers/api/v1/customer_controller.rb new file mode 100644 index 0000000..dfea4f0 --- /dev/null +++ b/app/controllers/api/v1/customer_controller.rb @@ -0,0 +1,40 @@ +class Api::V1::CustomerController < Api::V1::ApiController + + def index + @customers = Customer.all.where(company: @company) + + render status:200, json: @customers.as_json( except: %i[id company_id + created_at updated_at], + include: { company: { only: :legal_name } } ) + end + + def show + @customer = Customer.find_by(token: params[:id]) + raise ActiveRecord::RecordNotFound if @customer.nil? + + return render_not_authorized if @customer.company != @company + + render status: :ok, json: @customer.as_json(except: %i[id company_id + created_at updated_at], + include: { company: { only: :legal_name } }) + end + + def create + @customer = @company.customers.create(customer_params) + + if @customer.save + render status: :created, json: @customer.as_json(except: %i[id company_id created_at updated_at], + include: { company: { only: :legal_name } }) + else + render status: :unprocessable_entity, json: { message: 'Requisição inválida', errors: @customer.errors, + request: @customer.as_json(except: %i[id token company_id + created_at updated_at]) } + end + end + + + private + def customer_params + params.require(:customer).permit(:name, :cpf) + end +end diff --git a/app/controllers/api/v1/customer_payment_method_controller.rb b/app/controllers/api/v1/customer_payment_method_controller.rb new file mode 100644 index 0000000..d893a2a --- /dev/null +++ b/app/controllers/api/v1/customer_payment_method_controller.rb @@ -0,0 +1,77 @@ +module Api + module V1 + class CustomerPaymentMethodController < Api::V1::ApiController + def index + @customer_payment_method = CustomerPaymentMethod.where(company: @company) + + render status: :ok, json: success_json + end + + def show + @customer_payment_method = CustomerPaymentMethod.find_by(token: params[:id], company: @company) + raise ActiveRecord::RecordNotFound if @customer_payment_method.nil? + + render status: :ok, json: success_json + end + + def create + @payment_method = find_payment_method + @customer = Customer.find_by(token: customer_payment_method_params[:customer_token], company: @company) + + @customer_payment_method = CustomerPaymentMethod.new( + payment_method: @payment_method, customer: @customer, company: @company + ) + @customer_payment_method.add_credit_card(credit_card_params) if @payment_method&.credit_card? + + return render status: :created, json: success_json if @customer_payment_method.save + + render status: :unprocessable_entity, json: error_json + end + + private + + def customer_payment_method_params + params.require(:customer_payment_method).permit(:customer_token, :payment_method_token) + end + + def credit_card_params + params.require(:customer_payment_method).permit( + :credit_card_name, :credit_card_number, + :credit_card_expiration_date, :credit_card_security_code + ) + end + + def find_payment_method + payment_setting = @company.find_enabled_payment_setting_by_token( + customer_payment_method_params[:payment_method_token] + ) + payment_setting&.payment_method + end + + def success_json + @customer_payment_method.as_json( + only: %i[token], + include: { + payment_method: { only: %i[name type_of] }, + customer: { only: %i[token] }, + company: { only: %i[legal_name] } + } + ) + end + + def error_json + { + message: 'Requisição inválida', errors: @customer_payment_method.errors, + # TODO: passar entrada do cartão de crédito de volta? + request: @customer_payment_method.as_json( + only: %i[], + include: { + payment_method: { only: %i[name type_of] }, + customer: { only: %i[token] }, company: { only: %i[legal_name] } + } + ) + } + end + end + end +end diff --git a/app/models/boleto_setting.rb b/app/models/boleto_setting.rb index 96b2621..7912ab7 100644 --- a/app/models/boleto_setting.rb +++ b/app/models/boleto_setting.rb @@ -2,6 +2,9 @@ class BoletoSetting < ApplicationRecord belongs_to :company belongs_to :payment_method, -> { where(type_of: :boleto) }, inverse_of: :boleto_settings + enum status: { enabled: 5, disabled: 10 } + validates :agency_number, :account_number, :bank_code, presence: true validates :bank_code, bank_code: true + after_create :generate_token_attribute end diff --git a/app/models/company.rb b/app/models/company.rb index 65fdc8a..ab413d6 100644 --- a/app/models/company.rb +++ b/app/models/company.rb @@ -21,6 +21,18 @@ def payment_settings pix_settings + credit_card_settings + boleto_settings end + def find_enabled_payment_setting_by_token(token) + payment_settings.find do |ps| + ps.enabled? && ps.payment_method.enabled? && ps.token == token + end + end + + # TODO: remover se não for utilizado + def list_payment_methods + pix_settings.map(&:payment_method) + credit_card_settings.map(&:payment_method) + + boleto_settings.map(&:payment_method) + end + def blank_all_info! self.cnpj = '' self.legal_name = '' diff --git a/app/models/credit_card_setting.rb b/app/models/credit_card_setting.rb index 19bcaa2..5c8039b 100644 --- a/app/models/credit_card_setting.rb +++ b/app/models/credit_card_setting.rb @@ -2,5 +2,7 @@ class CreditCardSetting < ApplicationRecord belongs_to :company belongs_to :payment_method, -> { where(type_of: :credit_card) }, inverse_of: :credit_card_settings + enum status: { enabled: 5, disabled: 10 } + validates :company_code, presence: true end diff --git a/app/models/customer.rb b/app/models/customer.rb new file mode 100644 index 0000000..a533398 --- /dev/null +++ b/app/models/customer.rb @@ -0,0 +1,8 @@ +class Customer < ApplicationRecord + belongs_to :company + + after_create :generate_token_attribute + + validates :name, presence: true + validates :cpf, presence: true +end diff --git a/app/models/customer_payment_method.rb b/app/models/customer_payment_method.rb new file mode 100644 index 0000000..bcdd16c --- /dev/null +++ b/app/models/customer_payment_method.rb @@ -0,0 +1,35 @@ +class CustomerPaymentMethod < ApplicationRecord + belongs_to :payment_method + belongs_to :company + belongs_to :customer + + after_create :generate_token_attribute + + validates :credit_card_name, :credit_card_number, :credit_card_expiration_date, + :credit_card_security_code, presence: true, if: -> { payment_method&.credit_card? } + + validate :expiration_date_cannot_be_in_the_past, if: -> { payment_method&.credit_card? } + + enum name: { pix: 5, boleto: 10, cartao_de_credito: 15 } + + # TODO: testar esse metodo? + def add_credit_card(params) + return unless payment_method&.credit_card? + + self.credit_card_name = params[:credit_card_name] + self.credit_card_number = params[:credit_card_number] + self.credit_card_expiration_date = params[:credit_card_expiration_date] + self.credit_card_security_code = params[:credit_card_security_code] + end + + private + + def expiration_date_cannot_be_in_the_past + return unless credit_card_expiration_date.present? && credit_card_expiration_date < Time.zone.today + + errors.add(:credit_card_name, 'inválido(a)') + errors.add(:credit_card_number, 'inválido(a)') + errors.add(:credit_card_expiration_date, 'inválido(a)') + errors.add(:credit_card_security_code, 'inválido(a)') + end +end diff --git a/app/models/pix_setting.rb b/app/models/pix_setting.rb index e36b1fe..7f40ad6 100644 --- a/app/models/pix_setting.rb +++ b/app/models/pix_setting.rb @@ -2,6 +2,8 @@ class PixSetting < ApplicationRecord belongs_to :company belongs_to :payment_method, -> { where(type_of: :pix) }, inverse_of: :pix_settings + enum status: { enabled: 5, disabled: 10 } + validates :pix_key, :bank_code, presence: true validates :bank_code, bank_code: true end diff --git a/config/routes.rb b/config/routes.rb index 7990e2e..da572ba 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -22,4 +22,14 @@ resources :boleto_settings, only: %i[new create] resources :credit_card_settings, only: %i[new create] + + namespace :api do + namespace :v1 do + resources :customer, only: %i[index show create] + resources :pix_settings, only: %i[index show] + resources :boleto_settings, only: %i[index show] + resources :credit_card_settings, only: %i[index show] + resources :customer_payment_method, only: %i[index show create] + end + end end diff --git a/db/migrate/20211124234405_add_token_to_pix_setting.rb b/db/migrate/20211124234405_add_token_to_pix_setting.rb new file mode 100644 index 0000000..91bca0b --- /dev/null +++ b/db/migrate/20211124234405_add_token_to_pix_setting.rb @@ -0,0 +1,5 @@ +class AddTokenToPixSetting < ActiveRecord::Migration[6.1] + def change + add_column :pix_settings, :token, :string + end +end diff --git a/db/migrate/20211124234501_add_token_to_boleto_setting.rb b/db/migrate/20211124234501_add_token_to_boleto_setting.rb new file mode 100644 index 0000000..8a9fe37 --- /dev/null +++ b/db/migrate/20211124234501_add_token_to_boleto_setting.rb @@ -0,0 +1,5 @@ +class AddTokenToBoletoSetting < ActiveRecord::Migration[6.1] + def change + add_column :boleto_settings, :token, :string + end +end diff --git a/db/migrate/20211124234511_add_token_to_credit_card_setting.rb b/db/migrate/20211124234511_add_token_to_credit_card_setting.rb new file mode 100644 index 0000000..326d627 --- /dev/null +++ b/db/migrate/20211124234511_add_token_to_credit_card_setting.rb @@ -0,0 +1,5 @@ +class AddTokenToCreditCardSetting < ActiveRecord::Migration[6.1] + def change + add_column :credit_card_settings, :token, :string + end +end diff --git a/db/migrate/20211125160101_create_customers.rb b/db/migrate/20211125160101_create_customers.rb new file mode 100644 index 0000000..94d3bd2 --- /dev/null +++ b/db/migrate/20211125160101_create_customers.rb @@ -0,0 +1,12 @@ +class CreateCustomers < ActiveRecord::Migration[6.1] + def change + create_table :customers do |t| + t.string :name + t.string :cpf + t.string :token + t.references :company, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/migrate/20211125201854_create_customer_payment_methods.rb b/db/migrate/20211125201854_create_customer_payment_methods.rb new file mode 100644 index 0000000..fbc5c57 --- /dev/null +++ b/db/migrate/20211125201854_create_customer_payment_methods.rb @@ -0,0 +1,16 @@ +class CreateCustomerPaymentMethods < ActiveRecord::Migration[6.1] + def change + create_table :customer_payment_methods do |t| + t.references :payment_method, null: false, foreign_key: true + t.string :credit_card_name + t.string :credit_card_number + t.date :credit_card_expiration_date + t.string :credit_card_security_code + t.references :company, null: false, foreign_key: true + t.references :customer, null: false, foreign_key: true + t.string :token + + t.timestamps + end + end +end diff --git a/db/migrate/20211126165220_add_status_to_pix_setting.rb b/db/migrate/20211126165220_add_status_to_pix_setting.rb new file mode 100644 index 0000000..a6279eb --- /dev/null +++ b/db/migrate/20211126165220_add_status_to_pix_setting.rb @@ -0,0 +1,5 @@ +class AddStatusToPixSetting < ActiveRecord::Migration[6.1] + def change + add_column :pix_settings, :status, :integer, default: 5 + end +end diff --git a/db/migrate/20211127004210_add_status_to_boleto_setting.rb b/db/migrate/20211127004210_add_status_to_boleto_setting.rb new file mode 100644 index 0000000..fa4a48a --- /dev/null +++ b/db/migrate/20211127004210_add_status_to_boleto_setting.rb @@ -0,0 +1,5 @@ +class AddStatusToBoletoSetting < ActiveRecord::Migration[6.1] + def change + add_column :boleto_settings, :status, :integer, default: 5 + end +end diff --git a/db/migrate/20211127004220_add_status_to_credit_card_setting.rb b/db/migrate/20211127004220_add_status_to_credit_card_setting.rb new file mode 100644 index 0000000..f7df1ba --- /dev/null +++ b/db/migrate/20211127004220_add_status_to_credit_card_setting.rb @@ -0,0 +1,5 @@ +class AddStatusToCreditCardSetting < ActiveRecord::Migration[6.1] + def change + add_column :credit_card_settings, :status, :integer, default: 5 + end +end diff --git a/db/schema.rb b/db/schema.rb index 742f049..c2e774c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_11_22_002541) do +ActiveRecord::Schema.define(version: 2021_11_27_004220) do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false @@ -64,6 +64,8 @@ t.integer "payment_method_id", null: false t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false + t.string "token" + t.integer "status", default: 5 t.index ["company_id"], name: "index_boleto_settings_on_company_id" t.index ["payment_method_id"], name: "index_boleto_settings_on_payment_method_id" end @@ -85,10 +87,38 @@ t.integer "payment_method_id", null: false t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false + t.string "token" + t.integer "status", default: 5 t.index ["company_id"], name: "index_credit_card_settings_on_company_id" t.index ["payment_method_id"], name: "index_credit_card_settings_on_payment_method_id" end + create_table "customer_payment_methods", force: :cascade do |t| + t.integer "payment_method_id", null: false + t.string "credit_card_name" + t.string "credit_card_number" + t.date "credit_card_expiration_date" + t.string "credit_card_security_code" + t.integer "company_id", null: false + t.integer "customer_id", null: false + t.string "token" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["company_id"], name: "index_customer_payment_methods_on_company_id" + t.index ["customer_id"], name: "index_customer_payment_methods_on_customer_id" + t.index ["payment_method_id"], name: "index_customer_payment_methods_on_payment_method_id" + end + + create_table "customers", force: :cascade do |t| + t.string "name" + t.string "cpf" + t.string "token" + t.integer "company_id", null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["company_id"], name: "index_customers_on_company_id" + end + create_table "payment_methods", force: :cascade do |t| t.string "name" t.decimal "fee" @@ -106,6 +136,8 @@ t.integer "payment_method_id", null: false t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false + t.string "token" + t.integer "status", default: 5 t.index ["company_id"], name: "index_pix_settings_on_company_id" t.index ["payment_method_id"], name: "index_pix_settings_on_payment_method_id" end @@ -131,6 +163,10 @@ add_foreign_key "boleto_settings", "payment_methods" add_foreign_key "credit_card_settings", "companies" add_foreign_key "credit_card_settings", "payment_methods" + add_foreign_key "customer_payment_methods", "companies" + add_foreign_key "customer_payment_methods", "customers" + add_foreign_key "customer_payment_methods", "payment_methods" + add_foreign_key "customers", "companies" add_foreign_key "pix_settings", "companies" add_foreign_key "pix_settings", "payment_methods" add_foreign_key "users", "companies" diff --git a/spec/factories/customer_payment_methods.rb b/spec/factories/customer_payment_methods.rb new file mode 100644 index 0000000..6dec7c2 --- /dev/null +++ b/spec/factories/customer_payment_methods.rb @@ -0,0 +1,22 @@ +FactoryBot.define do + factory :customer_payment_method do + company { create(:company, status: :accepted) } + customer { create(:customer, company: company) } + + trait :pix do + payment_method { create(:payment_method, :pix) } + end + + trait :boleto do + payment_method { create(:payment_method, :boleto) } + end + + trait :credit_card do + payment_method { create(:payment_method, :credit_card) } + credit_card_name { 'Credit Card 1' } + credit_card_number { '4929513324664053' } + credit_card_expiration_date { 3.months.from_now } + credit_card_security_code { '123' } + end + end +end diff --git a/spec/factories/customerpaymentmethods.rb b/spec/factories/customerpaymentmethods.rb new file mode 100644 index 0000000..dca699d --- /dev/null +++ b/spec/factories/customerpaymentmethods.rb @@ -0,0 +1,13 @@ +FactoryBot.define do + factory :customerpaymentmethod do + payment_method { "MyString" } + payment_method { nil } + credit_card_name { "MyString" } + credit_card_number { "MyString" } + credit_card_expiration_date { "2021-11-25" } + credit_card_security_code { "MyString" } + company { nil } + customer { nil } + customer_payment_token { "MyString" } + end +end diff --git a/spec/factories/customers.rb b/spec/factories/customers.rb new file mode 100644 index 0000000..bfadb5f --- /dev/null +++ b/spec/factories/customers.rb @@ -0,0 +1,21 @@ +def cpf_sequence(sequence_number) + number_string = format('%011d', sequence_number) + "#{number_string.slice(0, 2)}."\ + "#{number_string.slice(1, 3)}."\ + "#{number_string.slice(4, 3)}/"\ + "#{number_string.slice(8, 4)}-"\ + "#{number_string.slice(12, 2)}" +end + +FactoryBot.define do + factory :customer do + name { "Customer da Silva" } + sequence(:cpf) do |n| + cpf_sequence n + end + name { "João" } + cpf { "111.111.111-11" } + token { "TAIGdGfCQR9n46HRcxF8" } + company { nil } + end +end diff --git a/spec/models/customer_payment_method_spec.rb b/spec/models/customer_payment_method_spec.rb new file mode 100644 index 0000000..b45fd21 --- /dev/null +++ b/spec/models/customer_payment_method_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe CustomerPaymentMethod, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 9dd4beb..5592ddc 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -38,6 +38,7 @@ exit 1 end RSpec.configure do |config| + config.include ApiMacro config.include Warden::Test::Helpers config.before(type: :system) do diff --git a/spec/requests/api/boleto_settings_api_spec.rb b/spec/requests/api/boleto_settings_api_spec.rb new file mode 100644 index 0000000..219e030 --- /dev/null +++ b/spec/requests/api/boleto_settings_api_spec.rb @@ -0,0 +1,109 @@ +require 'rails_helper' + +describe 'Boleto setting API' do + context 'GET /api/v1/boleto_settings/:company_token' do + it 'should get all settings from requesting company' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + other_owner = create(:user, :complete_company_owner) + other_company = other_owner.company + other_company.accepted! + + boleto_setting = create_list(:boleto_setting, 3, company: company) + boleto_setting[2].payment_method.disabled! + create_list(:boleto_setting, 2, company: other_company) + + get '/api/v1/boleto_settings', headers: { companyToken: company.token } + + expect(response).to have_http_status(200) + expect(parsed_body.first[:boleto_setting][:agency_number]).to eq(boleto_setting.first.agency_number) + expect(parsed_body.first[:boleto_setting][:account_number]).to eq(boleto_setting.first.account_number) + expect(parsed_body.first[:boleto_setting][:token]).to eq(boleto_setting.first.token) + expect(parsed_body.first[:boleto_setting][:bank_code]).to eq(boleto_setting.first.bank_code) + expect(parsed_body.first[:boleto_setting][:payment_method][:name]).to eq(boleto_setting.first.payment_method.name) + expect(parsed_body.second[:boleto_setting][:agency_number]).to eq(boleto_setting.second.agency_number) + expect(parsed_body.second[:boleto_setting][:token]).to eq(boleto_setting.second.token) + expect(parsed_body.count).to eq(2) + end + + it 'returns no settings' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + owner2 = create(:user, :complete_company_owner) + company2 = owner2.company + company2.accepted! + + create_list(:boleto_setting, 2, company: company2) + + get '/api/v1/boleto_settings', headers: { companyToken: company.token } + + expect(response).to have_http_status(200) + expect(parsed_body).to be_empty + end + end + + context 'GET /api/v1/boleto_settings/:token' do + it 'should get corresponding setting from requesting company' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + boleto_settings = create_list(:boleto_setting, 3, company: company) + boleto_settings.first.payment_method.disabled! + + get "/api/v1/boleto_settings/#{boleto_settings.first.token}", headers: { companyToken: company.token } + + expect(response).to have_http_status(200) + expect(parsed_body[:boleto_setting][:agency_number]).to eq(boleto_settings.first.agency_number) + expect(parsed_body[:boleto_setting][:account_number]).to eq(boleto_settings.first.account_number) + expect(parsed_body[:boleto_setting][:token]).to eq(boleto_settings.first.token) + expect(parsed_body[:boleto_setting][:bank_code]).to eq(boleto_settings.first.bank_code) + expect(parsed_body[:boleto_setting][:payment_method][:status]).to eq(boleto_settings.first.payment_method.status) + expect(parsed_body[:boleto_setting][:payment_method][:name]).to eq(boleto_settings.first.payment_method.name) + end + + it 'should return 404 if setting does not exist' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + get '/api/v1/boleto_settings/999', headers: { companyToken: company.token } + + expect(response).to have_http_status(404) + end + + it 'should return 401 if setting is from another company' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + other_owner = create(:user, :complete_company_owner) + other_company = other_owner.company + other_company.accepted! + + other_boleto_setting = create(:boleto_setting, company: other_company) + + get "/api/v1/boleto_settings/#{other_boleto_setting.token}", headers: { companyToken: company.token } + + expect(response).to have_http_status(401) + end + + it 'should return 500 if database is not available' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + boleto_setting = create(:boleto_setting, company: company) + + allow(BoletoSetting).to receive(:where).and_raise(ActiveRecord::ActiveRecordError) + + get "/api/v1/boleto_settings/#{boleto_setting.token}", headers: { companyToken: company.token } + + expect(response).to have_http_status(500) + end + end +end diff --git a/spec/requests/api/credit_card_settings_api_spec.rb b/spec/requests/api/credit_card_settings_api_spec.rb new file mode 100644 index 0000000..5bf5358 --- /dev/null +++ b/spec/requests/api/credit_card_settings_api_spec.rb @@ -0,0 +1,107 @@ +require 'rails_helper' + +describe 'Credit Card setting API' do + context 'GET /api/v1/credit_card_settings' do + it 'should get all settings from requesting company' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + other_owner = create(:user, :complete_company_owner) + other_company = other_owner.company + other_company.accepted! + + credit_card_settings = create_list(:credit_card_setting, 3, company: company) + credit_card_settings[2].payment_method.disabled! + first_cc = credit_card_settings[0] + second_cc = credit_card_settings[1] + create_list(:credit_card_setting, 2, company: other_company) + + get '/api/v1/credit_card_settings', headers: { companyToken: company.token } + + expect(response).to have_http_status(200) + expect(parsed_body.first[:credit_card_setting][:company_code]).to eq(first_cc.company_code) + expect(parsed_body.first[:credit_card_setting][:token]).to eq(first_cc.token) + expect(parsed_body.first[:credit_card_setting][:payment_method][:name]).to eq(first_cc.payment_method.name) + expect(parsed_body.second[:credit_card_setting][:company_code]).to eq(second_cc.company_code) + expect(parsed_body.second[:credit_card_setting][:token]).to eq(second_cc.token) + expect(parsed_body.count).to eq(2) + end + + it 'returns no settings' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + owner2 = create(:user, :complete_company_owner) + company2 = owner2.company + company2.accepted! + + create_list(:credit_card_setting, 2, company: company2) + + get '/api/v1/credit_card_settings', headers: { companyToken: company.token } + + expect(response).to have_http_status(200) + expect(parsed_body).to be_empty + end + end + + context 'GET /api/v1/credit_card_settings/:token' do + it 'should get corresponding setting from requesting company' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + cc_settings = create_list(:credit_card_setting, 3, company: company) + cc_settings.first.payment_method.disabled! + + get "/api/v1/credit_card_settings/#{cc_settings.first.token}", headers: { companyToken: company.token } + + expect(response).to have_http_status(200) + expect(parsed_body[:credit_card_setting][:company_code]).to eq(cc_settings.first.company_code) + expect(parsed_body[:credit_card_setting][:token]).to eq(cc_settings.first.token) + expect(parsed_body[:credit_card_setting][:payment_method][:status]).to eq(cc_settings.first.payment_method.status) + expect(parsed_body[:credit_card_setting][:payment_method][:name]).to eq(cc_settings.first.payment_method.name) + end + + it 'should return 404 if setting does not exist' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + get '/api/v1/credit_card_settings/999', headers: { companyToken: company.token } + + expect(response).to have_http_status(404) + end + + it 'should return 401 if setting is from another company' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + other_owner = create(:user, :complete_company_owner) + other_company = other_owner.company + other_company.accepted! + + other_credit_card_setting = create(:credit_card_setting, company: other_company) + + get "/api/v1/credit_card_settings/#{other_credit_card_setting.token}", headers: { companyToken: company.token } + + expect(response).to have_http_status(401) + end + + it 'should return 500 if database is not available' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + credit_card_setting = create(:credit_card_setting, company: company) + + allow(CreditCardSetting).to receive(:where).and_raise(ActiveRecord::ActiveRecordError) + + get "/api/v1/credit_card_settings/#{credit_card_setting.id}", headers: { companyToken: company.token } + + expect(response).to have_http_status(500) + end + end +end diff --git a/spec/requests/api/customer_api_spec.rb b/spec/requests/api/customer_api_spec.rb new file mode 100644 index 0000000..f98cc64 --- /dev/null +++ b/spec/requests/api/customer_api_spec.rb @@ -0,0 +1,242 @@ +require 'rails_helper' + +describe 'Customer API' do + context 'GET /api/v1/customer' do + it 'should get all customers' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + + customer1 = create(:customer, company: owner.company) + customer2 = create(:customer, company: owner.company) + + get '/api/v1/customer', headers: { companyToken: owner.company.token } + + expect(response).to have_http_status(200) + expect(response.content_type).to include('application/json') + expect(parsed_body.first[:customer][:name]).to eq(customer1.name) + expect(parsed_body.first[:customer][:cpf]).to eq(customer1.cpf) + expect(parsed_body.first[:customer][:token]).to eq(customer1.token) + expect(parsed_body.first[:customer][:company][:legal_name]).to eq(owner.company.legal_name) + expect(parsed_body.second[:customer][:name]).to eq(customer2.name) + expect(parsed_body.second[:customer][:cpf]).to eq(customer2.cpf) + expect(parsed_body.second[:customer][:token]).to eq(customer2.token) + expect(parsed_body.second[:customer][:company][:legal_name]).to eq(owner.company.legal_name) + end + end + + context 'GET /api/v1/customer/:token' do + it 'should get all customers' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + + customer1 = create(:customer, company: owner.company) + customer2 = create(:customer, company: owner.company) + + get '/api/v1/customer', headers: { companyToken: owner.company.token } + + expect(response).to have_http_status(200) + expect(response.content_type).to include('application/json') + expect(parsed_body.first[:customer][:name]).to eq(customer1.name) + expect(parsed_body.first[:customer][:cpf]).to eq(customer1.cpf) + expect(parsed_body.first[:customer][:token]).to eq(customer1.token) + expect(parsed_body.first[:customer][:company][:legal_name]).to eq(owner.company.legal_name) + expect(parsed_body.second[:customer][:name]).to eq(customer2.name) + expect(parsed_body.second[:customer][:cpf]).to eq(customer2.cpf) + expect(parsed_body.second[:customer][:token]).to eq(customer2.token) + expect(parsed_body.second[:customer][:company][:legal_name]).to eq(owner.company.legal_name) + end + it 'should return 500 if database is not available' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + create(:customer, company: company) + + allow(Customer).to receive(:all).and_raise(ActiveRecord::ActiveRecordError) + + get '/api/v1/customer', headers: { companyToken: company.token } + + expect(response).to have_http_status(500) + end + end + + context 'GET /api/v1/customer/:token' do + it 'should get customer 1' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + + customer1 = create(:customer, company: owner.company) + customer2 = create(:customer, company: owner.company) + + get "/api/v1/customer/#{customer1.token}", headers: { companyToken: owner.company.token } + + expect(response).to have_http_status(200) + expect(response.content_type).to include('application/json') + expect(parsed_body[:customer][:name]).to eq(customer1.name) + expect(parsed_body[:customer][:cpf]).to eq(customer1.cpf) + expect(parsed_body[:customer][:token]).to eq(customer1.token) + expect(parsed_body[:customer][:company][:legal_name]).to eq(owner.company.legal_name) + expect(parsed_body[:customer][:token]).to_not eq(customer2.token) + end + + it 'should return 404 if setting does not exist' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + get '/api/v1/customer/999', headers: { companyToken: company.token } + + expect(response).to have_http_status(404) + end + + it 'should return 401 if setting is from another company' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + other_owner = create(:user, :complete_company_owner) + other_company = other_owner.company + other_company.accepted! + + create(:customer, company: company) + customer2 = create(:customer, company: other_company) + + get "/api/v1/customer/#{customer2.token}", headers: { companyToken: company.token } + + expect(response).to have_http_status(401) + end + + it 'should return 500 if database is not available' do + owner = create(:user, :complete_company_owner) + company = owner.company + company.accepted! + + customer1 = create(:customer, company: company) + + allow(Customer).to receive(:find_by).and_raise(ActiveRecord::ActiveRecordError) + + get "/api/v1/customer/#{customer1.token}", headers: { companyToken: company.token } + + expect(response).to have_http_status(500) + end + end + + context 'POST /api/v1/customer' do + it 'should save a new customer' do + owner = create(:user, :complete_company_owner) + + owner.company.accepted! + customer_params = { customer: { name: 'Caio Silva', + cpf: '41492765872' } } + + allow(SecureRandom).to receive(:alphanumeric).with(20).and_return('LI5YuUJrZuJSB6uPH2jm') + + post '/api/v1/customer', params: customer_params, headers: { companyToken: owner.company.token } + + expect(response).to have_http_status(201) + expect(response.content_type).to include('application/json') + expect(parsed_body[:customer][:name]).to eq('Caio Silva') + expect(parsed_body[:customer][:cpf]).to eq('41492765872') + expect(parsed_body[:customer][:token]).to eq('LI5YuUJrZuJSB6uPH2jm') + end + + it 'should return error about name blank' do + owner = create(:user, :complete_company_owner) + + owner.company.accepted! + customer_params = { customer: { name: '', + cpf: '41492765872' } } + + post '/api/v1/customer', params: customer_params, headers: { companyToken: owner.company.token } + + expect(response).to have_http_status(422) + expect(response.content_type).to include('application/json') + expect(parsed_body[:message]).to eq('Requisição inválida') + expect(parsed_body[:errors][:name]).to include('não pode ficar em branco') + expect(parsed_body[:request]).to eq(customer_params) + end + + context 'POST /api/v1/customer' do + it 'should save a new customer' do + owner = create(:user, :complete_company_owner) + + owner.company.accepted! + customer_params = { customer: { name: 'Caio Silva', + cpf: '41492765872'} } + + allow(SecureRandom).to receive(:alphanumeric).with(20).and_return('LI5YuUJrZuJSB6uPH2jm') + + post '/api/v1/customer', params: customer_params, headers: { companyToken: owner.company.token } + + expect(response).to have_http_status(201) + expect(response.content_type).to include('application/json') + expect(parsed_body[:customer][:name]).to eq('Caio Silva') + expect(parsed_body[:customer][:cpf]).to eq('41492765872') + expect(parsed_body[:customer][:token]).to eq('LI5YuUJrZuJSB6uPH2jm') + end + + it 'should return error about name' do + owner = create(:user, :complete_company_owner) + + owner.company.accepted! + customer_params = { customer: { name: '', + cpf: '41492765872'} } + post '/api/v1/customer', params: customer_params, headers: { companyToken: owner.company.token } + + expect(response).to have_http_status(422) + expect(response.content_type).to include('application/json') + expect(parsed_body[:message]).to eq('Requisição inválida') + expect(parsed_body[:errors][:cpf]).to include('deve ser composto apenas por números') + expect(parsed_body[:request]).to eq(customer_params) + end + + it 'should return error about cpf format with "-" ' do + owner = create(:user, :complete_company_owner) + + owner.company.accepted! + customer_params = { customer: { name: 'Caio Silva', + cpf: '411467289-56' } } + + post '/api/v1/customer', params: customer_params, headers: { companyToken: owner.company.token } + + expect(response).to have_http_status(422) + expect(response.content_type).to include('application/json') + expect(parsed_body[:message]).to eq('Requisição inválida') + expect(parsed_body[:errors][:name]).to include('não pode ficar em branco') + expect(parsed_body[:request]).to eq(customer_params) + end + + it 'should return error about cpf' do + owner = create(:user, :complete_company_owner) + + owner.company.accepted! + customer_params = { customer: { name: 'Caio Silva', + cpf: ''} } + + post '/api/v1/customer', params: customer_params, headers: { companyToken: owner.company.token } + + expect(response).to have_http_status(422) + expect(response.content_type).to include('application/json') + expect(parsed_body[:message]).to eq('Requisição inválida') + expect(parsed_body[:errors][:cpf]).to include('não pode ficar em branco') + expect(parsed_body[:request]).to eq(customer_params) + end + + it 'should return error about both' do + owner = create(:user, :complete_company_owner) + + owner.company.accepted! + customer_params = { customer: { name: '', + cpf: ''} } + + post '/api/v1/customer', params: customer_params, headers: { companyToken: owner.company.token } + + expect(response).to have_http_status(422) + expect(response.content_type) .to include('application/json') + expect(parsed_body[:message]).to eq('Requisição inválida') + expect(parsed_body[:errors][:name]).to include('não pode ficar em branco') + expect(parsed_body[:errors][:cpf]).to include('não pode ficar em branco') + expect(parsed_body[:request]).to eq(customer_params) + end + end + end diff --git a/spec/requests/api/customer_choose_payment_method_spec.rb b/spec/requests/api/customer_choose_payment_method_spec.rb new file mode 100644 index 0000000..86fbda0 --- /dev/null +++ b/spec/requests/api/customer_choose_payment_method_spec.rb @@ -0,0 +1,442 @@ +require 'rails_helper' + +describe 'CustomerPaymentMethod API' do + context 'POST /api/v1/customer_payment_method' do + context 'successfully' do + it 'with pix' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + customer = create(:customer, company: owner.company) + pix_method = create(:payment_method, :pix) + create(:pix_setting, company: owner.company, payment_method: pix_method) + company_payment_setting, = owner.company.payment_settings + + allow(SecureRandom).to receive(:alphanumeric).with(20).and_return('hPxFizxVM5p5mNpFdOsf') + + customer_payment_method_params = { + customer_payment_method: { + customer_token: customer.token, + payment_method_token: company_payment_setting.token + } + } + post '/api/v1/customer_payment_method', + params: customer_payment_method_params, + headers: { 'companyToken' => owner.company.token } + + expect(response).to have_http_status(201) + expect(parsed_body[:customer_payment_method_token]).to eq('hPxFizxVM5p5mNpFdOsf') + expect(CustomerPaymentMethod.count).to eq(1) + end + + it 'with boleto' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + customer = create(:customer, company: owner.company) + boleto_method = create(:payment_method, :boleto) + create(:boleto_setting, company: owner.company, payment_method: boleto_method) + company_payment_setting, = owner.company.payment_settings + + allow(SecureRandom).to receive(:alphanumeric).with(20).and_return('hPxFizxVM5p5mNpFdOsf') + + customer_payment_method_params = { + customer_payment_method: { + customer_token: customer.token, + payment_method_token: company_payment_setting.token + } + } + post '/api/v1/customer_payment_method', + params: customer_payment_method_params, + headers: { 'companyToken' => owner.company.token } + + expect(response).to have_http_status(201) + expect(parsed_body[:customer_payment_method_token]).to eq('hPxFizxVM5p5mNpFdOsf') + expect(CustomerPaymentMethod.count).to eq(1) + end + + it 'with credit card' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + customer = create(:customer, company: owner.company) + credit_card_method = create(:payment_method, :credit_card) + create(:credit_card_setting, company: owner.company, payment_method: credit_card_method) + company_payment_setting, = owner.company.payment_settings + + allow(SecureRandom).to receive(:alphanumeric).with(20).and_return('hPxFizxVM5p5mNpFdOsf') + + customer_payment_method_params = { + customer_payment_method: { + customer_token: customer.token, + payment_method_token: company_payment_setting.token, + credit_card_name: 'Credit Card 1', + credit_card_number: '4929513324664053', + credit_card_expiration_date: 3.months.from_now, + credit_card_security_code: '123' + } + } + post '/api/v1/customer_payment_method', + params: customer_payment_method_params, + headers: { 'companyToken' => owner.company.token } + + customer_payment_method = parsed_body[:customer_payment_method] + expect(response).to have_http_status(201) + expect(CustomerPaymentMethod.count).to eq(1) + expect(customer_payment_method[:token]).to eq('hPxFizxVM5p5mNpFdOsf') + expect(customer_payment_method[:payment_method][:name]).to eq(credit_card_method.name) + expect(customer_payment_method[:payment_method][:type_of]).to eq(credit_card_method.type_of) + expect(customer_payment_method[:customer][:token]).to eq(customer.token) + expect(customer_payment_method[:company][:legal_name]).to eq(owner.company.legal_name) + end + end + + context '400 error' do + it 'should inform company token on headers' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + customer = create(:customer, company: owner.company) + pix_method = create(:payment_method, :pix) + create(:pix_setting, company: owner.company, payment_method: pix_method) + company_payment_setting, = owner.company.payment_settings + + customer_payment_method_params = { + customer_payment_method: { + customer_token: customer.token, + payment_method_token: company_payment_setting.token + } + } + post '/api/v1/customer_payment_method', params: customer_payment_method_params + + expect(response).to have_http_status(401) + expect(parsed_body[:message]).to eq('Há algo errado com sua autenticação.') + expect(CustomerPaymentMethod.count).to eq(0) + end + + it 'should inform customer token' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + pix_method = create(:payment_method, :pix) + create(:pix_setting, company: owner.company, payment_method: pix_method) + company_payment_setting, = owner.company.payment_settings + + customer_payment_method_params = { + customer_payment_method: { + customer_token: '', + payment_method_token: company_payment_setting.token + } + } + post '/api/v1/customer_payment_method', + params: customer_payment_method_params, + headers: { 'companyToken' => owner.company.token } + + customer_payment_method = parsed_body[:request][:customer_payment_method] + expect(response).to have_http_status(422) + expect(CustomerPaymentMethod.count).to eq(0) + expect(parsed_body[:message]).to eq('Requisição inválida') + expect(parsed_body[:errors][:customer].first).to eq('é obrigatório(a)') + expect(customer_payment_method[:payment_method][:name]).to eq(pix_method.name) + expect(customer_payment_method[:payment_method][:type_of]).to eq(pix_method.type_of) + expect(customer_payment_method[:company][:legal_name]).to eq(owner.company.legal_name) + expect(customer_payment_method[:customer]).to be_nil + end + + it 'should inform payment method token' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + customer = create(:customer, company: owner.company) + pix_method = create(:payment_method, :pix) + create(:pix_setting, company: owner.company, payment_method: pix_method) + + customer_payment_method_params = { + customer_payment_method: { + customer_token: customer.token, + payment_method_token: '' + } + } + post '/api/v1/customer_payment_method', + params: customer_payment_method_params, + headers: { 'companyToken' => owner.company.token } + + customer_payment_method = parsed_body[:request][:customer_payment_method] + expect(response).to have_http_status(422) + expect(CustomerPaymentMethod.count).to eq(0) + expect(parsed_body[:message]).to eq('Requisição inválida') + expect(parsed_body[:errors][:payment_method].first).to eq('é obrigatório(a)') + expect(customer_payment_method[:customer][:token]).to eq(customer.token) + expect(customer_payment_method[:company][:legal_name]).to eq(owner.company.legal_name) + expect(customer_payment_method[:payment_method]).to be_nil + end + + it 'should inform enabled payment method token' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + customer = create(:customer, company: owner.company) + pix_method = create(:payment_method, :pix) + create(:pix_setting, company: owner.company, payment_method: pix_method) + company_payment_setting, = owner.company.payment_settings + company_payment_setting.disabled! + + customer_payment_method_params = { + customer_payment_method: { + customer_token: customer.token, + payment_method_token: company_payment_setting.token + } + } + post '/api/v1/customer_payment_method', + params: customer_payment_method_params, + headers: { 'companyToken' => owner.company.token } + + customer_payment_method = parsed_body[:request][:customer_payment_method] + expect(response).to have_http_status(422) + expect(CustomerPaymentMethod.count).to eq(0) + expect(parsed_body[:message]).to eq('Requisição inválida') + expect(parsed_body[:errors][:payment_method].first).to eq('é obrigatório(a)') + expect(customer_payment_method[:customer][:token]).to eq(customer.token) + expect(customer_payment_method[:company][:legal_name]).to eq(owner.company.legal_name) + expect(customer_payment_method[:payment_method]).to be_nil + end + + it 'should inform credit card name' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + customer = create(:customer, company: owner.company) + credit_card_method = create(:payment_method, :credit_card) + create(:credit_card_setting, company: owner.company, payment_method: credit_card_method) + company_payment_setting, = owner.company.payment_settings + + customer_payment_method_params = { + customer_payment_method: { + customer_token: customer.token, + payment_method_token: company_payment_setting.token, + credit_card_name: '', + credit_card_number: '4929513324664053', + credit_card_expiration_date: 3.months.from_now, + credit_card_security_code: '123' + } + } + post '/api/v1/customer_payment_method', + params: customer_payment_method_params, + headers: { 'companyToken' => owner.company.token } + + customer_payment_method = parsed_body[:request][:customer_payment_method] + expect(response).to have_http_status(422) + expect(CustomerPaymentMethod.count).to eq(0) + expect(parsed_body[:message]).to eq('Requisição inválida') + expect(parsed_body[:errors][:credit_card_name].first).to eq('não pode ficar em branco') + expect(customer_payment_method[:customer][:token]).to eq(customer.token) + expect(customer_payment_method[:company][:legal_name]).to eq(owner.company.legal_name) + expect(customer_payment_method[:payment_method][:name]).to eq(credit_card_method.name) + expect(customer_payment_method[:payment_method][:type_of]).to eq(credit_card_method.type_of) + end + + it 'should inform credit card number' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + customer = create(:customer, company: owner.company) + credit_card_method = create(:payment_method, :credit_card) + create(:credit_card_setting, company: owner.company, payment_method: credit_card_method) + company_payment_setting, = owner.company.payment_settings + + customer_payment_method_params = { + customer_payment_method: { + customer_token: customer.token, + payment_method_token: company_payment_setting.token, + credit_card_name: 'Credit Card 1', + credit_card_number: '', + credit_card_expiration_date: 3.months.from_now, + credit_card_security_code: '123' + } + } + post '/api/v1/customer_payment_method', + params: customer_payment_method_params, + headers: { 'companyToken' => owner.company.token } + + customer_payment_method = parsed_body[:request][:customer_payment_method] + expect(response).to have_http_status(422) + expect(CustomerPaymentMethod.count).to eq(0) + expect(parsed_body[:message]).to eq('Requisição inválida') + expect(parsed_body[:errors][:credit_card_number].first).to eq('não pode ficar em branco') + expect(customer_payment_method[:customer][:token]).to eq(customer.token) + expect(customer_payment_method[:company][:legal_name]).to eq(owner.company.legal_name) + expect(customer_payment_method[:payment_method][:name]).to eq(credit_card_method.name) + expect(customer_payment_method[:payment_method][:type_of]).to eq(credit_card_method.type_of) + end + + it 'should inform credit card expiration date' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + customer = create(:customer, company: owner.company) + credit_card_method = create(:payment_method, :credit_card) + create(:credit_card_setting, company: owner.company, payment_method: credit_card_method) + company_payment_setting, = owner.company.payment_settings + + customer_payment_method_params = { + customer_payment_method: { + customer_token: customer.token, + payment_method_token: company_payment_setting.token, + credit_card_name: 'Credit Card 1', + credit_card_number: '4929513324664053', + credit_card_expiration_date: '', + credit_card_security_code: '123' + } + } + post '/api/v1/customer_payment_method', + params: customer_payment_method_params, + headers: { 'companyToken' => owner.company.token } + + customer_payment_method = parsed_body[:request][:customer_payment_method] + expect(response).to have_http_status(422) + expect(CustomerPaymentMethod.count).to eq(0) + expect(parsed_body[:message]).to eq('Requisição inválida') + expect(parsed_body[:errors][:credit_card_expiration_date].first).to eq('não pode ficar em branco') + expect(customer_payment_method[:customer][:token]).to eq(customer.token) + expect(customer_payment_method[:company][:legal_name]).to eq(owner.company.legal_name) + expect(customer_payment_method[:payment_method][:name]).to eq(credit_card_method.name) + expect(customer_payment_method[:payment_method][:type_of]).to eq(credit_card_method.type_of) + end + + it 'should inform credit card security code' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + customer = create(:customer, company: owner.company) + credit_card_method = create(:payment_method, :credit_card) + create(:credit_card_setting, company: owner.company, payment_method: credit_card_method) + company_payment_setting, = owner.company.payment_settings + + customer_payment_method_params = { + customer_payment_method: { + customer_token: customer.token, + payment_method_token: company_payment_setting.token, + credit_card_name: 'Credit Card 1', + credit_card_number: '4929513324664053', + credit_card_expiration_date: 3.months.from_now, + credit_card_security_code: '' + } + } + post '/api/v1/customer_payment_method', + params: customer_payment_method_params, + headers: { 'companyToken' => owner.company.token } + + customer_payment_method = parsed_body[:request][:customer_payment_method] + expect(response).to have_http_status(422) + expect(CustomerPaymentMethod.count).to eq(0) + expect(parsed_body[:message]).to eq('Requisição inválida') + expect(parsed_body[:errors][:credit_card_security_code].first).to eq('não pode ficar em branco') + expect(customer_payment_method[:customer][:token]).to eq(customer.token) + expect(customer_payment_method[:company][:legal_name]).to eq(owner.company.legal_name) + expect(customer_payment_method[:payment_method][:name]).to eq(credit_card_method.name) + expect(customer_payment_method[:payment_method][:type_of]).to eq(credit_card_method.type_of) + end + + it 'should inform credit card invalid when expired expiration date' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + customer = create(:customer, company: owner.company) + credit_card_method = create(:payment_method, :credit_card) + create(:credit_card_setting, company: owner.company, payment_method: credit_card_method) + company_payment_setting, = owner.company.payment_settings + + customer_payment_method_params = { + customer_payment_method: { + customer_token: customer.token, + payment_method_token: company_payment_setting.token, + credit_card_name: 'Credit Card 1', + credit_card_number: '4929513324664053', + credit_card_expiration_date: 3.days.ago, + credit_card_security_code: '123' + } + } + + post '/api/v1/customer_payment_method', + params: customer_payment_method_params, + headers: { 'companyToken' => owner.company.token } + + customer_payment_method = parsed_body[:request][:customer_payment_method] + expect(response).to have_http_status(422) + expect(CustomerPaymentMethod.count).to eq(0) + expect(parsed_body[:message]).to eq('Requisição inválida') + expect(parsed_body[:errors][:credit_card_name].first).to eq('inválido(a)') + expect(parsed_body[:errors][:credit_card_number].first).to eq('inválido(a)') + expect(parsed_body[:errors][:credit_card_expiration_date].first).to eq('inválido(a)') + expect(parsed_body[:errors][:credit_card_security_code].first).to eq('inválido(a)') + expect(customer_payment_method[:customer][:token]).to eq(customer.token) + expect(customer_payment_method[:company][:legal_name]).to eq(owner.company.legal_name) + expect(customer_payment_method[:payment_method][:name]).to eq(credit_card_method.name) + expect(customer_payment_method[:payment_method][:type_of]).to eq(credit_card_method.type_of) + end + end + end + + context 'GET /api/v1/customer_payment_method' do + it 'successfully' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + customer_payment_methods = create_list( + :customer_payment_method, 3, :pix, company: owner.company + ) + + get '/api/v1/customer_payment_method', + headers: { 'companyToken' => owner.company.token } + + expect(response).to have_http_status(200) + expect(parsed_body.count).to eq(3) + expect(parsed_body.first[:customer_payment_method][:token]).to eq(customer_payment_methods.first.token) + expect(parsed_body.first[:customer_payment_method][:customer][:token]).to eq( + customer_payment_methods.first.customer.token + ) + expect(parsed_body.second[:customer_payment_method][:token]).to eq(customer_payment_methods.second.token) + expect(parsed_body.second[:customer_payment_method][:customer][:token]).to eq( + customer_payment_methods.second.customer.token + ) + expect(parsed_body.third[:customer_payment_method][:token]).to eq(customer_payment_methods.third.token) + expect(parsed_body.third[:customer_payment_method][:customer][:token]).to eq( + customer_payment_methods.third.customer.token + ) + end + end + + context 'GET /api/v1/customer_payment_method/:id' do + it 'successfully' do + customer_payment_method = create(:customer_payment_method, :boleto) + + get "/api/v1/customer_payment_method/#{customer_payment_method.token}", + headers: { 'companyToken' => customer_payment_method.company.token } + + expect(response).to have_http_status(200) + expect(parsed_body[:customer_payment_method][:token]).to eq(customer_payment_method.token) + expect(parsed_body[:customer_payment_method][:payment_method][:name]).to eq( + customer_payment_method.payment_method.name + ) + expect(parsed_body[:customer_payment_method][:payment_method][:type_of]).to eq( + customer_payment_method.payment_method.type_of + ) + expect(parsed_body[:customer_payment_method][:customer][:token]).to eq( + customer_payment_method.customer.token + ) + expect(parsed_body[:customer_payment_method][:company][:legal_name]).to eq( + customer_payment_method.company.legal_name + ) + end + + it '404 not found error' do + owner = create(:user, :complete_company_owner) + owner.company.accepted! + + get '/api/v1/customer_payment_method/not_a_token', + headers: { 'companyToken' => owner.company.token } + + expect(response).to have_http_status(404) + expect(parsed_body[:message]).to eq('Objeto não encontrado') + end + + it '404 not found error when customer payment method from another company' do + customer_payment_method = create(:customer_payment_method, :boleto) + another_customer_payment_method = create(:customer_payment_method, :credit_card) + + get "/api/v1/customer_payment_method/#{customer_payment_method.token}", + headers: { 'companyToken' => another_customer_payment_method.company.token } + + expect(response).to have_http_status(404) + expect(parsed_body[:message]).to eq('Objeto não encontrado') + expect(CustomerPaymentMethod.count).to eq(2) + end + end +end diff --git a/spec/support/api_macro.rb b/spec/support/api_macro.rb new file mode 100644 index 0000000..25b78f3 --- /dev/null +++ b/spec/support/api_macro.rb @@ -0,0 +1,5 @@ +module ApiMacro + def parsed_body + @parsed_body ||= JSON.parse(response.body, symbolize_names: true) + end +end