<!doctype html>
<meta charset=utf-8>
<meta name="timeout" content="long">
<title>RTCDataChannel.prototype.send</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="RTCPeerConnection-helper.js"></script>
<script>
'use strict';

// Test is based on the following editor draft:
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html

// The following helper functions are called from RTCPeerConnection-helper.js:
//  createDataChannelPair
//  awaitMessage
//  blobToArrayBuffer
//  assert_equals_typed_array

/*
  6.2.  RTCDataChannel
    interface RTCDataChannel : EventTarget {
      ...
      readonly  attribute RTCDataChannelState readyState;
      readonly  attribute unsigned long       bufferedAmount;
                attribute EventHandler        onmessage;
                attribute DOMString           binaryType;

      void send(USVString data);
      void send(Blob data);
      void send(ArrayBuffer data);
      void send(ArrayBufferView data);
    };
 */

// Simple ASCII encoded string
const helloString = 'hello';
const emptyString = '';
// ASCII encoded buffer representation of the string
const helloBuffer = Uint8Array.of(0x68, 0x65, 0x6c, 0x6c, 0x6f);
const emptyBuffer = new Uint8Array();
const helloBlob = new Blob([helloBuffer]);

// Unicode string with multiple code units
const unicodeString = '世界你好';
// UTF-8 encoded buffer representation of the string
const unicodeBuffer = Uint8Array.of(
  0xe4, 0xb8, 0x96, 0xe7, 0x95, 0x8c,
  0xe4, 0xbd, 0xa0, 0xe5, 0xa5, 0xbd);

/*
    6.2.  send()
      2.  If channel's readyState attribute is connecting, throw an InvalidStateError.
 */
test(t => {
  const pc = new RTCPeerConnection();
  const channel = pc.createDataChannel('test');
  assert_equals(channel.readyState, 'connecting');
  assert_throws_dom('InvalidStateError', () => channel.send(helloString));
}, 'Calling send() when data channel is in connecting state should throw InvalidStateError');

