Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow scheduled posts to be shifted around on calendar #614

Merged
merged 1 commit into from
May 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions modules/calendar/calendar.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ class EF_Calendar extends EF_Module {
private $post_date_cache = array();
private static $post_li_html_cache_key = 'ef_calendar_post_li_html';

/**
* Calendar published statuses are the same as other
* components but without the future
*/
public $published_statuses = array(
'publish',
'private',
);

/**
* Construct the EF_Calendar class
*/
Expand Down
2 changes: 1 addition & 1 deletion modules/calendar/lib/calendar.css
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ table#ef-calendar-view .day-unit ul li .item-status {
line-height: 13px;
color: #999999;
word-wrap: break-word;
width: 55px;
width: 60px;
float: right;
padding-right: 2px;
text-align: right;
Expand Down
102 changes: 0 additions & 102 deletions tests/e2e/config/setup-test-framework.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,108 +203,6 @@ async function runAxeTestsForBlockEditor() {
} );
}

/**
* The following is copied from @wordpress/jest-console.
* There are existing console warnings that Edit Flow causing that need to be resolved before this can be turned back on.
* In the meantime, we'll configure this ourselves and ignore warnings that are thrown for the time being
*/

const supportedMatchers = {
error: 'toHaveErrored',
info: 'toHaveInformed',
log: 'toHaveLogged',
// warn: 'toHaveWarned', // Removing this because Edit Flow is emitting warnings that need to be fixed
};

const createToBeCalledMatcher = ( matcherName, methodName ) =>
( received ) => {
const spy = received[ methodName ];
const calls = spy.mock.calls;
const pass = calls.length > 0;
const message = pass ?
() =>
matcherHint( `.not${ matcherName }`, spy.getMockName() ) +
'\n\n' +
'Expected mock function not to be called but it was called with:\n' +
calls.map( printReceived ) :
() =>
matcherHint( matcherName, spy.getMockName() ) +
'\n\n' +
'Expected mock function to be called.';

spy.assertionsNumber += 1;

return {
message,
pass,
};
};

const createToBeCalledWithMatcher = ( matcherName, methodName ) =>
( received, ...expected ) => {
const spy = received[ methodName ];
const calls = spy.mock.calls;
const pass = some(
calls,
( objects ) => isEqual( objects, expected )
);
const message = pass ?
() =>
matcherHint( `.not${ matcherName }`, spy.getMockName() ) +
'\n\n' +
'Expected mock function not to be called with:\n' +
printExpected( expected ) :
() =>
matcherHint( matcherName, spy.getMockName() ) +
'\n\n' +
'Expected mock function to be called with:\n' +
printExpected( expected ) + '\n' +
'but it was called with:\n' +
calls.map( printReceived );

spy.assertionsNumber += 1;

return {
message,
pass,
};
};

expect.extend(
reduce( supportedMatchers, ( result, matcherName, methodName ) => {
const matcherNameWith = `${ matcherName }With`;

return {
...result,
[ matcherName ]: createToBeCalledMatcher( `.${ matcherName }`, methodName ),
[ matcherNameWith ]: createToBeCalledWithMatcher( `.${ matcherNameWith }`, methodName ),
};
}, {} )
);

/**
* Sets spy on the console object's method to make it possible to fail test when method called without assertion.
*
* @param {string} matcherName Name of Jest matcher.
* @param {string} methodName Name of console method.
*/
const setConsoleMethodSpy = ( matcherName, methodName ) => {
const spy = jest.spyOn( console, methodName ).mockName( `console.${ methodName }` );

beforeEach( () => {
spy.mockReset();
spy.assertionsNumber = 0;
} );

afterEach( () => {
if ( spy.assertionsNumber === 0 && spy.mock.calls.length > 0 ) {
expect( console ).not[ matcherName ]();
}
} );
};

forEach( supportedMatchers, setConsoleMethodSpy );

