diff --git a/app/Console/Commands/ImportVCards.php b/app/Console/Commands/ImportVCards.php index b371b8cf992..8eeeb77539e 100644 --- a/app/Console/Commands/ImportVCards.php +++ b/app/Console/Commands/ImportVCards.php @@ -92,7 +92,7 @@ private function import(string $path, User $user): ImportJob 'filename' => $pathName, ]); - dispatch_now(new AddContactFromVCard($importJob)); + AddContactFromVCard::dispatchSync($importJob); return $importJob; } diff --git a/app/Http/Controllers/Auth/InvitationController.php b/app/Http/Controllers/Auth/InvitationController.php index 52439835bf4..15426cb072e 100644 --- a/app/Http/Controllers/Auth/InvitationController.php +++ b/app/Http/Controllers/Auth/InvitationController.php @@ -129,7 +129,7 @@ protected function create(array $data, $invitation) $user->save(); // send me an alert - dispatch(new SendNewUserAlert($user)); + SendNewUserAlert::dispatch($user); return $user; } diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index a1beb9124b8..36f3df1c330 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -107,7 +107,7 @@ protected function create(array $data): ?User if (! $first) { // send me an alert - dispatch(new SendNewUserAlert($user)); + SendNewUserAlert::dispatch($user); } return $user; diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php index 718c0b3ed12..051f9c22860 100644 --- a/app/Http/Controllers/SettingsController.php +++ b/app/Http/Controllers/SettingsController.php @@ -199,7 +199,7 @@ public function export() */ public function exportToSql() { - $path = dispatch_now(new ExportAccountAsSQL()); + $path = ExportAccountAsSQL::dispatchSync(); $adapter = disk_adapter(ExportAccountAsSQL::STORAGE); @@ -250,7 +250,7 @@ public function storeImport(ImportsRequest $request) 'filename' => $filename, ]); - dispatch(new AddContactFromVCard($importJob, $request->input('behaviour'))); + AddContactFromVCard::dispatch($importJob, $request->input('behaviour')); return redirect()->route('settings.import'); } diff --git a/app/Jobs/GetGPSCoordinate.php b/app/Jobs/GetGPSCoordinate.php new file mode 100644 index 00000000000..23709397a57 --- /dev/null +++ b/app/Jobs/GetGPSCoordinate.php @@ -0,0 +1,72 @@ +place = $place->withoutRelations(); + } + + /** + * Get the middleware the job should pass through. + * + * @return array + */ + public function middleware() + { + return [ + new RateLimited('GPSCoordinatePerMinute'), + new RateLimited('GPSCoordinatePerDay'), + ]; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + app(GetGPSCoordinateService::class)->execute([ + 'account_id' => $this->place->account_id, + 'place_id' => $this->place->id, + ]); + } +} diff --git a/app/Jobs/SendNewUserAlert.php b/app/Jobs/SendNewUserAlert.php index 7b46690b34f..e84f1796fdd 100644 --- a/app/Jobs/SendNewUserAlert.php +++ b/app/Jobs/SendNewUserAlert.php @@ -8,11 +8,12 @@ use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Support\Facades\Notification; class SendNewUserAlert implements ShouldQueue { - use InteractsWithQueue, Queueable, SerializesModels; + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; protected $user; diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index d0e5333f57a..d9ca09e1e82 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -12,6 +12,8 @@ use App\Notifications\EmailMessaging; use Illuminate\Support\Facades\Schema; use Illuminate\Support\ServiceProvider; +use Illuminate\Cache\RateLimiting\Limit; +use Illuminate\Support\Facades\RateLimiter; use Illuminate\Auth\Notifications\VerifyEmail; use Illuminate\Auth\Notifications\ResetPassword; @@ -65,6 +67,13 @@ public function boot() }); Paginator::defaultView('vendor.pagination.default'); + + RateLimiter::for('GPSCoordinatePerMinute', function () { + return Limit::perMinute(60); + }); + RateLimiter::for('GPSCoordinatePerDay', function () { + return Limit::perDay(5000); + }); } /** diff --git a/app/Services/Account/Place/CreatePlace.php b/app/Services/Account/Place/CreatePlace.php index 831cb78cac0..74a388a689c 100644 --- a/app/Services/Account/Place/CreatePlace.php +++ b/app/Services/Account/Place/CreatePlace.php @@ -4,8 +4,7 @@ use App\Models\Account\Place; use App\Services\BaseService; -use GuzzleHttp\Client as GuzzleClient; -use App\Services\Instance\Geolocalization\GetGPSCoordinate; +use App\Jobs\GetGPSCoordinate; class CreatePlace extends BaseService { @@ -32,10 +31,9 @@ public function rules() * Create a place. * * @param array $data - * @param GuzzleClient $client the Guzzle client, only needed when unit testing * @return Place */ - public function execute(array $data, GuzzleClient $client = null): Place + public function execute(array $data): Place { $this->validate($data); @@ -50,8 +48,8 @@ public function execute(array $data, GuzzleClient $client = null): Place 'longitude' => $this->nullOrValue($data, 'longitude'), ]); - if (is_null($place->latitude)) { - $this->getGeocodingInfo($place, $client); + if (is_null($place->latitude) || is_null($place->longitude)) { + $this->getGeocodingInfo($place); } return $place; @@ -61,14 +59,12 @@ public function execute(array $data, GuzzleClient $client = null): Place * Get geocoding information about the place (lat/longitude). * * @param Place $place - * @param GuzzleClient $client the Guzzle client, only needed when unit testing * @return void */ - private function getGeocodingInfo(Place $place, GuzzleClient $client = null) + private function getGeocodingInfo(Place $place) { - app(GetGPSCoordinate::class)->execute([ - 'account_id' => $place->account_id, - 'place_id' => $place->id, - ], $client); + if (config('monica.enable_geolocation') && ! is_null(config('monica.location_iq_api_key'))) { + GetGPSCoordinate::dispatch($place); + } } } diff --git a/app/Services/Account/Place/UpdatePlace.php b/app/Services/Account/Place/UpdatePlace.php index 644fab0279a..425e658ce40 100644 --- a/app/Services/Account/Place/UpdatePlace.php +++ b/app/Services/Account/Place/UpdatePlace.php @@ -4,8 +4,7 @@ use App\Models\Account\Place; use App\Services\BaseService; -use GuzzleHttp\Client as GuzzleClient; -use App\Services\Instance\Geolocalization\GetGPSCoordinate; +use App\Jobs\GetGPSCoordinate; class UpdatePlace extends BaseService { @@ -33,10 +32,9 @@ public function rules() * Update a place. * * @param array $data - * @param GuzzleClient $client the Guzzle client, only needed when unit testing * @return Place */ - public function execute(array $data, GuzzleClient $client = null): Place + public function execute(array $data): Place { $this->validate($data); @@ -54,8 +52,8 @@ public function execute(array $data, GuzzleClient $client = null): Place 'longitude' => $this->nullOrValue($data, 'longitude'), ]); - if (is_null($place->latitude)) { - $this->getGeocodingInfo($place, $client); + if (is_null($place->latitude) || is_null($place->longitude)) { + $this->getGeocodingInfo($place); } return $place; @@ -65,14 +63,12 @@ public function execute(array $data, GuzzleClient $client = null): Place * Get geocoding information about the place (lat/longitude). * * @param Place $place - * @param GuzzleClient $client the Guzzle client, only needed when unit testing * @return void */ - private function getGeocodingInfo(Place $place, GuzzleClient $client = null) + private function getGeocodingInfo(Place $place) { - app(GetGPSCoordinate::class)->execute([ - 'account_id' => $place->account_id, - 'place_id' => $place->id, - ], $client); + if (config('monica.enable_geolocation') && ! is_null(config('monica.location_iq_api_key'))) { + GetGPSCoordinate::dispatch($place); + } } } diff --git a/app/Services/Instance/Geolocalization/GetGPSCoordinate.php b/app/Services/Instance/Geolocalization/GetGPSCoordinate.php index 4b842a9e2b7..ec5eab25575 100644 --- a/app/Services/Instance/Geolocalization/GetGPSCoordinate.php +++ b/app/Services/Instance/Geolocalization/GetGPSCoordinate.php @@ -5,16 +5,12 @@ use Illuminate\Support\Str; use App\Models\Account\Place; use App\Services\BaseService; -use function Safe\json_decode; use Illuminate\Support\Facades\Log; -use GuzzleHttp\Client as GuzzleClient; -use GuzzleHttp\Exception\ClientException; +use Illuminate\Support\Facades\Http; +use Illuminate\Http\Client\HttpClientException; class GetGPSCoordinate extends BaseService { - /** @var GuzzleClient */ - protected $client; - /** * Get the validation rules that apply to the service. * @@ -33,19 +29,12 @@ public function rules() * This method uses LocationIQ to process the geocoding. * * @param array $data - * @param GuzzleClient $client the Guzzle client, only needed when unit testing * @return Place|null */ - public function execute(array $data, GuzzleClient $client = null) + public function execute(array $data) { $this->validate($data); - if (! is_null($client)) { - $this->client = $client; - } else { - $this->client = new GuzzleClient(); - } - $place = Place::where('account_id', $data['account_id']) ->findOrFail($data['place_id']); @@ -88,19 +77,18 @@ private function query(Place $place): ?Place } try { - $response = $this->client->request('GET', $query); - } catch (ClientException $e) { - Log::error('Error making the call: '.$e); + $response = Http::get($query); + $response->throw(); - return null; - } - - $response = json_decode($response->getBody()); + $place->latitude = $response->json('0.lat'); + $place->longitude = $response->json('0.lon'); + $place->save(); - $place->latitude = $response[0]->lat; - $place->longitude = $response[0]->lon; - $place->save(); + return $place; + } catch (HttpClientException $e) { + Log::error('Error making the call: '.$e); + } - return $place; + return null; } } diff --git a/app/Services/Instance/Weather/GetWeatherInformation.php b/app/Services/Instance/Weather/GetWeatherInformation.php index 8e0d51d8fc5..637b22a239d 100644 --- a/app/Services/Instance/Weather/GetWeatherInformation.php +++ b/app/Services/Instance/Weather/GetWeatherInformation.php @@ -5,19 +5,15 @@ use Illuminate\Support\Str; use App\Models\Account\Place; use App\Services\BaseService; -use function Safe\json_decode; +use App\Jobs\GetGPSCoordinate; use App\Models\Account\Weather; use Illuminate\Support\Facades\Log; -use GuzzleHttp\Client as GuzzleClient; -use GuzzleHttp\Exception\ClientException; +use Illuminate\Support\Facades\Http; use App\Exceptions\MissingEnvVariableException; -use App\Services\Instance\Geolocalization\GetGPSCoordinate; +use Illuminate\Http\Client\HttpClientException; class GetWeatherInformation extends BaseService { - /** @var GuzzleClient */ - protected $client; - /** * Get the validation rules that apply to the service. * @@ -34,14 +30,12 @@ public function rules() * Get the weather information. * * @param array $data - * @param GuzzleClient $client the Guzzle client, only needed when unit testing * @return Weather|null * @throws \Illuminate\Validation\ValidationException if the array that is given in parameter is not valid * @throws \App\Exceptions\MissingEnvVariableException if the weather services are not enabled * @throws \Illuminate\Database\Eloquent\ModelNotFoundException if the Place object is not found - * @throws \GuzzleHttp\Exception\ClientException if the request to Darksky crashed */ - public function execute(array $data, GuzzleClient $client = null): ?Weather + public function execute(array $data): ?Weather { $this->validateWeatherEnvVariables(); @@ -57,12 +51,6 @@ public function execute(array $data, GuzzleClient $client = null): ?Weather } } - if (! is_null($client)) { - $this->client = $client; - } else { - $this->client = new GuzzleClient(); - } - return $this->query($place); } @@ -94,17 +82,17 @@ private function query(Place $place): ?Weather $query = $this->buildQuery($place); try { - $response = $this->client->request('GET', $query); - $response = json_decode($response->getBody()); + $response = Http::get($query); + $response->throw(); $weather = new Weather(); - $weather->weather_json = $response; + $weather->weather_json = $response->object(); $weather->account_id = $place->account_id; $weather->place_id = $place->id; $weather->save(); return $weather; - } catch (ClientException $e) { + } catch (HttpClientException $e) { Log::error('Error making the call: '.$e); } @@ -137,11 +125,15 @@ private function buildQuery(Place $place) * @param Place $place * @return Place|null */ - private function fetchGPS(Place $place) + private function fetchGPS(Place $place): ?Place { - return app(GetGPSCoordinate::class)->execute([ - 'account_id' => $place->account_id, - 'place_id' => $place->id, - ]); + if (config('monica.enable_geolocation') && ! is_null(config('monica.location_iq_api_key'))) { + GetGPSCoordinate::dispatchSync($place); + $place->refresh(); + + return $place; + } + + return null; } } diff --git a/tests/Feature/ExportAccountAsSQLTest.php b/tests/Feature/ExportAccountAsSQLTest.php index 3f38e320249..dcc89e11423 100644 --- a/tests/Feature/ExportAccountAsSQLTest.php +++ b/tests/Feature/ExportAccountAsSQLTest.php @@ -18,7 +18,7 @@ public function test_it_exports_account_file() $user = $this->signIn(); - $path = dispatch_now(new ExportAccountAsSQL()); + $path = ExportAccountAsSQL::dispatchSync(); $this->assertStringStartsWith('exports/', $path); $this->assertStringEndsWith('.sql', $path); diff --git a/tests/Feature/RegisterTest.php b/tests/Feature/RegisterTest.php index 3c493b386a9..06c9397ef11 100644 --- a/tests/Feature/RegisterTest.php +++ b/tests/Feature/RegisterTest.php @@ -71,7 +71,7 @@ public function test_it_dispatches_an_email() $user = factory(User::class)->create(); - dispatch(new SendNewUserAlert($user)); + SendNewUserAlert::dispatch($user); Notification::assertSentTo($route, NewUserAlert::class); diff --git a/tests/Unit/Jobs/ScheduleStayInTouchTest.php b/tests/Unit/Jobs/ScheduleStayInTouchTest.php index 4c222a89c48..c3ecc2d0054 100644 --- a/tests/Unit/Jobs/ScheduleStayInTouchTest.php +++ b/tests/Unit/Jobs/ScheduleStayInTouchTest.php @@ -38,7 +38,7 @@ public function it_dispatches_an_email() 'timezone' => 'America/New_York', ]); - dispatch(new ScheduleStayInTouch($contact)); + ScheduleStayInTouch::dispatch($contact); NotificationFacade::assertSentTo($user, StayInTouchEmail::class, function ($notification, $channels) use ($contact) { @@ -81,7 +81,7 @@ public function it_doesnt_dispatches_an_email_if_free_account() 'timezone' => 'America/New_York', ]); - dispatch(new ScheduleStayInTouch($contact)); + ScheduleStayInTouch::dispatch($contact); NotificationFacade::assertNotSentTo($user, StayInTouchEmail::class); NotificationFacade::assertNothingSent(); @@ -113,7 +113,7 @@ public function it_reschedule_missed_stayintouch() 'timezone' => 'America/New_York', ]); - dispatch(new ScheduleStayInTouch($contact)); + ScheduleStayInTouch::dispatch($contact); NotificationFacade::assertNotSentTo($user, StayInTouchEmail::class); NotificationFacade::assertNothingSent(); diff --git a/tests/Unit/Jobs/UpdateLastConsultedDateTest.php b/tests/Unit/Jobs/UpdateLastConsultedDateTest.php index 91b4660d21e..73e0791cf59 100644 --- a/tests/Unit/Jobs/UpdateLastConsultedDateTest.php +++ b/tests/Unit/Jobs/UpdateLastConsultedDateTest.php @@ -21,7 +21,7 @@ public function it_updates_the_last_consulted_at_field_for_the_given_contact() 'number_of_views' => 1, ]); - dispatch(new UpdateLastConsultedDate($contact)); + UpdateLastConsultedDate::dispatch($contact); $this->assertDatabaseHas('contacts', [ 'id' => $contact->id, diff --git a/tests/Unit/Models/ContactTest.php b/tests/Unit/Models/ContactTest.php index 645a6fb52b0..e7f74e9346a 100644 --- a/tests/Unit/Models/ContactTest.php +++ b/tests/Unit/Models/ContactTest.php @@ -1003,7 +1003,7 @@ public function it_sends_the_stay_in_touch_email() 'timezone' => 'America/New_York', ]); - dispatch(new ScheduleStayInTouch($contact)); + ScheduleStayInTouch::dispatch($contact); NotificationFacade::assertSentTo($user, StayInTouchEmail::class, function ($notification, $channels) use ($contact) { diff --git a/tests/Unit/Services/Account/Place/CreatePlaceTest.php b/tests/Unit/Services/Account/Place/CreatePlaceTest.php index b48bfba1a80..04214155dc2 100644 --- a/tests/Unit/Services/Account/Place/CreatePlaceTest.php +++ b/tests/Unit/Services/Account/Place/CreatePlaceTest.php @@ -3,12 +3,9 @@ namespace Tests\Unit\Services\Account\Place; use Tests\TestCase; -use GuzzleHttp\Client; -use GuzzleHttp\HandlerStack; use App\Models\Account\Place; -use GuzzleHttp\Psr7\Response; use App\Models\Account\Account; -use GuzzleHttp\Handler\MockHandler; +use Illuminate\Support\Facades\Http; use App\Services\Account\Place\CreatePlace; use Illuminate\Validation\ValidationException; use Illuminate\Foundation\Testing\DatabaseTransactions; @@ -55,9 +52,9 @@ public function it_stores_a_place_and_fetch_geolocation_information() config(['monica.location_iq_api_key' => 'test']); $body = file_get_contents(base_path('tests/Fixtures/Services/Account/Place/CreatePlaceSampleResponse.json')); - $mock = new MockHandler([new Response(200, [], $body)]); - $handler = HandlerStack::create($mock); - $client = new Client(['handler' => $handler]); + Http::fake([ + 'us1.locationiq.com/v1/*' => Http::response($body, 200), + ]); $account = factory(Account::class)->create([]); @@ -72,7 +69,7 @@ public function it_stores_a_place_and_fetch_geolocation_information() 'longitude' => '', ]; - $place = app(CreatePlace::class)->execute($request, $client); + $place = app(CreatePlace::class)->execute($request); $this->assertDatabaseHas('places', [ 'id' => $place->id, @@ -86,7 +83,7 @@ public function it_stores_a_place_and_fetch_geolocation_information() /** @test */ public function it_fails_if_wrong_parameters_are_given() { - $account = factory(Account::class)->create([]); + factory(Account::class)->create([]); $request = [ 'street' => '199 Lafayette Street', diff --git a/tests/Unit/Services/Account/Place/UpdatePlaceTest.php b/tests/Unit/Services/Account/Place/UpdatePlaceTest.php index 8f19f473fd1..16caba8ff0a 100644 --- a/tests/Unit/Services/Account/Place/UpdatePlaceTest.php +++ b/tests/Unit/Services/Account/Place/UpdatePlaceTest.php @@ -3,12 +3,9 @@ namespace Tests\Unit\Services\Account\Place; use Tests\TestCase; -use GuzzleHttp\Client; -use GuzzleHttp\HandlerStack; use App\Models\Account\Place; -use GuzzleHttp\Psr7\Response; use App\Models\Account\Account; -use GuzzleHttp\Handler\MockHandler; +use Illuminate\Support\Facades\Http; use App\Services\Account\Place\UpdatePlace; use Illuminate\Validation\ValidationException; use Illuminate\Foundation\Testing\DatabaseTransactions; @@ -57,9 +54,9 @@ public function it_updates_a_place_and_fetch_geolocation_information() config(['monica.location_iq_api_key' => 'test']); $body = file_get_contents(base_path('tests/Fixtures/Services/Account/Place/UpdatePlaceSampleResponse.json')); - $mock = new MockHandler([new Response(200, [], $body)]); - $handler = HandlerStack::create($mock); - $client = new Client(['handler' => $handler]); + Http::fake([ + 'us1.locationiq.com/v1/*' => Http::response($body, 200), + ]); $place = factory(Place::class)->create([]); @@ -75,7 +72,7 @@ public function it_updates_a_place_and_fetch_geolocation_information() 'longitude' => '', ]; - $place = app(UpdatePlace::class)->execute($request, $client); + $place = app(UpdatePlace::class)->execute($request); $this->assertDatabaseHas('places', [ 'id' => $place->id, diff --git a/tests/Unit/Services/Instance/Geolocalization/GetGPSCoordinateTest.php b/tests/Unit/Services/Instance/Geolocalization/GetGPSCoordinateTest.php index ff8d87aa47d..c8724d009b8 100644 --- a/tests/Unit/Services/Instance/Geolocalization/GetGPSCoordinateTest.php +++ b/tests/Unit/Services/Instance/Geolocalization/GetGPSCoordinateTest.php @@ -3,11 +3,8 @@ namespace Tests\Unit\Services\Instance\Geolocalization; use Tests\TestCase; -use GuzzleHttp\Client; -use GuzzleHttp\HandlerStack; use App\Models\Account\Place; -use GuzzleHttp\Psr7\Response; -use GuzzleHttp\Handler\MockHandler; +use Illuminate\Support\Facades\Http; use Illuminate\Validation\ValidationException; use Illuminate\Foundation\Testing\DatabaseTransactions; use App\Services\Instance\Geolocalization\GetGPSCoordinate; @@ -40,9 +37,9 @@ public function it_gets_gps_coordinates() config(['monica.location_iq_api_key' => 'test']); $body = file_get_contents(base_path('tests/Fixtures/Services/Instance/Geolocalization/GetGPSCoordinateSampleResponse.json')); - $mock = new MockHandler([new Response(200, [], $body)]); - $handler = HandlerStack::create($mock); - $client = new Client(['handler' => $handler]); + Http::fake([ + 'us1.locationiq.com/v1/*' => Http::response($body, 200), + ]); $place = factory(Place::class)->create(); @@ -51,7 +48,7 @@ public function it_gets_gps_coordinates() 'place_id' => $place->id, ]; - $place = app(GetGPSCoordinate::class)->execute($request, $client); + $place = app(GetGPSCoordinate::class)->execute($request); $this->assertDatabaseHas('places', [ 'id' => $place->id, @@ -70,9 +67,9 @@ public function it_returns_null_if_address_is_garbage() config(['monica.location_iq_api_key' => 'test']); $body = file_get_contents(base_path('tests/Fixtures/Services/Instance/Geolocalization/GetGPSCoordinateGarbageResponse.json')); - $mock = new MockHandler([new Response(200, [], $body)]); - $handler = HandlerStack::create($mock); - $client = new Client(['handler' => $handler]); + Http::fake([ + 'us1.locationiq.com/v1/*' => Http::response($body, 404), + ]); $place = factory(Place::class)->create([ 'country' => 'ewqr', diff --git a/tests/Unit/Services/Instance/Weather/GetWeatherInformationTest.php b/tests/Unit/Services/Instance/Weather/GetWeatherInformationTest.php index d807a408086..b71f82c0582 100644 --- a/tests/Unit/Services/Instance/Weather/GetWeatherInformationTest.php +++ b/tests/Unit/Services/Instance/Weather/GetWeatherInformationTest.php @@ -3,12 +3,10 @@ namespace Tests\Unit\Services\Instance\Weather; use Tests\TestCase; -use GuzzleHttp\Client; -use GuzzleHttp\HandlerStack; use App\Models\Account\Place; -use GuzzleHttp\Psr7\Response; +use App\Models\Account\Account; use App\Models\Account\Weather; -use GuzzleHttp\Handler\MockHandler; +use Illuminate\Support\Facades\Http; use Illuminate\Validation\ValidationException; use App\Exceptions\MissingEnvVariableException; use Illuminate\Foundation\Testing\DatabaseTransactions; @@ -30,15 +28,15 @@ public function it_gets_weather_information() config(['monica.darksky_api_key' => 'test']); $body = file_get_contents(base_path('tests/Fixtures/Services/Instance/Weather/GetWeatherInformationSampleResponse.json')); - $mock = new MockHandler([new Response(200, [], $body)]); - $handler = HandlerStack::create($mock); - $client = new Client(['handler' => $handler]); + Http::fake([ + 'api.darksky.net/forecast/*' => Http::response($body, 200), + ]); $request = [ 'place_id' => $place->id, ]; - $weather = app(GetWeatherInformation::class)->execute($request, $client); + $weather = app(GetWeatherInformation::class)->execute($request); $this->assertDatabaseHas('weather', [ 'id' => $weather->id, @@ -57,6 +55,56 @@ public function it_gets_weather_information() ); } + /** @test */ + public function it_gets_weather_information_for_new_place() + { + $account = factory(Account::class)->create(); + $place = factory(Place::class)->create([ + 'account_id' => $account->id, + ]); + + config(['monica.enable_weather' => true]); + config(['monica.darksky_api_key' => 'test']); + config(['monica.enable_geolocation' => true]); + config(['monica.location_iq_api_key' => 'test']); + + $body = file_get_contents(base_path('tests/Fixtures/Services/Instance/Weather/GetWeatherInformationSampleResponse.json')); + $placeBody = file_get_contents(base_path('tests/Fixtures/Services/Account/Place/CreatePlaceSampleResponse.json')); + Http::fake([ + 'us1.locationiq.com/v1/*' => Http::response($placeBody, 200), + 'api.darksky.net/forecast/*' => Http::response($body, 200), + ]); + + $request = [ + 'place_id' => $place->id, + ]; + + $weather = app(GetWeatherInformation::class)->execute($request); + + $this->assertDatabaseHas('weather', [ + 'id' => $weather->id, + 'account_id' => $account->id, + 'place_id' => $place->id, + ]); + $this->assertDatabaseHas('places', [ + 'id' => $place->id, + 'account_id' => $account->id, + 'street' => '12', + 'latitude' => 34.0736204, + 'longitude' => -118.4003563, + ]); + + $this->assertEquals( + 'Partly Cloudy', + $weather->summary + ); + + $this->assertInstanceOf( + Weather::class, + $weather + ); + } + /** @test */ public function it_cant_get_weather_info_if_weather_not_enabled() {