From da234d4dab9120a650dcc9542ab01574d7b3b069 Mon Sep 17 00:00:00 2001 From: Serra Allgood Date: Sat, 1 Jun 2019 17:33:32 -0700 Subject: [PATCH] roomserver/alias: Add test cases, load from DB if appserviceAPI says AliasExists Signed-off-by: Serra Allgood --- roomserver/alias/alias.go | 24 ++- .../dendrite/roomserver/alias/alias_test.go | 146 +++++++++++++++--- 2 files changed, 149 insertions(+), 21 deletions(-) diff --git a/roomserver/alias/alias.go b/roomserver/alias/alias.go index e6602c743..1b07f53eb 100644 --- a/roomserver/alias/alias.go +++ b/roomserver/alias/alias.go @@ -84,6 +84,19 @@ func (r *RoomserverAliasAPI) SetRoomAlias( 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 func (r *RoomserverAliasAPI) GetRoomIDForAlias( ctx context.Context, @@ -91,12 +104,12 @@ func (r *RoomserverAliasAPI) GetRoomIDForAlias( response *roomserverAPI.GetRoomIDForAliasResponse, ) error { // 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 { return err } - if len(roomID) == 0 { + if roomID == "" { // No rooms found locally, try our application services by making a call to // the appservice component aliasReq := appserviceAPI.RoomAliasExistsRequest{Alias: request.Alias} @@ -104,6 +117,13 @@ func (r *RoomserverAliasAPI) GetRoomIDForAlias( if err = r.AppserviceAPI.RoomAliasExists(ctx, &aliasReq, &aliasResp); err != nil { return err } + + if aliasResp.AliasExists { + roomID, err = getRoomIDFromDB(ctx, r.DB, request) + if err != nil { + return err + } + } } response.RoomID = roomID diff --git a/src/github.com/matrix-org/dendrite/roomserver/alias/alias_test.go b/src/github.com/matrix-org/dendrite/roomserver/alias/alias_test.go index 4bbff9846..516d3bba9 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/alias/alias_test.go +++ b/src/github.com/matrix-org/dendrite/roomserver/alias/alias_test.go @@ -1,4 +1,4 @@ -// Copyright 2017 Vector Creations Ltd +// Copyright 2019 Serra Allgood // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,20 +17,21 @@ package alias import ( "context" "fmt" + "strings" "testing" appserviceAPI "github.com/matrix-org/dendrite/appservice/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" ) -type MockRoomserverAliasAPIDatabase struct{} - -func (db MockRoomserverAliasAPIDatabase) SetRoomAlias(ctx context.Context, alias string, roomID string) error { - return nil +type MockRoomserverAliasAPIDatabase struct { + methodModes map[string]string + attempts int } -func (db MockRoomserverAliasAPIDatabase) GetRoomIDForAlias(ctx context.Context, alias string) (string, error) { - return "123", nil +// Those methods can be essentially noop +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) { @@ -42,8 +43,36 @@ func (db MockRoomserverAliasAPIDatabase) RemoveRoomAlias(ctx context.Context, al 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( ctx context.Context, req *appserviceAPI.UserIDExistsRequest, @@ -57,26 +86,48 @@ func (q MockAppServiceQueryAPI) RoomAliasExists( req *appserviceAPI.RoomAliasExistsRequest, resp *appserviceAPI.RoomAliasExistsResponse, ) 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) { - type args struct { + type arguments struct { ctx context.Context request *roomserverAPI.GetRoomIDForAliasRequest response *roomserverAPI.GetRoomIDForAliasResponse } + args := arguments{ + context.Background(), + &roomserverAPI.GetRoomIDForAliasRequest{}, + &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) { - aliasAPI := &RoomserverAliasAPI{ - DB: MockRoomserverAliasAPIDatabase{}, - AppserviceAPI: MockAppServiceQueryAPI{}, - } - args := args{ - context.Background(), - &roomserverAPI.GetRoomIDForAliasRequest{}, - &roomserverAPI.GetRoomIDForAliasResponse{}, - } + methodModes := make(map[string]string) + methodModes["GetRoomIDForAlias"] = "found" + methodModes["RoomAliasExists"] = "error" + aliasAPI := setup(methodModes) err := aliasAPI.GetRoomIDForAlias(args.ctx, args.request, args.response) if err != nil { @@ -87,4 +138,61 @@ func TestGetRoomIDForAlias(t *testing.T) { 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") + } + }) }