cieloz 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +170 -0
  5. data/Rakefile +16 -0
  6. data/cieloz.gemspec +34 -0
  7. data/config/locales/en.yml +11 -0
  8. data/config/locales/pt-BR.yml +11 -0
  9. data/lib/cieloz/bandeiras.rb +22 -0
  10. data/lib/cieloz/builder.rb +71 -0
  11. data/lib/cieloz/configuracao.rb +64 -0
  12. data/lib/cieloz/helpers.rb +35 -0
  13. data/lib/cieloz/homologacao.rb +16 -0
  14. data/lib/cieloz/requisicao/dados_ec.rb +14 -0
  15. data/lib/cieloz/requisicao/resposta/erro.rb +11 -0
  16. data/lib/cieloz/requisicao/resposta/transacao.rb +11 -0
  17. data/lib/cieloz/requisicao/resposta.rb +35 -0
  18. data/lib/cieloz/requisicao.rb +69 -0
  19. data/lib/cieloz/requisicao_tid.rb +23 -0
  20. data/lib/cieloz/requisicao_transacao/dados_pedido.rb +32 -0
  21. data/lib/cieloz/requisicao_transacao/dados_portador.rb +79 -0
  22. data/lib/cieloz/requisicao_transacao/forma_pagamento.rb +94 -0
  23. data/lib/cieloz/requisicao_transacao.rb +126 -0
  24. data/lib/cieloz/version.rb +3 -0
  25. data/lib/cieloz.rb +24 -0
  26. data/readme/cielo_developer_guide_2.0.3.pdf +0 -0
  27. data/readme/cielo_guia_seguranca_ecommerce.pdf +0 -0
  28. data/readme/cielo_payment_states.png +0 -0
  29. data/readme/contrato_de_afiliacao_ao_sistema_cielo.pdf +0 -0
  30. data/readme/credentials.png +0 -0
  31. data/readme/dicas_preventivas_para_vendas_mais_seguras.pdf +0 -0
  32. data/readme/email_cielo.pdf +0 -0
  33. data/readme/lista_de_documentos_necessarios_para_afiliacao_de_vendas_pela_internet_pessoa_juridica.pdf +0 -0
  34. data/readme/mastercard_securecodedemo.swf +0 -0
  35. data/readme/supported_products.png +0 -0
  36. data/readme/termo_de_adesao_de_risco.pdf +0 -0
  37. data/readme/verified_by_visa.png +0 -0
  38. data/test/integration/integration_test.rb +104 -0
  39. data/test/minitest_helper.rb +65 -0
  40. data/test/unit/bandeiras_operacoes_test.rb +25 -0
  41. data/test/unit/builder_test.rb +212 -0
  42. data/test/unit/configuracao_test.rb +85 -0
  43. data/test/unit/requisicao_autorizacao_tid_test.rb +19 -0
  44. data/test/unit/requisicao_cancelamento_test.rb +25 -0
  45. data/test/unit/requisicao_captura_test.rb +25 -0
  46. data/test/unit/requisicao_consulta_test.rb +19 -0
  47. data/test/unit/requisicao_test.rb +84 -0
  48. data/test/unit/requisicao_transacao_test.rb +82 -0
  49. data/test/unit/validations_test.rb +358 -0
  50. data/test/unit/xml/dados-ec.xml +4 -0
  51. data/test/unit/xml/dados-pagamento.xml +5 -0
  52. data/test/unit/xml/dados-pedido.xml +9 -0
  53. data/test/unit/xml/dados-portador.xml +7 -0
  54. data/test/unit/xml/dados-simple_attrs.xml +4 -0
  55. data/test/unit/xml/erro.xml +5 -0
  56. data/test/unit/xml/transacao.xml +19 -0
  57. metadata +280 -0
