Commit 2c75768d authored by Leon Han's avatar Leon Han Committed by Commit Bot

[webnfc] Separate 'absolute-url' record type from 'url'

This CL introduces a new record type 'absolute-url' based on the spec
change: https://github.com/w3c/web-nfc/pull/373

Now we read/write records containing urls like:
  'absolute-url' --> TNF_ABSOLUTE_URI
  'url'          --> TNF_WELL_KNOWN and RTD_URI

BUG=520391

Change-Id: I7b7a57c613eb1581efa01fd148c6083b26cd078a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1881786Reviewed-by: default avatarRijubrata Bhaumik <rijubrata.bhaumik@intel.com>
Reviewed-by: default avatarFrançois Beaufort <beaufort.francois@gmail.com>
Commit-Queue: Leon Han <leon.han@intel.com>
Cr-Commit-Position: refs/heads/master@{#711174}
parent 25ad81ca
...@@ -34,6 +34,7 @@ public final class NdefMessageUtils { ...@@ -34,6 +34,7 @@ public final class NdefMessageUtils {
public static final String RECORD_TYPE_EMPTY = "empty"; public static final String RECORD_TYPE_EMPTY = "empty";
public static final String RECORD_TYPE_TEXT = "text"; public static final String RECORD_TYPE_TEXT = "text";
public static final String RECORD_TYPE_URL = "url"; public static final String RECORD_TYPE_URL = "url";
public static final String RECORD_TYPE_ABSOLUTE_URL = "absolute-url";
public static final String RECORD_TYPE_JSON = "json"; public static final String RECORD_TYPE_JSON = "json";
public static final String RECORD_TYPE_OPAQUE = "opaque"; public static final String RECORD_TYPE_OPAQUE = "opaque";
public static final String RECORD_TYPE_SMART_POSTER = "smart-poster"; public static final String RECORD_TYPE_SMART_POSTER = "smart-poster";
...@@ -111,7 +112,9 @@ public final class NdefMessageUtils { ...@@ -111,7 +112,9 @@ public final class NdefMessageUtils {
UnsupportedEncodingException { UnsupportedEncodingException {
switch (record.recordType) { switch (record.recordType) {
case RECORD_TYPE_URL: case RECORD_TYPE_URL:
return android.nfc.NdefRecord.createUri(new String(record.data, "UTF-8")); return createPlatformUrlRecord(record.data, false /* isAbsUrl */);
case RECORD_TYPE_ABSOLUTE_URL:
return createPlatformUrlRecord(record.data, true /* isAbsUrl */);
case RECORD_TYPE_TEXT: case RECORD_TYPE_TEXT:
byte[] payload = createPayloadForTextRecord(record); byte[] payload = createPayloadForTextRecord(record);
return new android.nfc.NdefRecord(android.nfc.NdefRecord.TNF_WELL_KNOWN, return new android.nfc.NdefRecord(android.nfc.NdefRecord.TNF_WELL_KNOWN,
...@@ -149,7 +152,7 @@ public final class NdefMessageUtils { ...@@ -149,7 +152,7 @@ public final class NdefMessageUtils {
new String(ndefRecord.getType(), "UTF-8"), ndefRecord.getPayload()); new String(ndefRecord.getType(), "UTF-8"), ndefRecord.getPayload());
break; break;
case android.nfc.NdefRecord.TNF_ABSOLUTE_URI: case android.nfc.NdefRecord.TNF_ABSOLUTE_URI:
record = createURLRecord(ndefRecord.toUri()); record = createURLRecord(ndefRecord.toUri(), true /* isAbsUrl */);
break; break;
case android.nfc.NdefRecord.TNF_WELL_KNOWN: case android.nfc.NdefRecord.TNF_WELL_KNOWN:
record = createWellKnownRecord(ndefRecord); record = createWellKnownRecord(ndefRecord);
...@@ -186,17 +189,22 @@ public final class NdefMessageUtils { ...@@ -186,17 +189,22 @@ public final class NdefMessageUtils {
} }
/** /**
* Constructs URL NdefRecord * Constructs url NdefRecord
*/ */
private static NdefRecord createURLRecord(Uri uri) { private static NdefRecord createURLRecord(Uri uri, boolean isAbsUrl) {
if (uri == null) return null; if (uri == null) return null;
NdefRecord nfcRecord = new NdefRecord(); NdefRecord nfcRecord = new NdefRecord();
nfcRecord.recordType = RECORD_TYPE_URL; if (isAbsUrl) {
nfcRecord.recordType = RECORD_TYPE_ABSOLUTE_URL;
} else {
nfcRecord.recordType = RECORD_TYPE_URL;
}
nfcRecord.mediaType = TEXT_MIME; nfcRecord.mediaType = TEXT_MIME;
nfcRecord.data = ApiCompatibilityUtils.getBytesUtf8(uri.toString()); nfcRecord.data = ApiCompatibilityUtils.getBytesUtf8(uri.toString());
return nfcRecord; return nfcRecord;
} }
/**
/** /**
* Constructs MIME or JSON NdefRecord * Constructs MIME or JSON NdefRecord
*/ */
...@@ -246,7 +254,7 @@ public final class NdefMessageUtils { ...@@ -246,7 +254,7 @@ public final class NdefMessageUtils {
private static NdefRecord createWellKnownRecord(android.nfc.NdefRecord record) private static NdefRecord createWellKnownRecord(android.nfc.NdefRecord record)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
if (Arrays.equals(record.getType(), android.nfc.NdefRecord.RTD_URI)) { if (Arrays.equals(record.getType(), android.nfc.NdefRecord.RTD_URI)) {
return createURLRecord(record.toUri()); return createURLRecord(record.toUri(), false /* isAbsUrl */);
} }
if (Arrays.equals(record.getType(), android.nfc.NdefRecord.RTD_TEXT)) { if (Arrays.equals(record.getType(), android.nfc.NdefRecord.RTD_TEXT)) {
...@@ -280,6 +288,23 @@ public final class NdefMessageUtils { ...@@ -280,6 +288,23 @@ public final class NdefMessageUtils {
return nfcRecord; return nfcRecord;
} }
/**
* Creates a TNF_WELL_KNOWN + RTD_URI or TNF_ABSOLUTE_URI android.nfc.NdefRecord.
*/
public static android.nfc.NdefRecord createPlatformUrlRecord(byte[] url, boolean isAbsUrl)
throws UnsupportedEncodingException {
if (isAbsUrl) {
Uri uri = Uri.parse(new String(url, "UTF-8"));
if (uri == null) throw new NullPointerException("uri is null");
uri = uri.normalizeScheme();
String uriString = uri.toString();
if (uriString.length() == 0) throw new IllegalArgumentException("uri is empty");
return new android.nfc.NdefRecord(android.nfc.NdefRecord.TNF_ABSOLUTE_URI,
ApiCompatibilityUtils.getBytesUtf8(uriString), null, null);
}
return android.nfc.NdefRecord.createUri(new String(url, "UTF-8"));
}
/** /**
* Parses the input custom type to get its domain and type. * Parses the input custom type to get its domain and type.
* e.g. returns a pair ('w3.org', 'xyz') for the input 'w3.org:xyz'. * e.g. returns a pair ('w3.org', 'xyz') for the input 'w3.org:xyz'.
......
...@@ -231,9 +231,10 @@ public class NFCTest { ...@@ -231,9 +231,10 @@ public class NFCTest {
assertNull(emptyMojoNdefMessage.data[0].lang); assertNull(emptyMojoNdefMessage.data[0].lang);
assertEquals(0, emptyMojoNdefMessage.data[0].data.length); assertEquals(0, emptyMojoNdefMessage.data[0].data.length);
// Test URL record conversion. // Test url record conversion.
android.nfc.NdefMessage urlNdefMessage = android.nfc.NdefMessage urlNdefMessage =
new android.nfc.NdefMessage(android.nfc.NdefRecord.createUri(TEST_URL)); new android.nfc.NdefMessage(NdefMessageUtils.createPlatformUrlRecord(
ApiCompatibilityUtils.getBytesUtf8(TEST_URL), false /* isAbsUrl */));
NdefMessage urlMojoNdefMessage = NdefMessageUtils.toNdefMessage(urlNdefMessage); NdefMessage urlMojoNdefMessage = NdefMessageUtils.toNdefMessage(urlNdefMessage);
assertNull(urlMojoNdefMessage.url); assertNull(urlMojoNdefMessage.url);
assertEquals(1, urlMojoNdefMessage.data.length); assertEquals(1, urlMojoNdefMessage.data.length);
...@@ -244,6 +245,19 @@ public class NFCTest { ...@@ -244,6 +245,19 @@ public class NFCTest {
assertNull(urlMojoNdefMessage.data[0].lang); assertNull(urlMojoNdefMessage.data[0].lang);
assertEquals(TEST_URL, new String(urlMojoNdefMessage.data[0].data)); assertEquals(TEST_URL, new String(urlMojoNdefMessage.data[0].data));
// Test absolute-url record conversion.
android.nfc.NdefMessage absUrlNdefMessage =
new android.nfc.NdefMessage(NdefMessageUtils.createPlatformUrlRecord(
ApiCompatibilityUtils.getBytesUtf8(TEST_URL), true /* isAbsUrl */));
NdefMessage absUrlMojoNdefMessage = NdefMessageUtils.toNdefMessage(absUrlNdefMessage);
assertNull(absUrlMojoNdefMessage.url);
assertEquals(1, absUrlMojoNdefMessage.data.length);
assertEquals(NdefMessageUtils.RECORD_TYPE_ABSOLUTE_URL,
absUrlMojoNdefMessage.data[0].recordType);
assertEquals(TEXT_MIME, absUrlMojoNdefMessage.data[0].mediaType);
assertEquals(true, absUrlMojoNdefMessage.data[0].id.isEmpty());
assertEquals(TEST_URL, new String(absUrlMojoNdefMessage.data[0].data));
// Test TEXT record conversion for UTF-8 content. // Test TEXT record conversion for UTF-8 content.
android.nfc.NdefMessage utf8TextNdefMessage = new android.nfc.NdefMessage( android.nfc.NdefMessage utf8TextNdefMessage = new android.nfc.NdefMessage(
android.nfc.NdefRecord.createTextRecord(LANG_EN_US, TEST_TEXT)); android.nfc.NdefRecord.createTextRecord(LANG_EN_US, TEST_TEXT));
...@@ -363,11 +377,17 @@ public class NFCTest { ...@@ -363,11 +377,17 @@ public class NFCTest {
@Test @Test
@Feature({"NFCTest"}) @Feature({"NFCTest"})
public void testMojoToNdefConversion() throws InvalidNdefMessageException { public void testMojoToNdefConversion() throws InvalidNdefMessageException {
// Test URL record conversion. // Test url record conversion.
android.nfc.NdefMessage urlNdefMessage = createUrlWebNFCNdefMessage(TEST_URL); NdefRecord urlMojoNdefRecord = new NdefRecord();
urlMojoNdefRecord.recordType = NdefMessageUtils.RECORD_TYPE_URL;
urlMojoNdefRecord.data = ApiCompatibilityUtils.getBytesUtf8(TEST_URL);
NdefMessage urlMojoNdefMessage = createMojoNdefMessage(TEST_URL, urlMojoNdefRecord);
android.nfc.NdefMessage urlNdefMessage = NdefMessageUtils.toNdefMessage(urlMojoNdefMessage);
assertEquals(2, urlNdefMessage.getRecords().length); assertEquals(2, urlNdefMessage.getRecords().length);
assertEquals( assertEquals(
android.nfc.NdefRecord.TNF_WELL_KNOWN, urlNdefMessage.getRecords()[0].getTnf()); android.nfc.NdefRecord.TNF_WELL_KNOWN, urlNdefMessage.getRecords()[0].getTnf());
assertEquals(new String(android.nfc.NdefRecord.RTD_URI),
new String(urlNdefMessage.getRecords()[0].getType()));
assertEquals(TEST_URL, urlNdefMessage.getRecords()[0].toUri().toString()); assertEquals(TEST_URL, urlNdefMessage.getRecords()[0].toUri().toString());
assertEquals( assertEquals(
android.nfc.NdefRecord.TNF_EXTERNAL_TYPE, urlNdefMessage.getRecords()[1].getTnf()); android.nfc.NdefRecord.TNF_EXTERNAL_TYPE, urlNdefMessage.getRecords()[1].getTnf());
...@@ -375,6 +395,23 @@ public class NFCTest { ...@@ -375,6 +395,23 @@ public class NFCTest {
new String(urlNdefMessage.getRecords()[1].getType()) new String(urlNdefMessage.getRecords()[1].getType())
.compareToIgnoreCase(AUTHOR_RECORD_DOMAIN + ":" + AUTHOR_RECORD_TYPE)); .compareToIgnoreCase(AUTHOR_RECORD_DOMAIN + ":" + AUTHOR_RECORD_TYPE));
// Test absolute-url record conversion.
NdefRecord absUrlMojoNdefRecord = new NdefRecord();
absUrlMojoNdefRecord.recordType = NdefMessageUtils.RECORD_TYPE_ABSOLUTE_URL;
absUrlMojoNdefRecord.data = ApiCompatibilityUtils.getBytesUtf8(TEST_URL);
NdefMessage absUrlMojoNdefMessage = createMojoNdefMessage(TEST_URL, absUrlMojoNdefRecord);
android.nfc.NdefMessage absUrlNdefMessage =
NdefMessageUtils.toNdefMessage(absUrlMojoNdefMessage);
assertEquals(2, absUrlNdefMessage.getRecords().length);
assertEquals(android.nfc.NdefRecord.TNF_ABSOLUTE_URI,
absUrlNdefMessage.getRecords()[0].getTnf());
assertEquals(TEST_URL, absUrlNdefMessage.getRecords()[0].toUri().toString());
assertEquals(android.nfc.NdefRecord.TNF_EXTERNAL_TYPE,
absUrlNdefMessage.getRecords()[1].getTnf());
assertEquals(0,
new String(absUrlNdefMessage.getRecords()[1].getType())
.compareToIgnoreCase(AUTHOR_RECORD_DOMAIN + ":" + AUTHOR_RECORD_TYPE));
// Test TEXT record conversion for UTF-8 content. // Test TEXT record conversion for UTF-8 content.
NdefRecord utf8TextMojoNdefRecord = new NdefRecord(); NdefRecord utf8TextMojoNdefRecord = new NdefRecord();
utf8TextMojoNdefRecord.recordType = NdefMessageUtils.RECORD_TYPE_TEXT; utf8TextMojoNdefRecord.recordType = NdefMessageUtils.RECORD_TYPE_TEXT;
......
...@@ -163,13 +163,15 @@ static NDEFRecord* CreateTextRecord(const ExecutionContext* execution_context, ...@@ -163,13 +163,15 @@ static NDEFRecord* CreateTextRecord(const ExecutionContext* execution_context,
language, std::move(bytes)); language, std::move(bytes));
} }
static NDEFRecord* CreateUrlRecord(const String& media_type, // Create a 'url' record or an 'absolute-url' record.
static NDEFRecord* CreateUrlRecord(const String& record_type,
const String& media_type,
const ScriptValue& data, const ScriptValue& data,
ExceptionState& exception_state) { ExceptionState& exception_state) {
// https://w3c.github.io/web-nfc/#mapping-url-to-ndef // https://w3c.github.io/web-nfc/#mapping-url-to-ndef
if (data.IsEmpty() || !data.V8Value()->IsString()) { if (data.IsEmpty() || !data.V8Value()->IsString()) {
exception_state.ThrowTypeError( exception_state.ThrowTypeError(
"The data for 'url' NDEFRecord must be a String."); "The data for url NDEFRecord must be a String.");
return nullptr; return nullptr;
} }
...@@ -177,10 +179,10 @@ static NDEFRecord* CreateUrlRecord(const String& media_type, ...@@ -177,10 +179,10 @@ static NDEFRecord* CreateUrlRecord(const String& media_type,
String url = ToCoreString(data.V8Value().As<v8::String>()); String url = ToCoreString(data.V8Value().As<v8::String>());
if (!KURL(NullURL(), url).IsValid()) { if (!KURL(NullURL(), url).IsValid()) {
exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
"Cannot parse data for 'url' record."); "Cannot parse data for url record.");
return nullptr; return nullptr;
} }
return MakeGarbageCollected<NDEFRecord>("url", media_type, return MakeGarbageCollected<NDEFRecord>(record_type, media_type,
GetUTF8DataFromString(url)); GetUTF8DataFromString(url));
} }
...@@ -301,8 +303,9 @@ NDEFRecord* NDEFRecord::Create(const ExecutionContext* execution_context, ...@@ -301,8 +303,9 @@ NDEFRecord* NDEFRecord::Create(const ExecutionContext* execution_context,
return CreateTextRecord(execution_context, init->mediaType(), return CreateTextRecord(execution_context, init->mediaType(),
init->encoding(), init->lang(), init->data(), init->encoding(), init->lang(), init->data(),
exception_state); exception_state);
} else if (record_type == "url") { } else if (record_type == "url" || record_type == "absolute-url") {
return CreateUrlRecord(init->mediaType(), init->data(), exception_state); return CreateUrlRecord(record_type, init->mediaType(), init->data(),
exception_state);
} else if (record_type == "json") { } else if (record_type == "json") {
return CreateJsonRecord(init->mediaType(), init->data(), exception_state); return CreateJsonRecord(init->mediaType(), init->data(), exception_state);
} else if (record_type == "opaque") { } else if (record_type == "opaque") {
...@@ -400,7 +403,7 @@ String NDEFRecord::text() const { ...@@ -400,7 +403,7 @@ String NDEFRecord::text() const {
DOMArrayBuffer* NDEFRecord::arrayBuffer() const { DOMArrayBuffer* NDEFRecord::arrayBuffer() const {
if (record_type_ == "empty" || record_type_ == "text" || if (record_type_ == "empty" || record_type_ == "text" ||
record_type_ == "url") { record_type_ == "url" || record_type_ == "absolute-url") {
return nullptr; return nullptr;
} }
DCHECK(record_type_ == "json" || record_type_ == "opaque" || DCHECK(record_type_ == "json" || record_type_ == "opaque" ||
...@@ -412,7 +415,7 @@ DOMArrayBuffer* NDEFRecord::arrayBuffer() const { ...@@ -412,7 +415,7 @@ DOMArrayBuffer* NDEFRecord::arrayBuffer() const {
ScriptValue NDEFRecord::json(ScriptState* script_state, ScriptValue NDEFRecord::json(ScriptState* script_state,
ExceptionState& exception_state) const { ExceptionState& exception_state) const {
if (record_type_ == "empty" || record_type_ == "text" || if (record_type_ == "empty" || record_type_ == "text" ||
record_type_ == "url") { record_type_ == "url" || record_type_ == "absolute-url") {
return ScriptValue::CreateNull(script_state->GetIsolate()); return ScriptValue::CreateNull(script_state->GetIsolate());
} }
DCHECK(record_type_ == "json" || record_type_ == "opaque" || DCHECK(record_type_ == "json" || record_type_ == "opaque" ||
......
...@@ -47,6 +47,13 @@ const NDEFReaderOptionTests = ...@@ -47,6 +47,13 @@ const NDEFReaderOptionTests =
unmatchedScanOptions: {recordType: "json"}, unmatchedScanOptions: {recordType: "json"},
message: createMessage([createUrlRecord(test_url_data)]) message: createMessage([createUrlRecord(test_url_data)])
}, },
{
desc: "Test that reading data succeed when NDEFScanOptions'" +
" recordType is set to 'absolute-url'.",
scanOptions: {recordType: "absolute-url"},
unmatchedScanOptions: {recordType: "json"},
message: createMessage([createUrlRecord(test_url_data, true)])
},
{ {
desc: "Test that reading data succeed when NDEFScanOptions'" + desc: "Test that reading data succeed when NDEFScanOptions'" +
" recordType is set to a custom type for external type records.", " recordType is set to a custom type for external type records.",
...@@ -109,6 +116,13 @@ const ReadMultiMessagesTests = ...@@ -109,6 +116,13 @@ const ReadMultiMessagesTests =
message: createMessage([createUrlRecord(test_url_data)]), message: createMessage([createUrlRecord(test_url_data)]),
unmatchedMessage: createMessage([createTextRecord(test_text_data)]) unmatchedMessage: createMessage([createTextRecord(test_text_data)])
}, },
{
desc: "Test that filtering 'absolute-url' record from different messages" +
" correctly with NDEFScanOptions' recordType is set to 'absolute-url'.",
scanOptions: {recordType: "absolute-url"},
message: createMessage([createUrlRecord(test_url_data, true)]),
unmatchedMessage: createMessage([createTextRecord(test_text_data)])
},
{ {
desc: "Test that filtering external record from different messages" + desc: "Test that filtering external record from different messages" +
" correctly with NDEFScanOptions' recordType is set to the custom type.", " correctly with NDEFScanOptions' recordType is set to the custom type.",
......
...@@ -96,6 +96,17 @@ ...@@ -96,6 +96,17 @@
'text() has the same content with the original dictionary'); 'text() has the same content with the original dictionary');
}, 'NDEFRecord constructor with url record type'); }, 'NDEFRecord constructor with url record type');
test(() => {
const record = new NDEFRecord(createUrlRecord(test_url_data, true));
assert_equals(record.recordType, 'absolute-url', 'recordType');
assert_equals(record.mediaType, 'text/plain', 'mediaType');
const decoder = new TextDecoder();
assert_equals(decoder.decode(record.data), test_url_data,
'data has the same content with the original dictionary');
assert_equals(record.text(), test_url_data,
'text() has the same content with the original dictionary');
}, 'NDEFRecord constructor with absolute-url record type');
test(() => { test(() => {
let buffer = new ArrayBuffer(4); let buffer = new ArrayBuffer(4);
let buffer_view = new Uint8Array(buffer); let buffer_view = new Uint8Array(buffer);
......
...@@ -16,7 +16,7 @@ PASS Reject promise with exceptions thrown from serializing the 'json' record da ...@@ -16,7 +16,7 @@ PASS Reject promise with exceptions thrown from serializing the 'json' record da
PASS NDEFWriter.push should fail with TypeError when invalid target value is provided. PASS NDEFWriter.push should fail with TypeError when invalid target value is provided.
PASS Test that WebNFC API is not accessible from iframe context. PASS Test that WebNFC API is not accessible from iframe context.
PASS NDEFWriter.push should succeed when NFC HW is enabled PASS NDEFWriter.push should succeed when NFC HW is enabled
PASS NDEFWriter.push NDEFMessage containing text, json, opaque, url and external records with default NDEFPushOptions. PASS NDEFWriter.push NDEFMessage containing text, json, opaque, url, absolute-url and external records with default NDEFPushOptions.
PASS Test that NDEFWriter.push succeeds when message is DOMString. PASS Test that NDEFWriter.push succeeds when message is DOMString.
PASS Test that NDEFWriter.push succeeds when message is ArrayBuffer. PASS Test that NDEFWriter.push succeeds when message is ArrayBuffer.
PASS NDEFWriter.push with 'empty' record should succeed. PASS NDEFWriter.push with 'empty' record should succeed.
...@@ -31,7 +31,6 @@ PASS Test that recordType should be set to 'json' if NDEFRecordInit.record's rec ...@@ -31,7 +31,6 @@ PASS Test that recordType should be set to 'json' if NDEFRecordInit.record's rec
PASS Test that mediaType should be set to 'text/plain' if NDEFRecordInit.record's recordType is 'text' and NDEFRecordInit.record's mediaType is undefined. PASS Test that mediaType should be set to 'text/plain' if NDEFRecordInit.record's recordType is 'text' and NDEFRecordInit.record's mediaType is undefined.
PASS Test that mediaType should be set to 'application/octet-stream' if NDEFRecordInit.record's recordType is 'opaque' and NDEFRecordInit.record's mediaType is undefined. PASS Test that mediaType should be set to 'application/octet-stream' if NDEFRecordInit.record's recordType is 'opaque' and NDEFRecordInit.record's mediaType is undefined.
PASS Test that mediaType should be set to 'application/json' if NDEFRecordInit.record's recordType is 'json' and NDEFRecordInit.record's mediaType is undefined. PASS Test that mediaType should be set to 'application/json' if NDEFRecordInit.record's recordType is 'json' and NDEFRecordInit.record's mediaType is undefined.
FAIL Test that mediaType should be set to 'text/plain' if NDEFRecordInit.record's recordType is 'url' and NDEFRecordInit.record's mediaType is undefined. promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'substring' of null"
PASS Test that mediaType should be set to 'application/octet-stream' if NDEFRecordInit.record's recordType is external type and NDEFRecordInit.record's mediaType is undefined. PASS Test that mediaType should be set to 'application/octet-stream' if NDEFRecordInit.record's recordType is external type and NDEFRecordInit.record's mediaType is undefined.
PASS NDEFWriter.push should fail when the NFC device does not expose NDEF technology. PASS NDEFWriter.push should fail when the NFC device does not expose NDEF technology.
PASS NDEFWriter.push should succeed to push data to an unformatted NFC device when the NDEFPushOptions.overwrite is false. PASS NDEFWriter.push should succeed to push data to an unformatted NFC device when the NDEFPushOptions.overwrite is false.
......
...@@ -47,11 +47,20 @@ const invalid_type_messages = ...@@ -47,11 +47,20 @@ const invalid_type_messages =
// NDEFRecord must have data. // NDEFRecord must have data.
createMessage([createUrlRecord()]), createMessage([createUrlRecord()]),
// https://w3c.github.io/web-nfc/#dfn-map-a-url-to-ndef
// NDEFRecord must have data.
createMessage([createUrlRecord(undefined, true)]),
// NDEFRecord.data for 'url' record must be string. // NDEFRecord.data for 'url' record must be string.
createMessage([createUrlRecord(test_buffer_data)]), createMessage([createUrlRecord(test_buffer_data)]),
createMessage([createUrlRecord(test_number_data)]), createMessage([createUrlRecord(test_number_data)]),
createMessage([createUrlRecord(test_json_data)]), createMessage([createUrlRecord(test_json_data)]),
// NDEFRecord.data for 'absolute-url' record must be string.
createMessage([createUrlRecord(test_buffer_data, true)]),
createMessage([createUrlRecord(test_number_data, true)]),
createMessage([createUrlRecord(test_json_data, true)]),
// https://w3c.github.io/web-nfc/#dfn-map-binary-data-to-ndef // https://w3c.github.io/web-nfc/#dfn-map-binary-data-to-ndef
// NDEFRecord must have data. // NDEFRecord must have data.
createMessage([createOpaqueRecord()]), createMessage([createOpaqueRecord()]),
...@@ -82,8 +91,9 @@ const invalid_syntax_messages = ...@@ -82,8 +91,9 @@ const invalid_syntax_messages =
createMessage([createRecord('text', 'application/json', createMessage([createRecord('text', 'application/json',
test_text_data)]), test_text_data)]),
// Data for 'url' record, must be a valid URL. // Data for 'url' or 'absolute-url' record, must be a valid URL.
createMessage([createUrlRecord('Invalid URL:// Data')]), createMessage([createUrlRecord('Invalid URL:// Data')]),
createMessage([createUrlRecord('Invalid URL:// Data', true)]),
// A JSON MIME type is any MIME type whose subtype ends in "+json" or // A JSON MIME type is any MIME type whose subtype ends in "+json" or
// whose essence is "application/json" or "text/json". // whose essence is "application/json" or "text/json".
...@@ -292,12 +302,13 @@ nfc_test(async (t, mockNFC) => { ...@@ -292,12 +302,13 @@ nfc_test(async (t, mockNFC) => {
createJsonRecord(test_number_data), createJsonRecord(test_number_data),
createOpaqueRecord(test_buffer_data), createOpaqueRecord(test_buffer_data),
createUrlRecord(test_url_data), createUrlRecord(test_url_data),
createUrlRecord(test_url_data, true),
createRecord('w3.org:xyz', '', test_buffer_data)], createRecord('w3.org:xyz', '', test_buffer_data)],
test_message_origin); test_message_origin);
await writer.push(message); await writer.push(message);
assertNDEFMessagesEqual(message, mockNFC.pushedMessage()); assertNDEFMessagesEqual(message, mockNFC.pushedMessage());
}, "NDEFWriter.push NDEFMessage containing text, json, opaque, url and external records \ }, "NDEFWriter.push NDEFMessage containing text, json, opaque, url, absolute-url \
with default NDEFPushOptions."); and external records with default NDEFPushOptions.");
nfc_test(async (t, mockNFC) => { nfc_test(async (t, mockNFC) => {
const writer = new NDEFWriter(); const writer = new NDEFWriter();
...@@ -436,14 +447,6 @@ nfc_test(async (t, mockNFC) => { ...@@ -436,14 +447,6 @@ nfc_test(async (t, mockNFC) => {
NDEFRecordInit.record's recordType is 'json' and NDEFRecordInit.record's \ NDEFRecordInit.record's recordType is 'json' and NDEFRecordInit.record's \
mediaType is undefined."); mediaType is undefined.");
nfc_test(async (t, mockNFC) => {
const writer = new NDEFWriter();
await writer.push({ records: [{ recordType: "url", data: test_url_data }] });
const message = createMessage([createUrlRecord(test_url_data)]);
assertNDEFMessagesEqual(message, mockNFC.pushedMessage());
}, "Test that mediaType should be set to 'text/plain' if NDEFRecordInit.record's \
recordType is 'url' and NDEFRecordInit.record's mediaType is undefined.");
nfc_test(async (t, mockNFC) => { nfc_test(async (t, mockNFC) => {
const writer = new NDEFWriter(); const writer = new NDEFWriter();
await writer.push({ records: [{ recordType: "w3.org:xyz", data: test_buffer_data }] }); await writer.push({ records: [{ recordType: "w3.org:xyz", data: test_buffer_data }] });
......
...@@ -111,7 +111,10 @@ function createOpaqueRecord(buffer) { ...@@ -111,7 +111,10 @@ function createOpaqueRecord(buffer) {
return createRecord('opaque', 'application/octet-stream', buffer); return createRecord('opaque', 'application/octet-stream', buffer);
} }
function createUrlRecord(url) { function createUrlRecord(url, isAbsUrl) {
if (isAbsUrl) {
return createRecord('absolute-url', 'text/plain', url);
}
return createRecord('url', 'text/plain', url); return createRecord('url', 'text/plain', url);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment