Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
shopify_liquid_test_helper
Advanced tools
ShopifyLiquidTestHelper is a Ruby gem designed to assist in testing Shopify Liquid templates. It provides custom Liquid tags and helper methods that simulate Shopify-specific functionality, making it easier to test your Liquid templates in isolation.
Tag | Status |
---|---|
render | ✅ |
Add this line to your application's Gemfile:
gem 'shopify_liquid_test_helper'
And then execute:
$ bundle install
Or install it yourself as:
$ gem install shopify_liquid_test_helper
In your spec_helper.rb
or at the beginning of your test file, require and configure the helper:
require 'shopify_liquid_test_helper'
RSpec.configure do |config|
config.before(:each) do
ShopifyLiquidTestHelper.register_custom_tags
end
end
Here are some examples of how you can use ShopifyLiquidTestHelper in your RSpec tests:
RSpec.describe "Product template" do
before do
ShopifyLiquidTestHelper.register_snippet('product_title', '<h1>{{ product.title }}</h1>')
end
it "renders the product title" do
template = "{% render 'product_title' %}"
assigns = { 'product' => { 'title' => 'Awesome T-Shirt' } }
result = Liquid::Template.parse(template).render(assigns)
expect(result).to eq '<h1>Awesome T-Shirt</h1>'
end
end
RSpec.describe "Collection template" do
before do
ShopifyLiquidTestHelper.register_snippet('product_list', '{% for product in products %}{{ product.title }}{% endfor %}')
end
it "renders a list of product titles" do
template = "{% render 'product_list' for products %}"
assigns = { 'products' => [{ 'title' => 'Shirt' }, { 'title' => 'Pants' }] }
result = Liquid::Template.parse(template).render(assigns)
expect(result).to eq 'ShirtPants'
end
end
RSpec.describe "Capture tag" do
it "captures content into a variable" do
template = "{% capture my_variable %}Hello, {{ name }}!{% endcapture %}{{ my_variable }}"
assigns = { 'name' => 'World' }
result = Liquid::Template.parse(template).render(assigns)
expect(result).to eq 'Hello, World!'
end
end
ShopifyLiquidTestHelper can load snippets from a specific directory. By default, it looks for snippets in a snippets
directory relative to your current working directory. You can use this feature as follows:
snippets
directory in your project:mkdir snippets
product_card.liquid
:<!-- snippets/product_card.liquid -->
<div class="product-card">
<h2>{{ product.title }}</h2>
<p>Price: {{ product.price | money }}</p>
</div>
RSpec.describe "Product listing" do
it "renders a product card" do
template = "{% render 'product_card' %}"
assigns = {
'product' => {
'title' => 'Awesome T-Shirt',
'price' => 1999
}
}
result = Liquid::Template.parse(template).render(assigns)
expect(result).to include('Awesome T-Shirt')
expect(result).to include('Price: $19.99')
end
end
ShopifyLiquidTestHelper will automatically load the product_card
snippet from the snippets
directory when you use the render
tag in your Liquid template.
allow
in RSpecShopifyLiquidTestHelper provides functionality to mock Liquid snippets using RSpec's allow
method. This is particularly useful when testing templates that depend on other snippets.
Here's a simple example of how to use allow
for mocking:
<!-- snippets/product.liquid -->
<div class="product">
<h1>{{ product.title }}</h1>
<div class="price">
{% render 'product_price' %}
</div>
<div class="description">
{{ product.description }}
</div>
{% if product.available %}
<button type="button" class="add-to-cart">Add to Cart</button>
{% else %}
<p>Sold Out</p>
{% endif %}
</div>
RSpec.describe 'ProductTemplate' do
let(:template) { ShopifyLiquidTestHelper.parse_template('snippets/product.liquid') }
let(:product) { { 'title' => 'Test Product', 'price' => 1000 } }
before do
# Mock the 'product_price' snippet to return a formatted price
allow(ShopifyLiquidTestHelper).to receive(:get_snippet).with('product_price').and_return('{{ product.price | money }}')
end
it 'renders the product title and price' do
rendered = template.render('product' => product)
expect(rendered).to include('Test Product')
expect(rendered).to include('$10.00')
end
context 'when the product is on sale' do
before do
# Override the mock for a specific test
allow(ShopifyLiquidTestHelper).to receive(:get_snippet).with('product_price').and_return('On Sale: {{ product.price | money }}')
end
it 'shows the sale price' do
rendered = template.render('product' => product)
expect(rendered).to include('On Sale: $10.00')
end
end
end
### Customizing the Snippets Directory
If your snippets are located in a different directory, you can specify the path when initializing ShopifyLiquidTestHelper:
```ruby
ShopifyLiquidTestHelper.snippets_dir = 'path/to/your/snippets'
This allows you to organize your snippets in a way that best fits your project structure.
You can use both registered snippets (using ShopifyLiquidTestHelper.register_snippet
) and file-based snippets in the same test suite. ShopifyLiquidTestHelper will first check for registered snippets, and if not found, it will look for a matching file in the snippets directory.
RSpec.describe "Mixed snippet sources" do
before do
ShopifyLiquidTestHelper.register_snippet('inline_snippet', 'This is an inline snippet')
end
it "renders both registered and file-based snippets" do
template = """
{% render 'inline_snippet' %}
{% render 'product_card' %}
"""
assigns = {
'product' => {
'title' => 'Cool Product',
'price' => 2499
}
}
result = Liquid::Template.parse(template).render(assigns)
expect(result).to include('This is an inline snippet')
expect(result).to include('Cool Product')
expect(result).to include('Price: $24.99')
end
end
For more complex scenarios, you can create helper methods in your specs to simplify template rendering:
def render_template(template, assigns = {})
Liquid::Template.parse(template).render(assigns)
end
RSpec.describe "Complex template" do
it "renders a complex structure" do
template = """
{% render 'header' %}
{% for product in collection.products %}
{% render 'product_card' %}
{% endfor %}
{% render 'footer' %}
"""
assigns = {
'collection' => {
'products' => [
{ 'title' => 'Product 1', 'price' => 19.99 },
{ 'title' => 'Product 2', 'price' => 24.99 }
]
}
}
result = render_template(template, assigns)
expect(result).to include('Product 1')
expect(result).to include('Product 2')
expect(result).to include('19.99')
expect(result).to include('24.99')
end
end
This gem allows you to test your Shopify Liquid templates thoroughly, ensuring they render correctly with various inputs and scenarios.
Bug reports and pull requests are welcome on GitHub at https://github.com/giwa/shopify_liquid_test_helper.
The gem is available as open source under the terms of the MIT License.
FAQs
Unknown package
We found that shopify_liquid_test_helper demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.