Skip to content
This repository has been archived by the owner on Apr 12, 2023. It is now read-only.

感染性のある期間を有症状の場合は症状発生から10日、無症状の場合は検査日から7日とする #841

Merged
merged 13 commits into from Mar 17, 2022
3 changes: 2 additions & 1 deletion Covid19Radar/Covid19Radar/Common/DeviceVerifierUtils.cs
Expand Up @@ -29,7 +29,8 @@ public static byte[] CreateAndroidNonceV3(V1EventLogRequest eventLogRequest)

public static string GetNonceClearTextV3(DiagnosisSubmissionParameter submission)
{
return string.Join("|", submission.SymptomOnsetDate, submission.AppPackageName, GetKeyString(submission.Keys), GetRegionString(submission.Regions), submission.VerificationPayload);
string hasSymptom = submission.HasSymptom ? "HasSymptom" : "NoSymptom";
return string.Join("|", submission.AppPackageName, submission.OnsetOfSymptomOrTestDate, hasSymptom, GetKeyString(submission.Keys), GetRegionString(submission.Regions), submission.VerificationPayload);

static string GetKeyString(IEnumerable<DiagnosisSubmissionParameter.Key> keys) =>
string.Join(",", keys.OrderBy(k => k.KeyData).Select(k => GetKeyStringCore(k)));
Expand Down
Expand Up @@ -8,8 +8,11 @@ namespace Covid19Radar.Model
{
public class DiagnosisSubmissionParameter
{
[JsonProperty("symptomOnsetDate")]
public string SymptomOnsetDate { get; set; }
[JsonProperty("hasSymptom")]
public bool HasSymptom { get; set; }

[JsonProperty("onsetOfSymptomOrTestDate")]
public string OnsetOfSymptomOrTestDate { get; set; }

[JsonProperty("keys")]
public Key[] Keys { get; set; }
Expand Down
13 changes: 11 additions & 2 deletions Covid19Radar/Covid19Radar/Services/DiagnosisKeyRegisterServer.cs
Expand Up @@ -33,6 +33,7 @@ IDeviceVerifier deviceVerifier
}

public async Task<HttpStatusCode> SubmitDiagnosisKeysAsync(
bool hasSymptom,
DateTime symptomOnsetDate,
IList<TemporaryExposureKey> temporaryExposureKeys,
string processNumber,
Expand Down Expand Up @@ -60,7 +61,13 @@ string idempotencyKey
);
}

var diagnosisInfo = await CreateSubmissionAsync(symptomOnsetDate, temporaryExposureKeys, processNumber, idempotencyKey);
var diagnosisInfo = await CreateSubmissionAsync(
hasSymptom,
symptomOnsetDate,
temporaryExposureKeys,
processNumber,
idempotencyKey
);
return await _httpDataService.PutSelfExposureKeysAsync(diagnosisInfo);
}
finally
Expand All @@ -70,6 +77,7 @@ string idempotencyKey
}

