Ejemplo n.º 1
0
func TestGroupChannelFirstCreation(t *testing.T) {
	tests.WithRunner(t, func(r *runner.Runner) {
		Convey("While creating the new group channel for the first time", t, func() {
			Convey("user should be able to create group channel", func() {
				acc, err := models.CreateAccountInBothDbs()
				So(err, ShouldBeNil)

				groupName := models.RandomGroupName()
				ses, err := modelhelper.FetchOrCreateSession(acc.Nick, groupName)
				So(err, ShouldBeNil)
				So(ses, ShouldNotBeNil)

				channel, err := rest.CreateChannelByGroupNameAndType(
					acc.Id,
					groupName,
					models.Channel_TYPE_GROUP,
					ses.ClientId,
				)

				So(err, ShouldBeNil)
				So(channel.GroupName, ShouldEqual, groupName)
			})
		})
	})
}
Ejemplo n.º 2
0
func TestPresenceGetGroupPaymentStatusFromCache(t *testing.T) {
	tests.WithRunner(t, func(r *runner.Runner) {
		Convey("With non existing group", t, func() {
			groupName := models.RandomGroupName()
			Convey("should get err", func() {

				status, err := getGroupPaymentStatusFromCache(groupName)
				So(err, ShouldEqual, mgo.ErrNotFound)
				So(status, ShouldBeEmpty)

				Convey("With existing group", func() {
					_, _, groupSlug := models.CreateRandomGroupDataWithChecks()

					// make sure it is no in the cache
					_, err = groupCache.Get(groupSlug)
					So(err, ShouldEqual, cache.ErrNotFound)

					Convey("should work properly with invalid payment status", func() {
						status, err := getGroupPaymentStatusFromCache(groupSlug)
						So(err, ShouldBeNil)
						So(status, ShouldEqual, "invalid")
					})
				})
			})
		})
	})
}
Ejemplo n.º 3
0
func TestPresenceDailyPing(t *testing.T) {
	tests.WithRunner(t, func(r *runner.Runner) {
		groupName1 := models.RandomGroupName()
		Convey("With given presence data", t, func() {

			Convey("should work properly with non existant data", func() {
				today := time.Now().UTC()
				ping := &Ping{
					AccountID:     1, // non existing user
					GroupName:     groupName1,
					CreatedAt:     today,
					paymentStatus: string(mongomodels.SubStatusActive),
				}
				key := getKey(ping, today)
				_, err := pingCache.Get(key)
				So(err, ShouldEqual, cache.ErrNotFound)

				err = verifyRecord(ping, today)
				So(err, ShouldBeNil)

				// it should not be in cache
				_, err = pingCache.Get(key)
				So(err, ShouldEqual, cache.ErrNotFound)

				// we should be able to get it from db
				pd, err := getPresenceInfoFromDB(ping)
				So(err, ShouldBeNil)
				So(pd, ShouldNotBeNil)
			})
		})
	})
}
Ejemplo n.º 4
0
func TestCollaborationSesionEnd(t *testing.T) {
	r := runner.New("collaboration-tests")
	err := r.Init()
	if err != nil {
		panic(err)
	}

	defer r.Close()

	appConfig := config.MustRead(r.Conf.Path)
	modelhelper.Initialize(appConfig.Mongo)
	defer modelhelper.Close()

	Convey("while testing collaboration session end", t, func() {

		Convey("we should be able to create a doc on google drive", func() {
			Convey("we should be able to delete a created doc", func() {
				Convey("deleting an already deleted doc should not give error", func() {
				})
			})
		})

		Convey("trying to delete a non-existing doc should not give error", func() {
		})
	})

	Convey("while pinging collaboration", t, func() {
		// owner
		owner, err := apimodels.CreateAccountInBothDbs()
		So(err, ShouldBeNil)
		So(owner, ShouldNotBeNil)

		groupName := apimodels.RandomGroupName()
		apimodels.CreateTypedGroupedChannelWithTest(
			owner.Id,
			apimodels.Channel_TYPE_GROUP,
			groupName,
		)

		ownerSession, err := modelhelper.FetchOrCreateSession(owner.Nick, groupName)
		So(err, ShouldBeNil)
		So(ownerSession, ShouldNotBeNil)

		Convey("reponse should be success", func() {
			p := &models.Ping{
				AccountId: 1,
				FileId:    "hello",
			}

			res, err := rest.CollaborationPing(p, ownerSession.ClientId)
			So(err, ShouldBeNil)
			So(res, ShouldNotBeNil)
		})
	})
}
Ejemplo n.º 5
0
func TestPresenceDailyOperations(t *testing.T) {
	tests.WithRunner(t, func(r *runner.Runner) {
		groupName1 := models.RandomGroupName()
		Convey("With given presence data", t, func() {
			p1 := &models.PresenceDaily{
				AccountId: 1,
				GroupName: groupName1,
				// just to give some time between two records
				CreatedAt: time.Now().UTC().Add(-time.Millisecond * 100),
			}
			So(p1.Create(), ShouldBeNil)

			p2 := &models.PresenceDaily{
				AccountId: 1,
				GroupName: groupName1,
				CreatedAt: time.Now().UTC(),
			}
			So(p2.Create(), ShouldBeNil)

			Convey("getPresenceInfoFromDB should work properly", func() {
				pi, err := getPresenceInfoFromDB(&Ping{
					AccountID:     p2.AccountId,
					GroupName:     p2.GroupName,
					paymentStatus: string(mongomodels.SubStatusActive),
				})
				So(err, ShouldBeNil)
				So(pi, ShouldNotBeNil)
				// Why .Unix()? postgres omits after 6 decimal - due to our config.
				// Expected: '2016-09-21 13:44:50.695855774 +0000 UTC'
				// Actual:   '2016-09-21 13:44:50.695856 +0000 UTC'
				So(pi.CreatedAt.UTC().Unix(), ShouldEqual, p2.CreatedAt.UTC().Unix())

				pi2, err := getPresenceInfoFromDB(&Ping{
					AccountID:     p2.AccountId,
					GroupName:     "non_existent_group_name",
					paymentStatus: string(mongomodels.SubStatusActive),
				})
				So(err, ShouldNotBeNil)
				So(err, ShouldEqual, bongo.RecordNotFound)
				So(pi2, ShouldBeNil)

				pi3, err := getPresenceInfoFromDB(&Ping{
					AccountID:     rand.Int63(),
					GroupName:     groupName1,
					paymentStatus: string(mongomodels.SubStatusActive),
				})
				So(err, ShouldNotBeNil)
				So(err, ShouldEqual, bongo.RecordNotFound)
				So(pi3, ShouldBeNil)
			})
		})
	})
}
Ejemplo n.º 6
0
func TestChannelByParticipants(t *testing.T) {
	tests.WithRunner(t, func(r *runner.Runner) {
		Convey("while fetching channels by their participants", t, func() {
			admin1, _, groupName1 := models.CreateRandomGroupDataWithChecks()

			ses1, err := modelhelper.FetchOrCreateSession(admin1.Nick, groupName1)
			So(err, ShouldBeNil)
			So(ses1, ShouldNotBeNil)

			acc1, err := models.CreateAccountInBothDbs()
			So(err, ShouldBeNil)
			So(acc1, ShouldNotBeNil)

			acc2, err := models.CreateAccountInBothDbs()
			So(err, ShouldBeNil)
			So(acc1, ShouldNotBeNil)

			tc1 := createChannelAndParticipants(admin1, groupName1, models.Channel_TYPE_TOPIC, ses1.ClientId, acc1.Id, acc2.Id)
			tc2 := createChannelAndParticipants(admin1, groupName1, models.Channel_TYPE_TOPIC, ses1.ClientId, acc1.Id, acc2.Id)

			Convey("valid request should return valid response", func() {
				channels, err := rest.FetchChannelsByParticipants([]int64{acc1.Id, acc2.Id}, models.Channel_TYPE_TOPIC, ses1.ClientId)
				// there should be an err
				So(err, ShouldBeNil)
				So(channels, ShouldNotBeNil)
				So(len(channels), ShouldEqual, 2)
				So(tc1.Id, ShouldEqual, channels[0].Channel.Id)
				So(tc2.Id, ShouldEqual, channels[1].Channel.Id)
			})

			Convey("other group's content should not be in the result set", func() {

				groupName2 := models.RandomGroupName()
				models.CreateTypedGroupedChannelWithTest(
					admin1.Id,
					models.Channel_TYPE_GROUP,
					groupName2,
				)

				ses2, err := modelhelper.FetchOrCreateSession(admin1.Nick, groupName2)
				So(err, ShouldBeNil)
				So(ses2, ShouldNotBeNil)

				gtc1 := createChannelAndParticipants(admin1, groupName2, models.Channel_TYPE_TOPIC, ses2.ClientId, acc1.Id, acc2.Id)
				gtc2 := createChannelAndParticipants(admin1, groupName2, models.Channel_TYPE_TOPIC, ses2.ClientId, acc1.Id, acc2.Id)

				channels, err := rest.FetchChannelsByParticipants([]int64{acc1.Id, acc2.Id}, models.Channel_TYPE_TOPIC, ses1.ClientId)
				// there should be an err
				So(err, ShouldBeNil)
				So(channels, ShouldNotBeNil)
				So(len(channels), ShouldEqual, 2)
				So(channels[0].Channel.GroupName, ShouldEqual, groupName1)
				So(channels[1].Channel.GroupName, ShouldEqual, groupName1)
				So(tc1.Id, ShouldEqual, channels[0].Channel.Id)
				So(tc2.Id, ShouldEqual, channels[1].Channel.Id)

				channels, err = rest.FetchChannelsByParticipants([]int64{acc1.Id, acc2.Id}, models.Channel_TYPE_TOPIC, ses2.ClientId)
				// there should be an err
				So(err, ShouldBeNil)
				So(channels, ShouldNotBeNil)
				So(len(channels), ShouldEqual, 2)
				So(channels[0].Channel.GroupName, ShouldEqual, groupName2)
				So(channels[1].Channel.GroupName, ShouldEqual, groupName2)
				So(gtc1.Id, ShouldEqual, channels[0].Channel.Id)
				So(gtc2.Id, ShouldEqual, channels[1].Channel.Id)

			})
		})
	})
}
Ejemplo n.º 7
0
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)
				})
			})
		})
	})
}
Ejemplo n.º 8
0
func TestTeam(t *testing.T) {
	r := runner.New("test")
	if err := r.Init(); err != nil {
		t.Fatalf("couldnt start bongo %s", err.Error())
	}
	defer r.Close()

	appConfig := config.MustRead(r.Conf.Path)

	// init mongo connection
	modelhelper.Initialize(appConfig.Mongo)
	defer modelhelper.Close()

	handler := NewController(r.Log, appConfig)

	Convey("given a group", t, func() {
		// create admin
		admin, err := models.CreateAccountInBothDbsWithNick("sinan")
		So(err, ShouldBeNil)
		So(admin, ShouldNotBeNil)

		acc1, err := models.CreateAccountInBothDbs()
		So(err, ShouldBeNil)
		So(acc1, ShouldNotBeNil)

		// create another account
		acc2, err := models.CreateAccountInBothDbs()
		So(err, ShouldBeNil)
		So(acc2, ShouldNotBeNil)

		groupName := models.RandomGroupName()

		groupChannel := models.CreateTypedGroupedChannelWithTest(admin.Id, models.Channel_TYPE_GROUP, groupName)
		So(groupChannel, ShouldNotBeNil)

		defaultChannel1 := models.CreateTypedGroupedChannelWithTest(admin.Id, models.Channel_TYPE_TOPIC, groupName)
		So(defaultChannel1, ShouldNotBeNil)

		defaultChannel2 := models.CreateTypedGroupedChannelWithTest(admin.Id, models.Channel_TYPE_TOPIC, groupName)
		So(defaultChannel2, ShouldNotBeNil)

		group := &mongomodels.Group{
			Id:                 bson.NewObjectId(),
			Body:               groupName,
			Title:              groupName,
			Slug:               groupName,
			Privacy:            "private",
			Visibility:         "hidden",
			SocialApiChannelId: strconv.FormatInt(groupChannel.Id, 10),
			DefaultChannels: []string{
				strconv.FormatInt(defaultChannel1.Id, 10),
				strconv.FormatInt(defaultChannel2.Id, 10),
			},
		}

		err = modelhelper.CreateGroup(group)
		So(err, ShouldBeNil)

		Convey("should success if channel is not in db", func() {
			cp := &models.ChannelParticipant{
				AccountId: acc1.Id,
				ChannelId: math.MaxInt64,
			}
			err := handler.HandleParticipant(cp)
			So(err, ShouldBeNil)
		})

		Convey("should success if channel is not a group channel", func() {
			cp := &models.ChannelParticipant{
				AccountId: acc1.Id,
				ChannelId: defaultChannel1.Id,
			}
			err := handler.HandleParticipant(cp)
			So(err, ShouldBeNil)
		})

		Convey("should success if group is not in mongo", func() {
			groupName := models.RandomGroupName()

			groupChan := models.CreateTypedGroupedChannelWithTest(admin.Id, models.Channel_TYPE_GROUP, groupName)
			So(groupChan, ShouldNotBeNil)

			cp := &models.ChannelParticipant{
				AccountId: acc1.Id,
				ChannelId: groupChan.Id,
			}
			err := handler.HandleParticipant(cp)
			So(err, ShouldBeNil)
		})

		Convey("new participant should be in default channels", func() {
			cp := &models.ChannelParticipant{
				AccountId:      acc1.Id,
				ChannelId:      groupChannel.Id,
				StatusConstant: models.ChannelParticipant_STATUS_ACTIVE,
			}
			err := handler.HandleParticipant(cp)
			So(err, ShouldBeNil)

			isParticipant, err := defaultChannel1.IsParticipant(acc1.Id)
			So(err, ShouldBeNil)
			So(isParticipant, ShouldBeTrue)

			isParticipant, err = defaultChannel2.IsParticipant(acc1.Id)
			So(err, ShouldBeNil)
			So(isParticipant, ShouldBeTrue)

			Convey("after leaving group channel", func() {
				cp := &models.ChannelParticipant{
					AccountId:      acc1.Id,
					ChannelId:      groupChannel.Id,
					StatusConstant: models.ChannelParticipant_STATUS_LEFT,
				}
				err := handler.HandleParticipant(cp)
				So(err, ShouldBeNil)

				Convey("should be removed from default channels", func() {
					isParticipant, err := defaultChannel1.IsParticipant(acc1.Id)
					So(err, ShouldBeNil)
					So(isParticipant, ShouldBeFalse)

					isParticipant, err = defaultChannel2.IsParticipant(acc1.Id)
					So(err, ShouldBeNil)
					So(isParticipant, ShouldBeFalse)
				})

				Convey("should be removed from all channels", func() {
					ids, err := cp.FetchAllParticipatedChannelIdsInGroup(cp.AccountId, groupChannel.GroupName)
					So(err, ShouldBeNil)
					So(len(ids), ShouldEqual, 0)
				})
			})

			Convey("after being blocked", func() {
				cp := &models.ChannelParticipant{
					AccountId:      acc1.Id,
					ChannelId:      groupChannel.Id,
					StatusConstant: models.ChannelParticipant_STATUS_BLOCKED,
				}
				err := handler.HandleParticipant(cp)
				So(err, ShouldBeNil)

				Convey("should be removed from default channels", func() {
					isParticipant, err := defaultChannel1.IsParticipant(acc1.Id)
					So(err, ShouldBeNil)
					So(isParticipant, ShouldBeFalse)

					isParticipant, err = defaultChannel2.IsParticipant(acc1.Id)
					So(err, ShouldBeNil)
					So(isParticipant, ShouldBeFalse)
				})
			})
		})

		Convey("should success if default channels is not available anymore", func() {
			// delete the channel
			So(defaultChannel1.Delete(), ShouldBeNil)

			cp := &models.ChannelParticipant{
				AccountId:      acc1.Id,
				ChannelId:      groupChannel.Id,
				StatusConstant: models.ChannelParticipant_STATUS_ACTIVE,
			}
			err := handler.HandleParticipant(cp)
			So(err, ShouldBeNil)
		})
	})
}
Ejemplo n.º 9
0
func TestAccountTesting(t *testing.T) {
	runner, handler := getTestHandler()
	defer runner.Close()

	// init mongo connection
	appConfig := config.MustRead(runner.Conf.Path)
	modelhelper.Initialize(appConfig.Mongo)
	defer modelhelper.Close()

	Convey("given some fake account", t, func() {
		acc, _, name := models.CreateRandomGroupDataWithChecks()
		So(name, ShouldNotBeNil)
		So(acc, ShouldNotBeNil)

		Convey("it should save the document to algolia", func() {
			err := handler.AccountCreated(acc)
			So(err, ShouldBeNil)

			Convey("it should be able to fetch algolia data", func() {
				// make sure account is there
				So(doBasicTestForAccount(handler, acc.OldId), ShouldBeNil)

				_, err = modelhelper.GetUser(acc.Nick)
				So(err, ShouldBeNil)

				// update user's email
				selector := bson.M{"username": acc.Nick}
				newEmail := "mehmetalixsavasx1x2x" + models.RandomGroupName() + "@koding.com"
				updateQuery := bson.M{"email": newEmail}

				err = modelhelper.UpdateUser(selector, updateQuery)
				So(err, ShouldBeNil)

				err = handler.AccountUpdated(acc)
				So(err, ShouldBeNil)

				index, err := handler.indexes.GetIndex(IndexAccounts)
				So(err, ShouldBeNil)

				params := make(map[string]interface{})
				record, err := index.Search("mehmetalixsavasx1x2x", params)
				So(err, ShouldBeNil)

				hist, ok := record.(map[string]interface{})["hits"]

				usernames := make([]string, 0)
				objects := make([]string, 0)

				if ok {
					hinter, ok := hist.([]interface{})
					if ok {
						for _, v := range hinter {
							val, k := v.(map[string]interface{})
							if k {
								object := val["objectID"].(string)
								value := val["nick"].(string)

								usernames = append(usernames, value)
								objects = append(objects, object)

								_, err = index.DeleteObject(object)
								So(err, ShouldBeNil)
							}

						}
					}
				}

				So(usernames, ShouldNotBeNil)
				So(objects, ShouldNotBeNil)

			})

			Convey("it should be able to fetch many account with given query", func() {
				So(doBasicTestForAccount(handler, acc.OldId), ShouldBeNil)

				// we create 10 acc for algolia test
				for i := 0; i < 10; i++ {
					ac, _, _ := models.CreateRandomGroupDataWithChecks()

					err := handler.AccountCreated(ac)
					So(err, ShouldBeNil)

					selector := bson.M{"username": ac.Nick}
					newEmail := "mehmetali-test" + models.RandomGroupName() + "@koding.com"
					updateQuery := bson.M{"email": newEmail}
					err = modelhelper.UpdateUser(selector, updateQuery)
					So(err, ShouldBeNil)

					err = handler.AccountUpdated(ac)
					So(err, ShouldBeNil)
					time.Sleep(1 * time.Second)
				}

				//required for getting algolia datas correctly
				time.Sleep(5 * time.Second)

				_, err = modelhelper.GetUser(acc.Nick)
				So(err, ShouldBeNil)

				index, err := handler.indexes.GetIndex(IndexAccounts)
				So(err, ShouldBeNil)

				params := make(map[string]interface{})
				record, err := index.Search("mehmetali-test", params)
				So(err, ShouldBeNil)

				hist, ok := record.(map[string]interface{})["hits"]

				usernames := make([]string, 0)
				objects := make([]string, 0)

				if ok {
					hinter, ok := hist.([]interface{})
					if ok {
						for _, v := range hinter {
							val, k := v.(map[string]interface{})
							if k {
								object := val["objectID"].(string)
								value := val["nick"].(string)

								usernames = append(usernames, value)
								objects = append(objects, object)
							}

						}
					}
				}

				So(len(usernames), ShouldBeGreaterThan, 0)
				So(len(objects), ShouldBeGreaterThan, 0)

				Convey("it should be able to delete many account with given query", func() {

					So(doBasicTestForAccount(handler, acc.OldId), ShouldBeNil)

					for i := 0; i < 10; i++ {
						ac, _, _ := models.CreateRandomGroupDataWithChecks()

						err := handler.AccountCreated(ac)
						So(err, ShouldBeNil)

						selector := bson.M{"username": ac.Nick}
						newEmail := "mehmetali-test" + models.RandomGroupName() + "@koding.com"
						updateQuery := bson.M{"email": newEmail}
						err = modelhelper.UpdateUser(selector, updateQuery)
						So(err, ShouldBeNil)

						err = handler.AccountUpdated(ac)
						So(err, ShouldBeNil)
						time.Sleep(1 * time.Second)
					}

					time.Sleep(5 * time.Second)

					_, err = modelhelper.GetUser(acc.Nick)
					So(err, ShouldBeNil)

					_, err := handler.indexes.GetIndex(IndexAccounts)
					So(err, ShouldBeNil)

					usernames := make([]string, 0)
					objects := make([]string, 0)

					nbHits, _ := record.(map[string]interface{})["nbHits"]
					nbPages, _ := record.(map[string]interface{})["nbPages"]

					var pages float64 = nbPages.(float64)
					var nbHit float64 = nbHits.(float64)

					for pages > 0 && nbHit != 0 {
						record, err := index.Search("mehmetali-test", params)
						hist, ok := record.(map[string]interface{})["hits"]

						// fmt.Println("hist is :", hist)
						nbHits, _ := record.(map[string]interface{})["nbHits"]
						nbPages, _ := record.(map[string]interface{})["nbPages"]

						pages = nbPages.(float64)
						nbHit = nbHits.(float64)

						if ok {
							hinter, ok := hist.([]interface{})
							if ok {
								for _, v := range hinter {
									val, k := v.(map[string]interface{})
									if k {
										object := val["objectID"].(string)
										value := val["nick"].(string)

										usernames = append(usernames, value)
										objects = append(objects, object)
										_, err = index.DeleteObject(object)
										So(err, ShouldBeNil)
									}

								}
							}
						}
					}

					lenghtUsernames := len(usernames)
					lenghtObjects := len(objects)
					So(lenghtUsernames, ShouldBeGreaterThan, 10)
					So(lenghtObjects, ShouldBeGreaterThan, 10)

				})

				Convey("it should have delete algolia accounts", func() {
					fmt.Println("=============>>>>>>>>>>>>>>>>>>>")
					fmt.Println("=============>>>>>>>>>>>>>>>>>>>")
					fmt.Println("it should have delete algolia accounts")
					fmt.Println("=============>>>>>>>>>>>>>>>>>>>")
					fmt.Println("=============>>>>>>>>>>>>>>>>>>>")
					// make sure account is there
					So(doBasicTestForAccount(handler, acc.OldId), ShouldBeNil)

					for i := 0; i < 10; i++ {
						rand.Seed(time.Now().UnixNano())
						strconv.FormatInt(rand.Int63(), 10)
						name := "guter-" + strconv.FormatInt(rand.Int63(), 10)
						ac, _ := models.CreateAccountInBothDbsWithNick(name)

						err := handler.AccountCreated(ac)
						So(err, ShouldBeNil)

						selector := bson.M{"username": ac.Nick}
						newEmail := "mehmetali-test" + models.RandomGroupName() + "@koding.com"
						updateQuery := bson.M{"email": newEmail}
						err = modelhelper.UpdateUser(selector, updateQuery)
						So(err, ShouldBeNil)

						err = handler.AccountUpdated(ac)
						So(err, ShouldBeNil)
						time.Sleep(1 * time.Second)
					}

					time.Sleep(5 * time.Second)

					_, err = handler.indexes.GetIndex(IndexAccounts)
					So(err, ShouldBeNil)

					// record, _ := index.Search("mehmetalisa", map[string]interface{}{"restrictSearchableAttributes": "email"})
					// params := make(map[string]interface{})
					params := map[string]interface{}{"restrictSearchableAttributes": "nick"}
					record, _ := index.Search("guter-", params)

					hits, _ := record.(map[string]interface{})["nbHits"]
					hit := hits.(float64)
					So(hit, ShouldBeGreaterThan, 0)

					err = handler.DeleteNicksWithQuery("guter-")
					So(err, ShouldBeNil)

					// necessary for getting datas from algolia,
					time.Sleep(5 * time.Second)

					r, err := index.Search("guter-", params)
					So(err, ShouldBeNil)
					nbHits, _ := r.(map[string]interface{})["nbHits"]
					nbHit := nbHits.(float64)
					So(nbHit, ShouldBeLessThan, 10)
				})
			})
		})
	})
}
Ejemplo n.º 10
0
func TestChannelUpdatedCalculateUnreadItemCount(t *testing.T) {
	r := runner.New("test")
	if err := r.Init(); err != nil {
		t.Fatalf("couldnt start bongo %s", err.Error())
	}
	defer r.Close()

	appConfig := config.MustRead(r.Conf.Path)
	modelhelper.Initialize(appConfig.Mongo)
	defer modelhelper.Close()

	groupName := models.RandomGroupName()

	Convey("while testing get account", t, func() {
		Convey("if cookie is not set, should return nil", func() {
			a := getAccount(&http.Request{}, models.Channel_KODING_NAME)
			So(a, ShouldNotBeNil)
			So(a.Id, ShouldBeZeroValue)
		})

		Convey("if cookie value is not set, should return nil", func() {
			req, _ := http.NewRequest("GET", "/", nil)

			expire := time.Now().AddDate(0, 0, 1)
			cookie := http.Cookie{
				Name:    "clientId",
				Value:   "",
				Path:    "/",
				Domain:  "localhost",
				Expires: expire,
			}

			req.AddCookie(&cookie)

			a := getAccount(req, models.Channel_KODING_NAME)
			So(a, ShouldNotBeNil)
			So(a.Id, ShouldBeZeroValue)
		})

		Convey("if session doesnt have username, should return nil", func() {
			ses, err := modelhelper.CreateSessionForAccount("", groupName)
			So(err, ShouldBeNil)
			So(ses, ShouldNotBeNil)

			req, _ := http.NewRequest("GET", "/", nil)
			expire := time.Now().AddDate(0, 0, 1)
			cookie := http.Cookie{
				Name:    "clientId",
				Value:   ses.ClientId,
				Path:    "/",
				Domain:  "localhost",
				Expires: expire,
			}

			req.AddCookie(&cookie)

			a := getAccount(req, models.Channel_KODING_NAME)
			So(a, ShouldNotBeNil)
			So(a.Id, ShouldBeZeroValue)
		})

		Convey("if session is valid, should return account", func() {
			acc, err := models.CreateAccountInBothDbs()
			So(err, ShouldBeNil)
			So(acc, ShouldNotBeNil)

			ses, err := modelhelper.CreateSessionForAccount(acc.Nick, groupName)
			So(err, ShouldBeNil)
			So(ses, ShouldNotBeNil)

			req, _ := http.NewRequest("GET", "/", nil)
			expire := time.Now().AddDate(0, 0, 1)
			cookie := http.Cookie{
				Name:    "clientId",
				Value:   ses.ClientId,
				Path:    "/",
				Domain:  "localhost",
				Expires: expire,
			}

			req.AddCookie(&cookie)

			res := getAccount(req, models.Channel_KODING_NAME)
			So(res, ShouldNotBeNil)
			So(acc.Id, ShouldEqual, res.Id)
		})
	})

	Convey("while making sure account", t, func() {
		Convey("if account is not in postgres", func() {

			nick := models.RandomName()
			oldAcc := &kodingmodels.Account{
				Id: bson.NewObjectId(),
				Profile: kodingmodels.AccountProfile{
					Nickname: nick,
				},
			}
			err := modelhelper.CreateAccount(oldAcc)
			So(err, ShouldBeNil)

			oldUser := &kodingmodels.User{
				ObjectId:       bson.NewObjectId(),
				Password:       nick,
				Salt:           nick,
				Name:           nick,
				Email:          nick + "@koding.com",
				EmailFrequency: &kodingmodels.EmailFrequency{},
			}

			err = modelhelper.CreateUser(oldUser)
			So(err, ShouldBeNil)

			groupName := models.RandomGroupName()
			_, err = makeSureAccount(groupName, nick)
			So(err, ShouldBeNil)

			Convey("should create it in postgres", func() {
				a := models.NewAccount()
				err = a.ByNick(nick)
				So(err, ShouldBeNil)
				So(a.OldId, ShouldEqual, oldAcc.Id.Hex())

				Convey("should set socialAPI id in mongo", func() {
					oldAccFromDB, err := modelhelper.GetAccount(nick)
					So(err, ShouldBeNil)
					So(oldAccFromDB.SocialApiId, ShouldEqual, strconv.FormatInt(a.Id, 10))
				})
			})
		})

		Convey("if account is in postgres", func() {
			acc, err := models.CreateAccountInBothDbs()
			So(err, ShouldBeNil)
			So(acc, ShouldNotBeNil)

			groupName := models.RandomGroupName()

			_, err = makeSureAccount(groupName, acc.Nick)
			So(err, ShouldBeNil)

			Convey("should be in postgres", func() {
				a := models.NewAccount()
				err = a.ByNick(acc.Nick)
				So(err, ShouldBeNil)
				So(a.OldId, ShouldEqual, acc.OldId)

				Convey("should have socialAPI set", func() {
					oldAccFromDB, err := modelhelper.GetAccount(acc.Nick)
					So(err, ShouldBeNil)
					So(oldAccFromDB.SocialApiId, ShouldEqual, strconv.FormatInt(a.Id, 10))
				})
			})
		})
	})

	Convey("while making sure group membership", t, func() {
		Convey("if account is not not a member", func() {
			account := models.CreateAccountWithTest()
			requester := models.CreateAccountWithTest()
			groupChannel := models.CreateTypedPublicChannelWithTest(account.Id, models.Channel_TYPE_GROUP)

			err := makeSureMembership(groupChannel, requester.Id)
			So(err, ShouldBeNil)

			Convey("should add as participant", func() {
				status, err := groupChannel.IsParticipant(requester.Id)
				So(err, ShouldBeNil)
				So(status, ShouldBeTrue)

				Convey("if account is a member", func() {
					err := makeSureMembership(groupChannel, requester.Id)
					So(err, ShouldBeNil)

					Convey("should be a participant", func() {
						status, err := groupChannel.IsParticipant(requester.Id)
						So(err, ShouldBeNil)
						So(status, ShouldBeTrue)
					})
				})
			})

		})
	})
}
Ejemplo n.º 11
0
func TestCollaboration(t *testing.T) {
	r := runner.New("collaboration-tests")
	err := r.Init()
	if err != nil {
		panic(err)
	}

	defer r.Close()

	appConfig := config.MustRead(r.Conf.Path)

	modelhelper.Initialize(appConfig.Mongo)
	defer modelhelper.Close()

	// init with defaults
	mongoCache := cache.NewMongoCacheWithTTL(modelhelper.Mongo.Session)
	defer mongoCache.StopGC()

	handler := New(r.Log, mongoCache, appConfig, r.Kite)

	Convey("while pinging collaboration", t, func() {
		// owner
		owner := apimodels.NewAccount()
		owner.OldId = AccountOldId.Hex()
		owner, err := rest.CreateAccount(owner)
		So(err, ShouldBeNil)
		So(owner, ShouldNotBeNil)

		groupName := apimodels.RandomGroupName()

		ownerSession, err := modelhelper.FetchOrCreateSession(owner.Nick, groupName)
		So(err, ShouldBeNil)
		So(ownerSession, ShouldNotBeNil)

		rand.Seed(time.Now().UnixNano())

		req := &models.Ping{
			AccountId: 1,
			FileId:    fmt.Sprintf("%d", rand.Int63()),
		}

		Convey("while testing Ping", func() {
			Convey("reponse should be success with valid ping", func() {
				err = handler.Ping(req)
				So(err, ShouldBeNil)
			})

			Convey("reponse should be success with invalid FileId", func() {
				req.FileId = ""
				err = handler.Ping(req)
				So(err, ShouldBeNil)
			})

			Convey("reponse should be success with invalid AccountId", func() {
				req.AccountId = 0
				err = handler.Ping(req)
				So(err, ShouldBeNil)
			})

			Convey("reponse should be success with invalid session", func() {
				req := req
				// prepare an invalid session here
				req.CreatedAt = time.Now().UTC()

				err = mongoCache.SetEx(PrepareFileKey(req.FileId), ExpireSessionKeyDuration, req.CreatedAt.Add(-terminateSessionDuration))

				err = handler.Ping(req)
				So(err, ShouldBeNil)
			})

			Convey("after sleep time", func() {
				req := req

				Convey("expired session should get invalidSessoin", func() {
					st := sleepTime
					sleepTime = time.Millisecond * 110

					tsd := terminateSessionDuration
					terminateSessionDuration = 100

					// set durations back to the original value
					defer func() {
						sleepTime = st
						terminateSessionDuration = tsd
					}()

					req.CreatedAt = time.Now().UTC()
					// prepare a valid key
					err = mongoCache.SetEx(
						PrepareFileKey(req.FileId),
						terminateSessionDuration, // expire the key after this period
						req.CreatedAt.Unix())

					// while sleeping here, redis key should be removed
					// and we can understand that the Collab session is expired
					time.Sleep(sleepTime)

					req := req
					err = handler.wait(req)
					So(err, ShouldEqual, errSessionInvalid)
				})

				Convey("deadlined session should get errDeadlineReached", func() {
					st := sleepTime
					sleepTime = time.Millisecond * 110

					dd := deadLineDuration
					deadLineDuration = 100

					// set durations back to the original value
					defer func() {
						sleepTime = st
						deadLineDuration = dd
					}()

					req := req
					err := handler.wait(req)
					So(err, ShouldEqual, errDeadlineReached)
				})
			})
		})

		Convey("while testing checkIfKeyIsValid", func() {

			req := req
			req.CreatedAt = time.Now().UTC()

			// prepare a valid key
			err := mongoCache.SetEx(
				PrepareFileKey(req.FileId),
				ExpireSessionKeyDuration, // expire the key after this period
				req.CreatedAt.Unix(),     // value - unix time
			)

			So(err, ShouldBeNil)

			Convey("valid key should return nil", func() {
				err = handler.checkIfKeyIsValid(req)
				So(err, ShouldBeNil)
			})

			Convey("invalid key should return errSessionInvalid", func() {
				req := req
				// override fileId
				req.FileId = fmt.Sprintf("%d", rand.Int63())
				err = handler.checkIfKeyIsValid(req)
				So(err, ShouldEqual, errSessionInvalid)
			})

			Convey("invalid (non-timestamp) value should return errSessionInvalid", func() {
				req := req
				req.CreatedAt = time.Now().UTC()
				err = mongoCache.SetEx(
					PrepareFileKey(req.FileId),
					ExpireSessionKeyDuration, // expire the key after this period
					"req.CreatedAt.Unix()",   // replace timestamp with unix time
				)

				err = handler.checkIfKeyIsValid(req)

				So(err, ShouldEqual, errSessionInvalid)
			})

			Convey("old ping time should return errSessionInvalid", func() {
				req := req
				req.CreatedAt = time.Now().UTC()
				err = mongoCache.SetEx(
					PrepareFileKey(req.FileId),
					ExpireSessionKeyDuration, // expire the key after this period
					req.CreatedAt.Add(-terminateSessionDuration).Unix(),
				)

				err = handler.checkIfKeyIsValid(req)
				So(err, ShouldEqual, errSessionInvalid)
			})

			Convey("previous ping time is in safe area", func() {
				req := req
				testPingTimes(req, -1, mongoCache, handler, nil)
			})

			Convey("0 ping time is in safe area", func() {
				req := req
				testPingTimes(req, 0, mongoCache, handler, nil)
			})

			Convey("2 ping time is in safe area", func() {
				req := req
				testPingTimes(req, 2, mongoCache, handler, nil)
			})

			Convey("3 ping time is in safe area", func() {
				req := req
				testPingTimes(req, 3, mongoCache, handler, nil)
			})

			Convey("4 ping time is not in safe area - because we already reverted the time ", func() {
				req := req
				testPingTimes(req, 4, mongoCache, handler, errSessionInvalid)
			})

			Convey("5 ping time is not in safe area ", func() {
				req := req
				testPingTimes(req, 5, mongoCache, handler, errSessionInvalid)
			})
		})
	})
}
Ejemplo n.º 12
0
func TestPinnedActivityChannel(t *testing.T) {
	tests.WithRunner(t, func(r *runner.Runner) {

		SkipConvey("while  testing pinned activity channel", t, func() {
			groupName := models.RandomGroupName()

			account := models.NewAccount()
			account.OldId = AccountOldId.Hex()
			account, err := rest.CreateAccount(account)
			So(err, ShouldBeNil)
			So(account, ShouldNotBeNil)
			So(account.Id, ShouldNotEqual, 0)

			ses, err := modelhelper.FetchOrCreateSession(account.Nick, groupName)
			So(err, ShouldBeNil)
			So(ses, ShouldNotBeNil)

			nonOwnerAccount := models.NewAccount()
			nonOwnerAccount.OldId = AccountOldId.Hex()
			nonOwnerAccount, err = rest.CreateAccount(nonOwnerAccount)
			So(err, ShouldBeNil)
			So(nonOwnerAccount, ShouldNotBeNil)

			nonOwnerSes, err := modelhelper.FetchOrCreateSession(nonOwnerAccount.Nick, groupName)
			So(err, ShouldBeNil)
			So(nonOwnerSes, ShouldNotBeNil)

			groupChannel, err := rest.CreateChannelByGroupNameAndType(
				account.Id,
				groupName,
				models.Channel_TYPE_GROUP,
				ses.ClientId,
			)
			So(err, ShouldBeNil)
			So(groupChannel, ShouldNotBeNil)

			post, err := rest.CreatePost(groupChannel.Id, ses.ClientId)
			So(err, ShouldBeNil)
			So(post, ShouldNotBeNil)

			Convey("requester should have one", func() {
				account := account
				channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
				So(err, ShouldBeNil)
				So(channel, ShouldNotBeNil)
				So(channel.Id, ShouldNotEqual, 0)
				So(channel.TypeConstant, ShouldEqual, models.Channel_TYPE_PINNED_ACTIVITY)
				So(channel.CreatorId, ShouldEqual, account.Id)
			})

			Convey("owner should be able to update it", nil)

			Convey("non-owner should not be able to update it", nil)

			Convey("owner should not be able to add new participants into it", func() {
				channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
				So(err, ShouldBeNil)
				So(channel, ShouldNotBeNil)
				channelParticipant, err := rest.AddChannelParticipant(channel.Id, ses.ClientId, nonOwnerAccount.Id)
				// there should be an err
				So(err, ShouldNotBeNil)
				// channel should be nil
				So(channelParticipant, ShouldBeNil)
			})

			Convey("normal user shouldnt be able to add new participants to it", func() {
				channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
				So(err, ShouldBeNil)
				So(channel, ShouldNotBeNil)
				channelParticipant, err := rest.AddChannelParticipant(channel.Id, nonOwnerSes.ClientId, nonOwnerAccount.Id)
				// there should be an err
				So(err, ShouldNotBeNil)
				// channel should be nil
				So(channelParticipant, ShouldBeNil)
			})

			Convey("owner should  not be able to remove participant from it", func() {
				channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
				So(err, ShouldBeNil)
				So(channel, ShouldNotBeNil)
				channelParticipant, err := rest.DeleteChannelParticipant(channel.Id, ses.ClientId, nonOwnerAccount.Id)
				// there should be an err
				So(err, ShouldNotBeNil)
				// channel should be nil
				So(channelParticipant, ShouldBeNil)
			})

			Convey("normal user shouldnt be able to remove participants from it", func() {
				channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
				So(err, ShouldBeNil)
				So(channel, ShouldNotBeNil)
				channelParticipant, err := rest.DeleteChannelParticipant(channel.Id, nonOwnerSes.ClientId, nonOwnerAccount.Id)
				// there should be an err
				So(err, ShouldNotBeNil)
				// channel should be nil
				So(channelParticipant, ShouldBeNil)
			})

			Convey("owner should be able to add new message into it", func() {
				_, err := rest.AddPinnedMessage(account.Id, post.Id, "koding")
				// there should be an err
				So(err, ShouldBeNil)

				_, err = rest.RemovePinnedMessage(account.Id, post.Id, "koding")
				So(err, ShouldBeNil)

			})

			Convey("owner should be able to list messages", func() {
				groupName := "testgroup" + strconv.FormatInt(rand.Int63(), 10)

				pinnedChannel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
				So(err, ShouldBeNil)
				So(pinnedChannel, ShouldNotBeNil)

				groupChannel, err := rest.CreateChannelByGroupNameAndType(
					account.Id,
					groupName,
					models.Channel_TYPE_DEFAULT,
					ses.ClientId,
				)
				So(err, ShouldBeNil)
				So(groupChannel, ShouldNotBeNil)

				post1, err := rest.CreatePostWithBody(groupChannel.Id, nonOwnerAccount.Id, "create a message #1times")
				So(err, ShouldBeNil)
				So(post1, ShouldNotBeNil)

				_, err = rest.AddPinnedMessage(nonOwnerAccount.Id, post1.Id, groupName)
				// there should be an err
				So(err, ShouldBeNil)

				post2, err := rest.CreatePostWithBody(groupChannel.Id, nonOwnerAccount.Id, "create a message #1another")
				So(err, ShouldBeNil)
				So(post2, ShouldNotBeNil)

				_, err = rest.AddPinnedMessage(nonOwnerAccount.Id, post2.Id, groupName)
				// there should be an err
				So(err, ShouldBeNil)

				//time.Sleep(time.Second * 5)

				history, err := rest.FetchPinnedMessages(account.Id, groupName)
				// there should be an err
				So(err, ShouldBeNil)
				// channel should be nil
				So(history, ShouldNotBeNil)

				// message count should be 2
				So(len(history.MessageList), ShouldEqual, 2)

				// unread count should be 0
				So(history.UnreadCount, ShouldEqual, 0)

				// old id should be the same one
				So(history.MessageList[0].AccountOldId, ShouldContainSubstring, nonOwnerAccount.OldId)

				// replies count should be 0
				So(len(history.MessageList[0].Replies), ShouldEqual, 0)
			})

			Convey("Messages shouldnt be added as pinned twice ", func() {
				// use account id as message id
				_, err := rest.AddPinnedMessage(account.Id, post.Id, "koding")
				// there should be an err
				So(err, ShouldBeNil)
				// use account id as message id, pin message is idempotent, if it is
				// in the channel, wont give error
				_, err = rest.AddPinnedMessage(account.Id, post.Id, "koding")
				// there should not be an err
				So(err, ShouldBeNil)
			})

			Convey("Non-exist message should not be added as pinned ", nil)

		})
	})
}
Ejemplo n.º 13
0
func TestPrivateMesssages(t *testing.T) {
	tests.WithRunner(t, func(r *runner.Runner) {
		Convey("while testing private channels", t, func() {
			devrim, err := models.CreateAccountInBothDbsWithNick("devrim")
			So(err, ShouldBeNil)
			So(devrim, ShouldNotBeNil)
			sinan, err := models.CreateAccountInBothDbsWithNick("sinan")
			So(err, ShouldBeNil)
			So(sinan, ShouldNotBeNil)

			groupName := models.RandomGroupName()

			// cretae admin user
			account, err := models.CreateAccountInBothDbs()
			tests.ResultedWithNoErrorCheck(account, err)

			models.CreateTypedGroupedChannelWithTest(
				account.Id,
				models.Channel_TYPE_GROUP,
				groupName,
			)

			// fetch admin's session
			ses, err := modelhelper.FetchOrCreateSession(account.Nick, groupName)
			So(err, ShouldBeNil)
			So(ses, ShouldNotBeNil)

			groupChannel, err := rest.CreateChannelByGroupNameAndType(
				account.Id,
				groupName,
				models.Channel_TYPE_GROUP,
				ses.ClientId,
			)
			tests.ResultedWithNoErrorCheck(groupChannel, err)

			recipient := models.NewAccount()
			recipient.OldId = AccountOldId2.Hex()
			recipient, err = rest.CreateAccount(recipient)
			So(err, ShouldBeNil)
			So(recipient, ShouldNotBeNil)

			recipient2 := models.NewAccount()
			recipient2.OldId = AccountOldId3.Hex()
			recipient2, err = rest.CreateAccount(recipient2)
			So(err, ShouldBeNil)
			So(recipient2, ShouldNotBeNil)

			Convey("participants should be a member of parent group", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body message for private message @devrim @sinan"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"devrim", "sinan"}
				_, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldNotBeNil)
			})

			_, err = groupChannel.AddParticipant(sinan.Id)
			So(err, ShouldBeNil)

			_, err = groupChannel.AddParticipant(devrim.Id)
			So(err, ShouldBeNil)

			Convey("one can send private message to one person", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body message for private message @devrim @sinan"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"devrim", "sinan"}
				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)

			})

			Convey("0 recipient should not fail", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body for private message"
				pmr.GroupName = groupName
				pmr.Recipients = []string{}

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)

			})

			Convey("if sender is not defined but token is added, then shouldn't fail to create PM", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = 0
				pmr.Body = "this is a body for private message"
				pmr.GroupName = ""
				pmr.Recipients = []string{}

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)
			})

			Convey("one can send private message to multiple person", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body for private message @sinan"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"sinan"}
				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)

			})
			Convey("private message response should have created channel", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body for private message @devrim @sinan"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"devrim", "sinan"}

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)
				So(cmc.Channel.TypeConstant, ShouldEqual, models.Channel_TYPE_PRIVATE_MESSAGE)
				So(cmc.Channel.Id, ShouldBeGreaterThan, 0)
				So(cmc.Channel.GroupName, ShouldEqual, groupName)
				So(cmc.Channel.PrivacyConstant, ShouldEqual, models.Channel_PRIVACY_PRIVATE)

			})

			Convey("private message response should have participant status data", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body for private message @devrim @sinan"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"devrim", "sinan"}

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)
				So(cmc.IsParticipant, ShouldBeTrue)
			})

			Convey("private message response should have participant count", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body for @sinan private message @devrim"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"devrim", "sinan"}
				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)
				So(cmc.ParticipantCount, ShouldEqual, 3)
			})

			Convey("private message response should have participant preview", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is @sinan a body for @devrim private message"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"sinan", "devrim"}
				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)
				So(len(cmc.ParticipantsPreview), ShouldEqual, 3)
			})

			Convey("private message response should have last Message", func() {
				body := "hi @devrim this is a body for private message also for @sinan"
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = body
				pmr.GroupName = groupName
				pmr.Recipients = []string{"sinan", "devrim"}
				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)
				So(cmc.LastMessage.Message.Body, ShouldEqual, body)
			})

			Convey("private message should be listed by all recipients", func() {
				body := "hi @devrim this is a body for private message also for @sinan"
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = body
				pmr.GroupName = groupName
				pmr.Recipients = []string{"sinan", "devrim"}
				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)

				pm, err := rest.GetPrivateChannels(&request.Query{AccountId: account.Id, GroupName: groupName}, ses.ClientId)
				So(err, ShouldBeNil)
				So(pm, ShouldNotBeNil)
				So(len(pm), ShouldNotEqual, 0)
				So(pm[0], ShouldNotBeNil)
				So(pm[0].Channel.TypeConstant, ShouldEqual, models.Channel_TYPE_PRIVATE_MESSAGE)
				So(pm[0].Channel.Id, ShouldEqual, cmc.Channel.Id)
				So(pm[0].Channel.GroupName, ShouldEqual, cmc.Channel.GroupName)
				So(pm[0].LastMessage.Message.Body, ShouldEqual, cmc.LastMessage.Message.Body)
				So(pm[0].Channel.PrivacyConstant, ShouldEqual, models.Channel_PRIVACY_PRIVATE)
				So(len(pm[0].ParticipantsPreview), ShouldEqual, 3)
				So(pm[0].IsParticipant, ShouldBeTrue)

			})

			Convey("user should be able to search private messages via purpose field", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "search private messages"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"sinan", "devrim"}
				pmr.Purpose = "test me up"

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)

				query := request.Query{AccountId: account.Id, GroupName: groupName}
				_, err = rest.SearchPrivateChannels(&query, ses.ClientId)
				So(err, ShouldNotBeNil)

				query.Name = "test"
				pm, err := rest.SearchPrivateChannels(&query, ses.ClientId)
				So(err, ShouldBeNil)
				So(pm, ShouldNotBeNil)
				So(len(pm), ShouldNotEqual, 0)
				So(pm[0], ShouldNotBeNil)
				So(pm[0].Channel.TypeConstant, ShouldEqual, models.Channel_TYPE_PRIVATE_MESSAGE)
				So(pm[0].Channel.Id, ShouldEqual, cmc.Channel.Id)
				So(pm[0].Channel.GroupName, ShouldEqual, cmc.Channel.GroupName)
				So(pm[0].LastMessage.Message.Body, ShouldEqual, cmc.LastMessage.Message.Body)
				So(pm[0].Channel.PrivacyConstant, ShouldEqual, models.Channel_PRIVACY_PRIVATE)
				So(pm[0].IsParticipant, ShouldBeTrue)

			})

			payload := gorm.Hstore{}
			bar := "bar"
			payload["foo"] = &bar

			Convey("given payload should be populated", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body message for private message @devrim @sinan"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"devrim", "sinan"}
				pmr.Payload = payload

				pcr, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(pcr, ShouldNotBeNil)
				So(pcr.Channel, ShouldNotBeNil)
				So(pcr.Channel.Payload, ShouldNotBeNil)
				So(len(pcr.Channel.Payload), ShouldBeGreaterThan, 0)
				So(*pcr.Channel.Payload["foo"], ShouldEqual, bar)
			})

			Convey("user join activity should be listed by recipients", func() {
				groupName := models.RandomGroupName()

				// cretae admin user
				account, err := models.CreateAccountInBothDbs()
				tests.ResultedWithNoErrorCheck(account, err)
				// fetch admin's session
				ses, err := modelhelper.FetchOrCreateSession(account.Nick, groupName)
				So(err, ShouldBeNil)
				So(ses, ShouldNotBeNil)

				groupChannel := models.CreateTypedGroupedChannelWithTest(
					account.Id,
					models.Channel_TYPE_GROUP,
					groupName,
				)
				So(groupChannel, ShouldNotBeNil)

				_, err = groupChannel.AddParticipant(account.Id)
				So(err, ShouldBeNil)
				_, err = groupChannel.AddParticipant(devrim.Id)
				So(err, ShouldBeNil)
				_, err = groupChannel.AddParticipant(sinan.Id)
				So(err, ShouldBeNil)
				_, err = groupChannel.AddParticipant(recipient.Id)
				So(err, ShouldBeNil)

				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "test private message participants"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"sinan", "devrim"}
				if pmr.Payload == nil {
					pmr.Payload = gorm.Hstore{}
				}
				pic := "pictureSomethingLikeThat"
				pmr.Payload["link_embed"] = &pic

				cc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)

				So(err, ShouldBeNil)
				So(cc, ShouldNotBeNil)

				history, err := rest.GetHistory(
					cc.Channel.Id,
					&request.Query{
						AccountId: account.Id,
					},
					ses.ClientId,
				)

				So(err, ShouldBeNil)
				So(history, ShouldNotBeNil)
				So(len(history.MessageList), ShouldEqual, 2)

				// add participant
				_, err = rest.AddChannelParticipant(cc.Channel.Id, ses.ClientId, recipient.Id)
				So(err, ShouldBeNil)

				history, err = rest.GetHistory(
					cc.Channel.Id,
					&request.Query{
						AccountId: account.Id,
					},
					ses.ClientId,
				)

				So(err, ShouldBeNil)
				So(history, ShouldNotBeNil)
				So(len(history.MessageList), ShouldEqual, 3)

				So(history.MessageList[0].Message, ShouldNotBeNil)
				So(history.MessageList[0].Message.TypeConstant, ShouldEqual, models.ChannelMessage_TYPE_SYSTEM)
				So(history.MessageList[0].Message.Payload, ShouldNotBeNil)
				addedBy, ok := history.MessageList[0].Message.Payload["addedBy"]
				So(ok, ShouldBeTrue)
				So(*addedBy, ShouldEqual, account.Nick)

				systemType, ok := history.MessageList[0].Message.Payload["systemType"]
				So(ok, ShouldBeTrue)
				So(*systemType, ShouldEqual, models.ChannelRequestMessage_TYPE_JOIN)

				// we set link_embed into the payloadof the system message above.
				// But system message payload data will not have payload defined
				// by client side or else
				// As a result, system message will not be able to have link_embed payload data
				_, k := history.MessageList[0].Message.Payload["link_embed"]
				So(k, ShouldBeFalse)

				// try to add same participant
				_, err = rest.AddChannelParticipant(cc.Channel.Id, ses.ClientId, recipient.Id)
				So(err, ShouldBeNil)

				history, err = rest.GetHistory(
					cc.Channel.Id,
					&request.Query{
						AccountId: account.Id,
					},
					ses.ClientId,
				)

				So(err, ShouldBeNil)
				So(history, ShouldNotBeNil)
				So(len(history.MessageList), ShouldEqual, 3)

			})

			Convey("user should not be able to edit join messages", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "test private message participants again"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"devrim"}

				cc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cc, ShouldNotBeNil)

				_, err = rest.AddChannelParticipant(cc.Channel.Id, ses.ClientId, recipient.Id)
				So(err, ShouldBeNil)

				ses, err := modelhelper.FetchOrCreateSession(account.Nick, groupName)
				So(err, ShouldBeNil)
				So(ses, ShouldNotBeNil)

				history, err := rest.GetHistory(
					cc.Channel.Id,
					&request.Query{
						AccountId: account.Id,
					},
					ses.ClientId,
				)

				So(err, ShouldBeNil)
				So(history, ShouldNotBeNil)
				So(len(history.MessageList), ShouldEqual, 3)

				joinMessage := history.MessageList[0].Message
				So(joinMessage, ShouldNotBeNil)

				_, err = rest.UpdatePost(joinMessage, ses.ClientId)
				So(err, ShouldNotBeNil)
			})

			Convey("first chat message should include initial participants", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "test initial participation message"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"sinan", "devrim"}

				cc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cc, ShouldNotBeNil)

				ses, err := modelhelper.FetchOrCreateSession(account.Nick, groupName)
				So(err, ShouldBeNil)
				So(ses, ShouldNotBeNil)

				history, err := rest.GetHistory(
					cc.Channel.Id,
					&request.Query{
						AccountId: account.Id,
					},
					ses.ClientId,
				)

				So(err, ShouldBeNil)
				So(history, ShouldNotBeNil)
				So(len(history.MessageList), ShouldEqual, 2)

				joinMessage := history.MessageList[1].Message
				So(joinMessage.TypeConstant, ShouldEqual, models.ChannelMessage_TYPE_SYSTEM)
				So(joinMessage.Payload, ShouldNotBeNil)
				initialParticipants, ok := joinMessage.Payload["initialParticipants"]
				So(ok, ShouldBeTrue)

				systemType, ok := history.MessageList[1].Message.Payload["systemType"]
				So(ok, ShouldBeTrue)
				So(*systemType, ShouldEqual, models.ChannelRequestMessage_TYPE_INIT)

				participants := make([]string, 0)
				err = json.Unmarshal([]byte(*initialParticipants), &participants)
				So(err, ShouldBeNil)
				So(len(participants), ShouldEqual, 2)
				So(participants, ShouldContain, "devrim")
				// So(*addedBy, ShouldEqual, account.OldId)

			})

			Convey("targetted account should be able to list private message channel of himself", nil)
		})
	})
}
Ejemplo n.º 14
0
func TestGroupChannel(t *testing.T) {
	tests.WithRunner(t, func(r *runner.Runner) {
		Convey("while  testing pinned activity channel", t, func() {
			groupName := models.RandomGroupName()

			account, err := models.CreateAccountInBothDbs()
			So(err, ShouldBeNil)

			ses, err := modelhelper.FetchOrCreateSession(account.Nick, groupName)
			So(err, ShouldBeNil)
			So(ses, ShouldNotBeNil)

			models.CreateTypedGroupedChannelWithTest(
				account.Id,
				models.Channel_TYPE_GROUP,
				groupName,
			)

			Convey("channel should be there", func() {
				channel1, err := rest.CreateChannelByGroupNameAndType(
					account.Id,
					groupName,
					models.Channel_TYPE_GROUP,
					ses.ClientId,
				)
				So(err, ShouldBeNil)
				So(channel1, ShouldNotBeNil)

				channel2, err := rest.CreateChannelByGroupNameAndType(
					account.Id,
					groupName,
					models.Channel_TYPE_GROUP,
					ses.ClientId,
				)
				So(err, ShouldBeNil)
				So(channel2, ShouldNotBeNil)
			})

			Convey("group channel should be shown before announcement", func() {
				account, err := models.CreateAccountInBothDbs()
				So(err, ShouldBeNil)

				ses, err := modelhelper.FetchOrCreateSession(account.Nick, groupName)
				So(err, ShouldBeNil)
				So(ses, ShouldNotBeNil)

				_, err = rest.CreateChannelByGroupNameAndType(
					account.Id,
					groupName,
					models.Channel_TYPE_GROUP,
					ses.ClientId,
				)
				So(err, ShouldBeNil)

				_, err = rest.CreateChannelByGroupNameAndType(
					account.Id,
					groupName,
					models.Channel_TYPE_ANNOUNCEMENT,
					ses.ClientId,
				)
				So(err, ShouldBeNil)
				channels, err := rest.FetchChannelsByQuery(account.Id, &request.Query{
					GroupName: groupName,
					Type:      models.Channel_TYPE_GROUP,
				},
					ses.ClientId,
				)
				So(err, ShouldBeNil)
				So(len(channels), ShouldEqual, 2)
				So(channels[0].TypeConstant, ShouldEqual, models.Channel_TYPE_GROUP)
				So(channels[1].TypeConstant, ShouldEqual, models.Channel_TYPE_ANNOUNCEMENT)

			})

			Convey("owner should be able to update it", func() {
				channel1, err := rest.CreateChannelByGroupNameAndType(
					account.Id,
					groupName,
					models.Channel_TYPE_GROUP,
					ses.ClientId,
				)
				So(err, ShouldBeNil)
				So(channel1, ShouldNotBeNil)
				// fetching channel returns creator id
				_, err = rest.UpdateChannel(channel1, ses.ClientId)
				So(err, ShouldBeNil)
			})

			Convey("owner should only be able to update name and purpose of the channel", nil)

			Convey("normal user should be able to update it if and only if user is creator or participant", func() {
				channel1, err := rest.CreateChannelByGroupNameAndType(
					account.Id,
					groupName,
					models.Channel_TYPE_GROUP,
					ses.ClientId,
				)
				So(err, ShouldBeNil)
				So(channel1, ShouldNotBeNil)

				anotherAccount := models.NewAccount()
				anotherAccount.OldId = bson.NewObjectId().Hex()
				anotherAccount, err = rest.CreateAccount(anotherAccount)

				So(err, ShouldBeNil)
				So(account, ShouldNotBeNil)

				ses, err := modelhelper.FetchOrCreateSession(anotherAccount.Nick, groupName)
				So(err, ShouldBeNil)
				So(ses, ShouldNotBeNil)

				_, err = rest.UpdateChannel(channel1, ses.ClientId)
				So(err, ShouldBeNil)
			})

			Convey("owner cant delete it", func() {
				channel1, err := rest.CreateChannelByGroupNameAndType(
					account.Id,
					groupName,
					models.Channel_TYPE_GROUP,
					ses.ClientId,
				)
				So(err, ShouldBeNil)
				So(channel1, ShouldNotBeNil)

				err = rest.DeleteChannel(account.Id, channel1.Id)
				So(err, ShouldNotBeNil)
			})

			Convey("normal user cant delete it", func() {
				channel1, err := rest.CreateChannelByGroupNameAndType(
					account.Id,
					groupName,
					models.Channel_TYPE_GROUP,
					ses.ClientId,
				)
				So(err, ShouldBeNil)
				So(channel1, ShouldNotBeNil)

				err = rest.DeleteChannel(rand.Int63(), channel1.Id)
				So(err, ShouldNotBeNil)
			})

			Convey("member can post status update", nil)

			Convey("non-member can not post status update", nil)
		})
	})
}
Ejemplo n.º 15
0
func TestCollaborationDriveService(t *testing.T) {
	r := runner.New("collaboration-drive-tests")
	err := r.Init()
	if err != nil {
		panic(err)
	}

	defer r.Close()

	appConfig := config.MustRead(r.Conf.Path)
	modelhelper.Initialize(appConfig.Mongo)
	defer modelhelper.Close()

	// init with defaults
	mongoCache := cache.NewMongoCacheWithTTL(modelhelper.Mongo.Session)
	defer mongoCache.StopGC()

	handler := New(r.Log, mongoCache, appConfig, r.Kite)

	SkipConvey("while pinging collaboration", t, func() {
		// owner
		owner := apimodels.NewAccount()
		owner.OldId = AccountOldId.Hex()
		owner, err := rest.CreateAccount(owner)
		So(err, ShouldBeNil)
		So(owner, ShouldNotBeNil)

		groupName := apimodels.RandomGroupName()

		ownerSession, err := modelhelper.FetchOrCreateSession(owner.Nick, groupName)
		So(err, ShouldBeNil)
		So(ownerSession, ShouldNotBeNil)

		rand.Seed(time.Now().UnixNano())

		req := &models.Ping{
			AccountId: 1,
			FileId:    fmt.Sprintf("%d", rand.Int63()),
		}

		Convey("while testing drive operations", func() {
			req := req
			req.CreatedAt = time.Now().UTC()
			Convey("should be able to create the file", func() {
				f, err := createTestFile(handler)
				if err != nil {
					t.Skip("Err happened, skipping: %s", err.Error())
				}

				req.FileId = f.Id
				Convey("should be able to get the created file", func() {
					f2, err := handler.getFile(f.Id)
					if err != nil {
						t.Skip("Err happened, skipping: %s", err.Error())
					}

					So(f2, ShouldNotBeNil)

					Convey("should be able to delete the created file", func() {
						err = handler.deleteFile(req.FileId)
						if err != nil {
							t.Skip("Err happened, skipping: %s", err.Error())
						}

						Convey("should not be able to get the deleted file", func() {
							deadLine := time.After(TestTimeout)
							tick := time.Tick(time.Millisecond * 100)
							for {
								select {
								case <-tick:
									f2, err := handler.getFile(f.Id)
									if err != nil {
										t.Skip("Err happened, skipping: %s", err.Error())
									}

									So(f2, ShouldBeNil)
								case <-deadLine:
									t.Skip("Could not get file after %s", TestTimeout)
								}
							}
						})
						Convey("deleting the deleted file should not give error", func() {
							err = handler.deleteFile(req.FileId)
							if err != nil {
								t.Skip("Err happened, skipping: %s", err.Error())
							}

							So(err, ShouldBeNil)
						})
					})
				})
			})
		})
	})
}
Ejemplo n.º 16
0
func TestAddRemoveChannelParticipant(t *testing.T) {
	tests.WithRunner(t, func(r *runner.Runner) {
		controller := &Controller{}
		Convey("While testing add/remove channel participants", t, func() {
			account := models.CreateAccountInBothDbsWithCheck()
			groupName := models.RandomGroupName()
			_ = models.CreateTypedGroupedChannelWithTest(
				account.Id,
				models.Channel_TYPE_GROUP,
				groupName,
			)

			// fetch admin's session
			ses, err := modelhelper.FetchOrCreateSession(account.Nick, groupName)
			So(err, ShouldBeNil)
			So(ses, ShouldNotBeNil)

			pe := &models.ParticipantEvent{}

			Convey("When user follows/unfollows a topic, they must be notified", func() {
				topicChannel, err := rest.CreateChannelByGroupNameAndType(
					account.Id,
					groupName,
					models.Channel_TYPE_TOPIC,
					ses.ClientId,
				)
				tests.ResultedWithNoErrorCheck(topicChannel, err)

				pe.Id = topicChannel.Id
				cp := &models.ChannelParticipant{}
				cp.AccountId = account.Id

				pe.Participants = []*models.ChannelParticipant{cp}

				participants, err := controller.fetchNotifiedParticipantIds(topicChannel, pe, AddedToChannelEventName)
				So(err, ShouldBeNil)
				So(len(participants), ShouldEqual, 1)
				So(participants[0], ShouldEqual, account.Id)

				participants, err = controller.fetchNotifiedParticipantIds(topicChannel, pe, RemovedFromChannelEventName)
				So(err, ShouldBeNil)
				So(len(participants), ShouldEqual, 1)
				So(participants[0], ShouldEqual, account.Id)
			})

			Convey("When user joins a topic, only participant user must be notified", func() {
				privateChannel, err := rest.CreateChannelByGroupNameAndType(
					account.Id,
					groupName,
					models.Channel_TYPE_PRIVATE_MESSAGE,
					ses.ClientId,
				)

				tests.ResultedWithNoErrorCheck(privateChannel, err)

				pe.Id = privateChannel.Id
				cp := &models.ChannelParticipant{}
				cp.AccountId = account.Id

				pe.Participants = []*models.ChannelParticipant{cp}

				participants, err := controller.fetchNotifiedParticipantIds(privateChannel, pe, AddedToChannelEventName)
				So(err, ShouldBeNil)
				So(len(participants), ShouldEqual, 1)
				So(participants[0], ShouldEqual, account.Id)
			})

			Convey("When user leaves a topic, all participants musts be notified", func() {
				privateChannel, err := rest.CreateChannelByGroupNameAndType(
					account.Id,
					groupName,
					models.Channel_TYPE_PRIVATE_MESSAGE,
					ses.ClientId,
				)
				tests.ResultedWithNoErrorCheck(privateChannel, err)

				pe.Id = privateChannel.Id
				cp := &models.ChannelParticipant{}
				cp.AccountId = account.Id

				pe.Participants = []*models.ChannelParticipant{cp}

				participants, err := controller.fetchNotifiedParticipantIds(privateChannel, pe, RemovedFromChannelEventName)
				tests.ResultedWithNoErrorCheck(participants, err)

				So(len(participants), ShouldEqual, 2)
				So(participants[0], ShouldEqual, account.Id)
			})
		})
	})

}
Ejemplo n.º 17
0
func TestChannelUpdatedCalculateUnreadItemCount(t *testing.T) {
	r := runner.New("test")
	if err := r.Init(); err != nil {
		t.Fatalf("couldnt start bongo %s", err.Error())
	}
	defer r.Close()

	config.MustRead(r.Conf.Path)

	groupName := models.RandomGroupName()

	Convey("while testing unread count", t, func() {
		Convey("channel should be set", func() {
			cue := &channelUpdatedEvent{}
			unreadCount, err := cue.calculateUnreadItemCount()
			So(err, ShouldNotBeNil)
			So(err, ShouldEqual, models.ErrChannelIsNotSet)
			So(unreadCount, ShouldEqual, 0)
		})

		Convey("unread count for group channel can not be calculated", func() {
			c := models.NewChannel()
			c.TypeConstant = models.Channel_TYPE_GROUP
			cue := &channelUpdatedEvent{
				Channel: c,
			}
			unreadCount, err := cue.calculateUnreadItemCount()
			So(err, ShouldNotBeNil)
			So(err.Error(), ShouldContainSubstring, "not supported channel type for unread count calculation")
			So(unreadCount, ShouldEqual, 0)
		})

		Convey("unread count for following feed channel can not be calculated", func() {
			c := models.NewChannel()
			c.TypeConstant = models.Channel_TYPE_FOLLOWINGFEED
			cue := &channelUpdatedEvent{
				Channel: c,
			}
			unreadCount, err := cue.calculateUnreadItemCount()
			So(err, ShouldNotBeNil)
			So(err.Error(), ShouldContainSubstring, "not supported channel type for unread count calculation")
			So(unreadCount, ShouldEqual, 0)
		})

		Convey("unread count for followers feed channel can not be calculated", func() {
			c := models.NewChannel()
			c.TypeConstant = models.Channel_TYPE_FOLLOWERS
			cue := &channelUpdatedEvent{
				Channel: c,
			}
			unreadCount, err := cue.calculateUnreadItemCount()
			So(err, ShouldNotBeNil)
			So(err.Error(), ShouldContainSubstring, "not supported channel type for unread count calculation")
			So(unreadCount, ShouldEqual, 0)
		})

		Convey("unread count for default channel can not be calculated", func() {
			c := models.NewChannel()
			c.TypeConstant = models.Channel_TYPE_DEFAULT
			cue := &channelUpdatedEvent{
				Channel: c,
			}
			unreadCount, err := cue.calculateUnreadItemCount()
			So(err, ShouldNotBeNil)
			So(err.Error(), ShouldContainSubstring, "not supported channel type for unread count calculation")
			So(unreadCount, ShouldEqual, 0)
		})

		Convey("channel participant should be set", func() {
			c := models.NewChannel()
			c.TypeConstant = models.Channel_TYPE_TOPIC
			cue := &channelUpdatedEvent{
				Channel: c,
			}
			unreadCount, err := cue.calculateUnreadItemCount()
			So(err, ShouldNotBeNil)
			So(err, ShouldEqual, models.ErrChannelParticipantIsNotSet)
			So(unreadCount, ShouldEqual, 0)
		})

		SkipConvey("pinned message's unread count could be calculated", func() {
			// create an account
			account, err := createAccount()
			So(err, ShouldBeNil)
			So(account, ShouldNotBeNil)

			// create their pinned activity channel
			c, err := models.EnsurePinnedActivityChannel(account.Id, groupName)
			So(err, ShouldBeNil)
			So(c, ShouldNotBeNil)

			// fetch participant
			cp, err := c.FetchParticipant(account.Id)
			So(err, ShouldBeNil)
			So(cp, ShouldNotBeNil)

			// create message
			cm := models.NewChannelMessage()
			cm.AccountId = account.Id
			// this cahnnel should be group channel
			cm.InitialChannelId = c.Id
			cm.Body = "hello all from test"
			So(cm.Create(), ShouldBeNil)

			// add message to the list
			cml, err := c.AddMessage(cm)
			So(err, ShouldBeNil)
			So(cml, ShouldNotBeNil)

			cue := &channelUpdatedEvent{
				Channel:              c,
				ChannelParticipant:   cp,
				ParentChannelMessage: cm,
			}

			unreadCount, err := cue.calculateUnreadItemCount()
			So(err, ShouldBeNil)
			So(unreadCount, ShouldEqual, 0)

			// add replies to the message
			addRepliesToMessage(c.Id, account.Id, cm.Id)
			addRepliesToMessage(c.Id, account.Id, cm.Id)

			cue = &channelUpdatedEvent{
				Channel:              c,
				ChannelParticipant:   cp,
				ParentChannelMessage: cm,
			}

			unreadCount, err = cue.calculateUnreadItemCount()
			So(err, ShouldBeNil)
			So(unreadCount, ShouldEqual, 2)

			// glance message
			cml.Glance()
			//after glancing the message, unread count should be zero

			cue = &channelUpdatedEvent{
				Channel:              c,
				ChannelParticipant:   cp,
				ParentChannelMessage: cm,
			}

			unreadCount, err = cue.calculateUnreadItemCount()
			So(err, ShouldBeNil)
			So(unreadCount, ShouldEqual, 0)
		})

		Convey("private message's unread count could be calculated", func() {
			// create an account
			account, err := createAccount()
			So(err, ShouldBeNil)
			So(account, ShouldNotBeNil)

			// create private message channel
			c := models.NewPrivateMessageChannel(account.Id, groupName)
			So(c.Create(), ShouldBeNil)

			// add participant into channel
			cp, err := c.AddParticipant(account.Id)
			So(err, ShouldBeNil)
			So(cp, ShouldNotBeNil)

			// create message
			cm := models.NewChannelMessage()
			cm.AccountId = account.Id
			cm.InitialChannelId = c.Id
			cm.Body = "hello all from test"
			So(cm.Create(), ShouldBeNil)

			// add message to the list
			// but message is already added into channel
			cml, err := c.EnsureMessage(cm, false)
			So(err, ShouldBeNil)
			So(cml, ShouldNotBeNil)

			cue := &channelUpdatedEvent{
				Channel:              c,
				ChannelParticipant:   cp,
				ParentChannelMessage: cm,
			}

			// calculate unread count
			unreadCount, err := cue.calculateUnreadItemCount()
			So(err, ShouldBeNil)
			So(unreadCount, ShouldEqual, 1)

			cp.LastSeenAt = time.Now().UTC()
			So(cp.Update(), ShouldBeNil)

			// calculate unread count
			unreadCount, err = cue.calculateUnreadItemCount()
			So(err, ShouldBeNil)
			So(unreadCount, ShouldEqual, 0)
		})

		Convey("collaboration channel's unread count could be calculated", func() {
			// create an account
			account, err := createAccount()
			So(err, ShouldBeNil)
			So(account, ShouldNotBeNil)

			// create private message channel
			c := models.NewCollaborationChannel(account.Id, groupName)
			So(c.Create(), ShouldBeNil)

			// add participant into channel
			cp, err := c.AddParticipant(account.Id)
			So(err, ShouldBeNil)
			So(cp, ShouldNotBeNil)

			// create message
			cm := models.NewChannelMessage()
			cm.AccountId = account.Id
			cm.InitialChannelId = c.Id
			cm.Body = "hello all from test"
			So(cm.Create(), ShouldBeNil)

			// add message to the list
			cml, err := c.EnsureMessage(cm, false)
			So(err, ShouldBeNil)
			So(cml, ShouldNotBeNil)

			cue := &channelUpdatedEvent{
				Channel:              c,
				ChannelParticipant:   cp,
				ParentChannelMessage: cm,
			}

			// calculate unread count
			unreadCount, err := cue.calculateUnreadItemCount()
			So(err, ShouldBeNil)
			So(unreadCount, ShouldEqual, 1)

			cp.LastSeenAt = time.Now().UTC()
			So(cp.Update(), ShouldBeNil)

			// calculate unread count
			unreadCount, err = cue.calculateUnreadItemCount()
			So(err, ShouldBeNil)
			So(unreadCount, ShouldEqual, 0)
		})

		Convey("topic channel's unread count could be calculated", func() {
			// create an account
			account, err := createAccount()
			So(err, ShouldBeNil)
			So(account, ShouldNotBeNil)

			// create private message channel
			c, err := createTypedChannel(account.Id, groupName, models.Channel_TYPE_TOPIC)
			So(err, ShouldBeNil)
			So(c.Create(), ShouldBeNil)

			// add participant into channel
			cp, err := c.AddParticipant(account.Id)
			So(err, ShouldBeNil)
			So(cp, ShouldNotBeNil)

			// create message
			cm := models.NewChannelMessage()
			cm.AccountId = account.Id
			cm.InitialChannelId = c.Id
			cm.Body = "hello all from test"
			So(cm.Create(), ShouldBeNil)

			// add message to the list
			cml, err := c.AddMessage(cm)
			So(err, ShouldBeNil)
			So(cml, ShouldNotBeNil)

			cue := &channelUpdatedEvent{
				Channel:              c,
				ChannelParticipant:   cp,
				ParentChannelMessage: cm,
			}

			// calculate unread count
			unreadCount, err := cue.calculateUnreadItemCount()
			So(err, ShouldBeNil)
			So(unreadCount, ShouldEqual, 1)

			cp.LastSeenAt = time.Now().UTC()
			So(cp.Update(), ShouldBeNil)

			// calculate unread count
			unreadCount, err = cue.calculateUnreadItemCount()
			So(err, ShouldBeNil)
			So(unreadCount, ShouldEqual, 0)
		})

		Convey("announcement channel's unread count could be calculated", func() {
			// create an account
			account, err := createAccount()
			So(err, ShouldBeNil)
			So(account, ShouldNotBeNil)

			// create private message channel
			c, err := createTypedChannel(account.Id, groupName, models.Channel_TYPE_ANNOUNCEMENT)
			So(err, ShouldBeNil)
			So(c.Create(), ShouldBeNil)

			// add participant into channel
			cp, err := c.AddParticipant(account.Id)
			So(err, ShouldBeNil)
			So(cp, ShouldNotBeNil)

			// create message
			cm := models.NewChannelMessage()
			cm.AccountId = account.Id
			cm.InitialChannelId = c.Id
			cm.Body = "hello all from test"
			So(cm.Create(), ShouldBeNil)

			// add message to the list
			cml, err := c.EnsureMessage(cm, false)
			So(err, ShouldBeNil)
			So(cml, ShouldNotBeNil)

			cue := &channelUpdatedEvent{
				Channel:              c,
				ChannelParticipant:   cp,
				ParentChannelMessage: cm,
			}

			// calculate unread count
			unreadCount, err := cue.calculateUnreadItemCount()
			So(err, ShouldBeNil)
			So(unreadCount, ShouldEqual, 1)

			cp.LastSeenAt = time.Now().UTC()
			So(cp.Update(), ShouldBeNil)

			// calculate unread count
			unreadCount, err = cue.calculateUnreadItemCount()
			So(err, ShouldBeNil)
			So(unreadCount, ShouldEqual, 0)
		})
	})
}
Ejemplo n.º 18
0
func TestPresenceDailyVerifyRecord(t *testing.T) {
	tests.WithRunner(t, func(r *runner.Runner) {
		groupName1 := models.RandomGroupName()
		Convey("With given presence data", t, func() {

			Convey("should work properly with non existant data", func() {
				today := time.Now().UTC()
				ping := &Ping{
					AccountID:     1, // non existing user
					GroupName:     groupName1,
					CreatedAt:     today,
					paymentStatus: string(mongomodels.SubStatusActive),
				}
				key := getKey(ping, today)
				_, err := pingCache.Get(key)
				So(err, ShouldEqual, cache.ErrNotFound)

				err = verifyRecord(ping, today)
				So(err, ShouldBeNil)

				// it should not be in cache
				_, err = pingCache.Get(key)
				So(err, ShouldEqual, cache.ErrNotFound)

				// we should be able to get it from db
				pd, err := getPresenceInfoFromDB(ping)
				So(err, ShouldBeNil)
				So(pd, ShouldNotBeNil)
			})

			Convey("should work properly with old existing data", func() {
				today := time.Now().UTC()
				prev := today.Add(-time.Minute)
				ping := &Ping{
					AccountID:     2, // non existing user
					GroupName:     groupName1,
					CreatedAt:     prev,
					paymentStatus: string(mongomodels.SubStatusActive),
				}
				So(insertPresenceInfoToDB(ping), ShouldBeNil)

				ping.CreatedAt = today
				err := verifyRecord(ping, today)
				So(err, ShouldBeNil)

				// we should be able to get it from db
				pd, err := getPresenceInfoFromDB(ping)
				So(err, ShouldBeNil)
				So(pd, ShouldNotBeNil)
			})

			Convey("should work properly with old deleted data", func() {
				today := time.Now().UTC()
				ping := &Ping{
					AccountID:     3, // non existing user
					GroupName:     groupName1,
					CreatedAt:     today,
					paymentStatus: string(mongomodels.SubStatusActive),
				}
				So(insertPresenceInfoToDB(ping), ShouldBeNil)

				err := (&models.PresenceDaily{}).ProcessByGroupName(groupName1)
				So(err, ShouldBeNil)

				// just to by pass the check in verify
				err = verifyRecord(ping, ping.CreatedAt.Add(-time.Second))
				So(err, ShouldBeNil)

				// we should be able to get it from db
				pd, err := getPresenceInfoFromDB(ping)
				So(err, ShouldBeNil)
				So(pd, ShouldNotBeNil)
			})
		})
	})
}
Ejemplo n.º 19
0
func TestAccountUpdated(t *testing.T) {
	runner, handler := getTestHandler()
	defer runner.Close()

	// init mongo connection
	appConfig := config.MustRead(runner.Conf.Path)
	modelhelper.Initialize(appConfig.Mongo)
	defer modelhelper.Close()

	Convey("given some fake account", t, func() {
		acc, err := models.CreateAccountInBothDbs()
		So(acc, ShouldNotBeNil)
		So(err, ShouldBeNil)

		Convey("it should save the document to algolia if not created before", func() {
			err := handler.AccountUpdated(acc)
			So(err, ShouldBeNil)

			Convey("it should have email in it", func() {
				// make sure account is there
				So(doBasicTestForAccount(handler, acc.OldId), ShouldBeNil)

				// update user's email
				selector := bson.M{"username": acc.Nick}
				newEmail := models.RandomGroupName() + "@bar.com"
				updateQuery := bson.M{"email": newEmail}
				err = modelhelper.UpdateUser(selector, updateQuery)
				So(err, ShouldBeNil)

				err = handler.AccountUpdated(acc)
				So(err, ShouldBeNil)

				err = makeSureWithSearch(
					handler,
					IndexAccounts,
					newEmail,
					map[string]interface{}{"restrictSearchableAttributes": "email"},
					func(record map[string]interface{}, err error) bool {
						if err != nil {
							return false
						}

						if record == nil {
							return false
						}

						hits, ok := record["nbHits"]
						if hits == nil || !ok {
							return false
						}

						if hits.(float64) <= 0 {
							return false
						}

						return true
					})
				So(err, ShouldBeNil)
			})
		})

		Convey("updating the account again should success", func() {
			err := handler.AccountCreated(acc)
			So(err, ShouldBeNil)
			So(doBasicTestForAccount(handler, acc.OldId), ShouldBeNil)
		})

		Convey("it should delete the document when user account is deleted", func() {
			// first ensure account object is created
			err = handler.AccountCreated(acc)
			So(err, ShouldBeNil)
			So(doBasicTestForAccount(handler, acc.OldId), ShouldBeNil)

			newNick := "guest-" + models.RandomName() + "-rm"
			err = models.UpdateUsernameInBothDbs(acc.Nick, newNick)
			So(err, ShouldBeNil)

			acc.Nick = newNick

			err = handler.AccountUpdated(acc)
			So(err, ShouldBeNil)

			So(doBasicTestForAccountDeletion(handler, acc.OldId), ShouldBeNil)

			Convey("deleting the account again should success", func() {
				err = handler.AccountUpdated(acc)
				So(err, ShouldBeNil)
				So(doBasicTestForAccountDeletion(handler, acc.OldId), ShouldBeNil)
			})
		})

		Convey("it should not return any error when deleted user does not exist on Algolia", func() {
			newNick := "guest-" + models.RandomName() + "-rm"
			err = models.UpdateUsernameInBothDbs(acc.Nick, newNick)
			So(err, ShouldBeNil)

			acc.Nick = newNick

			err = handler.AccountUpdated(acc)
			So(err, ShouldBeNil)

			So(doBasicTestForAccountDeletion(handler, acc.OldId), ShouldBeNil)
		})

	})
}
Ejemplo n.º 20
0
func TestChannelHistory(t *testing.T) {
	tests.WithRunner(t, func(r *runner.Runner) {
		Convey("While testing history of a channel", t, func() {
			Convey("We should be able to create it(channel) first", func() {
				groupName := models.RandomGroupName()

				account, err := models.CreateAccountInBothDbsWithNick("sinan")
				So(err, ShouldBeNil)
				So(account, ShouldNotBeNil)

				ses, err := modelhelper.FetchOrCreateSession(account.Nick, groupName)
				So(err, ShouldBeNil)
				So(ses, ShouldNotBeNil)

				channel := models.CreateTypedGroupedChannelWithTest(
					account.Id,
					models.Channel_TYPE_GROUP,
					groupName,
				)
				_, err = channel.AddParticipant(account.Id)
				So(err, ShouldBeNil)

				Convey("While posting a new message to it", func() {
					var channelParticipant *models.ChannelParticipant
					var err error
					Convey("We should be able to create a participant first", func() {
						channelParticipant, err = rest.CreateChannelParticipant(channel.Id, ses.ClientId)
						So(err, ShouldBeNil)
						So(channelParticipant, ShouldNotBeNil)

						Convey("Create posts with created participant", func() {
							channel := channel
							for i := 0; i < 10; i++ {
								post, err := rest.CreatePost(channel.Id, ses.ClientId)
								So(err, ShouldBeNil)
								So(post, ShouldNotBeNil)
								So(post.Id, ShouldNotEqual, 0)
								So(post.Body, ShouldNotEqual, "")

							}
							Convey("We should be able to fetch the history", func() {
								history, err := rest.GetHistory(
									channel.Id,
									&request.Query{
										AccountId: account.Id,
									},
									ses.ClientId,
								)
								So(err, ShouldBeNil)
								So(history, ShouldNotBeNil)
								So(len(history.MessageList), ShouldEqual, 10)
							})

							Convey("We should be not able to fetch the history if the clientId is not set", func() {
								history, err := rest.GetHistory(
									channel.Id,
									&request.Query{
										AccountId: account.Id,
									},
									"",
								)
								So(err, ShouldNotBeNil)
								So(history, ShouldBeNil)
							})

							Convey("We should be not able to fetch the history if the clientId doesnt exist", func() {

								history, err := rest.GetHistory(
									channel.Id,
									&request.Query{
										AccountId: account.Id,
									},
									"foobarzaa",
								)

								So(err, ShouldNotBeNil)
								So(history, ShouldBeNil)
							})

							Convey("We should be able to get channel message count", func() {
								count, err := rest.CountHistory(channel.Id)
								So(err, ShouldBeNil)
								So(count, ShouldNotBeNil)
								So(count.TotalCount, ShouldEqual, 10)
							})
						})
						Convey("We should be able to check history according to request", func() {
							channel := channel
							for i := 0; i < 5; i++ {
								body := fmt.Sprintf("body%d", i)
								post, err := rest.CreatePostWithBodyAndAuth(channel.Id, body, ses.ClientId)
								// we need to wait while posting messages
								// if we dont use time sleep, Added_at field of the messages is
								// gonna be equal and this behavior is not expected situation
								// Then, tests will not be worked correctly
								time.Sleep(1000 * time.Millisecond)
								So(err, ShouldBeNil)
								So(post, ShouldNotBeNil)
								So(post.Id, ShouldNotEqual, 0)
								So(post.Body, ShouldNotEqual, "")
							}
							bodyMes := "postMid message"
							postMid, err := rest.CreatePostWithBodyAndAuth(channel.Id, bodyMes, ses.ClientId)
							So(postMid, ShouldNotBeNil)
							So(err, ShouldBeNil)
							for i := 5; i < 10; i++ {
								time.Sleep(1000 * time.Millisecond)
								body := fmt.Sprintf("body%d", i)
								post, err := rest.CreatePostWithBodyAndAuth(channel.Id, body, ses.ClientId)
								So(err, ShouldBeNil)
								So(post, ShouldNotBeNil)
								So(post.Id, ShouldNotEqual, 0)
								So(post.Body, ShouldNotEqual, "")
							}
							Convey("We should able to fetch the history with query request ", func() {
								history, err := rest.GetHistory(
									channel.Id,
									&request.Query{
										AccountId: account.Id,
									},
									ses.ClientId,
								)

								So(err, ShouldBeNil)
								So(history, ShouldNotBeNil)
								So(len(history.MessageList), ShouldEqual, 11)
							})

							Convey("We should able to fetch the history with query ADDED AT & ASC ", func() {
								history, err := rest.GetHistory(
									channel.Id,
									&request.Query{
										From:      postMid.CreatedAt,
										SortOrder: "ASC",
									},
									ses.ClientId,
								)

								var historyArr []string
								arr := []string{"postMid message", "body5", "body6", "body7", "body8", "body9"}
								for _, x := range history.MessageList {
									historyArr = append(historyArr, x.Message.Body)
								}
								So(err, ShouldBeNil)
								So(history, ShouldNotBeNil)
								So(len(history.MessageList), ShouldEqual, 6)
								So(arr, ShouldResemble, historyArr)
							})

							Convey("We should able to fetch the history with query ADDED AT & DESC ", func() {
								history, err := rest.GetHistory(
									channel.Id,
									&request.Query{
										From:      postMid.CreatedAt,
										SortOrder: "DESC",
									},
									ses.ClientId,
								)

								var historyArr []string
								arr := []string{"body4", "body3", "body2", "body1", "body0"}
								for _, x := range history.MessageList {
									historyArr = append(historyArr, x.Message.Body)
								}
								So(err, ShouldBeNil)
								So(history, ShouldNotBeNil)
								So(len(history.MessageList), ShouldEqual, 5)
								So(arr, ShouldResemble, historyArr)
							})
							Convey("We should able to fetch the with query ADDED AT & DESC ORDER& LIMIT ", func() {
								history, err := rest.GetHistory(
									channel.Id,
									&request.Query{
										From:      postMid.CreatedAt,
										SortOrder: "DESC",
										Limit:     3,
									},
									ses.ClientId,
								)

								var historyArr []string
								arr := []string{"body4", "body3", "body2"}
								for _, x := range history.MessageList {
									historyArr = append(historyArr, x.Message.Body)
								}
								So(err, ShouldBeNil)
								So(history, ShouldNotBeNil)
								So(len(history.MessageList), ShouldEqual, 3)
								So(arr, ShouldResemble, historyArr)
							})
							Convey("We should able to fetch the with query ADDED AT & ASC ORDER& LIMIT ", func() {
								history, err := rest.GetHistory(
									channel.Id,
									&request.Query{
										From:      postMid.CreatedAt,
										SortOrder: "ASC",
										Limit:     3,
									},
									ses.ClientId,
								)

								var historyArr []string
								arr := []string{"postMid message", "body5", "body6"}
								for _, x := range history.MessageList {
									historyArr = append(historyArr, x.Message.Body)
								}
								So(err, ShouldBeNil)
								So(history, ShouldNotBeNil)
								So(len(history.MessageList), ShouldEqual, 3)
								So(arr, ShouldResemble, historyArr)
							})
						})
					})
				})
			})
		})
	})
}
Ejemplo n.º 21
0
func TestCollaborationChannels(t *testing.T) {
	tests.WithRunner(t, func(r *runner.Runner) {
		Convey("while testing collaboration channel", t, func() {
			devrim, err := models.CreateAccountInBothDbsWithNick("devrim")
			So(err, ShouldBeNil)
			So(devrim, ShouldNotBeNil)
			sinan, err := models.CreateAccountInBothDbsWithNick("sinan")
			So(err, ShouldBeNil)
			So(sinan, ShouldNotBeNil)

			groupName := models.RandomGroupName()

			// cretae admin user
			account, err := models.CreateAccountInBothDbs()
			tests.ResultedWithNoErrorCheck(account, err)
			// fetch admin's session
			ses, err := modelhelper.FetchOrCreateSession(account.Nick, groupName)
			So(err, ShouldBeNil)
			So(ses, ShouldNotBeNil)

			groupChannel := models.CreateTypedGroupedChannelWithTest(
				account.Id,
				models.Channel_TYPE_GROUP,
				groupName,
			)

			groupChannel.AddParticipant(account.Id)

			_, err = groupChannel.AddParticipant(devrim.Id)
			So(err, ShouldBeNil)
			_, err = groupChannel.AddParticipant(sinan.Id)
			So(err, ShouldBeNil)

			recipient, err := models.CreateAccountInBothDbs()
			tests.ResultedWithNoErrorCheck(recipient, err)

			recipient2, err := models.CreateAccountInBothDbs()
			tests.ResultedWithNoErrorCheck(recipient2, err)

			Convey("one can send initiate the collaboration channel with only him", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body for private message"
				pmr.GroupName = groupName
				pmr.Recipients = []string{}
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)

			})

			Convey("one can send initiate the collaboration channel with 2 participants", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body message for private message @devrim @sinan"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"devrim", "sinan"}
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)

			})

			Convey("if group name is nil, should not fail to create collaboration channel", func() {
				ses, err := modelhelper.FetchOrCreateSession(sinan.Nick, "koding")
				So(err, ShouldBeNil)
				So(ses, ShouldNotBeNil)

				groupChannel, err := rest.CreateChannelByGroupNameAndType(
					sinan.Id,
					"koding",
					models.Channel_TYPE_GROUP,
					ses.ClientId,
				)
				tests.ResultedWithNoErrorCheck(groupChannel, err)
				groupChannel.AddParticipant(devrim.Id)  // ignore error
				groupChannel.AddParticipant(account.Id) // ignore error
				groupChannel.AddParticipant(sinan.Id)   // ignore error

				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body for private message @devrim @sinan"
				pmr.GroupName = ""
				pmr.Recipients = []string{"devrim", "sinan"}
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)
			})

			// we give token as parameter to SendPrivateChannelRequest
			// handler sets the accountId and groupname if not defined in handler's function
			// So it should not return any error unless account is defined
			Convey("if sender is not defined should not fail to create collaboration channel", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = 0
				pmr.Body = "this is a body for private message"
				pmr.GroupName = ""
				pmr.Recipients = []string{}
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)
			})

			Convey("one can send private message to multiple person", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body for private message @sinan"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"sinan"}
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)

			})

			Convey("response should have created channel", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body for private message @devrim @sinan"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"devrim", "sinan"}
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)
				So(cmc.Channel.TypeConstant, ShouldEqual, models.Channel_TYPE_COLLABORATION)
				So(cmc.Channel.Id, ShouldBeGreaterThan, 0)
				So(cmc.Channel.GroupName, ShouldEqual, groupName)
				So(cmc.Channel.PrivacyConstant, ShouldEqual, models.Channel_PRIVACY_PRIVATE)

			})

			Convey("send response should have participant status data", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body for private message @devrim @sinan"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"devrim", "sinan"}
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)
				So(cmc.IsParticipant, ShouldBeTrue)
			})

			Convey("send response should have participant count", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is a body for @sinan private message @devrim"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"devrim", "sinan"}
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)
				So(cmc.ParticipantCount, ShouldEqual, 3)
			})

			Convey("send response should have participant preview", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "this is @sinan a body for @devrim private message"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"sinan", "devrim"}
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)
				So(len(cmc.ParticipantsPreview), ShouldEqual, 3)
			})

			Convey("send response should have last Message", func() {
				body := "hi @devrim this is a body for private message also for @sinan"
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = body
				pmr.GroupName = groupName
				pmr.Recipients = []string{"sinan", "devrim"}
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)
				So(cmc.LastMessage.Message.Body, ShouldEqual, body)
			})

			Convey("channel messages should be listed by all recipients", func() {
				// // use a different group name
				// // in order not to interfere with another request
				// groupName := "testgroup" + strconv.FormatInt(rand.Int63(), 10)

				body := "hi @devrim this is a body for private message also for @sinan"
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = body
				pmr.GroupName = groupName
				pmr.Recipients = []string{"sinan", "devrim"}
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cmc, ShouldNotBeNil)

				query := &request.Query{
					AccountId: account.Id,
					GroupName: groupName,
					Type:      models.Channel_TYPE_COLLABORATION,
				}

				pm, err := rest.GetPrivateChannels(query, ses.ClientId)
				So(err, ShouldBeNil)
				So(pm, ShouldNotBeNil)
				So(len(pm), ShouldNotEqual, 0)
				So(pm[0], ShouldNotBeNil)
				So(pm[0].Channel.TypeConstant, ShouldEqual, models.Channel_TYPE_COLLABORATION)
				So(pm[0].Channel.Id, ShouldEqual, cmc.Channel.Id)
				So(pm[0].Channel.GroupName, ShouldEqual, cmc.Channel.GroupName)
				So(pm[0].LastMessage.Message.Body, ShouldEqual, cmc.LastMessage.Message.Body)
				So(pm[0].Channel.PrivacyConstant, ShouldEqual, models.Channel_PRIVACY_PRIVATE)
				So(len(pm[0].ParticipantsPreview), ShouldEqual, 3)
				So(pm[0].IsParticipant, ShouldBeTrue)

			})

			Convey("user should be able to search collaboration channels via purpose field", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "search collaboration channel"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"sinan", "devrim"}
				pmr.Purpose = "test me up"
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cmc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)

				query := request.Query{
					AccountId: account.Id,
					GroupName: groupName,
					Type:      models.Channel_TYPE_COLLABORATION,
				}

				_, err = rest.SearchPrivateChannels(&query, ses.ClientId)
				So(err, ShouldNotBeNil)

				query.Name = "test"
				pm, err := rest.SearchPrivateChannels(&query, ses.ClientId)
				So(err, ShouldBeNil)
				So(pm, ShouldNotBeNil)
				So(len(pm), ShouldNotEqual, 0)
				So(pm[0], ShouldNotBeNil)
				So(pm[0].Channel.TypeConstant, ShouldEqual, models.Channel_TYPE_COLLABORATION)
				So(pm[0].Channel.Id, ShouldEqual, cmc.Channel.Id)
				So(pm[0].Channel.GroupName, ShouldEqual, cmc.Channel.GroupName)
				So(pm[0].LastMessage.Message.Body, ShouldEqual, cmc.LastMessage.Message.Body)
				So(pm[0].Channel.PrivacyConstant, ShouldEqual, models.Channel_PRIVACY_PRIVATE)
				So(pm[0].IsParticipant, ShouldBeTrue)

			})

			Convey("user join activity should be listed by recipients", func() {
				groupName := models.RandomGroupName()

				// cretae admin user
				account, err := models.CreateAccountInBothDbs()
				tests.ResultedWithNoErrorCheck(account, err)
				// fetch admin's session
				ses, err := modelhelper.FetchOrCreateSession(account.Nick, groupName)
				So(err, ShouldBeNil)
				So(ses, ShouldNotBeNil)

				groupChannel := models.CreateTypedGroupedChannelWithTest(
					account.Id,
					models.Channel_TYPE_GROUP,
					groupName,
				)
				So(groupChannel, ShouldNotBeNil)

				_, err = groupChannel.AddParticipant(account.Id)
				So(err, ShouldBeNil)
				_, err = groupChannel.AddParticipant(devrim.Id)
				So(err, ShouldBeNil)
				_, err = groupChannel.AddParticipant(sinan.Id)
				So(err, ShouldBeNil)
				_, err = groupChannel.AddParticipant(recipient.Id)
				So(err, ShouldBeNil)

				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "test collaboration channel participants"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"sinan", "devrim"}
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)

				So(err, ShouldBeNil)
				So(cc, ShouldNotBeNil)

				history, err := rest.GetHistory(
					cc.Channel.Id,
					&request.Query{
						AccountId: account.Id,
					},
					ses.ClientId,
				)

				So(err, ShouldBeNil)
				So(history, ShouldNotBeNil)
				So(len(history.MessageList), ShouldEqual, 2)

				// add participant
				_, err = rest.AddChannelParticipant(cc.Channel.Id, ses.ClientId, recipient.Id)
				So(err, ShouldBeNil)

				history, err = rest.GetHistory(
					cc.Channel.Id,
					&request.Query{
						AccountId: account.Id,
					},
					ses.ClientId,
				)

				So(err, ShouldBeNil)
				So(history, ShouldNotBeNil)
				So(len(history.MessageList), ShouldEqual, 3)

				So(history.MessageList[0].Message, ShouldNotBeNil)
				So(history.MessageList[0].Message.TypeConstant, ShouldEqual, models.ChannelMessage_TYPE_SYSTEM)
				So(history.MessageList[0].Message.Payload, ShouldNotBeNil)
				addedBy, ok := history.MessageList[0].Message.Payload["addedBy"]
				So(ok, ShouldBeTrue)
				So(*addedBy, ShouldEqual, account.Nick)

				systemType, ok := history.MessageList[0].Message.Payload["systemType"]
				So(ok, ShouldBeTrue)
				So(*systemType, ShouldEqual, models.ChannelRequestMessage_TYPE_JOIN)

				// try to add same participant
				_, err = rest.AddChannelParticipant(cc.Channel.Id, ses.ClientId, recipient.Id)
				So(err, ShouldBeNil)

				history, err = rest.GetHistory(
					cc.Channel.Id,
					&request.Query{
						AccountId: account.Id,
					},
					ses.ClientId,
				)

				So(err, ShouldBeNil)
				So(history, ShouldNotBeNil)
				So(len(history.MessageList), ShouldEqual, 3)

			})

			Convey("user should not be able to edit join messages", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "test collaboration channel participants again"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"devrim"}
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cc, ShouldNotBeNil)

				_, err = rest.AddChannelParticipant(cc.Channel.Id, ses.ClientId, recipient.Id)
				So(err, ShouldBeNil)

				ses, err := modelhelper.FetchOrCreateSession(account.Nick, groupName)
				So(err, ShouldBeNil)
				So(ses, ShouldNotBeNil)

				history, err := rest.GetHistory(
					cc.Channel.Id,
					&request.Query{
						AccountId: account.Id,
					},
					ses.ClientId,
				)

				So(err, ShouldBeNil)
				So(history, ShouldNotBeNil)
				So(len(history.MessageList), ShouldEqual, 3)

				joinMessage := history.MessageList[0].Message
				So(joinMessage, ShouldNotBeNil)

				_, err = rest.UpdatePost(joinMessage, ses.ClientId)
				So(err, ShouldNotBeNil)
			})

			Convey("first chat message should include initial participants", func() {
				pmr := models.ChannelRequest{}
				pmr.AccountId = account.Id
				pmr.Body = "test initial participation message"
				pmr.GroupName = groupName
				pmr.Recipients = []string{"sinan", "devrim"}
				pmr.TypeConstant = models.Channel_TYPE_COLLABORATION

				cc, err := rest.SendPrivateChannelRequest(pmr, ses.ClientId)
				So(err, ShouldBeNil)
				So(cc, ShouldNotBeNil)

				ses, err := modelhelper.FetchOrCreateSession(account.Nick, groupName)
				So(err, ShouldBeNil)
				So(ses, ShouldNotBeNil)

				history, err := rest.GetHistory(
					cc.Channel.Id,
					&request.Query{
						AccountId: account.Id,
					},
					ses.ClientId,
				)

				So(err, ShouldBeNil)
				So(history, ShouldNotBeNil)
				So(len(history.MessageList), ShouldEqual, 2)

				joinMessage := history.MessageList[1].Message
				So(joinMessage.TypeConstant, ShouldEqual, models.ChannelMessage_TYPE_SYSTEM)
				So(joinMessage.Payload, ShouldNotBeNil)
				initialParticipants, ok := joinMessage.Payload["initialParticipants"]
				So(ok, ShouldBeTrue)

				systemType, ok := history.MessageList[1].Message.Payload["systemType"]
				So(ok, ShouldBeTrue)
				So(*systemType, ShouldEqual, models.ChannelRequestMessage_TYPE_INIT)

				participants := make([]string, 0)
				err = json.Unmarshal([]byte(*initialParticipants), &participants)
				So(err, ShouldBeNil)
				So(len(participants), ShouldEqual, 2)
				So(participants, ShouldContain, "devrim")
				// So(*addedBy, ShouldEqual, account.OldId)

			})
		})
	})
}