Skip to content

Commit

Permalink
feat(history-service): root location transformer createNewRootLocatio…
Browse files Browse the repository at this point in the history
…nForMultipleConsumers (#539)
  • Loading branch information
unstubbable committed Aug 26, 2019
1 parent f3cd884 commit 42691cf
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 12 deletions.
2 changes: 1 addition & 1 deletion packages/history-service/src/__tests__/index.node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ import {
createRootLocationTransformer,
defineHistoryService
} from '..';
import {Writable} from '../internal/writable';
import {
consumerPathsQueryParamName,
createSearch,
createUrl
} from './root-location-helpers';
import {stubbedLogger} from './stubbed-logger';
import {Writable} from './writable';

describe('defineHistoryService', () => {
describe('HistoryServiceV1 (on Node.js)', () => {
Expand Down
68 changes: 64 additions & 4 deletions packages/history-service/src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ import {
createRootLocationTransformer,
defineHistoryService
} from '..';
import {RootLocation} from '../create-root-location-transformer';
import {Writable} from '../internal/writable';
import {
consumerPathsQueryParamName,
createSearch,
createUrl
} from './root-location-helpers';
import {stubbedLogger} from './stubbed-logger';
import {Writable} from './writable';

const simulateOnPopState = (state: unknown, url: string) => {
// We need to use pushState to change to the URL that should set by the popstate event.
Expand Down Expand Up @@ -642,9 +643,7 @@ describe('defineHistoryService', () => {
featureServices: {'s2:logger': stubbedLogger}
};

createHistoryServiceBinder = (): FeatureServiceBinder<
HistoryServiceV2
> => {
createHistoryServiceBinder = () => {
const sharedHistoryService = defineHistoryService(
createRootLocationTransformer({consumerPathsQueryParamName})
).create(mockEnv);
Expand Down Expand Up @@ -1478,6 +1477,67 @@ describe('defineHistoryService', () => {
state: {test1: 42, test2: 'foo'}
});
});

describe('with a createNewRootLocationForMultipleConsumers method defined in the root location transformer', () => {
let createNewRootLocationForMultipleConsumersMock: jest.Mock;
let historyServiceTest1: HistoryServiceV2;

beforeEach(() => {
createNewRootLocationForMultipleConsumersMock = jest.fn(() => ({
pathname: 'root-test'
}));

createHistoryServiceBinder = () => {
const sharedHistoryService = defineHistoryService({
createRootLocation: jest.fn(),
getConsumerPathFromRootLocation: jest.fn(),
createNewRootLocationForMultipleConsumers: createNewRootLocationForMultipleConsumersMock
}).create(mockEnv);

return sharedHistoryService['2.0.0'];
};

const historyServiceBinder = createHistoryServiceBinder();
historyServiceTest1 = historyServiceBinder('test1').featureService;
});

it('uses the custom createNewRootLocationForMultipleConsumers method', () => {
const consumerLocation = {
historyKey: 'test1',
location: {pathname: '/test1'}
};

historyServiceTest1.createNewRootLocationForMultipleConsumers(
consumerLocation
);

expect(
createNewRootLocationForMultipleConsumersMock.mock.calls
).toEqual([[consumerLocation]]);
});

it('sets the consumer states on the new root location', () => {
const consumerLocation = {
historyKey: 'test1',
location: {pathname: '/test1', state: 42}
};

const location = historyServiceTest1.createNewRootLocationForMultipleConsumers(
consumerLocation
);

const expectedRootLocation: RootLocation = {
pathname: 'root-test',
search: '',
hash: '',
state: {
test1: 42
}
};

expect(location).toEqual(expectedRootLocation);
});
});
});

describe('when no Logger Feature Service is provided', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as history from 'history';
import {ConsumerLocation} from '.';
import {URLSearchParams} from './internal/url-search-params';

export interface ConsumerHistoryStates {
Expand Down Expand Up @@ -33,6 +34,10 @@ export interface RootLocationTransformer {
consumerLocation: history.LocationDescriptorObject,
historyKey: string
): history.LocationDescriptorObject;

createNewRootLocationForMultipleConsumers?(
...consumerLocations: ConsumerLocation[]
): RootLocationDescriptorObject;
}

export interface ConsumerPaths {
Expand Down
36 changes: 29 additions & 7 deletions packages/history-service/src/internal/history-multiplexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ import {
RootLocationDescriptorObject,
RootLocationTransformer
} from '../create-root-location-transformer';
import {Writable} from './writable';

function setConsumerStates(
rootLocation: RootLocationDescriptorObject,
...consumerLocations: ConsumerLocation[]
): RootLocation {
const consumerStates: Writable<ConsumerHistoryStates> = {};

for (const {historyKey, location} of consumerLocations) {
consumerStates[historyKey] = location.state;
}

return history.createLocation({...rootLocation, state: consumerStates});
}

export class HistoryMultiplexer {
public constructor(
Expand Down Expand Up @@ -72,17 +86,25 @@ export class HistoryMultiplexer {
public createNewRootLocationForMultipleConsumers(
...consumerLocations: ConsumerLocation[]
): RootLocationDescriptorObject {
let rootlocation: RootLocationDescriptorObject = {pathname: '/'};
let newRootLocation: RootLocationDescriptorObject = {pathname: '/'};

for (const consumerLocation of consumerLocations) {
rootlocation = this.createRootLocation(
consumerLocation.historyKey,
consumerLocation.location,
rootlocation
if (
this.rootLocationTransformer.createNewRootLocationForMultipleConsumers
) {
newRootLocation = this.rootLocationTransformer.createNewRootLocationForMultipleConsumers(
...consumerLocations
);
} else {
for (const consumerLocation of consumerLocations) {
newRootLocation = this.rootLocationTransformer.createRootLocation(
newRootLocation,
consumerLocation.location,
consumerLocation.historyKey
);
}
}

return rootlocation;
return setConsumerStates(newRootLocation, ...consumerLocations);
}

private createRootLocation(
Expand Down

0 comments on commit 42691cf

Please sign in to comment.