@@ -0,0 +1,32 @@
1
+ class Cieloz::RequisicaoTransacao
2
+ class DadosPedido
3
+ include Cieloz::Helpers
4
+
5
+ IDIOMAS = [ "PT", "EN", "ES" ] # portugues, ingles, espanhol
6
+
7
+ attr_accessor :numero, :valor, :moeda, :data_hora, :descricao, :idioma, :soft_descriptor
8
+
9
+ validates :numero, :valor, :moeda, :data_hora, presence: true
10
+
11
+ validates :numero, length: { in: 1..20 }
12
+
13
+ validates :valor, length: { in: 1..12 }
14
+ validates :valor, numericality: { only_integer: true }
15
+
16
+ validates :descricao, length: { in: 0..1024 }
17
+ validates :idioma, inclusion: { in: IDIOMAS }
18
+ validates :soft_descriptor, length: { in: 0..13 }
19
+
20
+ def attributes
21
+ {
22
+ numero: @numero,
23
+ valor: @valor,
24
+ moeda: @moeda,
25
+ data_hora: @data_hora.strftime("%Y-%m-%dT%H:%M:%S"),
26
+ descricao: @descricao,
27
+ idioma: @idioma,
28
+ soft_descriptor: @soft_descriptor
29
+ }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,79 @@
1
+ class Cieloz::RequisicaoTransacao
2
+ class DadosPortador
3
+ INDICADOR_NAO_INFORMADO = 0
4
+ INDICADOR_INFORMADO = 1
5
+ INDICADOR_ILEGIVEL = 2
6
+ INDICADOR_INEXISTENTE = 9
7
+
8
+ include Cieloz::Helpers
9
+
10
+ attr_accessor :numero, :nome_portador, :validade
11
+ attr_reader :indicador, :codigo_seguranca
12
+
13
+ validates :nome_portador, length: { in: 0..50 }
14
+
15
+ validates :numero, :validade, :indicador, presence: true
16
+
17
+ validates :numero, length: { is: 16 }
18
+ validates :numero, numericality: { only_integer: true }
19
+
20
+ validates :validade, length: { is: 6 }
21
+ validates :validade, format: { with: /2\d{3}(0[1-9]|1[012])/ }
22
+ validates :validade, numericality: { only_integer: true }
23
+
24
+ validates :codigo_seguranca, length: { in: 3..4 }
25
+ validates :codigo_seguranca, numericality: { only_integer: true }
26
+
27
+ def initialize attrs={}
28
+ super
29
+ indicador_nao_informado!
30
+ end
31
+
32
+ def codigo_seguranca= codigo
33
+ @indicador = INDICADOR_INFORMADO
34
+ @codigo_seguranca = codigo
35
+ end
36
+
37
+ def indicador_nao_informado!
38
+ @indicador = INDICADOR_NAO_INFORMADO
39
+ @codigo_seguranca = nil
40
+ end
41
+
42
+ def indicador_ilegivel!
43
+ @indicador = INDICADOR_ILEGIVEL
44
+ @codigo_seguranca = nil
45
+ end
46
+
47
+ def indicador_inexistente!
48
+ @indicador = INDICADOR_INEXISTENTE
49
+ @codigo_seguranca = nil
50
+ end
51
+
52
+ def attributes
53
+ {
54
+ numero: @numero,
55
+ validade: @validade,
56
+ indicador: indicador,
57
+ codigo_seguranca: @codigo_seguranca,
58
+ nome_portador: @nome_portador
59
+ }
60
+ end
61
+
62
+ module TEST
63
+ VISA = DadosPortador.new numero: 4012001037141112
64
+ MACSTERCARD = DadosPortador.new numero: 5453010000066167
65
+ VISA_NO_AUTH = DadosPortador.new numero: 4012001038443335
66
+ MASTERCARD_NO_AUTH = DadosPortador.new numero: 5453010000066167
67
+ AMEX = DadosPortador.new numero: 376449047333005
68
+ ELO = DadosPortador.new numero: 6362970000457013
69
+ DINERS = DadosPortador.new numero: 36490102462661
70
+ DISCOVERY = DadosPortador.new numero: 6011020000245045
71
+
72
+ constants.each { |c|
73
+ flag = const_get c
74
+ flag.validade = 201805
75
+ flag.codigo_seguranca = 123
76
+ }
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,94 @@
1
+ class Cieloz::RequisicaoTransacao
2
+ class FormaPagamento
3
+ DEBITO = "A"
4
+ CREDITO = 1
5
+ PARCELADO_LOJA = 2
6
+ PARCELADO_ADM = 3
7
+
8
+ BANDEIRAS_DEBITO = [ Cieloz::Bandeiras::VISA, Cieloz::Bandeiras::MASTERCARD ]
9
+ SUPORTAM_AUTENTICACAO = BANDEIRAS_DEBITO
10
+
11
+ BANDEIRAS_PARCELAMENTO = Cieloz::Bandeiras::ALL - [Cieloz::Bandeiras::DISCOVER]
12
+
13
+ include Cieloz::Helpers
14
+
15
+ attr_reader :bandeira, :produto, :parcelas
16
+
17
+ validates :bandeira, :produto, :parcelas, presence: true
18
+
19
+ validates :parcelas, numericality: {
20
+ only_integer: true, greater_than: 0,
21
+ less_than_or_equal_to: Cieloz::Configuracao.max_parcelas
22
+ }, if: "produto == PARCELADO_LOJA"
23
+
24
+ validates :parcelas, numericality: {
25
+ only_integer: true,
26
+ greater_than: Cieloz::Configuracao.max_parcelas,
27
+ less_than_or_equal_to: Cieloz::Configuracao.max_adm_parcelas
28
+ }, if: "produto == PARCELADO_ADM"
29
+
30
+ validates :bandeira, inclusion: { in: BANDEIRAS_DEBITO }, if: "@produto == DEBITO"
31
+ validates :bandeira, inclusion: { in: Cieloz::Bandeiras::ALL }, if: "@produto == CREDITO"
32
+ validates :bandeira, inclusion: { in: BANDEIRAS_PARCELAMENTO },
33
+ if: "[ PARCELADO_LOJA, PARCELADO_ADM ].include? @produto"
34
+
35
+ def attributes
36
+ {
37
+ bandeira: @bandeira,
38
+ produto: @produto,
39
+ parcelas: @parcelas
40
+ }
41
+ end
42
+
43
+ def suporta_autenticacao?
44
+ SUPORTAM_AUTENTICACAO.include? @bandeira
45
+ end
46
+
47
+ def debito bandeira
48
+ set_attrs bandeira, DEBITO, 1
49
+ end
50
+
51
+ def debito?
52
+ @produto == DEBITO
53
+ end
54
+
55
+ def credito bandeira
56
+ set_attrs bandeira, CREDITO, 1
57
+ end
58
+
59
+ def parcelado bandeira, parcelas
60
+ max, max_adm = Cieloz::Configuracao.max_parcelas, Cieloz::Configuracao.max_adm_parcelas
61
+ produto = case parcelas
62
+ when (1..max) then PARCELADO_LOJA
63
+ when (max+1..max_adm) then PARCELADO_ADM
64
+ end
65
+ parcelar bandeira, parcelas, produto
66
+ end
67
+
68
+ # Utility methods that deduces what authorization method should be performed
69
+ def operacao opr, parcelas
70
+ bandeira, @metodo_autorizacao = Cieloz::Bandeiras.operacao opr
71
+ parcelado bandeira, parcelas
72
+ end
73
+
74
+ def metodo_autorizacao
75
+ @metodo_autorizacao || :autorizacao_direta
76
+ end
77
+
78
+ private
79
+ def set_attrs bandeira, produto, parcelas
80
+ @bandeira = bandeira
81
+ @produto = produto
82
+ @parcelas = parcelas
83
+ self
84
+ end
85
+
86
+ def parcelar bandeira, parcelas, produto
87
+ if parcelas == 1
88
+ credito bandeira
89
+ else
90
+ set_attrs bandeira, produto, parcelas
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,126 @@
1
+ class Cieloz::RequisicaoTransacao < Cieloz::Requisicao
2
+ SOMENTE_AUTENTICAR = 0
3
+ AUTORIZAR_SE_AUTENTICADA = 1
4
+ AUTORIZAR_NAO_AUTENTICADA = 2
5
+ AUTORIZACAO_DIRETA = 3
6
+ RECORRENTE = 4
7
+
8
+ hattr_writer :dados_portador, :dados_pedido, :forma_pagamento
9
+ attr_reader :dados_portador, :dados_pedido, :forma_pagamento
10
+ attr_reader :autorizar, :capturar
11
+ attr_accessor :campo_livre, :url_retorno
12
+
13
+ validate :nested_validations
14
+
15
+ validates :dados_portador, presence: true, if: "Cieloz::Configuracao.store_mode?"
16
+ validates :dados_pedido, :forma_pagamento, presence: true
17
+
18
+ with_options unless: "@forma_pagamento.nil?" do |txn|
19
+ txn.validate :suporta_autorizacao_direta?
20
+ txn.validate :suporta_autenticacao?
21
+ end
22
+
23
+ validate :parcela_minima?,
24
+ if: "not @dados_pedido.nil? and not @forma_pagamento.nil?"
25
+
26
+ validates :autorizar, presence: true, inclusion: {
27
+ in: [
28
+ SOMENTE_AUTENTICAR, AUTORIZAR_SE_AUTENTICADA,
29
+ AUTORIZAR_NAO_AUTENTICADA, AUTORIZACAO_DIRETA, RECORRENTE
30
+ ]
31
+ }
32
+ # validates string values because false.blank? is true, failing presence validation
33
+ validates :capturar, presence: true, inclusion: { in: ["true", "false"] }
34
+
35
+ with_options if: "@autorizar != AUTORIZACAO_DIRETA" do |txn|
36
+ txn.validates :url_retorno, presence: true
37
+ txn.validates :url_retorno, length: { in: 1..1024 }
38
+ end
39
+
40
+ validates :campo_livre, length: { maximum: 128 }
41
+
42
+ def nested_validations
43
+ nested_attrs = [ :dados_ec, :dados_pedido, :forma_pagamento ]
44
+ nested_attrs << :dados_portador if Cieloz::Configuracao.store_mode?
45
+
46
+ nested_attrs.each { |attr|
47
+ attr_value = instance_variable_get "@#{attr}"
48
+ if not attr_value.nil? and not attr_value.valid?
49
+ errors.add attr, attr_value.errors
50
+ end
51
+ }
52
+ end
53
+
54
+ def parcela_minima?
55
+ if @dados_pedido.valid? and @forma_pagamento.valid?
56
+ if @dados_pedido.valor / @forma_pagamento.parcelas < 500
57
+ errors.add :forma_pagamento, :minimum_installment_not_satisfied
58
+ end
59
+ end
60
+ end
61
+
62
+ def somente_autenticar
63
+ @autorizar = SOMENTE_AUTENTICAR
64
+ self
65
+ end
66
+
67
+ def autorizar_somente_autenticada
68
+ @autorizar = AUTORIZAR_SE_AUTENTICADA
69
+ self
70
+ end
71
+
72
+ def autorizar_nao_autenticada
73
+ @autorizar = AUTORIZAR_NAO_AUTENTICADA
74
+ self
75
+ end
76
+
77
+ def autorizacao_direta
78
+ @autorizar = AUTORIZACAO_DIRETA
79
+ self
80
+ end
81
+
82
+ def autorizacao_direta?
83
+ @autorizar == AUTORIZACAO_DIRETA
84
+ end
85
+
86
+ def recorrente
87
+ @autorizar = RECORRENTE
88
+ self
89
+ end
90
+
91
+ def capturar_automaticamente
92
+ @capturar = "true"
93
+ self
94
+ end
95
+
96
+ def nao_capturar_automaticamente
97
+ @capturar = "false"
98
+ self
99
+ end
100
+
101
+ def suporta_autorizacao_direta?
102
+ if autorizacao_direta? and @forma_pagamento.debito?
103
+ errors.add :autorizar, :direct_auth_available_for_credit_only
104
+ end
105
+ end
106
+
107
+ def suporta_autenticacao?
108
+ if not autorizacao_direta? and not @forma_pagamento.suporta_autenticacao?
109
+ errors.add :autorizar, :authentication_not_supported
110
+ end
111
+ end
112
+
113
+ def attributes
114
+ {
115
+ dados_ec: @dados_ec,
116
+ dados_portador: @dados_portador,
117
+ dados_pedido: @dados_pedido,
118
+ forma_pagamento: @forma_pagamento,
119
+ url_retorno: @url_retorno,
120
+ autorizar: @autorizar,
121
+ capturar: @capturar,
122
+ campo_livre: @campo_livre,
123
+ bin: (@dados_portador.numero.to_s[0..5] unless @dados_portador.nil?)
124
+ }
125
+ end
126
+ end
@@ -0,0 +1,3 @@
1
+ module Cieloz
2
+ VERSION = "0.0.2"
3
+ end
data/lib/cieloz.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'active_support/core_ext/string'
2
+ require 'active_support/core_ext/object/with_options'
3
+ require 'active_model'
4
+ require 'nokogiri'
5
+
6
+ require 'cieloz/version'
7
+ require "cieloz/helpers"
8
+ require 'cieloz/builder'
9
+ require "cieloz/bandeiras"
10
+ require "cieloz/configuracao"
11
+ require "cieloz/homologacao"
12
+ require "cieloz/requisicao"
13
+ require "cieloz/requisicao/dados_ec"
14
+ require "cieloz/requisicao/resposta"
15
+ require "cieloz/requisicao/resposta/erro"
16
+ require "cieloz/requisicao/resposta/transacao"
17
+ require "cieloz/requisicao_transacao"
18
+ require "cieloz/requisicao_transacao/dados_portador"
19
+ require "cieloz/requisicao_transacao/dados_pedido"
20
+ require "cieloz/requisicao_transacao/forma_pagamento"
21
+ require "cieloz/requisicao_tid"
22
+
23
+ DIR = File.dirname __FILE__
24
+ I18n.load_path += Dir.glob "#{DIR}/../config/locales/*.{rb,yml}"
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,104 @@
1
+ require_relative '../minitest_helper'
2
+
3
+ describe "Integration test" do
4
+ let(:_) { Cieloz::RequisicaoTransacao }
5
+ let(:ec) { _::DadosEc.new Cieloz::Homologacao::Credenciais::CIELO }
6
+ let(:now) { Time.now }
7
+
8
+ let(:pedido) {
9
+ _::DadosPedido.new numero: 123, valor: 5000, moeda: 986,
10
+ data_hora: now, descricao: "teste", idioma: "PT", soft_descriptor: "13letterstest"
11
+ }
12
+
13
+ let(:pagamento) { _::FormaPagamento.new.credito "visa" }
14
+
15
+ let(:autorizacao) {
16
+ Cieloz::RequisicaoTransacao
17
+ .new(dados_ec: ec,
18
+ dados_pedido: pedido,
19
+ forma_pagamento: pagamento,
20
+ url_retorno: "http://ciel.oz/callback")
21
+ .autorizacao_direta
22
+ }
23
+
24
+ it "Autoriza, Consulta, Captura e Cancela" do
25
+ autorizacao.nao_capturar_automaticamente
26
+
27
+ txn = autorizacao.submit
28
+ assert_equal _::Transacao, txn.class, "#{txn.codigo}:\n#{txn.mensagem}"
29
+ assert_equal({}, autorizacao.errors.messages)
30
+ assert txn.criada?
31
+
32
+ assert_equal "302", post_credit_card_on_cielo_page(txn.url_autenticacao).code
33
+
34
+ params = { tid: txn.tid, dados_ec: ec }
35
+
36
+ consulta = Cieloz::RequisicaoConsulta.new params
37
+ cst = consulta.submit
38
+ assert_equal({}, consulta.errors.messages)
39
+ assert cst.autorizada?
40
+
41
+ captura = Cieloz::RequisicaoCaptura.new params
42
+ cap = captura.submit
43
+ assert_equal({}, captura.errors.messages)
44
+ assert cap.capturada?
45
+
46
+ cancelar = Cieloz::RequisicaoCancelamento.new params
47
+ cnc = cancelar.submit
48
+ assert_equal({}, cancelar.errors.messages)
49
+ assert cnc.cancelada?
50
+ end
51
+
52
+ it "Captura Automaticamente, Consulta e Cancela" do
53
+ autorizacao.capturar_automaticamente
54
+
55
+ txn = autorizacao.submit
56
+ assert_equal _::Transacao, txn.class, "#{txn.codigo}:\n#{txn.mensagem}"
57
+ assert_equal({}, autorizacao.errors.messages)
58
+ assert txn.criada?
59
+
60
+ assert_equal "302", post_credit_card_on_cielo_page(txn.url_autenticacao).code
61
+
62
+ params = { tid: txn.tid, dados_ec: ec }
63
+
64
+ consulta = Cieloz::RequisicaoConsulta.new params
65
+ cst = consulta.submit
66
+ assert_equal({}, consulta.errors.messages)
67
+ assert cst.capturada?
68
+
69
+ cancelar = Cieloz::RequisicaoCancelamento.new params
70
+ cnc = cancelar.submit
71
+ assert_equal({}, cancelar.errors.messages)
72
+ assert cnc.cancelada?
73
+ end
74
+
75
+ def post_credit_card_on_cielo_page url_cielo, bandeira=:visa,
76
+ portador=Cieloz::RequisicaoTransacao::DadosPortador::TEST::VISA
77
+ uri = URI(url_cielo)
78
+
79
+ # first, visit url_autenticacao - triggers em_andamento state
80
+ Net::HTTP.start(uri.host, uri.port, use_ssl: true,
81
+ verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
82
+ http.request Net::HTTP::Get.new uri.request_uri
83
+ end
84
+
85
+ # after, prepare post to verify
86
+ uri.path = "/web/verify.cbmp"
87
+
88
+ params = Hash[*(uri.query.split("&").collect{ |param| param.split("=") }.flatten)]
89
+
90
+ post = Net::HTTP::Post.new uri.path
91
+ post.set_form_data id: params["id"],
92
+ bin: 0, cancelar: false,
93
+ bandeira: bandeira,
94
+ numeroCartao: portador.numero,
95
+ mes: portador.validade.to_s[4..5],
96
+ ano: portador.validade.to_s[2..3],
97
+ codSeguranca: portador.codigo_seguranca
98
+
99
+ Net::HTTP.start(uri.host, uri.port, use_ssl: true,
100
+ verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
101
+ http.request post
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,65 @@
1
+ require 'debugger'
2
+ require 'cieloz'
3
+
4
+ require 'minitest/autorun'
5
+ require 'turn/autorun'
6
+
7
+ require 'minitest/matchers'
8
+ require 'shoulda/matchers'
9
+
10
+ require 'fakeweb'
11
+ require 'erb'
12
+
13
+ class MiniTest::Spec
14
+ include Shoulda::Matchers::ActiveModel
15
+
16
+ class << self
17
+ alias :_create :create
18
+
19
+ def create name, desc
20
+ cls = _create name, desc
21
+ begin
22
+ c = eval name
23
+ cls.subject {
24
+ if c.is_a? Class then c.new elsif c.is_a? Module then c end
25
+ }
26
+ rescue
27
+ end
28
+ cls
29
+ end
30
+ end
31
+ end
32
+
33
+ module Shoulda::Matchers::ActiveModel
34
+ class AllowValueMatcher
35
+ def matches? instance
36
+ @instance = instance
37
+ @values_to_match.none? do |value|
38
+ @value = value
39
+ @instance.instance_variable_set "@#{@attribute}", @value
40
+ errors_match?
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ def expected_xml opts={}
47
+ root, id, versao = opts[:root], opts[:id], opts[:versao]
48
+
49
+ '<?xml version="1.0" encoding="UTF-8"?>' +
50
+ %|<#{root} id="#{id}" versao="#{versao}">| +
51
+ "#{yield if block_given?}" +
52
+ "</#{root}>"
53
+ end
54
+
55
+ def render_template dir, filename, binding
56
+ template = File.join dir, [ "xml", filename ]
57
+ file = File.read template
58
+ erb = ERB.new file
59
+ res = erb.result binding
60
+ res.split("\n").collect {|line| line.strip }.join
61
+ end
62
+
63
+ def xml_for type, dir, binding
64
+ render_template dir, "dados-#{type}.xml", binding
65
+ end
@@ -0,0 +1,25 @@
1
+ describe "Bandeiras e Operacoes" do
2
+ let(:_) { Cieloz::Bandeiras }
3
+
4
+ it "recognizes mastercard secure code requires authentication" do
5
+ res = _.operacao "mastercard_securecode"
6
+ assert_equal [_::MASTERCARD, :autorizar_somente_autenticada], res
7
+ end
8
+
9
+ it "recognizes verified by visa code requires authentication" do
10
+ res = _.operacao "verified_by_visa"
11
+ assert_equal [_::VISA, :autorizar_somente_autenticada], res
12
+ end
13
+
14
+ it "recognizes supported products allows direct authorization" do
15
+ _::ALL.each do |bandeira|
16
+ res = _.operacao bandeira
17
+ assert_equal [bandeira, :autorizacao_direta], res
18
+ end
19
+ end
20
+
21
+ it "disallows unsupported products" do
22
+ error = lambda { _.operacao("anything else") }.must_raise RuntimeError
23
+ error.message.must_match /product_not_supported/
24
+ end
25
+ end