import * as React from 'react';
import { mount } from 'enzyme';
import sinon from 'sinon';

function isImageLoaded(img: HTMLImageElement) {
  return img.complete && img.naturalHeight > 0;
}

type Props = {
  src: string,
  onLoad: () => void,
};

class Image extends React.Component<Props> {
  imageElement: ?HTMLImageElement;

  componentDidMount() {
    if (this.imageElement && isImageLoaded(this.imageElement)) {
      this.props.onLoad();
    }
  }

  setImageElement = (img: ?HTMLImageElement) => {
    this.imageElement = img;
  };

  render() {
    const { src, onLoad } = this.props;
    return (
      <img src={src} ref={this.setImageElement} onLoad={onLoad} />
    );
  }
}

it('calls onLoad callback on load', () => {
  const onLoad = sinon.spy();
  const wrapper = mount(<Image src=“foo” onLoad={onLoad} />);
  wrapper.find('img').simulate('load');
  assert(onLoad.calledOnce);
});

it('calls onLoad callback if image is loaded on mount', () => {
  class LoadedImage extends Image {
    originalSetImageElement = this.setImageElement;
    setImageElement = (img) => {
      if (img) {
        Object.defineProperty(img, 'complete', { value: true });
        Object.defineProperty(img, 'naturalHeight', { value: 100 });
      }
      this.originalSetImageElement(img);
    };
  }

  const onLoad = sinon.spy();
  const wrapper = mount(<LoadedImage src=“foo” onLoad={onLoad} />);
  assert(onLoad.calledOnce);
});

class LoadedImage extends Image {
  setImageElement = (img) => {
    if (img) {
      Object.defineProperty(img, 'complete', { value: true });
      Object.defineProperty(img, 'naturalHeight', { value: 100 });
    }
    // Doesn't work...
    super.setImageElement(img);
  };
}