updates on the admin and zone things and minor changes
This commit is contained in:
@@ -65,7 +65,7 @@ describe('ZoneContext', () => {
|
||||
|
||||
it('should not load tenant locations for a staff login', () => {
|
||||
setup({ user: { tenantid: '0' } });
|
||||
expect(useHubs).toHaveBeenCalledWith({ enabled: true });
|
||||
expect(useHubs).toHaveBeenCalled();
|
||||
expect(useTenantLocations).toHaveBeenCalledWith(null, { enabled: false });
|
||||
});
|
||||
});
|
||||
@@ -79,17 +79,40 @@ describe('ZoneContext', () => {
|
||||
longitude: 77.6408
|
||||
};
|
||||
|
||||
it('should offer the tenant kitchen hubs instead of global hubs', () => {
|
||||
// A client sees their own locations first, then the Doormile hubs. A newly
|
||||
// onboarded client used to have no locations and therefore no zones at all
|
||||
// — not even the Coimbatore hub their orders run through.
|
||||
it('should offer the tenant own locations and then the Doormile hubs', () => {
|
||||
const { result } = setup({ user: { tenantid: '4' }, locations: [LOCATION] });
|
||||
expect(result.current.isTenantUser).toBe(true);
|
||||
expect(result.current.zones.map((z) => z.hubname)).toEqual(['All Zones', 'Indiranagar Kitchen']);
|
||||
expect(result.current.zones.map((z) => z.hubname)).toEqual(['All Zones', 'Indiranagar Kitchen', 'Koramangala Hub']);
|
||||
expect(result.current.zones[1].hubtype).toBe('kitchen_hub');
|
||||
expect(result.current.zones[1].isTenantLocation).toBe(true);
|
||||
expect(result.current.zones[2].isTenantLocation).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should prefix a location zone id so it cannot collide with a hub id', () => {
|
||||
const { result } = setup({ user: { tenantid: '4' }, locations: [{ ...LOCATION, tenantlocationid: 2 }] });
|
||||
expect(result.current.zones.map((z) => z.hubid)).toEqual(['all', 'loc:2', '2']);
|
||||
expect(result.current.zones[1].locationid).toBe('2');
|
||||
});
|
||||
|
||||
it('should offer only the hubs of the client own city when the login carries it', () => {
|
||||
const CBE = { ...KORAMANGALA, hubid: '7', hubname: 'Coimbatore Neptune Hub', applocationid: 1 };
|
||||
const BLR = { ...KORAMANGALA, applocationid: 3 };
|
||||
const { result } = setup({ user: { tenantid: '4', applocationid: 1 }, hubs: [CBE, BLR] });
|
||||
expect(result.current.zones.map((z) => z.hubname)).toEqual(['All Zones', 'Coimbatore Neptune Hub']);
|
||||
});
|
||||
|
||||
it('should still show the hubs to a client with no locations yet', () => {
|
||||
const { result } = setup({ user: { tenantid: '4' }, locations: [] });
|
||||
expect(result.current.zones.map((z) => z.hubname)).toEqual(['All Zones', 'Koramangala Hub']);
|
||||
});
|
||||
|
||||
it('should scope the location query to the operator own tenant', () => {
|
||||
setup({ user: { tenantid: '4' }, locations: [LOCATION] });
|
||||
expect(useTenantLocations).toHaveBeenCalledWith('4', { enabled: true });
|
||||
expect(useHubs).toHaveBeenCalledWith({ enabled: false });
|
||||
expect(useHubs).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should treat tenantid "0" as staff, not as a tenant', () => {
|
||||
@@ -425,7 +448,7 @@ describe('ZoneContext', () => {
|
||||
expect(result.current.isHubsLoading).toBe(true);
|
||||
});
|
||||
|
||||
it('should refetch the source the current login actually reads', () => {
|
||||
it('should refetch both sources a client login reads', () => {
|
||||
const refetchHubs = jest.fn();
|
||||
const refetchLocations = jest.fn();
|
||||
useAuth.mockReturnValue({ user: { tenantid: '4' } });
|
||||
@@ -436,7 +459,7 @@ describe('ZoneContext', () => {
|
||||
act(() => result.current.refetchHubs());
|
||||
|
||||
expect(refetchLocations).toHaveBeenCalledTimes(1);
|
||||
expect(refetchHubs).not.toHaveBeenCalled();
|
||||
expect(refetchHubs).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
51
tests/lib/consoleNav.test.js
Normal file
51
tests/lib/consoleNav.test.js
Normal file
@@ -0,0 +1,51 @@
|
||||
import { CLIENT_FLEET_OPS_PATHS, CLIENT_ONBOARDING_PATH, navGroupsFor } from '@/lib/consoleNav';
|
||||
import { canOnboardClients } from '@/lib/clientOnboarding';
|
||||
|
||||
const GROUPS = [
|
||||
{
|
||||
label: 'Fleet Ops',
|
||||
items: [
|
||||
{ label: 'Hubs', path: '/doormile/hubs' },
|
||||
{ label: 'Vehicles', path: '/doormile/vehicles' },
|
||||
{ label: 'Tripsheets', path: '/doormile/tripsheets' },
|
||||
{ label: 'Exceptions', path: '/doormile/exceptions' },
|
||||
{ label: 'Returns', path: '/doormile/returns' },
|
||||
{ label: 'Competitive Intel', path: '/doormile/competitive-intel' },
|
||||
{ label: 'App Users', path: '/doormile/app-users' },
|
||||
{ label: 'Agents', path: '/doormile/agents' },
|
||||
],
|
||||
},
|
||||
{ label: 'Reports', items: [{ label: 'Orders Summary', path: '/doormile/reports/orderssummary' }] },
|
||||
];
|
||||
const ONBOARD = { label: 'Client Onboarding', path: CLIENT_ONBOARDING_PATH };
|
||||
|
||||
const labelsOf = (groups, name) => groups.find((g) => g.label === name).items.map((i) => i.label);
|
||||
|
||||
describe('header menu per login', () => {
|
||||
test('a client sees Fleet Ops with only Hubs, Exceptions and Returns', () => {
|
||||
const groups = navGroupsFor(GROUPS, { isClient: true, canOnboard: false, onboardingItem: ONBOARD });
|
||||
expect(labelsOf(groups, 'Fleet Ops')).toEqual(['Hubs', 'Exceptions', 'Returns']);
|
||||
expect(labelsOf(groups, 'Reports')).toEqual(['Orders Summary']);
|
||||
});
|
||||
|
||||
test('a client never sees Agents or Client Onboarding, even if asked to', () => {
|
||||
const groups = navGroupsFor(GROUPS, { isClient: true, canOnboard: true, onboardingItem: ONBOARD });
|
||||
const all = groups.flatMap((g) => g.items.map((i) => i.path));
|
||||
expect(all).not.toContain('/doormile/agents');
|
||||
expect(all).not.toContain(CLIENT_ONBOARDING_PATH);
|
||||
expect(all.filter((p) => p.startsWith('/doormile/') && !p.includes('/reports/'))).toEqual(CLIENT_FLEET_OPS_PATHS);
|
||||
});
|
||||
|
||||
test('the onboarding owner sees the full Fleet Ops menu plus Client Onboarding', () => {
|
||||
const owner = { email: 'admin@doormile.com', role: 'admin' };
|
||||
const groups = navGroupsFor(GROUPS, { isClient: false, canOnboard: canOnboardClients(owner, false), onboardingItem: ONBOARD });
|
||||
expect(labelsOf(groups, 'Fleet Ops')).toEqual([...GROUPS[0].items.map((i) => i.label), 'Client Onboarding']);
|
||||
});
|
||||
|
||||
test('other Doormile staff see Fleet Ops and Agents but not Client Onboarding', () => {
|
||||
const staff = { email: 'ops@doormile.com', role: 'admin' };
|
||||
const groups = navGroupsFor(GROUPS, { isClient: false, canOnboard: canOnboardClients(staff, false), onboardingItem: ONBOARD });
|
||||
expect(labelsOf(groups, 'Fleet Ops')).toContain('Agents');
|
||||
expect(labelsOf(groups, 'Fleet Ops')).not.toContain('Client Onboarding');
|
||||
});
|
||||
});
|
||||
@@ -87,8 +87,10 @@ describe('a tenant session never matches on a hub id', () => {
|
||||
it('a booking whose pickuphubid is 5 does not land in tenant location 5', () => {
|
||||
// Two different id spaces. Matching them would file an order under a
|
||||
// kitchen it has nothing to do with, on a bare numeric collision.
|
||||
// A client location's zone id is prefixed ('loc:5') precisely so it can
|
||||
// never be confused with hub 5, which a client now also sees.
|
||||
const { result } = setup({ user: { tenantid: '13' }, locations: [KITCHEN] });
|
||||
expect(inZone(result, '5', {
|
||||
expect(inZone(result, 'loc:5', {
|
||||
bookingid: 3, bookingno: 'DM-X', tenantid: '13', pickuphubid: 5,
|
||||
pickupaddress: 'Gate 3', deliveryaddress: 'Block C'
|
||||
})).toBe(false);
|
||||
@@ -96,11 +98,28 @@ describe('a tenant session never matches on a hub id', () => {
|
||||
|
||||
it('but its own tenantlocationid still matches', () => {
|
||||
const { result } = setup({ user: { tenantid: '13' }, locations: [KITCHEN] });
|
||||
expect(inZone(result, '5', {
|
||||
expect(inZone(result, 'loc:5', {
|
||||
bookingid: 4, bookingno: 'DM-Y', tenantid: '13', tenantlocationid: 5,
|
||||
pickupaddress: 'Gate 3', deliveryaddress: 'Block C'
|
||||
})).toBe(true);
|
||||
});
|
||||
|
||||
it('a client who picks a Doormile HUB is matched on hub ids, never on location ids', () => {
|
||||
const { result } = setup({ user: { tenantid: '13' }, locations: [KITCHEN] });
|
||||
expect(inZone(result, '5', {
|
||||
bookingid: 5, bookingno: 'DM-H', tenantid: '13', pickuphubid: 5,
|
||||
pickupaddress: 'Gate 3', deliveryaddress: 'Block C'
|
||||
})).toBe(true);
|
||||
expect(inZone(result, '5', {
|
||||
bookingid: 6, bookingno: 'DM-L', tenantid: '13', tenantlocationid: 5,
|
||||
pickupaddress: 'Gate 3', deliveryaddress: 'Block C'
|
||||
})).toBe(false);
|
||||
});
|
||||
|
||||
it("never shows a client another tenant's order, whatever zone is picked", () => {
|
||||
const { result } = setup({ user: { tenantid: '13' }, locations: [KITCHEN] });
|
||||
expect(inZone(result, '5', { bookingid: 7, tenantid: '99', pickuphubid: 5, pickupaddress: 'a' })).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('the city comparison, which needs a city on the hub', () => {
|
||||
@@ -172,9 +191,18 @@ describe('one id space at a time', () => {
|
||||
const KITCHEN = { tenantlocationid: 5, locationname: 'Indiranagar Kitchen',
|
||||
city: 'Bengaluru', latitude: 12.9784, longitude: 77.6408, pincode: '560038' };
|
||||
const { result } = setup({ user: { tenantid: '13' }, locations: [KITCHEN] });
|
||||
expect(inZone(result, '5', { bookingid: 1, tenantid: '13', tenantlocationid: 5,
|
||||
expect(inZone(result, 'loc:5', { bookingid: 1, tenantid: '13', tenantlocationid: 5,
|
||||
pickupaddress: 'a', deliveryaddress: 'b' })).toBe(true);
|
||||
expect(inZone(result, '5', { bookingid: 2, tenantid: '13', servicinghubid: 5,
|
||||
expect(inZone(result, 'loc:5', { bookingid: 2, tenantid: '13', servicinghubid: 5,
|
||||
pickupaddress: 'a', deliveryaddress: 'b' })).toBe(false);
|
||||
});
|
||||
|
||||
it('a deactivated tenant location is not offered as a zone', () => {
|
||||
const LIVE = { tenantlocationid: 7, locationname: 'Saibaba Colony', status: 'Active' };
|
||||
const OLD = { tenantlocationid: 8, locationname: 'Main Branch', status: 'Inactive' };
|
||||
const { result } = setup({ user: { tenantid: '13' }, locations: [LIVE, OLD] });
|
||||
const ids = result.current.zones.map((z) => z.hubid);
|
||||
expect(ids).toContain('loc:7');
|
||||
expect(ids).not.toContain('loc:8');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user