fjffk简单的咖啡店科开发2方法2 环滁皆山也。其西南诸峰,林壑尤美,望之蔚然而深秀者,琅琊也。山行六七里,渐闻水声潺潺,而泻出于两峰之间者,酿泉也 ??????????????????????????????? ??????????????/????????????????? ............/................... .........................../... ??????????????????????????????? >>>>>>>>>>>>>/>>>>>>>>>>>>>>>>> ÿØÿà JFIF    ÿÛ „  ( %!1!%)+//.383,7(-.+  -%%-////---/-.+/--+------/------/--0+--/-/-----.-----ÿÀ  ¥2" ÿÄ     ÿÄ J    ! 1AQ"aq2‘#BR‚¡ÁÑ3br’¢±Âð$CSƒ²á4c“%DsÓñÿÄ   ÿÄ *  !1AQa‘"2q3±ð#b¡ÿÚ   ? ¼QxJQaÍuò¸Zö Úü8,ÐÚú "SSn<rçù–´âE—^ªBÖ9À\†¸ÔÁT­ÃÛ5 ëd´³Í#Ý;Þ38œî ¶H£M:wÎ3…³…âpÔF&‚FK¸9„â4àGEõªfÿ ‘ñ(ßw­pŽF|È¥ù®häðÍѶ¹‘[ÒinÙW¶ùñY˜Q{›K"išÒ[Ú8žë\F¹@-?v"ÔU”,ìöžkÿ {I‡£šÍ?e ríV ?> ......................................... ............................................................................. <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>/>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dsdfAI/TTSTest.php000064400000001617152665634450007105 0ustar00create(['gcs_file' => 'fake-gcs.json']); SettingTwo::factory()->create(['daily_voice_limit_enabled' => false]); } beforeEach(function () { $this->seed(); }); test('returns error if no speeches are provided', function () { mockSettings(); $controller = new TTSController; $request = Request::create('/generate-speech', 'POST', [ 'speeches' => json_encode([], JSON_THROW_ON_ERROR), ]); $response = $controller->generateSpeech($request); expect($response->getStatusCode())->toBe(429) ->and($response->getData()->errors[0])->toBeIn(['Please provide valid content for speech generation.', 'Please provide inputs.']); }); Enums/MagicResponseTest.php000064400000006261152665634450011770 0ustar00statusCode())->toBe(419); }); it('returns correct status', function () { expect(MagicResponse::NO_CREDITS_LEFT->status())->toBe('error'); }); it('returns correct response type', function () { expect(MagicResponse::NO_CREDITS_LEFT->responseType())->toBe('json'); }); it('returns correct message', function () { $expectedMessage = [ 'message' => __('You have no credits left. Please consider upgrading your plan.'), 'status' => 'error', ]; expect(MagicResponse::NO_CREDITS_LEFT->message())->toBe($expectedMessage); }); it('returns correct response', function () { $response = MagicResponse::NO_CREDITS_LEFT->response(); expect($response) ->toBeInstanceOf(JsonResponse::class) ->and($response->getStatusCode())->toBe(419) ->and($response->getData(true))->toBe([ 'message' => __('You have no credits left. Please consider upgrading your plan.'), 'status' => 'error', ]); }); it('throws correct exception - as json', function () { MagicResponse::NO_CREDITS_LEFT->exception(); })->throwsIf(MagicResponse::NO_CREDITS_LEFT->exceptionsAsJson(), MagicResponseApiException::class, 'You have no credits left. Please consider upgrading your plan.', 419) ->todo(); it('throws correct exception', function () { MagicResponse::NO_CREDITS_LEFT->exception(); })->throwsUnless(MagicResponse::NO_CREDITS_LEFT->exceptionsAsJson(), Exception::class, 'You have no credits left. Please consider upgrading your plan.', 419); it('throws correct runtime exception - as json', function () { MagicResponse::NO_CREDITS_LEFT->runtimeException(); })->throwsIf(MagicResponse::NO_CREDITS_LEFT->exceptionsAsJson(), MagicResponseApiRuntimeException::class, 'You have no credits left. Please consider upgrading your plan.', 419) ->todo(); it('throws correct runtime exception', function () { MagicResponse::NO_CREDITS_LEFT->runtimeException(); })->throwsUnless(MagicResponse::NO_CREDITS_LEFT->exceptionsAsJson(), RuntimeException::class, 'You have no credits left. Please consider upgrading your plan.', 419); it('aborts correctly - as json')->todo(); it('aborts correctly', function () { MagicResponse::NO_CREDITS_LEFT->abort(); })->throwsIf(MagicResponse::NO_CREDITS_LEFT->responseType() !== 'json', Exception::class, 'You have no credits left. Please consider upgrading your plan.', 419) ->todo(); it('aborts if correctly', function () { MagicResponse::NO_CREDITS_LEFT->abort_if(true); })->throwsIf(MagicResponse::NO_CREDITS_LEFT->responseType() !== 'json', Exception::class, 'You have no credits left. Please consider upgrading your plan.', 419) ->todo(); it('aborts unless condition is false', function () { MagicResponse::NO_CREDITS_LEFT->abort_unless(false); })->throwsIf(MagicResponse::NO_CREDITS_LEFT->responseType() !== 'json', Exception::class, 'You have no credits left. Please consider upgrading your plan.', 419) ->todo(); Models/PlanTest.php000064400000001644152665634450010257 0ustar00create(); expect($plan) ->toBeInstanceOf(Plan::class) ->ai_models ->toBeArray() ->ai_models ->not ->toBeEmpty(); $aiModels = $plan->ai_models; $aiModels[EngineEnum::OPEN_AI->value] = []; $aiModels[EngineEnum::OPEN_AI->value][EntityEnum::DAVINCI->value] = 2; $plan->update([ 'ai_models' => $aiModels, ]); $this->assertSame(2, $plan->refresh()->ai_models[EngineEnum::OPEN_AI->value][EntityEnum::DAVINCI->value]); }); test('return type of checkOpenAiItemCount', function () { expect(Plan::factory()->create([ 'open_ai_items' => null, ]))->open_ai_items ->toBeEmpty() ->checkOpenAiItemCount() ->toBeInt(); }); Views/CreditListModalTest.php000064400000003260152665634450012256 0ustar00create(); SettingTwo::factory()->create(); }); test('modal listable entity', function () { expect(Entity::all(onlyListableCases: false)) ->count() ->toBe(count(EntityEnum::cases())) ->and(Entity::all(onlyListableCases: true)) ->count() ->toBe(count(EntityEnum::listableCases())); }); test('modal credit list', function () { loginAsUser(); $engines = Engine::all()->map(function ($engine) { return [ 'engine' => $engine, 'entities' => Entity::all($engine->enum(), onlyListableCases: true), ]; }); expect($engines) ->toBeCollection() ->not ->toBeEmpty() ->each( fn ($item) => $item ->toHaveKey('engine') ->engine ->toBeInstanceOf(EngineDriverInterface::class) ->not ->toBeEmpty() ->engine->label() ->toBeString() ->entities ->toBeCollection() ->not ->toBeEmpty() ->each( fn ($entity) => $entity ->toBeInstanceOf(EntityDriverInterface::class) ->creditBalance() ->toBeFloat() ), ); }); Support/EngineDriverTest.php000064400000002743152665634450012200 0ustar00toBeCollection() ->toHaveCount(count(EngineEnum::cases())) ->each(function ($driver) { return $driver->toBeInstanceOf(EngineDriverInterface::class) ->enum()->toBeInstanceOf(EngineEnum::class); }); }); test('entityDrivers by default engine', function () { expect(Engine::entityDrivers()) ->toBeCollection() ->not ->toHaveCount(count(EntityEnum::cases())) ->each(function ($driver) { return $driver->toBeInstanceOf(EntityDriverInterface::class) ->enum()->toBeInstanceOf(EntityEnum::class) ->enum()->engine()->toBe(EngineEnum::from(Engine::getDefaultDriver())); }); }); test('entityDrivers by engine', function () { expect(Engine::entityDrivers(EngineEnum::STABLE_DIFFUSION)) ->toBeCollection() ->not ->toHaveCount(count(EntityEnum::cases())) ->each(function ($driver) { return $driver->toBeInstanceOf(EntityDriverInterface::class) ->enum()->toBeInstanceOf(EntityEnum::class) ->enum()->engine()->toBe(EngineEnum::STABLE_DIFFUSION); }); }); Support/AIModelTest.php000064400000001302152665634450011057 0ustar00enum()->toBeInstanceOf(EntityEnum::class); })->with('entities'); test('subLabel', function () { expect(EntityEnum::cases()) ->each( fn ($case) => $case->subLabel()->toBeString()->not->toBeEmpty(), ); }); test('listable cases from creditBy', function () { $cases = EntityEnum::cases(); $listableCases = EntityEnum::listableCases(); expect($listableCases) ->not ->toBeEmpty() // ->not # now we show all cases ->toHaveCount(count($cases)); }); Support/AIDriverTest.php000064400000010046152665634450011257 0ustar00increaseCredit(2); })->throws(RuntimeException::class, 'User is not provided'); test('driverClass', function () { expect(Entity::driver())->toBeInstanceOf(EntityEnum::GPT_4_O->driverClass()); }); test('driverClass for user', function () { $user = loginAsUser(); expect(Entity::driverForUser($user))->toBeInstanceOf(EntityEnum::GPT_4_O->driverClass()); }); test('specific driverClass for user', function () { $user = loginAsUser(); expect(Entity::driverForUser($user, EntityEnum::FLUX_PRO))->toBeInstanceOf(EntityEnum::FLUX_PRO->driverClass()); }); test('driver name to method name', function () { $values = collect(EntityEnum::cases())->map(function ($value) { return str($value->value)->slug()->camel()->toString(); })->toArray(); expect($values)->each->toBeString(); }); test('driver has accessible', function () { expect(Entity::driver(EntityEnum::AZURE)->inputVoiceCount(1)) ->toBeInstanceOf(EntityEnum::AZURE->driverClass()); }); test('input test', function () { $driver = Entity::driver(EntityEnum::GPT_4_O); $driver->input('foo bar'); expect($driver->getInput())->toBe('foo bar'); }); test('throws when image count is not provided', function () { $model = EntityEnum::STABLE_DIFFUSION_XL_1024_V_1_0; $driver = Entity::driverForUser(loginAsUser(), $model); $driver->calculateCredit(); })->throws(RuntimeException::class, 'Input image count is not provided'); test('calculate credit with input for all models', function ($model) { $driver = Entity::driverForUser(loginAsUser(), $model); match (true) { $driver instanceof WithImagesInterface => $driver->inputImageCount(2), $driver instanceof WithImageToVideoInterface, $driver instanceof WithVideoToVideoInterface, $driver instanceof WithTextToVideoInterface => $driver->inputVideoCount(2), $driver instanceof WithTextToSpeechInterface => $driver->inputVoiceCount(2), $driver instanceof WithCharsInterface => $driver->input('fo'), $driver instanceof WithMinuteInterface => $driver->inputMinute(2), $driver instanceof WithSecondInterface => $driver->inputSecond(2), $driver instanceof WithPresentationInterface => $driver->inputPresentation(2), default => $driver->input('foo bar'), }; $driver->calculateCredit(); expect($driver->getCalculatedInputCredit())->toBe(2.0); })->with('entities'); test('all drivers', function () { expect(Entity::all()) ->toBeCollection() ->toHaveCount(count(EntityEnum::cases())) ->each(function ($driver) { return $driver->toBeInstanceOf(EntityDriverInterface::class) ->enum()->toBeInstanceOf(EntityEnum::class); }); }); test('all drivers with engine filter', function () { expect(Entity::all(EngineEnum::OPEN_AI)) ->toBeCollection() ->not ->toHaveCount(count(EntityEnum::cases())) ->each(function ($driver) { return $driver->toBeInstanceOf(EntityDriverInterface::class) ->enum()->toBeInstanceOf(EntityEnum::class) ->enum()->engine()->toBe(EngineEnum::OPEN_AI); }); }); Support/AIEngineTest.php000064400000001155152665634450011232 0ustar00toBeInstanceOf(EngineEnum::OPEN_AI->driverClass()); }); test('driver name to method name', function () { $values = collect(EngineEnum::cases())->map(function ($value) { return str($value->value)->slug()->camel()->toString(); })->toArray(); expect($values)->each->toBeString(); }); test('enum', function ($engine) { expect(Engine::driver($engine))->enum()->toBeInstanceOf(EngineEnum::class); })->with('ai_engines'); .gitkeep000064400000000000152665634450006203 0ustar00Entity/EntityManagerTest.php000064400000023264152665634450012167 0ustar00create(); SettingTwo::factory()->create(); $this->fullCount = count(EngineEnum::cases()) + count(EntityEnum::listableCases()); }); function mockDefaultModelsCount($type): int { $engines = EngineEnum::cases(); $count = 0; foreach ($engines as $engine) { $engineDefaultModels = $engine->getDefaultModels(Setting::getCache(), SettingTwo::getCache()); $filteredCollection = collect($engineDefaultModels) ->map(function ($entity) { return Entity::driver($entity); // Adjust if `Entity::driver()` isn't static }) ->filter(fn (EntityDriverInterface $driver) => $driver instanceof $type); $count += $filteredCollection->count(); } return $count; } test('total default models credits for current user', function ($increase, $type) { $user = loginAsUser(); $this->seed([ EntitySeeder::class, EngineSeeder::class, ]); $stats = EntityStats::type($type) ->includeDisabled(true) ->includeUnlisted(! $increase); $stats->list() ->each(function (WithCreditInterface $entity) use ($increase, $user) { $this->assertEquals($user->id, $entity->getUser()->id); if ($increase) { $entity->increaseCredit(1.5); } else { $entity->setCredit(1.5); } }); expect($stats->totalCredits())->toBe(mockDefaultModelsCount($type) * 1.5); })->with('bool')->with([ WithCharsInterface::class, WithMinuteInterface::class, WithSecondInterface::class, WithPresentationInterface::class, WithImagesInterface::class, WithImageToVideoInterface::class, WithWordsInterface::class, WithSpeechToTextInterface::class, WithTextToSpeechInterface::class, WithVisionPreviewInterface::class, WithTextToVideoInterface::class, WithPlagiarismInterface::class, ]); test('default schema of user credits', function () { $enginesWithCredits = User::getFreshCredits(); expect($enginesWithCredits) ->toHaveCount(count(EngineEnum::cases())) // Ensure first-level count only ->each(function ($entities) { $entities->each(function ($entity) { $entity ->toBeArray() // Assert that $entity is an array ->toHaveKeys(['credit', 'isUnlimited']) // Check that it has the expected keys ->toHaveKey('credit', 0) // Check that 'credit' is 0 ->toHaveKey('isUnlimited', false); // Check that 'isUnlimited' is false }); }); }); test('default schema from user credits', function () { $creditModel = User::factory()->create([ 'entity_credits' => null, ]); expect($creditModel->entity_credits) ->toBeArray() ->not ->toBeEmpty() ->toHaveCount(count(EngineEnum::cases())); assertExpectedCreditsSize($creditModel->entity_credits, $this->fullCount); }); test('updated schema with missing models from user credits', function () { $creditModel = User::factory()->create(); $enginesFirstLevelCount = count(EngineEnum::cases()); $listableCasesCount = count(EntityEnum::listableCases()); $fullCount = $enginesFirstLevelCount + $listableCasesCount; expect($creditModel->entity_credits) ->toHaveCount($enginesFirstLevelCount) ->toHaveKey(EntityEnum::GPT_4_O->engine()->slug()); assertExpectedCreditsSize($creditModel->entity_credits, $fullCount); // retrun array not collection $enginesWithEntitiesWithoutGPT40Entity = collect($creditModel->entity_credits) ->map(function ($entities, $engine) { if ($engine === EntityEnum::GPT_4_O->engine()->slug()) { return collect($entities) ->filter(function ($entity, $key) { return $key !== EntityEnum::GPT_4_O->slug(); }); } return $entities; })->toArray(); expect($enginesWithEntitiesWithoutGPT40Entity) ->toHaveCount($enginesFirstLevelCount) ->toHaveKey(EntityEnum::GPT_4_O->engine()->slug()) ->and($enginesWithEntitiesWithoutGPT40Entity[EntityEnum::GPT_4_O->engine()->slug()])->not->toHaveKey(EntityEnum::GPT_4_O->slug()); assertExpectedCreditsSize($enginesWithEntitiesWithoutGPT40Entity, $fullCount - 1); $creditModel->update([ 'entity_credits' => $enginesWithEntitiesWithoutGPT40Entity, ]); // refresh the model $newModelCredits = $creditModel->refresh()->entity_credits; expect($newModelCredits) ->toHaveCount($enginesFirstLevelCount) ->toHaveKey(EntityEnum::GPT_4_O->engine()->slug()); assertExpectedCreditsSize($newModelCredits, $fullCount); }); test('total default models credits for specific user', function ($increase, $type) { $user = User::factory()->create(); $this->seed([ EntitySeeder::class, EngineSeeder::class, ]); $stats = EntityStats::type($type) ->includeDisabled(true) ->includeUnlisted(! $increase) ->forUser($user); $stats->list() ->each(function (WithCreditInterface $entity) use ($increase, $user) { $this->assertEquals($user->id, $entity->getUser()->id); if ($increase) { $entity->increaseCredit(1.5); } else { $entity->setCredit(1.5); } }); expect($stats->totalCredits())->toBe(mockDefaultModelsCount($type) * 1.5); })->with('bool')->with([ WithImagesInterface::class, WithImageToVideoInterface::class, WithWordsInterface::class, WithSpeechToTextInterface::class, WithTextToSpeechInterface::class, WithVisionPreviewInterface::class, WithTextToVideoInterface::class, WithPlagiarismInterface::class, ]); test('set all image drivers to unlimited', function () { $user = loginAsUser(); $this->seed([ EntitySeeder::class, EngineSeeder::class, ]); $stats = EntityStats::image() ->includeDisabled(true) ->includeUnlisted(true); $stats->list() ->each(function ($entity) { $entity->setAsUnlimited(); }); $stats->list() ->each(function ($entity) { $defaultModels = $entity->engine()->getDefaultModels(Setting::getCache(), SettingTwo::getCache()); if (in_array($entity->enum(), $defaultModels, true)) { $this->assertTrue($entity->isUnlimitedCredit()); } else { $this->assertFalse($entity->isUnlimitedCredit()); } }); }); test('set all image drivers to limited', function () { $user = loginAsUser(); $this->seed([ EntitySeeder::class, EngineSeeder::class, ]); $stats = EntityStats::image() ->includeDisabled(true) ->includeUnlisted(true); $stats->list() ->each(function ($entity) { $entity->setCredit(1.5); $entity->setAsUnlimited(false); }); $stats->list() ->each(function ($entity) { $this->assertFalse($entity->isUnlimitedCredit()); }); }); test('set all word drivers to unlimited', function () { $user = loginAsUser(); $this->seed([ EntitySeeder::class, EngineSeeder::class, ]); $stats = EntityStats::word() ->includeDisabled(true) ->includeUnlisted(true); $stats->list() ->each(function ($entity) { $entity->setAsUnlimited(); }); $stats->list() ->each(function ($entity) { $defaultModels = $entity->engine()->getDefaultModels(Setting::getCache(), SettingTwo::getCache()); if (in_array($entity->enum(), $defaultModels, true)) { $this->assertTrue($entity->isUnlimitedCredit()); } else { $this->assertFalse($entity->isUnlimitedCredit()); } }); }); test('set all word drivers to limited', function () { $user = loginAsUser(); $this->seed([ EntitySeeder::class, EngineSeeder::class, ]); $stats = EntityStats::word() ->includeDisabled(true) ->includeUnlisted(true); $stats->list() ->each(function ($entity) { $entity->setCredit(1.5); $entity->setAsUnlimited(false); }); $stats->list() ->each(function ($entity) { $this->assertFalse($entity->isUnlimitedCredit()); }); }); PlanMigrationTest.php000064400000011051152665634450010677 0ustar00fullCount = count(EngineEnum::cases()) + count(EntityEnum::listableCases()); }); test('transfer image and word limits for all models', function () { $migrationFilename = '2024_09_24_214000_update_plan_credits_temporary_migration'; $this->assertTrue(File::exists(database_path('migrations/' . $migrationFilename . '.php'))); $this->assertSame(0, User::count()); $user = User::factory()->create([ 'remaining_words' => 100, 'remaining_images' => 150, ]); $this->assertSame(1, User::count()); $this->assertNotNull($user); $migrationQuery = DB::table('migrations')->where('migration', $migrationFilename); $this->assertTrue($migrationQuery->exists()); $this->assertSame(1, $migrationQuery->delete()); $this->assertFalse($migrationQuery->exists()); SettingTwo::create([ 'stablediffusion_default_model' => EntityEnum::STABLE_DIFFUSION_XL_1024_V_1_0, 'dalle' => EntityEnum::DALL_E_3, ]); setting(['fal_ai_default_model' => EntityEnum::FLUX_REALISM->slug()])->save(); $this->artisan('migrate', ['--path' => 'database/migrations/' . $migrationFilename . '.php']); $expectedCredits = User::getFreshCredits(); $expectedCredits[EntityEnum::STABLE_DIFFUSION_XL_1024_V_1_0->engine()->slug()][EntityEnum::STABLE_DIFFUSION_XL_1024_V_1_0->slug()] = [ 'credit' => 50, 'isUnlimited' => false, ]; $expectedCredits[EntityEnum::DALL_E_3->engine()->slug()][EntityEnum::DALL_E_3->slug()] = [ 'credit' => 50, 'isUnlimited' => false, ]; $expectedCredits[EntityEnum::FLUX_REALISM->engine()->slug()][EntityEnum::FLUX_REALISM->slug()] = [ 'credit' => 50, 'isUnlimited' => false, ]; $expectedCredits[EntityEnum::GPT_4_O->engine()->slug()][EntityEnum::GPT_4_O->slug()] = [ 'credit' => 100, 'isUnlimited' => false, ]; expect($user->refresh()) ->entity_credits ->toBeArray() ->toHaveCount(count(EngineEnum::cases())) // 1st level engines count ->toEqualCanonicalizing($expectedCredits); assertExpectedCreditsSize($expectedCredits, $this->fullCount); }); test('transfer word limit for all models', function () { $migrationFilename = '2024_09_24_214000_update_plan_credits_temporary_migration'; $this->assertTrue(File::exists(database_path('migrations/' . $migrationFilename . '.php'))); $this->assertSame(0, User::count()); $user = User::factory()->create([ 'remaining_words' => 100, 'remaining_images' => 150, ]); $this->assertSame(1, User::count()); $this->assertNotNull($user); $migrationQuery = DB::table('migrations')->where('migration', $migrationFilename); $this->assertTrue($migrationQuery->exists()); $this->assertSame(1, $migrationQuery->delete()); $this->assertFalse($migrationQuery->exists()); SettingTwo::create([ 'stablediffusion_default_model' => EntityEnum::STABLE_DIFFUSION_XL_1024_V_1_0->slug(), 'dalle' => EntityEnum::DALL_E_2->slug(), ]); setting(['fal_ai_default_model' => EntityEnum::FLUX_REALISM->slug()])->save(); $this->artisan('migrate', ['--path' => 'database/migrations/' . $migrationFilename . '.php']); $expectedCredits = User::getFreshCredits(); $expectedCredits[EntityEnum::GPT_4_O->engine()->slug()][EntityEnum::GPT_4_O->slug()] = [ 'credit' => 100, 'isUnlimited' => false, ]; $expectedCredits[EntityEnum::STABLE_DIFFUSION_XL_1024_V_1_0->engine()->slug()][EntityEnum::STABLE_DIFFUSION_XL_1024_V_1_0->slug()] = [ 'credit' => 50, 'isUnlimited' => false, ]; $expectedCredits[EntityEnum::DALL_E_2->engine()->slug()][EntityEnum::DALL_E_2->slug()] = [ 'credit' => 50, 'isUnlimited' => false, ]; $expectedCredits[EntityEnum::FLUX_REALISM->engine()->slug()][EntityEnum::FLUX_REALISM->slug()] = [ 'credit' => 50, 'isUnlimited' => false, ]; expect($user->refresh()) ->entity_credits ->not->toBeNull() ->entity_credits ->toBeArray() ->toHaveCount(count(EngineEnum::cases())) ->toEqualCanonicalizing($expectedCredits); assertExpectedCreditsSize($expectedCredits, $this->fullCount); });