Exemplo n.º 1
0
        private async Task <ActivityDTO> EnsureSolutionAuthenticated(ActivityDTO solution)
        {
            var crateStorage = Crate.FromDto(solution.CrateStorage);
            var stAuthCrate  = crateStorage.CratesOfType <StandardAuthenticationCM>().FirstOrDefault();
            var defaultDocuSignAuthTokenExists = (stAuthCrate == null);

            if (!defaultDocuSignAuthTokenExists)
            {
                var creds = GetDocuSignCredentials();
                creds.Terminal = new TerminalSummaryDTO
                {
                    Name    = solution.ActivityTemplate.TerminalName,
                    Version = solution.ActivityTemplate.TerminalVersion
                };

                var token = await HttpPostAsync <CredentialsDTO, JObject>(
                    _baseUrl + "authentication/token", creds
                    );

                Assert.AreNotEqual(
                    token["error"].ToString(),
                    "Unable to authenticate in DocuSign service, invalid login name or password.", "DocuSign auth error. Perhaps max number of tokens is exceeded."
                    );

                Assert.AreEqual(
                    false,
                    string.IsNullOrEmpty(token["authTokenId"].Value <string>()),
                    "AuthTokenId is missing in API response."
                    );

                var tokenGuid = Guid.Parse(token["authTokenId"].Value <string>());

                var applyToken = new AuthenticationTokenGrantDTO()
                {
                    ActivityId  = solution.Id,
                    AuthTokenId = tokenGuid,
                    IsMain      = true
                };

                await HttpPostAsync <AuthenticationTokenGrantDTO[], string>(
                    _baseUrl + "ManageAuthToken/apply",
                    new AuthenticationTokenGrantDTO[]
                {
                    applyToken
                }
                    );

                solution = await HttpPostAsync <ActivityDTO, ActivityDTO>(
                    _baseUrl + "activities/configure?id=" + solution.Id,
                    solution
                    );
            }

            return(solution);
        }
        private async Task ApplyAuthTokenToSolution(ActivityDTO solution, AuthorizationTokenDO salesforceAuthToken)
        {
            var applyToken = new AuthenticationTokenGrantDTO()
            {
                ActivityId  = solution.Id,
                AuthTokenId = salesforceAuthToken.Id,
                IsMain      = true
            };

            await HttpPostAsync <AuthenticationTokenGrantDTO[], string>(GetHubApiBaseUrl() + "authentication/tokens/grant", new[] { applyToken });
        }
