private async Task <bool> RepoShipNeedsWebhookHelpHelper(bool hasHook, bool isAdmin)
        {
            using (var context = new ShipHubContext()) {
                var userAccount = TestUtil.MakeTestUser(context);
                var orgAccount  = new AccountTableType()
                {
                    Id    = 4001,
                    Login = "******",
                    Type  = "org",
                };
                var repo = new RepositoryTableType()
                {
                    Id        = 5001,
                    AccountId = 4001,
                    Name      = "unicorns",
                    FullName  = "pureimaginary/unicorns",
                    Private   = true,
                    HasIssues = true,
                };

                await context.BulkUpdateAccounts(DateTimeOffset.UtcNow, new[] { orgAccount });

                var user = context.Users.Single(x => x.Id == userAccount.Id);
                await context.SaveChangesAsync();

                await context.BulkUpdateRepositories(DateTimeOffset.UtcNow, new[] { repo });

                await context.SetUserOrganizations(user.Id, new[] { orgAccount.Id });

                await context.SetAccountLinkedRepositories(
                    userAccount.Id,
                    new[] { (repo.Id, isAdmin) });
        private static async Task <Environment> MakeEnvironment(ShipHubContext context)
        {
            var env = new Environment()
            {
                user1 = TestUtil.MakeTestUser(context, 3001, "alok"),
                user2 = TestUtil.MakeTestUser(context, 3002, "aroon"),
                org   = TestUtil.MakeTestOrg(context, 6001, "pureimaginary")
            };
            await context.SetUserOrganizations(env.user1.Id, new[] { env.org.Id });

            await context.SaveChangesAsync();

            return(env);
        }
        public async Task OrgHookWithOldErrorIsRetried()
        {
            using (var context = new ShipHubContext()) {
                var user = TestUtil.MakeTestUser(context);
                var org  = TestUtil.MakeTestOrg(context);
                var hook = context.Hooks.Add(new Hook()
                {
                    Id             = 1001,
                    Events         = "event1,event2",
                    GitHubId       = null, // Empty GitHub Id
                    OrganizationId = org.Id,
                    Secret         = Guid.NewGuid(),
                    LastError      = DateTimeOffset.UtcNow.Subtract(OrganizationActor.HookErrorDelay),
                });
                await context.SaveChangesAsync();

                await context.SetUserOrganizations(user.Id, new[] { org.Id });

                var mock = new Mock <IGitHubActor>();

                mock
                .Setup(x => x.OrganizationWebhooks(org.Login, null, It.IsAny <RequestPriority>()))
                .ReturnsAsync(new GitHubResponse <IEnumerable <Webhook> >(null)
                {
                    Result = new List <Webhook>()
                    {
                    },
                    Status = HttpStatusCode.OK,
                });
                mock
                .Setup(x => x.AddOrganizationWebhook(org.Login, It.IsAny <Webhook>(), It.IsAny <RequestPriority>()))
                .ReturnsAsync(new GitHubResponse <Webhook>(null)
                {
                    Result = new Webhook()
                    {
                        Id = 9999,
                    },
                    Status = HttpStatusCode.OK,
                });

                var orgActor = CreateOrgActor(org.Id, org.Login);
                var changes  = await orgActor.AddOrUpdateOrganizationWebhooks(context, mock.Object);

                await context.Entry(hook).ReloadAsync();

                Assert.AreEqual(9999, hook.GitHubId);
                Assert.IsNull(hook.LastError);
                Assert.IsTrue(changes.Organizations?.First() == org.Id, "New hook should send notifications.");
            }
        }
        public async Task WillAddHookWhenNoneExistsForOrg()
        {
            using (var context = new ShipHubContext()) {
                var user = TestUtil.MakeTestUser(context);
                var org  = TestUtil.MakeTestOrg(context);
                await context.SaveChangesAsync();

                await context.SetUserOrganizations(user.Id, new[] { org.Id });

                var orgLogItem           = context.SyncLogs.Single(x => x.OwnerType == "org" && x.OwnerId == org.Id && x.ItemType == "account" && x.ItemId == org.Id);
                var orgLogItemRowVersion = orgLogItem.RowVersion;

                var mock = new Mock <IGitHubActor>();

                mock
                .Setup(x => x.OrganizationWebhooks(org.Login, null, It.IsAny <RequestPriority>()))
                .ReturnsAsync(new GitHubResponse <IEnumerable <Webhook> >(null)
                {
                    Result = new List <Webhook>(),
                    Status = HttpStatusCode.OK,
                });

                Webhook installWebhook = null;

                mock
                .Setup(x => x.AddOrganizationWebhook(org.Login, It.IsAny <Webhook>(), It.IsAny <RequestPriority>()))
                .ReturnsAsync(new GitHubResponse <Webhook>(null)
                {
                    Result = new Webhook()
                    {
                        Id = 9999,
                    },
                    Status = HttpStatusCode.OK,
                })
                .Callback((string login, Webhook webhook, RequestPriority priority) => {
                    installWebhook = webhook;
                });

                var orgActor = CreateOrgActor(org.Id, org.Login);
                var changes  = await orgActor.AddOrUpdateOrganizationWebhooks(context, mock.Object);

                var hook = context.Hooks.Single(x => x.OrganizationId == org.Id);

                Assert.AreEqual(OrganizationActor.RequiredEvents, new HashSet <string>(hook.Events.Split(',')));
                Assert.AreEqual(org.Id, hook.OrganizationId);
                Assert.AreEqual(9999, hook.GitHubId);
                Assert.Null(hook.RepositoryId);
                Assert.Null(hook.LastSeen);
                Assert.NotNull(hook.Secret);

                Assert.AreEqual("web", installWebhook.Name);
                Assert.AreEqual(true, installWebhook.Active);
                Assert.AreEqual(OrganizationActor.RequiredEvents, new HashSet <string>(installWebhook.Events));
                Assert.AreEqual("json", installWebhook.Config.ContentType);
                Assert.AreEqual(false, installWebhook.Config.InsecureSsl);
                Assert.AreEqual(hook.Secret.ToString(), installWebhook.Config.Secret);

                orgLogItem = context.SyncLogs.Single(x => x.OwnerType == "org" && x.OwnerId == org.Id && x.ItemType == "account" && x.ItemId == org.Id);
                Assert.Greater(orgLogItem.RowVersion, orgLogItemRowVersion,
                               "row version should get bumped so the org gets synced");
                Assert.AreEqual(new long[] { org.Id }, changes.Organizations.ToArray());
            }
        }