public void MergeSurveyAnswersSummary(SurveyAnswersSummary partialSurveyAnswersSummary) { OptimisticConcurrencyContext context; var id = string.Format(CultureInfo.InvariantCulture, "{0}-{1}", partialSurveyAnswersSummary.Tenant, partialSurveyAnswersSummary.SlugName); var surveyAnswersSummaryInStore = this.surveyAnswersSummaryBlobContainer.Get(id, out context); partialSurveyAnswersSummary.MergeWith(surveyAnswersSummaryInStore); this.surveyAnswersSummaryBlobContainer.Save(context, partialSurveyAnswersSummary); }
public async Task MergeSurveyAnswersSummaryAsync(SurveyAnswersSummary partialSurveyAnswersSummary) { var id = string.Format(CultureInfo.InvariantCulture, "{0}-{1}", partialSurveyAnswersSummary.Tenant, partialSurveyAnswersSummary.SlugName); var surveyAnswersSummaryInStore = await this.surveyAnswersSummaryBlobContainer.GetAsync(id).ConfigureAwait(false); partialSurveyAnswersSummary.MergeWith(surveyAnswersSummaryInStore); await this.surveyAnswersSummaryBlobContainer.SaveAsync(id, partialSurveyAnswersSummary).ConfigureAwait(false); }
public void GetSurveyAnswersSummaryReturnsSumamryReadFromBlobContainer() { var mockSurveyAnswersSummaryBlobContainer = new Mock<IAzureBlobContainer<SurveyAnswersSummary>>(); var store = new SurveyAnswersSummaryStore(mockSurveyAnswersSummaryBlobContainer.Object); var surveyAnswersSummary = new SurveyAnswersSummary(); mockSurveyAnswersSummaryBlobContainer.Setup(c => c.Get("tenant-slug-name")).Returns(surveyAnswersSummary); SurveyAnswersSummary actualSurveyAnswersSummary = store.GetSurveyAnswersSummary("tenant", "slug-name"); Assert.AreSame(surveyAnswersSummary, actualSurveyAnswersSummary); }
public async Task MergeSurveyAnswerToAnalysisAsync(Client.Models.SurveyAnswer surveyAnswer) { try { var surveyAnswersSummaryCache = Connection.GetDatabase(); var success = false; do { var result = await surveyAnswersSummaryCache.StringGetAsync(surveyAnswer.SlugName); var isNew = result.IsNullOrEmpty; var transaction = surveyAnswersSummaryCache.CreateTransaction(); SurveyAnswersSummary surveyAnswersSummary = null; if (isNew) { transaction.AddCondition(Condition.KeyNotExists(surveyAnswer.SlugName)); surveyAnswersSummary = new SurveyAnswersSummary(surveyAnswer.SlugName); } else { surveyAnswersSummary = JsonConvert.DeserializeObject <SurveyAnswersSummary>(result); transaction.AddCondition(Condition.StringEqual(surveyAnswer.SlugName, result)); } ServiceEventSource.Current.Message("Slug name:{0}|Total answers:{1}", surveyAnswersSummary.SlugName, surveyAnswersSummary.TotalAnswers); // Add and merge the new answer to new or existing summary surveyAnswersSummary.AddNewAnswer(surveyAnswer.ToSurveyAnswer()); transaction.StringSetAsync(surveyAnswer.SlugName, JsonConvert.SerializeObject(surveyAnswersSummary)); //This is a simple implementation of optimistic concurrency. //If transaction fails, another user must have edited the same survey. //If so, try to process this survey answer again. //Another approach is to store each survey answer option as a separate hash in Redis and simply increment //the hash value. This technique will not cause collisions with other threads but will require a redesign of //how survey answer summaries are stored in redis. This approach is left to the reader to implement. success = await transaction.ExecuteAsync(); } while (!success); } catch (Exception ex) { ServiceEventSource.Current.ServiceRequestFailed(ex.ToString()); throw new SurveyAnalysisServiceException(); } }
public void GetSurveyAnswersSummaryReturnsSumamryReadFromBlobContainer() { var mockSurveyAnswersSummaryBlobContainer = new Mock <IAzureBlobContainer <SurveyAnswersSummary> >(); var store = new SurveyAnswersSummaryStore(mockSurveyAnswersSummaryBlobContainer.Object); var surveyAnswersSummary = new SurveyAnswersSummary(); mockSurveyAnswersSummaryBlobContainer.Setup(c => c.Get("tenant-slug-name")).Returns(surveyAnswersSummary); SurveyAnswersSummary actualSurveyAnswersSummary = store.GetSurveyAnswersSummary("tenant", "slug-name"); Assert.AreSame(surveyAnswersSummary, actualSurveyAnswersSummary); }
public void SaveSurveyAnswersSummarySavesBlob() { var mockSurveyAnswersSummaryBlobContainer = new Mock<IAzureBlobContainer<SurveyAnswersSummary>>(); var store = new SurveyAnswersSummaryStore(mockSurveyAnswersSummaryBlobContainer.Object); var surveyAnswersSummary = new SurveyAnswersSummary { Tenant = "tenant", SlugName = "slug-name" }; store.SaveSurveyAnswersSummary(surveyAnswersSummary); mockSurveyAnswersSummaryBlobContainer.Verify( c => c.Save("tenant-slug-name", surveyAnswersSummary), Times.Once()); }
public void MergeThrowsWhenTenantsAreNotEqual() { var existingSurveyAnswersSummary = new SurveyAnswersSummary { Tenant = "tenant" }; var newSurveyAnswersSummary = new SurveyAnswersSummary { Tenant = "other tenant" }; existingSurveyAnswersSummary.MergeWith(newSurveyAnswersSummary); }
public void MergeThrowsWhenSlugNamesAreNotEqual() { var existingSurveyAnswersSummary = new SurveyAnswersSummary { SlugName = "slug-name" }; var newSurveyAnswersSummary = new SurveyAnswersSummary { SlugName = "other-slug-name" }; existingSurveyAnswersSummary.MergeWith(newSurveyAnswersSummary); }
public async Task <SurveyAnswersSummary> GetSurveyAnswersSummaryAsync(string slugName) { SurveyAnswersSummary summary = null; HttpResponseMessage response = await httpClient.GetAsync($"api/Analysis/Summaries/{slugName}"); response.EnsureSuccessStatusCode(); string content = await response.Content.ReadAsStringAsync(); summary = JsonConvert.DeserializeObject <SurveyAnswersSummary>(content); return(summary); }
public void SaveSurveyAnswersSummarySavesBlob() { var mockSurveyAnswersSummaryBlobContainer = new Mock <IAzureBlobContainer <SurveyAnswersSummary> >(); var store = new SurveyAnswersSummaryStore(mockSurveyAnswersSummaryBlobContainer.Object); var surveyAnswersSummary = new SurveyAnswersSummary { Tenant = "tenant", SlugName = "slug-name" }; store.SaveSurveyAnswersSummary(surveyAnswersSummary); mockSurveyAnswersSummaryBlobContainer.Verify( c => c.Save("tenant-slug-name", surveyAnswersSummary), Times.Once()); }
public void AnalyzeReturnsTheSummaryGetFromTheStoreInTheModel() { var mockSurveyAnswersSummaryStore = new Mock <ISurveyAnswersSummaryStore>(); var surveyAnswersSummary = new SurveyAnswersSummary(); mockSurveyAnswersSummaryStore.Setup(r => r.GetSurveyAnswersSummary(It.IsAny <string>(), It.IsAny <string>())) .Returns(surveyAnswersSummary); using (var controller = new SurveysController(null, null, mockSurveyAnswersSummaryStore.Object, null, null)) { var result = controller.Analyze(string.Empty, string.Empty) as ViewResult; var model = result.ViewData.Model as TenantPageViewData <SurveyAnswersSummary>; Assert.AreSame(surveyAnswersSummary, model.ContentModel); } }
public void MergeCopiesTotalAnswersWhenThereAreNoPreviousAnswers() { var existingSurveyAnswersSummary = new SurveyAnswersSummary { TotalAnswers = 0 }; var newSurveyAnswersSummary = new SurveyAnswersSummary { TotalAnswers = 1 }; newSurveyAnswersSummary.QuestionAnswersSummaries.Add(new QuestionAnswersSummary()); existingSurveyAnswersSummary.MergeWith(newSurveyAnswersSummary); Assert.AreEqual(1, existingSurveyAnswersSummary.TotalAnswers); }
public void MergeMultipleChoiceAnswersFor2DifferentAnswers() { var existingSurveyAnswersSummary = new SurveyAnswersSummary { TotalAnswers = 1 }; var existingQuestionAnswersSummary = new QuestionAnswersSummary { QuestionType = QuestionType.MultipleChoice, AnswersSummary = new JavaScriptSerializer().Serialize(new Dictionary <string, int> { { "choice 1", 1 } }), QuestionText = "question to merge" }; existingSurveyAnswersSummary.QuestionAnswersSummaries.Add(existingQuestionAnswersSummary); var newSurveyAnswersSummary = new SurveyAnswersSummary { TotalAnswers = 1 }; var newQuestionAnswersSummary = new QuestionAnswersSummary { QuestionType = QuestionType.MultipleChoice, AnswersSummary = new JavaScriptSerializer().Serialize(new Dictionary <string, int> { { "choice 2", 1 } }), QuestionText = "question to merge" }; newSurveyAnswersSummary.QuestionAnswersSummaries.Add(newQuestionAnswersSummary); existingSurveyAnswersSummary.MergeWith(newSurveyAnswersSummary); Assert.AreEqual(2, existingSurveyAnswersSummary.TotalAnswers); Assert.AreEqual(1, existingSurveyAnswersSummary.QuestionAnswersSummaries.Count); var questionAnswersSummary = existingSurveyAnswersSummary.QuestionAnswersSummaries.First(); Assert.AreEqual("question to merge", questionAnswersSummary.QuestionText); Assert.AreEqual(QuestionType.MultipleChoice, questionAnswersSummary.QuestionType); var actualSummary = new JavaScriptSerializer().Deserialize <Dictionary <string, int> >(questionAnswersSummary.AnswersSummary); Assert.AreEqual(2, actualSummary.Keys.Count); Assert.AreEqual(1, actualSummary["choice 1"]); Assert.AreEqual(1, actualSummary["choice 2"]); }
public void Merge5StarsAnswersCalculatesRatingAverageFor3Answers() { var existingSurveyAnswersSummary = new SurveyAnswersSummary { TotalAnswers = 2 }; var existingQuestionAnswersSummary = new QuestionAnswersSummary { QuestionType = QuestionType.FiveStars, AnswersSummary = "1", QuestionText = "question to merge" }; existingSurveyAnswersSummary.QuestionAnswersSummaries.Add(existingQuestionAnswersSummary); var newSurveyAnswersSummary = new SurveyAnswersSummary { TotalAnswers = 1 }; var newQuestionAnswersSummary = new QuestionAnswersSummary { QuestionType = QuestionType.FiveStars, AnswersSummary = "2", QuestionText = "question to merge" }; newSurveyAnswersSummary.QuestionAnswersSummaries.Add(newQuestionAnswersSummary); existingSurveyAnswersSummary.MergeWith(newSurveyAnswersSummary); Assert.AreEqual(3, existingSurveyAnswersSummary.TotalAnswers); Assert.AreEqual(1, existingSurveyAnswersSummary.QuestionAnswersSummaries.Count); var questionAnswersSummary = existingSurveyAnswersSummary.QuestionAnswersSummaries.First(); Assert.AreEqual("question to merge", questionAnswersSummary.QuestionText); Assert.AreEqual(QuestionType.FiveStars, questionAnswersSummary.QuestionType); Assert.AreEqual("1.33", questionAnswersSummary.AnswersSummary); }
public void AnalyzeReturnsTheSummaryGetFromTheStoreInTheModel() { var mockSurveyAnswersSummaryStore = new Mock<ISurveyAnswersSummaryStore>(); var surveyAnswersSummary = new SurveyAnswersSummary(); mockSurveyAnswersSummaryStore.Setup(r => r.GetSurveyAnswersSummary(It.IsAny<string>(), It.IsAny<string>())) .Returns(surveyAnswersSummary); using (var controller = new SurveysController(null, null, mockSurveyAnswersSummaryStore.Object, null, null, null)) { var result = controller.Analyze(string.Empty, string.Empty) as ViewResult; var model = result.ViewData.Model as TenantPageViewData<SurveyAnswersSummary>; Assert.AreSame(surveyAnswersSummary, model.ContentModel); } }
public override void MergeWith(SurveyAnswersSummary surveyAnswersSummary) { this.MergeParameter = surveyAnswersSummary; }
public void MergeMultipleChoiceAnswersFor2SameAnswers() { var existingSurveyAnswersSummary = new SurveyAnswersSummary { TotalAnswers = 1 }; var existingQuestionAnswersSummary = new QuestionAnswersSummary { QuestionType = QuestionType.MultipleChoice, AnswersSummary = new JavaScriptSerializer().Serialize(new Dictionary<string, int> { { "choice 1", 1 } }), QuestionText = "question to merge" }; existingSurveyAnswersSummary.QuestionAnswersSummaries.Add(existingQuestionAnswersSummary); var newSurveyAnswersSummary = new SurveyAnswersSummary { TotalAnswers = 1 }; var newQuestionAnswersSummary = new QuestionAnswersSummary { QuestionType = QuestionType.MultipleChoice, AnswersSummary = new JavaScriptSerializer().Serialize(new Dictionary<string, int> { { "choice 1", 1 } }), QuestionText = "question to merge" }; newSurveyAnswersSummary.QuestionAnswersSummaries.Add(newQuestionAnswersSummary); existingSurveyAnswersSummary.MergeWith(newSurveyAnswersSummary); Assert.AreEqual(2, existingSurveyAnswersSummary.TotalAnswers); Assert.AreEqual(1, existingSurveyAnswersSummary.QuestionAnswersSummaries.Count); var questionAnswersSummary = existingSurveyAnswersSummary.QuestionAnswersSummaries.First(); Assert.AreEqual("question to merge", questionAnswersSummary.QuestionText); Assert.AreEqual(QuestionType.MultipleChoice, questionAnswersSummary.QuestionType); var actualSummary = new JavaScriptSerializer().Deserialize<Dictionary<string, int>>(questionAnswersSummary.AnswersSummary); Assert.AreEqual(1, actualSummary.Keys.Count); Assert.AreEqual(2, actualSummary["choice 1"]); }
public void SaveSurveyAnswersSummary(SurveyAnswersSummary surveyAnswersSummary) { var id = string.Format(CultureInfo.InvariantCulture, "{0}-{1}", surveyAnswersSummary.Tenant, surveyAnswersSummary.SlugName); this.surveyAnswersSummaryBlobContainer.Save(id, surveyAnswersSummary); }
public void Merge5StarsAnswersCalculatesRatingAverageFor2Answers() { var existingSurveyAnswersSummary = new SurveyAnswersSummary { TotalAnswers = 1 }; var existingQuestionAnswersSummary = new QuestionAnswersSummary { QuestionType = QuestionType.FiveStars, AnswersSummary = "1", QuestionText = "question to merge" }; existingSurveyAnswersSummary.QuestionAnswersSummaries.Add(existingQuestionAnswersSummary); var newSurveyAnswersSummary = new SurveyAnswersSummary { TotalAnswers = 1 }; var newQuestionAnswersSummary = new QuestionAnswersSummary { QuestionType = QuestionType.FiveStars, AnswersSummary = "2", QuestionText = "question to merge" }; newSurveyAnswersSummary.QuestionAnswersSummaries.Add(newQuestionAnswersSummary); existingSurveyAnswersSummary.MergeWith(newSurveyAnswersSummary); Assert.AreEqual(2, existingSurveyAnswersSummary.TotalAnswers); Assert.AreEqual(1, existingSurveyAnswersSummary.QuestionAnswersSummaries.Count); var questionAnswersSummary = existingSurveyAnswersSummary.QuestionAnswersSummaries.First(); Assert.AreEqual("question to merge", questionAnswersSummary.QuestionText); Assert.AreEqual(QuestionType.FiveStars, questionAnswersSummary.QuestionType); Assert.AreEqual("1.50", questionAnswersSummary.AnswersSummary); }
public async Task SaveSurveyAnswersSummaryAsync(SurveyAnswersSummary surveyAnswersSummary) { var id = string.Format(CultureInfo.InvariantCulture, "{0}-{1}", surveyAnswersSummary.Tenant, surveyAnswersSummary.SlugName); await this.surveyAnswersSummaryBlobContainer.SaveAsync(id, surveyAnswersSummary).ConfigureAwait(false); }