import React from 'react';
import fetchMock from 'fetch-mock';
import FormRenderer from '@data-driven-forms/react-form-renderer';
import SetOwnershipForm from '../../components/set-ownership-form';
import createSchema from '../../components/set-ownership-form/ownership-form.schema';
import '../helpers/miqAjaxButton';
import '../helpers/miqSparkle';
import '../helpers/addFlash';
import { mount } from '../helpers/mountForm';

describe('Set ownership form component', () => {
  let initialProps;
  const submitSpy = jest.spyOn(window, 'miqAjaxButton');
  const flashSpy = jest.spyOn(window, 'add_flash');

  beforeEach(() => {
    initialProps = {
      ownershipItems: [{ id: '123456', kind: 'vms' }],
    };
    global.ManageIQ.controller = 'vms';
  });

  afterEach(() => {
    fetchMock.restore();
    submitSpy.mockReset();
    flashSpy.mockReset();
    global.ManageIQ.controller = null;
  });

  it('should correctly map group and owner options ', () => {
    const groupOptions = [{ label: 'Foo', value: '1' }, { label: 'Bar', value: '2' }];
    const ownerOptions = [{ label: 'Baz', value: '3' }, { label: 'Qux', value: '4' }];

    const expectedResult = [
      expect.objectContaining({
        options: [{
          value: '3',
          label: 'Baz',
        }, {
          value: '4',
          label: 'Qux',
        }],
      }),
      expect.objectContaining({
        options: [{
          value: '1',
          label: 'Foo',
        }, {
          value: '2',
          label: 'Bar',
        }],
      }),
    ];
    const { fields } = createSchema(ownerOptions, groupOptions);
    expect(fields).toEqual(expectedResult);
  });

  it('should request initialForm values after mount', (done) => {
    fetchMock
      .getOnce('/api/vms/123456?expand=resources&attributes=evm_owner_id,miq_group_id',
        { evm_owner_id: 'a', miq_group_id: 'z2' })
      .getOnce('/api/users?expand=resources&attributes=id,name&sort_by=name&sort_order=ascending',
        { resources: [{ name: 'f', id: 'a' }, { name: 's', id: 'z' }] })
      .getOnce('/api/groups?expand=resources&attributes=id,description&sort_by=description&sort_order=ascending',
        { resources: [{ description: 'f2', id: 'a2' }, { description: 's2', id: 'z2' }] })
      .getOnce('/api/tenant_groups/z2', {});

    const wrapper = mount(<SetOwnershipForm {...initialProps} />);
    setImmediate(() => {
      expect(wrapper.contains(<SetOwnershipForm {...initialProps} />)).toBeTruthy();
      done();
    });
  });

  it('should send correct data on save', (done) => {
    fetchMock
      .getOnce('/api/vms/123456?expand=resources&attributes=evm_owner_id,miq_group_id',
        { evm_owner_id: 'a', miq_group_id: 'z2' })
      .getOnce('/api/users?expand=resources&attributes=id,name&sort_by=name&sort_order=ascending',
        { resources: [{ name: 'f', id: 'a' }, { name: 's', id: 'z' }] })
      .getOnce('/api/groups?expand=resources&attributes=id,description&sort_by=description&sort_order=ascending',
        { resources: [{ description: 'f2', id: 'a2' }, { description: 's2', id: 'z2' }] })
      .getOnce('/api/tenant_groups/z2', {})
      .postOnce('/api/vms', {});

    const wrapper = mount(<SetOwnershipForm {...initialProps} />);
    setImmediate(() => {
      const Form = wrapper.find(FormRenderer).childAt(0);
      Form.instance().form.change('user', 'z');
      wrapper.update();
      wrapper.find('button').first().simulate('click');
      setImmediate(() => {
        expect(submitSpy).toHaveBeenCalledWith('/vms/ownership_update/?button=save', { objectIds: ['123456'] });
        done();
      });
    });
  });

  it('should send correct data on cancel', () => {
    const wrapper = mount(<SetOwnershipForm {...initialProps} />);
    wrapper.find('button').last().simulate('click');
    expect(submitSpy).toHaveBeenCalledWith('/vms/ownership_update/?button=cancel');
  });

  it('should reset formValues and add flash messages on reset click', () => {
    const wrapper = mount(<SetOwnershipForm {...initialProps} />);
    const Form = wrapper.find(FormRenderer).childAt(0);
    Form.instance().form.change('user', 'foo');
    expect(Form.instance().form.getState().values).toEqual({ user: 'foo' });
    wrapper.find('button').at(1).simulate('click');
    expect(Form.instance().form.getState().values).toEqual({});
    expect(flashSpy).toHaveBeenCalledWith(expect.any(String), 'warn');
  });
});

@@ -20,16 +20,60 @@
 react';%0A
+import %7B act %7D from 'react-dom/test-utils';%0A
 import f
@@ -1740,16 +1740,21 @@
 mount', 
+async
 (done) =
@@ -2329,37 +2329,77 @@
 /z2', %7B%7D);%0A%0A    
-const
+let wrapper;%0A    await act(async() =%3E %7B%0A     
  wrapper = mount
@@ -2444,39 +2444,21 @@
 %3E);%0A    
-setImmediate(() =%3E %7B%0A  
+%7D);%0A%0A
     expe
@@ -2532,34 +2532,32 @@
 uthy();%0A    
-  
 done();%0A
     %7D);%0A  %7D)
@@ -2544,24 +2544,16 @@
 done();%0A
-    %7D);%0A
   %7D);%0A%0A 
@@ -2592,16 +2592,21 @@
  save', 
+async
 (done) =
@@ -3217,29 +3217,69 @@
 , %7B%7D);%0A%0A    
-const
+let wrapper;%0A    await act(async() =%3E %7B%0A     
  wrapper = m
@@ -3328,39 +3328,20 @@
 %3E);%0A    
-setImmediate(() =%3E %7B%0A  
+%7D);%0A
     cons
@@ -3388,18 +3388,16 @@
 dAt(0);%0A
-  
     Form
@@ -3434,26 +3434,24 @@
 , 'z');%0A    
-  
 wrapper.upda
@@ -3452,24 +3452,51 @@
 r.update();%0A
+    await act(async() =%3E %7B%0A
       wrappe
@@ -3547,35 +3547,12 @@
     
-  setImmediate(() =%3E %7B%0A    
+%7D);%0A
     
@@ -3656,20 +3656,16 @@
 6'%5D %7D);%0A
-    
     done
@@ -3672,26 +3672,8 @@
 ();%0A
-      %7D);%0A    %7D);%0A
   %7D)

Use async act on set-ownership-form spec.