1// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2// See LICENSE.txt for license information.
3
4package app
5
6import (
7	"testing"
8
9	"github.com/stretchr/testify/assert"
10	"github.com/stretchr/testify/require"
11
12	"github.com/mattermost/mattermost-server/v6/model"
13)
14
15func TestGetGroup(t *testing.T) {
16	th := Setup(t)
17	defer th.TearDown()
18	group := th.CreateGroup()
19
20	group, err := th.App.GetGroup(group.Id)
21	require.Nil(t, err)
22	require.NotNil(t, group)
23
24	group, err = th.App.GetGroup(model.NewId())
25	require.NotNil(t, err)
26	require.Nil(t, group)
27}
28
29func TestGetGroupByRemoteID(t *testing.T) {
30	th := Setup(t)
31	defer th.TearDown()
32	group := th.CreateGroup()
33
34	g, err := th.App.GetGroupByRemoteID(group.RemoteId, model.GroupSourceLdap)
35	require.Nil(t, err)
36	require.NotNil(t, g)
37
38	g, err = th.App.GetGroupByRemoteID(model.NewId(), model.GroupSourceLdap)
39	require.NotNil(t, err)
40	require.Nil(t, g)
41}
42
43func TestGetGroupsByType(t *testing.T) {
44	th := Setup(t)
45	defer th.TearDown()
46	th.CreateGroup()
47	th.CreateGroup()
48	th.CreateGroup()
49
50	groups, err := th.App.GetGroupsBySource(model.GroupSourceLdap)
51	require.Nil(t, err)
52	require.NotEmpty(t, groups)
53
54	groups, err = th.App.GetGroupsBySource(model.GroupSource("blah"))
55	require.Nil(t, err)
56	require.Empty(t, groups)
57}
58
59func TestCreateGroup(t *testing.T) {
60	th := Setup(t)
61	defer th.TearDown()
62
63	id := model.NewId()
64	group := &model.Group{
65		DisplayName: "dn_" + id,
66		Name:        model.NewString("name" + id),
67		Source:      model.GroupSourceLdap,
68		RemoteId:    model.NewId(),
69	}
70
71	g, err := th.App.CreateGroup(group)
72	require.Nil(t, err)
73	require.NotNil(t, g)
74
75	g, err = th.App.CreateGroup(group)
76	require.NotNil(t, err)
77	require.Nil(t, g)
78}
79
80func TestUpdateGroup(t *testing.T) {
81	th := Setup(t)
82	defer th.TearDown()
83	group := th.CreateGroup()
84	group.DisplayName = model.NewId()
85
86	g, err := th.App.UpdateGroup(group)
87	require.Nil(t, err)
88	require.NotNil(t, g)
89}
90
91func TestDeleteGroup(t *testing.T) {
92	th := Setup(t)
93	defer th.TearDown()
94	group := th.CreateGroup()
95
96	g, err := th.App.DeleteGroup(group.Id)
97	require.Nil(t, err)
98	require.NotNil(t, g)
99
100	g, err = th.App.DeleteGroup(group.Id)
101	require.NotNil(t, err)
102	require.Nil(t, g)
103}
104
105func TestCreateOrRestoreGroupMember(t *testing.T) {
106	th := Setup(t).InitBasic()
107	defer th.TearDown()
108	group := th.CreateGroup()
109
110	g, err := th.App.UpsertGroupMember(group.Id, th.BasicUser.Id)
111	require.Nil(t, err)
112	require.NotNil(t, g)
113
114	g, err = th.App.UpsertGroupMember(group.Id, th.BasicUser.Id)
115	require.Nil(t, err)
116	require.NotNil(t, g)
117}
118
119func TestDeleteGroupMember(t *testing.T) {
120	th := Setup(t).InitBasic()
121	defer th.TearDown()
122	group := th.CreateGroup()
123	groupMember, err := th.App.UpsertGroupMember(group.Id, th.BasicUser.Id)
124	require.Nil(t, err)
125	require.NotNil(t, groupMember)
126
127	groupMember, err = th.App.DeleteGroupMember(groupMember.GroupId, groupMember.UserId)
128	require.Nil(t, err)
129	require.NotNil(t, groupMember)
130
131	groupMember, err = th.App.DeleteGroupMember(groupMember.GroupId, groupMember.UserId)
132	require.NotNil(t, err)
133	require.Nil(t, groupMember)
134}
135
136func TestUpsertGroupSyncable(t *testing.T) {
137	th := Setup(t).InitBasic()
138	defer th.TearDown()
139	group := th.CreateGroup()
140	groupSyncable := model.NewGroupTeam(group.Id, th.BasicTeam.Id, false)
141
142	gs, err := th.App.UpsertGroupSyncable(groupSyncable)
143	require.Nil(t, err)
144	require.NotNil(t, gs)
145
146	// can update again without error
147	gs, err = th.App.UpsertGroupSyncable(groupSyncable)
148	require.Nil(t, err)
149	require.NotNil(t, gs)
150
151	gs, err = th.App.DeleteGroupSyncable(gs.GroupId, gs.SyncableId, gs.Type)
152	require.Nil(t, err)
153	require.NotEqual(t, int64(0), gs.DeleteAt)
154
155	// Un-deleting works
156	gs.DeleteAt = 0
157	gs, err = th.App.UpsertGroupSyncable(gs)
158	require.Nil(t, err)
159	require.Equal(t, int64(0), gs.DeleteAt)
160}
161
162func TestUpsertGroupSyncableTeamGroupConstrained(t *testing.T) {
163	th := Setup(t).InitBasic()
164	defer th.TearDown()
165
166	group1 := th.CreateGroup()
167	group2 := th.CreateGroup()
168
169	team := th.CreateTeam()
170	team.GroupConstrained = model.NewBool(true)
171	team, err := th.App.UpdateTeam(team)
172	require.Nil(t, err)
173	_, err = th.App.UpsertGroupSyncable(model.NewGroupTeam(group1.Id, team.Id, false))
174	require.Nil(t, err)
175
176	channel := th.CreateChannel(team)
177
178	_, err = th.App.UpsertGroupSyncable(model.NewGroupChannel(group2.Id, channel.Id, false))
179	require.NotNil(t, err)
180	require.Equal(t, err.Id, "group_not_associated_to_synced_team")
181
182	gs, err := th.App.GetGroupSyncable(group2.Id, channel.Id, model.GroupSyncableTypeChannel)
183	require.Nil(t, gs)
184	require.NotNil(t, err)
185
186	_, err = th.App.UpsertGroupSyncable(model.NewGroupChannel(group1.Id, channel.Id, false))
187	require.Nil(t, err)
188}
189
190func TestGetGroupSyncable(t *testing.T) {
191	th := Setup(t).InitBasic()
192	defer th.TearDown()
193	group := th.CreateGroup()
194	groupSyncable := model.NewGroupTeam(group.Id, th.BasicTeam.Id, false)
195
196	gs, err := th.App.UpsertGroupSyncable(groupSyncable)
197	require.Nil(t, err)
198	require.NotNil(t, gs)
199
200	gs, err = th.App.GetGroupSyncable(group.Id, th.BasicTeam.Id, model.GroupSyncableTypeTeam)
201	require.Nil(t, err)
202	require.NotNil(t, gs)
203}
204
205func TestGetGroupSyncables(t *testing.T) {
206	th := Setup(t).InitBasic()
207	defer th.TearDown()
208	group := th.CreateGroup()
209
210	// Create a group team
211	groupSyncable := model.NewGroupTeam(group.Id, th.BasicTeam.Id, false)
212
213	gs, err := th.App.UpsertGroupSyncable(groupSyncable)
214	require.Nil(t, err)
215	require.NotNil(t, gs)
216
217	groupTeams, err := th.App.GetGroupSyncables(group.Id, model.GroupSyncableTypeTeam)
218	require.Nil(t, err)
219
220	require.NotEmpty(t, groupTeams)
221}
222
223func TestDeleteGroupSyncable(t *testing.T) {
224	th := Setup(t).InitBasic()
225	defer th.TearDown()
226	group := th.CreateGroup()
227	groupChannel := model.NewGroupChannel(group.Id, th.BasicChannel.Id, false)
228
229	gs, err := th.App.UpsertGroupSyncable(groupChannel)
230	require.Nil(t, err)
231	require.NotNil(t, gs)
232
233	gs, err = th.App.DeleteGroupSyncable(group.Id, th.BasicChannel.Id, model.GroupSyncableTypeChannel)
234	require.Nil(t, err)
235	require.NotNil(t, gs)
236
237	gs, err = th.App.DeleteGroupSyncable(group.Id, th.BasicChannel.Id, model.GroupSyncableTypeChannel)
238	require.NotNil(t, err)
239	require.Nil(t, gs)
240}
241
242func TestGetGroupsByChannel(t *testing.T) {
243	th := Setup(t).InitBasic()
244	defer th.TearDown()
245	group := th.CreateGroup()
246
247	// Create a group channel
248	groupSyncable := &model.GroupSyncable{
249		GroupId:    group.Id,
250		AutoAdd:    false,
251		SyncableId: th.BasicChannel.Id,
252		Type:       model.GroupSyncableTypeChannel,
253	}
254
255	gs, err := th.App.UpsertGroupSyncable(groupSyncable)
256	require.Nil(t, err)
257	require.NotNil(t, gs)
258
259	opts := model.GroupSearchOpts{
260		PageOpts: &model.PageOpts{
261			Page:    0,
262			PerPage: 60,
263		},
264	}
265
266	groups, _, err := th.App.GetGroupsByChannel(th.BasicChannel.Id, opts)
267	require.Nil(t, err)
268	require.ElementsMatch(t, []*model.GroupWithSchemeAdmin{{Group: *group, SchemeAdmin: model.NewBool(false)}}, groups)
269	require.NotNil(t, groups[0].SchemeAdmin)
270
271	groups, _, err = th.App.GetGroupsByChannel(model.NewId(), opts)
272	require.Nil(t, err)
273	require.Empty(t, groups)
274}
275
276func TestGetGroupsAssociatedToChannelsByTeam(t *testing.T) {
277	th := Setup(t).InitBasic()
278	defer th.TearDown()
279	group := th.CreateGroup()
280
281	// Create a group channel
282	groupSyncable := &model.GroupSyncable{
283		GroupId:    group.Id,
284		AutoAdd:    false,
285		SyncableId: th.BasicChannel.Id,
286		Type:       model.GroupSyncableTypeChannel,
287	}
288
289	gs, err := th.App.UpsertGroupSyncable(groupSyncable)
290	require.Nil(t, err)
291	require.NotNil(t, gs)
292
293	opts := model.GroupSearchOpts{
294		PageOpts: &model.PageOpts{
295			Page:    0,
296			PerPage: 60,
297		},
298	}
299
300	groups, err := th.App.GetGroupsAssociatedToChannelsByTeam(th.BasicTeam.Id, opts)
301	require.Nil(t, err)
302
303	assert.Equal(t, map[string][]*model.GroupWithSchemeAdmin{
304		th.BasicChannel.Id: {
305			{Group: *group, SchemeAdmin: model.NewBool(false)},
306		},
307	}, groups)
308	require.NotNil(t, groups[th.BasicChannel.Id][0].SchemeAdmin)
309
310	groups, err = th.App.GetGroupsAssociatedToChannelsByTeam(model.NewId(), opts)
311	require.Nil(t, err)
312	require.Empty(t, groups)
313}
314
315func TestGetGroupsByTeam(t *testing.T) {
316	th := Setup(t).InitBasic()
317	defer th.TearDown()
318	group := th.CreateGroup()
319
320	// Create a group team
321	groupSyncable := &model.GroupSyncable{
322		GroupId:    group.Id,
323		AutoAdd:    false,
324		SyncableId: th.BasicTeam.Id,
325		Type:       model.GroupSyncableTypeTeam,
326	}
327
328	gs, err := th.App.UpsertGroupSyncable(groupSyncable)
329	require.Nil(t, err)
330	require.NotNil(t, gs)
331
332	groups, _, err := th.App.GetGroupsByTeam(th.BasicTeam.Id, model.GroupSearchOpts{})
333	require.Nil(t, err)
334	require.ElementsMatch(t, []*model.GroupWithSchemeAdmin{{Group: *group, SchemeAdmin: model.NewBool(false)}}, groups)
335	require.NotNil(t, groups[0].SchemeAdmin)
336
337	groups, _, err = th.App.GetGroupsByTeam(model.NewId(), model.GroupSearchOpts{})
338	require.Nil(t, err)
339	require.Empty(t, groups)
340}
341
342func TestGetGroups(t *testing.T) {
343	th := Setup(t)
344	defer th.TearDown()
345	group := th.CreateGroup()
346
347	groups, err := th.App.GetGroups(0, 60, model.GroupSearchOpts{})
348	require.Nil(t, err)
349	require.ElementsMatch(t, []*model.Group{group}, groups)
350}
351
352func TestUserIsInAdminRoleGroup(t *testing.T) {
353	th := Setup(t).InitBasic()
354	defer th.TearDown()
355	group1 := th.CreateGroup()
356	group2 := th.CreateGroup()
357
358	g, err := th.App.UpsertGroupMember(group1.Id, th.BasicUser.Id)
359	require.Nil(t, err)
360	require.NotNil(t, g)
361
362	g, err = th.App.UpsertGroupMember(group2.Id, th.BasicUser.Id)
363	require.Nil(t, err)
364	require.NotNil(t, g)
365
366	_, err = th.App.UpsertGroupSyncable(&model.GroupSyncable{
367		GroupId:    group1.Id,
368		AutoAdd:    false,
369		SyncableId: th.BasicTeam.Id,
370		Type:       model.GroupSyncableTypeTeam,
371	})
372	require.Nil(t, err)
373
374	groupSyncable2, err := th.App.UpsertGroupSyncable(&model.GroupSyncable{
375		GroupId:    group2.Id,
376		AutoAdd:    false,
377		SyncableId: th.BasicTeam.Id,
378		Type:       model.GroupSyncableTypeTeam,
379	})
380	require.Nil(t, err)
381
382	// no syncables are set to scheme admin true, so this returns false
383	actual, err := th.App.UserIsInAdminRoleGroup(th.BasicUser.Id, th.BasicTeam.Id, model.GroupSyncableTypeTeam)
384	require.Nil(t, err)
385	require.False(t, actual)
386
387	// set a syncable to be scheme admins
388	groupSyncable2.SchemeAdmin = true
389	_, err = th.App.UpdateGroupSyncable(groupSyncable2)
390	require.Nil(t, err)
391
392	// a syncable is set to scheme admin true, so this returns true
393	actual, err = th.App.UserIsInAdminRoleGroup(th.BasicUser.Id, th.BasicTeam.Id, model.GroupSyncableTypeTeam)
394	require.Nil(t, err)
395	require.True(t, actual)
396
397	// delete the syncable, should be false again
398	th.App.DeleteGroupSyncable(group2.Id, th.BasicTeam.Id, model.GroupSyncableTypeTeam)
399	actual, err = th.App.UserIsInAdminRoleGroup(th.BasicUser.Id, th.BasicTeam.Id, model.GroupSyncableTypeTeam)
400	require.Nil(t, err)
401	require.False(t, actual)
402}
403