Rewrite router tests for GROUP_LIST in a more robust way
A major issue with the existing tests is that they don't test the URL
parsing and matching at all. They just test the handler methods. That
creates a huge gap in testing and prevents safe refactorings.
We want to refactor all route matching and handling in a similar way as
change 356680 shows it for one route. So it makes sense to write the
tests in a way that the input is a URL and the output is a view state.
I will follow up with other tests once this change is approved and
submitted.
Release-Notes: skip
Change-Id: I7ed36dd147fac2d500331da7aa0384c6aeee8c7b
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.ts b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.ts
index 98272b4..af44739 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.ts
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.ts
@@ -11,6 +11,7 @@
stubRestApi,
addListenerForTest,
waitEventLoop,
+ waitUntilCalled,
} from '../../../test/test-utils';
import {GrRouter, routerToken, _testOnly_RoutePattern} from './gr-router';
import {GerritView} from '../../../services/router/router-model';
@@ -25,7 +26,7 @@
} from '../../../types/common';
import {AppElementParams} from '../../gr-app-types';
import {assert} from '@open-wc/testing';
-import {AdminChildView} from '../../../models/views/admin';
+import {AdminChildView, AdminViewState} from '../../../models/views/admin';
import {RepoDetailView} from '../../../models/views/repo';
import {GroupDetailView} from '../../../models/views/group';
import {ChangeChildView, ChangeViewState} from '../../../models/views/change';
@@ -38,6 +39,7 @@
createRevision,
} from '../../../test/test-data-generators';
import {ParsedChangeInfo} from '../../../types/types';
+import {ViewState} from '../../../models/views/base';
suite('gr-router tests', () => {
let router: GrRouter;
@@ -291,6 +293,19 @@
assert.deepEqual(setStateStub.lastCall.args[0], params);
}
+ async function checkUrlToState<T extends ViewState>(url: string, state: T) {
+ setStateStub.reset();
+ router.page.show(url);
+ await waitUntilCalled(setStateStub, 'setState');
+ assert.deepEqual(setStateStub.lastCall.firstArg, state);
+ }
+
+ async function checkUrlNotMatched(url: string) {
+ handlePassThroughRoute.reset();
+ router.page.show(url);
+ await waitUntilCalled(handlePassThroughRoute, 'handlePassThroughRoute');
+ }
+
function createPageContext(): PageContext {
return {
canonicalPath: '',
@@ -306,6 +321,7 @@
redirectStub = sinon.stub(router, 'redirect');
setStateStub = sinon.stub(router, 'setState');
handlePassThroughRoute = sinon.stub(router, 'handlePassThroughRoute');
+ router.startRouter();
});
test('handleLegacyProjectDashboardRoute', () => {
@@ -737,55 +753,55 @@
});
});
- test('handleGroupListOffsetRoute', () => {
- const ctx = createPageContext();
- assertctxToParams(ctx, 'handleGroupListOffsetRoute', {
+ test('list of groups', async () => {
+ const defaultState: AdminViewState = {
view: GerritView.ADMIN,
adminView: AdminChildView.GROUPS,
- offset: 0,
- filter: null,
+ offset: '0',
openCreateModal: false,
- });
-
- ctx.params[1] = '42';
- assertctxToParams(ctx, 'handleGroupListOffsetRoute', {
- view: GerritView.ADMIN,
- adminView: AdminChildView.GROUPS,
- offset: '42',
filter: null,
- openCreateModal: false,
- });
+ };
- ctx.hash = 'create';
- assertctxToParams(ctx, 'handleGroupListOffsetRoute', {
- view: GerritView.ADMIN,
- adminView: AdminChildView.GROUPS,
- offset: '42',
- filter: null,
+ await checkUrlToState('/admin/groups', defaultState);
+ await checkUrlToState('/admin/groups/', defaultState);
+ await checkUrlToState('/admin/groups#create', {
+ ...defaultState,
openCreateModal: true,
});
- });
-
- test('handleGroupListFilterOffsetRoute', () => {
- const ctx = {
- ...createPageContext(),
- params: {filter: 'foo', offset: '42'},
- };
- assertctxToParams(ctx, 'handleGroupListFilterOffsetRoute', {
- view: GerritView.ADMIN,
- adminView: AdminChildView.GROUPS,
- offset: '42',
- filter: 'foo',
+ await checkUrlToState('/admin/groups,123', {
+ ...defaultState,
+ offset: '123',
});
- });
-
- test('handleGroupListFilterRoute', () => {
- const ctx = {...createPageContext(), params: {filter: 'foo'}};
- assertctxToParams(ctx, 'handleGroupListFilterRoute', {
- view: GerritView.ADMIN,
- adminView: AdminChildView.GROUPS,
- filter: 'foo',
+ await checkUrlToState('/admin/groups,123#create', {
+ ...defaultState,
+ offset: '123',
+ openCreateModal: true,
});
+
+ await checkUrlToState('/admin/groups/q/filter:asdf', {
+ ...defaultState,
+ filter: 'asdf',
+ });
+ await checkUrlToState('/admin/groups/q/filter:asdf,123', {
+ ...defaultState,
+ filter: 'asdf',
+ offset: '123',
+ });
+ // #create is ignored when filtering
+ await checkUrlToState('/admin/groups/q/filter:asdf,123#create', {
+ ...defaultState,
+ filter: 'asdf',
+ offset: '123',
+ });
+ // filter is decoded (twice)
+ await checkUrlToState(
+ '/admin/groups/q/filter:XX%20XX%2520XX%252FXX%3FXX',
+ {...defaultState, filter: 'XX XX XX/XX?XX'}
+ );
+
+ // Slash must be double encoded in `filter` param.
+ await checkUrlNotMatched('/admin/groups/q/filter:asdf/qwer,11');
+ await checkUrlNotMatched('/admin/groups/q/filter:asdf%2Fqwer,11');
});
test('handleGroupRoute', () => {