package ws import ( "testing" "time" "github.com/DATA-DOG/go-sqlmock" "gorm.io/driver/postgres" "gorm.io/gorm" ) func TestDBDeviceAuthorizerRequiresOrganizationMembership(t *testing.T) { sqlDB, mock, err := sqlmock.New() if err != nil { t.Fatalf("create sqlmock: %v", err) } defer sqlDB.Close() db, err := gorm.Open(postgres.New(postgres.Config{Conn: sqlDB}), &gorm.Config{}) if err != nil { t.Fatalf("open gorm: %v", err) } mock.ExpectQuery(`.*FROM "users".*WHERE id = \$1.*`). WillReturnRows(sqlmock.NewRows([]string{"id", "username", "email", "password_hash", "full_name", "role", "active", "created_at", "updated_at"}). AddRow("user-1", "viewer", "viewer@example.com", "hash", nil, "viewer", true, time.Now(), time.Now())) mock.ExpectQuery(`.*role_permissions.*permissions.*`). WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1)) mock.ExpectQuery(`.*FROM "devices".*WHERE device_key = \$1.*`). WillReturnRows(sqlmock.NewRows([]string{"id", "device_key", "name", "kind", "model", "firmware", "online_status", "last_seen", "room_id", "topic", "created_at", "updated_at"}). AddRow("device-1", "device-a", "温度设备", "sensor", nil, nil, "online", nil, "room-1", nil, time.Now(), time.Now())) mock.ExpectQuery(`.*organization_members.*`). WithArgs("room-1", "user-1"). WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1)) authorizer := NewDBDeviceAuthorizer(db) ok, err := authorizer.CanReadDevice("user-1", "device-a") if err != nil { t.Fatalf("CanReadDevice error: %v", err) } if !ok { t.Fatal("member should read device in same organization") } if err := mock.ExpectationsWereMet(); err != nil { t.Fatalf("unmet sql expectations: %v", err) } } func TestDBDeviceAuthorizerDeniesForeignRoom(t *testing.T) { sqlDB, mock, err := sqlmock.New() if err != nil { t.Fatalf("create sqlmock: %v", err) } defer sqlDB.Close() db, err := gorm.Open(postgres.New(postgres.Config{Conn: sqlDB}), &gorm.Config{}) if err != nil { t.Fatalf("open gorm: %v", err) } mock.ExpectQuery(`.*FROM "users".*WHERE id = \$1.*`). WillReturnRows(sqlmock.NewRows([]string{"id", "username", "email", "password_hash", "full_name", "role", "active", "created_at", "updated_at"}). AddRow("user-1", "viewer", "viewer@example.com", "hash", nil, "viewer", true, time.Now(), time.Now())) mock.ExpectQuery(`.*role_permissions.*permissions.*`). WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1)) mock.ExpectQuery(`.*FROM "devices".*WHERE device_key = \$1.*`). WillReturnRows(sqlmock.NewRows([]string{"id", "device_key", "name", "kind", "model", "firmware", "online_status", "last_seen", "room_id", "topic", "created_at", "updated_at"}). AddRow("device-1", "device-a", "温度设备", "sensor", nil, nil, "online", nil, "room-1", nil, time.Now(), time.Now())) mock.ExpectQuery(`.*organization_members.*`). WithArgs("room-1", "user-1"). WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(0)) authorizer := NewDBDeviceAuthorizer(db) ok, err := authorizer.CanReadDevice("user-1", "device-a") if err != nil { t.Fatalf("CanReadDevice error: %v", err) } if ok { t.Fatal("user in another organization should not read device") } if err := mock.ExpectationsWereMet(); err != nil { t.Fatalf("unmet sql expectations: %v", err) } }