Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

finishing up generate

  • Loading branch information...
commit e59d575f963a7d16ce2c9aff79c11b35f5cc20e0 1 parent a479945
@lgleasain lgleasain authored
View
1  bin/pk
@@ -5,6 +5,7 @@ require 'terminal-table'
$:.push File.expand_path("../../lib", __FILE__)
require 'passbook'
+require 'utils/command_utils'
HighLine.track_eof = false # Fix for built-in Ruby
Signal.trap("INT") {} # Suppress backtrace when exiting command
View
7 lib/commands/build.rb
@@ -54,13 +54,6 @@
alias_command :archive, :build
alias_command :b, :build
-# this was added for testability because I couldn't figure out something better.
-class CommandUtils
- def get_assets(directory)
- Dir[File.join(directory, '*')]
- end
-end
-
private
def validate_output_filepath!
View
5 lib/commands/commands.rb
@@ -3,6 +3,8 @@
require 'commands/build'
require 'commands/generate'
#require 'commands/serve'
+# this was added for testability because I couldn't figure out something better.
+
private
def determine_directory!
@@ -24,3 +26,6 @@ def validate_directory!
def validate_certificate!
say_error "Missing or invalid certificate file" and abort if @certificate.nil? or not File.exist?(@certificate)
end
+
+
+
View
11 lib/commands/generate.rb
@@ -11,17 +11,16 @@
c.action do |args, options|
@directory = args.first
@directory ||= ask "Enter a passbook name: "
-
say_error "Missing pass name" and abort if @directory.nil? or @directory.empty?
say_error "Directory #{@directory} already exists" and abort if File.directory?(@directory)
say_error "File exists at #{@directory}" and abort if File.exist?(@directory)
@type = options.type
- #determine_type! unless @type
- #validate_type!
+ determine_type! unless @type
+ validate_type!
FileUtils.mkdir_p @directory
- FileUtils.cp File.join(File.dirname(__FILE__), '..', 'templates', "#{@type}.json"), File.join(@directory, 'pass.json')
+ FileUtils.cp File.join(CommandUtils.get_current_directory, '..', 'templates', "#{@type}.json"), File.join(@directory, 'pass.json')
['icon.png', 'icon@2x.png'].each do |file|
FileUtils.touch File.join(@directory, file)
end
@@ -36,10 +35,10 @@
private
def determine_type!
- @type ||= choose "Select a pass type", *Dubai::Passbook::Pass::TYPES
+ @type ||= choose "Select a pass type", *Passbook::PKPass::TYPES
end
def validate_type!
- say_error %{Invalid type: "#{@type}", expected one of: [#{Dubai::Passbook::Pass::TYPES.join(', ')}]} unless Dubai::Passbook::Pass::TYPES.include?(@type)
+ say_error %{Invalid type: "#{@type}", expected one of: [#{Passbook::PKPass::TYPES.join(', ')}]} and abort unless Passbook::PKPass::TYPES.include?(@type)
end
View
14 lib/commands/templates/boarding-pass.json
@@ -11,13 +11,13 @@
"primaryFields" : [
{
"key" : "origin",
- "label" : "San Francisco",
- "value" : "SFO"
+ "label" : "Atlanta",
+ "value" : "ATL"
},
{
"key" : "destination",
- "label" : "London",
- "value" : "LHR"
+ "label" : "Johannesburg",
+ "value" : "JNB"
}
],
"secondaryFields" : [
@@ -36,12 +36,12 @@
{
"key" : "passenger-name",
"label" : "Passenger",
- "value" : "John Appleseed"
+ "value" : "Honey Badger"
}
],
"transitType" : "PKTransitTypeAir",
"barcode" : {
- "message" : "ABC123",
+ "message" : "DL123",
"format" : "PKBarcodeFormatQR",
"messageEncoding" : "iso-8859-1"
},
@@ -49,7 +49,7 @@
{
"key" : "terms",
"label" : "Terms and Conditions",
- "value" : "Lorem ipsum dolar sit amet"
+ "value" : "Valid for date of travel only"
}
]
}
View
33 lib/commands/templates/coupon.json
@@ -0,0 +1,33 @@
+{
+ "formatVersion" : 1,
+ "passTypeIdentifier" : "pass.com.example.coupon",
+ "description" : "Example Coupon",
+ "teamIdentifier": "Example",
+ "organizationName": "Example",
+ "serialNumber" : "123456",
+ "foregroundColor": "#FFFFFF",
+ "backgroundColor": "#C799FF",
+ "generic" : {
+ "primaryFields" : [
+
+ ],
+ "secondaryFields" : [
+
+ ],
+ "auxiliaryFields" : [
+
+ ],
+ "barcode" : {
+ "message" : "ABCD 123 EFGH 456 IJKL 789 MNOP",
+ "format" : "PKBarcodeFormatPDF417",
+ "messageEncoding" : "iso-8859-1"
+ },
+ "backFields" : [
+ {
+ "key" : "terms",
+ "label" : "Terms and Conditions",
+ "value" : "T's and C's Apply"
+ }
+ ]
+ }
+}
View
33 lib/commands/templates/event-ticket.json
@@ -0,0 +1,33 @@
+{
+ "formatVersion" : 1,
+ "passTypeIdentifier" : "pass.com.example.event-ticket",
+ "description" : "Example Event Ticket",
+ "teamIdentifier": "Example",
+ "organizationName": "Example",
+ "serialNumber" : "123456",
+ "foregroundColor": "#FFFFFF",
+ "backgroundColor": "#FF5453",
+ "generic" : {
+ "primaryFields" : [
+
+ ],
+ "secondaryFields" : [
+
+ ],
+ "auxiliaryFields" : [
+
+ ],
+ "barcode" : {
+ "message" : "ABCD 123 EFGH 456 IJKL 789 MNOP",
+ "format" : "PKBarcodeFormatPDF417",
+ "messageEncoding" : "iso-8859-1"
+ },
+ "backFields" : [
+ {
+ "key" : "terms",
+ "label" : "Terms and Conditions",
+ "value" : "T's and C's apply"
+ }
+ ]
+ }
+}
View
33 lib/commands/templates/generic.json
@@ -0,0 +1,33 @@
+{
+ "formatVersion" : 1,
+ "passTypeIdentifier" : "pass.com.example.generic",
+ "description" : "Example Generic Pass",
+ "teamIdentifier": "Example",
+ "organizationName": "Example",
+ "serialNumber" : "123456",
+ "foregroundColor": "#FFFFFF",
+ "backgroundColor": "#444444",
+ "generic" : {
+ "primaryFields" : [
+
+ ],
+ "secondaryFields" : [
+
+ ],
+ "auxiliaryFields" : [
+
+ ],
+ "barcode" : {
+ "message" : "ABCD 123 EFGH 456 IJKL 789 MNOP",
+ "format" : "PKBarcodeFormatPDF417",
+ "messageEncoding" : "iso-8859-1"
+ },
+ "backFields" : [
+ {
+ "key" : "terms",
+ "label" : "Terms and Conditions",
+ "value" : "Put your terms here"
+ }
+ ]
+ }
+}
View
33 lib/commands/templates/store-card.json
@@ -0,0 +1,33 @@
+{
+ "formatVersion" : 1,
+ "passTypeIdentifier" : "pass.com.example.store-card",
+ "description" : "Example Store Card",
+ "teamIdentifier": "Example",
+ "organizationName": "Example",
+ "serialNumber" : "123456",
+ "foregroundColor": "#FFFFFF",
+ "backgroundColor": "#AFC1E3",
+ "generic" : {
+ "primaryFields" : [
+
+ ],
+ "secondaryFields" : [
+
+ ],
+ "auxiliaryFields" : [
+
+ ],
+ "barcode" : {
+ "message" : "ABCD 123 EFGH 456 IJKL 789 MNOP",
+ "format" : "PKBarcodeFormatPDF417",
+ "messageEncoding" : "iso-8859-1"
+ },
+ "backFields" : [
+ {
+ "key" : "terms",
+ "label" : "Terms and Conditions",
+ "value" : "T's and C's apply"
+ }
+ ]
+ }
+}
View
2  lib/passbook/pkpass.rb
@@ -7,6 +7,8 @@ module Passbook
class PKPass
attr_accessor :pass, :manifest_files
+ TYPES = ['boarding-pass', 'coupon', 'event-ticket', 'store-card', 'generic']
+
def initialize pass
@pass = pass
@manifest_files = []
View
12 lib/utils/command_utils.rb
@@ -0,0 +1,12 @@
+# this was added for testability because I couldn't figure out something better.
+class CommandUtils
+ def self.get_assets(directory)
+ Dir[File.join(directory, '*')]
+ end
+
+ def self.get_current_directory
+ File.dirname(__FILE__)
+ end
+end
+
+
View
28 spec/lib/commands/build_spec.rb
@@ -10,12 +10,7 @@
context 'command' do
specify 'missing directory' do
- begin
- lambda {
- run 'build'
- }.should raise_error(SystemExit, ' ')
-
- rescue
+ run_command 'build' do
@output.string.should eq "\e[31mMissing argument\e[0m\n"
end
end
@@ -29,12 +24,8 @@
end
specify 'no certificate file' do
- begin
- lambda {
- run('build', 'scraps')
- }.should raise_error(SystemExit, ' ')
- rescue
- @output.string.should eq "\e[31mMissing or invalid certificate file\e[0m\n"
+ run_command 'build', 'scraps' do
+ @output.string.should eq "\e[31mMissing or invalid certificate file\e[0m\n"
end
end
@@ -98,17 +89,4 @@
end
end
- def run_raw_command(*args)
- lambda{
- run(*args)
- }.should raise_error(SystemExit, ' ')
- end
-
- def run_command(*args, &block)
- begin
- run_raw_command *args
- rescue
- yield
- end
- end
end
View
14 spec/lib/commands/commands_spec_helper.rb
@@ -1,6 +1,7 @@
require 'spec_helper'
require 'terminal-table'
require 'commander/import'
+require 'utils/command_utils'
def load_commands
Dir['lib/commands/**/*.rb'].each {|f|
@@ -53,3 +54,16 @@ def run *args
end
end
+def run_raw_command(*args)
+ lambda{
+ run(*args)
+ }.should raise_error(SystemExit, ' ')
+end
+
+def run_command(*args, &block)
+ begin
+ run_raw_command *args
+ rescue
+ yield
+ end
+end
View
147 spec/lib/commands/generate_spec.rb
@@ -0,0 +1,147 @@
+require 'lib/commands/commands_spec_helper'
+require 'passbook'
+
+describe 'Generate' do
+
+ before :each do
+ $stderr = StringIO.new
+ mock_terminal
+ end
+
+ context 'command' do
+ specify 'no options' do
+ run_command 'generate' do
+ @output.string.should eq 'Enter a passbook name: '
+ end
+
+ end
+
+ specify 'passbook entered directory already exists' do
+ @input << "my_awesome_passbook\n"
+ @input.rewind
+ File.should_receive(:directory?).with('my_awesome_passbook').and_return true
+ run_command 'generate' do
+ @output.string.should eq "Enter a passbook name: \e[31mDirectory my_awesome_passbook already exists\e[0m\n"
+ end
+ end
+
+ specify 'passbook entered file already exists' do
+ @input << "my_awesome_passbook\n"
+ @input.rewind
+ File.should_receive(:directory?).with('my_awesome_passbook').and_return false
+ File.should_receive(:exist?).with('my_awesome_passbook').and_return true
+ run_command 'generate' do
+ @output.string.should eq "Enter a passbook name: \e[31mFile exists at my_awesome_passbook\e[0m\n"
+ end
+ end
+
+ context 'valid pass directory' do
+
+ before :each do
+ File.should_receive(:directory?).with('my_awesome_passbook').and_return false
+ File.should_receive(:exist?).with('my_awesome_passbook').and_return false
+ end
+
+ specify 'invalid type' do
+ @input << "my_awesome_passbook\n"
+ @input.rewind
+ run_command 'generate', '-T', 'honey_badger' do
+ @output.string.should eq "Enter a passbook name: \e[31mInvalid type: \"honey_badger\", expected one of: [boarding-pass, coupon, event-ticket, store-card, generic]\e[0m\n"
+ end
+ end
+
+ specify 'valid type' do
+ CommandUtils.should_receive(:get_current_directory).and_return('')
+ FileUtils.should_receive(:mkdir_p).with('my_awesome_passbook')
+ FileUtils.should_receive(:cp).with("/../templates/boarding-pass.json", "my_awesome_passbook/pass.json")
+ FileUtils.should_receive(:touch).with("my_awesome_passbook/icon.png")
+ FileUtils.should_receive(:touch).with("my_awesome_passbook/icon@2x.png")
+ @input << "1\n"
+ @input.rewind
+ run_command 'generate', 'my_awesome_passbook' do
+ @output.string.should eq "Select a pass type\n1. boarding-pass\n2. coupon\n3. event-ticket\n4. store-card\n5. generic\n? \e[32mPass generated in my_awesome_passbook\e[0m\n"
+ end
+ end
+ end
+
+ pending 'good directory' do
+
+ before :each do
+ File.should_receive(:directory?).with('scraps').and_return true
+ File.should_receive(:exist?).once.with('scraps/pass.json').and_return true
+ File.should_receive(:exist?).once.with('scraps.pkpass').and_return false
+ end
+
+ specify 'no certificate file' do
+ begin
+ lambda {
+ run('build', 'scraps')
+ }.should raise_error(SystemExit, ' ')
+ rescue
+ @output.string.should eq "\e[31mMissing or invalid certificate file\e[0m\n"
+ end
+ end
+
+ context 'good certificate file' do
+ before :each do
+ File.should_receive(:exist?).with('jackels').and_return true
+ end
+
+ specify 'no certificate password entered' do
+ run_command 'build', 'scraps', '-w', 'jackels' do
+ @output.string.should eq "Enter certificate password:\n\n"
+ end
+ end
+
+ context 'all required values' do
+
+ let(:pass_json) {'{"this":"is awesome json"}'}
+ let(:pass_assets) {['pass.json', 'something.jpeg']}
+
+ before :each do
+ Passbook.should_receive(:wwdc_cert=).with 'jackels'
+ Passbook.should_receive(:p12_key=).with 'badger_key'
+ Passbook.should_receive(:p12_certificate=).with 'badger_cert'
+ Passbook.should_receive(:p12_password=).with 'bees'
+ CommandUtils.should_receive(:get_assets).with('scraps').and_return pass_assets
+ @pk_pass = double 'pk pass'
+ File.should_receive(:read).with('pass.json').and_return pass_json
+ Passbook::PKPass.should_receive(:new).with(pass_json).and_return @pk_pass
+ @pk_pass.should_receive(:addFiles).with pass_assets
+ end
+
+ specify 'are set from command line' do
+ pass_stream = double 'passbook stream'
+ pass_stream.should_receive(:string).and_return 'my badass pass'
+ @pk_pass.should_receive(:stream).and_return pass_stream
+ File.should_receive(:open).with('scraps.pkpass', 'w')
+
+ run_command 'build', 'scraps', '-w', 'jackels',
+ '-p', 'bees', '-k', 'badger_key', '-c', 'badger_cert' do
+ @output.string.should eq ""
+ end
+ end
+
+ specify 'should catch a general error' do
+ @pk_pass.should_receive(:stream).and_raise(StandardError.new('I have failed'))
+ run_command 'build', 'scraps', '-w', 'jackels',
+ '-p', 'bees', '-k', 'badger_key', '-c', 'badger_cert' do
+ @output.string.should eq "\e[31mError: I have failed\e[0m\n"
+ end
+ end
+
+ specify 'should catch a general error' do
+ @pk_pass.should_receive(:stream).and_raise(OpenSSL::PKCS12::PKCS12Error.new('I am a failure'))
+ run_command 'build', 'scraps', '-w', 'jackels',
+ '-p', 'bees', '-k', 'badger_key', '-c', 'badger_cert' do
+ @output.string.should eq "\e[31mError: I am a failure\e[0m\n\e[33mYou may be getting this error because the certificate password is either incorrect or missing\e[0m\n"
+ end
+ end
+ end
+ end
+ end
+ end
+
+
+end
+
Please sign in to comment.
Something went wrong with that request. Please try again.