219 lines
7.5 KiB
PHP
219 lines
7.5 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Category;
|
|
use App\Models\Product;
|
|
use App\Models\Setting;
|
|
use App\Models\User;
|
|
use App\Services\MakerWorldService;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Tests\TestCase;
|
|
|
|
class MakerWorldImporterTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$admin = User::create([
|
|
'name' => 'Admin Jouwdriedee',
|
|
'email' => 'info@jouwdriedee.nl',
|
|
'password' => bcrypt('Jw3D!x9#QmK7$vR2'),
|
|
'is_admin' => true,
|
|
]);
|
|
|
|
$this->actingAs($admin);
|
|
}
|
|
|
|
protected function fakeMakerWorldApi(): void
|
|
{
|
|
Http::fake([
|
|
'https://api.bambulab.com/v1/design-service/design/55866' => Http::response([
|
|
'id' => 55866,
|
|
'title' => 'Test Calibration Cube',
|
|
'summary' => '<p>A test calibration cube for Bambu printers.</p>',
|
|
'coverUrl' => 'https://makerworld.bblmw.com/cover.png',
|
|
'license' => 'Creative Commons',
|
|
'designCreator' => [
|
|
'name' => 'DesignerBob',
|
|
'handle' => 'designer_bob',
|
|
],
|
|
'instances' => [
|
|
[
|
|
'title' => 'Standard Profile',
|
|
'weight' => 25.4,
|
|
'prediction' => 3600, // 1 hour
|
|
],
|
|
],
|
|
'designExtension' => [
|
|
'design_pictures' => [
|
|
['url' => 'https://makerworld.bblmw.com/photo1.png'],
|
|
],
|
|
],
|
|
], 200),
|
|
'https://api.bambulab.com/v1/design-service/contest/list*' => Http::response([
|
|
'total' => 1,
|
|
'hits' => [
|
|
[
|
|
'id' => 10,
|
|
'contestName' => 'Featured Contest',
|
|
'designs' => [
|
|
[
|
|
'id' => 55866,
|
|
'title' => 'Test Calibration Cube',
|
|
'cover' => 'https://makerworld.bblmw.com/cover.png',
|
|
'designCreator' => ['name' => 'DesignerBob'],
|
|
],
|
|
],
|
|
],
|
|
],
|
|
], 200),
|
|
'https://api.bambulab.com/v1/user-service/user/login' => Http::response([
|
|
'accessToken' => 'fake_bearer_token_12345',
|
|
], 200),
|
|
'https://api.bambulab.com/v1/design-user-service/my/preference' => Http::response([
|
|
'uid' => 99999,
|
|
'name' => 'Test Bambu User',
|
|
'account' => 'test@jouwdriedee.nl',
|
|
], 200),
|
|
]);
|
|
}
|
|
|
|
public function test_it_correctly_parses_makerworld_urls_and_ids(): void
|
|
{
|
|
$service = new MakerWorldService;
|
|
|
|
$this->assertSame(55866, $service->parseModelId('55866'));
|
|
$this->assertSame(55866, $service->parseModelId('https://makerworld.com/nl/models/55866#profileId-60000'));
|
|
$this->assertSame(12345, $service->parseModelId('https://makerworld.com/en/models/12345?keyword=vase'));
|
|
$this->assertSame(789, $service->parseModelId('makerworld.com/models/789'));
|
|
$this->assertNull($service->parseModelId('invalid-url-without-id'));
|
|
}
|
|
|
|
public function test_it_manages_makerworld_access_token_in_settings(): void
|
|
{
|
|
$this->fakeMakerWorldApi();
|
|
$service = new MakerWorldService;
|
|
|
|
$this->assertFalse($service->isAuthenticated());
|
|
|
|
$service->setAccessToken('fake_bearer_token_12345');
|
|
$this->assertTrue($service->isAuthenticated());
|
|
$this->assertSame('fake_bearer_token_12345', $service->getAccessToken());
|
|
|
|
$service->logout();
|
|
$this->assertFalse($service->isAuthenticated());
|
|
$this->assertNull($service->getAccessToken());
|
|
}
|
|
|
|
public function test_admin_makerworld_dashboard_loads_successfully(): void
|
|
{
|
|
$this->fakeMakerWorldApi();
|
|
|
|
$response = $this->get(route('admin.makerworld.index', ['tab' => 'community']));
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertSee('MakerWorld Product Importer');
|
|
$response->assertSee('Test Calibration Cube');
|
|
}
|
|
|
|
public function test_it_provides_json_preview_for_a_model(): void
|
|
{
|
|
$this->fakeMakerWorldApi();
|
|
|
|
$response = $this->getJson(route('admin.makerworld.preview', [
|
|
'query' => 'https://makerworld.com/nl/models/55866',
|
|
]));
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonPath('model.makerworld_id', 55866);
|
|
$response->assertJsonPath('model.name', 'Test Calibration Cube');
|
|
$response->assertJsonPath('model.makerworld_author', 'DesignerBob');
|
|
$response->assertJsonPath('model.weight_grams', 25);
|
|
$response->assertJsonPath('model.print_time_hours', 1);
|
|
}
|
|
|
|
public function test_it_can_import_a_model_into_the_shop(): void
|
|
{
|
|
$this->fakeMakerWorldApi();
|
|
|
|
$category = Category::create([
|
|
'name' => 'Tech & Gadgets',
|
|
'slug' => 'tech-gadgets',
|
|
]);
|
|
|
|
$response = $this->post(route('admin.makerworld.import'), [
|
|
'makerworld_id' => 55866,
|
|
'category_id' => $category->id,
|
|
'custom_price' => 19.95,
|
|
'custom_name' => 'Gekalibreerde Kubus Jouwdriedee',
|
|
'is_active' => 1,
|
|
]);
|
|
|
|
$response->assertRedirect();
|
|
$response->assertSessionHas('success');
|
|
|
|
$this->assertDatabaseHas('products', [
|
|
'makerworld_id' => 55866,
|
|
'name' => 'Gekalibreerde Kubus Jouwdriedee',
|
|
'slug' => 'gekalibreerde-kubus-jouwdriedee',
|
|
'category_id' => $category->id,
|
|
'base_price' => 19.95,
|
|
'makerworld_author' => 'DesignerBob',
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$product = Product::where('makerworld_id', 55866)->first();
|
|
$this->assertNotNull($product);
|
|
|
|
// Product should be visible on webshop show route
|
|
$detailResponse = $this->get(route('product.show', $product->slug));
|
|
$detailResponse->assertStatus(200);
|
|
$detailResponse->assertSee('Gekalibreerde Kubus Jouwdriedee');
|
|
}
|
|
|
|
public function test_it_can_batch_import_multiple_models(): void
|
|
{
|
|
$this->fakeMakerWorldApi();
|
|
|
|
$category = Category::create([
|
|
'name' => 'Tools',
|
|
'slug' => 'tools',
|
|
]);
|
|
|
|
$response = $this->post(route('admin.makerworld.batch-import'), [
|
|
'ids' => [55866],
|
|
'category_id' => $category->id,
|
|
'is_active' => 1,
|
|
]);
|
|
|
|
$response->assertRedirect();
|
|
$response->assertSessionHas('success');
|
|
|
|
$this->assertDatabaseHas('products', [
|
|
'makerworld_id' => 55866,
|
|
'category_id' => $category->id,
|
|
]);
|
|
}
|
|
|
|
public function test_it_can_save_token_and_disconnect(): void
|
|
{
|
|
$this->fakeMakerWorldApi();
|
|
|
|
$saveResponse = $this->post(route('admin.makerworld.token'), [
|
|
'token' => 'my_secret_token_12345678',
|
|
]);
|
|
|
|
$saveResponse->assertRedirect();
|
|
$this->assertSame('my_secret_token_12345678', Setting::get('makerworld_token'));
|
|
|
|
$disconnectResponse = $this->post(route('admin.makerworld.disconnect'));
|
|
$disconnectResponse->assertRedirect();
|
|
$this->assertNull(Setting::get('makerworld_token'));
|
|
}
|
|
}
|