mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-10-30 18:47:51 +00:00 
			
		
		
		
	 6d3ecfe3c1
			
		
	
	6d3ecfe3c1
	
	
	
		
			
			This PR has the initial version of the new sidebar targeted for the next major redesign of the app. This PR includes the following changes - Components in the `layouts-next` and `base-next` directories in `dashboard/components` - Two generic components `Avatar` and `Icon` - `SidebarGroup` component to manage expandable sidebar groups with nested navigation items. This includes handling active states, transitions, and permissions. - `SidebarGroupHeader` component to display the header of each navigation group with optional icons and active state indication. - `SidebarGroupLeaf` component for individual navigation items within a group, supporting icons and active state. - `SidebarGroupSeparator` component to visually separate nested navigation items. (They look a lot like header) - `SidebarGroupEmptyLeaf` component to render empty state of any navigation groups. ---- Co-authored-by: Pranav <pranav@chatwoot.com> Co-authored-by: Pranav <pranavrajs@gmail.com>
		
			
				
	
	
		
			117 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import { defineComponent, h } from 'vue';
 | |
| import { createStore } from 'vuex';
 | |
| import { describe, it, expect, vi, beforeEach } from 'vitest';
 | |
| import { useAccount } from '../useAccount';
 | |
| import { useRoute } from 'vue-router';
 | |
| import { mount } from '@vue/test-utils';
 | |
| 
 | |
| const store = createStore({
 | |
|   modules: {
 | |
|     auth: {
 | |
|       namespaced: false,
 | |
|       getters: {
 | |
|         getCurrentAccountId: () => 1,
 | |
|         getCurrentUser: () => ({
 | |
|           accounts: [
 | |
|             { id: 1, name: 'Chatwoot', role: 'administrator' },
 | |
|             { id: 2, name: 'GitX', role: 'agent' },
 | |
|           ],
 | |
|         }),
 | |
|       },
 | |
|     },
 | |
|     accounts: {
 | |
|       namespaced: true,
 | |
|       getters: {
 | |
|         getAccount: () => id => ({ id, name: 'Chatwoot' }),
 | |
|       },
 | |
|     },
 | |
|   },
 | |
| });
 | |
| 
 | |
| const mountParams = {
 | |
|   global: {
 | |
|     plugins: [store],
 | |
|   },
 | |
| };
 | |
| 
 | |
| vi.mock('vue-router');
 | |
| 
 | |
| describe('useAccount', () => {
 | |
|   beforeEach(() => {
 | |
|     useRoute.mockReturnValue({
 | |
|       params: {
 | |
|         accountId: '123',
 | |
|       },
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   const createComponent = () =>
 | |
|     defineComponent({
 | |
|       setup() {
 | |
|         return useAccount();
 | |
|       },
 | |
|       render() {
 | |
|         return h('div'); // Dummy render to satisfy mount
 | |
|       },
 | |
|     });
 | |
| 
 | |
|   it('returns accountId as a computed property', () => {
 | |
|     const wrapper = mount(createComponent(), mountParams);
 | |
|     const { accountId } = wrapper.vm;
 | |
|     expect(accountId).toBe(123);
 | |
|   });
 | |
| 
 | |
|   it('generates account-scoped URLs correctly', () => {
 | |
|     const wrapper = mount(createComponent(), mountParams);
 | |
|     const { accountScopedUrl } = wrapper.vm;
 | |
|     const result = accountScopedUrl('settings/inbox/new');
 | |
|     expect(result).toBe('/app/accounts/123/settings/inbox/new');
 | |
|   });
 | |
| 
 | |
|   it('handles URLs with leading slash', () => {
 | |
|     const wrapper = mount(createComponent(), mountParams);
 | |
|     const { accountScopedUrl } = wrapper.vm;
 | |
|     const result = accountScopedUrl('users');
 | |
|     expect(result).toBe('/app/accounts/123/users'); // Ensures no double slashes
 | |
|   });
 | |
| 
 | |
|   it('handles empty URL', () => {
 | |
|     const wrapper = mount(createComponent(), mountParams);
 | |
|     const { accountScopedUrl } = wrapper.vm;
 | |
|     const result = accountScopedUrl('');
 | |
|     expect(result).toBe('/app/accounts/123/');
 | |
|   });
 | |
| 
 | |
|   it('returns current account based on accountId', () => {
 | |
|     const wrapper = mount(createComponent(), mountParams);
 | |
|     const { currentAccount } = wrapper.vm;
 | |
|     expect(currentAccount).toEqual({ id: 123, name: 'Chatwoot' });
 | |
|   });
 | |
| 
 | |
|   it('returns an account-scoped route', () => {
 | |
|     const wrapper = mount(createComponent(), mountParams);
 | |
|     const { accountScopedRoute } = wrapper.vm;
 | |
|     const result = accountScopedRoute('accountDetail', { userId: 456 });
 | |
|     expect(result).toEqual({
 | |
|       name: 'accountDetail',
 | |
|       params: { accountId: 123, userId: 456 },
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   it('returns route with correct params', () => {
 | |
|     const wrapper = mount(createComponent(), mountParams);
 | |
|     const { route } = wrapper.vm;
 | |
|     expect(route.params).toEqual({ accountId: '123' });
 | |
|   });
 | |
| 
 | |
|   it('handles non-numeric accountId gracefully', async () => {
 | |
|     useRoute.mockReturnValueOnce({
 | |
|       params: { accountId: 'abc' },
 | |
|     });
 | |
| 
 | |
|     const wrapper = mount(createComponent(), mountParams);
 | |
|     const { accountId } = wrapper.vm;
 | |
|     expect(accountId).toBeNaN(); // Handles invalid numeric conversion
 | |
|   });
 | |
| });
 |