func TestChannelParticipantOperations(t *testing.T) { tests.WithRunner(t, func(r *runner.Runner) { Convey("while testing channel participants", t, func() { Convey("First Create Users and initiate conversation", func() { ownerAccount, groupChannel, groupName := models.CreateRandomGroupDataWithChecks() ownerSes, err := modelhelper.FetchOrCreateSession(ownerAccount.Nick, groupName) So(err, ShouldBeNil) So(ownerSes, ShouldNotBeNil) secondAccount, err := models.CreateAccountInBothDbs() tests.ResultedWithNoErrorCheck(secondAccount, err) _, err = groupChannel.AddParticipant(secondAccount.Id) So(err, ShouldBeNil) thirdAccount, err := models.CreateAccountInBothDbs() tests.ResultedWithNoErrorCheck(thirdAccount, err) _, err = groupChannel.AddParticipant(thirdAccount.Id) So(err, ShouldBeNil) forthAccount, err := models.CreateAccountInBothDbs() tests.ResultedWithNoErrorCheck(forthAccount, err) _, err = groupChannel.AddParticipant(forthAccount.Id) So(err, ShouldBeNil) devrim, err := models.CreateAccountInBothDbsWithNick("devrim") tests.ResultedWithNoErrorCheck(devrim, err) _, err = groupChannel.AddParticipant(devrim.Id) So(err, ShouldBeNil) ses, err := modelhelper.FetchOrCreateSession(ownerAccount.Nick, groupName) tests.ResultedWithNoErrorCheck(ses, err) secondSes, err := modelhelper.FetchOrCreateSession(secondAccount.Nick, groupName) tests.ResultedWithNoErrorCheck(secondSes, err) pmr := models.ChannelRequest{} pmr.AccountId = ownerAccount.Id pmr.Body = "new conversation" pmr.GroupName = groupName pmr.Recipients = []string{"devrim"} channelContainer, err := rest.SendPrivateChannelRequest(pmr, ownerSes.ClientId) So(err, ShouldBeNil) So(channelContainer, ShouldNotBeNil) Convey("First user should be able to add second and third users to conversation", func() { _, err = rest.AddChannelParticipant(channelContainer.Channel.Id, ownerSes.ClientId, secondAccount.Id, thirdAccount.Id) So(err, ShouldBeNil) participants, err := rest.ListChannelParticipants(channelContainer.Channel.Id, ownerSes.ClientId) So(err, ShouldBeNil) So(participants, ShouldNotBeNil) // it is four because first user is "devrim" here So(len(participants), ShouldEqual, 4) Convey("First user should not be able to re-add second participant", func() { _, err = rest.AddChannelParticipant(channelContainer.Channel.Id, ownerSes.ClientId, secondAccount.Id) So(err, ShouldBeNil) participants, err := rest.ListChannelParticipants(channelContainer.Channel.Id, ownerSes.ClientId) So(err, ShouldBeNil) So(participants, ShouldNotBeNil) So(len(participants), ShouldEqual, 4) }) Convey("Second user should be able to leave conversation", func() { // token of account -> secondAccount _, err = rest.DeleteChannelParticipant(channelContainer.Channel.Id, secondSes.ClientId, secondAccount.Id) So(err, ShouldBeNil) participants, err := rest.ListChannelParticipants(channelContainer.Channel.Id, ownerSes.ClientId) So(err, ShouldBeNil) So(participants, ShouldNotBeNil) So(len(participants), ShouldEqual, 3) Convey("A user who is not participant of a conversation should not be able to add another user to the conversation", func() { _, err = rest.AddChannelParticipant(channelContainer.Channel.Id, secondSes.ClientId, forthAccount.Id) So(err, ShouldNotBeNil) participants, err := rest.ListChannelParticipants(channelContainer.Channel.Id, ownerSes.ClientId) So(err, ShouldBeNil) So(participants, ShouldNotBeNil) So(len(participants), ShouldEqual, 3) }) }) Convey("Channel owner should be able to kick another conversation participant", func() { _, err = rest.DeleteChannelParticipant(channelContainer.Channel.Id, ownerSes.ClientId, secondAccount.Id) So(err, ShouldBeNil) participants, err := rest.ListChannelParticipants(channelContainer.Channel.Id, ownerSes.ClientId) So(err, ShouldBeNil) So(participants, ShouldNotBeNil) So(len(participants), ShouldEqual, 3) }) Convey("when a user is blocked", func() { _, err = rest.BlockChannelParticipant(channelContainer.Channel.Id, ownerSes.ClientId, secondAccount.Id) So(err, ShouldBeNil) Convey("it should not be in channel participant list", func() { participants, err := rest.ListChannelParticipants(channelContainer.Channel.Id, ownerSes.ClientId) So(err, ShouldBeNil) So(participants, ShouldNotBeNil) So(len(participants), ShouldEqual, 3) }) Convey("should not be able to add it back", func() { _, err = rest.AddChannelParticipant(channelContainer.Channel.Id, ownerSes.ClientId, secondAccount.Id) So(err, ShouldNotBeNil) }) Convey("should be able to unblock", func() { _, err = rest.UnblockChannelParticipant(channelContainer.Channel.Id, ownerSes.ClientId, secondAccount.Id) So(err, ShouldBeNil) Convey("it should not be in channel participant list still", func() { participants, err := rest.ListChannelParticipants(channelContainer.Channel.Id, ownerSes.ClientId) So(err, ShouldBeNil) So(participants, ShouldNotBeNil) So(len(participants), ShouldEqual, 3) }) Convey("when we add the same user as participant", func() { _, err = rest.AddChannelParticipant(channelContainer.Channel.Id, ownerSes.ClientId, secondAccount.Id, thirdAccount.Id) So(err, ShouldBeNil) Convey("it should be in channel participant list", func() { participants, err := rest.ListChannelParticipants(channelContainer.Channel.Id, ownerSes.ClientId) So(err, ShouldBeNil) So(participants, ShouldNotBeNil) So(len(participants), ShouldEqual, 4) }) }) }) }) Convey("Second user should not be able to kick another conversation participant", func() { _, err = rest.DeleteChannelParticipant(channelContainer.Channel.Id, secondSes.ClientId, thirdAccount.Id) So(err, ShouldNotBeNil) }) }) Convey("First user should be able to invite second user", func() { _, err = rest.InviteChannelParticipant(channelContainer.Channel.Id, ownerSes.ClientId, secondAccount.Id) So(err, ShouldBeNil) participants, err := rest.ListChannelParticipants(channelContainer.Channel.Id, ownerSes.ClientId) So(err, ShouldBeNil) So(participants, ShouldNotBeNil) // it is four because first user is "devrim" here So(len(participants), ShouldEqual, 2) Convey("Second user should be able to reject invitation", func() { ses, err := modelhelper.FetchOrCreateSession(secondAccount.Nick, groupName) So(err, ShouldBeNil) So(ses, ShouldNotBeNil) err = rest.RejectInvitation(channelContainer.Channel.Id, ses.ClientId) So(err, ShouldBeNil) participants, err := rest.ListChannelParticipants(channelContainer.Channel.Id, ownerSes.ClientId) So(err, ShouldBeNil) So(participants, ShouldNotBeNil) So(len(participants), ShouldEqual, 2) }) Convey("Second user should be able to accept invitation", func() { ses, err := modelhelper.FetchOrCreateSession(secondAccount.Nick, groupName) So(err, ShouldBeNil) So(ses, ShouldNotBeNil) err = rest.AcceptInvitation(channelContainer.Channel.Id, ses.ClientId) So(err, ShouldBeNil) participants, err := rest.ListChannelParticipants(channelContainer.Channel.Id, ownerSes.ClientId) So(err, ShouldBeNil) So(participants, ShouldNotBeNil) So(len(participants), ShouldEqual, 3) }) }) // TODO Until we find a better way for handling async stuff, this test is skipped. Instead of sleep, we should use some // timeouts for testing these kind of stuff. SkipConvey("All private messages must be deleted when all participant users leave the channel", func() { account := models.NewAccount() err = account.ByNick("devrim") So(err, ShouldBeNil) _, err = rest.DeleteChannelParticipant(channelContainer.Channel.Id, ses.ClientId, account.Id) So(err, ShouldBeNil) _, err = rest.DeleteChannelParticipant(channelContainer.Channel.Id, ownerSes.ClientId, ownerAccount.Id) So(err, ShouldBeNil) time.Sleep(1 * time.Second) testChannel := models.NewChannel() err := testChannel.ById(channelContainer.Channel.Id) So(err, ShouldEqual, bongo.RecordNotFound) testChannelList := models.NewChannelMessageList() err = bongo.B.Unscoped().Where("channel_id = ?", channelContainer.Channel.Id).Find(testChannelList).Error So(err, ShouldEqual, bongo.RecordNotFound) testMessage := models.NewChannelMessage() err = bongo.B.Unscoped().Where("initial_channel_id = ?", channelContainer.Channel.Id).Find(testMessage).Error So(err, ShouldEqual, bongo.RecordNotFound) }) Convey("Users should not be able to add/remove users to/from bot channels", func() { ownerAccount, _, groupName := models.CreateRandomGroupDataWithChecks() participant := models.NewAccount() participant.OldId = AccountOldId.Hex() participant, err = rest.CreateAccount(participant) So(err, ShouldBeNil) So(participant, ShouldNotBeNil) ses, err := modelhelper.FetchOrCreateSession(ownerAccount.Nick, groupName) So(err, ShouldBeNil) ch, err := rest.CreateChannelByGroupNameAndType(ownerAccount.Id, groupName, models.Channel_TYPE_BOT, ses.ClientId) So(err, ShouldBeNil) So(ch, ShouldNotBeNil) // account is -> ownerAccount.Id _, err = rest.AddChannelParticipant(ch.Id, ses.ClientId, participant.Id) So(strings.Contains(err.Error(), "can not add participants for bot channel"), ShouldBeTrue) }) Convey("Users should be able to add/remove users to/from topic channels", func() { ownerAccount, _, groupName := models.CreateRandomGroupDataWithChecks() participant := models.NewAccount() participant.OldId = AccountOldId.Hex() participant, err = rest.CreateAccount(participant) So(err, ShouldBeNil) So(participant, ShouldNotBeNil) ses, err := modelhelper.FetchOrCreateSession(ownerAccount.Nick, groupName) So(err, ShouldBeNil) ch, err := rest.CreateChannelByGroupNameAndType(ownerAccount.Id, groupName, models.Channel_TYPE_TOPIC, ses.ClientId) So(err, ShouldBeNil) So(ch, ShouldNotBeNil) // account is -> ownerAccount.Id _, err = rest.AddChannelParticipant(ch.Id, ses.ClientId, participant.Id) So(err, ShouldBeNil) Convey("adding same user again should success", func() { _, err = rest.AddChannelParticipant(ch.Id, ses.ClientId, participant.Id) So(err, ShouldBeNil) }) _, err = rest.DeleteChannelParticipant(ch.Id, ses.ClientId, participant.Id) So(err, ShouldBeNil) Convey("removing same user again should success", func() { _, err = rest.DeleteChannelParticipant(ch.Id, ses.ClientId, participant.Id) So(err, ShouldBeNil) }) }) Convey("while removing users from group channels", func() { ownerAccount, _, groupName := models.CreateRandomGroupDataWithChecks() participant := models.NewAccount() participant.OldId = AccountOldId.Hex() participant, err = rest.CreateAccount(participant) So(err, ShouldBeNil) So(participant, ShouldNotBeNil) participant2 := models.NewAccount() participant2.OldId = AccountOldId.Hex() participant2, err = rest.CreateAccount(participant2) So(err, ShouldBeNil) So(participant2, ShouldNotBeNil) ownerSes, err := modelhelper.FetchOrCreateSession(ownerAccount.Nick, groupName) So(err, ShouldBeNil) ses, err := modelhelper.FetchOrCreateSession(participant.Nick, groupName) So(err, ShouldBeNil) ch, err := rest.CreateChannelByGroupNameAndType(ownerAccount.Id, groupName, models.Channel_TYPE_GROUP, ownerSes.ClientId) So(err, ShouldBeNil) So(ch, ShouldNotBeNil) // ownerSes session is admin's session data _, err = rest.AddChannelParticipant(ch.Id, ownerSes.ClientId, participant.Id) So(err, ShouldBeNil) _, err = rest.AddChannelParticipant(ch.Id, ownerSes.ClientId, participant2.Id) So(err, ShouldBeNil) Convey("owner should be able to remove user from group channel", func() { // ownerSes session is admin's session data _, err = rest.DeleteChannelParticipant(ch.Id, ownerSes.ClientId, participant2.Id) So(err, ShouldBeNil) }) Convey("nonOwner should not be able to remove user from group channel", func() { // ses session is participant's session data _, err = rest.DeleteChannelParticipant(ch.Id, ses.ClientId, participant2.Id) So(err, ShouldNotBeNil) }) }) }) }) }) }
func TestChannelCreation(t *testing.T) { tests.WithRunner(t, func(r *runner.Runner) { Convey("while testing channel", t, func() { Convey("First Create Users", func() { account, err := models.CreateAccountInBothDbs() So(err, ShouldBeNil) groupName := models.RandomGroupName() ses, err := modelhelper.FetchOrCreateSession(account.Nick, groupName) So(err, ShouldBeNil) So(ses, ShouldNotBeNil) groupChannel := models.CreateTypedGroupedChannelWithTest( account.Id, models.Channel_TYPE_GROUP, groupName, ) So(err, ShouldBeNil) So(groupChannel, ShouldNotBeNil) nonOwnerAccount := models.NewAccount() nonOwnerAccount.OldId = AccountOldId2.Hex() nonOwnerAccount, err = rest.CreateAccount(nonOwnerAccount) So(err, ShouldBeNil) So(nonOwnerAccount, ShouldNotBeNil) noses, err := modelhelper.FetchOrCreateSession( nonOwnerAccount.Nick, groupName, ) So(err, ShouldBeNil) So(noses, ShouldNotBeNil) Convey("we should be able to create it", func() { channel1, err := rest.CreateChannelByGroupNameAndType( account.Id, groupName, models.Channel_TYPE_PRIVATE_MESSAGE, ses.ClientId, ) So(err, ShouldBeNil) So(channel1, ShouldNotBeNil) _, err = rest.AddChannelParticipant(channel1.Id, ses.ClientId, account.Id) So(err, ShouldBeNil) Convey("owner should be able to update it", func() { updatedPurpose := "another purpose from the paradise" channel1.Purpose = updatedPurpose channel2, err := rest.UpdateChannel(channel1, ses.ClientId) So(err, ShouldBeNil) So(channel2, ShouldNotBeNil) So(channel1.Purpose, ShouldEqual, channel1.Purpose) Convey("owner should be able to update payload", func() { if channel1.Payload == nil { channel1.Payload = gorm.Hstore{} } value := "value" channel1.Payload = gorm.Hstore{ "key": &value, } channel2, err := rest.UpdateChannel(channel1, ses.ClientId) So(err, ShouldBeNil) So(channel2, ShouldNotBeNil) So(channel1.Payload, ShouldNotBeNil) So(*channel1.Payload["key"], ShouldEqual, value) }) }) Convey("participant should be able to update only purpose, not name or payload", func() { _, err = rest.AddChannelParticipant(channel1.Id, ses.ClientId, nonOwnerAccount.Id) So(err, ShouldBeNil) updatedPurpose := "ChannelPurposeUpdated" updatedName := "ChannelNameUpdated" channel1.Name = updatedName channel1.Purpose = updatedPurpose channel2, err := rest.UpdateChannel(channel1, noses.ClientId) So(err, ShouldBeNil) So(channel2, ShouldNotBeNil) So(channel2.Name, ShouldNotBeNil) // participant cannot update channel name // can update only purpose of the channel So(channel2.Name, ShouldNotEqual, updatedName) So(channel2.Purpose, ShouldEqual, updatedPurpose) }) Convey("owner should be get channel by name", func() { channel2, err := rest.FetchChannelByName( account.Id, channel1.Name, channel1.GroupName, channel1.TypeConstant, ses.ClientId, ) So(err, ShouldBeNil) So(channel2, ShouldNotBeNil) So(channel1.Id, ShouldEqual, channel2.Id) So(channel1.Name, ShouldEqual, channel2.Name) So(channel1.GroupName, ShouldEqual, channel2.GroupName) So(channel1.GroupName, ShouldEqual, channel2.GroupName) }) Convey("unread count should be set", func() { channelContainer, err := rest.FetchChannelContainerByName(account.Id, channel1.Name, channel1.GroupName, channel1.TypeConstant, ses.ClientId) So(err, ShouldBeNil) So(channelContainer, ShouldNotBeNil) So(channelContainer.UnreadCount, ShouldEqual, 0) post, err := rest.CreatePost(channel1.Id, ses.ClientId) So(err, ShouldBeNil) So(post, ShouldNotBeNil) channelContainer, err = rest.FetchChannelContainerByName(account.Id, channel1.Name, channel1.GroupName, channel1.TypeConstant, ses.ClientId) So(err, ShouldBeNil) So(channelContainer, ShouldNotBeNil) So(channelContainer.UnreadCount, ShouldEqual, 1) }) Convey("non-owner should not be able to update it", func() { updatedPurpose := "another purpose from the paradise" channel1.Purpose = updatedPurpose channel1.CreatorId = nonOwnerAccount.Id channel2, err := rest.UpdateChannel(channel1, noses.ClientId) So(err, ShouldNotBeNil) So(channel2, ShouldBeNil) }) Convey("non-owner should not be able to get channel by name", func() { _, err := rest.FetchChannelByName( nonOwnerAccount.Id, channel1.Name, channel1.GroupName, channel1.TypeConstant, noses.ClientId, ) So(err, ShouldNotBeNil) }) }) Convey("normal user shouldnt be able to add new participants to pinned activity channel", func() { channel1, err := rest.CreateChannelByGroupNameAndType( account.Id, groupName, models.Channel_TYPE_PINNED_ACTIVITY, ses.ClientId, ) So(err, ShouldBeNil) So(channel1, ShouldNotBeNil) channelParticipant, err := rest.AddChannelParticipant(channel1.Id, noses.ClientId, nonOwnerAccount.Id) // there should be an err So(err, ShouldNotBeNil) // channel should be nil So(channelParticipant, ShouldBeNil) }) Convey("owner should be able list participants", func() { channel1, err := rest.CreateChannelByGroupNameAndType( account.Id, groupName, models.Channel_TYPE_DEFAULT, ses.ClientId, ) So(err, ShouldBeNil) So(channel1, ShouldNotBeNil) // add first participant channelParticipant1, err := rest.AddChannelParticipant(channel1.Id, ses.ClientId, nonOwnerAccount.Id) // there should be an err So(err, ShouldBeNil) // channel should be nil So(channelParticipant1, ShouldNotBeNil) nonOwnerAccount2 := models.NewAccount() nonOwnerAccount2.OldId = AccountOldId3.Hex() nonOwnerAccount2, err = rest.CreateAccount(nonOwnerAccount2) So(err, ShouldBeNil) So(nonOwnerAccount2, ShouldNotBeNil) channelParticipant2, err := rest.AddChannelParticipant(channel1.Id, ses.ClientId, nonOwnerAccount2.Id) // there should be an err So(err, ShouldBeNil) // channel should be nil So(channelParticipant2, ShouldNotBeNil) participants, err := rest.ListChannelParticipants(channel1.Id, ses.ClientId) // there should be an err So(err, ShouldBeNil) So(participants, ShouldNotBeNil) // owner // nonOwner1 // nonOwner2 So(len(participants), ShouldEqual, 3) }) Convey("normal user should be able to list participants", func() { channel1, err := rest.CreateChannelByGroupNameAndType( account.Id, groupName, models.Channel_TYPE_DEFAULT, ses.ClientId, ) So(err, ShouldBeNil) So(channel1, ShouldNotBeNil) // add first participant channelParticipant1, err := rest.AddChannelParticipant(channel1.Id, ses.ClientId, nonOwnerAccount.Id) // there should be an err So(err, ShouldBeNil) // channel should be nil So(channelParticipant1, ShouldNotBeNil) nonOwnerAccount2 := models.NewAccount() nonOwnerAccount2.OldId = AccountOldId3.Hex() nonOwnerAccount2, err = rest.CreateAccount(nonOwnerAccount2) So(err, ShouldBeNil) So(nonOwnerAccount2, ShouldNotBeNil) nonOwnerSes2, err := modelhelper.FetchOrCreateSession(nonOwnerAccount2.Nick, groupName) So(err, ShouldBeNil) So(nonOwnerSes2, ShouldNotBeNil) channelParticipant2, err := rest.AddChannelParticipant(channel1.Id, ses.ClientId, nonOwnerAccount2.Id) // there should be an err So(err, ShouldBeNil) // channel should be nil So(channelParticipant2, ShouldNotBeNil) participants, err := rest.ListChannelParticipants(channel1.Id, nonOwnerSes2.ClientId) // there should be an err So(err, ShouldBeNil) So(participants, ShouldNotBeNil) // owner // nonOwner1 // nonOwner2 So(len(participants), ShouldEqual, 3) }) }) }) }) }