import { screen, render } from '@testing-library/react'
import { Dropzone } from './dropzone'

describe('<Dropzone />', () => {
  describe('children', () => {
    it('children gets rendered', () => {
      const Component = () => <div id="children-element">I am children</div>
      const { container } = render(<Dropzone>{Component}</Dropzone>)
      expect(container.querySelector('#children-element')).toBeInTheDocument()
    })

    it('state object gets passed to children', () => {
      const children = jest.fn()
      render(<Dropzone>{children}</Dropzone>)
      expect(children).toBeCalledWith({
        open: expect.anything(),
        isFocused: expect.anything(),
        isDragActive: expect.anything(),
        isDragAccept: expect.anything(),
        isDragReject: expect.anything(),
        isFileDialogActive: expect.anything(),
        acceptedFiles: expect.anything(),
        fileRejections: expect.anything(),
        rootRef: expect.anything(),
        inputRef: expect.anything(),
      })
    })

    it('{getRootProps} and {getInputProps} do NOT get passed to children', () => {
      const children = jest.fn()
      render(<Dropzone>{children}</Dropzone>)
      expect(children).not.toBeCalledWith({
        getRootProps: expect.anything(),
        getInputProps: expect.anything(),
      })
    })

    it('{rootRef, inputRef} are exposed', () => {
      let root
      let input
      const Component = ({ rootRef, inputRef }) => {
        root = rootRef
        input = inputRef
        return <div>I am children</div>
      }
      const { container } = render(<Dropzone>{Component}</Dropzone>)
      expect(container.querySelector('div')).toEqual(root.current)
      expect(container.querySelector('input')).toEqual(input.current)
    })
  })

  test('{rootProps} and {inputProps} get set correctly', () => {
    const dropOptions = {
      accept: {
        'image/jpeg': [],
      },
      minSize: 0,
      maxSize: 0,
      maxFiles: 0,
      preventDropOnDocument: true,
      noClick: false,
      noKeyboard: false,
      noDrag: false,
      noDragEventsBubbling: false,
      disabled: false,
      onDrop: jest.fn(),
      onDropAccepted: jest.fn(),
      onDropRejected: jest.fn(),
      getFilesFromEvent: jest.fn(),
      onFileDialogCancel: jest.fn(),
      onFileDialogOpen: jest.fn(),
      onError: jest.fn(),
      validator: jest.fn(),
      useFsAccessApi: true,
      autoFocus: false,
      multiple: true,
      onDragEnter: jest.fn(),
      onDragLeave: jest.fn(),
      onDragOver: jest.fn(),
    }

    const inputProps = {
      id: 'input-id',
      className: 'input-class-name',
    }

    const props = {
      ...dropOptions,
      inputProps,
      id: 'root-id',
      className: 'root-class-name',
    }

    const { container } = render(<Dropzone {...props} />)

    Object.keys(dropOptions).forEach((attr) => {
      expect(container.querySelector('div')).not.toHaveAttribute(attr)
    })

    expect(container.querySelector('div')).not.toHaveAttribute('inputProps')
    expect(container.querySelector('input')).not.toHaveAttribute('id', 'root-id')
    expect(container.querySelector('input')).not.toHaveAttribute('class', 'root-class-name')

    expect(container.querySelector('div')?.getAttribute('class')).toContain('root-class-name')
    expect(container.querySelector('div')).toHaveAttribute('id', 'root-id')
    expect(container.querySelector('input')).toHaveAttribute('id', 'input-id')
    expect(container.querySelector('input')).toHaveAttribute('class', 'input-class-name')
  })

  describe('data-testid', () => {
    it('should have default value', () => {
      const { container } = render(<Dropzone />)

      expect(container.querySelector('div')?.getAttribute('data-testid')).not.toBeNull()
    })

    it('should override default value', () => {
      render(<Dropzone data-testid="new-test-id" />)
      expect(screen.getByTestId('new-test-id')).toBeInTheDocument()
    })
  })
})
