blob: a2ea09fa681aff85e0cf69d217a89e9a79a8d96b [file] [log] [blame]
<!DOCTYPE html>
<title>NDEFRecord constructor</title>
<link rel="help" href="https://w3c.github.io/web-nfc/#dom-ndefrecord">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/nfc-helpers.js"></script>
<script>
test(() => {
assert_equals(NDEFRecord.length, 1);
assert_throws(new TypeError, () => new NDEFRecord());
}, 'NDEFRecord constructor without init dict');
test(() => {
assert_throws(new TypeError, () => new NDEFRecord(null),
'NDEFRecordInit#recordType is a required field.');
}, 'NDEFRecord constructor with null init dict');
test(() => {
assert_throws(new TypeError, () => new NDEFRecord({id: test_record_id, data: test_text_data}),
'NDEFRecordInit#recordType is a required field.');
}, 'NDEFRecord constructor without NDEFRecordInit#recordType field');
test(() => {
assert_throws(new TypeError, () => new NDEFRecord(
createRecord('empty', test_text_data, test_record_id)),
'id does not apply for empty record type.');
}, 'NDEFRecord constructor with empty record type and id');
test(() => {
assert_throws(new TypeError, () => new NDEFRecord(
createRecord('empty', test_text_data, test_record_id, 'text/plain')),
'mediaType does not apply for empty record type.');
assert_throws(new TypeError, () => new NDEFRecord(
createRecord('text', test_text_data, test_record_id, 'text/plain')),
'mediaType does not apply for text record type.');
assert_throws(new TypeError, () => new NDEFRecord(
createRecord('url', test_url_data, test_record_id, 'text/plain')),
'mediaType does not apply for url record type.');
assert_throws(new TypeError, () => new NDEFRecord(
createRecord('absolute-url', test_url_data, test_record_id, 'text/plain')),
'mediaType does not apply for absolute-url record type.');
assert_throws(new TypeError, () => new NDEFRecord(
createRecord('unknown', test_buffer_data, test_record_id, 'application/octet-stream')),
'mediaType does not apply for unknown record type.');
assert_throws(new TypeError, () => new NDEFRecord(
createRecord('foo.example.com:bar', test_buffer_data, test_record_id, 'application/octet-stream')),
'mediaType does not apply for external record type.');
}, 'NDEFRecord constructor should only accept mediaType for mime record type');
test(() => {
{
const record = new NDEFRecord(createRecord('text', test_text_data));
assert_equals(record.id, null, 'id');
}
{
const record = new NDEFRecord(createRecord('text', test_text_data, ''));
assert_equals(record.id, '', 'id');
}
{
const dummy_id = 'https://dummy_host/mypath/myid';
const record = new NDEFRecord(createRecord('text', test_text_data, dummy_id));
assert_equals(record.id, dummy_id, 'id');
}
{
const dummy_id = 'http://dummy_host/mypath/myid';
const record = new NDEFRecord(createRecord('text', test_text_data, dummy_id));
assert_equals(record.id, dummy_id, 'id');
}
{
const dummy_id = 'mypath/myid';
const record = new NDEFRecord(createRecord('text', test_text_data, dummy_id));
assert_equals(record.id, dummy_id, 'id');
}
}, 'NDEFRecord constructor with custom record ids');
test(() => {
const record = new NDEFRecord(createRecord('empty'));
assert_equals(record.recordType, 'empty', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, null, 'id');
assert_equals(record.encoding, null, 'encoding');
assert_equals(record.lang, null, 'lang');
assert_equals(record.data, null, 'data');
assert_throws('NotSupportedError', () => record.toRecords(),
'Only smart-poster records and external type records could have embedded records.');
}, 'NDEFRecord constructor with empty record type');
test(() => {
const record = new NDEFRecord(createTextRecord(test_text_data));
assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
assert_equals(record.encoding, 'utf-8', 'encoding');
assert_equals(record.lang, 'en', 'lang');
const decoder = new TextDecoder();
assert_equals(decoder.decode(record.data), test_text_data,
'data has the same content with the original dictionary');
assert_throws('NotSupportedError', () => record.toRecords(),
'Only smart-poster records and external type records could have embedded records.');
}, 'NDEFRecord constructor with text record type and string data');
test(() => {
const encoder = new TextEncoder();
const uint8Array = encoder.encode(test_text_data);
const record = new NDEFRecord(createTextRecord(uint8Array.buffer));
assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
// By default, 'utf-8'.
assert_equals(record.encoding, 'utf-8', 'encoding');
assert_equals(record.lang, 'en', 'lang');
const decoder = new TextDecoder();
assert_equals(decoder.decode(record.data), test_text_data,
'data has the same content with the original dictionary');
assert_throws('NotSupportedError', () => record.toRecords(),
'Only smart-poster records and external type records could have embedded records.');
}, 'NDEFRecord constructor with text record type and arrayBuffer data');
test(() => {
const encoder = new TextEncoder();
const uint8Array = encoder.encode(test_text_data);
const record = new NDEFRecord(createTextRecord(uint8Array));
assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
// By default, 'utf-8'.
assert_equals(record.encoding, 'utf-8', 'encoding');
assert_equals(record.lang, 'en', 'lang');
const decoder = new TextDecoder();
assert_equals(decoder.decode(record.data), test_text_data,
'data has the same content with the original dictionary');
assert_throws('NotSupportedError', () => record.toRecords(),
'Only smart-poster records and external type records could have embedded records.');
}, 'NDEFRecord constructor with text record type and arrayBufferView data');
test(() => {
assert_throws(new TypeError, () => new NDEFRecord(createTextRecord(
test_text_data, 'random-encoding')));
assert_throws(new TypeError, () => new NDEFRecord(createTextRecord(
test_text_data, 'utf-16')));
// Only 'utf-8' is OK for a DOMString data source.
const record = new NDEFRecord(createTextRecord(test_text_data, 'utf-8', 'fr'));
assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.encoding, 'utf-8', 'encoding');
assert_equals(record.lang, 'fr', 'lang');
const decoder = new TextDecoder();
assert_equals(decoder.decode(record.data), test_text_data,
'data has the same content with the original text');
assert_throws(new TypeError, () => new NDEFRecord(createTextRecord(
encodeTextToArrayBuffer(test_text_data, 'utf-8'), 'random-encoding')));
// The encoding list valid for a BufferSource data source.
const encodings = ['utf-8', 'utf-16', 'utf-16be', 'utf-16le'];
for (const encoding of encodings) {
const record = new NDEFRecord(createTextRecord(encodeTextToArrayBuffer(
test_text_data, encoding), encoding, 'fr'));
assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.encoding, encoding, 'encoding');
assert_equals(record.lang, 'fr', 'lang');
const decoder = new TextDecoder(record.encoding);
assert_equals(decoder.decode(record.data), test_text_data,
'data has the same content with the original text. encoding: ' + encoding);
}
}, 'NDEFRecord constructor with text record type, encoding, and lang');
test(t => {
const previous_lang = document.querySelector('html').getAttribute('lang');
const test_lang = 'fr';
document.querySelector('html').setAttribute('lang', test_lang);
t.add_cleanup(() => {
document.querySelector('html').setAttribute('lang', previous_lang);
});
const record = new NDEFRecord(createTextRecord(test_text_data));
assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
assert_equals(record.encoding, 'utf-8', 'encoding');
assert_equals(record.lang, test_lang, 'lang');
const decoder = new TextDecoder();
assert_equals(decoder.decode(record.data), test_text_data,
'data has the same content with the original dictionary');
}, 'NDEFRecord constructor with text record type and custom document language');
test(() => {
const record = new NDEFRecord(createUrlRecord(test_url_data));
assert_equals(record.recordType, 'url', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
const decoder = new TextDecoder();
assert_equals(decoder.decode(record.data), test_url_data,
'data has the same content with the original dictionary');
assert_throws('NotSupportedError', () => record.toRecords(),
'Only smart-poster records and external type records could have embedded records.');
}, '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, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
const decoder = new TextDecoder();
assert_equals(decoder.decode(record.data), test_url_data,
'data has the same content with the original dictionary');
assert_throws('NotSupportedError', () => record.toRecords(),
'Only smart-poster records and external type records could have embedded records.');
}, 'NDEFRecord constructor with absolute-url record type');
test(() => {
assert_throws(new TypeError, () => new NDEFRecord(
createMimeRecord("A string is not a BufferSource")),
'Only BufferSource is allowed to be the record data.');
let buffer = new ArrayBuffer(4);
new Uint8Array(buffer).set([1, 2, 3, 4]);
// Feed ArrayBuffer.
{
const record = new NDEFRecord(createMimeRecord(buffer));
assert_equals(record.recordType, 'mime', 'recordType');
assert_equals(record.mediaType, 'application/octet-stream', 'mediaType');
assert_equals(record.id, test_record_id, 'id');
assert_array_equals(new Uint8Array(record.data.buffer), [1, 2, 3, 4],
'data has the same content with the original buffer');
assert_throws('NotSupportedError', () => record.toRecords(),
'Only smart-poster records and external type records could have embedded records.');
}
// Feed ArrayBufferView.
{
let buffer_view = new Uint8Array(buffer, 1);
const record = new NDEFRecord(createMimeRecord(buffer_view));
assert_equals(record.recordType, 'mime', 'recordType');
assert_equals(record.id, test_record_id, 'id');
assert_array_equals(new Uint8Array(record.data.buffer), [2, 3, 4],
'data has the same content with the original buffer view');
assert_throws('NotSupportedError', () => record.toRecords(),
'Only smart-poster records and external type records could have embedded records.');
}
}, 'NDEFRecord constructor with mime record type and stream data');
test(() => {
const record = new NDEFRecord(createMimeRecordFromJson(test_json_data));
assert_equals(record.recordType, 'mime', 'recordType');
assert_equals(record.mediaType, 'application/json', 'mediaType');
assert_equals(record.id, test_record_id, 'id');
assert_object_equals(JSON.parse(new TextDecoder().decode(record.data)),
test_json_data,
'data has the same content with the original json');
assert_throws('NotSupportedError', () => record.toRecords(),
'Only smart-poster records and external type records could have embedded records.');
}, 'NDEFRecord constructor with mime record type and json data');
test(() => {
assert_throws(new TypeError, () => new NDEFRecord(
createUnknownRecord("A string is not a BufferSource")),
'Only BufferSource is allowed to be the record data.');
let buffer = new ArrayBuffer(4);
new Uint8Array(buffer).set([1, 2, 3, 4]);
// Feed ArrayBuffer.
{
const record = new NDEFRecord(createUnknownRecord(buffer));
assert_equals(record.recordType, 'unknown', 'recordType');
assert_equals(record.id, test_record_id, 'id');
assert_array_equals(new Uint8Array(record.data.buffer), [1, 2, 3, 4],
'data has the same content with the original buffer');
assert_throws('NotSupportedError', () => record.toRecords(),
'Only smart-poster records and external type records could have embedded records.');
}
// Feed ArrayBufferView.
{
let buffer_view = new Uint8Array(buffer, 1);
const record = new NDEFRecord(createUnknownRecord(buffer_view));
assert_equals(record.recordType, 'unknown', 'recordType');
assert_equals(record.id, test_record_id, 'id');
assert_array_equals(new Uint8Array(record.data.buffer), [2, 3, 4],
'data has the same content with the original buffer view');
assert_throws('NotSupportedError', () => record.toRecords(),
'Only smart-poster records and external type records could have embedded records.');
}
}, 'NDEFRecord constructor with unknown record type');
test(() => {
assert_throws(new TypeError, () => new NDEFRecord(
createRecord('foo.eXamPle.com:bAr*-', "A string is not a BufferSource or NDEFMessageInit")),
'Only BufferSource and NDEFMessageInit are allowed to be the record data.');
let buffer = new ArrayBuffer(4);
new Uint8Array(buffer).set([1, 2, 3, 4]);
// Feed ArrayBuffer.
{
const record = new NDEFRecord(createRecord('foo.eXamPle.com:bAr*-', buffer, test_record_id));
assert_equals(record.recordType, 'foo.eXamPle.com:bAr*-', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
assert_array_equals(new Uint8Array(record.data.buffer), [1, 2, 3, 4],
'data has the same content with the original buffer');
assert_equals(record.toRecords(), null,
'toRecords() returns null if the payload is not an NDEF message.');
}
// Feed ArrayBufferView.
{
let buffer_view = new Uint8Array(buffer, 1);
const record = new NDEFRecord(createRecord(
'foo.eXamPle.com:bAr*-', buffer_view, test_record_id));
assert_equals(record.recordType, 'foo.eXamPle.com:bAr*-', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
assert_array_equals(new Uint8Array(record.data.buffer), [2, 3, 4],
'data has the same content with the original buffer view');
assert_equals(record.toRecords(), null,
'toRecords() returns null if the payload is not an NDEF message.');
}
// Feed NDEFMessageInit.
{
const payload_message = createMessage([createTextRecord(test_text_data)]);
const record = new NDEFRecord(createRecord(
'foo.eXamPle.com:bAr*-', payload_message, "dummy_record_id"));
assert_equals(record.recordType, 'foo.eXamPle.com:bAr*-', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, "dummy_record_id", 'id');
const embedded_records = record.toRecords();
assert_equals(embedded_records.length, 1, 'Only one embedded record.');
// The only one embedded record has correct content.
assert_equals(embedded_records[0].recordType, 'text', 'recordType');
assert_equals(embedded_records[0].mediaType, null, 'mediaType');
assert_equals(embedded_records[0].id, test_record_id, 'id');
const decoder = new TextDecoder();
assert_equals(decoder.decode(embedded_records[0].data), test_text_data,
'data has the same content with the original dictionary');
}
}, 'NDEFRecord constructor with external record type');
test(() => {
assert_throws(new TypeError, () => new NDEFRecord(createRecord('EMptY')),
'Unknown record type.');
assert_throws(new TypeError, () => new NDEFRecord(createRecord('TeXt', test_text_data)),
'Unknown record type.');
assert_throws(new TypeError, () => new NDEFRecord(createRecord('uRL', test_url_data)),
'Unknown record type.');
assert_throws(new TypeError, () => new NDEFRecord(createRecord('Mime', test_buffer_data)),
'Unknown record type.');
assert_throws(new TypeError, () => new NDEFRecord(createRecord('sMart-PosTER', test_url_data)),
'Unknown record type.');
}, 'NDEFRecord constructor with record type string being treated as case sensitive');
test(() => {
assert_throws(new TypeError, () => new NDEFRecord(createRecord(
'example.com:hellö', test_buffer_data)),
'The external type must be an ASCII string.');
// Length of the external type is 255, OK.
const record = new NDEFRecord(createRecord(
[...Array(251)].map(_ => 'a').join('') + ':xyz', test_buffer_data));
// Exceeding 255, Throws.
assert_throws(new TypeError, () => new NDEFRecord(createRecord(
[...Array(252)].map(_ => 'a').join('') + ':xyz', test_buffer_data)),
'The external type should not be longer than 255.');
assert_throws(new TypeError, () => new NDEFRecord(createRecord(
'xyz', test_buffer_data)), 'The external type must have a \':\'.');
assert_throws(new TypeError, () => new NDEFRecord(createRecord(
':xyz', test_buffer_data)), 'The domain should not be empty.');
assert_throws(new TypeError, () => new NDEFRecord(createRecord(
'example.com:', test_buffer_data)), 'The type should not be empty.');
assert_throws(new TypeError, () => new NDEFRecord(createRecord(
'example.com:xyz[', test_buffer_data)), 'The type should not contain \'[\'.');
assert_throws(new TypeError, () => new NDEFRecord(createRecord(
'example.com:xyz~', test_buffer_data)), 'The type should not contain \'~\'.');
assert_throws(new TypeError, () => new NDEFRecord(createRecord(
'example.com:xyz/', test_buffer_data)), 'The type should not contain \'/\'.');
}, 'NDEFRecord constructor with invalid external record type');
</script>