getJson('/api/admin/telegram/tariffs'); $r->assertStatus(200); $tariffs = $r->json('tariffs'); expect($tariffs)->toHaveCount(3); expect(collect($tariffs)->pluck('media_kind')->all()) ->toBe([Campaign::MEDIA_NONE, Campaign::MEDIA_IMAGE, Campaign::MEDIA_VIDEO]); expect($tariffs[0]['price_rub'])->toBe('0.480'); expect($tariffs[2]['price_rub'])->toBe('0.816'); }); test('PUT /api/admin/telegram/tariffs заменяет себестоимость всех трёх видов', function () { $r = $this->putJson('/api/admin/telegram/tariffs', [ 'rows' => [ ['media_kind' => Campaign::MEDIA_NONE, 'price_rub' => '0.500'], ['media_kind' => Campaign::MEDIA_IMAGE, 'price_rub' => '0.750'], ['media_kind' => Campaign::MEDIA_VIDEO, 'price_rub' => '0.900'], ], ]); $r->assertStatus(200); expect(Tariff::count())->toBe(3) ->and(Tariff::where('media_kind', Campaign::MEDIA_NONE)->first()->price_rub)->toBe('0.500') ->and(Tariff::where('media_kind', Campaign::MEDIA_VIDEO)->first()->price_rub)->toBe('0.900'); expect(collect($r->json('tariffs'))->pluck('media_kind')->all()) ->toBe([Campaign::MEDIA_NONE, Campaign::MEDIA_IMAGE, Campaign::MEDIA_VIDEO]); }); test('PUT /api/admin/telegram/tariffs с нулевой ценой → 422', function () { $this->putJson('/api/admin/telegram/tariffs', [ 'rows' => [ ['media_kind' => Campaign::MEDIA_NONE, 'price_rub' => '0.000'], ['media_kind' => Campaign::MEDIA_IMAGE, 'price_rub' => '0.750'], ['media_kind' => Campaign::MEDIA_VIDEO, 'price_rub' => '0.900'], ], ])->assertStatus(422); // Исходные строки не тронуты. expect(Tariff::count())->toBe(3) ->and(Tariff::where('media_kind', Campaign::MEDIA_NONE)->first()->price_rub)->toBe('0.480'); }); /** * 🔴 Главное, что охраняет эта ручка. Прежняя принимала произвольный список ступеней: * владелец мог сохранить сетку без нужной строки, и расчёт упал бы уже в бою — в момент * списания денег с клиента. Теперь набор строго три вида, каждый ровно один раз. */ test('PUT /api/admin/telegram/tariffs без одного вида медиа → 422, старое сохранено', function () { $this->putJson('/api/admin/telegram/tariffs', [ 'rows' => [ ['media_kind' => Campaign::MEDIA_NONE, 'price_rub' => '0.500'], ['media_kind' => Campaign::MEDIA_IMAGE, 'price_rub' => '0.750'], ], ])->assertStatus(422); expect(Tariff::count())->toBe(3) ->and(Tariff::where('media_kind', Campaign::MEDIA_NONE)->first()->price_rub)->toBe('0.480'); }); test('PUT /api/admin/telegram/tariffs с задвоенным видом → 422', function () { $this->putJson('/api/admin/telegram/tariffs', [ 'rows' => [ ['media_kind' => Campaign::MEDIA_NONE, 'price_rub' => '0.500'], ['media_kind' => Campaign::MEDIA_NONE, 'price_rub' => '0.600'], ['media_kind' => Campaign::MEDIA_VIDEO, 'price_rub' => '0.900'], ], ])->assertStatus(422); expect(Tariff::count())->toBe(3); }); test('PUT /api/admin/telegram/tariffs с выдуманным видом медиа → 422', function () { $this->putJson('/api/admin/telegram/tariffs', [ 'rows' => [ ['media_kind' => 'gif', 'price_rub' => '0.500'], ['media_kind' => Campaign::MEDIA_IMAGE, 'price_rub' => '0.750'], ['media_kind' => Campaign::MEDIA_VIDEO, 'price_rub' => '0.900'], ], ])->assertStatus(422); expect(Tariff::count())->toBe(3); });