Files
jouwdriedee/tests/Feature/MakerWorldImporterTest.php
T

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'));
}
}