Skip to content

Commit

Permalink
[Plugin] Printify/Stripe integration (#1593)
Browse files Browse the repository at this point in the history
Living Doc: #1562

### Currency
Printify has two currency settings;

- catalog currency: This is the currency in which we can view different product prices in Printify's catalog.
- billing currency : This is the currency in which the shop owner will be charged by Printify.

We can find further details about it over Printify webpage. [LINK 1](https://help.printify.com/hc/en-us/articles/12203640151953-How-can-I-change-the-currency-on-Printify-), [LINK 2](https://help.printify.com/hc/en-us/articles/4483625794577-In-which-currency-can-I-sell-my-products-)

The Printify's products API does not provide any details regarding the `currency` being used. It only returns the price in figures.
<img width="1003" alt="Screenshot 2023-05-26 at 4 54 58 PM" src="https://github.com/restarone/violet_rails/assets/25191509/8a66cb17-3a2c-45ee-a309-62d0f118f783">

So, to overcome this barrier, we would have to manually set the `currency`, which is being used or has been setup in Printify platform, in Violet-Rails end. It will be saved under a `shop` api-resource's properties as below; [TEST-NET LINK](https://violet-test.net/api_namespaces/53/resources/709)

<img width="1212" alt="Screenshot 2023-05-26 at 5 12 42 PM" src="https://github.com/restarone/violet_rails/assets/25191509/f3a274e2-d071-4e0b-b7a2-5561251fa85c">

This `currency` information will be used to show the prices in products-listing, product-detail, cart and Stripe's checkout page.

**Note:** For now, we are using `USD` currency over the test-net.

## HOW TO RUN PRINTIFY PLUGIN INSTALER SCRIPT

#1557


### Export variables
 
- cd to violet_rails root

**Required Variables**
- `export SHOP_NAME="Restarone"`
- `export PRINTIFY_API_KEY="your api key"`

**Optional Variables**

- `export STRIPE_SECRET_KEY="your stripe secret key"`
- `export PRODUCTS_PAGE_SLUG="your products page url"`
- `export BUSINESS_NAME="your business name in printify account"`


### Run Installer

**In development**

- `docker-compose run --rm -e SHOP_NAME -e PRINTIFY_API_KEY -e STRIPE_SECRET_KEY -e PRODUCTS_PAGE_SLUG -e BUSINESS_NAME solutions_app rails r ./plugins/installers/printify_stripe_e_commerce.rb`

**In production**

- `rails r ./plugins/installers/printify_stripe_e_commerce.rb`

**In test server with dokku**
- `dokku run -e SHOP_NAME -e PRINTIFY_API_KEY -e STRIPE_SECRET_KEY -e PRODUCTS_PAGE_SLUG -e BUSINESS_NAME <APP_NAME> rails r ./plugins/installers/printify_stripe_e_commerce.rb`


### Variables

#### SHOP_NAME:

Name of the printify shop you want to sync to violet rails.

<img width="1179" alt="Screenshot 2023-05-30 at 5 30 19 PM" src="https://github.com/restarone/violet_rails/assets/50227291/db5e432a-932c-490c-83e6-9a106ab38895">

<br/>

#### PRINTIFY_API_KEY:
https://github.com/restarone/violet_rails/assets/50227291/22a2853d-1d99-4fc0-8dc8-2a81e31eb67e

<br/>

#### STRIPE_SECRET_KEY:

https://github.com/restarone/violet_rails/assets/50227291/1d92065c-c04c-4a45-a656-46017466429c

<br/>

#### BUSINESS_NAME:
Business name in your printify account.

https://github.com/restarone/violet_rails/assets/50227291/ce67a088-6412-4c02-8f68-1b2c8392e945

<br/>

#### PRODUCTS_PAGE_SLUG:
The url you want for your products list page. Default is 'products'

https://github.com/restarone/violet_rails/assets/50227291/125c9681-84ac-49c6-ab7e-8e6d784abcbe

<br/>

# STORE MANAGEMENT

### How to hide  product from the store:

<img width="1184" alt="Screenshot 2023-06-04 at 9 12 04 AM" src="https://github.com/restarone/violet_rails/assets/50227291/313a23f8-4aad-46ee-9a8c-d00578517682">

https://github.com/restarone/violet_rails/assets/50227291/6698994e-1d33-4073-bc6e-6d18cd88a92c


<br/>

### How to change who pays processing fees (Pass On to customer or Absorb Fees)

If pass_processing_fees_to_customer is set to true, the Convenience fee, ie.  the stripe processing fee (2.9% + $0.30) and stripe tax collection charge (0.5% if sales tax enabled) will be passed to customers

<img width="1140" alt="Screenshot 2023-06-04 at 9 33 51 AM" src="https://github.com/restarone/violet_rails/assets/50227291/0e592bc6-68a6-4862-91b3-15303a3d4f19">
<img width="1229" alt="Screenshot 2023-06-04 at 9 34 32 AM" src="https://github.com/restarone/violet_rails/assets/50227291/02205dba-2870-4614-92b9-dd0f79feb0ac">


https://github.com/restarone/violet_rails/assets/50227291/6b703d35-7b29-437f-b49e-43947cb4e9b1


<br/>

# DEBUGGING

If any feature is not working, please check `shop_logs` namespace. We store error logs there.

### Stuck in `publishing` state?

- Run sync_printify_products plugin

https://github.com/restarone/violet_rails/assets/50227291/08e24d9f-b816-4cb8-9aa5-376f1771e7f1



### How to check if Printify webhooks are created?

- On rails console

```
PRINTIFY_API_KEY="your api key"
```

```
PRINTIFY_HEADERS = {                                             
  "Content-Type" => 'application/json;charset=utf-8',
  "Authorization" => "Bearer #{PRINTIFY_API_KEY}" 
}

shop_id = ApiNamespace.friendly.find('shops').api_resources.first.properties['printify_shop_id']

response = HTTParty.get("https://api.printify.com/v1/shops/#{shop_id}/webhooks.json", headers: PRINTIFY_HEADERS)

JSON.parse(response.body)
```

Co-authored-by: Prashant <[email protected]>
  • Loading branch information
donrestarone and alis-khadka authored Aug 25, 2023
1 parent a69e609 commit 865914b
Show file tree
Hide file tree
Showing 38 changed files with 6,838 additions and 158 deletions.
5 changes: 4 additions & 1 deletion app/models/api_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,10 @@ def define_associations
def handle_associations
ActiveRecord::Base.transaction do
api_namespace.associations.each do |association|
associated_resources = ApiNamespace.friendly.find(association['namespace']).api_resources.jsonb_search(:properties, { "#{api_namespace.slug.underscore.singularize}_id" => self.id })
associated_namespace = ApiNamespace.find_by(slug: association['namespace'])
next if associated_namespace.nil?

associated_resources = associated_namespace.api_resources.jsonb_search(:properties, { "#{api_namespace.slug.underscore.singularize}_id" => self.id })
if association['dependent'] == 'destroy'
associated_resources.destroy_all
elsif association['dependent'] == 'restrict_with_error'
Expand Down
2 changes: 1 addition & 1 deletion app/models/external_api_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def start
validates :drive_every, inclusion: { in: ExternalApiClient::DRIVE_INTERVALS.keys.map(&:to_s) }, allow_blank: true, allow_nil: true
validates :model_definition, safe_executable: { skip_keywords: SKIPPABLE_KEYWORDS }

has_one :webhook_verification_method
has_one :webhook_verification_method, dependent: :destroy

accepts_nested_attributes_for :webhook_verification_method

Expand Down
4,000 changes: 4,000 additions & 0 deletions plugins/installers/printify_stripe_e_commerce.rb

Large diffs are not rendered by default.

205 changes: 102 additions & 103 deletions test/controllers/admin/comfy/api_namespaces_controller_test.rb

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion test/fixtures/api_namespaces.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,12 @@ namespace_with_slash:
<%= IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_namespaces/timesheet_request_namespaces.yml") %>
<%= IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_namespaces/transcript_parser_namespaces.yml") %>
<%= IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_namespaces/unique_string_aggregator_namespaces.yml") %>
<%= IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_namespaces/vacuum_job_namespaces.yml") %>
<%= IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_namespaces/vacuum_job_namespaces.yml") %>

# Printify Integration related fixtures
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_namespaces/orders.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_namespaces/order_cleanup_logs.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_namespaces/printify_accounts.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_namespaces/products.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_namespaces/shops.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_namespaces/shop_logs.yml")).result %>
6 changes: 6 additions & 0 deletions test/fixtures/api_resources.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,9 @@ resource_with_all_types_two:
# ERB is used to evaluate the embedded ruby code in following files
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_resources/time_tracker_resources.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_resources/timesheet_request_resources.yml")).result %>

# Printify Integration related fixtures
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_resources/orders_resources.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_resources/printify_account_resources.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_resources/products_resources.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/dependencies/api_resources/shops_resources.yml")).result %>
12 changes: 11 additions & 1 deletion test/fixtures/external_api_clients.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,14 @@ webhook_drive_strategy:
<%= IO.read(Rails.root.join "test/plugin_fixtures/sync_to_mailchimp.yml") %>
<%= IO.read(Rails.root.join "test/plugin_fixtures/transcript_parser_plugin.yml") %>
<%= IO.read(Rails.root.join "test/plugin_fixtures/unique_string_aggregator_plugin.yml") %>
<%= IO.read(Rails.root.join "test/plugin_fixtures/vacuum_job.yml") %>
<%= IO.read(Rails.root.join "test/plugin_fixtures/vacuum_job.yml") %>

# Printify Integration related fixtures
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/clean_unprocessed_orders_manually.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/clean_unprocessed_orders.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/create_order_and_stripe_chekout_session.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/fetch_printify_shipping_and_stripe_processing_fees.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/shops_detail.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/sync_printify_shops.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/sync_printify_products.yml")).result %>
<%= ERB.new(IO.read(Rails.root.join "test/plugin_fixtures/publish_succeed.yml")).result %>
3 changes: 3 additions & 0 deletions test/integration/mini_profiler_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ class Rack::MiniProfilerTest < ActionDispatch::IntegrationTest
assert response.headers['Content-Type'].include?('text/plain')
refute response.headers['Content-Type'].include?('text/html')

response_body = response.body
response_body = response_body.force_encoding('UTF-8')

assert_match 'ObjectSpace stats:', response.body
assert_match '1000 Largest strings:', response.body
end
Expand Down
101 changes: 88 additions & 13 deletions test/models/api_namespace_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -370,27 +370,102 @@ class ApiNamespaceTest < ActiveSupport::TestCase
end

test 'has_many: should add foreign key and belongs_to association to child namespace' do
namespace_1 = ApiNamespace.create(name: 'products', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'shops', version: 1, properties: { name: '' }, associations: [{type: 'has_many', namespace: 'products'}]);
namespace_1 = ApiNamespace.create(name: 'items', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'stall', version: 1, properties: { name: '' }, associations: [{type: 'has_many', namespace: 'items'}]);

assert namespace_1.reload.properties.key?('shop_id')
assert_includes namespace_1.associations, { "type" => 'belongs_to', "namespace" => 'shops' }
assert namespace_1.reload.properties.key?('stall_id')
assert_includes namespace_1.associations, { "type" => 'belongs_to', "namespace" => 'stall' }
end

test 'has_one: should add foreign key and belongs_to association to child namespace' do
namespace_1 = ApiNamespace.create(name: 'products', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'shops', version: 1, properties: { name: '' }, associations: [{type: 'has_one', namespace: 'products'}]);
namespace_1 = ApiNamespace.create(name: 'items', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'stall', version: 1, properties: { name: '' }, associations: [{type: 'has_one', namespace: 'items'}]);

assert namespace_1.reload.properties.key?('shop_id')
assert_includes namespace_1.reload.associations, { "type" => 'belongs_to', "namespace" => 'shops' }
assert namespace_1.reload.properties.key?('stall_id')
assert_includes namespace_1.reload.associations, { "type" => 'belongs_to', "namespace" => 'stall' }
end

test 'belongs_to: should add foreign key and has_many association to parent namespace' do
namespace_2 = ApiNamespace.create(name: 'shops', version: 1, properties: { name: '' });
namespace_1 = ApiNamespace.create(name: 'products', version: 1, properties: { title: '' }, associations: [{type: 'belongs_to', namespace: 'shops'}]);
namespace_2 = ApiNamespace.create(name: 'stall', version: 1, properties: { name: '' });
namespace_1 = ApiNamespace.create(name: 'items', version: 1, properties: { title: '' }, associations: [{type: 'belongs_to', namespace: 'stall'}]);

assert namespace_1.reload.properties.key?('shop_id')
assert_includes namespace_1.reload.associations, { "type" => 'belongs_to', "namespace" => 'shops' }
assert_includes namespace_2.reload.associations, { "type" => 'has_many', "namespace" => 'products' }
assert namespace_1.reload.properties.key?('stall_id')
assert_includes namespace_1.reload.associations, { "type" => 'belongs_to', "namespace" => 'stall' }
assert_includes namespace_2.reload.associations, { "type" => 'has_many', "namespace" => 'items' }
end

test 'should destroy api_namespace and dependent associations of resources if dependent set to destroy' do
namespace_1 = ApiNamespace.create(name: 'items', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'stall', version: 1, properties: { name: '' }, associations: [{type: 'has_many', namespace: 'items', dependent: 'destroy'}]);

namespace_1.reload
namespace_2.reload

stall_1 = namespace_2.api_resources.create(properties: {name: 'Restarone'})

product_1 = namespace_1.api_resources.create(properties: {title: 'T-shirt', stall_id: stall_1.id})
product_2 = namespace_1.api_resources.create(properties: {title: 'Jeans', stall_id: stall_1.id})

assert_difference "namespace_1.reload.api_resources.count", -2 do
assert_difference "ApiNamespace.count", -1 do
namespace_2.destroy
end
end
end

test 'should destroy api_namespace but leave dependent associations of resources as is if dependent set to blank' do
namespace_1 = ApiNamespace.create(name: 'items', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'stall', version: 1, properties: { name: '' }, associations: [{type: 'has_many', namespace: 'items'}]);

namespace_1.reload
namespace_2.reload

stall_1 = namespace_2.api_resources.create(properties: {name: 'Restarone'})

product_1 = namespace_1.api_resources.create(properties: {title: 'T-shirt', stall_id: stall_1.id})
product_2 = namespace_1.api_resources.create(properties: {title: 'Jeans', stall_id: stall_1.id})

assert_no_difference "namespace_1.reload.api_resources.count" do
assert_difference "ApiResource.count", -1 do
assert_difference "ApiNamespace.count", -1 do
namespace_2.destroy
end
end
end
end

test 'should not destroy api_namespace dependent set to restrict_with_error and dependent api resources exist' do
namespace_1 = ApiNamespace.create(name: 'items', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'stall', version: 1, properties: { name: '' }, associations: [{type: 'has_many', namespace: 'items', dependent: 'restrict_with_error'}]);

namespace_1.reload
namespace_2.reload

stall = namespace_2.api_resources.create(properties: {name: 'Restarone'})

item_1 = namespace_1.api_resources.create(properties: {title: 'T-shirt', stall_id: stall.id})
item_2 = namespace_1.api_resources.create(properties: {title: 'Jeans', stall_id: stall.id})

assert_no_difference "namespace_1.reload.api_resources.count" do
assert_no_difference "ApiNamespace.count" do
namespace_2.destroy
end
end
end

test 'should destroy api_namespace dependent set to restrict_with_error but dependent api resources do not exist' do
namespace_1 = ApiNamespace.create(name: 'items', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'stall', version: 1, properties: { name: '' }, associations: [{type: 'has_many', namespace: 'items', dependent: 'restrict_with_error'}]);

namespace_1.reload
namespace_2.reload

stall_1 = namespace_2.api_resources.create(properties: {name: 'Restarone'})

assert_difference "ApiResource.count", -1 do
assert_difference "ApiNamespace.count", -1 do
namespace_2.destroy
end
end
end
end
72 changes: 36 additions & 36 deletions test/models/api_resource_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -202,97 +202,97 @@ class ApiResourceTest < ActiveSupport::TestCase
end

test 'should define associations: has_many' do
namespace_1 = ApiNamespace.create(name: 'products', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'shops', version: 1, properties: { name: '' }, associations: [{type: 'has_many', namespace: 'products'}]);
namespace_1 = ApiNamespace.create(name: 'items', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'stall', version: 1, properties: { name: '' }, associations: [{type: 'has_many', namespace: 'items'}]);

namespace_1.reload
namespace_2.reload

shop_1 = namespace_2.api_resources.create(properties: {name: 'Restarone'})
shop_2 = namespace_2.api_resources.create(properties: {name: 'Engineering'})
stall_1 = namespace_2.api_resources.create(properties: {name: 'Restarone'})
stall_2 = namespace_2.api_resources.create(properties: {name: 'Engineering'})

product_1 = namespace_1.api_resources.create(properties: {title: 'T-shirt', shop_id: shop_1.id})
product_2 = namespace_1.api_resources.create(properties: {title: 'Jeans', shop_id: shop_1.id})
item_1 = namespace_1.api_resources.create(properties: {title: 'T-shirt', stall_id: stall_1.id})
item_2 = namespace_1.api_resources.create(properties: {title: 'Jeans', stall_id: stall_1.id})

assert_equal [product_1.id, product_2.id], shop_1.products.pluck(:id)
assert_equal [], shop_2.products.pluck(:id)
assert_equal [item_1.id, item_2.id], stall_1.items.pluck(:id)
assert_equal [], stall_2.items.pluck(:id)

assert_equal shop_1, product_1.shop
assert_equal shop_1, product_2.shop
assert_equal stall_1, item_1.stall
assert_equal stall_1, item_2.stall
end

test 'should define associations: has_one' do
namespace_1 = ApiNamespace.create(name: 'products', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'shops', version: 1, properties: { name: '' }, associations: [{type: 'has_one', namespace: 'products'}]);
namespace_1 = ApiNamespace.create(name: 'items', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'stall', version: 1, properties: { name: '' }, associations: [{type: 'has_one', namespace: 'items'}]);

namespace_1.reload
namespace_2.reload

shop_1 = namespace_2.api_resources.create(properties: {name: 'Restarone'})
shop_2 = namespace_2.api_resources.create(properties: {name: 'Engineering'})
stall_1 = namespace_2.api_resources.create(properties: {name: 'Restarone'})
stall_2 = namespace_2.api_resources.create(properties: {name: 'Engineering'})

product_1 = namespace_1.api_resources.create(properties: {title: 'T-shirt', shop_id: shop_1.id})
product_2 = namespace_1.api_resources.create(properties: {title: 'Jeans', shop_id: shop_1.id})
item_1 = namespace_1.api_resources.create(properties: {title: 'T-shirt', stall_id: stall_1.id})
item_2 = namespace_1.api_resources.create(properties: {title: 'Jeans', stall_id: stall_1.id})

assert_equal product_2, shop_1.product
assert_equal nil, shop_2.product
assert_equal item_2, stall_1.item
assert_equal nil, stall_2.item

assert_equal shop_1, product_1.shop
assert_equal stall_1, item_1.stall
end

test ' should destroy dependent associations when dependent is set to destroy' do
namespace_1 = ApiNamespace.create(name: 'products', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'shops', version: 1, properties: { name: '' }, associations: [{type: 'has_many', namespace: 'products', dependent: 'destroy'}]);
namespace_1 = ApiNamespace.create(name: 'items', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'stall', version: 1, properties: { name: '' }, associations: [{type: 'has_many', namespace: 'items', dependent: 'destroy'}]);

namespace_1.reload
namespace_2.reload

shop_1 = namespace_2.api_resources.create(properties: {name: 'Restarone'})
stall_1 = namespace_2.api_resources.create(properties: {name: 'Restarone'})

product_1 = namespace_1.api_resources.create(properties: {title: 'T-shirt', shop_id: shop_1.id})
product_2 = namespace_1.api_resources.create(properties: {title: 'Jeans', shop_id: shop_1.id})
item_1 = namespace_1.api_resources.create(properties: {title: 'T-shirt', stall_id: stall_1.id})
item_2 = namespace_1.api_resources.create(properties: {title: 'Jeans', stall_id: stall_1.id})

assert_difference "namespace_2.reload.api_resources.count", -1 do
assert_difference "namespace_1.reload.api_resources.count", -2 do
shop_1.destroy
stall_1.destroy
end
end
end

test 'should not allow destroy if dependent association exist when dependent is set to restrict_with_error' do
namespace_1 = ApiNamespace.create(name: 'products', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'shops', version: 1, properties: { name: '' }, associations: [{type: 'has_one', namespace: 'products', dependent: 'restrict_with_error'}]);
namespace_1 = ApiNamespace.create(name: 'items', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'stall', version: 1, properties: { name: '' }, associations: [{type: 'has_one', namespace: 'items', dependent: 'restrict_with_error'}]);

namespace_1.reload
namespace_2.reload

shop_1 = namespace_2.api_resources.create(properties: {name: 'Restarone'})
stall_1 = namespace_2.api_resources.create(properties: {name: 'Restarone'})

product_1 = namespace_1.api_resources.create(properties: {title: 'T-shirt', shop_id: shop_1.id})
item_1 = namespace_1.api_resources.create(properties: {title: 'T-shirt', stall_id: stall_1.id})

assert_no_difference "namespace_2.reload.api_resources.count" do
assert_no_difference "namespace_1.reload.api_resources.count" do
shop_1.destroy
stall_1.destroy
end
end

assert_equal ["Cannot delete record because dependent products exist"], shop_1.reload.errors.full_messages
assert_equal ["Cannot delete record because dependent items exist"], stall_1.reload.errors.full_messages
end

test 'should not remove dependent association when dependent is not set' do
namespace_1 = ApiNamespace.create(name: 'products', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'shops', version: 1, properties: { name: '' }, associations: [{type: 'has_many', namespace: 'products'}]);
namespace_1 = ApiNamespace.create(name: 'items', version: 1, properties: { title: '' });
namespace_2 = ApiNamespace.create(name: 'stall', version: 1, properties: { name: '' }, associations: [{type: 'has_many', namespace: 'items'}]);

namespace_1.reload
namespace_2.reload

shop_1 = namespace_2.api_resources.create(properties: {name: 'Restarone'})
stall_1 = namespace_2.api_resources.create(properties: {name: 'Restarone'})

product_1 = namespace_1.api_resources.create(properties: {title: 'T-shirt', shop_id: shop_1.id})
item_1 = namespace_1.api_resources.create(properties: {title: 'T-shirt', stall_id: stall_1.id})

assert_difference "namespace_2.reload.api_resources.count", -1 do
assert_no_difference "namespace_1.reload.api_resources.count" do
shop_1.destroy
stall_1.destroy
end
end
end
Expand Down
Loading

0 comments on commit 865914b

Please sign in to comment.