roomserver/alias: Add test cases, load from DB if appserviceAPI says AliasExists

Signed-off-by: Serra Allgood <serra@allgood.dev>
This commit is contained in:
Serra Allgood 2019-06-01 17:33:32 -07:00
parent 6a7cc65cdb
commit da234d4dab
2 changed files with 149 additions and 21 deletions

View file

@ -84,6 +84,19 @@ func (r *RoomserverAliasAPI) SetRoomAlias(
return r.sendUpdatedAliasesEvent(context.TODO(), request.UserID, request.RoomID) return r.sendUpdatedAliasesEvent(context.TODO(), request.UserID, request.RoomID)
} }
func getRoomIDFromDB(
ctx context.Context,
db RoomserverAliasAPIDatabase,
request *roomserverAPI.GetRoomIDForAliasRequest,
) (string, error) {
roomID, err := db.GetRoomIDForAlias(ctx, request.Alias)
if err != nil {
return "", err
}
return roomID, nil
}
// GetRoomIDForAlias implements alias.RoomserverAliasAPI // GetRoomIDForAlias implements alias.RoomserverAliasAPI
func (r *RoomserverAliasAPI) GetRoomIDForAlias( func (r *RoomserverAliasAPI) GetRoomIDForAlias(
ctx context.Context, ctx context.Context,
@ -91,12 +104,12 @@ func (r *RoomserverAliasAPI) GetRoomIDForAlias(
response *roomserverAPI.GetRoomIDForAliasResponse, response *roomserverAPI.GetRoomIDForAliasResponse,
) error { ) error {
// Look up the room ID in the database // Look up the room ID in the database
roomID, err := r.DB.GetRoomIDForAlias(ctx, request.Alias) roomID, err := getRoomIDFromDB(ctx, r.DB, request)
if err != nil { if err != nil {
return err return err
} }
if len(roomID) == 0 { if roomID == "" {
// No rooms found locally, try our application services by making a call to // No rooms found locally, try our application services by making a call to
// the appservice component // the appservice component
aliasReq := appserviceAPI.RoomAliasExistsRequest{Alias: request.Alias} aliasReq := appserviceAPI.RoomAliasExistsRequest{Alias: request.Alias}
@ -104,6 +117,13 @@ func (r *RoomserverAliasAPI) GetRoomIDForAlias(
if err = r.AppserviceAPI.RoomAliasExists(ctx, &aliasReq, &aliasResp); err != nil { if err = r.AppserviceAPI.RoomAliasExists(ctx, &aliasReq, &aliasResp); err != nil {
return err return err
} }
if aliasResp.AliasExists {
roomID, err = getRoomIDFromDB(ctx, r.DB, request)
if err != nil {
return err
}
}
} }
response.RoomID = roomID response.RoomID = roomID

View file

@ -1,4 +1,4 @@
// Copyright 2017 Vector Creations Ltd // Copyright 2019 Serra Allgood
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -17,20 +17,21 @@ package alias
import ( import (
"context" "context"
"fmt" "fmt"
"strings"
"testing" "testing"
appserviceAPI "github.com/matrix-org/dendrite/appservice/api" appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
) )
type MockRoomserverAliasAPIDatabase struct{} type MockRoomserverAliasAPIDatabase struct {
methodModes map[string]string
func (db MockRoomserverAliasAPIDatabase) SetRoomAlias(ctx context.Context, alias string, roomID string) error { attempts int
return nil
} }
func (db MockRoomserverAliasAPIDatabase) GetRoomIDForAlias(ctx context.Context, alias string) (string, error) { // Those methods can be essentially noop
return "123", nil func (db MockRoomserverAliasAPIDatabase) SetRoomAlias(ctx context.Context, alias string, roomID string) error {
return nil
} }
func (db MockRoomserverAliasAPIDatabase) GetAliasesForRoomID(ctx context.Context, roomID string) ([]string, error) { func (db MockRoomserverAliasAPIDatabase) GetAliasesForRoomID(ctx context.Context, roomID string) ([]string, error) {
@ -42,8 +43,36 @@ func (db MockRoomserverAliasAPIDatabase) RemoveRoomAlias(ctx context.Context, al
return nil return nil
} }
type MockAppServiceQueryAPI struct{} // This method needs to change depending on test case
func (db MockRoomserverAliasAPIDatabase) GetRoomIDForAlias(ctx context.Context, alias string) (string, error) {
switch db.methodModes["GetRoomIDForAlias"] {
case "empty":
return "", nil
case "error":
return "", fmt.Errorf("found an error from GetRoomIDForAlias")
case "found":
return "123", nil
case "emptyFound":
switch db.attempts {
case 0:
db.attempts = 1
return "", nil
case 1:
db.attempts = 0
return "123", nil
default:
return "", nil
}
default:
return "", fmt.Errorf("Unknown option used")
}
}
type MockAppServiceQueryAPI struct {
methodModes map[string]string
}
// This method can be noop
func (q MockAppServiceQueryAPI) UserIDExists( func (q MockAppServiceQueryAPI) UserIDExists(
ctx context.Context, ctx context.Context,
req *appserviceAPI.UserIDExistsRequest, req *appserviceAPI.UserIDExistsRequest,
@ -57,27 +86,49 @@ func (q MockAppServiceQueryAPI) RoomAliasExists(
req *appserviceAPI.RoomAliasExistsRequest, req *appserviceAPI.RoomAliasExistsRequest,
resp *appserviceAPI.RoomAliasExistsResponse, resp *appserviceAPI.RoomAliasExistsResponse,
) error { ) error {
return fmt.Errorf("Should not have called this") switch q.methodModes["RoomAliasExists"] {
case "error":
return fmt.Errorf("found an error from RoomAliasExists")
case "found":
resp.AliasExists = true
return nil
case "empty":
resp.AliasExists = false
return nil
default:
return fmt.Errorf("Unknown option used")
}
} }
func TestGetRoomIDForAlias(t *testing.T) { func TestGetRoomIDForAlias(t *testing.T) {
type args struct { type arguments struct {
ctx context.Context ctx context.Context
request *roomserverAPI.GetRoomIDForAliasRequest request *roomserverAPI.GetRoomIDForAliasRequest
response *roomserverAPI.GetRoomIDForAliasResponse response *roomserverAPI.GetRoomIDForAliasResponse
} }
t.Run("Found local alias", func(t *testing.T) { args := arguments{
aliasAPI := &RoomserverAliasAPI{
DB: MockRoomserverAliasAPIDatabase{},
AppserviceAPI: MockAppServiceQueryAPI{},
}
args := args{
context.Background(), context.Background(),
&roomserverAPI.GetRoomIDForAliasRequest{}, &roomserverAPI.GetRoomIDForAliasRequest{},
&roomserverAPI.GetRoomIDForAliasResponse{}, &roomserverAPI.GetRoomIDForAliasResponse{},
} }
setup := func(modes map[string]string) *RoomserverAliasAPI {
mockAliasAPIDB := MockRoomserverAliasAPIDatabase{modes, 0}
mockAppServiceQueryAPI := MockAppServiceQueryAPI{modes}
return &RoomserverAliasAPI{
DB: mockAliasAPIDB,
AppserviceAPI: mockAppServiceQueryAPI,
}
}
t.Run("Found local alias", func(t *testing.T) {
methodModes := make(map[string]string)
methodModes["GetRoomIDForAlias"] = "found"
methodModes["RoomAliasExists"] = "error"
aliasAPI := setup(methodModes)
err := aliasAPI.GetRoomIDForAlias(args.ctx, args.request, args.response) err := aliasAPI.GetRoomIDForAlias(args.ctx, args.request, args.response)
if err != nil { if err != nil {
t.Errorf("Got %s; wanted no error", err) t.Errorf("Got %s; wanted no error", err)
@ -87,4 +138,61 @@ func TestGetRoomIDForAlias(t *testing.T) {
t.Errorf("Got %s; wanted 123", args.response.RoomID) t.Errorf("Got %s; wanted 123", args.response.RoomID)
} }
}) })
t.Run("found appservice alias", func(t *testing.T) {
methodModes := make(map[string]string)
methodModes["GetRoomIDForAlias"] = "emptyFound"
methodModes["RoomAliasExists"] = "found"
aliasAPI := setup(methodModes)
if err := aliasAPI.GetRoomIDForAlias(args.ctx, args.request, args.response); err != nil {
t.Fatalf("Got %s; wanted no error", err)
}
if args.response.RoomID != "123" {
t.Errorf("Got %s; wanted 123", args.response.RoomID)
}
})
t.Run("error returned from DB", func(t *testing.T) {
methodModes := make(map[string]string)
methodModes["GetRoomIDForAlias"] = "error"
aliasAPI := setup(methodModes)
err := aliasAPI.GetRoomIDForAlias(args.ctx, args.request, args.response)
if err == nil {
t.Fatalf("Got no error; wanted error from DB")
} else if !strings.Contains(err.Error(), "GetRoomIDForAlias") {
t.Errorf("Got %s; wanted error from GetRoomIDForAlias", err)
}
})
t.Run("error returned from appserviceAPI", func(t *testing.T) {
methodModes := make(map[string]string)
methodModes["GetRoomIDForAlias"] = "empty"
methodModes["RoomAliasExists"] = "error"
aliasAPI := setup(methodModes)
err := aliasAPI.GetRoomIDForAlias(args.ctx, args.request, args.response)
if err == nil {
t.Fatalf("Got no error; wanted error from appserviceAPI")
} else if !strings.Contains(err.Error(), "RoomAliasExists") {
t.Errorf("Got %s; wanted error from RoomAliasExists", err)
}
})
t.Run("no errors but no alias", func(t *testing.T) {
methodModes := make(map[string]string)
methodModes["GetRoomIDForAlias"] = "empty"
methodModes["RoomAliasExists"] = "empty"
aliasAPI := setup(methodModes)
args.response.RoomID = "Should be empty"
if err := aliasAPI.GetRoomIDForAlias(args.ctx, args.request, args.response); err != nil {
t.Fatalf("Got %s; wanted no error", err)
}
if args.response.RoomID != "" {
t.Errorf("response.RoomID should have been empty")
}
})
} }