// Before every test suite run, delete all content created by the test. This ensures
// other posts/comments/etc. aren't dirtying tests and tests don't depend on
// each other's side-effects.
Expand Down
8 changes: 4 additions & 4 deletions tests/e2e/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ module.exports = {
setupFilesAfterEnv: [
'<rootDir>/config/setup-test-framework.js',
/**
* There are existing console warnings that Edit Flow causing
* that need to be resolved before this can be turned back on.
* In the meantime, we'll configure this ourselves
* and ignore warnings that are thrown for the time being
* Sometimes Edit Flow causes a console warning/error
* and sometimes core does, irrespective of the test being
* run. So we're not going to enable `jest-console` for the time
* being.
*
* ex: "[DOM] Found 2 elements with non-unique id #_wpnonce: (More info: https://goo.gl/9p2vKq) %o %o"],["[DOM] Found 2 elements with non-unique id #_wpnonce: (More info: https://goo.gl/9p2vKq) %o %o"
*/
Expand Down
98 changes: 98 additions & 0 deletions tests/e2e/specs/calendar-body.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* WordPress dependencies
*/

import { createNewPost, visitAdminPage, saveDraft } from "@wordpress/e2e-test-utils";
import { publishPost, schedulePost } from '../utils';

describe("Calendar Body", () => {

it("expects a published post cannot be dragged and dropped", async () => {
await createNewPost({title: 'Published Post' });
await publishPost();

await visitAdminPage("index.php", "page=calendar");

await page.waitForSelector('.ef-calendar-header');

const dayUnit = await page.$('.day-unit');
const dayUnitBoundingBox = await dayUnit.boundingBox();

const publishedPost = (await page.$x('//strong[text()="Published Post"]'))[0];
const publishedPostParent = await publishedPost.evaluateHandle((node) => node.closest('.day-item'));
const publishedPostParentBounding = await publishedPostParent.boundingBox();
const publishedPostDay = await publishedPost.evaluateHandle((node) => node.closest('.post-list'));
const publishedPostDayBounding = await publishedPostDay.boundingBox();

await page.mouse.move(publishedPostParentBounding.x + publishedPostParentBounding.width / 2, publishedPostParentBounding.y + publishedPostParentBounding.height / 2);
await page.mouse.down();
await page.mouse.move(publishedPostParentBounding.x, publishedPostParentBounding.y + publishedPostDayBounding.height);
await page.mouse.up();


expect(await publishedPostDay.evaluate((node) => {
return Array.prototype.slice.call(node.querySelectorAll('.item-headline.post-title strong')).map((n) => n.innerText)
})).toContain('Published Post');
});

it("expects an unpublished post can be dragged and dropped", async () => {
await createNewPost({title: 'Unpublished Post' });
await saveDraft();

await visitAdminPage("index.php", "page=calendar");

await page.waitForSelector('.ef-calendar-header');

const unpublishedPost = (await page.$x('//strong[text()="Unpublished Post"]'))[0];
const unpublishedPostParent = await unpublishedPost.evaluateHandle((node) => node.closest('.day-item'));
const unpublishedPostParentBounding = await unpublishedPostParent.boundingBox();
const unpublishedPostDay = await unpublishedPost.evaluateHandle((node) => node.closest('.post-list'));
const unpublishedPostDayBounding = await unpublishedPostDay.boundingBox();

/**
* Simulate drag and drop
*/
await page.mouse.move(unpublishedPostParentBounding.x + unpublishedPostParentBounding.width / 2, unpublishedPostParentBounding.y + unpublishedPostParentBounding.height / 2);
await page.mouse.down();
await page.mouse.move(unpublishedPostParentBounding.x + unpublishedPostParentBounding.width / 2, unpublishedPostParentBounding.y + unpublishedPostDayBounding.height + 20);
await page.mouse.up();

await page.waitFor(200);

expect(await unpublishedPostDay.evaluate((node) => {
return Array.prototype.slice.call(node.querySelectorAll('.item-headline.post-title strong')).map((n) => n.innerText)
})).not.toContain('Unpublished Post');
});

it("expects a scheduled post can be dragged and dropped", async () => {
await createNewPost({title: 'Scheduled Post' });
await schedulePost();

await visitAdminPage("index.php", "page=calendar");

await page.waitForSelector('.ef-calendar-header');

const scheduledPost = (await page.$x('//strong[text()="Scheduled Post"]'))[0];
const scheduledPostParent = await scheduledPost.evaluateHandle((node) => node.closest('.day-item'));
const scheduledPostParentBounding = await scheduledPostParent.boundingBox();
const scheduledPostDay = await scheduledPost.evaluateHandle((node) => node.closest('.post-list'));
const scheduledPostDayBounding = await scheduledPostDay.boundingBox();

/**
* Simulate drag and drop
*/
await page.mouse.move(scheduledPostParentBounding.x + scheduledPostParentBounding.width / 2, scheduledPostParentBounding.y + scheduledPostParentBounding.height / 2);
await page.mouse.down();
await page.waitFor(3000);
await page.mouse.move(scheduledPostParentBounding.x + scheduledPostParentBounding.width / 2, scheduledPostParentBounding.y - scheduledPostDayBounding.height - 20);
await page.waitFor(3000);
await page.mouse.up();
await page.waitFor(3000);

await page.waitFor(200);

expect(await scheduledPostDay.evaluate((node) => {
return Array.prototype.slice.call(node.querySelectorAll('.item-headline.post-title strong')).map((n) => n.innerText)
})).not.toContain('Scheduled Post');
});
});
18 changes: 17 additions & 1 deletion tests/e2e/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,20 @@ const publishPost = async() => {

}

export { addCategoryToPost, publishPost }
const schedulePost = async() => {
await page.waitForSelector( '.edit-post-post-schedule__toggle' );

await page.click( '.edit-post-post-schedule__toggle' );

// wait for popout animation
await page.waitFor(200);

await page.click( 'div[aria-label="Move forward to switch to the next month."]' );

await page.click( '.CalendarDay_1' );

await publishPost();

}

export { addCategoryToPost, publishPost, schedulePost }