// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:html';
import 'package:test/test.dart';
import 'package:observatory/models.dart' as M;
import 'package:observatory/src/elements/nav/notify.dart';
import 'package:observatory/src/elements/vm_connect_target.dart';
import 'package:observatory/src/elements/vm_connect.dart';
import '../mocks.dart';

void load(_) {}

main() {
  VMConnectElement.tag.ensureRegistration();

  final nTag = NavNotifyElement.tag.name;
  final tTag = VMConnectTargetElement.tag.name;

  group('instantiation', () {
    test('default', () {
      final e = new VMConnectElement(
          new TargetRepositoryMock(), load, new NotificationRepositoryMock());
      expect(e, isNotNull, reason: 'element correctly created');
    });
  });
  test('is correctly listening', () async {
    final targets = new TargetRepositoryMock();
    final e =
        new VMConnectElement(targets, load, new NotificationRepositoryMock());
    document.body.append(e);
    await e.onRendered.first;
    expect(targets.hasListeners, isTrue, reason: 'is listening');
    e.remove();
    await e.onRendered.first;
    expect(targets.hasListeners, isFalse, reason: 'is no more listening');
  });
  group('elements', () {
    test('created after attachment', () async {
      final targets = new TargetRepositoryMock(list: const [
        const TargetMock(name: 't-1'),
        const TargetMock(name: 't-2'),
      ]);
      final e =
          new VMConnectElement(targets, load, new NotificationRepositoryMock());
      document.body.append(e);
      await e.onRendered.first;
      expect(targets.listInvoked, isTrue, reason: 'should invoke list()');
      expect(e.children.length, isNonZero, reason: 'has elements');
      expect(e.querySelectorAll(nTag).length, equals(1));
      expect(e.querySelectorAll(tTag).length, equals(2));
      e.remove();
      await e.onRendered.first;
      expect(e.children.length, isZero, reason: 'is empty');
    });
    test('react to update event', () async {
      final list = <TargetMock>[const TargetMock(name: 't-1')];
      final targets = new TargetRepositoryMock(list: list);
      final e =
          new VMConnectElement(targets, load, new NotificationRepositoryMock());
      document.body.append(e);
      await e.onRendered.first;
      expect(e.querySelectorAll(tTag).length, equals(1));
      list.add(const TargetMock(name: 't-2'));
      targets.triggerChangeEvent();
      await e.onRendered.first;
      expect(e.querySelectorAll(tTag).length, equals(2));
      e.remove();
      await e.onRendered.first;
      expect(e.children.length, isZero, reason: 'is empty');
    });
  });
  group('invokes', () {
    test('add on click', () async {
      final address = 'ws://host:1234/ws';
      final list = <TargetMock>[const TargetMock(name: 't-1')];
      final targets = new TargetRepositoryMock(
          list: list,
          add: expectAsync1((String val) {
            expect(val, equals(address));
          }, count: 1, reason: 'should be invoked'));
      final e = new VMConnectElement(
          targets, load, new NotificationRepositoryMock(),
          address: address);
      document.body.append(e);
      await e.onRendered.first;
      (e.querySelector('button.vm_connect') as ButtonElement).click();
      e.remove();
      await e.onRendered.first;
    });
    test('connect', () async {
      final list = <TargetMock>[const TargetMock(name: 't-1')];
      final targets = new TargetRepositoryMock(
          list: list,
          setCurrent: expectAsync1((M.Target t) {
            expect(t, equals(list[0]));
          }, count: 1, reason: 'should be invoked'));
      final e =
          new VMConnectElement(targets, load, new NotificationRepositoryMock());
      document.body.append(e);
      await e.onRendered.first;
      (e.querySelector(tTag) as VMConnectTargetElement).connect();
      e.remove();
      await e.onRendered.first;
    });
    test('delete', () async {
      final list = <TargetMock>[const TargetMock(name: 't-1')];
      final targets = new TargetRepositoryMock(
          list: list,
          delete: expectAsync1((M.Target t) {
            expect(t, equals(list[0]));
          }, count: 1, reason: 'should be invoked'));
      final e =
          new VMConnectElement(targets, load, new NotificationRepositoryMock());
      document.body.append(e);
      await e.onRendered.first;
      (e.querySelector(tTag) as VMConnectTargetElement).delete();
      e.remove();
      await e.onRendered.first;
    });
  });
}
