Skip to content

Commit

Permalink
Add unit test for the UpdateLinkAttribute
Browse files Browse the repository at this point in the history
  • Loading branch information
bangank36 committed Sep 21, 2023
1 parent 797ea44 commit 7895ebd
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 77 deletions.
60 changes: 17 additions & 43 deletions packages/block-library/src/button/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
*/
import classnames from 'classnames';

/**
* Internal dependencies
*/
import {
updateLinkAttributes,
NEW_TAB_TARGET,
NOFOLLOW_REL
} from './utils';

/**
* WordPress dependencies
*/
Expand Down Expand Up @@ -32,11 +41,6 @@ import { displayShortcut, isKeyboardEvent } from '@wordpress/keycodes';
import { link, linkOff } from '@wordpress/icons';
import { createBlock } from '@wordpress/blocks';
import { useMergeRefs } from '@wordpress/compose';
import { prependHTTP } from '@wordpress/url';

const NEW_TAB_REL = 'noreferrer noopener';
const NEW_TAB_TARGET = '_blank';
const NOFOLLOW_REL = 'nofollow';

const LINK_SETTINGS = [
...LinkControl.DEFAULT_LINK_SETTINGS,
Expand Down Expand Up @@ -102,37 +106,6 @@ function ButtonEdit( props ) {

const TagName = tagName || 'a';

function updateLinkAttributes( newUrl, opensInNewWindow, nofollow ) {
let newLinkTarget;
// Since `rel` is editable attribute, we need to check for existing values and proceed accordingly.
let updatedRel = rel || '';

if ( opensInNewWindow ) {
newLinkTarget = NEW_TAB_TARGET;
updatedRel = updatedRel?.includes( NEW_TAB_REL )
? updatedRel
: updatedRel + ` ${ NEW_TAB_REL }`;
} else {
const relRegex = new RegExp( `\\b${ NEW_TAB_REL }\\s*`, 'g' );
updatedRel = updatedRel?.replace( relRegex, '' ).trim();
}

if ( nofollow ) {
updatedRel = updatedRel?.includes( NOFOLLOW_REL )
? updatedRel
: updatedRel + ` ${ NOFOLLOW_REL }`;
} else {
const relRegex = new RegExp( `\\b${ NOFOLLOW_REL }\\s*`, 'g' );
updatedRel = updatedRel?.replace( relRegex, '' ).trim();
}

setAttributes( {
url: prependHTTP( newUrl ),
linkTarget: newLinkTarget,
rel: updatedRel || undefined,
} );
}

function setButtonText( newText ) {
// Remove anchor tags from button text content.
setAttributes( { text: newText.replace( /<\/?a[^>]*>/g, '' ) } );
Expand Down Expand Up @@ -282,15 +255,16 @@ function ButtonEdit( props ) {
<LinkControl
value={ linkValue }
onChange={ ( {
url: newURL = '',
url: newURL,
opensInNewTab: newOpensInNewTab,
nofollow: newNoFollow,
nofollow: newNofollow,
} ) =>
updateLinkAttributes(
newURL,
newOpensInNewTab,
newNoFollow
)
setAttributes( updateLinkAttributes( {
rel,
url: newURL,
opensInNewTab: newOpensInNewTab,
nofollow: newNofollow
} ) )
}
onRemove={ () => {
unlink();
Expand Down
143 changes: 109 additions & 34 deletions packages/block-library/src/button/test/update-link-attribute.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,109 @@
// npm run test:unit -- packages/block-library/src/button

import React from 'react';
import { render } from '@testing-library/react';
import ButtonEdit from '../edit'; // Import your ButtonEdit component

// Mock the setAttributes function
const mockSetAttributes = jest.fn();

describe('ButtonEdit Component', () => {
it('should update link attributes correctly', () => {
const attributes = {
// Initialize your attributes as needed for the test
};

const { updateLinkAttributes } = render(
<ButtonEdit
attributes={attributes}
setAttributes={mockSetAttributes}
// Add other required props here
/>
);

// Call the updateLinkAttributes method with desired arguments
updateLinkAttributes('newURL', true, true);

// Assert that setAttributes was called with the expected parameters
expect(mockSetAttributes).toHaveBeenCalledWith({
url: 'newURL',
linkTarget: 'new_tab_target_value', // Replace with your expected value
rel: 'rel_value', // Replace with your expected value
});
});
});
/**
* Internal dependencies
*/
import { updateLinkAttributes } from '../utils';

describe( 'updateLinkAttributes method', () => {
it( 'should correctly handle unassigned rel', () => {
const options = {
url: 'example.com',
opensInNewTab: true,
nofollow: false,
};

const result = updateLinkAttributes(options);

expect( result.url ).toEqual( 'http://example.com' );
expect( result.linkTarget ).toEqual( '_blank' );
expect( result.rel ).toEqual( 'noreferrer noopener' );
} );

it( 'should return empty rel value as undefined', () => {
const options = {
url: 'example.com',
opensInNewTab: false,
nofollow: false,
};

const result = updateLinkAttributes(options);

expect( result.url ).toEqual( 'http://example.com' );
expect( result.linkTarget ).toEqual( undefined );
expect( result.rel ).toEqual( undefined );
} );

it( 'should correctly handle rel with existing values', () => {
const options = {
url: 'example.com',
opensInNewTab: true,
nofollow: true,
rel: 'rel_value',
};

const result = updateLinkAttributes(options);

expect( result.url ).toEqual( 'http://example.com' );
expect( result.linkTarget ).toEqual( '_blank' );
expect( result.rel ).toEqual( 'rel_value noreferrer noopener nofollow' );
} );

it( 'should correctly update link attributes with opensInNewTab', () => {
const options = {
url: 'example.com',
opensInNewTab: true,
nofollow: false,
rel: 'rel_value',
};

const result = updateLinkAttributes(options);

expect( result.url ).toEqual( 'http://example.com' );
expect( result.linkTarget ).toEqual( '_blank' );
expect( result.rel ).toEqual( 'rel_value noreferrer noopener' );
} );

it ( 'should correctly update link attributes with nofollow', () => {
const options = {
url: 'example.com',
opensInNewTab: false,
nofollow: true,
rel: 'rel_value',
};

const result = updateLinkAttributes(options);

expect( result.url ).toEqual( 'http://example.com' );
expect( result.linkTarget ).toEqual( undefined );
expect( result.rel ).toEqual( 'rel_value nofollow' );
} );

it ( 'should correctly handle rel with existing nofollow values and remove duplicates', () => {
const options = {
url: 'example.com',
opensInNewTab: true,
nofollow: true,
rel: 'rel_value nofollow',
};

const result = updateLinkAttributes(options);

expect( result.url ).toEqual( 'http://example.com' );
expect( result.linkTarget ).toEqual( '_blank' );
expect( result.rel ).toEqual( 'rel_value nofollow noreferrer noopener' );
} );

it ( 'should correctly handle rel with existing new tab values and remove duplicates', () => {
const options = {
url: 'example.com',
opensInNewTab: true,
nofollow: false,
rel: 'rel_value noreferrer noopener',
};

const result = updateLinkAttributes(options);

expect( result.url ).toEqual( 'http://example.com' );
expect( result.linkTarget ).toEqual( '_blank' );
expect( result.rel ).toEqual( 'rel_value noreferrer noopener' );
} );
} )
51 changes: 51 additions & 0 deletions packages/block-library/src/button/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* WordPress dependencies
*/
import { prependHTTP } from '@wordpress/url';

/**
* Constants
*/
export const NEW_TAB_REL = 'noreferrer noopener';
export const NEW_TAB_TARGET = '_blank';
export const NOFOLLOW_REL = 'nofollow';

/**
* Updates the link attributes.
*
* @param {Object} attributes The current block attributes.
* @param {string} attributes.rel The current link rel attribute.
* @param {string} attributes.url The current link url.
* @param {boolean} attributes.opensInNewTab Whether the link should open in a new window.
* @param {boolean} attributes.nofollow Whether the link should be marked as nofollow.
*/
export function updateLinkAttributes( { rel = '', url = '', opensInNewTab, nofollow } ) {
let newLinkTarget;
// Since `rel` is editable attribute, we need to check for existing values and proceed accordingly.
let updatedRel = rel;

if ( opensInNewTab ) {
newLinkTarget = NEW_TAB_TARGET;
updatedRel = updatedRel?.includes( NEW_TAB_REL )
? updatedRel
: updatedRel + ` ${ NEW_TAB_REL }`;
} else {
const relRegex = new RegExp( `\\b${ NEW_TAB_REL }\\s*`, 'g' );
updatedRel = updatedRel?.replace( relRegex, '' ).trim();
}

if ( nofollow ) {
updatedRel = updatedRel?.includes( NOFOLLOW_REL )
? updatedRel
: updatedRel + ` ${ NOFOLLOW_REL }`;
} else {
const relRegex = new RegExp( `\\b${ NOFOLLOW_REL }\\s*`, 'g' );
updatedRel = updatedRel?.replace( relRegex, '' ).trim();
}

return {
url: prependHTTP( url ),
linkTarget: newLinkTarget,
rel: updatedRel || undefined,
};
}

0 comments on commit 7895ebd

Please sign in to comment.