for (const options of [{}, {negotiated: true, id: 0}]) {
  const mode = `${options.negotiated? "Negotiated d" : "D"}atachannel`;

  /*
    6.2.  send()
      3.  Execute the sub step that corresponds to the type of the methods argument:

          string object
            Let data be the object and increase the bufferedAmount attribute
            by the number of bytes needed to express data as UTF-8.

    [WebSocket]
    5.  Feedback from the protocol
      When a WebSocket message has been received
        4.  If type indicates that the data is Text, then initialize event's data
            attribute to data.
   */
  promise_test(t => {
    return createDataChannelPair(t, options)
    .then(([channel1, channel2]) => {
      channel1.send(helloString);
      return awaitMessage(channel2)
    }).then(message => {
      assert_equals(typeof message, 'string',
        'Expect message to be a string');

      assert_equals(message, helloString);
    });
  }, `${mode} should be able to send simple string and receive as string`);

  promise_test(t => {
    return createDataChannelPair(t, options)
    .then(([channel1, channel2]) => {
      channel1.send(unicodeString);
      return awaitMessage(channel2)
    }).then(message => {
      assert_equals(typeof message, 'string',
        'Expect message to be a string');

      assert_equals(message, unicodeString);
    });
  }, `${mode} should be able to send unicode string and receive as unicode string`);
  promise_test(t => {
    return createDataChannelPair(t, options)
    .then(([channel1, channel2]) => {
      channel2.binaryType = 'arraybuffer';
      channel1.send(helloString);
      return awaitMessage(channel2);
    }).then(message => {
      assert_equals(typeof message, 'string',
        'Expect message to be a string');

      assert_equals(message, helloString);
    });
  }, `${mode} should ignore binaryType and always receive string message as string`);
  promise_test(t => {
    return createDataChannelPair(t, options)
    .then(([channel1, channel2]) => {
      channel1.send(emptyString);
      // Send a non-empty string in case the implementation ignores empty messages
      channel1.send(helloString);
      return awaitMessage(channel2)
    }).then(message => {
      assert_equals(typeof message, 'string',
        'Expect message to be a string');

      assert_equals(message, emptyString);
    });
  }, `${mode} should be able to send an empty string and receive an empty string`);

  /*
    6.2. send()
      3.  Execute the sub step that corresponds to the type of the methods argument:
          ArrayBufferView object
            Let data be the data stored in the section of the buffer described
            by the ArrayBuffer object that the ArrayBufferView object references
            and increase the bufferedAmount attribute by the length of the
            ArrayBufferView in bytes.

    [WebSocket]
    5.  Feedback from the protocol
      When a WebSocket message has been received
        4.  If binaryType is set to "arraybuffer", then initialize event's data
            attribute to a new read-only ArrayBuffer object whose contents are data.

    [WebIDL]
    4.1.  ArrayBufferView
      typedef (Int8Array or Int16Array or Int32Array or
        Uint8Array or Uint16Array or Uint32Array or Uint8ClampedArray or
        Float32Array or Float64Array or DataView) ArrayBufferView;
   */
  promise_test(t => {
    return createDataChannelPair(t, options)
    .then(([channel1, channel2]) => {
      channel2.binaryType = 'arraybuffer';
      channel1.send(helloBuffer);
      return awaitMessage(channel2)
    }).then(messageBuffer => {
      assert_true(messageBuffer instanceof ArrayBuffer,
        'Expect messageBuffer to be an ArrayBuffer');

      assert_equals_typed_array(messageBuffer, helloBuffer.buffer);
    });
  }, `${mode} should be able to send Uint8Array message and receive as ArrayBuffer`);

  /*
    6.2. send()
      3.  Execute the sub step that corresponds to the type of the methods argument:
          ArrayBuffer object
            Let data be the data stored in the buffer described by the ArrayBuffer
            object and increase the bufferedAmount attribute by the length of the
            ArrayBuffer in bytes.
   */
  promise_test(t => {
    return createDataChannelPair(t, options)
    .then(([channel1, channel2]) => {
      channel2.binaryType = 'arraybuffer';
      channel1.send(helloBuffer.buffer);
      return awaitMessage(channel2)
    }).then(messageBuffer => {
      assert_true(messageBuffer instanceof ArrayBuffer,
        'Expect messageBuffer to be an ArrayBuffer');

      assert_equals_typed_array(messageBuffer, helloBuffer.buffer);
    });
  }, `${mode} should be able to send ArrayBuffer message and receive as ArrayBuffer`);

  promise_test(t => {
    return createDataChannelPair(t, options)
    .then(([channel1, channel2]) => {
      channel2.binaryType = 'arraybuffer';
      channel1.send(emptyBuffer.buffer);
      // Send a non-empty buffer in case the implementation ignores empty messages
      channel1.send(helloBuffer.buffer);
      return awaitMessage(channel2)
    }).then(messageBuffer => {
      assert_true(messageBuffer instanceof ArrayBuffer,
        'Expect messageBuffer to be an ArrayBuffer');

      assert_equals_typed_array(messageBuffer, emptyBuffer.buffer);
    });
  }, `${mode} should be able to send an empty ArrayBuffer message and receive as ArrayBuffer`);

  /*
    6.2. send()
      3.  Execute the sub step that corresponds to the type of the methods argument:
          Blob object
            Let data be the raw data represented by the Blob object and increase
            the bufferedAmount attribute by the size of data, in bytes.
   */
  promise_test(t => {
    return createDataChannelPair(t, options)
    .then(([channel1, channel2]) => {
      channel2.binaryType = 'arraybuffer';
      channel1.send(helloBlob);
      return awaitMessage(channel2);
    }).then(messageBuffer => {
      assert_true(messageBuffer instanceof ArrayBuffer,
        'Expect messageBuffer to be an ArrayBuffer');

      assert_equals_typed_array(messageBuffer, helloBuffer.buffer);
    });
  }, `${mode} should be able to send Blob message and receive as ArrayBuffer`);

  /*
    [WebSocket]
    5.  Feedback from the protocol
      When a WebSocket message has been received
        4.  If binaryType is set to "blob", then initialize event's data attribute
            to a new Blob object that represents data as its raw data.
   */
  promise_test(t => {
    return createDataChannelPair(t, options)
    .then(([channel1, channel2]) => {
      channel2.binaryType = 'blob';
      channel1.send(helloBuffer);
      return awaitMessage(channel2);
    })
    .then(messageBlob => {
      assert_true(messageBlob instanceof Blob,
        'Expect received messageBlob to be a Blob');

      return blobToArrayBuffer(messageBlob);
    }).then(messageBuffer => {
      assert_true(messageBuffer instanceof ArrayBuffer,
        'Expect messageBuffer to be an ArrayBuffer');

      assert_equals_typed_array(messageBuffer, helloBuffer.buffer);
    });
  }, `${mode} should be able to send ArrayBuffer message and receive as Blob`);

  /*
    6.2.  RTCDataChannel
      binaryType
        The binaryType attribute must, on getting, return the value to which it was
        last set. On setting, the user agent must set the IDL attribute to the new
        value. When a RTCDataChannel object is created, the binaryType attribute must
        be initialized to the string "blob".
   */
  promise_test(t => {
    return createDataChannelPair(t, options)
    .then(([channel1, channel2]) => {
      assert_equals(channel2.binaryType, 'blob',
        'Expect initial binaryType value to be blob');

      channel1.send(helloBuffer);
      return awaitMessage(channel2);
    })
    .then(messageBlob => {
      assert_true(messageBlob instanceof Blob,
        'Expect received messageBlob to be a Blob');

      return blobToArrayBuffer(messageBlob);
    }).then(messageBuffer => {
      assert_true(messageBuffer instanceof ArrayBuffer,
        'Expect messageBuffer to be an ArrayBuffer');

      assert_equals_typed_array(messageBuffer, helloBuffer.buffer);
    });
  }, `${mode} binaryType should receive message as Blob by default`);

  // Test sending 3 messages: helloBuffer, unicodeString, helloBlob
  async_test(t => {
    const receivedMessages = [];

    const onMessage = t.step_func(event => {
      const { data } = event;
      receivedMessages.push(data);

      if(receivedMessages.length === 3) {
        assert_equals_typed_array(receivedMessages[0], helloBuffer.buffer);
        assert_equals(receivedMessages[1], unicodeString);
        assert_equals_typed_array(receivedMessages[2], helloBuffer.buffer);

        t.done();
      }
    });

    createDataChannelPair(t, options)
    .then(([channel1, channel2]) => {
      channel2.binaryType = 'arraybuffer';
      channel2.addEventListener('message', onMessage);

      channel1.send(helloBuffer);
      channel1.send(unicodeString);
      channel1.send(helloBlob);

    }).catch(t.step_func(err =>
      assert_unreached(`Unexpected promise rejection: ${err}`)));
  }, `${mode} sending multiple messages with different types should succeed and be received`);

  /*
    [Deferred]
    6.2.  RTCDataChannel
      The send() method is being amended in w3c/webrtc-pc#1209 to throw error instead
      of closing data channel when buffer is full

      send()
        4.  If channel's underlying data transport is not established yet, or if the
            closing procedure has started, then abort these steps.
        5.  Attempt to send data on channel's underlying data transport; if the data
            cannot be sent, e.g. because it would need to be buffered but the buffer
            is full, the user agent must abruptly close channel's underlying data
            transport with an error.

    test(t => {
      const pc = new RTCPeerConnection();
      const channel = pc.createDataChannel('test');
      channel.close();
      assert_equals(channel.readyState, 'closing');
      channel.send(helloString);
    }, 'Calling send() when data channel is in closing state should succeed');
  */

  promise_test(async t => {
    let pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    let [channel1, channel2] = await createDataChannelPair(t, options, pc1);
    let message = 'hello888'; // 8 bytes
    while (message.length <= pc1.sctp.maxMessageSize) {
      channel1.send(message);
      let received_message = await awaitMessage(channel2);
      assert_equals(received_message.length, message.length, "Size mismatch");
      // Double size
      message = message + message;
    }
    // "send" method step 4:
    // If the byte size of "data" exceeds the value of maxMessageSize, throw
    // a TypeError.
    assert_throws_js(TypeError, () => channel1.send(message));
  }, `${mode} send() up to max size should succeed, above max size should fail`);
}
</script>
