0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-03 23:00:14 -05:00

Add tests to tabs and events pagination (#15757)

closes TryGhost/Team#2128
This commit is contained in:
Elena Baidakova 2022-11-07 16:32:06 +04:00 committed by GitHub
parent f2c0bff9df
commit b526c4b719
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 209 additions and 7 deletions

View file

@ -64,10 +64,13 @@ export default class ActivityFeedFetcher extends Resource {
@action
loadNextPage() {
if (this.hasReachedEnd) {
return;
}
const lastEvent = this.data[this.data.length - 1];
const lastEventDate = moment.utc(lastEvent.data.created_at).format('YYYY-MM-DD HH:mm:ss');
const lastEventId = lastEvent.data.id;
let filter = `(data.created_at:<'${lastEventDate}',(data.created_at:'${lastEventDate}'+id:<'${lastEventId}'))`;
this.eventsBookmarks.push(filter);
@ -80,6 +83,9 @@ export default class ActivityFeedFetcher extends Resource {
@action
loadPreviousPage() {
if (this.hasReachedStart) {
return;
}
this.eventsBookmarks.pop();
let filter = this.eventsBookmarks[this.eventsBookmarks.length - 1];

View file

@ -290,15 +290,45 @@ export default function mockMembers(server) {
}));
server.get('/members/events/', withPermissionsCheck(ALLOWED_ROLES, function ({memberActivityEvents}, {queryParams}) {
let {limit} = queryParams;
let {limit, filter, page} = queryParams;
limit = +limit || 15;
page = +page || 1;
let collection = memberActivityEvents.all().sort((a, b) => {
return (new Date(a.createdAt)) - (new Date(b.createdAt));
}).slice(0, limit);
let collection = memberActivityEvents.all();
collection = collection.sort((a, b) => {
return Number(b.id) - Number(a.id);
});
return collection;
if (filter) {
try {
const nqlFilter = nql(filter, {
expansions: [
{
key: 'data.created_at',
replacement: 'created_at'
}
]
});
collection = collection.filter((event) => {
const serializedEvent = {};
// mirage model keys match our main model keys, so we need to transform
// camelCase to underscore to match the filter format
Object.keys(event.attrs).forEach((key) => {
serializedEvent[underscore(key)] = event.attrs[key];
});
return nqlFilter.queryJSON(serializedEvent);
});
} catch (err) {
console.error(err); // eslint-disable-line
throw err;
}
}
return paginateModelCollection('members', collection, page, limit);
}));
mockMembersStats(server);

View file

@ -37,6 +37,6 @@ export default BaseSerializer.extend({
};
});
return {events};
return {events, meta: serialized.meta};
}
});

View file

@ -102,4 +102,31 @@ describe('Integration: Component: tabs/tabs', function () {
await triggerKeyEvent(tabButtons[0], 'keyup', 'End');
isTabRenders(2);
});
it('renders content for all tabs with forceRender option', async function () {
await render(hbs`
<Tabs::Tabs class="test-tab" @forceRender={{true}} as |tabs|>
<tabs.tab>Tab 1</tabs.tab>
<tabs.tab>Tab 2</tabs.tab>
<tabs.tabPanel>Content 1</tabs.tabPanel>
<tabs.tabPanel>Content 2</tabs.tabPanel>
</Tabs::Tabs>`);
const tabButtons = findAll('.tab');
const tabPanels = findAll('.tab-panel');
expect(tabPanels[0]).to.have.trimmed.text('Content 1');
expect(tabPanels[1]).to.have.trimmed.text('Content 2');
await click(tabButtons[1]);
expect(findAll('.tab-selected').length).to.equal(1);
expect(findAll('.tab-panel-selected').length).to.equal(1);
expect(tabButtons[1]).to.have.class('tab-selected');
expect(tabPanels[1]).to.have.class('tab-panel-selected');
expect(tabPanels[0]).to.have.trimmed.text('Content 1');
expect(tabPanels[1]).to.have.trimmed.text('Content 2');
});
});

View file

