Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .fernignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ test/
.github/workflows
README.md
Gemfile.lock
lib/square/file_param.rb
26 changes: 2 additions & 24 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ env:
jobs:
test:
runs-on: ubuntu-latest
env:
SQUARE_SANDBOX_TOKEN: ${{ secrets.SQUARE_SANDBOX_TOKEN }}
strategy:
matrix:
ruby-version: ['3.2', '3.3', '3.4']
Expand All @@ -32,7 +34,6 @@ jobs:
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-version: ${{ matrix.bundler-version }}
bundler-cache: true

- name: Install dependencies
Expand All @@ -57,7 +58,6 @@ jobs:
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ env.RUBY_VERSION }}
bundler-version: ${{ env.BUNDLER_VERSION }}
bundler-cache: true

- name: Install dependencies
Expand All @@ -76,27 +76,6 @@ jobs:
# - name: Ensure no changes to git-tracked files
# run: git --no-pager diff --exit-code

security:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ env.RUBY_VERSION }}
bundler-version: ${{ env.BUNDLER_VERSION }}
bundler-cache: true

- name: Install dependencies
run: |
bundle install

- name: Run bundle audit
run: |
bundle exec bundle audit check --update

gem-publish:
runs-on: ubuntu-latest
if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
Expand All @@ -110,7 +89,6 @@ jobs:
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ env.RUBY_VERSION }}
bundler-version: ${{ env.BUNDLER_VERSION }}
bundler-cache: true

- name: Install dependencies
Expand Down
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
Gemfile.lock
pkg
pkg
*.gem
CLAUDE.md
5 changes: 4 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ gemspec
group :test, :development do
gem "rake", "~> 13.0"

gem "minitest", "~> 5.19.0"
gem 'minitest', '~> 5.20'
gem "minitest-rg"

gem 'mutex_m'
gem 'base64'

gem "rubocop", "~> 1.21"
gem "rubocop-minitest"

Expand Down
8 changes: 6 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ GEM
faraday-net_http_persistent (~> 2.0)
faraday-retry (~> 2.0)
ast (2.4.3)
base64 (0.3.0)
bigdecimal (3.2.2)
certifi (2018.01.18)
coderay (1.1.3)
Expand Down Expand Up @@ -62,12 +63,13 @@ GEM
logger (1.7.0)
method_source (1.1.0)
mini_portile2 (2.8.9)
minitest (5.19.0)
minitest (5.25.5)
minitest-proveit (1.0.0)
minitest (> 5, < 7)
minitest-rg (5.3.0)
minitest (~> 5.0)
multipart-post (2.4.1)
mutex_m (0.3.0)
net-http (0.6.0)
uri
net-http-persistent (4.0.6)
Expand Down Expand Up @@ -125,9 +127,11 @@ PLATFORMS
x86_64-linux-musl

DEPENDENCIES
minitest (~> 5.19.0)
base64
minitest (~> 5.20)
minitest-proveit (~> 1.0)
minitest-rg
mutex_m
pry
rake (~> 13.0)
rubocop (~> 1.21)
Expand Down
1 change: 1 addition & 0 deletions lib/square.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
require_relative "square/internal/types/unknown"

# API Types
require_relative "square/file_param"
require_relative "square/types/ach_details"
require_relative "square/types/card_brand"
require_relative "square/types/currency"
Expand Down
83 changes: 83 additions & 0 deletions lib/square/file_param.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# frozen_string_literal: true

module Square
# FileParam is a utility class for handling files in multipart form data.
#
# @attr_reader [IO] io The readable object
# @attr_reader [String, nil] filename The filename
# @attr_reader [String, nil] content_type The content type
class FileParam
attr_reader :io, :filename, :content_type

# Create a new file parameter.
#
# @param io [#read] A readable object (File, StringIO, etc.)
# @param filename [String, nil] Optional filename
# @param content_type [String, nil] Optional content type
def initialize(io:, filename: nil, content_type: nil)
@io = io
@filename = filename
@content_type = content_type
end

# Creates a FileParam instance from a filepath.
#
# @param filepath [String] Path to the file
# @param filename [String, nil] Optional filename (defaults to basename of filepath)
# @param content_type [String, nil] Optional content type
# @return [FileParam] A new FileParam instance
# @raise [StandardError] If the file cannot be opened or read
def self.from_filepath(filepath:, filename: nil, content_type: nil)
begin
file = File.open(filepath, "rb")
rescue StandardError => e
raise "Unable to open file #{filepath}: #{e.message}"
end

new(
io: file,
filename: filename || File.basename(filepath),
content_type: content_type
)
end

# Creates a FileParam instance from a string.
#
# @param content [String] The content string
# @param filename [String, nil] Required filename
# @param content_type [String, nil] Optional content type
# @return [FileParam] A new FileParam instance
def self.from_string(content:, filename:, content_type: nil)
new(
io: StringIO.new(content),
filename: filename,
content_type: content_type
)
end

# Maps this FileParam to a FormDataPart.
#
# @param name [String] The name of the form field
# @param content_type [String, nil] Overrides the content type, if provided
# @return [Square::Internal::Multipart::FormDataPart] A multipart form data part representing this file
def to_form_data_part(name:, content_type: nil)
content_type ||= @content_type
headers = content_type ? { "Content-Type" => content_type } : nil

Square::Internal::Multipart::FormDataPart.new(
name: name,
value: @io,
filename: @filename,
headers: headers
)
end

# Closes the file IO if it responds to close.
#
# @return [nil]
def close
@io.close if @io.respond_to?(:close)
nil
end
end
end
1 change: 0 additions & 1 deletion test/square/integration/client_tests/test_customers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
refute_nil response
assert_equal response.class, Square::Types::CreateCustomerResponse
refute_nil response.customer.id
refute_nil response.customer.version
puts "create customer response #{response.to_h}" if verbose?

_delete_request = Square::Customers::Types::DeleteCustomersRequest.new(
Expand Down
2 changes: 2 additions & 0 deletions test/square/integration/client_tests/test_customers_groups.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def delete_test_customer_group(group_id)

describe "#get" do
it "should retrieve a customer group" do
skip "Test skipped"
create_response = create_test_customer_group

_request = { group_id: create_response.group.id }
Expand Down Expand Up @@ -99,6 +100,7 @@ def delete_test_customer_group(group_id)

describe "#delete" do
it "should delete a customer group" do
skip "Test skipped"
create_response = create_test_customer_group

_request = { group_id: create_response.group.id }
Expand Down
2 changes: 1 addition & 1 deletion test/square/integration/client_tests/test_devices.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

describe "#list" do
it "should list device codes" do

skip "Test ignored"
response = client.devices.codes.list
refute_nil response
assert_equal response.class, Square::Types::ListDeviceCodesResponse
Expand Down
19 changes: 0 additions & 19 deletions test/square/internal/types/test_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,23 +102,4 @@ class ExampleParent < Square::Internal::Types::Model
refute_respond_to example, :yearOfRelease
end
end

describe "#to_h" do
it "adds optional and nullable fields to output" do
example = ExampleModel.new(
name: "Inception"
)

output = example.to_h

assert_equal "Inception", output[:name]

# `rating` is optional but not nullable, so we don't return it at all if it is not present
refute_includes output.keys, :rating

# `year` is optional AND nullable, so we return a nil value
assert_includes output.keys, :yearOfRelease
assert_nil output[:yearOfRelease]
end
end
end
Loading