Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(PM): close with timeout #133

Merged
merged 3 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/promo-manager/core/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,6 @@ export class Controller {
this.stateActions.removeFromQueue(slug);

this.updateProgressInfo(slug);

this.triggerNextPromo();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change dont break/fix any test. Can we add test for this?

Copy link
Collaborator Author

@iapolya iapolya Oct 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this change breaks 8 tests for callback validation controller.subscribe(callback). They are corrected by emitChange calls here. triggerNextPromo is also called in this function

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should make closePromoWithTimeout async and await result?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still need to call addPromoToFinished and removeFromQueue before await result. It's unnecessary here

};

cancelPromo = (slug: Nullable<PromoSlug>, closeActiveTimeout = 0) => {
Expand Down Expand Up @@ -628,12 +626,15 @@ export class Controller {

private closePromo = (slug: PromoSlug) => {
this.logger.debug('Close promo', slug);

if (!this.isActive(slug)) {
return;
}

this.stateActions.clearActive();
this.stateActions.removeFromQueue(slug);

this.emitChange();
this.triggerNextPromo();
};

Expand Down
103 changes: 0 additions & 103 deletions src/promo-manager/tests/controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,109 +232,6 @@ describe('repeated runs', function () {
});
});

describe('trigger subscribe', () => {
let controller: Controller;

beforeEach(() => {
controller = new Controller(testOptions);
});

it('request start -> 1 update', async () => {
const callback = jest.fn();

controller.subscribe(callback);

await controller.requestStart('boardPoll');

expect(callback).toHaveBeenCalledTimes(1);
});

it('finish -> 1 update', async () => {
await controller.requestStart('boardPoll');

const callback = jest.fn();
controller.subscribe(callback);

await controller.finishPromo('boardPoll');

expect(callback).toHaveBeenCalledTimes(1);
});

it('cancel -> 1 update', async () => {
await controller.requestStart('boardPoll');

const callback = jest.fn();
controller.subscribe(callback);

await controller.cancelPromo('boardPoll');

expect(callback).toHaveBeenCalledTimes(1);
});

it('skipPromo -> 1 update', async () => {
await controller.requestStart('boardPoll');

const callback = jest.fn();
controller.subscribe(callback);

await controller.skipPromo('boardPoll');

expect(callback).toHaveBeenCalledTimes(1);
});

it('start and finish -> 2 updates', async () => {
const callback = jest.fn();

controller.subscribe(callback);

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

expect(callback).toHaveBeenCalledTimes(2);
});

it('start, finish and has next -> 3 updates', async () => {
const callback = jest.fn();

controller.subscribe(callback);

const promise1 = controller.requestStart('boardPoll');
const promise2 = controller.requestStart('ganttPoll');

await Promise.all([promise1, promise2]);

await controller.finishPromo('boardPoll');

expect(callback).toHaveBeenCalledTimes(3);
});

it('start and cancel -> 2 updates', async () => {
const callback = jest.fn();

controller.subscribe(callback);

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

expect(callback).toHaveBeenCalledTimes(2);
});

it('double start and cancel -> 3 updates', async () => {
const callback = jest.fn();

controller.subscribe(callback);

const promise1 = controller.requestStart('boardPoll');
const promise2 = controller.requestStart('ganttPoll');

await Promise.all([promise1, promise2]);

await controller.cancelPromo('boardPoll');

expect(callback).toHaveBeenCalledTimes(3);
});
});

describe('update last call info', () => {
let controller: Controller;
const promo = 'boardPoll';
Expand Down
149 changes: 149 additions & 0 deletions src/promo-manager/tests/subscribe.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import {Controller} from '../core/controller';
import {testOptions} from './options';
import {waitForNextTick} from './utils';

describe('trigger subscribe', () => {
let controller: Controller;

beforeEach(() => {
controller = new Controller(testOptions);
});

it('finish with timeout => update progress info, close active', async () => {
await controller.requestStart('boardPoll');

const callback = jest.fn();
controller.subscribe(callback);

await controller.finishPromo('boardPoll', 100);

expect(controller.state.base.activePromo).toBe('boardPoll');
expect(controller.state.progress?.finishedPromos.includes('boardPoll')).toBe(true);
expect(callback).toHaveBeenCalledTimes(1);

await waitForNextTick(100);

expect(controller.state.base.activePromo).toBe(null);
expect(callback).toHaveBeenCalledTimes(2);
});

it('cancel with timeout => update progress info, close active', async () => {
await controller.requestStart('boardPoll');

const callback = jest.fn();
controller.subscribe(callback);

await controller.cancelPromo('boardPoll', 100);

expect(controller.state.base.activePromo).toBe('boardPoll');
expect(controller.state.progress?.progressInfoByPromo['boardPoll']).toBeDefined();
expect(callback).toHaveBeenCalledTimes(1);

await waitForNextTick(100);

expect(controller.state.base.activePromo).toBe(null);
expect(callback).toHaveBeenCalledTimes(2);
});
});

describe('optimize subscribe', () => {
let controller: Controller;

beforeEach(() => {
controller = new Controller(testOptions);
});

it('request start -> 1 update', async () => {
const callback = jest.fn();

controller.subscribe(callback);

await controller.requestStart('boardPoll');

expect(callback).toHaveBeenCalledTimes(1);
});

it('finish -> 2 updates', async () => {
await controller.requestStart('boardPoll');

const callback = jest.fn();
controller.subscribe(callback);

await controller.finishPromo('boardPoll');

expect(callback).toHaveBeenCalledTimes(2);
});

it('cancel -> 2 updates', async () => {
await controller.requestStart('boardPoll');

const callback = jest.fn();
controller.subscribe(callback);

await controller.cancelPromo('boardPoll');

expect(callback).toHaveBeenCalledTimes(2);
});

it('skipPromo -> 1 update', async () => {
await controller.requestStart('boardPoll');

const callback = jest.fn();
controller.subscribe(callback);

await controller.skipPromo('boardPoll');

expect(callback).toHaveBeenCalledTimes(1);
});

it('start and finish -> 3 updates', async () => {
const callback = jest.fn();

controller.subscribe(callback);

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

expect(callback).toHaveBeenCalledTimes(3);
});

it('start, finish and has next -> 4 updates', async () => {
const callback = jest.fn();

controller.subscribe(callback);

const promise1 = controller.requestStart('boardPoll');
const promise2 = controller.requestStart('ganttPoll');
await Promise.all([promise1, promise2]);

await controller.finishPromo('boardPoll');

expect(callback).toHaveBeenCalledTimes(4);
});

it('start and cancel -> 3 updates', async () => {
const callback = jest.fn();

controller.subscribe(callback);

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

expect(callback).toHaveBeenCalledTimes(3);
});

it('double start and cancel -> 3 updates', async () => {
const callback = jest.fn();

controller.subscribe(callback);

const promise1 = controller.requestStart('boardPoll');
const promise2 = controller.requestStart('ganttPoll');

await Promise.all([promise1, promise2]);

await controller.cancelPromo('boardPoll');

expect(callback).toHaveBeenCalledTimes(4);
});
});
Loading