|
| 1 | +import { describe, it, expect } from 'vitest'; |
| 2 | +import { buildDbSetupCommand, buildRedisSetupCommand } from '../../src/cli/commands/setup.js'; |
| 3 | + |
| 4 | +describe('buildDbSetupCommand', () => { |
| 5 | + it('postgres: installs, creates user and db', () => { |
| 6 | + const cmd = buildDbSetupCommand({ type: 'postgres', host: 'localhost', port: 5432, name: 'mydb', user: 'myuser' }); |
| 7 | + expect(cmd).toContain('apt-get install -y postgresql postgresql-contrib'); |
| 8 | + expect(cmd).toContain('systemctl enable postgresql'); |
| 9 | + expect(cmd).toContain('CREATE USER \\"myuser\\"'); |
| 10 | + expect(cmd).toContain("datname='mydb'"); |
| 11 | + expect(cmd).toContain('createdb -O "myuser" "mydb"'); |
| 12 | + }); |
| 13 | + |
| 14 | + it('postgres: includes password in createUser when provided', () => { |
| 15 | + const cmd = buildDbSetupCommand({ type: 'postgres', host: 'localhost', port: 5432, name: 'mydb', user: 'myuser', password: 'secret' }); |
| 16 | + expect(cmd).toContain("WITH PASSWORD 'secret'"); |
| 17 | + }); |
| 18 | + |
| 19 | + it('postgres: adds login probe when password is provided', () => { |
| 20 | + const cmd = buildDbSetupCommand({ type: 'postgres', host: 'localhost', port: 5432, name: 'mydb', user: 'myuser', password: 'secret' }); |
| 21 | + expect(cmd).toContain("PGPASSWORD='secret' psql -h localhost -U 'myuser' -d 'mydb'"); |
| 22 | + }); |
| 23 | + |
| 24 | + it('postgres: no login probe without password', () => { |
| 25 | + const cmd = buildDbSetupCommand({ type: 'postgres', host: 'localhost', port: 5432, name: 'mydb', user: 'myuser' }); |
| 26 | + expect(cmd).not.toContain('PGPASSWORD'); |
| 27 | + }); |
| 28 | + |
| 29 | + it('postgres: escapes $ in user/name with shDq to prevent shell expansion', () => { |
| 30 | + const cmd = buildDbSetupCommand({ type: 'postgres', host: 'localhost', port: 5432, name: '$mydb', user: '$myuser', password: 'p' }); |
| 31 | + expect(cmd).toContain('\\$myuser'); |
| 32 | + expect(cmd).toContain('\\$mydb'); |
| 33 | + }); |
| 34 | + |
| 35 | + it('mysql: installs, creates user and db', () => { |
| 36 | + const cmd = buildDbSetupCommand({ type: 'mysql', host: 'localhost', port: 3306, name: 'mydb', user: 'myuser' }); |
| 37 | + expect(cmd).toContain('apt-get install -y mysql-server'); |
| 38 | + expect(cmd).toContain("CREATE USER IF NOT EXISTS 'myuser'@'localhost'"); |
| 39 | + expect(cmd).toContain('CREATE DATABASE IF NOT EXISTS'); |
| 40 | + expect(cmd).toContain("GRANT ALL PRIVILEGES ON"); |
| 41 | + expect(cmd).toContain('FLUSH PRIVILEGES'); |
| 42 | + }); |
| 43 | + |
| 44 | + it('mysql: adds login probe when password is provided', () => { |
| 45 | + const cmd = buildDbSetupCommand({ type: 'mysql', host: 'localhost', port: 3306, name: 'mydb', user: 'myuser', password: 'secret' }); |
| 46 | + expect(cmd).toContain("MYSQL_PWD='secret' mysql -h 127.0.0.1 -u 'myuser' 'mydb'"); |
| 47 | + }); |
| 48 | + |
| 49 | + it('mysql: no login probe without password', () => { |
| 50 | + const cmd = buildDbSetupCommand({ type: 'mysql', host: 'localhost', port: 3306, name: 'mydb', user: 'myuser' }); |
| 51 | + expect(cmd).not.toContain('MYSQL_PWD'); |
| 52 | + }); |
| 53 | + |
| 54 | + it('mongodb: installs and starts mongod', () => { |
| 55 | + const cmd = buildDbSetupCommand({ type: 'mongodb', host: 'localhost', port: 27017, name: 'mydb', user: 'myuser' }); |
| 56 | + expect(cmd).toContain('command -v mongod'); |
| 57 | + expect(cmd).toContain('mongodb-org'); |
| 58 | + expect(cmd).toContain('systemctl enable mongod'); |
| 59 | + expect(cmd).toContain('systemctl start mongod'); |
| 60 | + }); |
| 61 | + |
| 62 | + it('mongodb: enables auth and creates user when password provided', () => { |
| 63 | + const cmd = buildDbSetupCommand({ type: 'mongodb', host: 'localhost', port: 27017, name: 'mydb', user: 'myuser', password: 'secret' }); |
| 64 | + expect(cmd).toContain('authorization: enabled'); |
| 65 | + expect(cmd).toContain("db.createUser({user:'myuser',pwd:'secret'"); |
| 66 | + }); |
| 67 | + |
| 68 | + it('mongodb: adds login probe when password provided', () => { |
| 69 | + const cmd = buildDbSetupCommand({ type: 'mongodb', host: 'localhost', port: 27017, name: 'mydb', user: 'myuser', password: 'secret' }); |
| 70 | + expect(cmd).toContain("mongosh --host localhost 'mydb' -u 'myuser' -p 'secret'"); |
| 71 | + }); |
| 72 | + |
| 73 | + it('mongodb: no auth or user creation without password', () => { |
| 74 | + const cmd = buildDbSetupCommand({ type: 'mongodb', host: 'localhost', port: 27017, name: 'mydb', user: 'myuser' }); |
| 75 | + expect(cmd).not.toContain('authorization'); |
| 76 | + expect(cmd).not.toContain('createUser'); |
| 77 | + }); |
| 78 | + |
| 79 | + it('throws for sqlite', () => { |
| 80 | + expect(() => buildDbSetupCommand({ type: 'sqlite', name: './data.db' })).toThrow(); |
| 81 | + }); |
| 82 | +}); |
| 83 | + |
| 84 | +describe('buildRedisSetupCommand', () => { |
| 85 | + it('installs and starts redis', () => { |
| 86 | + const cmd = buildRedisSetupCommand({ host: 'localhost', port: 6379 }); |
| 87 | + expect(cmd).toContain('apt-get install -y redis-server'); |
| 88 | + expect(cmd).toContain('systemctl enable redis-server'); |
| 89 | + expect(cmd).toContain('systemctl start redis-server'); |
| 90 | + expect(cmd).not.toContain('requirepass'); |
| 91 | + }); |
| 92 | + |
| 93 | + it('sets requirepass and restarts when password provided', () => { |
| 94 | + const cmd = buildRedisSetupCommand({ host: 'localhost', port: 6379, password: 'secret' }); |
| 95 | + expect(cmd).toContain('requirepass secret'); |
| 96 | + expect(cmd).toContain('systemctl restart redis-server'); |
| 97 | + }); |
| 98 | + |
| 99 | + it('adds login probe when password provided', () => { |
| 100 | + const cmd = buildRedisSetupCommand({ host: 'localhost', port: 6379, password: 'secret' }); |
| 101 | + expect(cmd).toContain("redis-cli -h localhost -p 6379 -a 'secret' PING"); |
| 102 | + }); |
| 103 | + |
| 104 | + it('does not use / as sed delimiter — password with slash must not break sed', () => { |
| 105 | + const cmd = buildRedisSetupCommand({ host: 'localhost', port: 6379, password: 'pass/word' }); |
| 106 | + // Old code used s/.../.../ which breaks on /; new code deletes and appends instead |
| 107 | + expect(cmd).not.toMatch(/sed -i "s\//); |
| 108 | + expect(cmd).toContain('requirepass pass/word'); |
| 109 | + }); |
| 110 | + |
| 111 | + it('escapes $ in password to prevent shell expansion', () => { |
| 112 | + const cmd = buildRedisSetupCommand({ host: 'localhost', port: 6379, password: '$ecret' }); |
| 113 | + expect(cmd).toContain('\\$ecret'); |
| 114 | + }); |
| 115 | +}); |
0 commit comments