212 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			212 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using System.Collections.Generic; | ||
|  | using System.Linq; | ||
|  | using NUnit.Framework; | ||
|  | using Unity.Multiplayer.Center.Analytics; | ||
|  | using Unity.Multiplayer.Center.Common; | ||
|  | using Unity.Multiplayer.Center.Recommendations; | ||
|  | 
 | ||
|  | namespace Unity.MultiplayerCenterTests | ||
|  | { | ||
|  |     [TestFixture] | ||
|  |     internal class AnalyticsUtilsTests | ||
|  |     { | ||
|  |         [Test] | ||
|  |         public void AnalyticsUtils_GetQuestionDisplayNames_RightCount() | ||
|  |         { | ||
|  |             var questionnaire = UtilsForRecommendationTests.GetProjectQuestionnaire(); | ||
|  |             var questionDisplayNames = AnalyticsUtils.GetQuestionDisplayNames(questionnaire); | ||
|  |             Assert.AreEqual(questionDisplayNames.Count, questionnaire.Questions.Length); | ||
|  |         } | ||
|  |          | ||
|  |         /// <summary> | ||
|  |         /// Note: this test checks exact values and has to be adapted in case those display names change. | ||
|  |         /// Why do that? To force the developers to think about the impact on the analytics! | ||
|  |         /// Contact the engine-data team and product. | ||
|  |         /// </summary> | ||
|  |         [Test] | ||
|  |         public void AnalyticsUtils_GetQuestionDisplayNames_RightValuesForSelectedQuestions() | ||
|  |         { | ||
|  |             var questionnaire = UtilsForRecommendationTests.GetProjectQuestionnaire(); | ||
|  |             var questionDisplayNames = AnalyticsUtils.GetQuestionDisplayNames(questionnaire); | ||
|  |             Assert.AreEqual("Number of Players per Session", questionDisplayNames["PlayerCount"]); | ||
|  |             Assert.AreEqual("Gameplay Pace", questionDisplayNames["Pace"]); | ||
|  |             Assert.AreEqual("Cheating / Modding Prevention", questionDisplayNames["Cheating"]); | ||
|  |             Assert.AreEqual("Cost Sensitivity", questionDisplayNames["CostSensitivity"]); | ||
|  |             Assert.AreEqual("Netcode Architecture", questionDisplayNames["NetcodeArchitecture"]); | ||
|  |         } | ||
|  |          | ||
|  |         [Test] | ||
|  |         public void AnalyticsUtils_GetAnswerDisplayNames_RightCount() | ||
|  |         { | ||
|  |             var questionnaire = UtilsForRecommendationTests.GetProjectQuestionnaire(); | ||
|  |             var answerDisplayNames = AnalyticsUtils.GetAnswerDisplayNames(questionnaire); | ||
|  |              | ||
|  |             // Note: 2 birds one stone: this test also nicely checks if we have duplicates with question ids | ||
|  |             var expectedCount = questionnaire.Questions.Sum(question => question.Choices.Length); | ||
|  |             Assert.AreEqual(answerDisplayNames.Count, expectedCount); | ||
|  |         } | ||
|  |          | ||
|  |         [Test] | ||
|  |         public void AnalyticsUtils_GetPresetFullNames_RightCountAndIntValuesDidNotChange() | ||
|  |         { | ||
|  |             var presetFullNames = AnalyticsUtils.GetPresetFullNames(); | ||
|  |             Assert.AreEqual(12, presetFullNames.Length); | ||
|  |         } | ||
|  |          | ||
|  |         /// <summary> | ||
|  |         /// Note: this test checks exact values and has to be adapted in case those display names change. | ||
|  |         /// Why do that? To force the developers to think about the impact on the analytics! | ||
|  |         /// Contact the engine-data team and product. | ||
|  |         /// </summary> | ||
|  |         [Test] | ||
|  |         public void AnalyticsUtils_GetPresetFullNames_RightValues() | ||
|  |         { | ||
|  |             var presetFullNames = AnalyticsUtils.GetPresetFullNames(); | ||
|  |             Assert.AreEqual("-", presetFullNames[0]); | ||
|  |             Assert.AreEqual("Adventure", presetFullNames[1]); | ||
|  |             Assert.AreEqual("Shooter, Battle Royale, Battle Arena", presetFullNames[2]); | ||
|  |             Assert.AreEqual("Racing", presetFullNames[3]); | ||
|  |             Assert.AreEqual("Card Battle, Turn-based, Tabletop", presetFullNames[4]); | ||
|  |             Assert.AreEqual("Simulation", presetFullNames[5]); | ||
|  |             Assert.AreEqual("Strategy", presetFullNames[6]); | ||
|  |             Assert.AreEqual("Sports", presetFullNames[7]); | ||
|  |             Assert.AreEqual("Role-Playing, MMO", presetFullNames[8]); | ||
|  |             Assert.AreEqual("Async, Idle, Hyper Casual, Puzzle", presetFullNames[9]); | ||
|  |             Assert.AreEqual("Fighting", presetFullNames[10]); | ||
|  |             Assert.AreEqual("Arcade, Platformer, Sandbox", presetFullNames[11]); | ||
|  |         } | ||
|  |          | ||
|  |         [Test] | ||
|  |         public void AnalyticsUtils_ToGameSpecs_AllIdsAreInTheGameSpecs() | ||
|  |         { | ||
|  |             var questionnaire = UtilsForRecommendationTests.GetProjectQuestionnaire(); | ||
|  |             var answerDisplayNames = AnalyticsUtils.GetAnswerDisplayNames(questionnaire); | ||
|  |             var answerData = UtilsForRecommendationTests.BuildAnswerMatching(questionnaire); | ||
|  |             var questionIdToQuestionName = AnalyticsUtils.GetQuestionDisplayNames(questionnaire); | ||
|  |             var gameSpecs = AnalyticsUtils.ToGameSpecs(answerData, answerDisplayNames, questionIdToQuestionName); | ||
|  |             Assert.AreEqual(answerData.Answers.Count, gameSpecs.Length); | ||
|  |              | ||
|  |             var questionIdsFromAnswerData = answerData.Answers.Select(answer => answer.QuestionId).ToArray(); | ||
|  |             var questionIdsFromGameSpecs = gameSpecs.Select(spec => spec.QuestionId).ToArray(); | ||
|  |             CollectionAssert.AreEquivalent(questionIdsFromAnswerData, questionIdsFromGameSpecs); | ||
|  |         } | ||
|  | 
 | ||
|  |         [Test] | ||
|  |         public void AnalyticsUtils_ToGameSpecs_ValueCheck() | ||
|  |         { | ||
|  |             var answerDisplayNames = new Dictionary<string, string>(){ | ||
|  |                 {"A1", "Display Name A1"}, | ||
|  |                 {"A2", "Display Name A2"}, | ||
|  |                 {"A3", "Display Name A3"}, | ||
|  |                 {"A4", "Display Name A4"} | ||
|  |             }; | ||
|  |             var questionIdToQuestionName = new Dictionary<string, string>() | ||
|  |             { | ||
|  |                 {"Q1", "Display Name Q1"}, | ||
|  |                 {"Q2", "Display Name Q2"} | ||
|  |             }; | ||
|  |             var answerData = new AnswerData() | ||
|  |             { | ||
|  |                 Answers = new List<AnsweredQuestion>() | ||
|  |                 { | ||
|  |                     new() {QuestionId = "Q2", Answers = new List<string>() {"A3"}}, | ||
|  |                     new() {QuestionId = "Q1", Answers = new List<string>() {"A1"}} | ||
|  |                 } | ||
|  |             }; | ||
|  |             var gameSpecs = AnalyticsUtils.ToGameSpecs(answerData, answerDisplayNames, questionIdToQuestionName); | ||
|  | 
 | ||
|  |             var expectedGameSpecs = new GameSpec[] | ||
|  |             { | ||
|  |                 new (){ QuestionId = "Q2", QuestionText = "Display Name Q2", AcceptsMultipleAnswers = false, AnswerId = "A3", AnswerText = "Display Name A3"}, | ||
|  |                 new (){ QuestionId = "Q1", QuestionText = "Display Name Q1", AcceptsMultipleAnswers = false, AnswerId = "A1", AnswerText = "Display Name A1"}, | ||
|  |             }; | ||
|  |             CollectionAssert.AreEquivalent(expectedGameSpecs, gameSpecs); | ||
|  |         } | ||
|  | 
 | ||
|  |         [Test] | ||
|  |         public void AnalyticsUtils_ToGameSpecs_NoEmptyString() | ||
|  |         { | ||
|  |             GetAnswersWithMatchingAnalyticsData(out var _, out var gameSpecs); | ||
|  |             foreach (var spec in gameSpecs) | ||
|  |             { | ||
|  |                 Assert.False(string.IsNullOrEmpty(spec.QuestionId), spec.QuestionId); | ||
|  |                 Assert.False(string.IsNullOrEmpty(spec.QuestionText), spec.QuestionText); | ||
|  |                 Assert.False(string.IsNullOrEmpty(spec.AnswerId), spec.AnswerId); | ||
|  |                 Assert.False(string.IsNullOrEmpty(spec.AnswerText), spec.AnswerText); | ||
|  |             } | ||
|  |         } | ||
|  |          | ||
|  |         [Test] | ||
|  |         public void AnalyticsUtils_AssumptionTest_HardCodedNumNetcodePackageMatchesRecommendations() | ||
|  |         { | ||
|  |             // note that the amount of possible netcode does not change with the answer data. | ||
|  |             var someRecommendation = UtilsForRecommendationTests.GetSomeRecommendation(); | ||
|  |             var netcodePackageCount = someRecommendation.NetcodeOptions.Count(e | ||
|  |                 => !string.IsNullOrEmpty(e.MainPackage?.PackageId)); | ||
|  |              | ||
|  |             Assert.AreEqual(netcodePackageCount, AnalyticsUtils.NumNetcodePackage); | ||
|  |         } | ||
|  |          | ||
|  |         [Test] | ||
|  |         public void AnalyticsUtils_AssumptionTest_HardCodedNumHostingPackageMatchesRecommendations() | ||
|  |         { | ||
|  |             // note that the amount of possible netcode does not change with the answer data. | ||
|  |             var someRecommendation = UtilsForRecommendationTests.GetSomeRecommendation(); | ||
|  |             var hostingPackageCount = someRecommendation.ServerArchitectureOptions.Count(e | ||
|  |                 => !string.IsNullOrEmpty(e.MainPackage?.PackageId)); | ||
|  |              | ||
|  |             Assert.AreEqual(hostingPackageCount, AnalyticsUtils.NumHostingPackages); | ||
|  |         } | ||
|  | 
 | ||
|  |         [Test] | ||
|  |         public void AnalyticsUtils_GetPackagesWithAnalyticsFormat_NetcodeValuesMakeSense() | ||
|  |         { | ||
|  |             const string ngo = "com.unity.netcode.gameobjects"; | ||
|  |             const string n4e = "com.unity.netcode"; | ||
|  |             const string tp = "com.unity.transport"; | ||
|  |              | ||
|  |             var someRecommendation = UtilsForRecommendationTests.GetSomeRecommendation(); | ||
|  |             var packageViews = RecommenderSystem.GetSolutionsToRecommendedPackageViewData(); | ||
|  |             var packagesAnalyticsFormat = AnalyticsUtils.GetPackagesWithAnalyticsFormat(someRecommendation, packageViews); | ||
|  | 
 | ||
|  |             // all netcode packages are in the array | ||
|  |             Assert.AreEqual(1,packagesAnalyticsFormat.Count(e => e.PackageId == ngo) ); | ||
|  |             Assert.AreEqual(1, packagesAnalyticsFormat.Count(e => e.PackageId == n4e)); | ||
|  |             Assert.AreEqual(1, packagesAnalyticsFormat.Count(e => e.PackageId == tp)); | ||
|  |              | ||
|  |             var netcodePackages = packagesAnalyticsFormat.Where(e => e.PackageId is ngo or n4e or tp).ToArray(); | ||
|  |             Assert.AreEqual(3, netcodePackages.Count()); // exactly 3 matches | ||
|  |             Assert.AreEqual(1, netcodePackages.Count(e => e.SelectedForInstall)); // 1 selected | ||
|  |             Assert.AreEqual(1, netcodePackages.Count(e => e.IsRecommended)); // 1 recommended | ||
|  |              | ||
|  |             // Since we only look at the project direct dependencies, 1 netcode max can be installed in a normal setup | ||
|  |             // edge case would be: some installed ngo/n4e and manually added Transport to the manifest | ||
|  |             Assert.True(netcodePackages.Count(e => e.IsAlreadyInstalled) <= 1); | ||
|  |         } | ||
|  | 
 | ||
|  |         [Test] | ||
|  |         public void AnalyticsUtils_GetPackagesWithAnalyticsFormat_AllPackagesAreIn() | ||
|  |         { | ||
|  |             var someRecommendation = UtilsForRecommendationTests.GetSomeRecommendation(); | ||
|  |             var packageViews = RecommenderSystem.GetSolutionsToRecommendedPackageViewData(); | ||
|  |             var packagesAnalyticsFormat = AnalyticsUtils.GetPackagesWithAnalyticsFormat(someRecommendation, packageViews); | ||
|  |              | ||
|  |             var allPackages = RecommenderSystemDataObject.instance.RecommenderSystemData.PackageDetailsById.Keys; | ||
|  |              | ||
|  |             foreach (var id in allPackages) | ||
|  |             { | ||
|  |                 Assert.AreEqual(1, packagesAnalyticsFormat.Count(e => e.PackageId == id), id); | ||
|  |             } | ||
|  |         } | ||
|  |          | ||
|  |         static void GetAnswersWithMatchingAnalyticsData(out AnswerData answerData, out GameSpec[] gameSpecs) | ||
|  |         { | ||
|  |             var questionnaire = UtilsForRecommendationTests.GetProjectQuestionnaire(); | ||
|  |             var answerDisplayNames = AnalyticsUtils.GetAnswerDisplayNames(questionnaire); | ||
|  |             answerData = UtilsForRecommendationTests.BuildAnswerMatching(questionnaire); | ||
|  |             var questionIdToQuestionName = AnalyticsUtils.GetQuestionDisplayNames(questionnaire); | ||
|  |             gameSpecs = AnalyticsUtils.ToGameSpecs(answerData, answerDisplayNames, questionIdToQuestionName); | ||
|  |         } | ||
|  |     } | ||
|  | } |