admin = User::create([ 'name' => 'Admin Jouwdriedee', 'email' => 'info@jouwdriedee.nl', 'password' => bcrypt('Jw3D!x9#QmK7$vR2'), 'is_admin' => true, ]); $this->category = Category::create([ 'name' => 'Fidget Toys & Gadgets', 'slug' => 'fidget-toys', 'description' => 'Leuke fidget toys', 'is_featured' => true, ]); $this->actingAs($this->admin); } protected function fakeCollectionHttp(): void { Http::fake([ 'https://api.bambulab.com/v1/design-service/favorites/9205051' => Http::response([ 'id' => 9205051, 'title' => 'Top Populaire Modellen', 'description' => 'Mijn favoriete collectie', 'cover' => 'https://makerworld.bblmw.com/collection_cover.jpg', 'designCnt' => 2, 'designs' => [ [ 'id' => 1740435, 'title' => 'Glow in the dark Fidget Slug', 'cover' => 'https://makerworld.bblmw.com/slug_cover.jpg', 'summary' => '

Super flexibele fidget slug.

', 'designCreator' => [ 'name' => 'MakerBob', 'handle' => 'maker_bob', ], 'instances' => [ [ 'title' => '0.4mm High Speed Profile', 'printerName' => 'Bambu Lab P1S', 'nozzleDiameter' => '0.4 mm', 'weight' => 75.5, 'prediction' => 7200, // 2 hours 'filamentConfig' => ['PLA Silk Rainbow'], ], ], 'designExtension' => [ 'design_pictures' => [ ['url' => 'https://makerworld.bblmw.com/slug_photo_1.jpg'], ['url' => 'https://makerworld.bblmw.com/slug_photo_2.jpg'], ], 'real_pictures' => [ ['url' => 'https://makerworld.bblmw.com/slug_real_1.jpg'], ], ], ], ], ], 200), 'https://api.bambulab.com/v1/design-service/design/1740435' => Http::response([ 'id' => 1740435, 'title' => 'Glow in the dark Fidget Slug', 'coverUrl' => 'https://makerworld.bblmw.com/slug_cover.jpg', 'summary' => '

Super flexibele fidget slug.

', 'license' => 'CC-BY-SA', 'designCreator' => [ 'name' => 'MakerBob', 'handle' => 'maker_bob', ], 'instances' => [ [ 'title' => '0.4mm High Speed Profile', 'printerName' => 'Bambu Lab P1S', 'nozzleDiameter' => '0.4 mm', 'weight' => 75.5, 'prediction' => 7200, ], ], 'designExtension' => [ 'design_pictures' => [ ['url' => 'https://makerworld.bblmw.com/slug_photo_1.jpg'], ['url' => 'https://makerworld.bblmw.com/slug_photo_2.jpg'], ], ], ], 200), ]); } public function test_admin_can_add_makerworld_collection(): void { $this->fakeCollectionHttp(); $response = $this->post(route('admin.makerworld.collections.add'), [ 'collection_input' => 'https://makerworld.com/nl/collections/9205051', 'is_active_sync' => true, 'sync_now' => true, ]); $response->assertRedirect(route('admin.makerworld.index', ['tab' => 'collections'])); $response->assertSessionHas('success'); $this->assertDatabaseHas('makerworld_collections', [ 'makerworld_collection_id' => '9205051', 'name' => 'Top Populaire Modellen', 'is_active_sync' => true, ]); } public function test_collection_sync_creates_draft_products_with_photos_and_print_info(): void { $this->fakeCollectionHttp(); $collection = MakerWorldCollection::create([ 'makerworld_collection_id' => '9205051', 'name' => 'Top Populaire Modellen', 'is_active_sync' => true, 'sync_interval_minutes' => 10, ]); /** @var MakerWorldService $service */ $service = app(MakerWorldService::class); $result = $service->syncCollection($collection); $this->assertEquals(1, $result['imported']); $this->assertNull($result['error']); // Assert database record $product = Product::where('makerworld_id', 1740435)->first(); $this->assertNotNull($product); $this->assertEquals('draft', $product->status); $this->assertFalse($product->is_active); $this->assertEquals($collection->id, $product->makerworld_collection_id); $this->assertEquals('https://makerworld.bblmw.com/slug_cover.jpg', $product->image_url); $this->assertNotEmpty($product->gallery_images); $this->assertEquals(76, $product->weight_grams); $this->assertEquals(2.0, $product->print_time_hours); $this->assertNotNull($product->print_info); $this->assertEquals('0.4 mm', $product->print_info['nozzle']); // Assert product is NOT visible on customer storefront $shopResponse = $this->get(route('catalog')); $shopResponse->assertOk(); $shopResponse->assertDontSee('Glow in the dark Fidget Slug'); } public function test_artisan_sync_makerworld_collections_command(): void { $this->fakeCollectionHttp(); $collection = MakerWorldCollection::create([ 'makerworld_collection_id' => '9205051', 'name' => 'Top Populaire Modellen', 'is_active_sync' => true, 'sync_interval_minutes' => 10, ]); $exitCode = Artisan::call('app:sync-makerworld-collections'); $this->assertEquals(0, $exitCode); $this->assertDatabaseHas('products', [ 'makerworld_id' => 1740435, 'status' => 'draft', 'makerworld_collection_id' => $collection->id, ]); } public function test_admin_can_publish_staged_product_in_artikel_beheer(): void { $product = Product::create([ 'makerworld_id' => 1740435, 'name' => 'Staged Fidget Model', 'slug' => 'staged-fidget-model', 'short_description' => 'Korte omschrijving', 'description' => 'Volledige omschrijving', 'base_price' => 12.50, 'status' => 'draft', 'is_active' => false, 'category_id' => $this->category->id, ]); $response = $this->post(route('admin.makerworld.staging.publish', $product), [ 'name' => 'Gecureerde Fidget Slug Deluxe', 'category_id' => $this->category->id, 'base_price' => 19.95, 'is_featured' => true, ]); $response->assertRedirect(); $response->assertSessionHas('success'); $product->refresh(); $this->assertEquals('published', $product->status); $this->assertTrue($product->is_active); $this->assertEquals(19.95, $product->base_price); $this->assertEquals('Gecureerde Fidget Slug Deluxe', $product->name); // Verify it is now visible in the customer catalog $catalogResp = $this->get(route('catalog')); $catalogResp->assertOk(); $catalogResp->assertSee('Gecureerde Fidget Slug Deluxe'); } public function test_admin_can_bulk_publish_staged_products(): void { $p1 = Product::create([ 'makerworld_id' => 101, 'name' => 'Concept 1', 'slug' => 'concept-1', 'description' => 'Test 1', 'base_price' => 10.00, 'status' => 'draft', 'is_active' => false, ]); $p2 = Product::create([ 'makerworld_id' => 102, 'name' => 'Concept 2', 'slug' => 'concept-2', 'description' => 'Test 2', 'base_price' => 15.00, 'status' => 'draft', 'is_active' => false, ]); $response = $this->post(route('admin.makerworld.staging.bulk-publish'), [ 'product_ids' => [$p1->id, $p2->id], 'category_id' => $this->category->id, 'custom_markup' => 20, // 20% markup ]); $response->assertRedirect(); $response->assertSessionHas('success'); $p1->refresh(); $p2->refresh(); $this->assertEquals('published', $p1->status); $this->assertTrue($p1->is_active); $this->assertEquals(12.00, $p1->base_price); // 10 + 20% $this->assertEquals('published', $p2->status); $this->assertTrue($p2->is_active); $this->assertEquals(18.00, $p2->base_price); // 15 + 20% } public function test_admin_can_toggle_sync_and_delete_collection(): void { $collection = MakerWorldCollection::create([ 'makerworld_collection_id' => '8888', 'name' => 'Test Collection', 'is_active_sync' => true, ]); // Toggle sync $toggleResp = $this->post(route('admin.makerworld.collections.toggle', $collection)); $toggleResp->assertRedirect(); $collection->refresh(); $this->assertFalse($collection->is_active_sync); // Delete collection $deleteResp = $this->delete(route('admin.makerworld.collections.delete', $collection)); $deleteResp->assertRedirect(); $this->assertDatabaseMissing('makerworld_collections', ['id' => $collection->id]); } }