import * as React from 'react' ; import { createTestComponent } from '@client/tests/util' ; import { ReviewDuplicates , rejectMutation , notADuplicateMutation , FETCH_DUPLICATES , createDuplicateDetailsQuery } from '@client/views/Duplicates/ReviewDuplicates' ; import { createStore } from '@client/store' ; import { ReactWrapper } from 'enzyme' ; import { DuplicateDetails } from '@client/components/DuplicateDetails' ; import { clone } from 'lodash' ; import { REGISTRAR_HOME } from '@client/navigation/routes' ; import { waitForElement , waitFor } from '@client/tests/wait-for-element' ; const assign = window . location . assign as jest . Mock ; describe ( 'Review Duplicates component' , ( ) => { const graphqlMock = [ { request : { query : FETCH_DUPLICATES , variables : { id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } , result : { data : { fetchBirthRegistration : { id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , registration : { id : '123' , duplicates : [ '450ce5e3-b495-4868-bb6a-1183ffd0fff1' ] } } } } } , { request : { query : FETCH_DUPLICATES , variables : { id : '460ce5e3-b495-4868-bb6a-1183ffd0fee1' } } , result : { data : { fetchBirthRegistration : { id : '460ce5e3-b495-4868-bb6a-1183ffd0fee1' , registration : { id : '123' , duplicates : [ ] } } } } } , { request : { query : createDuplicateDetailsQuery ( [ '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , '450ce5e3-b495-4868-bb6a-1183ffd0fff1' ] ) , variables : { duplicate0Id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , duplicate1Id : '450ce5e3-b495-4868-bb6a-1183ffd0fff1' } } , result : { data : { duplicate0 : { createdAt : '2019-01-22T09:46:02.547Z' , id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , registration : { id : '123' , trackingId : 'BFCJ02U' , type : 'BIRTH' , status : [ { type : 'DECLARED' , timestamp : '2019-01-22T09:46:02.547Z' , user : { name : [ { use : 'en' , firstNames : 'Shakib' , familyName : 'Al Hasan' } , { use : 'bn' , firstNames : '' , familyName : '' } ] , role : 'FIELD_AGENT' } , office : { name : 'Moktarpur Union Parishad' } , comments : [ { comment : 'note' } ] } ] } , child : { id : '123' , name : [ { use : 'bn' , firstNames : 'গায়ত্রী' , familyName : 'স্পিভক' } , { use : 'en' , firstNames : 'Gayatri' , familyName : 'Spivak' } ] , birthDate : '2018-08-01' , gender : 'female' } , mother : { id : '123' , name : [ { use : 'bn' , firstNames : 'গায়ত্রী' , familyName : 'স্পিভক' } , { use : 'en' , firstNames : 'Gayatri' , familyName : 'Spivak' } ] , birthDate : '2018-08-01' , gender : null , identifier : [ { id : '1' , type : 'NATIONAL_ID' } ] } , father : { id : '123' , name : [ { use : 'bn' , firstNames : 'গায়ত্রী' , familyName : 'স্পিভক' } , { use : 'en' , firstNames : 'Gayatri' , familyName : 'Spivak' } ] , birthDate : '2018-08-01' , gender : null , identifier : [ { id : '1' , type : 'NATIONAL_ID' } ] } } , duplicate1 : { createdAt : '2019-01-22T09:46:02.547Z' , id : '450ce5e3-b495-4868-bb6a-1183ffd0fff1' , registration : { id : 'hghgjhg' , trackingId : 'BFCJ02U' , type : 'BIRTH' , status : [ { type : 'REGISTERED' , timestamp : '2019-01-22T09:46:02.547Z' , user : { name : [ { use : 'en' , firstNames : 'Shakib' , familyName : 'Al Hasan' } , { use : 'bn' , firstNames : '' , familyName : '' } ] , role : 'FIELD_AGENT' } , office : { name : 'Moktarpur Union Parishad' } , comments : [ { comment : 'note' } ] } ] } , child : { id : '123' , name : [ { use : 'bn' , firstNames : 'গায়ত্রী' , familyName : 'স্পিভক' } , { use : 'en' , firstNames : 'Gayatri' , familyName : 'Spivak' } ] , birthDate : '2018-08-01' , gender : 'female' } , mother : { id : '123' , name : [ { use : 'bn' , firstNames : 'গায়ত্রী' , familyName : 'স্পিভক' } , { use : 'en' , firstNames : 'Gayatri' , familyName : 'Spivak' } ] , birthDate : '2018-08-01' , gender : null , identifier : [ { id : '1' , type : 'NATIONAL_ID' } ] } , father : { id : '123' , name : [ { use : 'bn' , firstNames : 'গায়ত্রী' , familyName : 'স্পিভক' } , { use : 'en' , firstNames : 'Gayatri' , familyName : 'Spivak' } ] , birthDate : '2018-08-01' , gender : null , identifier : [ { id : '1' , type : 'NATIONAL_ID' } ] } } } } } , { request : { query : notADuplicateMutation , variables : { id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , duplicateId : '450ce5e3-b495-4868-bb6a-1183ffd0fff1' } } , result : { data : { notADuplicate : 'ec9e0fae-8342-4fb9-803a-07b7c71325a1' } } } ] ; const graphqlMockMinimal = [ { request : { query : FETCH_DUPLICATES , variables : { id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } , result : { data : { fetchBirthRegistration : { id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , registration : { id : '123' , duplicates : [ '450ce5e3-b495-4868-bb6a-1183ffd0fff1' ] } } } } } , { request : { query : FETCH_DUPLICATES , variables : { id : '460ce5e3-b495-4868-bb6a-1183ffd0fee1' } } , result : { data : { fetchBirthRegistration : { id : '460ce5e3-b495-4868-bb6a-1183ffd0fee1' , registration : { id : '123' , duplicates : [ ] } } } } } , { request : { query : createDuplicateDetailsQuery ( [ '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , '450ce5e3-b495-4868-bb6a-1183ffd0fff1' ] ) , variables : { duplicate0Id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , duplicate1Id : '450ce5e3-b495-4868-bb6a-1183ffd0fff1' } } , result : { data : { duplicate0 : { createdAt : '2019-01-22T09:46:02.547Z' , id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , registration : { id : '123' , trackingId : 'BFCJ02U' , type : 'BIRTH' , status : [ { type : 'DECLARED' , timestamp : '2019-01-22T09:46:02.547Z' , user : null , office : { name : null } , comments : [ { comment : 'note' } ] } ] } , child : { id : '123' , name : [ { use : 'bn' , firstNames : 'গায়ত্রী' , familyName : 'স্পিভক' } , { use : 'en' , firstNames : 'Gayatri' , familyName : 'Spivak' } ] , birthDate : null , gender : 'female' } , mother : { id : '123' , name : [ { use : 'bn' , firstNames : 'গায়ত্রী' , familyName : 'স্পিভক' } , { use : 'en' , firstNames : 'Gayatri' , familyName : 'Spivak' } ] , birthDate : null , gender : null , identifier : [ { id : '1' , type : 'NATIONAL_ID' } ] } , father : { id : '123' , name : [ { use : 'bn' , firstNames : 'গায়ত্রী' , familyName : 'স্পিভক' } , { use : 'en' , firstNames : 'Gayatri' , familyName : 'Spivak' } ] , birthDate : null , gender : null , identifier : null } } , duplicate1 : { createdAt : '2019-01-22T09:46:02.547Z' , id : '450ce5e3-b495-4868-bb6a-1183ffd0fff1' , registration : { id : 'hghgjhg' , trackingId : 'BFCJ02U' , type : 'BIRTH' , status : [ { type : 'REGISTERED' , timestamp : '2019-01-22T09:46:02.547Z' , user : null , office : { name : null } , comments : [ { comment : 'note' } ] } ] } , child : { id : '123' , name : [ { use : 'bn' , firstNames : 'গায়ত্রী' , familyName : 'স্পিভক' } , { use : 'en' , firstNames : 'Gayatri' , familyName : 'Spivak' } ] , birthDate : null , gender : 'female' } , mother : { id : '123' , name : [ { use : 'bn' , firstNames : 'গায়ত্রী' , familyName : 'স্পিভক' } , { use : 'en' , firstNames : 'Gayatri' , familyName : 'Spivak' } ] , birthDate : null , gender : null , identifier : [ { id : '1' , type : 'NATIONAL_ID' } ] } , father : { id : '123' , name : [ { use : 'bn' , firstNames : 'গায়ত্রী' , familyName : 'স্পিভক' } , { use : 'en' , firstNames : 'Gayatri' , familyName : 'Spivak' } ] , birthDate : null , gender : null , identifier : null } } } } } ] ; it ( 'query gateway correctly and displays the returned duplicates correctly' , async ( ) => { const { store } = createStore ( ) ; const testComponent = await createTestComponent ( < ReviewDuplicates match = { { params : { applicationId : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } } />, store, graphqlMock); const details = await waitForElement ( testComponent . component , DuplicateDetails ) ; expect ( details ) . toHaveLength ( 2 ) ; } ) ; it ( 'query gateway correctly and displays the returned duplicates correctly in case of minimal data' , async ( ) => { const { store } = createStore ( ) ; const testComponent = await createTestComponent ( < ReviewDuplicates match = { { params : { applicationId : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } } />, store, graphqlMockMinimal); const details = await waitForElement ( testComponent . component , DuplicateDetails ) ; expect ( details ) . toHaveLength ( 2 ) ; } ) ; it ( 'displays error text when the query to fetch duplicates fails' , async ( ) => { const graphqlErrorMock = [ { request : { query : FETCH_DUPLICATES , variables : { id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } , result : { data : { fetchBirthRegistration : { id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , registration : { duplicates : [ '450ce5e3-b495-4868-bb6a-1183ffd0fff1' ] } } } } } , { request : { query : createDuplicateDetailsQuery ( [ '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , '450ce5e3-b495-4868-bb6a-1183ffd0fff1' ] ) , variables : { duplicate0Id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , duplicate1Id : '450ce5e3-b495-4868-bb6a-1183ffd0fff1' } } , error : new Error ( 'boom!' ) } ] ; const { store } = createStore ( ) ; const testComponent = await createTestComponent ( < ReviewDuplicates match = { { params : { applicationId : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } } />, store, graphqlErrorMock); const error = await waitForElement ( testComponent . component , '#duplicates-error-text' ) ; expect ( error . children ( ) . hostNodes ( ) . text ( ) ) . toBe ( 'An error occurred while fetching data' ) ; } ) ; it ( 'displays error text when the query to fetch the duplicates DETAILS fails' , async ( ) => { const graphqlErrorMock = [ { request : { query : FETCH_DUPLICATES , variables : { id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } , error : new Error ( 'boom!' ) } ] ; const { store } = createStore ( ) ; const testComponent = await createTestComponent ( < ReviewDuplicates match = { { params : { applicationId : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } } />, store, graphqlErrorMock); const error = await waitForElement ( testComponent . component , '#duplicates-error-text' ) ; expect ( error . children ( ) . hostNodes ( ) . text ( ) ) . toBe ( 'An error occurred while fetching data' ) ; } ) ; describe ( 'reject for duplication' , ( ) => { let component ; beforeEach ( async ( ) => { const { store } = createStore ( ) ; const testComponent = await createTestComponent ( < ReviewDuplicates match = { { params : { applicationId : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } } />, store, graphqlMock); component = testComponent . component ; await waitForElement ( component , '#review-duplicates-grid' ) ; } ) ; it ( 'detail boxes are loaded properly' , ( ) => { expect ( component . find ( '#detail_box_450ce5e3-b495-4868-bb6a-1183ffd0fee1' ) . hostNodes ( ) ) . toHaveLength ( 1 ) ; expect ( component . find ( '#detail_box_450ce5e3-b495-4868-bb6a-1183ffd0fff1' ) . hostNodes ( ) ) . toHaveLength ( 1 ) ; } ) ; it ( 'reject confirmation shows up if reject link is clicked' , ( ) => { component . find ( '#reject_link_450ce5e3-b495-4868-bb6a-1183ffd0fee1' ) . hostNodes ( ) . simulate ( 'click' ) ; component . update ( ) ; expect ( component . find ( '#reject_confirm' ) . hostNodes ( ) ) . toHaveLength ( 1 ) ; } ) ; it ( 'back link on reject confirm modal hides the confirm modal' , ( ) => { component . find ( '#reject_link_450ce5e3-b495-4868-bb6a-1183ffd0fee1' ) . hostNodes ( ) . simulate ( 'click' ) ; component . find ( '#back_link' ) . hostNodes ( ) . simulate ( 'click' ) ; component . update ( ) ; expect ( component . find ( '#reject_confirm' ) . hostNodes ( ) ) . toHaveLength ( 0 ) ; } ) ; it ( 'successfuly rejects the application' , async ( ) => { const mock = clone ( graphqlMock ) ; mock . push ( { request : { query : rejectMutation , variables : { id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , reason : 'duplicate' } } , result : { data : { markEventAsVoided : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } } ) ; const { store } = createStore ( ) ; const testComponent = await createTestComponent ( < ReviewDuplicates match = { { params : { applicationId : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } } />, store, mock); await new Promise ( ( resolve ) => { setTimeout ( resolve , 100 ) ; } ) ; testComponent . component . update ( ) ; testComponent . component . find ( '#reject_link_450ce5e3-b495-4868-bb6a-1183ffd0fee1' ) . hostNodes ( ) . simulate ( 'click' ) ; testComponent . component . update ( ) ; testComponent . component . find ( '#reject_confirm' ) . hostNodes ( ) . simulate ( 'click' ) ; await new Promise ( ( resolve ) => { setTimeout ( resolve , 100 ) ; } ) ; testComponent . component . update ( ) ; expect ( testComponent . component . find ( '#reject_confirm' ) . hostNodes ( ) ) . toHaveLength ( 0 ) ; } ) ; } ) ; describe ( 'remove duplication mark' , ( ) => { let component ; beforeEach ( async ( ) => { const { store } = createStore ( ) ; const testComponent = await createTestComponent ( < ReviewDuplicates match = { { params : { applicationId : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } } />, store, graphqlMock); component = testComponent . component ; await new Promise ( ( resolve ) => { setTimeout ( resolve , 100 ) ; } ) ; component . update ( ) ; } ) ; it ( 'reject confirmation shows up if reject link is clicked' , ( ) => { component . find ( '#not_duplicate_link_450ce5e3-b495-4868-bb6a-1183ffd0fee1' ) . hostNodes ( ) . simulate ( 'click' ) ; component . update ( ) ; expect ( component . find ( '#not_duplicate_confirm' ) . hostNodes ( ) ) . toHaveLength ( 1 ) ; } ) ; it ( 'back link on reject confirm modal hides the confirm modal' , ( ) => { component . find ( '#not_duplicate_link_450ce5e3-b495-4868-bb6a-1183ffd0fee1' ) . hostNodes ( ) . simulate ( 'click' ) ; component . find ( '#not_duplicate_close' ) . hostNodes ( ) . simulate ( 'click' ) ; component . update ( ) ; expect ( component . find ( '#not_duplicate_confirm' ) . hostNodes ( ) ) . toHaveLength ( 0 ) ; } ) ; it ( 'successfully removes duplicate from application' , async ( ) => { const mock = clone ( graphqlMock ) ; mock . push ( { request : { query : notADuplicateMutation , variables : { id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , duplicateId : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } , result : { data : { notADuplicate : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } } ) ; const { store } = createStore ( ) ; const testComponent = await createTestComponent ( < ReviewDuplicates match = { { params : { applicationId : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } } />, store, mock); await new Promise ( ( resolve ) => { setTimeout ( resolve , 100 ) ; } ) ; testComponent . component . update ( ) ; testComponent . component . find ( '#not_duplicate_link_450ce5e3-b495-4868-bb6a-1183ffd0fee1' ) . hostNodes ( ) . simulate ( 'click' ) ; testComponent . component . update ( ) ; testComponent . component . find ( '#not_duplicate_confirm' ) . hostNodes ( ) . simulate ( 'click' ) ; await new Promise ( ( resolve ) => { setTimeout ( resolve , 100 ) ; } ) ; testComponent . component . update ( ) ; expect ( testComponent . component . find ( '#not_duplicate_confirm' ) . hostNodes ( ) ) . toHaveLength ( 0 ) ; } ) ; it ( 'successfully redirects to Registration-Home if all duplicates removed' , async ( ) => { const mock = clone ( graphqlMock ) ; mock . push ( { request : { query : notADuplicateMutation , variables : { id : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' , duplicateId : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } , result : { data : { notADuplicate : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } } ) ; const { store } = createStore ( ) ; const testComponent = await createTestComponent ( < ReviewDuplicates match = { { params : { applicationId : '450ce5e3-b495-4868-bb6a-1183ffd0fee1' } } } />, store, mock); const link = await waitForElement ( testComponent . component , '#not_duplicate_link_450ce5e3-b495-4868-bb6a-1183ffd0fee1' ) ; link . hostNodes ( ) . simulate ( 'click' ) ; const confirm = await waitForElement ( testComponent . component , '#not_duplicate_confirm' ) ; confirm . hostNodes ( ) . simulate ( 'click' ) ; await waitFor ( ( ) => assign . mock . calls . length > 0 ) ; expect ( assign ) . toBeCalledWith ( REGISTRAR_HOME ) ; } ) ; it ( 'successfully redirects to Registration-Home if no duplicates returned from fetch query' , async ( ) => { const { store } = createStore ( ) ; const testComponent = await createTestComponent ( < ReviewDuplicates match = { { params : { applicationId : '460ce5e3-b495-4868-bb6a-1183ffd0fee1' } } } />, store, graphqlMock); await new Promise ( ( resolve ) => { setTimeout ( resolve , 100 ) ; } ) ; testComponent . component . update ( ) ; await new Promise ( ( resolve ) => { setTimeout ( resolve , 100 ) ; } ) ; testComponent . component . update ( ) ; expect ( assign ) . toBeCalledWith ( REGISTRAR_HOME ) ; } ) ; } ) ; } ) ;