1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
import { neon } from "@neondatabase/serverless";
import bcrypt from "bcryptjs";
// Get the database URL from environment variables
const databaseUrl = process.env.DATABASE_URL;
const jwtSecret = process.env.JWT_SECRET;
if (!databaseUrl) {
console.error("โ DATABASE_URL environment variable is not set");
process.exit(1);
}
if (!jwtSecret) {
console.error("โ JWT_SECRET environment variable is not set");
process.exit(1);
}
console.log("โ
Environment variables are properly configured");
// Create a SQL client with the Neon database URL
const sql = neon(databaseUrl);
async function testCompleteSystem() {
try {
console.log("\n๐งช Testing Complete System...\n");
// Test 1: Database Connection
console.log("1๏ธโฃ Testing database connection...");
const dbTest = await sql`SELECT NOW() as current_time`;
console.log(`โ
Database connected successfully at ${dbTest[0].current_time}`);
// Test 2: Check if tables exist
console.log("\n2๏ธโฃ Checking database tables...");
const tables = await sql`
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_name
`;
const expectedTables = ['users', 'projects', 'project_settings', 'changelogs', 'team_members', 'api_keys', 'audit_logs'];
const existingTables = tables.map(t => t.table_name);
console.log(`๐ Found tables: ${existingTables.join(', ')}`);
for (const table of expectedTables) {
if (existingTables.includes(table)) {
console.log(`โ
Table '${table}' exists`);
} else {
console.log(`โ Table '${table}' missing`);
}
}
// Test 3: Create test user if not exists
console.log("\n3๏ธโฃ Setting up test data...");
const passwordHash = await bcrypt.hash("password123", 10);
const userResult = await sql`
INSERT INTO users (username, email, password_hash, name)
VALUES ('testuser', 'test@example.com', ${passwordHash}, 'Test User')
ON CONFLICT (email) DO UPDATE
SET username = EXCLUDED.username,
password_hash = EXCLUDED.password_hash,
name = EXCLUDED.name
RETURNING id, email, name
`;
const userId = userResult[0].id;
console.log(`โ
Test user ready: ${userResult[0].name} (${userResult[0].email})`);
// Test 4: Create sample projects
console.log("\n4๏ธโฃ Creating sample projects...");
const projects = [
{
name: "Next.js Changelog Generator",
description: "A self-hostable changelog generator built with Next.js",
repository_url: "https://github.com/vercel/next.js",
default_branch: "canary",
framework: "Next.js",
status: "active",
is_public: true,
owner_id: userId,
},
{
name: "React Components Library",
description: "A collection of reusable React components",
repository_url: "https://github.com/facebook/react",
default_branch: "main",
framework: "React",
status: "active",
is_public: false,
owner_id: userId,
}
];
for (const project of projects) {
const projectResult = await sql`
INSERT INTO projects (name, description, repository_url, default_branch, framework, status, is_public, owner_id)
VALUES (${project.name}, ${project.description}, ${project.repository_url}, ${project.default_branch}, ${project.framework}, ${project.status}, ${project.is_public}, ${project.owner_id})
ON CONFLICT (name, owner_id) DO UPDATE
SET description = EXCLUDED.description,
repository_url = EXCLUDED.repository_url,
default_branch = EXCLUDED.default_branch,
framework = EXCLUDED.framework,
status = EXCLUDED.status,
is_public = EXCLUDED.is_public,
updated_at = CURRENT_TIMESTAMP
RETURNING id, name
`;
const projectId = projectResult[0].id;
console.log(`โ
Project created/updated: ${projectResult[0].name} (ID: ${projectId})`);
// Create project settings
await sql`
INSERT INTO project_settings (project_id, use_conventional_commits, highlight_breaking_changes, auto_generate_on_tag)
VALUES (${projectId}, true, true, false)
ON CONFLICT (project_id) DO UPDATE
SET use_conventional_commits = EXCLUDED.use_conventional_commits,
highlight_breaking_changes = EXCLUDED.highlight_breaking_changes,
auto_generate_on_tag = EXCLUDED.auto_generate_on_tag,
updated_at = CURRENT_TIMESTAMP
`;
// Create sample changelog for the first project
if (project.name === "Next.js Changelog Generator") {
const changelog = `# Changelog
## [1.0.0] - ${new Date().toISOString().split('T')[0]}
### ๐ Features
- Initial release of the changelog generator
- Support for conventional commits parsing
- Multi-format output (Markdown, JSON, HTML)
- Self-hosting capabilities with Docker
- Web dashboard for project management
### ๐ Bug Fixes
- Fixed responsive layout issues
- Resolved database connection timeouts
- Fixed authentication token expiration
### ๐ Documentation
- Added comprehensive README
- Created API documentation
- Added deployment guides
### ๐งน Chores
- Set up CI/CD pipeline
- Added automated testing
- Configured code formatting`;
await sql`
INSERT INTO changelogs (project_id, title, version, from_ref, to_ref, content, format, status, commit_count, created_by, published_at)
VALUES (${projectId}, 'Initial Release', 'v1.0.0', null, 'HEAD', ${changelog}, 'markdown', 'published', 25, ${userId}, CURRENT_TIMESTAMP)
ON CONFLICT DO NOTHING
`;
console.log(`โ
Sample changelog created for ${project.name}`);
}
}
// Test 5: Verify data integrity
console.log("\n5๏ธโฃ Verifying data integrity...");
const userCount = await sql`SELECT COUNT(*) as count FROM users`;
const projectCount = await sql`SELECT COUNT(*) as count FROM projects WHERE owner_id = ${userId}`;
const changelogCount = await sql`SELECT COUNT(*) as count FROM changelogs WHERE created_by = ${userId}`;
console.log(`โ
Users in database: ${userCount[0].count}`);
console.log(`โ
Projects for test user: ${projectCount[0].count}`);
console.log(`โ
Changelogs for test user: ${changelogCount[0].count}`);
// Test 6: Test authentication flow simulation
console.log("\n6๏ธโฃ Testing authentication simulation...");
const testUser = await sql`
SELECT id, username, email, password_hash, name
FROM users
WHERE email = 'test@example.com'
`;
if (testUser.length > 0) {
const user = testUser[0];
const passwordMatch = await bcrypt.compare("password123", user.password_hash);
if (passwordMatch) {
console.log(`โ
Password verification successful for ${user.email}`);
} else {
console.log(`โ Password verification failed for ${user.email}`);
}
}
// Test 7: Test project queries
console.log("\n7๏ธโฃ Testing project queries...");
const userProjects = await sql`
SELECT p.*, ps.use_conventional_commits, ps.highlight_breaking_changes
FROM projects p
LEFT JOIN project_settings ps ON p.id = ps.project_id
WHERE p.owner_id = ${userId}
ORDER BY p.updated_at DESC
`;
console.log(`โ
Found ${userProjects.length} projects for user`);
userProjects.forEach(project => {
console.log(` ๐ ${project.name} (${project.framework}) - ${project.status}`);
});
// Test 8: Test changelog queries
console.log("\n8๏ธโฃ Testing changelog queries...");
const recentChangelogs = await sql`
SELECT c.*, p.name as project_name
FROM changelogs c
JOIN projects p ON c.project_id = p.id
WHERE p.owner_id = ${userId}
ORDER BY c.updated_at DESC
LIMIT 5
`;
console.log(`โ
Found ${recentChangelogs.length} recent changelogs`);
recentChangelogs.forEach(changelog => {
console.log(` ๐ ${changelog.title} (${changelog.project_name}) - ${changelog.status}`);
});
// Test 9: Environment configuration check
console.log("\n9๏ธโฃ Checking environment configuration...");
console.log(`โ
JWT_SECRET configured: ${jwtSecret ? 'Yes' : 'No'}`);
console.log(`โ
DATABASE_URL configured: ${databaseUrl ? 'Yes' : 'No'}`);
console.log("\n๐ All tests completed successfully!");
console.log("\n๐ Summary:");
console.log(" โ
Database connection working");
console.log(" โ
All required tables exist");
console.log(" โ
Test data created successfully");
console.log(" โ
Authentication flow ready");
console.log(" โ
Project and changelog queries working");
console.log(" โ
Environment variables configured");
console.log("\n๐ Your changelog generator is ready to use!");
console.log("\n๐ Test credentials:");
console.log(" Email: test@example.com");
console.log(" Password: password123");
} catch (error) {
console.error("\nโ Test failed:", error);
console.error(error.stack);
process.exit(1);
}
}
testCompleteSystem();No Output
Run the code to generate an output.