blessing-skin-server/resources/assets/tests/views/skinlib/SkinLibrary.test.tsx
Zephyr Lykos 9524a234cf
cleanup: wip 3.1
mostly misc cleanups
2024-02-24 23:01:32 +08:00

517 lines
14 KiB
TypeScript

import {
expect, test, vi, it, beforeEach,
} from 'vitest';
import {render, fireEvent, waitFor} from '@testing-library/react';
import {createPaginator} from '../../utils';
import {t} from '@/scripts/i18n';
import * as fetch from '@/scripts/net';
import {TextureType} from '@/scripts/types';
import urls from '@/scripts/urls';
import SkinLibrary from '@/views/skinlib/SkinLibrary';
import type {LibraryItem} from '@/views/skinlib/SkinLibrary/types';
vi.mock('@/scripts/net');
const fixtureItem: Readonly<LibraryItem> = Object.freeze<LibraryItem>({
tid: 1,
name: 'my skin',
type: TextureType.Steve,
uploader: 1,
nickname: 'me',
public: true,
likes: 70,
});
beforeEach(() => {
window.blessing.extra = {currentUid: null};
});
test('without authenticated', async () => {
fetch.get.mockResolvedValue(createPaginator([]));
const {queryByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
expect(fetch.get).toBeCalledWith(
urls.skinlib.list(),
expect.toSatisfy((search: URLSearchParams) => {
expect(search.get('filter')).toBe('skin');
expect(search.get('sort')).toBe('time');
expect(search.get('page')).toBe('1');
return true;
}),
);
expect(fetch.get).not.toBeCalledWith('/user/closet/ids');
expect(queryByText(t('skinlib.seeMyUpload'))).not.toBeInTheDocument();
});
test('search by keyword', async () => {
fetch.get.mockResolvedValue({...createPaginator([]), last_page: 10});
const {getByText, getByTitle, getByPlaceholderText} = render(
<SkinLibrary/>,
);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
// Test for resetting page
fireEvent.click(getByText('2'));
fireEvent.input(getByPlaceholderText(t('vendor.datatable.search')), {
target: {value: 'k'},
});
fireEvent.click(getByTitle(t('vendor.datatable.search')));
await waitFor(() => {
expect(fetch.get).toHaveBeenLastCalledWith(
urls.skinlib.list(),
expect.toSatisfy((search: URLSearchParams) => {
expect(search.get('keyword')).toBe('k');
expect(search.get('page')).toBe('1');
return true;
}),
);
},
);
});
test('select uploaded by self', async () => {
window.blessing.extra.currentUid = 1;
fetch.get.mockResolvedValue({...createPaginator([]), last_page: 10});
const {getByText, queryByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
// Test for resetting page
fireEvent.click(getByText('2'));
fireEvent.click(getByText(t('skinlib.seeMyUpload')));
await waitFor(() => {
expect(fetch.get).toHaveBeenLastCalledWith(
urls.skinlib.list(),
expect.toSatisfy((search: URLSearchParams) => {
expect(search.get('uploader')).toBe('1');
expect(search.get('page')).toBe('1');
return true;
}),
);
},
);
expect(queryByText(t('skinlib.filter.uploader', {uid: 1})));
});
test('reset query', async () => {
window.blessing.extra.currentUid = 1;
fetch.get.mockResolvedValue(createPaginator([]));
const {getByText, getByTitle, getByPlaceholderText, queryByText} = render(
<SkinLibrary/>,
);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText('Steve'));
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.input(getByPlaceholderText(t('vendor.datatable.search')), {
target: {value: 'k'},
});
fireEvent.click(getByTitle(t('vendor.datatable.search')));
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText(t('skinlib.seeMyUpload')));
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText(t('skinlib.sort.likes')));
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText(t('skinlib.reset')));
await waitFor(() => {
expect(fetch.get).toHaveBeenLastCalledWith(
urls.skinlib.list(),
expect.toSatisfy((search: URLSearchParams) => {
expect(search.get('filter')).toBe('skin');
expect(search.get('keyword')).toBeNull();
expect(search.get('uploader')).toBeNull();
expect(search.get('sort')).toBe('time');
expect(search.get('page')).toBe('1');
return true;
}),
);
},
);
expect(queryByText(t('skinlib.filter.uploader', {uid: 1})));
});
test('browser goes back', async () => {
fetch.get.mockResolvedValue(createPaginator([]));
const {getByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText('Steve'));
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
const {state} = window.history;
const event = new PopStateEvent('popstate', {
state: state.replace('steve', 'skin'),
});
window.dispatchEvent(event);
await waitFor(() => {
expect(fetch.get).toHaveBeenLastCalledWith(
urls.skinlib.list(),
expect.toSatisfy((search: URLSearchParams) => {
expect(search.get('filter')).toBe('skin');
return true;
}),
);
},
);
});
test('pagination', async () => {
const response = {...createPaginator([]), last_page: 2};
fetch.get.mockResolvedValue(response);
const {getByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText('2'));
expect(fetch.get).toHaveBeenLastCalledWith(
urls.skinlib.list(),
expect.toSatisfy((search: URLSearchParams) => {
expect(search.get('page')).toBe('2');
return true;
}),
);
});
test('library item', async () => {
fetch.get.mockResolvedValue(createPaginator([fixtureItem]));
const {getByText, queryByText, queryAllByText, queryByAltText} = render(
<SkinLibrary/>,
);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
expect(queryAllByText('Steve')).toHaveLength(2);
expect(queryByText(fixtureItem.name)).toBeInTheDocument();
expect(queryByAltText(fixtureItem.name)).toHaveAttribute(
'src',
`/preview/${fixtureItem.tid}?height=150&png`,
);
expect(queryByText(fixtureItem.nickname)).toBeInTheDocument();
fireEvent.click(getByText(fixtureItem.nickname));
await waitFor(() => {
expect(fetch.get).toHaveBeenLastCalledWith(
urls.skinlib.list(),
expect.toSatisfy((search: URLSearchParams) => {
expect(search.get('uploader')).toBe(fixtureItem.uploader.toString());
return true;
}),
);
},
);
const search = new URLSearchParams(location.search);
expect(search.get('uploader')).toBe(fixtureItem.uploader.toString());
});
test('private texture', async () => {
const item = {...fixtureItem, public: false};
fetch.get.mockResolvedValue(createPaginator([item]));
const {queryByTitle} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
expect(queryByTitle(t('skinlib.private'))).toBeInTheDocument();
});
describe('by filter', () => {
beforeEach(() => {
fetch.get.mockResolvedValue({...createPaginator([]), last_page: 10});
});
it('skin', async () => {
const {getByText, queryAllByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
// Test for resetting page
fireEvent.click(getByText('2'));
fireEvent.click(getByText('Steve'));
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText(t('general.skin')));
await waitFor(() => {
expect(fetch.get).toHaveBeenLastCalledWith(
urls.skinlib.list(),
expect.toSatisfy((search: URLSearchParams) => {
expect(search.get('filter')).toBe('skin');
expect(search.get('page')).toBe('1');
return true;
}),
);
},
);
expect(queryAllByText(t('general.skin'))).toHaveLength(2);
const search = new URLSearchParams(location.search);
expect(search.get('filter')).toBe('skin');
});
it('steve', async () => {
const {getByText, queryAllByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
// Test for resetting page
fireEvent.click(getByText('2'));
fireEvent.click(getByText('Steve'));
await waitFor(() => {
expect(fetch.get).toHaveBeenLastCalledWith(
urls.skinlib.list(),
expect.toSatisfy((search: URLSearchParams) => {
expect(search.get('filter')).toBe('steve');
expect(search.get('page')).toBe('1');
return true;
}),
);
},
);
expect(queryAllByText('Steve')).toHaveLength(2);
const search = new URLSearchParams(location.search);
expect(search.get('filter')).toBe('steve');
});
it('alex', async () => {
const {getByText, queryAllByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
// Test for resetting page
fireEvent.click(getByText('2'));
fireEvent.click(getByText('Alex'));
await waitFor(() => {
expect(fetch.get).toHaveBeenLastCalledWith(
urls.skinlib.list(),
expect.toSatisfy((search: URLSearchParams) => {
expect(search.get('filter')).toBe('alex');
expect(search.get('page')).toBe('1');
return true;
}),
);
},
);
expect(queryAllByText('Alex')).toHaveLength(2);
const search = new URLSearchParams(location.search);
expect(search.get('filter')).toBe('alex');
});
it('cape', async () => {
const {getByText, queryAllByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
// Test for resetting page
fireEvent.click(getByText('2'));
fireEvent.click(getByText(t('general.cape')));
await waitFor(() => {
expect(fetch.get).toHaveBeenLastCalledWith(
urls.skinlib.list(),
expect.toSatisfy((search: URLSearchParams) => {
expect(search.get('filter')).toBe('cape');
expect(search.get('page')).toBe('1');
return true;
}),
);
},
);
expect(queryAllByText(t('general.cape'))).toHaveLength(2);
const search = new URLSearchParams(location.search);
expect(search.get('filter')).toBe('cape');
});
});
describe('sorting', () => {
beforeEach(() => {
fetch.get.mockResolvedValue(createPaginator([]));
});
it('by time', async () => {
const {getByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText(t('skinlib.sort.likes')));
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText(t('skinlib.sort.time')));
await waitFor(() => {
expect(fetch.get).toHaveBeenLastCalledWith(
urls.skinlib.list(),
expect.toSatisfy((search: URLSearchParams) => {
expect(search.get('sort')).toBe('time');
return true;
}),
);
},
);
const search = new URLSearchParams(location.search);
expect(search.get('sort')).toBe('time');
});
it('by likes', async () => {
const {getByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText(t('skinlib.sort.likes')));
await waitFor(() => {
expect(fetch.get).toHaveBeenLastCalledWith(
urls.skinlib.list(),
expect.toSatisfy((search: URLSearchParams) => {
expect(search.get('sort')).toBe('likes');
return true;
}),
);
},
);
const search = new URLSearchParams(location.search);
expect(search.get('sort')).toBe('likes');
});
});
describe('add to closet', () => {
beforeEach(() => {
fetch.get.mockImplementation(async (url: string) => {
if (url === urls.skinlib.list()) {
return createPaginator([fixtureItem]);
}
return [];
});
});
it('without authenticated', async () => {
const {getByText, queryByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText(fixtureItem.likes.toString()));
expect(queryByText(t('skinlib.anonymous'))).toBeInTheDocument();
expect(fetch.post).not.toBeCalled();
});
it('succeeded', async () => {
window.blessing.extra.currentUid = 1;
fetch.post.mockResolvedValue({code: 0, message: 'ok'});
const {getByText, queryByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText(fixtureItem.likes.toString()));
fireEvent.click(getByText(t('general.confirm')));
await waitFor(() => {
expect(fetch.post).toBeCalled();
});
expect(queryByText((fixtureItem.likes + 1).toString())).toBeInTheDocument();
});
it('failed', async () => {
window.blessing.extra.currentUid = 1;
fetch.post.mockResolvedValue({code: 1, message: 'failed'});
const {getByText, queryByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText(fixtureItem.likes.toString()));
fireEvent.click(getByText(t('general.confirm')));
await waitFor(() => {
expect(fetch.post).toBeCalled();
});
expect(queryByText(fixtureItem.likes.toString())).toBeInTheDocument();
});
});
describe('remove from closet', () => {
beforeEach(() => {
window.blessing.extra.currentUid = 1;
fetch.get.mockImplementation(async (url: string) => {
if (url === urls.skinlib.list()) {
return createPaginator([fixtureItem]);
}
return [fixtureItem.tid];
});
});
it('succeeded', async () => {
fetch.del.mockResolvedValue({code: 0, message: 'ok'});
const {getByText, queryByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText(fixtureItem.likes.toString()));
fireEvent.click(getByText(t('general.confirm')));
await waitFor(() => {
expect(fetch.del).toBeCalled();
});
expect(queryByText((fixtureItem.likes - 1).toString())).toBeInTheDocument();
});
it('failed', async () => {
fetch.del.mockResolvedValue({code: 1, message: 'failed'});
const {getByText, queryByText} = render(<SkinLibrary/>);
await waitFor(() => {
expect(fetch.get).toBeCalled();
});
fireEvent.click(getByText(fixtureItem.likes.toString()));
fireEvent.click(getByText(t('general.confirm')));
await waitFor(() => {
expect(fetch.del).toBeCalled();
});
expect(queryByText(fixtureItem.likes.toString())).toBeInTheDocument();
});
});