Этот коммит содержится в:
Saturnino Abril
2017-04-04 02:34:14 +09:00
коммит произвёл Corey Hulen
родитель 6b61834ab1
Коммит 43e795448f
10 изменённых файлов: 364 добавлений и 1 удалений

Просмотреть файл

@@ -20,6 +20,7 @@ func InitTeam() {
BaseRoutes.Teams.Handle("", ApiSessionRequired(createTeam)).Methods("POST") BaseRoutes.Teams.Handle("", ApiSessionRequired(createTeam)).Methods("POST")
BaseRoutes.Teams.Handle("", ApiSessionRequired(getAllTeams)).Methods("GET") BaseRoutes.Teams.Handle("", ApiSessionRequired(getAllTeams)).Methods("GET")
BaseRoutes.Teams.Handle("/search", ApiSessionRequired(searchTeams)).Methods("POST")
BaseRoutes.TeamsForUser.Handle("", ApiSessionRequired(getTeamsForUser)).Methods("GET") BaseRoutes.TeamsForUser.Handle("", ApiSessionRequired(getTeamsForUser)).Methods("GET")
BaseRoutes.TeamsForUser.Handle("/unread", ApiSessionRequired(getTeamsUnreadForUser)).Methods("GET") BaseRoutes.TeamsForUser.Handle("/unread", ApiSessionRequired(getTeamsUnreadForUser)).Methods("GET")
@@ -456,6 +457,35 @@ func getAllTeams(c *Context, w http.ResponseWriter, r *http.Request) {
w.Write([]byte(model.TeamListToJson(teams))) w.Write([]byte(model.TeamListToJson(teams)))
} }
func searchTeams(c *Context, w http.ResponseWriter, r *http.Request) {
props := model.TeamSearchFromJson(r.Body)
if props == nil {
c.SetInvalidParam("team_search")
return
}
if len(props.Term) == 0 {
c.SetInvalidParam("term")
return
}
var teams []*model.Team
var err *model.AppError
if app.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
teams, err = app.SearchAllTeams(props.Term)
} else {
teams, err = app.SearchOpenTeams(props.Term)
}
if err != nil {
c.Err = err
return
}
w.Write([]byte(model.TeamListToJson(teams)))
}
func teamExists(c *Context, w http.ResponseWriter, r *http.Request) { func teamExists(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireTeamName() c.RequireTeamName()
if c.Err != nil { if c.Err != nil {

Просмотреть файл

@@ -7,6 +7,7 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"net/http" "net/http"
"reflect"
"strconv" "strconv"
"strings" "strings"
"testing" "testing"
@@ -405,6 +406,81 @@ func TestGetTeamByName(t *testing.T) {
CheckForbiddenStatus(t, resp) CheckForbiddenStatus(t, resp)
} }
func TestSearchAllTeams(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer TearDown()
Client := th.Client
oTeam := th.BasicTeam
pTeam := &model.Team{DisplayName: "PName", Name: GenerateTestTeamName(), Email: GenerateTestEmail(), Type: model.TEAM_INVITE}
Client.CreateTeam(pTeam)
rteams, resp := Client.SearchTeams(&model.TeamSearch{Term: oTeam.Name})
CheckNoError(t, resp)
if len(rteams) != 1 {
t.Fatal("should have returned 1 team")
}
if !reflect.DeepEqual(rteams[0], oTeam) {
t.Fatal("invalid team")
}
rteams, resp = Client.SearchTeams(&model.TeamSearch{Term: oTeam.DisplayName})
CheckNoError(t, resp)
if len(rteams) != 1 {
t.Fatal("should have returned 1 team")
}
if !reflect.DeepEqual(rteams[0], oTeam) {
t.Fatal("invalid team")
}
rteams, resp = Client.SearchTeams(&model.TeamSearch{Term: pTeam.Name})
CheckNoError(t, resp)
if len(rteams) != 0 {
t.Fatal("should have not returned team")
}
rteams, resp = Client.SearchTeams(&model.TeamSearch{Term: pTeam.DisplayName})
CheckNoError(t, resp)
if len(rteams) != 0 {
t.Fatal("should have not returned team")
}
rteams, resp = th.SystemAdminClient.SearchTeams(&model.TeamSearch{Term: oTeam.Name})
CheckNoError(t, resp)
if len(rteams) != 1 {
t.Fatal("should have returned 1 team")
}
rteams, resp = th.SystemAdminClient.SearchTeams(&model.TeamSearch{Term: pTeam.DisplayName})
CheckNoError(t, resp)
if len(rteams) != 1 {
t.Fatal("should have returned 1 team")
}
rteams, resp = Client.SearchTeams(&model.TeamSearch{Term: "junk"})
CheckNoError(t, resp)
if len(rteams) != 0 {
t.Fatal("should have not returned team")
}
Client.Logout()
rteams, resp = Client.SearchTeams(&model.TeamSearch{Term: pTeam.Name})
CheckUnauthorizedStatus(t, resp)
rteams, resp = Client.SearchTeams(&model.TeamSearch{Term: pTeam.DisplayName})
CheckUnauthorizedStatus(t, resp)
}
func TestGetTeamsForUser(t *testing.T) { func TestGetTeamsForUser(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin() th := Setup().InitBasic().InitSystemAdmin()
defer TearDown() defer TearDown()

Просмотреть файл

@@ -367,6 +367,22 @@ func GetAllOpenTeams() ([]*model.Team, *model.AppError) {
} }
} }
func SearchAllTeams(term string) ([]*model.Team, *model.AppError) {
if result := <-Srv.Store.Team().SearchAll(term); result.Err != nil {
return nil, result.Err
} else {
return result.Data.([]*model.Team), nil
}
}
func SearchOpenTeams(term string) ([]*model.Team, *model.AppError) {
if result := <-Srv.Store.Team().SearchOpen(term); result.Err != nil {
return nil, result.Err
} else {
return result.Data.([]*model.Team), nil
}
}
func GetAllOpenTeamsPage(offset int, limit int) ([]*model.Team, *model.AppError) { func GetAllOpenTeamsPage(offset int, limit int) ([]*model.Team, *model.AppError) {
if result := <-Srv.Store.Team().GetAllTeamPageListing(offset, limit); result.Err != nil { if result := <-Srv.Store.Team().GetAllTeamPageListing(offset, limit); result.Err != nil {
return nil, result.Err return nil, result.Err

Просмотреть файл

@@ -5511,6 +5511,14 @@
"id": "store.sql_team.save_member.save.app_error", "id": "store.sql_team.save_member.save.app_error",
"translation": "We couldn't save the team member" "translation": "We couldn't save the team member"
}, },
{
"id": "store.sql_team.search_open_team.app_error",
"translation": "We encountered an error searching open teams"
},
{
"id": "store.sql_team.search_all_team.app_error",
"translation": "We encountered an error searching teams"
},
{ {
"id": "store.sql_team.update.app_error", "id": "store.sql_team.update.app_error",
"translation": "We couldn't update the team" "translation": "We couldn't update the team"

Просмотреть файл

@@ -842,6 +842,16 @@ func (c *Client4) GetTeamByName(name, etag string) (*Team, *Response) {
} }
} }
// SearchTeams returns teams matching the provided search term.
func (c *Client4) SearchTeams(search *TeamSearch) ([]*Team, *Response) {
if r, err := c.DoApiPost(c.GetTeamsRoute()+"/search", search.ToJson()); err != nil {
return nil, &Response{StatusCode: r.StatusCode, Error: err}
} else {
defer closeBody(r)
return TeamListFromJson(r.Body), BuildResponse(r)
}
}
// TeamExists returns true or false if the team exist or not. // TeamExists returns true or false if the team exist or not.
func (c *Client4) TeamExists(name, etag string) (bool, *Response) { func (c *Client4) TeamExists(name, etag string) (bool, *Response) {
if r, err := c.DoApiGet(c.GetTeamByNameRoute(name)+"/exists", etag); err != nil { if r, err := c.DoApiGet(c.GetTeamByNameRoute(name)+"/exists", etag); err != nil {

35
model/team_search.go Обычный файл
Просмотреть файл

@@ -0,0 +1,35 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package model
import (
"encoding/json"
"io"
)
type TeamSearch struct {
Term string `json:"term"`
}
// ToJson convert a TeamSearch to json string
func (c *TeamSearch) ToJson() string {
b, err := json.Marshal(c)
if err != nil {
return ""
}
return string(b)
}
// TeamSearchFromJson decodes the input and returns a TeamSearch
func TeamSearchFromJson(data io.Reader) *TeamSearch {
decoder := json.NewDecoder(data)
var cs TeamSearch
err := decoder.Decode(&cs)
if err == nil {
return &cs
}
return nil
}

19
model/team_search_test.go Обычный файл
Просмотреть файл

@@ -0,0 +1,19 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package model
import (
"strings"
"testing"
)
func TestTeamSearchJson(t *testing.T) {
teamSearch := TeamSearch{Term: NewId()}
json := teamSearch.ToJson()
rteamSearch := ChannelSearchFromJson(strings.NewReader(json))
if teamSearch.Term != rteamSearch.Term {
t.Fatal("Terms do not match")
}
}

Просмотреть файл

@@ -257,6 +257,48 @@ func (s SqlTeamStore) SearchByName(name string) StoreChannel {
return storeChannel return storeChannel
} }
func (s SqlTeamStore) SearchAll(term string) StoreChannel {
storeChannel := make(StoreChannel, 1)
go func() {
result := StoreResult{}
var teams []*model.Team
if _, err := s.GetReplica().Select(&teams, "SELECT * FROM Teams WHERE Name LIKE :Term OR DisplayName LIKE :Term", map[string]interface{}{"Term": term + "%"}); err != nil {
result.Err = model.NewLocAppError("SqlTeamStore.SearchAll", "store.sql_team.search_all_team.app_error", nil, "term="+term+", "+err.Error())
}
result.Data = teams
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlTeamStore) SearchOpen(term string) StoreChannel {
storeChannel := make(StoreChannel, 1)
go func() {
result := StoreResult{}
var teams []*model.Team
if _, err := s.GetReplica().Select(&teams, "SELECT * FROM Teams WHERE Type = 'O' AND (Name LIKE :Term OR DisplayName LIKE :Term)", map[string]interface{}{"Term": term + "%"}); err != nil {
result.Err = model.NewLocAppError("SqlTeamStore.SearchOpen", "store.sql_team.search_open_team.app_error", nil, "term="+term+", "+err.Error())
}
result.Data = teams
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlTeamStore) GetAll() StoreChannel { func (s SqlTeamStore) GetAll() StoreChannel {
storeChannel := make(StoreChannel, 1) storeChannel := make(StoreChannel, 1)

Просмотреть файл

@@ -4,9 +4,10 @@
package store package store
import ( import (
"github.com/mattermost/platform/model"
"testing" "testing"
"time" "time"
"github.com/mattermost/platform/model"
) )
func TestTeamStoreSave(t *testing.T) { func TestTeamStoreSave(t *testing.T) {
@@ -156,6 +157,130 @@ func TestTeamStoreSearchByName(t *testing.T) {
} }
} }
func TestTeamStoreSearchAll(t *testing.T) {
Setup()
o1 := model.Team{}
o1.DisplayName = "ADisplayName" + model.NewId()
o1.Name = "a" + model.NewId() + "a"
o1.Email = model.NewId() + "@nowhere.com"
o1.Type = model.TEAM_OPEN
if err := (<-store.Team().Save(&o1)).Err; err != nil {
t.Fatal(err)
}
p2 := model.Team{}
p2.DisplayName = "BDisplayName" + model.NewId()
p2.Name = "b" + model.NewId() + "b"
p2.Email = model.NewId() + "@nowhere.com"
p2.Type = model.TEAM_INVITE
if err := (<-store.Team().Save(&p2)).Err; err != nil {
t.Fatal(err)
}
r1 := <-store.Team().SearchAll(o1.Name)
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 1 {
t.Fatal("should have returned 1 team")
}
if r1.Data.([]*model.Team)[0].ToJson() != o1.ToJson() {
t.Fatal("invalid returned team")
}
r1 = <-store.Team().SearchAll(p2.DisplayName)
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 1 {
t.Fatal("should have returned 1 team")
}
if r1.Data.([]*model.Team)[0].ToJson() != p2.ToJson() {
t.Fatal("invalid returned team")
}
r1 = <-store.Team().SearchAll("junk")
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 0 {
t.Fatal("should have not returned a team")
}
}
func TestTeamStoreSearchOpen(t *testing.T) {
Setup()
o1 := model.Team{}
o1.DisplayName = "ADisplayName" + model.NewId()
o1.Name = "a" + model.NewId() + "a"
o1.Email = model.NewId() + "@nowhere.com"
o1.Type = model.TEAM_OPEN
if err := (<-store.Team().Save(&o1)).Err; err != nil {
t.Fatal(err)
}
p2 := model.Team{}
p2.DisplayName = "BDisplayName" + model.NewId()
p2.Name = "b" + model.NewId() + "b"
p2.Email = model.NewId() + "@nowhere.com"
p2.Type = model.TEAM_INVITE
if err := (<-store.Team().Save(&p2)).Err; err != nil {
t.Fatal(err)
}
r1 := <-store.Team().SearchOpen(o1.Name)
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 1 {
t.Fatal("should have returned 1 team")
}
if r1.Data.([]*model.Team)[0].ToJson() != o1.ToJson() {
t.Fatal("invalid returned team")
}
r1 = <-store.Team().SearchOpen(o1.DisplayName)
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 1 {
t.Fatal("should have returned 1 team")
}
if r1.Data.([]*model.Team)[0].ToJson() != o1.ToJson() {
t.Fatal("invalid returned team")
}
r1 = <-store.Team().SearchOpen(p2.Name)
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 0 {
t.Fatal("should have not returned a team")
}
r1 = <-store.Team().SearchOpen(p2.DisplayName)
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 0 {
t.Fatal("should have not returned a team")
}
r1 = <-store.Team().SearchOpen("junk")
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 0 {
t.Fatal("should have not returned a team")
}
}
func TestTeamStoreGetByIniviteId(t *testing.T) { func TestTeamStoreGetByIniviteId(t *testing.T) {
Setup() Setup()

Просмотреть файл

@@ -61,6 +61,8 @@ type TeamStore interface {
Get(id string) StoreChannel Get(id string) StoreChannel
GetByName(name string) StoreChannel GetByName(name string) StoreChannel
SearchByName(name string) StoreChannel SearchByName(name string) StoreChannel
SearchAll(term string) StoreChannel
SearchOpen(term string) StoreChannel
GetAll() StoreChannel GetAll() StoreChannel
GetAllPage(offset int, limit int) StoreChannel GetAllPage(offset int, limit int) StoreChannel
GetAllTeamListing() StoreChannel GetAllTeamListing() StoreChannel