Skip to content
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
2 changes: 1 addition & 1 deletion .cursor/skills/writing-x-posts/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Create engaging X (Twitter) posts and threads that capture attention, drive enga
### Brevity is Power
X rewards concise, punchy content. Every word must earn its place. If you can say it in fewer words, do it.

### One Idea Per Tweet
### One Idea Per Tweeta
Single tweets should contain one complete thought. Threads expand on ideas but each tweet should still stand alone.

### Hook or Die
Expand Down
38 changes: 36 additions & 2 deletions actions/content-plan.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,12 @@ describe('createPlan', () => {
mockFrom.mockImplementation((table: string) => {
if (table === 'subscriptions') {
return createChainMock({
data: { id: 'sub-1', plans: { slug: 'basic-monthly' } },
data: { id: 'sub-1', plans: { slug: 'basic-monthly', max_posts_per_generation: 1 } },
});
}
if (table === 'credits') {
return createChainMock({ data: { balance: 50 } });
}
return createChainMock({ data: null });
});

Expand All @@ -183,7 +186,7 @@ describe('createPlan', () => {
const result = await createPlan(validCreatePlanInput);

expect(result.success).toBe(false);
expect(result.error).toBe('Insufficient credits');
expect(result.error).toContain('Insufficient credits');
});

it('should create plan and posts successfully', async () => {
Expand Down Expand Up @@ -306,6 +309,9 @@ describe('regeneratePost', () => {
it('should regenerate post successfully', async () => {
mockGetUser.mockResolvedValue({ data: { user: mockUser } });
mockFrom.mockImplementation((table: string) => {
if (table === 'subscriptions') {
return createChainMock({ data: { id: 'sub-1', plans: { slug: 'pro-monthly', max_posts_per_generation: 5 } } });
}
if (table === 'posts') {
const chain = createChainMock({
data: {
Expand Down Expand Up @@ -347,6 +353,9 @@ describe('regeneratePost', () => {
it('should include memory context in regenerate prompt', async () => {
mockGetUser.mockResolvedValue({ data: { user: mockUser } });
mockFrom.mockImplementation((table: string) => {
if (table === 'subscriptions') {
return createChainMock({ data: { id: 'sub-1', plans: { slug: 'pro-monthly', max_posts_per_generation: 5 } } });
}
if (table === 'posts') {
const chain = createChainMock({
data: {
Expand Down Expand Up @@ -520,6 +529,12 @@ describe('schedulePlan', () => {
if (table === 'content_plans') {
return createChainMock({ data: { id: 'plan-123' } });
}
if (table === 'subscriptions') {
return createChainMock({ data: { id: 'sub-1', plans: { slug: 'pro-monthly', max_posts_per_generation: 5 } } });
}
if (table === 'credits') {
return createChainMock({ data: { balance: 50 } });
}
if (table === 'posts') {
const makeChainable = (): Record<string, ReturnType<typeof vi.fn>> => {
const c: Record<string, ReturnType<typeof vi.fn>> = {};
Expand Down Expand Up @@ -563,6 +578,12 @@ describe('schedulePlan', () => {
if (table === 'content_plans') {
return createChainMock({ data: { id: 'plan-123' } });
}
if (table === 'subscriptions') {
return createChainMock({ data: { id: 'sub-1', plans: { slug: 'pro-monthly', max_posts_per_generation: 5 } } });
}
if (table === 'credits') {
return createChainMock({ data: { balance: 50 } });
}
if (table === 'posts') {
const makeChainable = (): Record<string, ReturnType<typeof vi.fn>> => {
const c: Record<string, ReturnType<typeof vi.fn>> = {};
Expand All @@ -587,6 +608,7 @@ describe('schedulePlan', () => {
return createChainMock({ data: null });
});


await schedulePlan({
planId: '550e8400-e29b-41d4-a716-446655440000',
platformConnectionIds: [twConnId],
Expand Down Expand Up @@ -615,6 +637,12 @@ describe('schedulePlan', () => {
if (table === 'content_plans') {
return createChainMock({ data: { id: 'plan-123' } });
}
if (table === 'subscriptions') {
return createChainMock({ data: { id: 'sub-1', plans: { slug: 'pro-monthly', max_posts_per_generation: 5 } } });
}
if (table === 'credits') {
return createChainMock({ data: { balance: 50 } });
}
if (table === 'posts') {
const makeChainable = (): Record<string, ReturnType<typeof vi.fn>> => {
const c: Record<string, ReturnType<typeof vi.fn>> = {};
Expand Down Expand Up @@ -659,6 +687,12 @@ describe('schedulePlan', () => {
if (table === 'content_plans') {
return createChainMock({ data: { id: 'plan-123' } });
}
if (table === 'subscriptions') {
return createChainMock({ data: { id: 'sub-1', plans: { slug: 'pro-monthly', max_posts_per_generation: 5 } } });
}
if (table === 'credits') {
return createChainMock({ data: { balance: 50 } });
}
if (table === 'posts') {
const makeChainable = (): Record<string, ReturnType<typeof vi.fn>> => {
const c: Record<string, ReturnType<typeof vi.fn>> = {};
Expand Down
Loading
Loading