Skip to content

Commit 7b90bb2

Browse files
committed
add feature is on middleware
1 parent cb6e552 commit 7b90bb2

File tree

3 files changed

+58
-26
lines changed

3 files changed

+58
-26
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ Its recommended that you seed the features to your database before a new deploym
5858

5959
### Check If A Feature Is Enabled
6060
#### Blade View
61+
Use the `@feature` blade directive anywhere in your view files.
6162
```php
6263
@feature('search-v2')
6364
// new search goes here
@@ -67,6 +68,7 @@ Its recommended that you seed the features to your database before a new deploym
6768
```
6869

6970
#### In Your Code
71+
Use the `FeatureFlag` facade to conveniently check the state of a feature in your app code.
7072
```php
7173
use Codinglabs\FeatureFlags\Facades\FeatureFlag;
7274

@@ -77,6 +79,19 @@ if (FeatureFlag::isOn('search-v2')) {
7779
}
7880
```
7981

82+
#### Middleware
83+
Register `feature` as a route middleware in your HTTP Kernel to protect routes. A 404 response will be returned if the feature does not resolve to the on state.
84+
```php
85+
// app/Http/Kernel.php
86+
protected $routeMiddleware = [
87+
// ...
88+
'feature' => \Codinglabs\FeatureFlags\Middleware\VerifyFeatureIsOn::class,
89+
];
90+
91+
// routes/web.php
92+
Route::get('search-v2', \App\Http\Controllers\SearchV2Controller::class)->middleware('feature:search-v2');
93+
```
94+
8095
### Check If A Feature Is Disabled
8196
#### Blade View
8297
```php

src/Middleware/VerifyFeatureIsOn.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Codinglabs\FeatureFlags\Middleware;
4+
5+
use Closure;
6+
use Illuminate\Http\Request;
7+
use Codinglabs\FeatureFlags\Facades\FeatureFlag;
8+
9+
class VerifyFeatureIsOn
10+
{
11+
public function handle(Request $request, Closure $next, $feature)
12+
{
13+
abort_unless(FeatureFlag::isOn($feature), 404, __('Page not found.'));
14+
15+
return $next($request);
16+
}
17+
}

tests/FeaturesTest.php

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@
4343
// handling...
4444
});
4545

46-
expect(FeatureFlag::isOn('some-feature'))->toBeFalse();
47-
expect(FeatureFlag::isOff('some-feature'))->toBeTrue();
48-
expect(cache()->store('array')->get('testing.some-feature'))->toBeNull();
46+
expect(FeatureFlag::isOn('some-feature'))->toBeFalse()
47+
->and(FeatureFlag::isOff('some-feature'))->toBeTrue()
48+
->and(cache()->store('array')->get('testing.some-feature'))->toBeNull();
4949
});
5050

5151
it('resolves isOn to false when the features state is "off"', function () {
@@ -54,9 +54,9 @@
5454
'state' => FeatureState::off()
5555
]);
5656

57-
expect(FeatureFlag::isOn('some-feature'))->toBeFalse();
58-
expect(FeatureFlag::isOff('some-feature'))->toBeTrue();
59-
expect(cache()->store('array')->get('testing.some-feature'))->toBe(FeatureState::off()->value);
57+
expect(FeatureFlag::isOn('some-feature'))->toBeFalse()
58+
->and(FeatureFlag::isOff('some-feature'))->toBeTrue()
59+
->and(cache()->store('array')->get('testing.some-feature'))->toBe(FeatureState::off()->value);
6060
});
6161

6262
it('resolves isOn to true when the features state is "on"', function () {
@@ -65,9 +65,9 @@
6565
'state' => FeatureState::on()
6666
]);
6767

68-
expect(FeatureFlag::isOn('some-feature'))->toBeTrue();
69-
expect(FeatureFlag::isOff('some-feature'))->toBeFalse();
70-
expect(cache()->store('array')->get('testing.some-feature'))->toBe(FeatureState::on()->value);
68+
expect(FeatureFlag::isOn('some-feature'))->toBeTrue()
69+
->and(FeatureFlag::isOff('some-feature'))->toBeFalse()
70+
->and(cache()->store('array')->get('testing.some-feature'))->toBe(FeatureState::on()->value);
7171
});
7272

7373
it('resolves isOn to true when feature state is "dynamic" and the closure returns true', function () {
@@ -80,9 +80,9 @@
8080
return true;
8181
});
8282

83-
expect(FeatureFlag::isOn('some-feature'))->toBeTrue();
84-
expect(FeatureFlag::isOff('some-feature'))->toBeFalse();
85-
expect(cache()->store('array')->get('testing.some-feature'))->toBe(FeatureState::dynamic()->value);
83+
expect(FeatureFlag::isOn('some-feature'))->toBeTrue()
84+
->and(FeatureFlag::isOff('some-feature'))->toBeFalse()
85+
->and(cache()->store('array')->get('testing.some-feature'))->toBe(FeatureState::dynamic()->value);
8686
});
8787

8888
it('resolves isOn to false when feature state is "dynamic" and the closure returns false', function () {
@@ -95,9 +95,9 @@
9595
return false;
9696
});
9797

98-
expect(FeatureFlag::isOn('some-feature'))->toBeFalse();
99-
expect(FeatureFlag::isOff('some-feature'))->toBeTrue();
100-
expect(cache()->store('array')->get('testing.some-feature'))->toBe(FeatureState::dynamic()->value);
98+
expect(FeatureFlag::isOn('some-feature'))->toBeFalse()
99+
->and(FeatureFlag::isOff('some-feature'))->toBeTrue()
100+
->and(cache()->store('array')->get('testing.some-feature'))->toBe(FeatureState::dynamic()->value);
101101
});
102102

103103
it('uses the default dynamic closure if no feature specific closure has been defined', function () {
@@ -110,9 +110,9 @@
110110
return true;
111111
});
112112

113-
expect(FeatureFlag::isOn('some-feature'))->toBeTrue();
114-
expect(FeatureFlag::isOff('some-feature'))->toBeFalse();
115-
expect(cache()->store('array')->get('testing.some-feature'))->toBe(FeatureState::dynamic()->value);
113+
expect(FeatureFlag::isOn('some-feature'))->toBeTrue()
114+
->and(FeatureFlag::isOff('some-feature'))->toBeFalse()
115+
->and(cache()->store('array')->get('testing.some-feature'))->toBe(FeatureState::dynamic()->value);
116116
});
117117

118118
it('resolves isOn to false when feature state is "dynamic" and no dynamic closure has been defined', function () {
@@ -121,8 +121,8 @@
121121
'state' => FeatureState::dynamic(),
122122
]);
123123

124-
expect(FeatureFlag::isOn('some-feature'))->toBeFalse();
125-
expect(FeatureFlag::isOff('some-feature'))->toBeTrue();
124+
expect(FeatureFlag::isOn('some-feature'))->toBeFalse()
125+
->and(FeatureFlag::isOff('some-feature'))->toBeTrue();
126126
});
127127

128128
it('resolves the current state', function () {
@@ -139,9 +139,9 @@
139139
'state' => FeatureState::on()
140140
]);
141141

142-
expect(FeatureFlag::getState('some-off-feature'))->toBe(FeatureState::off());
143-
expect(FeatureFlag::getState('some-dynamic-feature'))->toBe(FeatureState::dynamic());
144-
expect(FeatureFlag::getState('some-on-feature'))->toBe(FeatureState::on());
142+
expect(FeatureFlag::getState('some-off-feature'))->toBe(FeatureState::off())
143+
->and(FeatureFlag::getState('some-dynamic-feature'))->toBe(FeatureState::dynamic())
144+
->and(FeatureFlag::getState('some-on-feature'))->toBe(FeatureState::on());
145145
});
146146

147147
it('can update a features state', function () {
@@ -157,9 +157,9 @@
157157
FeatureFlag::updateFeatureState('some-feature', FeatureState::on());
158158

159159
Event::assertDispatched(\Codinglabs\FeatureFlags\Events\FeatureUpdatedEvent::class);
160-
expect(FeatureFlag::isOn('some-feature'))->toBeTrue();
161-
expect(FeatureFlag::isOff('some-feature'))->toBeFalse();
162-
expect(cache()->store('array')->get('testing.some-feature'))->toBe(FeatureState::on()->value);
160+
expect(FeatureFlag::isOn('some-feature'))->toBeTrue()
161+
->and(FeatureFlag::isOff('some-feature'))->toBeFalse()
162+
->and(cache()->store('array')->get('testing.some-feature'))->toBe(FeatureState::on()->value);
163163
});
164164

165165
it('uses the default cache store when cache store has not been set', function () {

0 commit comments

Comments
 (0)