@ -0,0 +1,139 @@
import hbs from 'htmlbars-inline-precompile';
import moment from 'moment-timezone';
import {click, find, findAll, render} from '@ember/test-helpers';
import {describe, it} from 'mocha';
import {expect} from 'chai';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {setupRenderingTest} from 'ember-mocha';
describe('Integration: Helper: activity-feed-fetcher-test', function () {
const hooks = setupRenderingTest();
setupMirage(hooks);
it('can fetch events', async function () {
this.server.createList('member-activity-event', 10, {createdAt: moment('2022-11-01 12:00:00').format('YYYY-MM-DD HH:mm:ss')});
await render(hbs`
{{#let (activity-feed-fetcher pageSize="2") as |eventsFetcher|}}
<div class="shown-events">{{eventsFetcher.shownEvents}}</div>
<div class="total-events">{{eventsFetcher.totalEvents}}</div>
{{/let}}
`);
expect(find('.shown-events')).to.have.trimmed.text('2');
expect(find('.total-events')).to.have.trimmed.text('10');
});
it('can update total/shown amount of events ', async function () {
this.server.createList('member-activity-event', 5, {createdAt: moment('2022-11-01 12:00:00').format('YYYY-MM-DD HH:mm:ss')});
await render(hbs`
{{#let (activity-feed-fetcher pageSize="2") as |eventsFetcher|}}
<button class="previous" {{on "click" eventsFetcher.loadPreviousPage}}>Previous page</button>
<button class="next" {{on "click" eventsFetcher.loadNextPage}}>Next page</button>
<div class="shown-events">{{eventsFetcher.shownEvents}}</div>
<div class="total-events">{{eventsFetcher.totalEvents}}</div>
{{/let}}
`);
const totalEvents = find('.total-events');
const shownEvents = find('.shown-events');
expect(shownEvents).to.have.trimmed.text('2');
expect(totalEvents).to.have.trimmed.text('5');
// nothing should change if user tries to load previous page on the first one
await click('.previous');
expect(shownEvents).to.have.trimmed.text('2');
expect(totalEvents).to.have.trimmed.text('5');
// go to the last page
await click('.next');
await click('.next');
expect(shownEvents).to.have.trimmed.text('5');
expect(totalEvents).to.have.trimmed.text('5');
// nothing should change if user tries to load next page on the last one
await click('.next');
expect(shownEvents).to.have.trimmed.text('5');
expect(totalEvents).to.have.trimmed.text('5');
await click('.previous');
expect(shownEvents).to.have.trimmed.text('4');
expect(totalEvents).to.have.trimmed.text('5');
});
it('can update data for each page', async function () {
this.server.createList('member-activity-event', 5, {createdAt: moment('2022-11-01 12:00:00').format('YYYY-MM-DD HH:mm:ss')});
// create event in future to make sure that user don't get events after current date
this.server.create('member-activity-event', {createdAt: moment().add(1, 'd').format('YYYY-MM-DD HH:mm:ss')});
await render(hbs`
{{#let (activity-feed-fetcher pageSize="2") as |eventsFetcher|}}
<button class="previous" {{on "click" eventsFetcher.loadPreviousPage}}>Previous page</button>
<button class="next" {{on "click" eventsFetcher.loadNextPage}}>Next page</button>
{{#each eventsFetcher.data as |event|}}
<div class="event-id">{{event.data.id}}</div>
{{/each}}
{{/let}}
`);
expect(findAll('.event-id').length).to.equal(2);
expect(findAll('.event-id')[0]).to.have.trimmed.text('5');
await click('.next');
expect(findAll('.event-id').length).to.equal(2);
expect(findAll('.event-id')[0]).to.have.trimmed.text('3');
await click('.next');
expect(findAll('.event-id').length).to.equal(1);
expect(findAll('.event-id')[0]).to.have.trimmed.text('1');
// nothing should change if user tries to load next page on the last one
await click('.next');
expect(findAll('.event-id').length).to.equal(1);
expect(findAll('.event-id')[0]).to.have.trimmed.text('1');
await click('.previous');
expect(findAll('.event-id').length).to.equal(2);
expect(findAll('.event-id')[0]).to.have.trimmed.text('3');
await click('.previous');
expect(findAll('.event-id').length).to.equal(2);
expect(findAll('.event-id')[0]).to.have.trimmed.text('5');
// nothing should change if user tries to load previous page on the first one
await click('.previous');
expect(findAll('.event-id').length).to.equal(2);
expect(findAll('.event-id')[0]).to.have.trimmed.text('5');
});
it('change error state and show error message if fetch was unsuccessful ', async function () {
this.server.createList('member-activity-event', 10, {createdAt: moment('2022-11-01 12:00:00').format('YYYY-MM-DD HH:mm:ss')});
await render(hbs`
{{#let (activity-feed-fetcher pageSize="2") as |eventsFetcher|}}
<button class="next" {{on "click" eventsFetcher.loadNextPage}}>Next page</button>
<div class="error">{{eventsFetcher.isError}}</div>
<div class="error-message">{{eventsFetcher.errorMessage}}</div>
{{/let}}
`);
expect(find('.error')).to.have.trimmed.text('false');
expect(find('.error-message')).to.have.trimmed.text('');
this.server.get(
'/members/events',
() => ({errors: [{message: 'Error message'}]}),
500
);
await click('.next');
expect(find('.error')).to.have.trimmed.text('true');
expect(find('.error-message')).to.have.trimmed.text('Error message');
});
});