github.com/qichengzx/mattermost-server@v4.5.1-0.20180604164826-2c75247c97d0+incompatible/plugin/rpcplugin/api_test.go (about) 1 package rpcplugin 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "net/http" 8 "testing" 9 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/mock" 12 "github.com/stretchr/testify/require" 13 14 "github.com/mattermost/mattermost-server/model" 15 "github.com/mattermost/mattermost-server/plugin" 16 "github.com/mattermost/mattermost-server/plugin/plugintest" 17 ) 18 19 func testAPIRPC(api plugin.API, f func(plugin.API)) { 20 r1, w1 := io.Pipe() 21 r2, w2 := io.Pipe() 22 23 c1 := NewMuxer(NewReadWriteCloser(r1, w2), false) 24 defer c1.Close() 25 26 c2 := NewMuxer(NewReadWriteCloser(r2, w1), true) 27 defer c2.Close() 28 29 id, server := c1.Serve() 30 go ServeAPI(api, server, c1) 31 32 remote := ConnectAPI(c2.Connect(id), c2) 33 defer remote.Close() 34 35 f(remote) 36 } 37 38 func TestAPI(t *testing.T) { 39 keyValueStore := &plugintest.KeyValueStore{} 40 api := plugintest.API{Store: keyValueStore} 41 defer api.AssertExpectations(t) 42 43 type Config struct { 44 Foo string 45 Bar struct { 46 Baz string 47 } 48 } 49 50 api.On("LoadPluginConfiguration", mock.MatchedBy(func(x interface{}) bool { return true })).Run(func(args mock.Arguments) { 51 dest := args.Get(0).(interface{}) 52 json.Unmarshal([]byte(`{"Foo": "foo", "Bar": {"Baz": "baz"}}`), dest) 53 }).Return(nil) 54 55 testChannel := &model.Channel{ 56 Id: "thechannelid", 57 } 58 59 testChannelMember := &model.ChannelMember{ 60 ChannelId: "thechannelid", 61 UserId: "theuserid", 62 } 63 64 testTeam := &model.Team{ 65 Id: "theteamid", 66 } 67 teamNotFoundError := model.NewAppError("SqlTeamStore.GetByName", "store.sql_team.get_by_name.app_error", nil, "name=notateam", http.StatusNotFound) 68 69 testUser := &model.User{ 70 Id: "theuserid", 71 } 72 73 testPost := &model.Post{ 74 Message: "hello", 75 } 76 77 testAPIRPC(&api, func(remote plugin.API) { 78 var config Config 79 assert.NoError(t, remote.LoadPluginConfiguration(&config)) 80 assert.Equal(t, "foo", config.Foo) 81 assert.Equal(t, "baz", config.Bar.Baz) 82 83 api.On("RegisterCommand", mock.AnythingOfType("*model.Command")).Return(fmt.Errorf("foo")).Once() 84 assert.Error(t, remote.RegisterCommand(&model.Command{})) 85 api.On("RegisterCommand", mock.AnythingOfType("*model.Command")).Return(nil).Once() 86 assert.NoError(t, remote.RegisterCommand(&model.Command{})) 87 88 api.On("UnregisterCommand", "team", "trigger").Return(fmt.Errorf("foo")).Once() 89 assert.Error(t, remote.UnregisterCommand("team", "trigger")) 90 api.On("UnregisterCommand", "team", "trigger").Return(nil).Once() 91 assert.NoError(t, remote.UnregisterCommand("team", "trigger")) 92 93 api.On("CreateChannel", mock.AnythingOfType("*model.Channel")).Return(func(c *model.Channel) *model.Channel { 94 c.Id = "thechannelid" 95 return c 96 }, nil).Once() 97 channel, err := remote.CreateChannel(testChannel) 98 assert.Equal(t, "thechannelid", channel.Id) 99 assert.Nil(t, err) 100 101 api.On("DeleteChannel", "thechannelid").Return(nil).Once() 102 assert.Nil(t, remote.DeleteChannel("thechannelid")) 103 104 api.On("GetChannel", "thechannelid").Return(testChannel, nil).Once() 105 channel, err = remote.GetChannel("thechannelid") 106 assert.Equal(t, testChannel, channel) 107 assert.Nil(t, err) 108 109 api.On("GetChannelByName", "foo", "theteamid").Return(testChannel, nil).Once() 110 channel, err = remote.GetChannelByName("foo", "theteamid") 111 assert.Equal(t, testChannel, channel) 112 assert.Nil(t, err) 113 114 api.On("GetDirectChannel", "user1", "user2").Return(testChannel, nil).Once() 115 channel, err = remote.GetDirectChannel("user1", "user2") 116 assert.Equal(t, testChannel, channel) 117 assert.Nil(t, err) 118 119 api.On("GetGroupChannel", []string{"user1", "user2", "user3"}).Return(testChannel, nil).Once() 120 channel, err = remote.GetGroupChannel([]string{"user1", "user2", "user3"}) 121 assert.Equal(t, testChannel, channel) 122 assert.Nil(t, err) 123 124 api.On("UpdateChannel", mock.AnythingOfType("*model.Channel")).Return(func(c *model.Channel) *model.Channel { 125 return c 126 }, nil).Once() 127 channel, err = remote.UpdateChannel(testChannel) 128 assert.Equal(t, testChannel, channel) 129 assert.Nil(t, err) 130 131 api.On("AddChannelMember", testChannel.Id, "theuserid").Return(testChannelMember, nil).Once() 132 member, err := remote.AddChannelMember(testChannel.Id, "theuserid") 133 assert.Equal(t, testChannelMember, member) 134 assert.Nil(t, err) 135 136 api.On("GetChannelMember", "thechannelid", "theuserid").Return(testChannelMember, nil).Once() 137 member, err = remote.GetChannelMember("thechannelid", "theuserid") 138 assert.Equal(t, testChannelMember, member) 139 assert.Nil(t, err) 140 141 api.On("UpdateChannelMemberRoles", testChannel.Id, "theuserid", model.CHANNEL_ADMIN_ROLE_ID).Return(testChannelMember, nil).Once() 142 member, err = remote.UpdateChannelMemberRoles(testChannel.Id, "theuserid", model.CHANNEL_ADMIN_ROLE_ID) 143 assert.Equal(t, testChannelMember, member) 144 assert.Nil(t, err) 145 146 notifications := map[string]string{} 147 notifications[model.MARK_UNREAD_NOTIFY_PROP] = model.CHANNEL_MARK_UNREAD_MENTION 148 api.On("UpdateChannelMemberNotifications", testChannel.Id, "theuserid", notifications).Return(testChannelMember, nil).Once() 149 member, err = remote.UpdateChannelMemberNotifications(testChannel.Id, "theuserid", notifications) 150 assert.Equal(t, testChannelMember, member) 151 assert.Nil(t, err) 152 153 api.On("DeleteChannelMember", "thechannelid", "theuserid").Return(nil).Once() 154 err = remote.DeleteChannelMember("thechannelid", "theuserid") 155 assert.Nil(t, err) 156 157 api.On("CreateUser", mock.AnythingOfType("*model.User")).Return(func(u *model.User) *model.User { 158 u.Id = "theuserid" 159 return u 160 }, nil).Once() 161 user, err := remote.CreateUser(testUser) 162 assert.Equal(t, "theuserid", user.Id) 163 assert.Nil(t, err) 164 165 api.On("DeleteUser", "theuserid").Return(nil).Once() 166 assert.Nil(t, remote.DeleteUser("theuserid")) 167 168 api.On("GetUser", "theuserid").Return(testUser, nil).Once() 169 user, err = remote.GetUser("theuserid") 170 assert.Equal(t, testUser, user) 171 assert.Nil(t, err) 172 173 api.On("GetUserByEmail", "foo@foo").Return(testUser, nil).Once() 174 user, err = remote.GetUserByEmail("foo@foo") 175 assert.Equal(t, testUser, user) 176 assert.Nil(t, err) 177 178 api.On("GetUserByUsername", "foo").Return(testUser, nil).Once() 179 user, err = remote.GetUserByUsername("foo") 180 assert.Equal(t, testUser, user) 181 assert.Nil(t, err) 182 183 api.On("UpdateUser", mock.AnythingOfType("*model.User")).Return(func(u *model.User) *model.User { 184 return u 185 }, nil).Once() 186 user, err = remote.UpdateUser(testUser) 187 assert.Equal(t, testUser, user) 188 assert.Nil(t, err) 189 190 api.On("CreateTeam", mock.AnythingOfType("*model.Team")).Return(func(t *model.Team) *model.Team { 191 t.Id = "theteamid" 192 return t 193 }, nil).Once() 194 team, err := remote.CreateTeam(testTeam) 195 assert.Equal(t, "theteamid", team.Id) 196 assert.Nil(t, err) 197 198 api.On("DeleteTeam", "theteamid").Return(nil).Once() 199 assert.Nil(t, remote.DeleteTeam("theteamid")) 200 201 api.On("GetTeam", "theteamid").Return(testTeam, nil).Once() 202 team, err = remote.GetTeam("theteamid") 203 assert.Equal(t, testTeam, team) 204 assert.Nil(t, err) 205 206 api.On("GetTeamByName", "foo").Return(testTeam, nil).Once() 207 team, err = remote.GetTeamByName("foo") 208 assert.Equal(t, testTeam, team) 209 assert.Nil(t, err) 210 211 api.On("GetTeamByName", "notateam").Return(nil, teamNotFoundError).Once() 212 team, err = remote.GetTeamByName("notateam") 213 assert.Nil(t, team) 214 assert.Equal(t, teamNotFoundError, err) 215 216 api.On("UpdateTeam", mock.AnythingOfType("*model.Team")).Return(func(t *model.Team) *model.Team { 217 return t 218 }, nil).Once() 219 team, err = remote.UpdateTeam(testTeam) 220 assert.Equal(t, testTeam, team) 221 assert.Nil(t, err) 222 223 api.On("CreatePost", mock.AnythingOfType("*model.Post")).Return(func(p *model.Post) *model.Post { 224 p.Id = "thepostid" 225 return p 226 }, nil).Once() 227 post, err := remote.CreatePost(testPost) 228 require.Nil(t, err) 229 assert.NotEmpty(t, post.Id) 230 assert.Equal(t, testPost.Message, post.Message) 231 232 api.On("DeletePost", "thepostid").Return(nil).Once() 233 assert.Nil(t, remote.DeletePost("thepostid")) 234 235 api.On("GetPost", "thepostid").Return(testPost, nil).Once() 236 post, err = remote.GetPost("thepostid") 237 assert.Equal(t, testPost, post) 238 assert.Nil(t, err) 239 240 api.On("UpdatePost", mock.AnythingOfType("*model.Post")).Return(func(p *model.Post) *model.Post { 241 return p 242 }, nil).Once() 243 post, err = remote.UpdatePost(testPost) 244 assert.Equal(t, testPost, post) 245 assert.Nil(t, err) 246 247 api.KeyValueStore().(*plugintest.KeyValueStore).On("Set", "thekey", []byte("thevalue")).Return(nil).Once() 248 err = remote.KeyValueStore().Set("thekey", []byte("thevalue")) 249 assert.Nil(t, err) 250 251 api.KeyValueStore().(*plugintest.KeyValueStore).On("Get", "thekey").Return(func(key string) []byte { 252 return []byte("thevalue") 253 }, nil).Once() 254 ret, err := remote.KeyValueStore().Get("thekey") 255 assert.Nil(t, err) 256 assert.Equal(t, []byte("thevalue"), ret) 257 258 api.KeyValueStore().(*plugintest.KeyValueStore).On("Delete", "thekey").Return(nil).Once() 259 err = remote.KeyValueStore().Delete("thekey") 260 assert.Nil(t, err) 261 }) 262 } 263 264 func TestAPI_GobRegistration(t *testing.T) { 265 keyValueStore := &plugintest.KeyValueStore{} 266 api := plugintest.API{Store: keyValueStore} 267 defer api.AssertExpectations(t) 268 269 testAPIRPC(&api, func(remote plugin.API) { 270 api.On("CreatePost", mock.AnythingOfType("*model.Post")).Return(func(p *model.Post) *model.Post { 271 p.Id = "thepostid" 272 return p 273 }, nil).Once() 274 _, err := remote.CreatePost(&model.Post{ 275 Message: "hello", 276 Props: map[string]interface{}{ 277 "attachments": []*model.SlackAttachment{ 278 &model.SlackAttachment{ 279 Actions: []*model.PostAction{ 280 &model.PostAction{ 281 Integration: &model.PostActionIntegration{ 282 Context: map[string]interface{}{ 283 "foo": "bar", 284 "foos": []interface{}{"bar", "baz", 1, 2}, 285 "foo_map": map[string]interface{}{ 286 "1": "bar", 287 "2": 2, 288 }, 289 }, 290 }, 291 }, 292 }, 293 Timestamp: 1, 294 }, 295 }, 296 }, 297 }) 298 require.Nil(t, err) 299 }) 300 }