mirror of
https://github.com/directus/directus.git
synced 2026-01-27 06:18:23 -05:00
* Render add new link, only render delete on isnew is false * Add header actions buttons based on state * Add header buttons and breadcrumbs * Style tweaks * Add navigation guard for single collections * Add delete button logic * Add ability to delete items on browse * Add select mode to tabular layout * Add saving / deleting logic to detail view * remove tests (temporarily) * Remove empty tests temporarily * Add pagination to tabular layout if collection is large * Add server sort * wip table tweaks * show shadow only on scroll, fix padding on top of private view. * Update table * fix header hiding the scrollbar * Fix rAF leak * Make pagination sticky * fix double scroll bug * add selfScroll prop to private view * Last try * Lower the default limit * Fix tests for table / private / public view * finish header * remove unnessesary code * Fix debug overflow + icon alignment * Fix breadcrumbs * Fix item fetching * browse view now collapses on scroll * Add drawer-button component * Fix styling of drawer-button drawer-detail * Revert "browse view now collapses on scroll" This reverts commit a8534484d496deef01e399574126f7ba877e098c. * Final commit for the night * Add scroll solution for header overflow * Render table header over shadow * Add useScrollDistance compositoin * Add readme for scroll distance * Restructure header bar using sticky + margin / add shadow * Tweak box shadow to not show up at top on scroll up * Fix tests Co-authored-by: Nitwel <nitwel@arcor.de>
172 lines
3.3 KiB
TypeScript
172 lines
3.3 KiB
TypeScript
import Vue from 'vue';
|
|
import VueCompositionAPI from '@vue/composition-api';
|
|
import { onRequest, onResponse, onError, getRootPath, Error } from './api';
|
|
import * as auth from '@/auth';
|
|
import { useRequestsStore } from '@/stores/requests';
|
|
|
|
const defaultError: Error = {
|
|
config: {},
|
|
isAxiosError: false,
|
|
toJSON: () => ({}),
|
|
name: 'error',
|
|
message: '',
|
|
response: {
|
|
data: null,
|
|
status: 200,
|
|
statusText: 'OK',
|
|
headers: {},
|
|
config: {
|
|
id: 'abc'
|
|
}
|
|
}
|
|
};
|
|
|
|
describe('API', () => {
|
|
beforeEach(() => {
|
|
jest.spyOn(auth, 'logout');
|
|
jest.spyOn(auth, 'checkAuth');
|
|
Vue.use(VueCompositionAPI);
|
|
window = Object.create(window);
|
|
});
|
|
|
|
it('Calculates the correct API root URL based on window', () => {
|
|
Object.defineProperty(window, 'location', {
|
|
value: {
|
|
pathname: '/api/nested/admin'
|
|
},
|
|
writable: true
|
|
});
|
|
|
|
const result = getRootPath();
|
|
expect(result).toBe('/api/nested/');
|
|
});
|
|
|
|
it('Calls startRequest on the store on any request', () => {
|
|
const store = useRequestsStore({});
|
|
const spy = jest.spyOn(store, 'startRequest');
|
|
spy.mockImplementation(() => 'abc');
|
|
const newRequest = onRequest({});
|
|
expect(spy).toHaveBeenCalled();
|
|
expect(newRequest.id).toBe('abc');
|
|
});
|
|
|
|
it('Calls endRequest on responses', () => {
|
|
const store = useRequestsStore({});
|
|
const spy = jest.spyOn(store, 'endRequest');
|
|
onResponse({
|
|
data: null,
|
|
status: 200,
|
|
statusText: 'OK',
|
|
headers: {},
|
|
config: {
|
|
id: 'abc'
|
|
}
|
|
});
|
|
expect(spy).toHaveBeenCalledWith('abc');
|
|
});
|
|
|
|
it('Calls endRequest on errors', async () => {
|
|
const store = useRequestsStore({});
|
|
const spy = jest.spyOn(store, 'endRequest');
|
|
try {
|
|
await onError({
|
|
...defaultError
|
|
});
|
|
} catch {}
|
|
|
|
expect(spy).toHaveBeenCalledWith('abc');
|
|
});
|
|
|
|
it('Passes the error on to the next catch handler on unrelated 401 errors', async () => {
|
|
const error = {
|
|
...defaultError,
|
|
response: {
|
|
...defaultError.response,
|
|
status: 401,
|
|
config: {
|
|
id: 'abc'
|
|
},
|
|
data: {
|
|
error: {
|
|
code: -5
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
expect(onError(error)).rejects.toEqual(error);
|
|
});
|
|
|
|
it('Checks the auth status on 401+3 errors', async () => {
|
|
try {
|
|
await onError({
|
|
...defaultError,
|
|
response: {
|
|
...defaultError.response,
|
|
config: {
|
|
id: 'abc'
|
|
},
|
|
status: 401,
|
|
data: {
|
|
error: {
|
|
code: 3
|
|
}
|
|
}
|
|
}
|
|
});
|
|
} catch {
|
|
expect(auth.checkAuth).toHaveBeenCalled();
|
|
}
|
|
});
|
|
|
|
it('Forces a logout when the users is not logged in on 401+3 errors', async () => {
|
|
(auth.checkAuth as jest.Mock).mockImplementation(async () => false);
|
|
|
|
try {
|
|
await onError({
|
|
...defaultError,
|
|
response: {
|
|
...defaultError.response,
|
|
config: {
|
|
id: 'abc'
|
|
},
|
|
status: 401,
|
|
data: {
|
|
error: {
|
|
code: 3
|
|
}
|
|
}
|
|
}
|
|
});
|
|
} catch {
|
|
expect(auth.logout).toHaveBeenCalledWith({
|
|
reason: auth.LogoutReason.ERROR_SESSION_EXPIRED
|
|
});
|
|
}
|
|
});
|
|
|
|
it('Does not call logout if the user is logged in on 401+3 error', async () => {
|
|
(auth.checkAuth as jest.Mock).mockImplementation(async () => true);
|
|
|
|
try {
|
|
await onError({
|
|
...defaultError,
|
|
response: {
|
|
...defaultError.response,
|
|
config: {
|
|
id: 'abc'
|
|
},
|
|
status: 401,
|
|
data: {
|
|
error: {
|
|
code: 3
|
|
}
|
|
}
|
|
}
|
|
});
|
|
} catch {
|
|
expect(auth.logout).not.toHaveBeenCalled();
|
|
}
|
|
});
|
|
});
|