255 lines
8.7 KiB
255 lines
8.7 KiB
/* |
|
* Spreed WebRTC. |
|
* Copyright (C) 2013-2015 struktur AG |
|
* |
|
* This file is part of Spreed WebRTC. |
|
* |
|
* This program is free software: you can redistribute it and/or modify |
|
* it under the terms of the GNU Affero General Public License as published by |
|
* the Free Software Foundation, either version 3 of the License, or |
|
* (at your option) any later version. |
|
* |
|
* This program is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU Affero General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU Affero General Public License |
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
* |
|
*/ |
|
|
|
package api |
|
|
|
import ( |
|
"errors" |
|
"fmt" |
|
"testing" |
|
|
|
"github.com/gorilla/securecookie" |
|
|
|
"github.com/strukturag/spreed-webrtc/go/buffercache" |
|
"github.com/strukturag/spreed-webrtc/go/channelling" |
|
) |
|
|
|
type fakeClient struct { |
|
} |
|
|
|
func (fake *fakeClient) Index() uint64 { |
|
return 0 |
|
} |
|
|
|
func (fake *fakeClient) Send(_ buffercache.Buffer) { |
|
} |
|
|
|
type fakeRoomManager struct { |
|
joinedRoomID string |
|
leftRoomID string |
|
roomUsers []*channelling.DataSession |
|
joinedID string |
|
joinError error |
|
leftID string |
|
broadcasts []interface{} |
|
updatedRoom *channelling.DataRoom |
|
updateError error |
|
} |
|
|
|
func (fake *fakeRoomManager) RoomUsers(session *channelling.Session) []*channelling.DataSession { |
|
return fake.roomUsers |
|
} |
|
|
|
func (fake *fakeRoomManager) JoinRoom(id, roomName, roomType string, _ *channelling.DataRoomCredentials, session *channelling.Session, sessionAuthenticated bool, _ channelling.Sender) (*channelling.DataRoom, error) { |
|
fake.joinedID = id |
|
return &channelling.DataRoom{Name: roomName, Type: roomType}, fake.joinError |
|
} |
|
|
|
func (fake *fakeRoomManager) LeaveRoom(roomID, sessionID string) { |
|
fake.leftID = roomID |
|
} |
|
|
|
func (fake *fakeRoomManager) Broadcast(_, _ string, outgoing *channelling.DataOutgoing) { |
|
fake.broadcasts = append(fake.broadcasts, outgoing.Data) |
|
} |
|
|
|
func (fake *fakeRoomManager) UpdateRoom(_ *channelling.Session, _ *channelling.DataRoom) (*channelling.DataRoom, error) { |
|
return fake.updatedRoom, fake.updateError |
|
} |
|
|
|
func (fake *fakeRoomManager) MakeRoomID(roomName, roomType string) string { |
|
if roomType == "" { |
|
roomType = "Room" |
|
} |
|
return fmt.Sprintf("%s:%s", roomType, roomName) |
|
} |
|
|
|
func NewTestChannellingAPI() (channelling.ChannellingAPI, *fakeClient, *channelling.Session, *fakeRoomManager) { |
|
apiConsumer := channelling.NewChannellingAPIConsumer() |
|
client, roomManager := &fakeClient{}, &fakeRoomManager{} |
|
sessionNonces := securecookie.New(securecookie.GenerateRandomKey(64), nil) |
|
session := channelling.NewSession(nil, nil, roomManager, roomManager, nil, sessionNonces, "", "") |
|
busManager := channelling.NewBusManager(apiConsumer, "", false, "") |
|
api := New(nil, roomManager, nil, nil, nil, nil, nil, nil, busManager, nil) |
|
apiConsumer.SetChannellingAPI(api) |
|
return api, client, session, roomManager |
|
} |
|
|
|
func Test_ChannellingAPI_OnIncoming_HelloMessage_JoinsTheSelectedRoom(t *testing.T) { |
|
roomID, roomName, ua := "Room:foobar", "foobar", "unit tests" |
|
api, client, session, roomManager := NewTestChannellingAPI() |
|
|
|
api.OnIncoming(client, session, &channelling.DataIncoming{Type: "Hello", Hello: &channelling.DataHello{Id: roomName, Ua: ua}}) |
|
|
|
if roomManager.joinedID != roomID { |
|
t.Errorf("Expected to have joined room %v, but got %v", roomID, roomManager.joinedID) |
|
} |
|
|
|
if broadcastCount := len(roomManager.broadcasts); broadcastCount != 1 { |
|
t.Fatalf("Expected 1 broadcast, but got %d", broadcastCount) |
|
} |
|
|
|
dataSession, ok := roomManager.broadcasts[0].(*channelling.DataSession) |
|
if !ok { |
|
t.Fatal("Expected a session data broadcast") |
|
} |
|
|
|
if dataSession.Ua != ua { |
|
t.Errorf("Expected to have broadcasted a user agent of %v, but was %v", ua, dataSession.Ua) |
|
} |
|
} |
|
|
|
func Test_ChannellingAPI_OnIncoming_HelloMessage_LeavesAnyPreviouslyJoinedRooms(t *testing.T) { |
|
roomID, roomName := "Room:foobar", "foobar" |
|
api, client, session, roomManager := NewTestChannellingAPI() |
|
|
|
api.OnIncoming(client, session, &channelling.DataIncoming{Type: "Hello", Hello: &channelling.DataHello{Id: roomName}}) |
|
api.OnIncoming(client, session, &channelling.DataIncoming{Type: "Hello", Hello: &channelling.DataHello{Id: "baz"}}) |
|
|
|
if roomManager.leftID != roomID { |
|
t.Errorf("Expected to have left room %v, but got %v", roomID, roomManager.leftID) |
|
} |
|
|
|
if broadcastCount := len(roomManager.broadcasts); broadcastCount != 3 { |
|
t.Fatalf("Expected 3 broadcasts, but got %d", broadcastCount) |
|
} |
|
|
|
dataSession, ok := roomManager.broadcasts[1].(*channelling.DataSession) |
|
if !ok { |
|
t.Fatal("Expected a session data broadcast") |
|
} |
|
|
|
if status := "soft"; dataSession.Status != status { |
|
t.Errorf("Expected to have broadcast a leave status of of %v, but was %v", status, dataSession.Status) |
|
} |
|
} |
|
|
|
func Test_ChannellingAPI_OnIncoming_HelloMessage_DoesNotJoinIfNotPermitted(t *testing.T) { |
|
api, client, session, roomManager := NewTestChannellingAPI() |
|
roomManager.joinError = errors.New("Can't enter this room") |
|
|
|
api.OnIncoming(client, session, &channelling.DataIncoming{Type: "Hello", Hello: &channelling.DataHello{}}) |
|
|
|
if broadcastCount := len(roomManager.broadcasts); broadcastCount != 0 { |
|
t.Fatalf("Expected no broadcasts, but got %d", broadcastCount) |
|
} |
|
} |
|
|
|
func Test_ChannellingAPI_OnIncoming_HelloMessage_RespondsWithAWelcome(t *testing.T) { |
|
roomID := "a-room" |
|
api, client, session, roomManager := NewTestChannellingAPI() |
|
roomManager.roomUsers = []*channelling.DataSession{&channelling.DataSession{}} |
|
|
|
reply, err := api.OnIncoming(client, session, &channelling.DataIncoming{Type: "Hello", Hello: &channelling.DataHello{Id: roomID}}) |
|
if err != nil { |
|
t.Fatalf("Unexpected error %v", err) |
|
} |
|
|
|
welcome, ok := reply.(*channelling.DataWelcome) |
|
if !ok { |
|
t.Fatalf("Expected response %#v to be a Welcome", reply) |
|
} |
|
|
|
if welcome.Type != "Welcome" { |
|
t.Error("Message did not have the correct type") |
|
} |
|
|
|
if welcome.Room == nil || welcome.Room.Name != roomID { |
|
t.Errorf("Expected room with name %v, but got %#v", roomID, welcome.Room) |
|
} |
|
|
|
if len(welcome.Users) != len(roomManager.roomUsers) { |
|
t.Errorf("Expected to get users %#v, but was %#v", roomManager.roomUsers, welcome.Users) |
|
} |
|
} |
|
|
|
func Test_ChannellingAPI_OnIncoming_HelloMessage_RespondsWithAnErrorIfTheRoomCannotBeJoined(t *testing.T) { |
|
api, client, session, roomManager := NewTestChannellingAPI() |
|
roomManager.joinError = channelling.NewDataError("bad_join", "") |
|
|
|
_, err := api.OnIncoming(client, session, &channelling.DataIncoming{Type: "Hello", Hello: &channelling.DataHello{}}) |
|
|
|
assertDataError(t, err, "bad_join") |
|
} |
|
|
|
func Test_ChannellingAPI_OnIncoming_RoomMessage_RespondsWithAndBroadcastsTheUpdatedRoom(t *testing.T) { |
|
roomName := "foo" |
|
api, client, session, roomManager := NewTestChannellingAPI() |
|
roomManager.updatedRoom = &channelling.DataRoom{Name: "FOO"} |
|
|
|
_, err := api.OnIncoming(client, session, &channelling.DataIncoming{Type: "Hello", Hello: &channelling.DataHello{Id: roomName}}) |
|
if err != nil { |
|
t.Fatalf("Unexpected error %v", err) |
|
} |
|
|
|
reply, err := api.OnIncoming(client, session, &channelling.DataIncoming{Type: "Room", Room: &channelling.DataRoom{Name: roomName}}) |
|
if err != nil { |
|
t.Fatalf("Unexpected error %v", err) |
|
} |
|
|
|
room, ok := reply.(*channelling.DataRoom) |
|
if !ok { |
|
t.Fatalf("Expected response message to be a Room") |
|
} |
|
|
|
if room.Name != roomManager.updatedRoom.Name { |
|
t.Errorf("Expected updated room with name %v, but got %#v", roomManager.updatedRoom, room) |
|
} |
|
|
|
if broadcastCount := len(roomManager.broadcasts); broadcastCount != 2 { |
|
t.Fatalf("Expected 1 broadcasts, but got %d", broadcastCount) |
|
} |
|
|
|
if _, ok := roomManager.broadcasts[1].(*channelling.DataRoom); !ok { |
|
t.Fatal("Expected a room data broadcast") |
|
} |
|
} |
|
|
|
func Test_ChannellingAPI_OnIncoming_RoomMessage_RespondsWithAnErrorIfUpdatingTheRoomFails(t *testing.T) { |
|
roomName := "foo" |
|
api, client, session, roomManager := NewTestChannellingAPI() |
|
roomManager.updateError = channelling.NewDataError("a_room_error", "") |
|
|
|
_, err := api.OnIncoming(client, session, &channelling.DataIncoming{Type: "Hello", Hello: &channelling.DataHello{Id: roomName}}) |
|
if err != nil { |
|
t.Fatalf("Unexpected error %v", err) |
|
} |
|
_, err = api.OnIncoming(client, session, &channelling.DataIncoming{Type: "Room", Room: &channelling.DataRoom{Name: roomName}}) |
|
|
|
assertDataError(t, err, "a_room_error") |
|
} |
|
|
|
func assertDataError(t *testing.T, err error, code string) { |
|
if err == nil { |
|
t.Error("Expected an error, but none was returned") |
|
return |
|
} |
|
|
|
dataError, ok := err.(*channelling.DataError) |
|
if !ok { |
|
t.Errorf("Expected error %#v to be a *DataError", err) |
|
return |
|
} |
|
|
|
if code != dataError.Code { |
|
t.Errorf("Expected error code to be %v, but was %v", code, dataError.Code) |
|
} |
|
}
|
|
|