<!doctype html>
<meta charset=utf-8>
<title>onaddstream tests</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
  'use strict';

  const stopTracks = (...streams) => {
    streams.forEach(stream => stream.getTracks().forEach(track => track.stop()));
  };

  const collectEvents = (target, name, check) => {
    const events = [];
    const handler = e => {
      check(e);
      events.push(e);
    };

    target.addEventListener(name, handler);

    const finishCollecting = () => {
      target.removeEventListener(name, handler);
      return events;
    };

    return {finish: finishCollecting};
  };

  const collectAddTrackEvents = stream => {
    const checkEvent = e => {
      assert_true(e.track instanceof MediaStreamTrack, "Track is set on event");
      assert_true(stream.getTracks().includes(e.track),
        "track in addtrack event is in the stream");
    };
    return collectEvents(stream, "addtrack", checkEvent);
  };

  const collectRemoveTrackEvents = stream => {
    const checkEvent = e => {
      assert_true(e.track instanceof MediaStreamTrack, "Track is set on event");
      assert_true(!stream.getTracks().includes(e.track),
        "track in removetrack event is not in the stream");
    };
    return collectEvents(stream, "removetrack", checkEvent);
  };

  const collectTrackEvents = pc => {
    const checkEvent = e => {
      assert_true(e.track instanceof MediaStreamTrack, "Track is set on event");
      assert_true(e.receiver instanceof RTCRtpReceiver, "Receiver is set on event");
      assert_true(e.transceiver instanceof RTCRtpTransceiver, "Transceiver is set on event");
      assert_true(Array.isArray(e.streams), "Streams is set on event");
      e.streams.forEach(stream => {
        assert_true(stream.getTracks().includes(e.track),
           "Each stream in event contains the track");
      });
      assert_equals(e.receiver, e.transceiver.receiver,
                    "Receiver belongs to transceiver");
      assert_equals(e.track, e.receiver.track,
                    "Track belongs to receiver");
    };

    return collectEvents(pc, "track", checkEvent);
  };

  // comparable() - produces copy of object that is JSON comparable.
  // o = original object (required)
  // t = template of what to examine. Useful if o is non-enumerable (optional)

  const comparable = (o, t = o) => {
    if (typeof o != 'object' || !o) {
      return o;
    }
    if (Array.isArray(t) && Array.isArray(o)) {
      return o.map((n, i) => comparable(n, t[i]));
    }
    return Object.keys(t).sort()
        .reduce((r, key) => (r[key] = comparable(o[key], t[key]), r), {});
  };

  const stripKeyQuotes = s => s.replace(/"(\w+)":/g, "$1:");

  const hasProps = (observed, expected) => {
    const observable = comparable(observed, expected);
    assert_equals(stripKeyQuotes(JSON.stringify(observable)),
       stripKeyQuotes(JSON.stringify(comparable(expected))));
  };

  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    const stream1 = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
    t.add_cleanup(() => stopTracks(stream1));
    const audio1 = stream1.getAudioTracks()[0];
    pc1.addTrack(audio1, stream1);
    const video1 = stream1.getVideoTracks()[0];
    pc1.addTrack(video1, stream1);

    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());
    const stream2 = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
    t.add_cleanup(() => stopTracks(stream2));
    const audio2 = stream2.getAudioTracks()[0];
    pc2.addTrack(audio2, stream2);
    const video2 = stream2.getVideoTracks()[0];
    pc2.addTrack(video2, stream2);

    const offer = await pc1.createOffer();

    let trackEventCollector = collectTrackEvents(pc2);
    let addstreamEventCollector = collectEvents(pc2, "addstream", e => {
      hasProps(e, {stream: {id: stream1.id}});
      assert_equals(e.stream.getAudioTracks().length, 1, "One audio track");
      assert_equals(e.stream.getVideoTracks().length, 1, "One video track");
    });

    await pc2.setRemoteDescription(offer);

    let addstreamEvents = addstreamEventCollector.finish();
    assert_equals(addstreamEvents.length, 1, "Should have 1 addstream event");

    let trackEvents = trackEventCollector.finish();

    hasProps(trackEvents,
      [
        {streams: [addstreamEvents[0].stream]},
        {streams: [addstreamEvents[0].stream]}
      ]);

    await pc1.setLocalDescription(offer);
    const answer = await pc2.createAnswer();

    trackEventCollector = collectTrackEvents(pc1);
    addstreamEventCollector = collectEvents(pc1, "addstream", e => {
      hasProps(e, {stream: {id: stream2.id}});
      assert_equals(e.stream.getAudioTracks().length, 1, "One audio track");
      assert_equals(e.stream.getVideoTracks().length, 1, "One video track");
    });

    await pc1.setRemoteDescription(answer);
    addstreamEvents = addstreamEventCollector.finish();
    assert_equals(addstreamEvents.length, 1, "Should have 1 addstream event");

    trackEvents = trackEventCollector.finish();

    hasProps(trackEvents,
      [
        {streams: [addstreamEvents[0].stream]},
        {streams: [addstreamEvents[0].stream]}
      ]);
  },"Check onaddstream");
</script>
