<!doctype html>
<meta charset=utf-8>
<meta name="timeout" content="long">
<title>RTCDataChannel.prototype.bufferedAmount</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 revision:
// https://rawgit.com/w3c/webrtc-pc/1cc5bfc3ff18741033d804c4a71f7891242fb5b3/webrtc.html

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

/*
  6.2.  RTCDataChannel
    interface RTCDataChannel : EventTarget {
      ...
      readonly  attribute unsigned long       bufferedAmount;
      void send(USVString data);
      void send(Blob data);
      void send(ArrayBuffer data);
      void send(ArrayBufferView data);
    };

    bufferedAmount
      The bufferedAmount attribute must return the number of bytes of application
      data (UTF-8 text and binary data) that have been queued using send() but that,
      as of the last time the event loop started executing a task, had not yet been
      transmitted to the network. (This thus includes any text sent during the
      execution of the current task, regardless of whether the user agent is able
      to transmit text asynchronously with script execution.) This does not include
      framing overhead incurred by the protocol, or buffering done by the operating
      system or network hardware. The value of the [[BufferedAmount]] slot will only
      increase with each call to the send() method as long as the [[ReadyState]] slot
      is open; however, the slot does not reset to zero once the channel closes. When
      the underlying data transport sends data from its queue, the user agent MUST
      queue a task that reduces [[BufferedAmount]] with the number of bytes that was
      sent.


  [WebMessaging]
  interface MessageEvent : Event {
    readonly attribute any 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);

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

  /*
    Ensure .bufferedAmount is 0 initially for both sides.
   */
  promise_test(async (t) => {
    const [dc1, dc2] = await createDataChannelPair(t, options);

    assert_equals(dc1.bufferedAmount, 0, 'Expect bufferedAmount to be 0');
    assert_equals(dc2.bufferedAmount, 0, 'Expect bufferedAmount to be 0');
  }, `${mode} bufferedAmount initial value should be 0 for both peers`);

  /*
    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.
   */
  promise_test(async (t) => {
    const [dc1, dc2] = await createDataChannelPair(t, options);

    dc1.send(unicodeString);
    assert_equals(dc1.bufferedAmount, unicodeBuffer.byteLength,
      'Expect bufferedAmount to be the byte length of the unicode string');

    await awaitMessage(dc2);
    assert_equals(dc1.bufferedAmount, 0,
      'Expect sender bufferedAmount to be reduced after message is sent');
  }, `${mode} bufferedAmount should increase to byte length of encoded` +
     `unicode string sent`);

  /*
    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(async (t) => {
    const [dc1, dc2] = await createDataChannelPair(t, options);

    dc1.send(helloBuffer.buffer);
    assert_equals(dc1.bufferedAmount, helloBuffer.byteLength,
      'Expect bufferedAmount to increase to byte length of sent buffer');

    await awaitMessage(dc2);
    assert_equals(dc1.bufferedAmount, 0,
      'Expect sender bufferedAmount to be reduced after message is sent');
  }, `${mode} bufferedAmount should increase to byte length of buffer sent`);

  /*
    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(async (t) => {
    const [dc1, dc2] = await createDataChannelPair(t, options);

    dc1.send(helloBlob);
    assert_equals(dc1.bufferedAmount, helloBlob.size,
      'Expect bufferedAmount to increase to size of sent blob');

    await awaitMessage(dc2);
    assert_equals(dc1.bufferedAmount, 0,
      'Expect sender bufferedAmount to be reduced after message is sent');
  }, `${mode} bufferedAmount should increase to size of blob sent`);

  // Test sending 3 messages: helloBuffer, unicodeString, helloBlob
  promise_test(async (t) => {
    const resolver = new Resolver();
    let messageCount = 0;

    const [dc1, dc2] = await createDataChannelPair(t, options);
    dc2.onmessage = t.step_func(() => {
      if (++messageCount === 3) {
        assert_equals(dc1.bufferedAmount, 0,
          'Expect sender bufferedAmount to be reduced after message is sent');
        resolver.resolve();
      }
    });

    dc1.send(helloBuffer);
    assert_equals(dc1.bufferedAmount, helloString.length,
      'Expect bufferedAmount to be the total length of all messages queued to send');

    dc1.send(unicodeString);
    assert_equals(dc1.bufferedAmount,
      helloString.length + unicodeBuffer.byteLength,
      'Expect bufferedAmount to be the total length of all messages queued to send');

    dc1.send(helloBlob);
    assert_equals(dc1.bufferedAmount,
      helloString.length*2 + unicodeBuffer.byteLength,
      'Expect bufferedAmount to be the total length of all messages queued to send');

    await resolver;
  }, `${mode} bufferedAmount should increase by byte length for each message sent`);

  promise_test(async (t) => {
    const [dc1] = await createDataChannelPair(t, options);

    dc1.send(helloBuffer.buffer);
    assert_equals(dc1.bufferedAmount, helloBuffer.byteLength,
      'Expect bufferedAmount to increase to byte length of sent buffer');

    dc1.close();
    assert_equals(dc1.bufferedAmount, helloBuffer.byteLength,
      'Expect bufferedAmount to not decrease immediately after closing the channel');
  }, `${mode} bufferedAmount should not decrease immediately after initiating closure`);

  promise_test(async (t) => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    const [dc1] = await createDataChannelPair(t, options, pc1);

    dc1.send(helloBuffer.buffer);
    assert_equals(dc1.bufferedAmount, helloBuffer.byteLength,
      'Expect bufferedAmount to increase to byte length of sent buffer');

    pc1.close();
    assert_equals(dc1.bufferedAmount, helloBuffer.byteLength,
      'Expect bufferedAmount to not decrease after closing the peer connection');
  }, `${mode} bufferedAmount should not decrease after closing the peer connection`);

  promise_test(async t => {
    const [channel1, channel2] = await createDataChannelPair(t, options);
    channel1.addEventListener('bufferedamountlow', t.step_func_done(() => {
      assert_true(channel1.bufferedAmount <= channel1.bufferedAmountLowThreshold);
    }));
    const eventWatcher = new EventWatcher(t, channel1, ['bufferedamountlow']);
    channel1.send(helloString);
    await eventWatcher.wait_for(['bufferedamountlow']);
  }, `${mode} bufferedamountlow event fires after send() is complete`);

  promise_test(async t => {
    const [channel1, channel2] = await createDataChannelPair(t, options);
    channel1.send(helloString);
    assert_equals(channel1.bufferedAmount, helloString.length);
    await awaitMessage(channel2);
    assert_equals(channel1.bufferedAmount, 0);
  }, `${mode} bufferedamount is data.length on send(data)`);

  promise_test(async t => {
    const [channel1, channel2] = await createDataChannelPair(t, options);
    channel1.send(helloString);
    assert_equals(channel1.bufferedAmount, helloString.length);
    assert_equals(channel1.bufferedAmount, helloString.length);
  }, `${mode} bufferedamount returns the same amount if no more data is`);

  promise_test(async t => {
    const [channel1, channel2] = await createDataChannelPair(t, options);
    let eventFireCount = 0;
    channel1.addEventListener('bufferedamountlow', t.step_func(() => {
      assert_true(channel1.bufferedAmount <= channel1.bufferedAmountLowThreshold);
      assert_equals(++eventFireCount, 1);
    }));
    const eventWatcher = new EventWatcher(t, channel1, ['bufferedamountlow']);
    channel1.send(helloString);
    assert_equals(channel1.bufferedAmount, helloString.length);
    channel1.send(helloString);
    assert_equals(channel1.bufferedAmount, 2 * helloString.length);
    await eventWatcher.wait_for(['bufferedamountlow']);
  }, `${mode} bufferedamountlow event fires only once after multiple` +
     ` consecutive send() calls`);

  promise_test(async t => {
    const [channel1, channel2] = await createDataChannelPair(t, options);
    const eventWatcher = new EventWatcher(t, channel1, ['bufferedamountlow']);
    channel1.send(helloString);
    assert_equals(channel1.bufferedAmount, helloString.length);
    await eventWatcher.wait_for(['bufferedamountlow']);
    assert_equals(await awaitMessage(channel2), helloString);
    channel1.send(helloString);
    assert_equals(channel1.bufferedAmount, helloString.length);
    await eventWatcher.wait_for(['bufferedamountlow']);
    assert_equals(await awaitMessage(channel2), helloString);
  }, `${mode} bufferedamountlow event fires after each sent message`);
}
</script>
