Remove browsing selection ceilings
This commit is contained in:
1 parent
c028637556
commit
bc42c55555
14 files changed
+81
-53
No files matched your search
@@ -157,16 +157,17 @@ describe('AccountBrowsingSimulationService', () => {
|
||||
});
|
||||
|
||||
it('selects the configured number of distinct things in one session', async () => {
|
||||
enable({ postWeight: 100, commentWeight: 0, selectionsPerSession: 3 });
|
||||
const fixture = service({ posts: [post('one'), post('two'), post('three'), post('four')] });
|
||||
const posts = Array.from({ length: 18 }, (_, index) => post(`item-${index}`));
|
||||
enable({ postWeight: 100, commentWeight: 0, selectionsPerSession: 15 });
|
||||
const fixture = service({ posts });
|
||||
|
||||
const result = await fixture.instance.runNow();
|
||||
|
||||
expect(result).toMatchObject({ kind: 'simulated' });
|
||||
if (result.kind !== 'simulated') throw new Error('Expected a simulated session');
|
||||
expect(result.decisions).toHaveLength(3);
|
||||
expect(new Set(result.decisions.map((decision) => decision.thingFullname)).size).toBe(3);
|
||||
expect(repository.listRecentSelections(ACCOUNT)).toHaveLength(3);
|
||||
expect(result.decisions).toHaveLength(15);
|
||||
expect(new Set(result.decisions.map((decision) => decision.thingFullname)).size).toBe(15);
|
||||
expect(repository.listRecentSelections(ACCOUNT)).toHaveLength(15);
|
||||
});
|
||||
|
||||
it('caps a scheduled multi-selection session at the remaining daily target', async () => {
|
||||
@@ -335,7 +336,7 @@ describe('browsing migration', () => {
|
||||
runMigrations(db);
|
||||
const version = db.pragma('user_version', { simple: true }) as number;
|
||||
db.exec('DROP TABLE account_browsing_decisions; DROP TABLE account_browsing_settings;');
|
||||
db.pragma(`user_version = ${version - 4}`);
|
||||
db.pragma(`user_version = ${version - 5}`);
|
||||
|
||||
runMigrations(db);
|
||||
insertAccount(db, ACCOUNT, 'owner');
|
||||
@@ -343,6 +344,9 @@ describe('browsing migration', () => {
|
||||
expect(new AccountBrowsingSimulationRepository(db).getSettings(ACCOUNT)).toMatchObject({
|
||||
enabled: false, dailyTargetMin: 3, dailyTargetMax: 6, selectionsPerSession: 1, nextDueAt: null,
|
||||
});
|
||||
expect(new AccountBrowsingSimulationRepository(db).saveSettings(ACCOUNT, {
|
||||
dailyTargetMin: 20, dailyTargetMax: 40, selectionsPerSession: 25,
|
||||
})).toMatchObject({ dailyTargetMin: 20, dailyTargetMax: 40, selectionsPerSession: 25 });
|
||||
expect(db.prepare(`PRAGMA table_info(account_growth_settings)`).all())
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ name: 'daily_limit' })]));
|
||||
});
|
||||
|
||||
@@ -278,12 +278,12 @@ describe('GrowthPage', () => {
|
||||
|
||||
const size = screen.getByLabelText('Selections per session');
|
||||
await user.clear(size);
|
||||
await user.type(size, '4');
|
||||
await user.type(size, '25');
|
||||
await user.click(screen.getByRole('button', { name: 'Save session size' }));
|
||||
|
||||
await waitFor(() => expect(requests).toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({ method: 'PATCH', body: { minimumGapMs: 5_400_000 } }),
|
||||
expect.objectContaining({ method: 'PATCH', body: { selectionsPerSession: 4 } }),
|
||||
expect.objectContaining({ method: 'PATCH', body: { selectionsPerSession: 25 } }),
|
||||
])));
|
||||
});
|
||||
|
||||
@@ -293,14 +293,14 @@ describe('GrowthPage', () => {
|
||||
|
||||
const minimum = await screen.findByLabelText('Daily minimum');
|
||||
await user.clear(minimum);
|
||||
await user.type(minimum, '6');
|
||||
await user.type(minimum, '20');
|
||||
const maximum = screen.getByLabelText('Daily maximum');
|
||||
await user.clear(maximum);
|
||||
await user.type(maximum, '9');
|
||||
await user.type(maximum, '40');
|
||||
await user.click(screen.getByRole('button', { name: 'Save daily range' }));
|
||||
|
||||
await waitFor(() => expect(requests).toContainEqual(expect.objectContaining({
|
||||
method: 'PATCH', body: { dailyTargetMin: 6, dailyTargetMax: 9 },
|
||||
method: 'PATCH', body: { dailyTargetMin: 20, dailyTargetMax: 40 },
|
||||
})));
|
||||
});
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ const OTHER_ACCOUNT = '@t2_other:reddit.com';
|
||||
/** Migrations that make up account growth, replayed together in the upgrade test. */
|
||||
// Browsing migrations depend on the growth tables, so a pre-growth fixture
|
||||
// must rewind past both the growth sequence and the later browsing additions.
|
||||
const GROWTH_MIGRATION_COUNT = 6;
|
||||
const GROWTH_MIGRATION_COUNT = 7;
|
||||
|
||||
function thread(id: string, overrides: Partial<RedditPost> = {}): RedditPost {
|
||||
return {
|
||||
@@ -538,9 +538,9 @@ describe('growth migration', () => {
|
||||
runMigrations(db);
|
||||
const version = db.pragma('user_version', { simple: true }) as number;
|
||||
db.exec('ALTER TABLE account_growth_settings DROP COLUMN daily_limit');
|
||||
// Browsing simulation is the migration after the growth daily-limit
|
||||
// column, so rewind both to replay the real upgrade sequence.
|
||||
db.pragma(`user_version = ${version - 2}`);
|
||||
// Rewind the daily-limit migration and every browsing migration that now
|
||||
// follows it so the upgrade replays against the old growth row shape.
|
||||
db.pragma(`user_version = ${version - 6}`);
|
||||
insertAccount(db, ACCOUNT);
|
||||
// Seed a row with the old shape so the upgrade runs against real data.
|
||||
db.prepare(`
|
||||
|
||||
@@ -262,16 +262,16 @@ describe('growth route', () => {
|
||||
it('enables simulation within the conservative hard limits', async () => {
|
||||
const { status, json } = await call(app, 'PATCH', `/api/growth/${ENCODED}/browsing`, {
|
||||
enabled: true,
|
||||
dailyTargetMin: 4,
|
||||
dailyTargetMax: 8,
|
||||
dailyTargetMin: 14,
|
||||
dailyTargetMax: 28,
|
||||
minimumGapMs: 3_600_000,
|
||||
selectionsPerSession: 4,
|
||||
selectionsPerSession: 18,
|
||||
});
|
||||
|
||||
expect(status).toBe(200);
|
||||
const parsed = GrowthAccountResponseSchema.parse(json);
|
||||
expect(parsed.account.browsing).toMatchObject({
|
||||
settings: { enabled: true, dailyTargetMin: 4, dailyTargetMax: 8, selectionsPerSession: 4 },
|
||||
settings: { enabled: true, dailyTargetMin: 14, dailyTargetMax: 28, selectionsPerSession: 18 },
|
||||
noVotesSubmitted: true,
|
||||
});
|
||||
expect(pushed).toContainEqual({
|
||||
@@ -280,9 +280,9 @@ describe('growth route', () => {
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ dailyTargetMax: 13 },
|
||||
{ minimumGapMs: 44 * 60_000 },
|
||||
{ selectionsPerSession: 13 },
|
||||
{ dailyTargetMin: 0 },
|
||||
{ dailyTargetMax: 2 },
|
||||
{ selectionsPerSession: 0 },
|
||||
{ postWeight: 0, commentWeight: 0 },
|
||||
{ nextDueAt: 123 },
|
||||
])('rejects unsafe or non-operator settings %o', async (body) => {
|
||||
|
||||
Reference in new issue
Block a user