feat(linkedin-thought-leadership): v1.1.0 — Q2 2026 feature release
9 improvements across 3 tracks: Onboarding: /linkedin:onboarding wizard, README Quick Start rewrite Content Quality: voice drift scoring, industry angle variants, /linkedin:carousel, /linkedin:react multi-URL comparison Analytics: automated week-rollover, day-of-week heatmap, month-over-month reports 25→27 commands. All Q2 ROADMAP items completed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
abf7322200
commit
1a8cc1942c
33 changed files with 1726 additions and 236 deletions
|
|
@ -0,0 +1,102 @@
|
|||
import { describe, test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { applyWeekRollover } from '../week-rollover.mjs';
|
||||
|
||||
const SAMPLE_STATE = `---
|
||||
last_post_date: "2026-04-05"
|
||||
first_post_date: "2026-01-15"
|
||||
last_post_topic: "AI strategy"
|
||||
posts_this_week: 3
|
||||
weekly_goal: 3
|
||||
current_streak: 5
|
||||
longest_streak: 12
|
||||
current_week: "2026-W14"
|
||||
last_import_date: "2026-04-01"
|
||||
follower_count: 850
|
||||
follower_target: 10000
|
||||
target_date: "2026-12-31"
|
||||
---
|
||||
|
||||
## Recent Posts
|
||||
- 2026-04-05: AI strategy post
|
||||
`;
|
||||
|
||||
describe('applyWeekRollover', () => {
|
||||
test('resets posts_this_week to 0 on week change', () => {
|
||||
const result = applyWeekRollover(SAMPLE_STATE, '2026-W14', '2026-W15');
|
||||
assert.notEqual(result, null);
|
||||
assert.match(result.content, /^posts_this_week: 0$/m);
|
||||
});
|
||||
|
||||
test('updates current_week to new week', () => {
|
||||
const result = applyWeekRollover(SAMPLE_STATE, '2026-W14', '2026-W15');
|
||||
assert.notEqual(result, null);
|
||||
assert.match(result.content, /^current_week: "2026-W15"$/m);
|
||||
});
|
||||
|
||||
test('returns descriptive message on rollover', () => {
|
||||
const result = applyWeekRollover(SAMPLE_STATE, '2026-W14', '2026-W15');
|
||||
assert.notEqual(result, null);
|
||||
assert.ok(result.message.includes('2026-W15'));
|
||||
assert.ok(result.message.includes('2026-W14'));
|
||||
});
|
||||
|
||||
test('returns null when week matches (no change needed)', () => {
|
||||
const result = applyWeekRollover(SAMPLE_STATE, '2026-W14', '2026-W14');
|
||||
assert.equal(result, null);
|
||||
});
|
||||
|
||||
test('preserves all other YAML fields unchanged', () => {
|
||||
const result = applyWeekRollover(SAMPLE_STATE, '2026-W14', '2026-W15');
|
||||
assert.notEqual(result, null);
|
||||
assert.match(result.content, /^last_post_date: "2026-04-05"$/m);
|
||||
assert.match(result.content, /^current_streak: 5$/m);
|
||||
assert.match(result.content, /^weekly_goal: 3$/m);
|
||||
assert.match(result.content, /^follower_count: 850$/m);
|
||||
});
|
||||
|
||||
test('preserves markdown body after frontmatter', () => {
|
||||
const result = applyWeekRollover(SAMPLE_STATE, '2026-W14', '2026-W15');
|
||||
assert.notEqual(result, null);
|
||||
assert.ok(result.content.includes('## Recent Posts'));
|
||||
assert.ok(result.content.includes('AI strategy post'));
|
||||
});
|
||||
|
||||
test('initializes current_week when empty without resetting posts', () => {
|
||||
const stateWithEmptyWeek = SAMPLE_STATE.replace(
|
||||
'current_week: "2026-W14"',
|
||||
'current_week: ""'
|
||||
);
|
||||
const result = applyWeekRollover(stateWithEmptyWeek, '', '2026-W15');
|
||||
assert.notEqual(result, null);
|
||||
assert.match(result.content, /^current_week: "2026-W15"$/m);
|
||||
// posts_this_week should NOT be reset (user may have manually tracked)
|
||||
assert.match(result.content, /^posts_this_week: 3$/m);
|
||||
});
|
||||
|
||||
test('returns null when actualWeek is empty', () => {
|
||||
const result = applyWeekRollover(SAMPLE_STATE, '2026-W14', '');
|
||||
assert.equal(result, null);
|
||||
});
|
||||
|
||||
test('returns null when actualWeek is null/undefined', () => {
|
||||
assert.equal(applyWeekRollover(SAMPLE_STATE, '2026-W14', null), null);
|
||||
assert.equal(applyWeekRollover(SAMPLE_STATE, '2026-W14', undefined), null);
|
||||
});
|
||||
|
||||
test('handles year boundary rollover (W52 → W01)', () => {
|
||||
const yearEndState = SAMPLE_STATE.replace('2026-W14', '2025-W52');
|
||||
const result = applyWeekRollover(yearEndState, '2025-W52', '2026-W01');
|
||||
assert.notEqual(result, null);
|
||||
assert.match(result.content, /^posts_this_week: 0$/m);
|
||||
assert.match(result.content, /^current_week: "2026-W01"$/m);
|
||||
});
|
||||
|
||||
test('handles posts_this_week already at 0', () => {
|
||||
const zeroPostsState = SAMPLE_STATE.replace('posts_this_week: 3', 'posts_this_week: 0');
|
||||
const result = applyWeekRollover(zeroPostsState, '2026-W14', '2026-W15');
|
||||
assert.notEqual(result, null);
|
||||
assert.match(result.content, /^posts_this_week: 0$/m);
|
||||
assert.match(result.content, /^current_week: "2026-W15"$/m);
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue