Skip to content

Commit

Permalink
Merge pull request #155 from gravity-ui/fix-state-sync
Browse files Browse the repository at this point in the history
fix(promo-manager): invalidate base state after state sync
  • Loading branch information
vanilla-wave authored Feb 5, 2025
2 parents 003028e + ce7d113 commit 3cb429e
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 5 deletions.
27 changes: 23 additions & 4 deletions src/promo-manager/core/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ import {EventsMap as OnboardingEventsMap} from '../../types';

type Listener = () => void;

const defaultBaseState = {
activePromo: null,
activeQueue: [],
};

const defaultProgressState: ProgressState = {
finishedPromos: [],
progressInfoByPromo: {},
Expand Down Expand Up @@ -85,10 +90,7 @@ export class Controller {

this.state = JSON.parse(
JSON.stringify({
base: {
activePromo: null,
activeQueue: [],
},
base: defaultBaseState,
progress: options.progressState
? {
...defaultProgressState,
Expand Down Expand Up @@ -361,6 +363,23 @@ export class Controller {
}
};

protected invalidateBaseState = () => {
const promoToValidate = [
this.state.base.activePromo,
...this.state.base.activeQueue,
].filter((slug): slug is string => {
if (!slug) {
return false;
}
return this.isAbleToRun(slug);
});

this.state.base = defaultBaseState;

promoToValidate.forEach((slug) => this.addPromoToActiveQueue(slug));
this.emitChange();
};

private checkPromoConditions = (slug: PromoSlug): boolean => {
this.logger.debug('Promo', slug, 'Check conditions');
if (!this.checkConstraints()) {
Expand Down
75 changes: 74 additions & 1 deletion src/promo-manager/plugins/promo-tab-sync-plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ it('tab focus -> apply value from LS', async () => {
expect(controller.state.progress).toEqual(newValue.value);
});

it('promo finished in fresh state -> closes promo', async () => {
it('promo finished in fresh state -> apply fresh progress state', async () => {
const controller = new Controller({
...testOptions,
plugins: [
Expand Down Expand Up @@ -145,6 +145,79 @@ it('promo finished in fresh state -> closes promo', async () => {
expect(controller.state.progress).toEqual(newValue.value);
});

it('promo finished in fresh state -> mutate base state', async () => {
const controller = new Controller({
...testOptions,
plugins: [
new PromoTabSyncPlugin({
stateLSKey: 'someKey',
__UNSTABLE__syncState: true,
}),
],
dateNow: () => DATE_NOW,
});

await controller.ensureInit();
await controller.requestStart('boardPoll');

const newValue = {
date: DATE_IN_FUTURE,
value: {
finishedPromos: ['boardPoll'],
progressInfoByPromo: {
boardPoll: {
lastCallTime: DATE_IN_FUTURE,
},
},
},
};
window.localStorage.setItem('someKey', JSON.stringify(newValue));

// current date > event date
controller.dateNow = () => DATE_IN_FUTURE;
document.dispatchEvent(new Event('visibilitychange'));

await waitForNextTick();
await waitForNextTick();

expect(controller.state.base.activePromo).not.toEqual('boardPoll');
});

it('promo canceled in fresh state -> mutate base state', async () => {
const controller = new Controller({
...testOptions,
plugins: [
new PromoTabSyncPlugin({
stateLSKey: 'someKey',
__UNSTABLE__syncState: true,
}),
],
dateNow: () => DATE_NOW,
});

await controller.ensureInit();
await controller.requestStart('boardPoll');

const newValue = {
date: DATE_IN_FUTURE,
value: {
progressInfoByPromo: {
boardPoll: {
lastCallTime: DATE_IN_FUTURE,
},
},
},
};
window.localStorage.setItem('someKey', JSON.stringify(newValue));

// current date > event date
controller.dateNow = () => DATE_IN_FUTURE;
document.dispatchEvent(new Event('visibilitychange'));

await waitForNextTick();

expect(controller.state.base.activePromo).not.toEqual('boardPoll');
});
it('old value int ls + tab focus -> dont apply change', async () => {
const controller = new Controller({
...testOptions,
Expand Down
1 change: 1 addition & 0 deletions src/promo-manager/plugins/promo-tab-sync-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export class PromoTabSyncPlugin implements PromoManagerPlugin {
if (isFreshData) {
promoManager.state.progress = lsValue.value;
promoManager['emitChange']();
promoManager['invalidateBaseState']();

this.storeChangedTime = lsValue.date;
}
Expand Down

0 comments on commit 3cb429e

Please sign in to comment.