blob: 9f80522b12d6ebc59ff63ad0270f99402f2fd5d1 [file] [log] [blame]
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
import { mount } from 'enzyme';
import React from 'react';
import sinon from 'sinon';
import utils from '../../../../../test/mocha/testUtils';
import FauxtonAPI from '../../../../core/api';
import '../../base';
import DesignDoc from '../components/DesignDoc';
import IndexSection from '../components/IndexSection';
import MainSidebar from '../components/MainSidebar';
import { act } from 'react-dom/test-utils';
const { restore} = utils;
describe('DesignDoc', () => {
const database = { id: 'test-db' };
const selectedNavInfo = {
navItem: 'all-docs',
designDocName: '',
designDocSection: '',
indexName: ''
};
const defaultProps = {
database,
toggle: () => {},
sidebarListTypes: [],
isExpanded: true,
isPartitioned: false,
designDocName: 'doc-$-#-.1',
selectedNavInfo,
toggledSections: {},
designDoc: {},
showDeleteIndexModal: () => {},
showCloneIndexModal: () => {}
};
afterEach(() => {
restore(FauxtonAPI.urls);
});
it('confirm URLs are properly encoded when design doc name has special chars', async() => {
const wrapper = mount(<DesignDoc
{...defaultProps}
designDocName={'doc-$-#-.1'}
/>);
expect(wrapper.find('a.toggle-view.accordion-header').props()['href']).toContain('/doc-%24-%23-.1');
const dropdownBtn = wrapper.find('a.icon.fonticon-plus-circled').at(0);
dropdownBtn.simulate('click');
await act(async () => {
wrapper.update();
});
const menuItem = wrapper.find('a.dropdown-item');
expect(menuItem.first().prop('href')).toContain('/doc-%24-%23-.1');
});
it('check toggle() works when design doc name has special characters', () => {
sinon.stub(FauxtonAPI, 'urls');
const toggleStub = sinon.stub();
const wrapper = mount(<DesignDoc
{...defaultProps}
toggle={toggleStub}
designDocName={'id#1'}
selectedNavInfo={{}}
/>);
// NOTE: wrapper.find doesn't work special chars so we use class name instead
wrapper.find('div.accordion-list-item').simulate('click', {preventDefault: sinon.stub()});
expect(toggleStub.calledOnce).toBeTruthy();
});
//here
it('confirm only single sub-option is shown by default (metadata link)', function () {
const el = mount(<DesignDoc
{...defaultProps}
designDoc={{ customProp: { one: 'something' } }}
designDocName={'doc-$-#-.1'}
/>);
const subOptions = el.find('.accordion-body li');
expect(subOptions.length).toBe(1);
});
it('confirm design doc sidebar extensions appear', function () {
sinon.stub(FauxtonAPI, 'urls');
const el = mount(<DesignDoc
{...defaultProps}
sidebarListTypes={[{
selector: 'customProp',
name: 'Search Indexes',
icon: 'icon-here',
urlNamespace: 'whatever',
indexLabel: 'the label',
onDelete: () => {},
onClone: () => {}
}]}
designDoc={{ customProp: { one: 'something' } }}
designDocName={'doc-$-#-.1'}
/>);
const subOptions = el.find('.accordion-body li');
expect(subOptions.length).toBe(3); // 1 for "Metadata" row, 1 for Type List row ("search indexes") and one for the index itself
});
it('confirm design doc sidebar extensions do not appear when they have no content', function () {
sinon.stub(FauxtonAPI, 'urls');
const el = mount(<DesignDoc
{...defaultProps}
sidebarListTypes={[{
selector: 'customProp',
name: 'Search Indexes',
icon: 'icon-here',
urlNamespace: 'whatever',
indexLabel: 'the label',
onDelete: () => {},
onClone: () => {}
}]}
designDocName={'doc-$-#-.1'}
/>);
const subOptions = el.find('.accordion-body li');
expect(subOptions.length).toBe(1);
});
it('confirm doc metadata page is highlighted if selected', function () {
const el = mount(<DesignDoc
{...defaultProps}
selectedNavInfo={{
navItem: 'designDoc',
designDocName: 'id',
designDocSection: 'metadata',
indexName: ''
}}
designDocName={'doc-$-#-.1'}
/>);
expect(el.find('.accordion-body li.active a').text()).toBe('Metadata');
});
it('shows different icons for global and partitioned ddocs', () => {
const wrapper = mount(<DesignDoc
{...defaultProps}
designDocName={'doc-$-#-.1'}
isPartitioned={false}
/>);
expect(wrapper.find('i.fonticon-document').exists()).toBeTruthy();
const wrapper2 = mount(<DesignDoc
{...defaultProps}
designDocName={'doc-$-#-.1'}
isPartitioned={true}
/>);
expect(wrapper2.find('i.fonticon-documents').exists()).toBeTruthy();
});
it('confirms links only include the partition key when one is selected', async() => {
const wrapper = mount(<DesignDoc
{...defaultProps}
selectedPartitionKey={'part-key-$-%1'}
/>);
// Metadata link
expect(wrapper.find('a.toggle-view.accordion-header').props()['href']).toContain('/_partition/part-key-%24-%251/');
// New View link
const dropdownBtn = wrapper.find('a.icon.fonticon-plus-circled').at(0);
dropdownBtn.simulate('click');
await act(async () => {
wrapper.update();
});
const menuItem = wrapper.find('a.dropdown-item');
expect(menuItem.first().prop('href')).toContain('/doc-%24-%23-.1');
const wrapper2 = mount(<DesignDoc
{...defaultProps}
/>);
// Metadata link (ii)
expect(wrapper2.find('a.toggle-view.accordion-header').props()['href']).not.toContain('/_partition/');
// New View link (ii)
const dropdownBtn2 = wrapper2.find('a.icon.fonticon-plus-circled').at(0);
dropdownBtn2.simulate('click');
await act(async () => {
wrapper2.update();
});
const menuItem2 = wrapper2.find('a.dropdown-item');
expect(menuItem2.first().prop('href')).not.toContain('/_partition/');
});
});
describe('MainSidebar', () => {
const defaultProps = {
databaseName: 'test-db',
selectedNavItem: 'Metadata'
};
it('confirm links are properly encoded and include the partition key when provided', () => {
const wrapper = mount(<MainSidebar
{...defaultProps}
selectedPartitionKey={'part-key-$-%1'}
/>);
expect(wrapper.find('a#all-docs').props()['href']).toContain('/_partition/part-key-%24-%251/');
expect(wrapper.find('a#design-docs').props()['href']).toContain('/_partition/part-key-%24-%251/');
expect(wrapper.find('a#mango-query').props()['href']).toContain('/_partition/part-key-%24-%251/');
});
it('confirm New links are properly encoded and include the partition key when provided', () => {
const wrapper = mount(<MainSidebar
{...defaultProps}
selectedPartitionKey={'part-key-$-%1'}
/>);
const newLinks = wrapper.instance().getNewButtonLinks()[0].links;
newLinks.forEach(link => {
if (link.title === 'New Doc') {
expect(link.url).toContain('?partitionKey=part-key-%24-%251');
} else {
expect(link.url).toContain('/_partition/part-key-%24-%251/');
}
});
});
});
describe('IndexSection', () => {
const defaultProps = {
urlNamespace: 'view',
indexLabel: 'Views',
database: { id: 'test-db' },
designDocName: 'ddoc-%-1',
items: ['viewA-$', 'viewB/#'],
isExpanded: true,
isPartitioned: false,
selectedPartitionKey: undefined,
selectedIndex: 'bla',
onDelete: () => {},
onClone: () => {},
showDeleteIndexModal: () => {},
showCloneIndexModal: () => {}
};
it('encodes the links for each item', () => {
const wrapper = mount(<IndexSection
{...defaultProps}
/>);
defaultProps.items.forEach((view, idx) => {
expect(wrapper.find('a.toggle-view').at(idx).prop('href')).toContain(
'/_design/' + encodeURIComponent('ddoc-%-1') + '/_view/' + encodeURIComponent(view)
);
});
});
it('links include partition key when one is selected', () => {
const wrapper = mount(<IndexSection
{...defaultProps}
selectedPartitionKey={'part%1'}
/>);
defaultProps.items.forEach((view, idx) => {
expect(wrapper.find('a.toggle-view').at(idx).prop('href')).toContain('/_partition/' + encodeURIComponent('part%1') + '/');
});
});
});