<!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';
// ASCII encoded buffer representation of the string
const helloBuffer = Uint8Array.of(0x68, 0x65, 0x6c, 0x6c, 0x6f);
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`);

  /*
    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`);

  /*
    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>
