Skip to content

Commit d38be33

Browse files
author
Maxim Chechel
committed
tests for APDU::Request
1 parent 1d25ebd commit d38be33

File tree

9 files changed

+110
-9
lines changed

9 files changed

+110
-9
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
source 'https://rubygems.org'
22

33
gem 'ffi'
4+
gem 'minitest'

Gemfile.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ GEM
22
remote: https://rubygems.org/
33
specs:
44
ffi (1.9.3)
5+
minitest (5.4.2)
56

67
PLATFORMS
78
ruby
89

910
DEPENDENCIES
1011
ffi
12+
minitest

Rakefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
require 'rake/testtask'
2+
3+
Rake::TestTask.new do |t|
4+
t.libs << 'test'
5+
t.pattern = "test/*_test.rb"
6+
end

lib/ruby-nfc/apdu/apdu.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
module APDU
2+
class Error < ::Exception; end
3+
24
class Errno < ::Exception
35
STATUS_STRINGS = {
46
#0x6XXX => "Transmission protocol related codes

lib/ruby-nfc/apdu/apdu_request.rb

Lines changed: 0 additions & 9 deletions
This file was deleted.

lib/ruby-nfc/apdu/request.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
require_relative './apdu'
2+
3+
module APDU
4+
class Request
5+
attr_accessor :cla, :ins, :p1, :p2, :lc, :data, :le
6+
7+
def self.from_string(apdu)
8+
raise APDU::Error, "APDU is too short: #{apdu.size}" if apdu.size < 5
9+
10+
apdu_8bit = apdu.dup
11+
apdu_8bit.force_encoding('ASCII-8BIT')
12+
13+
req = self.new
14+
req.cla, req.ins, req.p1, req.p2, req.lc, req.data = apdu.unpack('CCCCCA*')
15+
16+
if req.data.size == req.lc
17+
req.le = 0
18+
elsif req.data.size == req.lc + 1
19+
req.le = req.data[-1,1].ord
20+
req.data = req.data[0...-1]
21+
else
22+
raise APDU::Error, "Wrong Lc or wrong command data length"
23+
end
24+
25+
req
26+
end
27+
28+
def self.from_hex_string(apdu)
29+
raise APDU::Error, "Wrong format" if apdu !~ /^([a-fA-F0-9]{2}){5,128}$/
30+
from_string([apdu].pack('H*'))
31+
end
32+
33+
# Public: Build APDU command
34+
def build
35+
[self.to_s].pack('H*')
36+
end
37+
38+
def to_s
39+
[cla, ins, p1, p2, lc, data, le].pack('CCCCCA*C').unpack('H*').pop.upcase
40+
end
41+
end
42+
end

ruby-nfc.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
3030
s.requirements << 'libfreefare'
3131

3232
s.add_runtime_dependency 'ffi'
33+
s.add_development_dependency 'minitest'
3334

3435
s.post_install_message = [
3536
"Don't forget to install libnfc and libfreefare",

test/apdu_request_test.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
require 'test_helper'
2+
require 'ruby-nfc/apdu/request'
3+
4+
class PostTest < MiniTest::Unit::TestCase
5+
def test_raise_apdu_error_if_length_too_small
6+
e = assert_raises(APDU::Error) {APDU::Request.from_string("123")}
7+
assert_match e.message, /too short/
8+
end
9+
10+
def test_raise_apdu_error_if_wrong_command_data_length
11+
apdu = "\x01\x02\x03\x04\x05\xDE\xAD\xBE\xEF"
12+
e = assert_raises(APDU::Error) {APDU::Request.from_string(apdu)}
13+
assert_match e.message, /Wrong Lc/
14+
15+
apdu << "\xAA\xBB\xCC"
16+
e = assert_raises(APDU::Error) {APDU::Request.from_string(apdu)}
17+
assert_match e.message, /Wrong Lc/
18+
end
19+
20+
def test_from_string_method
21+
apdu = "\x01\x02\x03\x04\x05\xDE\xAD\xBE\xEF\xAA\x06"
22+
request = APDU::Request.from_string(apdu)
23+
request_helper(request)
24+
end
25+
26+
def test_from_hex_string_method_wrong_format
27+
apdu = "0102030405DEADBEEFAA0"
28+
e = assert_raises(APDU::Error) {APDU::Request.from_hex_string(apdu)}
29+
assert_match e.message, /Wrong format/
30+
31+
apdu = "0102030405DEADBEEFAA0Z"
32+
e = assert_raises(APDU::Error) {APDU::Request.from_hex_string(apdu)}
33+
assert_match e.message, /Wrong format/
34+
end
35+
36+
def test_from_hex_string_method
37+
apdu = "0102030405DEADBEEFAA06"
38+
request = APDU::Request.from_hex_string(apdu)
39+
request_helper(request)
40+
end
41+
42+
def request_helper(request)
43+
assert_equal 1, request.cla
44+
assert_equal 2, request.ins
45+
assert_equal 3, request.p1
46+
assert_equal 4, request.p2
47+
assert_equal 5, request.lc
48+
assert_equal 6, request.le
49+
assert_equal "\xDE\xAD\xBE\xEF\xAA", request.data
50+
end
51+
end

test/test_helper.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
require 'ruby-nfc'
2+
3+
require 'minitest/unit'
4+
require 'minitest/autorun'
5+
require 'minitest/pride'

0 commit comments

Comments
 (0)