public async Task CreateVersionCurrentCostStage() { // Arrange var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video) .WithApprovalStage(CostStages.OriginalEstimate.ToString()); var cost = await CreateCost(builder, AdminUser); await SetCostStatus(cost, CostStageRevisionStatus.Rejected); // Act await ExecuteAction(cost.Id, CostAction.Reopen, AdminUser); var browserResponse = await Browser.Get($"/v1/costs/{cost.Id}/stage", w => w.User(AdminUser)); var stages = Deserialize <CostStageModel[]>(browserResponse, HttpStatusCode.OK); // Assert stages.Should().NotBeNull(); stages.Should().HaveCount(1); stages[0].Key.Should().Be(CostStages.OriginalEstimate.ToString()); stages[0].Revisions.Should().HaveCount(2); stages[0].Revisions[1].Status.Should().Be(CostStageRevisionStatus.Draft); }
public async Task MoveCostToNextStage_whenEnoughPermissionsAndAllowed() { // Arrange var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video) .WithApprovalStage(CostStages.OriginalEstimate.ToString()); var cost = await CreateCost(builder, AdminUser); await SetCostStatus(cost, CostStageRevisionStatus.Approved); // Act await ExecuteAction(cost.Id, CostAction.NextStage, AdminUser); var browserResponse = await Browser.Get($"/v1/costs/{cost.Id}/stage", w => w.User(AdminUser)); var stages = Deserialize <CostStageModel[]>(browserResponse, HttpStatusCode.OK); // Assert stages.Should().NotBeNull(); stages.Should().HaveCount(2); stages[0].Key.Should().Be(CostStages.OriginalEstimate.ToString()); stages[0].Revisions.Should().HaveCount(1); stages[1].Key.Should().Be(CostStages.FirstPresentation.ToString()); stages[1].Revisions.Should().HaveCount(1); }
public async Task ReturnCreateRevision_WhenOwnerButAlreadyRevision() { // Arrange var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video) .WithApprovalStage(CostStages.OriginalEstimate.ToString()); var cost = await CreateCost(builder, AdminUser); // Approve first stage await SetCostStatus(cost, CostStageRevisionStatus.Approved); // Create revision stage of current stage await ExecuteAction(cost.Id, CostAction.CreateRevision, AdminUser); // Approve revision stage await SetCostStatus(cost, CostStageRevisionStatus.Approved); // Act var url = $"{CostRevisionWorkflowUrl(cost.Id, GetLatestRevisionId(cost.Id))}/actions"; var response = await Browser.Get(url, w => w.User(AdminUser)); var actionModels = Deserialize <Dictionary <string, ActionModel> >(response, HttpStatusCode.OK); // Assert actionModels.Should().NotBeNull(); actionModels.Should().ContainKey(CostAction.CreateRevision.ToString()); actionModels.Should().ContainKey(CostAction.NextStage.ToString()); }
public async Task Recall_When_PendingTechnicalApproval() { // Arrange var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video) .WithProductionType(Constants.ProductionType.PostProductionOnly) .WithBudgetRegion(Constants.BudgetRegion.AsiaPacific) .WithInitialBudget(12312312312); var dbCost = await CreateCost(builder, AdminUser); await AddApprover(dbCost, AdminUser, Approver); await SetCostStatus(dbCost, CostStageRevisionStatus.PendingTechnicalApproval); // Act await ExecuteAction(dbCost.Id, CostAction.Recall, AdminUser); var browserResponse = await Browser.Get($"/v1/costs/{dbCost.Id}", w => w.User(AdminUser)); var cost = Deserialize <Cost>(browserResponse, HttpStatusCode.OK); // Assert cost.Should().NotBeNull(); cost.Status.Should().Be(CostStageRevisionStatus.Recalled); }
public async Task SkipFirstPresentation_For_StillImage_If_(CostType costType, string contentType, string region, string productionType) { // Arrange var builder = new CreateCostModelBuilder(); if (costType != CostType.Buyout) { builder.WithContentType(contentType); } builder.WithBudgetRegion(region); builder.WithProductionType(productionType); var cost = await CreateCost(builder, AdminUser, costType); // Act var url = $"{CostWorkflowUrl(cost.Id)}/stages"; var response = await Browser.Get(url, w => w.User(AdminUser)); var stageModes = Deserialize <Dictionary <string, StageModel> >(response, HttpStatusCode.OK); // Assert stageModes.Should().HaveCount(4); stageModes.Should().NotContainKeys(CostStages.FirstPresentation.ToString()); stageModes[CostStages.New.ToString()].Transitions.Should().ContainKey(CostStages.FinalActual.ToString()); stageModes[CostStages.OriginalEstimate.ToString()].Transitions.Should().ContainKey(CostStages.FinalActual.ToString()); stageModes[CostStages.OriginalEstimateRevision.ToString()].Transitions.Should().ContainKey(CostStages.FinalActual.ToString()); }
public async Task Recall_When_PendingBrandApproval_AndCyclone_AndNorthAmerica() { // Arrange var agencyAbstractType = await CreateAgencyAbstractType(isCyclone : true, agencyName : "Advertiser_AGENCY"); var owner = await CreateUser($"{Guid.NewGuid()}bob", Roles.CostOwner, agencyAbstractType.ObjectId); var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video) .WithProductionType(Constants.ProductionType.PostProductionOnly) .WithBudgetRegion(Constants.BudgetRegion.NorthAmerica) .WithInitialBudget(12312312312); var dbCost = await CreateCost(builder, owner); await AddApprover(dbCost, owner, Approver); await SetCostStatus(dbCost, CostStageRevisionStatus.PendingBrandApproval); // Act await ExecuteAction(dbCost.Id, CostAction.Recall, owner); var browserResponse = await Browser.Get($"/v1/costs/{dbCost.Id}", w => w.User(owner)); var cost = Deserialize <Cost>(browserResponse, HttpStatusCode.OK); // Assert cost.Should().NotBeNull(); cost.Status.Should().Be(CostStageRevisionStatus.Recalled); }
public async Task ReturnSortedAIPEWorklowStages_when_VideoFullProduction() { // Arrange var builder = new CreateCostModelBuilder(); builder.WithContentType(Constants.ContentType.Video); builder.WithBudgetRegion(Constants.BudgetRegion.NorthAmerica); builder.WithProductionType(Constants.ProductionType.FullProduction); var cost = await CreateCost(builder, AdminUser); // Act var url = $"{CostWorkflowUrl(cost.Id)}/stages"; var response = await Browser.Get(url, w => w.User(AdminUser)); var stageModes = Deserialize <Dictionary <string, StageModel> >(response, HttpStatusCode.OK); // Assert stageModes.Should().HaveCount(7); stageModes.Should().ContainKey(CostStages.New.ToString()); stageModes.Should().ContainKey(CostStages.Aipe.ToString()); stageModes.Should().ContainKey(CostStages.OriginalEstimate.ToString()); stageModes.Should().ContainKey(CostStages.OriginalEstimateRevision.ToString()); stageModes.Should().ContainKey(CostStages.FirstPresentation.ToString()); stageModes.Should().ContainKey(CostStages.FirstPresentationRevision.ToString()); stageModes.Should().ContainKey(CostStages.FinalActual.ToString()); stageModes.Skip(1).First().Key.Should().Be(CostStages.Aipe.ToString()); }
protected async Task <Cost> CreateCost(CreateCostModelBuilder createCostModelBuilder, CostUser user, CostType costType = CostType.Production) { if (!Enum.IsDefined(typeof(CostType), costType)) { throw new ArgumentOutOfRangeException(nameof(costType), "Value should be defined in the CostType enum."); } if (costType == CostType.Production && CostTemplate == null) { CostTemplate = await CreateTemplate(user, costType); } if (costType == CostType.Buyout && UsageCostTemplate == null) { UsageCostTemplate = await CreateTemplate(user, costType); } var costTemplateId = costType == CostType.Production ? CostTemplate.Id : UsageCostTemplate.Id; createCostModelBuilder .WithTemplateId(costTemplateId) .WithAgency(user.Agency.AbstractTypes.FirstOrDefault()); var createCostResult = await CreateCost(user, createCostModelBuilder.Build()); var cost = Deserialize <Cost>(createCostResult, HttpStatusCode.Created); var latestStage = await GetCostLatestStage(cost.Id, user); await GetCostLatestRevision(cost.Id, latestStage.Id, user); return(cost); }
public async Task NotReturn_NextStage_CreateRevision_ApproveReopen_RejectReopen_WhenFinalActualAndStatusIsDraft() { // Arrange var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video); CostAction[] invalidActions = { CostAction.NextStage, CostAction.CreateRevision, CostAction.ApproveReopen, CostAction.RejectReopen }; var cost = await CreateCost(builder, AdminUser); var latestStage = await GetCostLatestStage(cost.Id, AdminUser); var latestRevision = await GetCostLatestRevision(cost.Id, latestStage.Id, AdminUser); var currency = await GetDefaultCurrency(); var lineItemSection = await EFContext.CostLineItemSectionTemplate.FirstOrDefaultAsync(ts => ts.Name == Constants.CostSection.Production); await CreateCostLineItems(cost.Id, latestStage.Id, latestRevision.Id, new List <CostLineItemModel> { new CostLineItemModel { Name = "Item1", Value = 412842, LocalCurrencyId = currency.Id, TemplateSectionId = lineItemSection.Id } }, AdminUser); var stagesResponse = await Browser.Get($"{CostWorkflowUrl(cost.Id)}/stages", w => w.User(AdminUser)); var stages = Deserialize <Dictionary <string, StageModel> >(stagesResponse, HttpStatusCode.OK); // Move to last stage ( 'FinalActual' ) for (var i = 1; i < stages.Values.Count(s => !s.IsRequired); ++i) { await SetCostStatus(cost, CostStageRevisionStatus.Approved); await ExecuteAction(cost.Id, CostAction.NextStage, AdminUser); } // Act var url = $"{CostRevisionWorkflowUrl(cost.Id, GetLatestRevisionId(cost.Id))}/actions"; var response = await Browser.Get(url, w => w.User(AdminUser)); var actionModels = Deserialize <Dictionary <string, ActionModel> >(response, HttpStatusCode.OK); // Assert actionModels.Should().NotBeNull(); actionModels.Should().NotContainKeys(invalidActions.Select(a => a.ToString())); }
public async Task ReturnEditValueReporting_WhenCostIsAtFinalActualApproved() { var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video); var cost = await CreateCost(builder, AdminUser); var lateststage = await GetCostLatestStage(cost.Id, AdminUser); var latestRevision = await GetCostLatestRevision(cost.Id, lateststage.Id, AdminUser); var currency = await GetDefaultCurrency(); var lineItemSection = await EFContext.CostLineItemSectionTemplate.FirstOrDefaultAsync(ts => ts.Name == Constants.CostSection.Production); await CreateCostLineItems(cost.Id, lateststage.Id, latestRevision.Id, new List <CostLineItemModel> { new CostLineItemModel { Name = "Item1", Value = 1111111, LocalCurrencyId = currency.Id, TemplateSectionId = lineItemSection.Id } }, AdminUser); var approver = await CreateUser($"{Guid.NewGuid()}approver_valueReporting", Roles.CostApprover); await AddApprover(cost, AdminUser, approver); await ExecuteAction(cost.Id, CostAction.Submit, AdminUser); await ExecuteAction(cost.Id, CostAction.Approve, approver); var stageResponse = await Browser.Get($"{CostWorkflowUrl(cost.Id)}/stages", w => w.User(AdminUser)); var stages = Deserialize <Dictionary <string, StageModel> >(stageResponse, HttpStatusCode.OK); for (var i = 1; i < stages.Values.Count(s => !s.IsRequired); ++i) { await SetCostStatus(cost, CostStageRevisionStatus.Approved); await ExecuteAction(cost.Id, CostAction.NextStage, AdminUser); } await ExecuteAction(cost.Id, CostAction.Submit, AdminUser); await ExecuteAction(cost.Id, CostAction.Approve, approver); cost = EFContext.Cost.First(c => c.Id == cost.Id); EFContext.Entry(cost).Reload(); var url = $"{CostRevisionWorkflowUrl(cost.Id, GetLatestRevisionId(cost.Id))}/actions"; var response = await Browser.Get(url, w => w.User(approver)); var actionModels = Deserialize <Dictionary <string, ActionModel> >(response, HttpStatusCode.OK); actionModels.Should().ContainKey(CostAction.EditValueReporting.ToString()); }
public async Task DeleteCosts() { // Arrange var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video); var cost = await CreateCost(builder, AdminUser); // Act await ExecuteAction(cost.Id, CostAction.Delete, AdminUser); // Assert var browserResponse = await Browser.Get($"/v1/costs/{cost.Id}", w => w.User(AdminUser)); browserResponse.StatusCode.Should().Be(HttpStatusCode.NotFound); }
protected void InitData( string budgetRegion = Constants.BudgetRegion.AsiaPacific, string contentType = Constants.ContentType.Photography, string productionType = Constants.ProductionType.FullProduction, CostType costType = CostType.Production ) { CreateTemplateIfNotCreated(User).Wait(); var costTemplateId = costType == CostType.Production ? CostTemplate.Id : costType == CostType.Buyout ? UsageCostTemplate.Id : TrafficCostTemplate.Id; var costModel = new CreateCostModelBuilder() .WithBudgetRegion(budgetRegion) .WithContentType(contentType) .WithProductionType(productionType) .WithTemplateId(costTemplateId) .Build(); var createCostResponse = CreateCost(User, costModel).Result; _cost = Deserialize <Cost>(createCostResponse.Body); _revision = EFContext.CostStageRevision.First(csr => csr.Id == _cost.LatestCostStageRevisionId.Value); var costStageRevisionId = _revision.Id; _contentType = contentType; _productionType = productionType; _stageDetails = new PgStageDetailsForm { ContentType = new DictionaryValue { Key = _contentType }, ProductionType = new DictionaryValue { Key = _productionType }, BudgetRegion = new AbstractTypeValue { Key = budgetRegion } }; _productionDetails = new PgProductionDetailsForm(); _costStageRevisionServiceMock.Setup(csr => csr.GetRevisionById(costStageRevisionId)).ReturnsAsync(_revision); _costStageRevisionServiceMock.Setup(csr => csr.GetStageDetails <PgStageDetailsForm>(costStageRevisionId)).ReturnsAsync(_stageDetails); _costStageRevisionServiceMock.Setup(csr => csr.GetProductionDetails <PgProductionDetailsForm>(costStageRevisionId)).ReturnsAsync(_productionDetails); }
public async Task ReturnReject_WhenStatusIsPendingIPMApprovalAndAboveAuthLimit() { // Arrange var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video) .WithProductionType(Constants.ProductionType.PostProductionOnly) .WithBudgetRegion(Constants.BudgetRegion.AsiaPacific) .WithApprovalStage(CostStages.FinalActual.ToString()) .WithInitialBudget(12312); var cost = await CreateCost(builder, AdminUser); var latestStage = await GetCostLatestStage(cost.Id, AdminUser); var latestRevision = await GetCostLatestRevision(cost.Id, latestStage.Id, AdminUser); var currency = await GetDefaultCurrency(); var lineItemSection = await EFContext.CostLineItemSectionTemplate.FirstOrDefaultAsync(ts => ts.Name == Constants.CostSection.Production); await CreateCostLineItems(cost.Id, latestStage.Id, latestRevision.Id, new List <CostLineItemModel> { new CostLineItemModel { Name = "Item1", Value = 10000, LocalCurrencyId = currency.Id, TemplateSectionId = lineItemSection.Id } }, AdminUser); await AddApprover(cost, AdminUser, Approver); await ExecuteAction(cost.Id, CostAction.Submit, AdminUser); await SetApproverAuthLimit(9999); // Act var url = $"{CostRevisionWorkflowUrl(cost.Id, GetLatestRevisionId(cost.Id))}/actions"; var response = await Browser.Get(url, w => w.User(Approver)); var actionModels = Deserialize <Dictionary <string, ActionModel> >(response, HttpStatusCode.OK); // Assert actionModels.Should().NotBeNull(); actionModels.Should().HaveCount(1); actionModels.Should().ContainKey(CostAction.Reject.ToString()); }
public async Task ReturnCollectionOfAwailableActions() { // Arrange var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video); var cost = await CreateCost(builder, AdminUser); // Act var url = $"{CostRevisionWorkflowUrl(cost.Id, GetLatestRevisionId(cost.Id))}/actions"; var response = await Browser.Get(url, w => w.User(AdminUser)); var actionModels = Deserialize <Dictionary <string, ActionModel> >(response, HttpStatusCode.OK); // Assert actionModels.Should().NotBeNull(); }
public async Task ReturnSubmitAction_WhenStatusIsDraftAndOwner() { // Arrange var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video); var cost = await CreateCost(builder, AdminUser); // Act var url = $"{CostRevisionWorkflowUrl(cost.Id, GetLatestRevisionId(cost.Id))}/actions"; var response = await Browser.Get(url, w => w.User(AdminUser)); var actionModels = Deserialize <Dictionary <string, ActionModel> >(response, HttpStatusCode.OK); // Assert actionModels.Should().NotBeNull(); actionModels.Should().ContainKey(CostAction.Submit.ToString()); actionModels[CostAction.Submit.ToString()].Key.Should().Be(CostAction.Submit); }
public async Task ReturnEditValueReporting_WhenIPMApproverAndPendingBrandApproval() { var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video); var cost = await CreateCost(builder, AdminUser); var latestStage = await GetCostLatestStage(cost.Id, AdminUser); var latestRevision = await GetCostLatestRevision(cost.Id, latestStage.Id, AdminUser); var currency = await GetDefaultCurrency(); var lineItemSection = await EFContext.CostLineItemSectionTemplate.FirstOrDefaultAsync(ts => ts.Name == Constants.CostSection.Production); await CreateCostLineItems(cost.Id, latestStage.Id, latestRevision.Id, new List <CostLineItemModel> { new CostLineItemModel { Name = "Item1", Value = 412842, LocalCurrencyId = currency.Id, TemplateSectionId = lineItemSection.Id } }, AdminUser); var approver = await CreateUser($"{Guid.NewGuid()}approver_ValueReporting", Roles.CostApprover); await AddApprover(cost, AdminUser, approver); await ExecuteAction(cost.Id, CostAction.Submit, AdminUser); await ExecuteAction(cost.Id, CostAction.Approve, approver); // Act var url = $"{CostRevisionWorkflowUrl(cost.Id, GetLatestRevisionId(cost.Id))}/actions"; var response = await Browser.Get(url, w => w.User(approver)); var actionModels = Deserialize <Dictionary <string, ActionModel> >(response, HttpStatusCode.OK); // Assert actionModels.Should().NotBeNull(); actionModels.Should().ContainKey(CostAction.EditValueReporting.ToString()); }
public async Task SubmitCost_when_submitRequestedAndEnoughPermissions() { // Arrange var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video) .WithApprovalStage(CostStages.OriginalEstimate.ToString()) .WithProductionType(Constants.ProductionType.PostProductionOnly) .WithBudgetRegion(Constants.BudgetRegion.China) .WithInitialBudget(12312); var cost = await CreateCost(builder, AdminUser); var dbCost = await EFContext.Cost.Include(c => c.LatestCostStageRevision).FirstAsync(c => c.Id == cost.Id); var currency = await GetCurrencyByCode("CAD"); var lineItemSection = await EFContext.CostLineItemSectionTemplate.FirstOrDefaultAsync(ts => ts.Name == Constants.CostSection.Production); await CreateExchangeRate(currency, (decimal)1.5); await CreateCostLineItems(cost.Id, dbCost.LatestCostStageRevision.CostStageId, dbCost.LatestCostStageRevision.Id, new List <CostLineItemModel> { new CostLineItemModel { Name = "Item1", Value = 41284, LocalCurrencyId = currency.Id, TemplateSectionId = lineItemSection.Id } }, AdminUser); await AddApprover(cost, AdminUser, Approver); // Act await ExecuteAction(cost.Id, CostAction.Submit, AdminUser); // Assert var latestStage = await GetCostLatestStage(cost.Id, AdminUser); var latestRevision = await GetCostLatestRevision(cost.Id, latestStage.Id, AdminUser); latestRevision.Status.Should().Be(CostStageRevisionStatus.PendingTechnicalApproval); }
public async Task ReturnCancellAction_WhenOwnerAndApproved() { // Arrange var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video); var cost = await CreateCost(builder, AdminUser); await SetCostStatus(cost, CostStageRevisionStatus.Approved); // Act var url = $"{CostRevisionWorkflowUrl(cost.Id, GetLatestRevisionId(cost.Id))}/actions"; var response = await Browser.Get(url, w => w.User(AdminUser)); var actionModels = Deserialize <Dictionary <string, ActionModel> >(response, HttpStatusCode.OK); // Assertcos actionModels.Should().NotBeNull(); actionModels.Should().ContainKey(CostAction.Cancel.ToString()); }
public async Task ReturnNotReturnAnyAction_WhenStatusIsDraftAndNotOwner() { // Arrange var builder = new CreateCostModelBuilder() .WithContentType(Constants.ContentType.Video) .WithProductionType(Constants.ProductionType.PostProductionOnly) .WithBudgetRegion(Constants.BudgetRegion.AsiaPacific) .WithInitialBudget(12312312312); var cost = await CreateCost(builder, AdminUser); await AddApprover(cost, AdminUser, Approver); // Act var url = $"{CostRevisionWorkflowUrl(cost.Id, GetLatestRevisionId(cost.Id))}/actions"; var response = await Browser.Get(url, w => w.User(Approver)); var actionModels = Deserialize <Dictionary <string, ActionModel> >(response, HttpStatusCode.OK); // Assert actionModels.Should().NotBeNull(); actionModels.Should().BeEmpty(); }