Skip to content
This repository was archived by the owner on Jul 23, 2023. It is now read-only.

Commit caaf8b3

Browse files
committed
Guard support
1 parent e3079ec commit caaf8b3

File tree

6 files changed

+94
-0
lines changed

6 files changed

+94
-0
lines changed

README.md

+16
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,19 @@ If the feature is not enabled, the DOM is removed.
8585
<entry v-feature-flipping="'XXX'">Third</entry>
8686
</menu>
8787
```
88+
89+
#### Route
90+
91+
A [**guard**](https://router.vuejs.org/guide/advanced/navigation-guards.html) is defined to intercept all routes defining `featureFlipping` [**meta field**](https://router.vuejs.org/guide/advanced/meta.html).
92+
If the feature is not enabled, the router redirect to `"/"` route.
93+
94+
```javascript
95+
import VueRouter from 'vue-router'
96+
import TestComponent from './TestComponent'
97+
98+
new VueRouter({
99+
routes: [
100+
{ path: '/test', component: TestComponent, meta: { featureFlipping: 'XXX' } },
101+
]
102+
})
103+
```

package-lock.json

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"jest": "^23.1.0",
2121
"sinon": "^6.0.0",
2222
"vue": "^2.5.16",
23+
"vue-router": "^3.0.1",
2324
"vue-template-compiler": "^2.5.16"
2425
}
2526
}

src/guard.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { isEnabled } from './service'
2+
3+
/**
4+
* @example
5+
* const router = new VueRouter({
6+
* routes: [
7+
* { path: '/test', component: TestComponent, meta: { featureFlipping: 'XXXXX' } }
8+
* ]
9+
* })
10+
*/
11+
export async function featureFlippingGuard (to, from, next) {
12+
if (to.meta.featureFlipping && !isEnabled(to.meta.featureFlipping)) {
13+
return next({path: '/'})
14+
}
15+
return next()
16+
}

src/plugin.js

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { featureFlippingDirective } from './directive'
2+
import { featureFlippingGuard } from './guard'
23
import { setEnabledFeatures } from './service'
34

45
/**
@@ -12,4 +13,5 @@ import { setEnabledFeatures } from './service'
1213
export function featureFlippingPluginInstall (vue, options) {
1314
options && options.init && options.init((it) => setEnabledFeatures(it))
1415
vue.directive('feature-flipping', featureFlippingDirective)
16+
vue.mixin({beforeRouteEnter: featureFlippingGuard})
1517
}

tests/guard.spec.js

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { createLocalVue } from '@vue/test-utils'
2+
import { createSandbox } from 'sinon'
3+
import VueRouter from 'vue-router'
4+
import FeatureFlipping from '..'
5+
import * as service from '../src/service' // internal
6+
7+
describe('guard', () => {
8+
const sinon = createSandbox()
9+
afterEach(() => sinon.restore())
10+
11+
let localVue
12+
let router
13+
beforeEach(() => {
14+
localVue = createLocalVue()
15+
localVue.use(VueRouter)
16+
router = new VueRouter({
17+
routes: [
18+
{path: '/', name: 'index', component: {render: () => 'index'}},
19+
{path: '/stable', name: 'stable', component: {render: () => 'stable'}},
20+
{path: '/test', name: 'test', component: {render: () => 'test'}, meta: {featureFlipping: 'KEY'}}
21+
],
22+
})
23+
24+
localVue.use(FeatureFlipping) // define guard
25+
})
26+
27+
it('\'meta\' not defined: should accept route', async () => {
28+
router.push({name: 'stable'})
29+
await localVue.nextTick()
30+
31+
expect(router.history.current.path).toEqual('/stable')
32+
})
33+
34+
describe('\'meta\' defined: should test using \'isEnabled()\'', () => {
35+
it('\'enabled\': should accept route', async () => {
36+
sinon.stub(service, 'isEnabled').withArgs('KEY').returns(true)
37+
38+
router.push({name: 'test'})
39+
await localVue.nextTick()
40+
41+
expect(router.history.current.path).toEqual('/test')
42+
})
43+
44+
it('\'not enabled\': should redirect to \'/\'', async () => {
45+
sinon.stub(service, 'isEnabled').withArgs('KEY').returns(false)
46+
47+
router.push({name: 'test'})
48+
await localVue.nextTick()
49+
50+
expect(router.history.current.path).toEqual('/')
51+
})
52+
})
53+
})

0 commit comments

Comments
 (0)