refactor: hardcode Bowli mobile scheme
CI / 🧪 Tests Laravel (push) Successful in 2m8s
CI / 🐳 Build & Push Image (push) Successful in 31s

This commit is contained in:
2026-08-11 16:20:27 +02:00
parent 2f2bac9d3a
commit bd1b4bba20
7 changed files with 11 additions and 33 deletions
-1
View File
@@ -3,7 +3,6 @@ APP_ENV=local
APP_KEY= APP_KEY=
APP_DEBUG=true APP_DEBUG=true
APP_URL=http://localhost APP_URL=http://localhost
APP_MOBILE_SCHEME=bowly
APP_PORT=8003 APP_PORT=8003
APP_LOCALE=fr APP_LOCALE=fr
APP_FALLBACK_LOCALE=en APP_FALLBACK_LOCALE=en
-1
View File
@@ -3,7 +3,6 @@ APP_ENV=production
APP_KEY= APP_KEY=
APP_DEBUG=false APP_DEBUG=false
APP_URL=https://dailyapi.leonmorival.xyz APP_URL=https://dailyapi.leonmorival.xyz
APP_MOBILE_SCHEME=bowly
APP_LOCALE=fr APP_LOCALE=fr
APP_FALLBACK_LOCALE=en APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=fr_FR APP_FAKER_LOCALE=fr_FR
+3 -8
View File
@@ -4,23 +4,18 @@ namespace App\Services;
class MobileDeepLink class MobileDeepLink
{ {
private const string SCHEME = 'bowli';
/** /**
* @param array<string, mixed> $query * @param array<string, mixed> $query
*/ */
public static function to(string $path, array $query = []): string public static function to(string $path, array $query = []): string
{ {
$url = sprintf('%s://%s', self::scheme(), ltrim($path, '/')); $url = sprintf('%s://%s', self::SCHEME, ltrim($path, '/'));
$queryString = http_build_query($query, '', '&', PHP_QUERY_RFC3986); $queryString = http_build_query($query, '', '&', PHP_QUERY_RFC3986);
return $queryString === '' return $queryString === ''
? $url ? $url
: "{$url}?{$queryString}"; : "{$url}?{$queryString}";
} }
private static function scheme(): string
{
$scheme = rtrim((string) config('app.mobile_scheme', 'bowly'), ':/');
return $scheme !== '' ? $scheme : 'bowly';
}
} }
-2
View File
@@ -54,8 +54,6 @@ return [
'url' => env('APP_URL', 'http://localhost'), 'url' => env('APP_URL', 'http://localhost'),
'mobile_scheme' => env('APP_MOBILE_SCHEME', 'bowly'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Application Timezone | Application Timezone
@@ -12,7 +12,6 @@ uses(RefreshDatabase::class);
it('sends engagement reminders only to eligible mobile users', function () { it('sends engagement reminders only to eligible mobile users', function () {
app()->setLocale('fr'); app()->setLocale('fr');
config()->set('app.mobile_scheme', 'dailymeal');
Http::fake([ Http::fake([
'https://exp.host/*' => Http::response([ 'https://exp.host/*' => Http::response([
@@ -63,15 +62,13 @@ it('sends engagement reminders only to eligible mobile users', function () {
return $payload['to'] === 'ExponentPushToken[eligible]' return $payload['to'] === 'ExponentPushToken[eligible]'
&& $payload['data']['type'] === 'engagement_reminder' && $payload['data']['type'] === 'engagement_reminder'
&& in_array($payload['data']['url'], [ && in_array($payload['data']['url'], [
'dailymeal://create', 'bowli://create',
'dailymeal://profile/workouts?create=1', 'bowli://profile/workouts?create=1',
], true); ], true);
}); });
}); });
it('uses the hard-coded localized reminder copy', function () { it('uses the hard-coded localized reminder copy', function () {
config()->set('app.mobile_scheme', 'dailymeal');
foreach (['fr', 'en'] as $locale) { foreach (['fr', 'en'] as $locale) {
app()->setLocale($locale); app()->setLocale($locale);
@@ -86,18 +83,12 @@ it('uses the hard-coded localized reminder copy', function () {
expect($payload['title'])->toBeString()->not->toBeEmpty() expect($payload['title'])->toBeString()->not->toBeEmpty()
->and($payload['body'])->toBeString()->not->toBeEmpty() ->and($payload['body'])->toBeString()->not->toBeEmpty()
->and($payload['data']['message_key'])->toBe($messageKey) ->and($payload['data']['message_key'])->toBe($messageKey)
->and($payload['data']['url'])->toBe("dailymeal://{$expectedPath}"); ->and($payload['data']['url'])->toBe("bowli://{$expectedPath}");
} }
} }
}); });
it('builds mobile deep links from the configured scheme', function () { it('builds mobile deep links with the Bowli scheme', function () {
config()->set('app.mobile_scheme', 'dailymeal://'); expect(MobileDeepLink::to('/create'))->toBe('bowli://create')
->and(MobileDeepLink::to('strava/callback', ['code' => 'abc 123']))->toBe('bowli://strava/callback?code=abc%20123');
expect(MobileDeepLink::to('/create'))->toBe('dailymeal://create')
->and(MobileDeepLink::to('strava/callback', ['code' => 'abc 123']))->toBe('dailymeal://strava/callback?code=abc%20123');
config()->set('app.mobile_scheme', '');
expect(MobileDeepLink::to('create'))->toBe('bowly://create');
}); });
+1 -3
View File
@@ -43,8 +43,6 @@ it('creates one review per user for a meal post', function () {
}); });
it('sends a push notification to the meal owner when another user comments on their meal', function () { it('sends a push notification to the meal owner when another user comments on their meal', function () {
config()->set('app.mobile_scheme', 'dailymeal');
Http::fake([ Http::fake([
'https://exp.host/*' => Http::response([ 'https://exp.host/*' => Http::response([
'data' => [ 'data' => [
@@ -79,7 +77,7 @@ it('sends a push notification to the meal owner when another user comments on th
'sound' => 'default', 'sound' => 'default',
'channelId' => 'default', 'channelId' => 'default',
'data' => [ 'data' => [
'url' => "dailymeal://meals/{$mealPost->id}", 'url' => "bowli://meals/{$mealPost->id}",
], ],
], ],
]); ]);
+1 -3
View File
@@ -38,8 +38,6 @@ it('returns a strava authorization url for the api callback', function () {
}); });
it('redirects the strava web callback to the mobile app', function () { it('redirects the strava web callback to the mobile app', function () {
config()->set('app.mobile_scheme', 'dailymeal');
$query = http_build_query([ $query = http_build_query([
'code' => 'authorization-code', 'code' => 'authorization-code',
'scope' => 'read activity:read', 'scope' => 'read activity:read',
@@ -48,7 +46,7 @@ it('redirects the strava web callback to the mobile app', function () {
$this $this
->get("/strava/callback?{$query}") ->get("/strava/callback?{$query}")
->assertRedirect("dailymeal://strava/callback?{$query}"); ->assertRedirect("bowli://strava/callback?{$query}");
}); });
it('stores strava tokens from an authorization code', function () { it('stores strava tokens from an authorization code', function () {