generated from VLADIMIR/template
135 lines
5.2 KiB
Go
135 lines
5.2 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"evening_detective_server/internal/modules/cudy"
|
|
"evening_detective_server/internal/modules/processor_jwt"
|
|
"evening_detective_server/internal/services/device_presence_service"
|
|
"evening_detective_server/internal/services/game_service"
|
|
"evening_detective_server/internal/services/screen_service"
|
|
"evening_detective_server/internal/services/team_service"
|
|
"evening_detective_server/internal/services/wifi_service"
|
|
proto "evening_detective_server/proto"
|
|
|
|
"github.com/google/uuid"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/metadata"
|
|
"google.golang.org/grpc/status"
|
|
"google.golang.org/protobuf/encoding/protojson"
|
|
)
|
|
|
|
func TestDeviceTransport(t *testing.T) {
|
|
s := &server{devicePresenceService: device_presence_service.NewDevicePresenceService(true, nil, nil, nil)}
|
|
ctx := metadata.NewIncomingContext(context.Background(), metadata.Pairs("x-real-ip", "192.0.2.3", "grpcgateway-user-agent", "test-browser"))
|
|
req := &proto.DeviceHeartbeatReq{DeviceID: uuid.NewString(), ConnectionID: uuid.NewString()}
|
|
rsp, err := s.DeviceHeartbeat(ctx, req)
|
|
if err != nil || !rsp.GetEnabled() || rsp.ServerTime == nil {
|
|
t.Fatal(rsp, err)
|
|
}
|
|
for _, role := range []string{"organizer", "admin", "developer", "author", "user", ""} {
|
|
t.Run(role, func(t *testing.T) {
|
|
roleCtx := processor_jwt.ContextWithClaims(ctx, &processor_jwt.JWTClaims{Roles: []string{role}})
|
|
devices, err := s.GetDevices(roleCtx, &proto.GetDevicesReq{})
|
|
if role == "author" || role == "user" || role == "" {
|
|
if status.Code(err) != codes.PermissionDenied {
|
|
t.Fatal(err)
|
|
}
|
|
return
|
|
}
|
|
if err != nil || len(devices.Devices) != 1 {
|
|
t.Fatal(devices, err)
|
|
}
|
|
connection := devices.Devices[0].Connections[0]
|
|
if connection.IP != "192.0.2.3" || connection.UserAgent != "test-browser" {
|
|
t.Fatal(connection)
|
|
}
|
|
raw, err := protojson.Marshal(devices)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, secret := range []string{"password", "accessToken", "ScreenTokenHash", "email", "URL"} {
|
|
if strings.Contains(string(raw), secret) {
|
|
t.Fatal("secret field in response")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
req.DeviceID = "bad"
|
|
if _, err = s.DeviceHeartbeat(ctx, req); status.Code(err) != codes.InvalidArgument {
|
|
t.Fatal(err)
|
|
}
|
|
s.devicePresenceService = device_presence_service.NewDevicePresenceService(false, nil, nil, nil)
|
|
rsp, err = s.DeviceHeartbeat(ctx, req)
|
|
if err != nil || rsp.GetEnabled() {
|
|
t.Fatal(rsp, err)
|
|
}
|
|
raw, err := protojson.Marshal(rsp)
|
|
if err != nil || !strings.Contains(string(raw), `"enabled":false`) {
|
|
t.Fatal("disabled flag must be explicit", string(raw), err)
|
|
}
|
|
if _, err = s.GetDevices(ctx, &proto.GetDevicesReq{}); status.Code(err) != codes.FailedPrecondition {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestDeviceErrors(t *testing.T) {
|
|
for _, test := range []struct {
|
|
err error
|
|
code codes.Code
|
|
}{
|
|
{context.Canceled, codes.Canceled},
|
|
{context.DeadlineExceeded, codes.DeadlineExceeded},
|
|
{device_presence_service.ErrInvalid, codes.InvalidArgument},
|
|
{device_presence_service.ErrDisabled, codes.FailedPrecondition},
|
|
{device_presence_service.ErrPermission, codes.PermissionDenied},
|
|
{device_presence_service.ErrUnauthorized, codes.Unauthenticated},
|
|
{device_presence_service.ErrFull, codes.ResourceExhausted},
|
|
{team_service.ErrTeamNotFound, codes.NotFound},
|
|
{game_service.ErrGameNotFound, codes.NotFound},
|
|
{screen_service.ErrScreenNotFound, codes.Unauthenticated},
|
|
{errors.New("SQL password=secret /private/path"), codes.Internal},
|
|
} {
|
|
err := deviceErrorStatus(test.err)
|
|
if status.Code(err) != test.code || strings.Contains(err.Error(), "secret") || strings.Contains(err.Error(), "/private") {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestWiFiUsesExistingPresencePermissions(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "state.json")
|
|
signal := -65
|
|
snapshot := cudy.Snapshot{Enabled: true, CollectedAt: time.Now().UTC(), Clients: []cudy.Client{{IP: "192.168.10.9", MAC: "AA:BB:CC:DD:EE:01", Band: "5 GHz", Signal: &signal}}}
|
|
data, err := json.Marshal(snapshot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(path, data, 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
s := &server{devicePresenceService: device_presence_service.NewDevicePresenceService(true, nil, nil, nil), wifiService: wifi_service.New(path)}
|
|
for _, role := range []string{"organizer", "developer", "admin"} {
|
|
ctx := processor_jwt.ContextWithClaims(context.Background(), &processor_jwt.JWTClaims{Roles: []string{role}})
|
|
result, err := s.GetDevices(ctx, &proto.GetDevicesReq{})
|
|
if err != nil || !result.Wifi.Enabled || result.Wifi.Stale || len(result.Wifi.Clients) != 1 || result.Wifi.Clients[0].GetSignal() != -65 {
|
|
t.Fatalf("Wi-Fi for %s: %v, %v", role, result, err)
|
|
}
|
|
}
|
|
if _, err := s.GetDevices(context.Background(), &proto.GetDevicesReq{}); status.Code(err) != codes.PermissionDenied {
|
|
t.Fatal(err)
|
|
}
|
|
s.devicePresenceService = device_presence_service.NewDevicePresenceService(false, nil, nil, nil)
|
|
ctx := processor_jwt.ContextWithClaims(context.Background(), &processor_jwt.JWTClaims{Roles: []string{"developer"}})
|
|
if _, err := s.GetDevices(ctx, &proto.GetDevicesReq{}); status.Code(err) != codes.FailedPrecondition {
|
|
t.Fatal("prod exposes Wi-Fi", err)
|
|
}
|
|
}
|