private async Task<DiagnosisSubmissionParameter> CreateSubmissionAsync(
bool hasSymptom,
DateTime symptomOnsetDate,
IList<TemporaryExposureKey> temporaryExposureKeys,
string processNumber,
Expand All @@ -93,7 +101,8 @@ string idempotencyKey
// Create the submission
var submission = new DiagnosisSubmissionParameter()
{
SymptomOnsetDate = symptomOnsetDate.ToString(AppConstants.FORMAT_TIMESTAMP),
HasSymptom = hasSymptom,
OnsetOfSymptomOrTestDate = symptomOnsetDate.ToString(AppConstants.FORMAT_TIMESTAMP),
Keys = keys.ToArray(),
Regions = AppSettings.Instance.SupportedRegions,
Platform = DeviceInfo.Platform.ToString().ToLowerInvariant(),
Expand Down
Expand Up @@ -13,6 +13,7 @@ namespace Covid19Radar.Services
public interface IDiagnosisKeyRegisterServer
{
public Task<HttpStatusCode> SubmitDiagnosisKeysAsync(
bool hasSymptom,
DateTime symptomOnsetDate,
IList<TemporaryExposureKey> temporaryExposureKeys,
string processNumber,
Expand Down
Expand Up @@ -33,6 +33,8 @@ public class NotifyOtherPageViewModel : ViewModelBase, IExposureNotificationEven
private readonly IEssentialsService _essentialsService;
private readonly int _delayForErrorMillis;

private bool _hasSymptom = false;

private string _processingNumber;
public string ProcessingNumber
{
Expand Down Expand Up @@ -366,6 +368,7 @@ IList<TemporaryExposureKey> filteredTemporaryExposureKeyList
}

return await diagnosisKeyRegisterServer.SubmitDiagnosisKeysAsync(
_hasSymptom,
_diagnosisDate,
filteredTemporaryExposureKeyList,
ProcessingNumber,
Expand Down Expand Up @@ -429,11 +432,13 @@ public void OnClickRadioButtonIsTrueCommand(string text)

if (AppResources.NotifyOtherPageRadioButtonYes.Equals(text))
{
_hasSymptom = true;
IsVisibleWithSymptomsLayout = true;
IsVisibleNoSymptomsLayout = false;
}
else if (AppResources.NotifyOtherPageRadioButtonNo.Equals(text))
{
_hasSymptom = false;
IsVisibleWithSymptomsLayout = false;
IsVisibleNoSymptomsLayout = true;
}
Expand Down
Expand Up @@ -16,7 +16,8 @@ public class DeviceVerifierUtilsDiagnosisSubmissionParametersTests
{
private const string EXPECTED_CLEAR_TEXT_V1 = "jp.go.mhlw.cocoa.unit_test|S2V5RGF0YTE=.10000.140.0,S2V5RGF0YTI=.20000.141.0,S2V5RGF0YTM=.30000.142.0,S2V5RGF0YTQ=.40000.143.0,S2V5RGF0YTU=.50000.70.0|440,441|VerificationPayload THIS STRING IS MEANINGLESS";
private const string EXPECTED_CLEAR_TEXT_V2 = "jp.go.mhlw.cocoa.unit_test|S2V5RGF0YTE=.10000.140,S2V5RGF0YTI=.20000.141,S2V5RGF0YTM=.30000.142,S2V5RGF0YTQ=.40000.143,S2V5RGF0YTU=.50000.70|440,441|VerificationPayload THIS STRING IS MEANINGLESS";
private const string EXPECTED_CLEAR_TEXT_V3 = "2021-12-19T19:02:00.000+09:00|jp.go.mhlw.cocoa.unit_test|S2V5RGF0YTE=.10000.140.1,S2V5RGF0YTI=.20000.141.1,S2V5RGF0YTM=.30000.142.1,S2V5RGF0YTQ=.40000.143.1,S2V5RGF0YTU=.50000.70.1|440,441|VerificationPayload THIS STRING IS MEANINGLESS";
private const string EXPECTED_CLEAR_TEXT_V3_HASSYMPTOM = "jp.go.mhlw.cocoa.unit_test|2021-12-19T19:02:00.000+09:00|HasSymptom|S2V5RGF0YTE=.10000.140.1,S2V5RGF0YTI=.20000.141.1,S2V5RGF0YTM=.30000.142.1,S2V5RGF0YTQ=.40000.143.1,S2V5RGF0YTU=.50000.70.1|440,441|VerificationPayload THIS STRING IS MEANINGLESS";
private const string EXPECTED_CLEAR_TEXT_V3_NOSYMPTOM = "jp.go.mhlw.cocoa.unit_test|2021-12-19T19:02:00.000+09:00|NoSymptom|S2V5RGF0YTE=.10000.140.1,S2V5RGF0YTI=.20000.141.1,S2V5RGF0YTM=.30000.142.1,S2V5RGF0YTQ=.40000.143.1,S2V5RGF0YTU=.50000.70.1|440,441|VerificationPayload THIS STRING IS MEANINGLESS";
Comment on lines +19 to +20
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

症状の有無でDeviceVerificaitonのClearTextの内容が変わる。
アプリ側のテスト調整。

テストデータは src/Covid19Radar.Api.Tests/Models/V3DiagnosisSubmissionParameterTest のものと一致する。


private static DiagnosisSubmissionParameter.Key CreateDiagnosisKey(
string keyData,
Expand Down Expand Up @@ -124,7 +125,7 @@ public void AndroidClearTextTestV2()
}

[Fact]
public void AndroidClearTextTestV3()
public void AndroidClearTextTestV3_HasSymptom()
{
var platform = "Android";
var dummyDiagnosisKeyDataList = new[] {
Expand All @@ -151,9 +152,57 @@ public void AndroidClearTextTestV3()

var submissionParameter = new DiagnosisSubmissionParameter()
{
HasSymptom = true,
Platform = platform,
Regions = dummyRegions,
OnsetOfSymptomOrTestDate = dummySymptomOnsetDate,
Keys = dummyDiagnosisKeyDataList,
DeviceVerificationPayload = dummyDeviceVerificationPayload,
AppPackageName = dummyAppPackageName,
VerificationPayload = dummyVerificationPayload,
Padding = dummyPadding,
};

string clearText = DeviceVerifierUtils.GetNonceClearTextV3(submissionParameter);
Assert.Equal(
EXPECTED_CLEAR_TEXT_V3_HASSYMPTOM,
clearText
);
}


[Fact]
public void AndroidClearTextTestV3_NoSymptom()
{
var platform = "Android";
var dummyDiagnosisKeyDataList = new[] {
CreateDiagnosisKey("KeyData1", 10000, 140, 1),
CreateDiagnosisKey("KeyData2", 20000, 141, 1),
CreateDiagnosisKey("KeyData3", 30000, 142, 1),
CreateDiagnosisKey("KeyData4", 40000, 143, 1),
CreateDiagnosisKey("KeyData5", 50000, 70, 1),
};

var dummyRegions = new string[]
{
"440",
"441",
};

var dummySymptomOnsetDate = "2021-12-19T19:02:00.000+09:00";
var dummyDeviceVerificationPayload = "DeviceVerificationPayload THIS STRING IS MEANINGLESS";
var dummyAppPackageName = "jp.go.mhlw.cocoa.unit_test";
var dummyVerificationPayload = "VerificationPayload THIS STRING IS MEANINGLESS";

// This value will not affect any result.
var dummyPadding = new Random().Next().ToString();

var submissionParameter = new DiagnosisSubmissionParameter()
{
HasSymptom = false,
Platform = platform,
Regions = dummyRegions,
SymptomOnsetDate = dummySymptomOnsetDate,
OnsetOfSymptomOrTestDate = dummySymptomOnsetDate,
Keys = dummyDiagnosisKeyDataList,
DeviceVerificationPayload = dummyDeviceVerificationPayload,
AppPackageName = dummyAppPackageName,
Expand All @@ -163,7 +212,7 @@ public void AndroidClearTextTestV3()

string clearText = DeviceVerifierUtils.GetNonceClearTextV3(submissionParameter);
Assert.Equal(
EXPECTED_CLEAR_TEXT_V3,
EXPECTED_CLEAR_TEXT_V3_NOSYMPTOM,
clearText
);
}
Expand Down
11 changes: 11 additions & 0 deletions src/Covid19Radar.Api.Common/Common/Constants.cs
Expand Up @@ -28,10 +28,21 @@ public static class Constants
public const uint ActiveRollingPeriod = 144;

/// <summary>
/// For compatible with Legacy-V1 mode.
/// Number of days relative that have infectiousness from the date of diagnosis or onset.
/// </summary>
public const int DaysHasInfectiousness = -3;

/*
* [Important]
* The value `daysSinceOnsetOfSymptoms` must be less than or equal to `+14` and greater than or equal to `-14`.
*
* If any diagnosis-keys file CONTAMINATED by out of range value(e.g. -199, 62) that provide detectExposure/provideDiagnosisKeys method,
* ExposureNotification API for Android doesn't return any result(ExposureDetected/ExposureNotDetected) to BroadcastReceiver.
*/
public const int MIN_DAYS_SINCE_ONSET_OF_SYMPTOMS = -14;
public const int MAX_DAYS_SINCE_ONSET_OF_SYMPTOMS = 14;

/// <summary>
/// Extra value when TemporaryExposureKey reoprtType missing.
/// </summary>
Expand Down
Expand Up @@ -3,7 +3,6 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

using System;
using Covid19Radar.Api.Extensions;
using System.Text;
using Covid19Radar.Api.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;
Expand All @@ -14,11 +13,13 @@ namespace Covid19Radar.Api.Tests.Models
[TestCategory("Models")]
public class V3DiagnosisSubmissionParameterTest
{
private const string EXPECTED_CLEAR_TEXT_V3 = "2021-12-19T19:02:00.000+09:00|jp.go.mhlw.cocoa.unit_test|S2V5RGF0YTE=.10000.140.1,S2V5RGF0YTI=.20000.141.1,S2V5RGF0YTM=.30000.142.1,S2V5RGF0YTQ=.40000.143.1,S2V5RGF0YTU=.50000.70.1|440,441|VerificationPayload THIS STRING IS MEANINGLESS";
private const string EXPECTED_TRANSACTION_ID_SEED_V3 = "2021-12-19T19:02:00.000+09:00jp.go.mhlw.cocoa.unit_testS2V5RGF0YTE=.10000.140.1,S2V5RGF0YTI=.20000.141.1,S2V5RGF0YTM=.30000.142.1,S2V5RGF0YTQ=.40000.143.1,S2V5RGF0YTU=.50000.70.1440,441";
private const string EXPECTED_CLEAR_TEXT_V3_HASSYMPTOM = "jp.go.mhlw.cocoa.unit_test|2021-12-19T19:02:00.000+09:00|HasSymptom|S2V5RGF0YTE=.10000.140.1,S2V5RGF0YTI=.20000.141.1,S2V5RGF0YTM=.30000.142.1,S2V5RGF0YTQ=.40000.143.1,S2V5RGF0YTU=.50000.70.1|440,441|VerificationPayload THIS STRING IS MEANINGLESS";
private const string EXPECTED_TRANSACTION_ID_SEED_V3_HASSYMPTOM = "jp.go.mhlw.cocoa.unit_test2021-12-19T19:02:00.000+09:00HasSymptomS2V5RGF0YTE=.10000.140.1,S2V5RGF0YTI=.20000.141.1,S2V5RGF0YTM=.30000.142.1,S2V5RGF0YTQ=.40000.143.1,S2V5RGF0YTU=.50000.70.1440,441";
private const string EXPECTED_CLEAR_TEXT_V3_NOSYMPTOM = "jp.go.mhlw.cocoa.unit_test|2021-12-19T19:02:00.000+09:00|NoSymptom|S2V5RGF0YTE=.10000.140.1,S2V5RGF0YTI=.20000.141.1,S2V5RGF0YTM=.30000.142.1,S2V5RGF0YTQ=.40000.143.1,S2V5RGF0YTU=.50000.70.1|440,441|VerificationPayload THIS STRING IS MEANINGLESS";
private const string EXPECTED_TRANSACTION_ID_SEED_V3_NOSYMPTOM = "jp.go.mhlw.cocoa.unit_test2021-12-19T19:02:00.000+09:00NoSymptomS2V5RGF0YTE=.10000.140.1,S2V5RGF0YTI=.20000.141.1,S2V5RGF0YTM=.30000.142.1,S2V5RGF0YTQ=.40000.143.1,S2V5RGF0YTU=.50000.70.1440,441";

private const string EXPECTED_CLEAR_TEXT_V3_NO_KEY = "2021-12-19T19:02:00.000+09:00|jp.go.mhlw.cocoa.unit_test||440,441|VerificationPayload THIS STRING IS MEANINGLESS";
private const string EXPECTED_TRANSACTION_ID_SEED_V3_NO_KEY = "2021-12-19T19:02:00.000+09:00jp.go.mhlw.cocoa.unit_test440,441";
private const string EXPECTED_CLEAR_TEXT_V3_NO_KEY = "jp.go.mhlw.cocoa.unit_test|2021-12-19T19:02:00.000+09:00|HasSymptom||440,441|VerificationPayload THIS STRING IS MEANINGLESS";
private const string EXPECTED_TRANSACTION_ID_SEED_V3_NO_KEY = "jp.go.mhlw.cocoa.unit_test2021-12-19T19:02:00.000+09:00HasSymptom440,441";
Comment on lines -17 to +22
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

症状の有無でDeviceVerificaitonのClearTextの内容が変わる。

サーバー側のテスト調整。

テストデータは Covid19Radar/Tests/Covid19Radar.UnitTests/Common/DeviceVerifierUtilsTests のものと一致する。


[TestMethod]
public void CreateMethod()
Expand All @@ -36,37 +37,6 @@ public void PropertiesTest()
Helper.ModelTestHelper.PropetiesTest(model);
}

[DataTestMethod]
[DataRow("KEYDATA", 0, 0, 0, true)]
[DataRow("KEYDATA", 145, 0, 0, false)]
[DataRow("KEYDATA", 144, -15, 0, false)]
[DataRow("KEYDATA", 144, -14, 0, true)]
[DataRow("KEYDATA", 144, -6, 0, true)]
[DataRow("KEYDATA", 144, -5, 0, true)]
[DataRow("KEYDATA", 144, -4, 0, true)]
[DataRow("KEYDATA", 144, -3, 0, true)]
[DataRow("KEYDATA", 144, -2, 0, true)]
[DataRow("KEYDATA", 144, -1, 0, true)]
[DataRow("KEYDATA", 144, 0, 0, true)]
[DataRow("KEYDATA", 144, 0, -14, true)]
[DataRow("KEYDATA", 144, 0, 14, true)]
[DataRow("KEYDATA", 144, 0, -15, false)]
[DataRow("KEYDATA", 144, 0, 15, false)]
[DataRow("KEYDATA", 144, 1, 0, false)]
public void KeyValidationTest(string keyData, int rollingPeriod, int rollingStartNummberDayOffset, int daysSinceOnsetOfSymptoms, bool isValid)
{
var dateTime = DateTime.UtcNow.Date;

var key = CreateDiagnosisKey(
keyData,
(int)dateTime.AddDays(rollingStartNummberDayOffset).ToRollingStartNumber(),
rollingPeriod,
1,
daysSinceOnsetOfSymptoms
);
Assert.AreEqual(isValid, key.IsValid());
}
Comment on lines -39 to -68
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

V3DiagnosisSubmissionParameter.KeyのIsValidは廃止。

TemporaryExposureKeyValidationServiceとして実装する。


private static V3DiagnosisSubmissionParameter.Key CreateDiagnosisKey(
string keyData,
int rollingStartNumber,
Expand All @@ -89,7 +59,60 @@ int daysSinceOnsetOfSymptoms
}

[TestMethod]
public void DeviceVerificationTest()
public void DeviceVerificationTest_HasSymptom()
{
var platform = "Android";
var dummyDiagnosisKeyDataList = new[] {
CreateDiagnosisKey("KeyData1", 10000, 140, 1, -1),
CreateDiagnosisKey("KeyData2", 20000, 141, 1, 0),
CreateDiagnosisKey("KeyData3", 30000, 142, 1, 1),
CreateDiagnosisKey("KeyData4", 40000, 143, 1, 2),
CreateDiagnosisKey("KeyData5", 50000, 70, 1, 3),
};

var dummyRegions = new string[]
{
"440",
"441",
};
var dummySymptomOnsetDate = "2021-12-19T19:02:00.000+09:00";

var dummyDeviceVerificationPayload = "DeviceVerificationPayload THIS STRING IS MEANINGLESS";
var dummyAppPackageName = "jp.go.mhlw.cocoa.unit_test";
var dummyVerificationPayload = "VerificationPayload THIS STRING IS MEANINGLESS";

// This value will not affect any result.
var dummyPadding = new Random().Next().ToString();

// preparation
var model = new V3DiagnosisSubmissionParameter()
{
HasSymptom = true,
Platform = platform,
Regions = dummyRegions,
OnsetOfSymptomOrTestDate = dummySymptomOnsetDate,
Keys = dummyDiagnosisKeyDataList,
DeviceVerificationPayload = dummyDeviceVerificationPayload,
AppPackageName = dummyAppPackageName,
VerificationPayload = dummyVerificationPayload,
Padding = dummyPadding,
};

Assert.AreEqual(dummyDeviceVerificationPayload, model.JwsPayload);
Assert.AreEqual(
EXPECTED_CLEAR_TEXT_V3_HASSYMPTOM,
model.ClearText
);

Assert.AreEqual(dummyDeviceVerificationPayload, model.DeviceToken);
Assert.AreEqual(
EXPECTED_TRANSACTION_ID_SEED_V3_HASSYMPTOM,
model.TransactionIdSeed
);
}

[TestMethod]
public void DeviceVerificationTest_NoSymptom()
{
var platform = "Android";
var dummyDiagnosisKeyDataList = new[] {
Expand Down Expand Up @@ -117,9 +140,10 @@ public void DeviceVerificationTest()
// preparation
var model = new V3DiagnosisSubmissionParameter()
{
HasSymptom = false,
Platform = platform,
Regions = dummyRegions,
SymptomOnsetDate = dummySymptomOnsetDate,
OnsetOfSymptomOrTestDate = dummySymptomOnsetDate,
Keys = dummyDiagnosisKeyDataList,
DeviceVerificationPayload = dummyDeviceVerificationPayload,
AppPackageName = dummyAppPackageName,
Expand All @@ -129,13 +153,13 @@ public void DeviceVerificationTest()

Assert.AreEqual(dummyDeviceVerificationPayload, model.JwsPayload);
Assert.AreEqual(
EXPECTED_CLEAR_TEXT_V3,
EXPECTED_CLEAR_TEXT_V3_NOSYMPTOM,
model.ClearText
);

Assert.AreEqual(dummyDeviceVerificationPayload, model.DeviceToken);
Assert.AreEqual(
EXPECTED_TRANSACTION_ID_SEED_V3,
EXPECTED_TRANSACTION_ID_SEED_V3_NOSYMPTOM,
model.TransactionIdSeed
);
}
Expand Down Expand Up @@ -164,9 +188,10 @@ public void DeviceVerificationTest_NoKey()
// preparation
var model = new V3DiagnosisSubmissionParameter()
{
HasSymptom = true,
Platform = platform,
Regions = dummyRegions,
SymptomOnsetDate = dummySymptomOnsetDate,
OnsetOfSymptomOrTestDate = dummySymptomOnsetDate,
Keys = dummyDiagnosisKeyDataList,
DeviceVerificationPayload = dummyDeviceVerificationPayload,
AppPackageName = dummyAppPackageName,
Expand Down Expand Up @@ -210,9 +235,10 @@ public void DeviceVerificationTestKeysNull()
// preparation
var model = new V3DiagnosisSubmissionParameter()
{
HasSymptom = true,
Platform = platform,
Regions = dummyRegions,
SymptomOnsetDate = dummySymptomOnsetDate,
OnsetOfSymptomOrTestDate = dummySymptomOnsetDate,
Keys = dummyDiagnosisKeyDataList,
DeviceVerificationPayload = dummyDeviceVerificationPayload,
AppPackageName = dummyAppPackageName,
Expand Down