feat: add Products context with provider integration (Phase 1)
Implement the schema foundation for syncing products from POD providers like Printify. This includes encrypted credential storage, product/variant schemas, and an Oban worker for background sync. New modules: - Vault: AES-256-GCM encryption for API keys - Products context: CRUD and sync operations for products - Provider behaviour: abstraction for POD provider implementations - ProductSyncWorker: Oban job for async product sync Schemas: ProviderConnection, Product, ProductImage, ProductVariant Also reorganizes Printify client to lib/simpleshop_theme/clients/ and mockup generator to lib/simpleshop_theme/mockups/ for better structure. 134 tests added covering all new functionality. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
69
test/simpleshop_theme/sync/product_sync_worker_test.exs
Normal file
69
test/simpleshop_theme/sync/product_sync_worker_test.exs
Normal file
@@ -0,0 +1,69 @@
|
||||
defmodule SimpleshopTheme.Sync.ProductSyncWorkerTest do
|
||||
use SimpleshopTheme.DataCase, async: false
|
||||
use Oban.Testing, repo: SimpleshopTheme.Repo
|
||||
|
||||
alias SimpleshopTheme.Sync.ProductSyncWorker
|
||||
|
||||
import SimpleshopTheme.ProductsFixtures
|
||||
|
||||
describe "perform/1" do
|
||||
test "cancels for missing connection" do
|
||||
fake_id = Ecto.UUID.generate()
|
||||
|
||||
assert {:cancel, :connection_not_found} =
|
||||
perform_job(ProductSyncWorker, %{provider_connection_id: fake_id})
|
||||
end
|
||||
|
||||
test "cancels for disabled connection" do
|
||||
conn = provider_connection_fixture(%{enabled: false})
|
||||
|
||||
assert {:cancel, :connection_disabled} =
|
||||
perform_job(ProductSyncWorker, %{provider_connection_id: conn.id})
|
||||
end
|
||||
end
|
||||
|
||||
describe "enqueue/1" do
|
||||
test "creates a job with correct args" do
|
||||
# Temporarily switch to manual mode to avoid inline execution
|
||||
Oban.Testing.with_testing_mode(:manual, fn ->
|
||||
conn = provider_connection_fixture()
|
||||
|
||||
assert {:ok, %Oban.Job{} = job} = ProductSyncWorker.enqueue(conn.id)
|
||||
# In manual mode, args use atom keys
|
||||
assert job.args == %{provider_connection_id: conn.id}
|
||||
assert job.queue == "sync"
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
describe "enqueue/2 with delay" do
|
||||
test "schedules a job for later" do
|
||||
Oban.Testing.with_testing_mode(:manual, fn ->
|
||||
conn = provider_connection_fixture()
|
||||
|
||||
assert {:ok, %Oban.Job{} = job} = ProductSyncWorker.enqueue(conn.id, 60)
|
||||
# In manual mode, args use atom keys
|
||||
assert job.args == %{provider_connection_id: conn.id}
|
||||
|
||||
# Job should be scheduled in the future
|
||||
assert DateTime.compare(job.scheduled_at, DateTime.utc_now()) == :gt
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
describe "job creation" do
|
||||
test "new/1 creates job changeset with provider_connection_id" do
|
||||
changeset = ProductSyncWorker.new(%{provider_connection_id: "test-id"})
|
||||
|
||||
assert changeset.changes.args == %{provider_connection_id: "test-id"}
|
||||
assert changeset.changes.queue == "sync"
|
||||
end
|
||||
|
||||
test "new/2 with scheduled_at creates scheduled job" do
|
||||
future = DateTime.add(DateTime.utc_now(), 60, :second)
|
||||
changeset = ProductSyncWorker.new(%{provider_connection_id: "test-id"}, scheduled_at: future)
|
||||
|
||||
assert changeset.changes.scheduled_at == future
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user