From 6dbaed42dcbe9d679230c737d0e73ff360b202ae Mon Sep 17 00:00:00 2001 From: "Ronald A. Richardson" Date: Mon, 12 Oct 2026 22:17:09 +0800 Subject: [PATCH] fix(network): removing a store through addStores keeps its other networks addStores() deleted the requested stores with NetworkStore::where('store_uuid', $storeId)->delete(), with no network condition, so removing a store from one network removed it from every network it belonged to. The delete is now scoped to this network, as removeStores() already is. --- .../Http/Controllers/NetworkController.php | 4 +-- .../SmallControllerContractsTest.php | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/server/src/Http/Controllers/NetworkController.php b/server/src/Http/Controllers/NetworkController.php index 214c543b..0ba0eb9a 100644 --- a/server/src/Http/Controllers/NetworkController.php +++ b/server/src/Http/Controllers/NetworkController.php @@ -546,9 +546,9 @@ public function addStores(string $id, NetworkActionRequest $request) ); } - // delete each + // delete each from this network only; the store stays in its other networks foreach ($remove as $storeId) { - NetworkStore::where('store_uuid', $storeId)->delete(); + NetworkStore::where(['network_uuid' => $network->uuid, 'store_uuid' => $storeId])->delete(); } $this->forgetCachedResponses(); diff --git a/server/tests/Unit/Http/Controllers/SmallControllerContractsTest.php b/server/tests/Unit/Http/Controllers/SmallControllerContractsTest.php index ab947dd5..9bc643cc 100644 --- a/server/tests/Unit/Http/Controllers/SmallControllerContractsTest.php +++ b/server/tests/Unit/Http/Controllers/SmallControllerContractsTest.php @@ -1106,3 +1106,36 @@ public function get(string $key): ?string ->and($connection->table('network_stores')->where('store_uuid', 'store_new')->whereNull('deleted_at')->exists())->toBeTrue() ->and($connection->table('network_stores')->where('store_uuid', 'store_old')->whereNotNull('deleted_at')->exists())->toBeTrue(); }); + +test('network controller add stores removes a store from this network only', function () { + $connection = Model::getConnectionResolver()->connection('mysql'); + $schema = $connection->getSchemaBuilder(); + $schema->dropIfExists('networks'); + $schema->dropIfExists('network_stores'); + $schema->create('networks', function ($table) { + $table->string('uuid')->primary(); + $table->timestamp('deleted_at')->nullable(); + }); + $schema->create('network_stores', function ($table) { + $table->increments('id'); + $table->string('uuid')->nullable(); + $table->string('network_uuid'); + $table->string('store_uuid'); + $table->string('status')->default('active'); + $table->string('category_uuid')->nullable(); + $table->timestamps(); + $table->timestamp('deleted_at')->nullable(); + }); + $connection->table('networks')->insert([['uuid' => 'network_uuid'], ['uuid' => 'other_network_uuid']]); + $connection->table('network_stores')->insert([ + ['network_uuid' => 'network_uuid', 'store_uuid' => 'shared_store', 'created_at' => now(), 'updated_at' => now()], + ['network_uuid' => 'other_network_uuid', 'store_uuid' => 'shared_store', 'created_at' => now(), 'updated_at' => now()], + ]); + + $request = NetworkActionRequest::create('/network', 'POST', ['remove' => ['shared_store']]); + $response = (new NetworkController())->addStores('network_uuid', $request); + + expect($response->getData(true))->toBe(['status' => 'ok']) + ->and($connection->table('network_stores')->where('network_uuid', 'network_uuid')->value('deleted_at'))->not->toBeNull() + ->and($connection->table('network_stores')->where('network_uuid', 'other_network_uuid')->value('deleted_at'))->toBeNull(); +});