toBeTrue(); $check = DB::selectOne( "SELECT pg_get_constraintdef(c.oid) AS def FROM pg_constraint c JOIN pg_class t ON c.conrelid = t.oid WHERE t.relname = 'projects' AND c.conname LIKE '%signal_type%'" ); expect($check->def) ->toContain("'site'") ->toContain("'call'") ->toContain("'sms'"); }); test('projects table has signal_identifier text column', function () { expect(Schema::hasColumn('projects', 'signal_identifier'))->toBeTrue(); }); test('projects table has sms_senders jsonb array column', function () { expect(Schema::hasColumn('projects', 'sms_senders'))->toBeTrue(); $type = DB::selectOne( "SELECT data_type FROM information_schema.columns WHERE table_name = 'projects' AND column_name = 'sms_senders'" ); expect($type->data_type)->toBe('jsonb'); }); test('projects table has sms_keyword nullable text column', function () { expect(Schema::hasColumn('projects', 'sms_keyword'))->toBeTrue(); $col = DB::selectOne( "SELECT is_nullable FROM information_schema.columns WHERE table_name = 'projects' AND column_name = 'sms_keyword'" ); expect($col->is_nullable)->toBe('YES'); }); test('projects table has delivered_in_month integer counter', function () { expect(Schema::hasColumn('projects', 'delivered_in_month'))->toBeTrue(); }); test('projects table has supplier_b1_project_id, b2, b3 nullable FK columns', function () { foreach (['supplier_b1_project_id', 'supplier_b2_project_id', 'supplier_b3_project_id'] as $col) { expect(Schema::hasColumn('projects', $col))->toBeTrue(); } }); test('signal_type sms requires sms_senders non-empty (CHECK constraint)', function () { $check = DB::selectOne( "SELECT pg_get_constraintdef(c.oid) AS def FROM pg_constraint c JOIN pg_class t ON c.conrelid = t.oid WHERE t.relname = 'projects' AND c.conname = 'chk_projects_sms_senders_required'" ); expect($check)->not->toBeNull(); expect($check->def)->toContain('signal_type'); });