Exemplo n.º 3
0
        public async Task ApplyNewToken(Guid activityId, Guid authTokenId)
        {
            var applyToken = new AuthenticationTokenGrantDTO()
            {
                ActivityId  = activityId,
                AuthTokenId = authTokenId,
                IsMain      = false
            };

            var token = new[] { applyToken };

            var url = $"{GetHubUrlWithApiVersion()}/authentication/tokens/grant";
            var uri = new Uri(url);
            await _restfulServiceClient.PostAsync(uri, token, null, await GetHMACHeader(uri, token));
        }
        private async Task AddAndAuthorizeMonitorGmailInboxActivity(AuthorizationTokenDO token, PlanDTO testPlan)
        {
            var gmailMonitorActivity = await _googleActivityConfigurator.CreateMonitorGmailInbox(testPlan, 1);

            gmailMonitorActivity.CrateStorage = new CrateStorageDTO();
            var tokenDTO = AutoMapper.Mapper.Map <AuthorizationTokenDTO>(token);

            var applyToken = new AuthenticationTokenGrantDTO()
            {
                ActivityId  = gmailMonitorActivity.Id,
                AuthTokenId = Guid.Parse(tokenDTO.Id),
                IsMain      = false
            };

            await HttpPostAsync <AuthenticationTokenGrantDTO[], string>(GetHubApiBaseUrl() + "authentication/tokens/grant", new[] { applyToken });

            gmailMonitorActivity = await _googleActivityConfigurator.SaveActivity(gmailMonitorActivity);

            gmailMonitorActivity = await _googleActivityConfigurator.ConfigureActivity(gmailMonitorActivity);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Authenticate to DocuSign and accociate generated token with activity
        /// </summary>
        /// <param name="activityId"></param>
        /// <param name="credentials"></param>
        /// <param name="terminalId"></param>
        /// <returns></returns>
        public async Task <Guid> AuthenticateDocuSignAndAssociateTokenWithAction(Guid activityId, CredentialsDTO credentials, TerminalSummaryDTO terminalDTO)
        {
            //
            // Authenticate with DocuSign Credentials
            //
            var authTokenDTO = await GenerateAuthToken(credentials.Username, credentials.Password, terminalDTO);

            var tokenGuid = Guid.Parse(authTokenDTO.Token);

            //
            // Asociate token with action
            //
            var applyToken = new AuthenticationTokenGrantDTO()
            {
                ActivityId  = activityId,
                AuthTokenId = tokenGuid,
                IsMain      = true
            };
            await _baseHubITest.HttpPostAsync <AuthenticationTokenGrantDTO[], string>(_baseHubITest.GetHubApiBaseUrl() + "authentication/tokens/grant", new[] { applyToken });

            return(tokenGuid);
        }
Exemplo n.º 6
0
        public async Task <ActivityDTO> AddAndConfigure_QueryDocuSign(PlanDTO plan, int ordering, int version = 1)
        {
            var queryDocuSignActivity = FixtureData.Query_DocuSign_v1_InitialConfiguration();
            var activityTemplates     = await _baseHubITest.HttpGetAsync <ActivityTemplateCategoryDTO[]>(_baseHubITest.GetHubApiBaseUrl() + "/activity_templates");

            var apmActivityTemplate = activityTemplates
                                      .SelectMany(a => a.Activities)
                                      .Select(x => new ActivityTemplateSummaryDTO
            {
                Name            = x.Name,
                Version         = x.Version,
                TerminalName    = x.Terminal.Name,
                TerminalVersion = x.Terminal.Version
            })
                                      .FirstOrDefault(a => a.Name == "Query_DocuSign" && a.Version == version.ToString());

            if (apmActivityTemplate == null)
            {
                throw new Exception("Unable to find template for Query_DocuSign v1");
            }

            queryDocuSignActivity.ActivityTemplate = apmActivityTemplate;

            //connect current activity with a plan
            var subPlan = plan.SubPlans.FirstOrDefault();

            queryDocuSignActivity.ParentPlanNodeId = subPlan.SubPlanId;
            queryDocuSignActivity.RootPlanNodeId   = plan.Id;
            queryDocuSignActivity.Ordering         = ordering;

            //call initial configuration to server
            queryDocuSignActivity = await _baseHubITest.HttpPostAsync <ActivityDTO, ActivityDTO>(_baseHubITest.GetHubApiBaseUrl() + "activities/save", queryDocuSignActivity);

            //this call is without authtoken
            queryDocuSignActivity = await _baseHubITest.HttpPostAsync <ActivityDTO, ActivityDTO>(_baseHubITest.GetHubApiBaseUrl() + "activities/configure", queryDocuSignActivity);

            var initialcrateStorage = _baseHubITest.Crate.FromDto(queryDocuSignActivity.CrateStorage);

            var stAuthCrate = initialcrateStorage.CratesOfType <StandardAuthenticationCM>().FirstOrDefault();

            ;

            //if (!defaultDocuSignAuthTokenExists)
            //{
            var terminalDocuSignTools = new Fr8.Testing.Integration.Tools.Terminals.IntegrationTestTools_terminalDocuSign(_baseHubITest);
            // queryDocuSignActivity.AuthToken = await terminalDocuSignTools.GenerateAuthToken("*****@*****.**", "fr8mesomething", queryDocuSignActivity.ActivityTemplate.Terminal);
            var terminalSummaryDTO = new TerminalSummaryDTO
            {
                Name    = queryDocuSignActivity.ActivityTemplate.TerminalName,
                Version = queryDocuSignActivity.ActivityTemplate.TerminalVersion
            };

            queryDocuSignActivity.AuthToken = await terminalDocuSignTools.GenerateAuthToken("*****@*****.**", "I6HmXEbCxN", terminalSummaryDTO);

            var applyToken = new AuthenticationTokenGrantDTO()
            {
                ActivityId  = queryDocuSignActivity.Id,
                AuthTokenId = Guid.Parse(queryDocuSignActivity.AuthToken.Token),
            };
            await _baseHubITest.HttpPostAsync <AuthenticationTokenGrantDTO[], string>(_baseHubITest.GetHubApiBaseUrl() + "authentication/tokens/grant", new AuthenticationTokenGrantDTO[] { applyToken });

            //send configure with the auth token
            queryDocuSignActivity = await _baseHubITest.HttpPostAsync <ActivityDTO, ActivityDTO>(_baseHubITest.GetHubApiBaseUrl() + "activities/save", queryDocuSignActivity);

            queryDocuSignActivity = await _baseHubITest.HttpPostAsync <ActivityDTO, ActivityDTO>(_baseHubITest.GetHubApiBaseUrl() + "activities/configure", queryDocuSignActivity);

            initialcrateStorage = _baseHubITest.Crate.FromDto(queryDocuSignActivity.CrateStorage);

            Assert.True(initialcrateStorage.CratesOfType <StandardConfigurationControlsCM>().Any(),
                        "Query_DocuSign: Crate StandardConfigurationControlsCM is missing in API response.");

            var controlsCrate = initialcrateStorage.CratesOfType <StandardConfigurationControlsCM>().First();
            //set the value of folder to drafts and
            var controls      = controlsCrate.Content.Controls;
            var folderControl = controls.OfType <DropDownList>().FirstOrDefault(c => c.Name == "FolderFilter");

            Assert.IsNotNull(folderControl, "Query_DocuSign: DropDownList control for Folder value selection was not found");
            folderControl.Value       = "Draft";
            folderControl.selectedKey = "Draft";

            //set the value of status to any
            var statusControl = controls.OfType <DropDownList>().FirstOrDefault(c => c.Name == "StatusFilter");

            Assert.IsNotNull(folderControl, "Query_DocuSign: DropDownList control for Status value selection was not found");
            statusControl.Value       = null;
            statusControl.selectedKey = null;

            //call followup configuration
            using (var crateStorage = _baseHubITest.Crate.GetUpdatableStorage(queryDocuSignActivity))
            {
                crateStorage.Remove <StandardConfigurationControlsCM>();
                crateStorage.Add(controlsCrate);
            }
            queryDocuSignActivity = await _baseHubITest.HttpPostAsync <ActivityDTO, ActivityDTO>(_baseHubITest.GetHubApiBaseUrl() + "activities/save", queryDocuSignActivity);

            queryDocuSignActivity = await _baseHubITest.HttpPostAsync <ActivityDTO, ActivityDTO>(_baseHubITest.GetHubApiBaseUrl() + "activities/configure", queryDocuSignActivity);

            return(await Task.FromResult(queryDocuSignActivity));
        }
        private async Task <Guid> ResolveAuth(ActivityDTO solution, ICrateStorage crateStorage)
        {
            Guid?tokenGuid = null;

            var stAuthCrate = crateStorage
                              .CratesOfType <StandardAuthenticationCM>()
                              .FirstOrDefault();

            if (stAuthCrate != null)
            {
                var terminalsAndTokens =
                    await HttpGetAsync <AuthenticationTokenTerminalDTO[]>(
                        _baseUrl + "authentication/tokens"
                        );

                var terminalDocuSign = terminalsAndTokens
                                       .SingleOrDefault(x => x.Name == "terminalDocuSign");

                if (terminalDocuSign != null)
                {
                    var token = terminalDocuSign.AuthTokens.FirstOrDefault(x => x.IsMain);
                    if (token == null)
                    {
                        token = terminalDocuSign.AuthTokens.FirstOrDefault();
                    }

                    Assert.NotNull(token, "Failed to get the auth token for Docusign terminal. ");
                    tokenGuid = token.Id;
                }

                if (!tokenGuid.HasValue)
                {
                    var creds = GetDocuSignCredentials();
                    creds.Terminal = new TerminalSummaryDTO
                    {
                        Name    = solution.ActivityTemplate.TerminalName,
                        Version = solution.ActivityTemplate.TerminalVersion
                    };

                    var token = await HttpPostAsync <CredentialsDTO, JObject>(
                        _baseUrl + "authentication/token",
                        creds
                        );

                    Assert.AreEqual(
                        false,
                        string.IsNullOrEmpty(token["authTokenId"].Value <string>()),
                        "AuthTokenId is missing in API response."
                        );

                    tokenGuid = Guid.Parse(token["authTokenId"].Value <string>());
                }
            }

            var applyToken = new AuthenticationTokenGrantDTO()
            {
                ActivityId  = solution.Id,
                AuthTokenId = tokenGuid.Value,
                IsMain      = false
            };

            await HttpPostAsync <AuthenticationTokenGrantDTO[], string>(
                _baseUrl + "authentication/tokens/grant",
                new AuthenticationTokenGrantDTO[] { applyToken }
                );

            return(tokenGuid.Value);
        }
        public async Task Extract_Data_From_Envelopes_EndToEnd()
        {
            await RevokeTokens();

            string baseUrl = GetHubApiBaseUrl();

            var solutionCreateUrl = baseUrl + "plans?solutionName=Extract_Data_From_Envelopes";

            //
            // Create solution
            //
            var plan = await HttpPostAsync <string, PlanDTO>(solutionCreateUrl, null);

            var solution = plan.SubPlans.FirstOrDefault().Activities.FirstOrDefault();

            //
            // Send configuration request without authentication token
            //
            _solution = await HttpPostAsync <ActivityDTO, ActivityDTO>(_baseUrl + "activities/configure?id=" + solution.Id, solution);

            _crateStorage = Crate.FromDto(_solution.CrateStorage);
            var authTokenId = await ResolveAuth(_solution, _crateStorage);

            //
            // Send configuration request with authentication token
            //
            _solution = await HttpPostAsync <ActivityDTO, ActivityDTO>(_baseUrl + "activities/configure?id=" + _solution.Id, _solution);

            _crateStorage = Crate.FromDto(_solution.CrateStorage);
            Assert.True(_crateStorage.CratesOfType <StandardConfigurationControlsCM>().Any(), "Crate StandardConfigurationControlsCM is missing in API response.");

            var controlsCrate = _crateStorage.CratesOfType <StandardConfigurationControlsCM>().First();
            var controls      = controlsCrate.Content.Controls;

            //let's make some selections and go for re-configure
            var dataSource = controls.OfType <DropDownList>().FirstOrDefault(c => c.Name == "FinalActionsList");

            dataSource.Value       = "Send_DocuSign_Envelope";
            dataSource.selectedKey = "Send DocuSign Envelope";

            using (var updater = Crate.GetUpdatableStorage(_solution))
            {
                updater.Remove <StandardConfigurationControlsCM>();
                updater.Add(controlsCrate);
            }

            _solution = await HttpPostAsync <ActivityDTO, ActivityDTO>(baseUrl + "activities/configure?id=" + _solution.Id, _solution);

            _crateStorage = Crate.FromDto(_solution.CrateStorage);
            Assert.AreEqual(2, _solution.ChildrenActivities.Count(), "Solution child activities failed to create.");
            Assert.True(_solution.ChildrenActivities.Any(a => a.ActivityTemplate.Name == "Monitor_DocuSign_Envelope_Activity" && a.Ordering == 1),
                        "Failed to detect Monitor DocuSign Envelope Activity as the first child activity");
            Assert.True(_solution.ChildrenActivities.Any(a => a.ActivityTemplate.Name == "Send_DocuSign_Envelope" && a.Ordering == 2),
                        "Failed to detect Send DocuSign Envelope as the second child activity");


            var monitorDocuSignEnvelopeActivity = _solution.ChildrenActivities
                                                  .Single(x => x.ActivityTemplate.Name == "Monitor_DocuSign_Envelope_Activity");

            //
            // Apply auth-token to child MonitorDocuSignEvnelope activity.
            //

            var applyToken = new AuthenticationTokenGrantDTO()
            {
                ActivityId  = monitorDocuSignEnvelopeActivity.Id,
                AuthTokenId = authTokenId,
                IsMain      = false
            };

            await HttpPostAsync <AuthenticationTokenGrantDTO[], string>(
                _baseUrl + "authentication/tokens/grant",
                new AuthenticationTokenGrantDTO[] { applyToken }
                );


            monitorDocuSignEnvelopeActivity = await HttpPostAsync <ActivityDTO, ActivityDTO>(
                _baseUrl + "activities/configure?id=" + monitorDocuSignEnvelopeActivity.Id,
                monitorDocuSignEnvelopeActivity
                );

            //
            // Rename route
            //
            var newName = plan.Name + " | " + DateTime.UtcNow.ToShortDateString() + " " +
                          DateTime.UtcNow.ToShortTimeString();

            await HttpPostAsync <object, PlanDTO>(_baseUrl + "plans?id=" + plan.Id,
                                                  new { id = plan.Id, name = newName });

            //
            // Configure Monitor DocuSign Envelope action
            //
            _crateStorage = Crate.FromDto(monitorDocuSignEnvelopeActivity.CrateStorage);

            controlsCrate = _crateStorage.CratesOfType <StandardConfigurationControlsCM>().First();

            var checkbox = (CheckBox)controlsCrate.Content.Controls.Single(c => c.Type == ControlTypes.CheckBox && c.Name == "EnvelopeSent");

            checkbox.Selected = true;

            var radioButtonGroup = (RadioButtonGroup)controlsCrate.Content.Controls.Single(c => c.Type == ControlTypes.RadioButtonGroup && c.Name == "TemplateRecipientPicker");

            radioButtonGroup.Radios[1].Selected = true;

            using (var updatableStorage = Crate.GetUpdatableStorage(monitorDocuSignEnvelopeActivity))
            {
                updatableStorage.Remove <StandardConfigurationControlsCM>();
                updatableStorage.Add(controlsCrate);
            }

            monitorDocuSignEnvelopeActivity = await HttpPostAsync <ActivityDTO, ActivityDTO>(_baseUrl + "activities/save", monitorDocuSignEnvelopeActivity);

            monitorDocuSignEnvelopeActivity = await HttpPostAsync <ActivityDTO, ActivityDTO>(_baseUrl + "activities/configure", monitorDocuSignEnvelopeActivity);

            radioButtonGroup = (RadioButtonGroup)controlsCrate.Content.Controls.Single(c => c.Type == ControlTypes.RadioButtonGroup && c.Name == "TemplateRecipientPicker");
            var docuSignTemplate = radioButtonGroup.Radios[1].Controls.OfType <DropDownList>().First();

            docuSignTemplate.Value       = "9a4d2154-5b18-4316-9824-09432e62f458";
            docuSignTemplate.selectedKey = "Medical_Form_v1";
            docuSignTemplate.ListItems.Add(new ListItem()
            {
                Value = "9a4d2154-5b18-4316-9824-09432e62f458", Key = "Medical_Form_v1"
            });

            using (var updatableStorage = Crate.GetUpdatableStorage(monitorDocuSignEnvelopeActivity))
            {
                updatableStorage.Remove <StandardConfigurationControlsCM>();
                updatableStorage.Add(controlsCrate);
            }

            monitorDocuSignEnvelopeActivity = await HttpPostAsync <ActivityDTO, ActivityDTO>(_baseUrl + "activities/save", monitorDocuSignEnvelopeActivity);

            monitorDocuSignEnvelopeActivity = await HttpPostAsync <ActivityDTO, ActivityDTO>(_baseUrl + "activities/configure", monitorDocuSignEnvelopeActivity);

            _crateStorage    = Crate.FromDto(monitorDocuSignEnvelopeActivity.CrateStorage);
            controlsCrate    = _crateStorage.CratesOfType <StandardConfigurationControlsCM>().First();
            radioButtonGroup = (RadioButtonGroup)controlsCrate.Content.Controls.Single(c => c.Type == ControlTypes.RadioButtonGroup && c.Name == "TemplateRecipientPicker");
            docuSignTemplate = radioButtonGroup.Radios[1].Controls.OfType <DropDownList>().First();

            Assert.AreEqual("9a4d2154-5b18-4316-9824-09432e62f458", docuSignTemplate.Value, "Selected DocuSign Template did not save on Send DocuSign Envelope activity.");
            Assert.AreEqual("Medical_Form_v1", docuSignTemplate.selectedKey, "Selected DocuSign Template did not save on Send DocuSign Envelope activity.");

            //
            // Configure Send DocuSign Envelope action
            //
            var sendEnvelopeAction = _solution.ChildrenActivities.Single(a => a.ActivityTemplate.Name == "Send_DocuSign_Envelope");

            var sendEnvelopeApplyToken = new AuthenticationTokenGrantDTO()
            {
                ActivityId  = sendEnvelopeAction.Id,
                AuthTokenId = authTokenId,
                IsMain      = false
            };

            await HttpPostAsync <AuthenticationTokenGrantDTO[], string>(
                _baseUrl + "authentication/tokens/grant",
                new AuthenticationTokenGrantDTO[] { sendEnvelopeApplyToken }
                );

            sendEnvelopeAction = await HttpPostAsync <ActivityDTO, ActivityDTO>(
                _baseUrl + "activities/configure?id=" + sendEnvelopeAction.Id,
                sendEnvelopeAction
                );


            using (var updatableStorage = Crate.GetUpdatableStorage(sendEnvelopeAction))
            {
                controlsCrate = updatableStorage.CratesOfType <StandardConfigurationControlsCM>().First();

                docuSignTemplate             = controlsCrate.Content.Controls.OfType <DropDownList>().First();
                docuSignTemplate.Value       = "9a4d2154-5b18-4316-9824-09432e62f458";
                docuSignTemplate.selectedKey = "Medical_Form_v1";
                docuSignTemplate.ListItems.Add(new ListItem()
                {
                    Value = "9a4d2154-5b18-4316-9824-09432e62f458", Key = "Medical_Form_v1"
                });
            }

            sendEnvelopeAction = await HttpPostAsync <ActivityDTO, ActivityDTO>(_baseUrl + "activities/save", sendEnvelopeAction);

            sendEnvelopeAction = await HttpPostAsync <ActivityDTO, ActivityDTO>(_baseUrl + "activities/configure", sendEnvelopeAction);

            // Follow-up Configuration

            TextSource emailField;
            TextSource emailNameField;

            using (var updatableStorage = Crate.GetUpdatableStorage(sendEnvelopeAction))
            {
                controlsCrate          = updatableStorage.CratesOfType <StandardConfigurationControlsCM>().First();
                emailField             = controlsCrate.Content.Controls.OfType <TextSource>().First(f => f.InitialLabel == "freight testing role email");
                emailField.ValueSource = "specific";
                emailField.Value       = TestEmail;
                emailField.TextValue   = TestEmail;

                emailNameField             = controlsCrate.Content.Controls.OfType <TextSource>().First(f => f.InitialLabel == "freight testing role name");
                emailNameField.ValueSource = "specific";
                emailNameField.Value       = TestEmailName;
                emailNameField.TextValue   = TestEmailName;
            }

            sendEnvelopeAction = await HttpPostAsync <ActivityDTO, ActivityDTO>(_baseUrl + "activities/save", sendEnvelopeAction);

            _crateStorage = Crate.FromDto(sendEnvelopeAction.CrateStorage);
            controlsCrate = _crateStorage.CratesOfType <StandardConfigurationControlsCM>().First();

            docuSignTemplate = controlsCrate.Content.Controls.OfType <DropDownList>().First();
            Assert.AreEqual("9a4d2154-5b18-4316-9824-09432e62f458", docuSignTemplate.Value, "Selected DocuSign Template did not save on Send DocuSign Envelope action.");
            Assert.AreEqual("Medical_Form_v1", docuSignTemplate.selectedKey, "Selected DocuSign Template did not save on Send DocuSign Envelope action.");

            emailField = controlsCrate.Content.Controls.OfType <TextSource>().First(f => f.InitialLabel == "freight testing role email");
            Assert.AreEqual(TestEmail, emailField.Value, "Email did not save on Send DocuSign Envelope action.");
            Assert.AreEqual(TestEmail, emailField.TextValue, "Email did not save on Send DocuSign Envelope action.");

            emailNameField = controlsCrate.Content.Controls.OfType <TextSource>().First(f => f.InitialLabel == "freight testing role name");
            Assert.AreEqual(TestEmailName, emailNameField.Value, "Email Name did not save on Send DocuSign Envelope action.");
            Assert.AreEqual(TestEmailName, emailNameField.TextValue, "Email Name did not save on Send DocuSign Envelope action.");

            // Delete Monitor action
            await HttpDeleteAsync(_baseUrl + "activities?id=" + _solution.ChildrenActivities[0].Id);

            // Add Add Payload Manually action
            var activityCategoryParam = ActivityCategories.ProcessId.ToString();
            var activityTemplates     = await HttpGetAsync <List <WebServiceActivitySetDTO> >(_baseUrl + "webservices?id=" + activityCategoryParam);

            var apmActivityTemplate = activityTemplates
                                      .SelectMany(a => a.Activities)
                                      .Single(a => a.Name == "Add_Payload_Manually");
            var activityTemplateSummary = new ActivityTemplateSummaryDTO
            {
                Name            = apmActivityTemplate.Name,
                Version         = apmActivityTemplate.Version,
                TerminalName    = apmActivityTemplate.Terminal.Name,
                TerminalVersion = apmActivityTemplate.Terminal.Version
            };
            var apmAction = new ActivityDTO()
            {
                ActivityTemplate = activityTemplateSummary,
                ParentPlanNodeId = _solution.Id,
                RootPlanNodeId   = plan.Id
            };

            apmAction = await HttpPostAsync <ActivityDTO, ActivityDTO>(_baseUrl + "activities/save", apmAction);

            Assert.NotNull(apmAction, "Add Payload Manually action failed to create");
            Assert.IsTrue(apmAction.Id != default(Guid), "Add Payload Manually activity failed to create");

            //Add rows to Add Payload Manually action
            apmAction = await HttpPostAsync <ActivityDTO, ActivityDTO>(_baseUrl + "activities/configure", apmAction);

            _crateStorage = Crate.FromDto(apmAction.CrateStorage);
            controlsCrate = _crateStorage.CratesOfType <StandardConfigurationControlsCM>().First();
            var fieldList = controlsCrate.Content.Controls.OfType <FieldList>().First();

            fieldList.Value = @"[{""Key"":""Doctor"",""Value"":""Doctor1""},{""Key"":""Condition"",""Value"":""Condition1""}]";

            using (var updatableStorage = Crate.GetUpdatableStorage(apmAction))
            {
                updatableStorage.Remove <StandardConfigurationControlsCM>();
                updatableStorage.Add(controlsCrate);
            }

            // Move Add Payload Manually action to the beginning of the plan
            apmAction.Ordering = 1;
            apmAction          = await HttpPostAsync <ActivityDTO, ActivityDTO>(_baseUrl + "activities/save", apmAction);

            apmAction = await HttpPostAsync <ActivityDTO, ActivityDTO>(_baseUrl + "activities/configure", apmAction);

            Assert.AreEqual(1, apmAction.Ordering, "Failed to reoder the activity Add Payload Manually");

            //
            // Activate and run plan
            //
            await HttpPostAsync <string, ContainerDTO>(_baseUrl + "plans/run?planId=" + plan.Id, null);

            //
            // Deactivate plan
            //
            await HttpPostAsync <string, string>(_baseUrl + "plans/deactivate?planId=" + plan.Id, null);

            //
            // Delete plan
            //
            //await HttpDeleteAsync(_baseUrl + "plans?id=" + plan.Id);
        }
        public async Task Track_DocuSign_Recipients_EndToEnd()
        {
            await RevokeTokens();

            string baseUrl = GetHubApiBaseUrl();

            var solutionCreateUrl = baseUrl + "plans?solutionName=Track_DocuSign_Recipients_v2";


            //
            // Create solution
            //
            var plan = await HttpPostAsync <string, PlanDTO>(solutionCreateUrl, null);

            var solution = plan.SubPlans.FirstOrDefault().Activities.FirstOrDefault();

            var planReloadUrl = string.Format(baseUrl + "plans?id={0}&include_children=true", plan.Id);

            //
            // Send configuration request without authentication token
            //
            this._solution = await HttpPostAsync <ActivityDTO, ActivityDTO>(baseUrl + "activities/configure?id=" + solution.Id, solution);

            _crateStorage = Crate.FromDto(this._solution.CrateStorage);
            var  stAuthCrate = _crateStorage.CratesOfType <StandardAuthenticationCM>().FirstOrDefault();
            bool defaultDocuSignAuthTokenExists = stAuthCrate == null;

            if (!defaultDocuSignAuthTokenExists)
            {
                //
                // Authenticate with DocuSign
                //
                var creds = GetDocuSignCredentials();
                creds.Terminal = new TerminalSummaryDTO
                {
                    Name    = solution.ActivityTemplate.TerminalName,
                    Version = solution.ActivityTemplate.TerminalVersion
                };

                var token = await HttpPostAsync <CredentialsDTO, JObject>(baseUrl + "authentication/token", creds);

                Assert.AreEqual(false, String.IsNullOrEmpty(token["authTokenId"].Value <string>()), "AuthTokenId is missing in API response.");
                Guid tokenGuid = Guid.Parse(token["authTokenId"].Value <string>());

                //
                // Asociate token with action
                //
                var applyToken = new AuthenticationTokenGrantDTO()
                {
                    ActivityId  = solution.Id,
                    AuthTokenId = tokenGuid,
                    IsMain      = true
                };
                await HttpPostAsync <AuthenticationTokenGrantDTO[], string>(baseUrl + "authentication/tokens/grant", new AuthenticationTokenGrantDTO[] { applyToken });

                //let's give it some time to create MonitorDocusignEvents plan
                await Task.Delay(TimeSpan.FromSeconds(15));

                //let's post a fake event to populate MT database
                await PostFakeEvent();
            }



            //
            // Send configuration request with authentication token
            //
            this._solution = await HttpPostAsync <ActivityDTO, ActivityDTO>(baseUrl + "activities/configure?id=" + solution.Id, solution);

            _crateStorage = Crate.FromDto(this._solution.CrateStorage);

            ShouldHaveCorrectCrateStructure(_crateStorage);
            Assert.True(this._solution.ChildrenActivities.Length == 0);

            var controlsCrate = _crateStorage.CratesOfType <StandardConfigurationControlsCM>().First();
            var controls      = controlsCrate.Content.Controls;

            #region CHECK_CONFIGURATION_CONTROLS

            Assert.AreEqual(5, controls.Count);
            Assert.True(controls.Any(c => c.Type == ControlTypes.DropDownList && c.Name == "NotifierSelector"));
            Assert.True(controls.Any(c => c.Type == ControlTypes.DropDownList && c.Name == "RecipientEventSelector"));
            Assert.True(controls.Any(c => c.Type == ControlTypes.Duration && c.Name == "TimePeriod"));
            Assert.True(controls.Any(c => c.Type == ControlTypes.RadioButtonGroup && c.Name == "EnvelopeTypeSelectionGroup"));

            var radioButtonGroup = (RadioButtonGroup)controls.Single(c => c.Type == ControlTypes.RadioButtonGroup && c.Name == "EnvelopeTypeSelectionGroup");
            Assert.AreEqual(2, radioButtonGroup.Radios.Count);
            Assert.True(radioButtonGroup.Radios.Any(c => c.Name == "SentToSpecificRecipientOption"));
            Assert.True(radioButtonGroup.Radios.Any(c => c.Name == "BasedOnTemplateOption"));

            var specificRecipientOption = (RadioButtonOption)radioButtonGroup.Radios.Single(c => c.Name == "SentToSpecificRecipientOption");
            Assert.AreEqual(1, specificRecipientOption.Controls.Count);
            Assert.True(specificRecipientOption.Controls.Any(c => c.Name == "SpecificRecipientEmailText" && c.Type == ControlTypes.TextBox));

            var specificTemplateOption = (RadioButtonOption)radioButtonGroup.Radios.Single(c => c.Name == "BasedOnTemplateOption");
            Assert.AreEqual(1, specificTemplateOption.Controls.Count);
            Assert.True(specificTemplateOption.Controls.Any(c => c.Name == "TemplateSelector" && c.Type == ControlTypes.DropDownList));

            #endregion

            //let's make some selections and go for re-configure
            //RDN shouldn't update it's child activity structure until we select a notification method
            radioButtonGroup.Radios[0].Selected       = true;
            radioButtonGroup.Radios[1].Selected       = false;
            specificRecipientOption.Controls[0].Value = "*****@*****.**";

            using (var updater = Crate.GetUpdatableStorage(_solution))
            {
                updater.Remove <StandardConfigurationControlsCM>();
                updater.Add(controlsCrate);
            }

            this._solution = await HttpPostAsync <ActivityDTO, ActivityDTO>(baseUrl + "activities/configure?id=" + this._solution.Id, this._solution);

            _crateStorage = Crate.FromDto(this._solution.CrateStorage);
            ShouldHaveCorrectCrateStructure(_crateStorage);
            Assert.True(this._solution.ChildrenActivities.Length == 0);

            //everything seems perfect for now
            //let's force RDN for a followup configuration

            var timePeriod          = (Duration)controls.Single(c => c.Type == ControlTypes.Duration && c.Name == "TimePeriod");
            var notificationHandler = (DropDownList)controls.Single(c => c.Type == ControlTypes.DropDownList && c.Name == "NotifierSelector");
            var recipientEvent      = (DropDownList)controls.Single(c => c.Type == ControlTypes.DropDownList && c.Name == "RecipientEventSelector");

            timePeriod.Days    = 0;
            timePeriod.Hours   = 0;
            timePeriod.Minutes = 0;

            notificationHandler.SelectByKey("Send Email Using SendGrid Account");
            Assert.IsNotNullOrEmpty(notificationHandler.Value);
            recipientEvent.SelectByKey("Signed Envelope");
            Assert.IsNotNullOrEmpty(recipientEvent.Value);

            var button = (Button)controls.Single(c => c.Type == ControlTypes.Button && c.Name == "BuildSolutionButton");
            button.Clicked = true;

            using (var updatableStorage = Crate.GetUpdatableStorage(_solution))
            {
                updatableStorage.Remove <StandardConfigurationControlsCM>();
                updatableStorage.Add(controlsCrate);
            }

            this._solution = await HttpPostAsync <ActivityDTO, ActivityDTO>(baseUrl + "activities/configure?id=" + this._solution.Id, this._solution);

            _crateStorage = Crate.FromDto(this._solution.CrateStorage);

            //from now on our solution should have followup crate structure
            Assert.True(this._solution.ChildrenActivities.Length == 4, "Solution child actions failed to create.");

            Assert.True(this._solution.ChildrenActivities.Any(a => a.ActivityTemplate.Name == "Monitor_DocuSign_Envelope_Activity" && a.Ordering == 1));
            Assert.True(this._solution.ChildrenActivities.Any(a => a.ActivityTemplate.Name == "Set_Delay" && a.Ordering == 2));
            Assert.True(this._solution.ChildrenActivities.Any(a => a.ActivityTemplate.Name == "Get_Data_From_Fr8_Warehouse" && a.Ordering == 3));
            Assert.True(this._solution.ChildrenActivities.Any(a => a.ActivityTemplate.Name == "Test_Incoming_Data" && a.Ordering == 4));

            plan = await HttpGetAsync <PlanDTO>(planReloadUrl);

            Assert.AreEqual(3, plan.SubPlans.First().Activities.Count);
            Assert.True(plan.SubPlans.First().Activities.Any(a => a.ActivityTemplate.Name == "Build_Message" && a.Ordering == 2));
            var emailActivity = plan.SubPlans.First().Activities.Last();

            var activityTemplates = await HttpGetAsync <IEnumerable <ActivityTemplateCategoryDTO> >($"{baseUrl}/activity_templates");

            var templates            = activityTemplates.SelectMany(x => x.Activities);
            var selectedActivityName = templates.First(x => x.Id == Guid.Parse(notificationHandler.Value));
            Assert.True(emailActivity.ActivityTemplate.Name == selectedActivityName.Name);

            //let's configure email settings

            //let's configure this
            emailActivity = await HttpPostAsync <ActivityDTO, ActivityDTO>(baseUrl + "activities/configure?id=" + emailActivity.Id, emailActivity);

            var emailCrateStorage = Crate.GetStorage(emailActivity);

            var emailControlsCrate = emailCrateStorage.CratesOfType <StandardConfigurationControlsCM>().First();
            var emailAddress       = (TextSource)emailControlsCrate.Content.Controls.Single(c => c.Name == "EmailAddress");
            var emailSubject       = (TextSource)emailControlsCrate.Content.Controls.Single(c => c.Name == "EmailSubject");
            var emailBody          = (TextSource)emailControlsCrate.Content.Controls.Single(c => c.Name == "EmailBody");

            var upstreamFieldDescription = await HttpGetAsync <IncomingCratesDTO>(baseUrl + "plan_nodes/signals?id=" + emailActivity.Id);

            Assert.True(upstreamFieldDescription.AvailableCrates.SelectMany(x => x.Fields).Any(y => y.Name == "NotificationMessage"));
            Assert.AreEqual("NotificationMessage", emailBody.Value);

            emailAddress.ValueSource = "specific";
            emailAddress.Value       = TestEmail;
            emailAddress.TextValue   = TestEmail;

            emailSubject.ValueSource = "specific";
            emailSubject.Value       = "Fr8-TrackDocuSignRecipientsTest";
            emailSubject.TextValue   = "Fr8-TrackDocuSignRecipientsTest";

            emailBody.ValueSource = "specific";
            emailBody.Value       = "Fr8-TrackDocuSignRecipientsTest";
            emailBody.TextValue   = "Fr8-TrackDocuSignRecipientsTest";

            using (var updatableStorage = Crate.GetUpdatableStorage(emailActivity))
            {
                updatableStorage.Remove <StandardConfigurationControlsCM>();
                updatableStorage.Add(emailControlsCrate);
            }

            //save changes
            await HttpPostAsync <ActivityDTO, ActivityDTO>(baseUrl + "activities/save", emailActivity);

            //
            //Rename plan
            //
            var newName = plan.Name + " | " + DateTime.UtcNow.ToShortDateString() + " " + DateTime.UtcNow.ToShortTimeString();
            await HttpPostAsync <object, PlanDTO>(baseUrl + "plans?id=" + plan.Id, new { id = plan.Id, name = newName });

            //let's activate our plan
            await HttpPostAsync <string, string>(baseUrl + "plans/run?planId=" + plan.Id, null);


            //everything seems perfect -> let's fake a docusign event
            await PostFakeEvent();

            //let's wait 45 seconds before continuing
            await Task.Delay(TimeSpan.FromSeconds(45));

            //we should have received an email about this operation


            //
            // Deactivate plan
            //
            await HttpPostAsync <string, string>(baseUrl + "plans/deactivate?planid=" + plan.Id, plan.Id.ToString());

            //
            // Delete plan
            //
            await HttpDeleteAsync(baseUrl + "plans?id=" + plan.Id);

            // Verify that test email has been received
            //EmailAssert.EmailReceived(ConfigurationManager.AppSettings["OpsEmail"], "Fr8-TrackDocuSignRecipientsTest");
        }