public async Task GetExposureRiskConfigurationTest_preferCache() { string existConfigurationJson = GetTestJson(JSON_EXPOSURE_RISK_CONFIGURATION1); File.WriteAllText(CURRENT_EXPOSURE_RISK_CONFIGURATION_FILE_PATH, existConfigurationJson); V1ExposureRiskCalculationConfiguration expect = JsonConvert.DeserializeObject <V1ExposureRiskCalculationConfiguration>(existConfigurationJson); string newConfigurationJson = GetTestJson(JSON_EXPOSURE_RISK_CONFIGURATION2); var jsonContent = new StringContent( newConfigurationJson, Encoding.UTF8, "application/json" ); var client = HttpClientUtils.CreateHttpClient(HttpStatusCode.OK, jsonContent); mockClientService.Setup(x => x.Create()).Returns(client); mockLocalPathService.Setup(x => x.ExposureConfigurationDirPath).Returns("./"); mockLocalPathService.Setup(x => x.CurrentExposureRiskCalculationConfigurationPath).Returns(CURRENT_EXPOSURE_RISK_CONFIGURATION_FILE_PATH); mockServerConfigurationRepository.Setup(x => x.ExposureRiskCalculationConfigurationUrl).Returns("https://example.com/exposure_risk_configuration.json"); var unitUnderTest = CreateRepository(); var result = await unitUnderTest.GetExposureRiskCalculationConfigurationAsync(preferCache : true); mockServerConfigurationRepository.Verify(s => s.LoadAsync(), Times.Never()); Assert.NotNull(result); Assert.Equal(result, expect); }
public override async void Initialize(INavigationParameters parameters) { base.Initialize(parameters); _loggerService.StartMethod(); _exposureRiskCalculationConfiguration = parameters.GetValue <V1ExposureRiskCalculationConfiguration>(ExposureCheckPage.ExposureRiskCalculationConfigurationKey); if (_exposureRiskCalculationConfiguration is null) { _exposureRiskCalculationConfiguration = await _exposureRiskCalculationConfigurationRepository.GetExposureRiskCalculationConfigurationAsync(preferCache : true); } _loggerService.Info(_exposureRiskCalculationConfiguration.ToString()); ShowExposureRiskCalculationConfiguration(); try { // 一時的に閾値未満の内容は表示しないようにするためコメントアウト //_ = Setup(); } catch (Exception exception) { _loggerService.Exception("Exception occurred", exception); } finally { _loggerService.EndMethod(); } }
public void RiskExposureTest_AND2() { var configuration = new V1ExposureRiskCalculationConfiguration() { DailySummary_DaySummary_ScoreSum = new V1ExposureRiskCalculationConfiguration.Threshold() { Op = V1ExposureRiskCalculationConfiguration.Threshold.OPERATION_GREATER_EQUAL, Value = 1170.0 }, ExposureWindow_ScanInstance_SecondsSinceLastScanSum = new V1ExposureRiskCalculationConfiguration.Threshold() { Op = V1ExposureRiskCalculationConfiguration.Threshold.OPERATION_GREATER_EQUAL, Value = 900.0 }, }; var dailySummary = new DailySummary() { DateMillisSinceEpoch = 0, DaySummary = new ExposureSummaryData() { ScoreSum = 1170.0 }, ConfirmedClinicalDiagnosisSummary = new ExposureSummaryData(), ConfirmedTestSummary = new ExposureSummaryData(), RecursiveSummary = new ExposureSummaryData(), SelfReportedSummary = new ExposureSummaryData() }; var exposureWindows = new List <ExposureWindow>() { new ExposureWindow() { CalibrationConfidence = CalibrationConfidence.High, DateMillisSinceEpoch = 0, Infectiousness = Infectiousness.High, ReportType = ReportType.Unknown, ScanInstances = new List <ScanInstance>() { new ScanInstance() { SecondsSinceLastScan = 600, TypicalAttenuationDb = 1 }, new ScanInstance() { SecondsSinceLastScan = 240, TypicalAttenuationDb = 10 } } } }; IExposureRiskCalculationService service = CreateService(); RiskLevel result = service.CalcRiskLevel(dailySummary, exposureWindows, configuration); Assert.Equal(RiskLevel.Low, result); }
public RiskLevel CalcRiskLevel( DailySummary dailySummary, List <ExposureWindow> exposureWindowList, V1ExposureRiskCalculationConfiguration configuration ) { if ( configuration.DailySummary_DaySummary_ScoreSum.Op == Threshold.OPERATION_NOP && configuration.DailySummary_WeightedDurationAverage.Op == Threshold.OPERATION_NOP && configuration.ExposureWindow_ScanInstance_SecondsSinceLastScanSum.Op == Threshold.OPERATION_NOP && configuration.ExposureWindow_ScanInstance_TypicalAttenuationDb_Max.Op == Threshold.OPERATION_NOP && configuration.ExposureWindow_ScanInstance_TypicalAttenuationDb_Min.Op == Threshold.OPERATION_NOP ) { _loggerService.Info("All conditions are NOP."); return(RiskLevel.Low); } var allScanInstances = exposureWindowList .SelectMany(ew => ew.ScanInstances); double secondsSinceLastScanSum = allScanInstances .Sum(si => si.SecondsSinceLastScan); double weightedDurationAverage = 0; if (secondsSinceLastScanSum > 0) { weightedDurationAverage = dailySummary.DaySummary.WeightedDurationSum / secondsSinceLastScanSum; } double typicalAttenuationDbMax = 0; if (allScanInstances.Count() > 0) { typicalAttenuationDbMax = allScanInstances.Max(si => si.TypicalAttenuationDb); } double typicalAttenuationDbMin = 0; if (allScanInstances.Count() > 0) { typicalAttenuationDbMin = allScanInstances.Min(si => si.TypicalAttenuationDb); } // AND if (configuration.DailySummary_DaySummary_ScoreSum.Cond(dailySummary.DaySummary.ScoreSum) && configuration.DailySummary_WeightedDurationAverage.Cond(weightedDurationAverage) && configuration.ExposureWindow_ScanInstance_SecondsSinceLastScanSum.Cond(secondsSinceLastScanSum) && configuration.ExposureWindow_ScanInstance_TypicalAttenuationDb_Max.Cond(typicalAttenuationDbMax) && configuration.ExposureWindow_ScanInstance_TypicalAttenuationDb_Min.Cond(typicalAttenuationDbMin) ) { return(RiskLevel.High); } return(RiskLevel.Low); }
private (List <DailySummary>, List <ExposureWindow>) GenerateDummyLowRiskData( V1ExposureRiskCalculationConfiguration config ) { var dailySummaries = new List <DailySummary>() { new DailySummary() { DateMillisSinceEpoch = GetDateTimeUnixEpochInMillis(-1), DaySummary = new ExposureSummaryData() { ScoreSum = 1 } }, new DailySummary() { DateMillisSinceEpoch = GetDateTimeUnixEpochInMillis(-2), DaySummary = new ExposureSummaryData() { ScoreSum = config.DailySummary_DaySummary_ScoreSum.Value - 1 } }, }; int secondsSinceLastScanSumThreshold = (int)Math.Round(config.ExposureWindow_ScanInstance_SecondsSinceLastScanSum.Value); var exposureWindows = new List <ExposureWindow>() { new ExposureWindow() { DateMillisSinceEpoch = GetDateTimeUnixEpochInMillis(-1), ScanInstances = new List <ScanInstance>() { new ScanInstance() { SecondsSinceLastScan = 1, }, } }, new ExposureWindow() { DateMillisSinceEpoch = GetDateTimeUnixEpochInMillis(-2), ScanInstances = new List <ScanInstance>() { new ScanInstance() { SecondsSinceLastScan = secondsSinceLastScanSumThreshold - 1, }, } }, }; return(dailySummaries, exposureWindows); }
public static INavigationParameters BuildNavigationParams( V1ExposureRiskCalculationConfiguration exposureRiskCalculationConfiguration, INavigationParameters?baseParam = null ) { var param = new NavigationParameters(); param.CopyFrom(baseParam); param.Add(ExposureRiskCalculationConfigurationKey, exposureRiskCalculationConfiguration); return(param); }
public void RiskExposureTest_AllNOP() { var configuration = new V1ExposureRiskCalculationConfiguration() { // All conditions are NOP }; var dailySummary = new DailySummary() { DateMillisSinceEpoch = 0, DaySummary = new ExposureSummaryData() { ScoreSum = 2000.0 }, ConfirmedClinicalDiagnosisSummary = new ExposureSummaryData(), ConfirmedTestSummary = new ExposureSummaryData(), RecursiveSummary = new ExposureSummaryData(), SelfReportedSummary = new ExposureSummaryData() }; var exposureWindows = new List <ExposureWindow>() { new ExposureWindow() { CalibrationConfidence = CalibrationConfidence.High, DateMillisSinceEpoch = 0, Infectiousness = Infectiousness.High, ReportType = ReportType.Unknown, ScanInstances = new List <ScanInstance>() { new ScanInstance() { SecondsSinceLastScan = 600, TypicalAttenuationDb = 1 }, new ScanInstance() { SecondsSinceLastScan = 600, TypicalAttenuationDb = 10 } } } }; IExposureRiskCalculationService service = CreateService(); RiskLevel result = service.CalcRiskLevel(dailySummary, exposureWindows, configuration); Assert.Equal(RiskLevel.Low, result); }
public void JsonDeserializeTests() { V1ExposureRiskCalculationConfiguration expected = new V1ExposureRiskCalculationConfiguration() { DailySummary_DaySummary_ScoreSum = new V1ExposureRiskCalculationConfiguration.Threshold() { Op = V1ExposureRiskCalculationConfiguration.Threshold.OPERATION_GREATER_EQUAL, Value = 2000.0 } }; var testJson = GetTestJson(JSON_V1_EXPOSURE_RISK_CALCULATION_CONFIGURATION); var deserialized = JsonConvert.DeserializeObject <V1ExposureRiskCalculationConfiguration>(testJson); Assert.NotNull(deserialized); Assert.Equal(expected, deserialized); }
public void JsonSerializeTests() { var expectedJson = GetTestJson(JSON_V1_EXPOSURE_RISK_CALCULATION_CONFIGURATION); V1ExposureRiskCalculationConfiguration configuration = new V1ExposureRiskCalculationConfiguration() { DailySummary_DaySummary_ScoreSum = new V1ExposureRiskCalculationConfiguration.Threshold() { Op = V1ExposureRiskCalculationConfiguration.Threshold.OPERATION_GREATER_EQUAL, Value = 2000.0 } }; var serializedJson = JsonConvert.SerializeObject(configuration); Assert.NotEmpty(serializedJson); Assert.Equal(expectedJson, serializedJson); }
public void RiskExposureTest(string scoreSumOp, double scoreSumValue, double scoreSum, RiskLevel expected) { var configuration = new V1ExposureRiskCalculationConfiguration() { DailySummary_DaySummary_ScoreSum = new V1ExposureRiskCalculationConfiguration.Threshold() { Op = scoreSumOp, Value = scoreSumValue } }; var dailySummary = new DailySummary() { DateMillisSinceEpoch = 0, DaySummary = new ExposureSummaryData() { ScoreSum = scoreSum }, ConfirmedClinicalDiagnosisSummary = new ExposureSummaryData(), ConfirmedTestSummary = new ExposureSummaryData(), RecursiveSummary = new ExposureSummaryData(), SelfReportedSummary = new ExposureSummaryData() }; var exposureWindows = new List <ExposureWindow>() { new ExposureWindow() { CalibrationConfidence = CalibrationConfidence.High, DateMillisSinceEpoch = 0, Infectiousness = Infectiousness.High, ReportType = ReportType.Unknown, ScanInstances = new List <ScanInstance>() } }; IExposureRiskCalculationService service = CreateService(); RiskLevel result = service.CalcRiskLevel(dailySummary, exposureWindows, configuration); Assert.Equal(expected, result); }
public override async void Initialize(INavigationParameters parameters) { base.Initialize(parameters); _loggerService.StartMethod(); _exposureRiskCalculationConfiguration = parameters.GetValue <V1ExposureRiskCalculationConfiguration>(ExposureCheckPage.ExposureRiskCalculationConfigurationKey); ShowExposureRiskCalculationConfiguration(); try { var summaries = await _exposureDataRepository .GetDailySummariesAsync(AppConstants.DaysOfExposureInformationToDisplay); if (0 < summaries.Count()) { IsVisibleLowRiskContact = true; IsVisibleNoRiskContact = false; _ = SetupExposureCheckScoresAsync(summaries); } else { IsVisibleLowRiskContact = false; IsVisibleNoRiskContact = true; } } catch (Exception exception) { _loggerService.Exception("Exception occurred", exception); } finally { _loggerService.EndMethod(); } }
public async Task GetExposureRiskConfigurationTest_not_updated() { string currentConfigurationJson = GetTestJson(JSON_EXPOSURE_RISK_CONFIGURATION1); File.WriteAllText(CURRENT_EXPOSURE_RISK_CONFIGURATION_FILE_PATH, currentConfigurationJson); V1ExposureRiskCalculationConfiguration currentConfiguration = JsonConvert.DeserializeObject <V1ExposureRiskCalculationConfiguration>(currentConfigurationJson); string newConfigurationJson = GetTestJson(JSON_EXPOSURE_RISK_CONFIGURATION2); V1ExposureRiskCalculationConfiguration newConfiguration = JsonConvert.DeserializeObject <V1ExposureRiskCalculationConfiguration>(newConfigurationJson); var jsonContent = new StringContent( newConfigurationJson, Encoding.UTF8, "application/json" ); var client = HttpClientUtils.CreateHttpClient(HttpStatusCode.OK, jsonContent); mockClientService.Setup(x => x.Create()).Returns(client); mockLocalPathService.Setup(x => x.ExposureConfigurationDirPath).Returns("./"); mockLocalPathService.Setup(x => x.CurrentExposureRiskCalculationConfigurationPath).Returns(CURRENT_EXPOSURE_RISK_CONFIGURATION_FILE_PATH); mockServerConfigurationRepository.Setup(x => x.ExposureRiskCalculationConfigurationUrl).Returns("https://example.com/exposure_risk_configuration.json"); var unitUnderTest = CreateRepository(); var result = await unitUnderTest.GetExposureRiskCalculationConfigurationAsync(preferCache : false); result = await unitUnderTest.GetExposureRiskCalculationConfigurationAsync(preferCache : false); mockServerConfigurationRepository.Verify(s => s.LoadAsync(), Times.Exactly(2)); mockLoggerService.Verify(x => x.Info("ExposureRiskCalculationConfiguration have not been changed.", It.IsAny <string>(), It.IsAny <string>(), It.IsAny <int>()), Times.Once); Assert.NotNull(result); Assert.NotEqual(result, currentConfiguration); Assert.Equal(result, newConfiguration); }
public void LowRiskPage_Initialize_Display() { var dummyDailySummaries = new List <DailySummary>() { new DailySummary() { DateMillisSinceEpoch = (new DateTime().AddDays(0).Date).ToUnixEpochMillis(), DaySummary = new ExposureSummaryData() { ScoreSum = 1700 }, }, new DailySummary() { DateMillisSinceEpoch = (new DateTime().AddDays(1).Date).ToUnixEpochMillis(), DaySummary = new ExposureSummaryData() { ScoreSum = 1700 }, }, new DailySummary() { DateMillisSinceEpoch = (new DateTime().AddDays(2).Date).ToUnixEpochMillis(), DaySummary = new ExposureSummaryData() { ScoreSum = 1000 }, }, }; var dummyExposureWindows = new List <ExposureWindow>() { new ExposureWindow() { DateMillisSinceEpoch = (new DateTime().AddDays(0).Date).ToUnixEpochMillis(), ScanInstances = new List <ScanInstance>() { new ScanInstance() { SecondsSinceLastScan = 840, } }, }, new ExposureWindow() { DateMillisSinceEpoch = (new DateTime().AddDays(1).Date).ToUnixEpochMillis(), ScanInstances = new List <ScanInstance>() { new ScanInstance() { SecondsSinceLastScan = 840, } }, }, new ExposureWindow() { DateMillisSinceEpoch = (new DateTime().AddDays(2).Date).ToUnixEpochMillis(), ScanInstances = new List <ScanInstance>() { new ScanInstance() { SecondsSinceLastScan = 900, } }, }, }; mockUserDataRepository .Setup(x => x.GetDaysOfUse()) .Returns(14); mockDateTimeUtility .Setup(x => x.UtcNow) .Returns((new DateTime()).AddDays(14)); mockExposureDataRepository .Setup(x => x.GetDailySummariesAsync(AppConstants.TermOfExposureRecordValidityInDays)) .ReturnsAsync(dummyDailySummaries); mockExposureDataRepository .Setup(x => x.GetExposureWindowsAsync(AppConstants.TermOfExposureRecordValidityInDays)) .ReturnsAsync(dummyExposureWindows); var riskConfiguration = new V1ExposureRiskCalculationConfiguration() { DailySummary_DaySummary_ScoreSum = new Threshold() { Op = Threshold.OPERATION_GREATER_EQUAL, Value = 1170, }, ExposureWindow_ScanInstance_SecondsSinceLastScanSum = new Threshold() { Op = Threshold.OPERATION_GREATER_EQUAL, Value = 900, }, }; var exposureCheckPageViewModel = CreateViewModel(); var parameters = ExposureCheckPage.BuildNavigationParams(riskConfiguration); exposureCheckPageViewModel.Initialize(parameters); Assert.True(exposureCheckPageViewModel.IsExposureDetected); Assert.Equal(14, exposureCheckPageViewModel.ExposureCheckScores.Count()); var dates = Enumerable.Range(0, 14) .Select(offset => new DateTime().AddDays(offset).Date.ToUnixEpochMillis()) .ToList(); dates.Sort((a, b) => b.CompareTo(a)); // Sort DESC for (int i = 0; i < 14; i++) { Assert.Equal(dates[i], exposureCheckPageViewModel.ExposureCheckScores[i].DateMillisSinceEpoch); } Assert.Equal(dummyDailySummaries[2].DateMillisSinceEpoch, exposureCheckPageViewModel.ExposureCheckScores[11].DateMillisSinceEpoch); Assert.True(exposureCheckPageViewModel.ExposureCheckScores[11].IsScoreVisible); Assert.False(exposureCheckPageViewModel.ExposureCheckScores[11].IsDurationTimeVisible); Assert.True(exposureCheckPageViewModel.ExposureCheckScores[11].IsReceived); Assert.Equal(dummyDailySummaries[1].DateMillisSinceEpoch, exposureCheckPageViewModel.ExposureCheckScores[12].DateMillisSinceEpoch); Assert.True(exposureCheckPageViewModel.ExposureCheckScores[12].IsScoreVisible); Assert.True(exposureCheckPageViewModel.ExposureCheckScores[12].IsDurationTimeVisible); Assert.True(exposureCheckPageViewModel.ExposureCheckScores[12].IsReceived); Assert.Equal(dummyDailySummaries[0].DateMillisSinceEpoch, exposureCheckPageViewModel.ExposureCheckScores[13].DateMillisSinceEpoch); Assert.True(exposureCheckPageViewModel.ExposureCheckScores[13].IsScoreVisible); Assert.True(exposureCheckPageViewModel.ExposureCheckScores[13].IsDurationTimeVisible); Assert.True(exposureCheckPageViewModel.ExposureCheckScores[13].IsReceived); }
private async Task <V1ExposureRiskCalculationConfiguration> GetExposureRiskCalculationConfigurationInternalAsync(bool preferCache) { _loggerService.StartMethod(); V1ExposureRiskCalculationConfiguration currentConfiguration = null; if (File.Exists(_currentPath)) { _loggerService.Debug("ExposureConfiguration file is found."); try { string exposureRiskCalculationConfigurationAsJson = await LoadAsync(_currentPath); currentConfiguration = JsonConvert.DeserializeObject <V1ExposureRiskCalculationConfiguration>(exposureRiskCalculationConfigurationAsJson); } catch (IOException exception) { _loggerService.Exception("IOException. ExposureRiskCalculationConfiguration file has been deleted.", exception); RemoveExposureRiskCalculationConfiguration(); } catch (JsonException exception) { _loggerService.Exception("JsonException. ExposureRiskCalculationConfiguration file has been deleted.", exception); RemoveExposureRiskCalculationConfiguration(); } } if (currentConfiguration is null) { currentConfiguration = CreateDefaultConfiguration(); } else if (preferCache) { _loggerService.EndMethod(); return(currentConfiguration); } await _serverConfigurationRepository.LoadAsync(); string url = _serverConfigurationRepository.ExposureRiskCalculationConfigurationUrl; V1ExposureRiskCalculationConfiguration newExposureRiskCalculationConfiguration = null; try { var response = await _httpClient.GetAsync(url); if (response.IsSuccessStatusCode) { string exposureRiskCalculationConfigurationAsJson = await response.Content.ReadAsStringAsync(); _loggerService.Debug(exposureRiskCalculationConfigurationAsJson); newExposureRiskCalculationConfiguration = JsonConvert.DeserializeObject <V1ExposureRiskCalculationConfiguration>(exposureRiskCalculationConfigurationAsJson); } else { _loggerService.Warning($"Download ExposureRiskCalculationConfiguration failed from {url}"); } } catch (JsonException exception) { _loggerService.Exception("JsonException.", exception); } catch (HttpRequestException exception) { _loggerService.Exception("HttpRequestException.", exception); } if (newExposureRiskCalculationConfiguration is null) { _loggerService.EndMethod(); return(currentConfiguration); } if (newExposureRiskCalculationConfiguration.Equals(currentConfiguration)) { _loggerService.Info("ExposureRiskCalculationConfiguration have not been changed."); _loggerService.EndMethod(); return(currentConfiguration); } _loggerService.Info("ExposureRiskCalculationConfiguration have been changed."); string tmpFilePath = Path.Combine(_configDir, Guid.NewGuid().ToString()); try { await SaveAsync( JsonConvert.SerializeObject(newExposureRiskCalculationConfiguration, Formatting.Indented), tmpFilePath ); Swap(tmpFilePath, _currentPath); return(newExposureRiskCalculationConfiguration); } finally { File.Delete(tmpFilePath); _loggerService.EndMethod(); } }
public void LowRiskPage_Initialize_Display() { mockExposureDataRepository .Setup(x => x.GetDailySummariesAsync(AppConstants.DaysOfExposureInformationToDisplay)) .ReturnsAsync(new List <DailySummary>() { new DailySummary() { DateMillisSinceEpoch = (1000 * 60 * 60 * 24), DaySummary = new ExposureSummaryData() { ScoreSum = 1700 }, }, new DailySummary() { DateMillisSinceEpoch = (1000 * 60 * 60 * 24) * 2, DaySummary = new ExposureSummaryData() { ScoreSum = 1700 }, }, new DailySummary() { DateMillisSinceEpoch = (1000 * 60 * 60 * 24) * 3, DaySummary = new ExposureSummaryData() { ScoreSum = 1000 }, }, }); mockExposureDataRepository .Setup(x => x.GetExposureWindowsAsync(AppConstants.DaysOfExposureInformationToDisplay)) .ReturnsAsync(new List <ExposureWindow>() { new ExposureWindow() { DateMillisSinceEpoch = (1000 * 60 * 60 * 24), ScanInstances = new List <ScanInstance>() { new ScanInstance() { SecondsSinceLastScan = 900, } }, }, new ExposureWindow() { DateMillisSinceEpoch = (1000 * 60 * 60 * 24) * 2, ScanInstances = new List <ScanInstance>() { new ScanInstance() { SecondsSinceLastScan = 840, } }, }, new ExposureWindow() { DateMillisSinceEpoch = (1000 * 60 * 60 * 24) * 3, ScanInstances = new List <ScanInstance>() { new ScanInstance() { SecondsSinceLastScan = 840, } }, }, }); var riskConfiguration = new V1ExposureRiskCalculationConfiguration() { DailySummary_DaySummary_ScoreSum = new Threshold() { Op = Threshold.OPERATION_GREATER_EQUAL, Value = 1170, }, ExposureWindow_ScanInstance_SecondsSinceLastScanSum = new Threshold() { Op = Threshold.OPERATION_GREATER_EQUAL, Value = 900, }, }; var exposureCheckPageViewModel = CreateViewModel(); var parameters = ExposureCheckPage.BuildNavigationParams(riskConfiguration); exposureCheckPageViewModel.Initialize(parameters); Assert.True(exposureCheckPageViewModel.IsVisibleLowRiskContact); Assert.False(exposureCheckPageViewModel.IsVisibleNoRiskContact); Assert.Equal(3, exposureCheckPageViewModel.ExposureCheckScores.Count()); // Sort DESC Assert.Equal((1000 * 60 * 60 * 24) * 3, exposureCheckPageViewModel.ExposureCheckScores[0].DateMillisSinceEpoch); Assert.Equal((1000 * 60 * 60 * 24) * 2, exposureCheckPageViewModel.ExposureCheckScores[1].DateMillisSinceEpoch); Assert.Equal(1000 * 60 * 60 * 24, exposureCheckPageViewModel.ExposureCheckScores[2].DateMillisSinceEpoch); Assert.True(exposureCheckPageViewModel.ExposureCheckScores[0].IsScoreVisible); Assert.False(exposureCheckPageViewModel.ExposureCheckScores[0].IsDurationTimeVisible); Assert.True(exposureCheckPageViewModel.ExposureCheckScores[1].IsScoreVisible); Assert.True(exposureCheckPageViewModel.ExposureCheckScores[1].IsDurationTimeVisible); Assert.True(exposureCheckPageViewModel.ExposureCheckScores[2].IsScoreVisible); Assert.False(exposureCheckPageViewModel.ExposureCheckScores[2].IsDurationTimeVisible); }