瀏覽代碼

automated tests for event/select overlap

Adam Shaw 11 年之前
父節點
當前提交
c646503520
共有 3 個文件被更改,包括 1008 次插入7 次删除
  1. 1 1
      tests/automated/background-events.js
  2. 991 0
      tests/automated/overlap.js
  3. 16 6
      tests/lib/dnd-resize-utils.js

+ 1 - 1
tests/automated/background-events.js

@@ -1,5 +1,5 @@
 
-ddescribe('background events', function() {
+describe('background events', function() {
 
 	var options;
 

+ 991 - 0
tests/automated/overlap.js

@@ -0,0 +1,991 @@
+
+describe('event overlap', function() {
+	var options;
+
+	beforeEach(function() {
+		options = {
+			defaultDate: '2014-11-04',
+			defaultView: 'agendaWeek',
+			scrollTime: '00:00'
+		};
+		affix('#cal');
+		$('#cal').width(1100);
+	});
+
+	describe('when other event overlap is false', function() {
+
+		describe('when dragged adjacently before the other event', function() {
+			describe('when subject event\'s end is explicit', function() {
+				it('allows dragging', function(done) {
+					options.events = [
+						{
+							title: 'Event A',
+							className: 'event-a',
+							start: '2014-11-04T01:00:00',
+							end: '2014-11-04T03:00:00'
+						},
+						{
+							title: 'Event B',
+							className: 'event-b',
+							start: '2014-11-04T05:00:00',
+							end: '2014-11-04T09:00:00',
+							overlap: false
+						}
+					];
+					testEventDrag(options, '2014-11-04T03:00:00', true, done, 'event-a');
+				});
+			});
+			describe('when subject event\'s end is implied', function() {
+				it('allows dragging', function(done) {
+					options.defaultTimedEventDuration = '01:30';
+					options.events = [
+						{
+							title: 'Event A',
+							className: 'event-a',
+							start: '2014-11-04T01:00:00'
+						},
+						{
+							title: 'Event B',
+							className: 'event-b',
+							start: '2014-11-04T05:00:00',
+							end: '2014-11-04T09:00:00',
+							overlap: false
+						}
+					];
+					testEventDrag(options, '2014-11-04T03:30:00', true, done, 'event-a');
+				});
+			});
+		});
+
+		describe('when dragged adjacently after the other event', function() {
+			it('allows dragging', function(done) {
+				options.events = [
+					{
+						title: 'Event A',
+						className: 'event-a',
+						start: '2014-11-04T01:00:00',
+						end: '2014-11-04T03:00:00'
+					},
+					{
+						title: 'Event B',
+						className: 'event-b',
+						start: '2014-11-04T05:00:00',
+						end: '2014-11-04T09:00:00',
+						overlap: false
+					}
+				];
+				testEventDrag(options, '2014-11-04T09:00:00', true, done, 'event-a');
+			});
+		});
+
+		describe('when dragged intersecting the other event\'s start', function() {
+			describe('when no timezone', function() {
+				describe('when subject event\'s end is explicit', function() {
+					it('does not allow dragging', function(done) {
+						options.events = [
+							{
+								title: 'Event A',
+								className: 'event-a',
+								start: '2014-11-04T01:00:00',
+								end: '2014-11-04T03:00:00'
+							},
+							{
+								title: 'Event B',
+								className: 'event-b',
+								start: '2014-11-04T05:00:00',
+								end: '2014-11-04T09:00:00',
+								overlap: false
+							}
+						];
+						testEventDrag(options, '2014-11-04T04:00:00', false, done, 'event-a');
+					});
+				});
+				describe('when subject event\'s end is implied', function() {
+					it('does not allow dragging', function(done) {
+						options.defaultTimedEventDuration = '03:00';
+						options.events = [
+							{
+								title: 'Event A',
+								className: 'event-a',
+								start: '2014-11-04T01:00:00'
+							},
+							{
+								title: 'Event B',
+								className: 'event-b',
+								start: '2014-11-04T05:00:00',
+								end: '2014-11-04T09:00:00',
+								overlap: false
+							}
+						];
+						testEventDrag(options, '2014-11-04T03:00:00', false, done, 'event-a');
+					});
+				});
+			});
+			describe('when UTC timezone', function() {
+				it('does not allow dragging', function(done) {
+					options.timezone = 'UTC';
+					options.events = [
+						{
+							title: 'Event A',
+							className: 'event-a',
+							start: '2014-11-04T01:00:00+00:00',
+							end: '2014-11-04T03:00:00+00:00'
+						},
+						{
+							title: 'Event B',
+							className: 'event-b',
+							start: '2014-11-04T05:00:00+00:00',
+							end: '2014-11-04T09:00:00+00:00',
+							overlap: false
+						}
+					];
+					testEventDrag(options, '2014-11-04T04:00:00+00:00', false, done, 'event-a');
+				});
+			});
+		});
+
+		describe('when dragged intersecting the other event\'s end', function() {
+			describe('when in agendaWeek view with timed events', function() {
+				describe('when no timezone', function() {
+					it('does not allow dragging', function(done) {
+						options.events = [
+							{
+								title: 'Event A',
+								className: 'event-a',
+								start: '2014-11-04T01:00:00',
+								end: '2014-11-04T03:00:00'
+							},
+							{
+								title: 'Event B',
+								className: 'event-b',
+								start: '2014-11-04T05:00:00',
+								end: '2014-11-04T09:00:00',
+								overlap: false
+							}
+						];
+						testEventDrag(options, '2014-11-04T08:00:00', false, done, 'event-a');
+					});
+				});
+				describe('when UTC timezone', function() {
+					it('does not allow dragging', function(done) {
+						options.timezone = 'UTC';
+						options.events = [
+							{
+								title: 'Event A',
+								className: 'event-a',
+								start: '2014-11-04T01:00:00+00:00',
+								end: '2014-11-04T03:00:00+00:00'
+							},
+							{
+								title: 'Event B',
+								className: 'event-b',
+								start: '2014-11-04T05:00:00+00:00',
+								end: '2014-11-04T09:00:00+00:00',
+								overlap: false
+							}
+						];
+						testEventDrag(options, '2014-11-04T08:00:00+00:00', false, done, 'event-a');
+					});
+				});
+			});
+			describe('when in month view', function() {
+				beforeEach(function() {
+					options.defaultView = 'month';
+				});
+				describe('with all-day subject and all-day other', function() {
+					it('does not allow dragging', function(done) {
+						options.events = [
+							{
+								title: 'Event A',
+								className: 'event-a',
+								start: '2014-11-04',
+								end: '2014-11-05'
+							},
+							{
+								title: 'Event B',
+								className: 'event-b',
+								start: '2014-11-07',
+								end: '2014-11-09',
+								overlap: false
+							}
+						];
+						testEventDrag(options, '2014-11-08', false, done, 'event-a');
+					});
+				});
+				describe('with all-day subject and timed other', function() {
+					it('does not allow dragging', function(done) {
+						options.events = [
+							{
+								title: 'Event A',
+								className: 'event-a',
+								start: '2014-11-04',
+								end: '2014-11-05'
+							},
+							{
+								title: 'Event B',
+								className: 'event-b',
+								start: '2014-11-07T05:00:00',
+								end: '2014-11-09T12:00:00',
+								overlap: false
+							}
+						];
+						testEventDrag(options, '2014-11-08', false, done, 'event-a');
+					});
+				});
+			});
+		});
+
+		describe('when dragged to be encompassed by the other event', function() {
+			it('does not allow dragging', function(done) {
+				options.events = [
+					{
+						title: 'Event A',
+						className: 'event-a',
+						start: '2014-11-04T01:00:00',
+						end: '2014-11-04T03:00:00'
+					},
+					{
+						title: 'Event B',
+						className: 'event-b',
+						start: '2014-11-04T05:00:00',
+						end: '2014-11-04T09:00:00',
+						overlap: false
+					}
+				];
+				testEventDrag(options, '2014-11-04T06:00:00', false, done, 'event-a');
+			});
+			describe('when both events have the same ID', function() {
+				it('allows the drag', function(done) {
+					options.events = [
+						{
+							id: 'myid',
+							title: 'Event A',
+							className: 'event-a',
+							start: '2014-11-04T01:00:00',
+							end: '2014-11-04T03:00:00'
+						},
+						{
+							id: 'myid',
+							title: 'Event B',
+							className: 'event-b',
+							start: '2014-11-04T05:00:00',
+							end: '2014-11-04T09:00:00',
+							overlap: false
+						}
+					];
+					testEventDrag(options, '2014-11-04T06:00:00', true, done, 'event-a');
+				});
+			});
+		});
+
+		describe('when resized to be adjacently before the other event', function() {
+			it('allows resizing', function(done) {
+				options.events = [
+					{
+						title: 'Event A',
+						className: 'event-a',
+						start: '2014-11-04T01:00:00',
+						end: '2014-11-04T03:00:00'
+					},
+					{
+						title: 'Event B',
+						className: 'event-b',
+						start: '2014-11-04T05:00:00',
+						end: '2014-11-04T09:00:00',
+						overlap: false
+					}
+				];
+				testEventResize(options, '2014-11-04T05:00:00', true, done, 'event-a');
+			});
+		});
+
+		describe('when resized to intersect the other event\'s start', function() {
+			it('does not allow resizing', function(done) {
+				options.events = [
+					{
+						title: 'Event A',
+						className: 'event-a',
+						start: '2014-11-04T01:00:00',
+						end: '2014-11-04T03:00:00'
+					},
+					{
+						title: 'Event B',
+						className: 'event-b',
+						start: '2014-11-04T05:00:00',
+						end: '2014-11-04T09:00:00',
+						overlap: false
+					}
+				];
+				testEventResize(options, '2014-11-04T06:00:00', false, done, 'event-a');
+			});
+		});
+	});
+
+	describe('when both events\' overlap is true AND they intersect', function() {
+		it('allows dragging', function(done) {
+			options.events = [
+				{
+					title: 'Event A',
+					className: 'event-a',
+					start: '2014-11-04T01:00:00',
+					end: '2014-11-04T03:00:00',
+					overlap: true
+				},
+				{
+					title: 'Event B',
+					className: 'event-b',
+					start: '2014-11-04T05:00:00',
+					end: '2014-11-04T09:00:00',
+					overlap: true
+				}
+			];
+			testEventDrag(options, '2014-11-04T04:00:00', true, done, 'event-a');
+		});
+	});
+
+	describe('when other eventSource overlap is false', function() {
+		describe('when dragged over the other event', function() {
+			it('does not allow dragging', function(done) {
+				options.eventSources = [
+					{
+						events: [ {
+							title: 'Event A',
+							className: 'event-a',
+							start: '2014-11-04T01:00:00',
+							end: '2014-11-04T03:00:00'
+						} ]
+					},
+					{
+						overlap: false,
+						events: [ {
+							title: 'Event B',
+							className: 'event-b',
+							start: '2014-11-04T05:00:00',
+							end: '2014-11-04T09:00:00'
+						} ]
+					}
+				];
+				testEventDrag(options, '2014-11-04T06:00:00', false, done, 'event-a');
+			});
+		});
+	});
+
+	describe('when other eventSource overlap is a function', function() {
+		describe('when dragged over an intersecting event', function() {
+			describe('and function returns false', function() {
+				it('does not allow dragging', function(done) {
+					options.eventSources = [
+						{
+							events: [ {
+								title: 'Event A',
+								className: 'event-a',
+								start: '2014-11-04T01:00:00',
+								end: '2014-11-04T03:00:00'
+							} ]
+						},
+						{
+							overlap: function(otherEvent, thisEvent) {
+								// checks that the arguments are correct
+								expect(otherEvent.title).toBe('Event A');
+								expect(thisEvent.title).toBe('Event B');
+								return false;
+							},
+							events: [ {
+								title: 'Event B',
+								className: 'event-b',
+								start: '2014-11-04T05:00:00',
+								end: '2014-11-04T09:00:00'
+							} ]
+						}
+					];
+					testEventDrag(options, '2014-11-04T06:00:00', false, done, 'event-a');
+				});
+			});
+			describe('and function returns true', function() {
+				it('allows dragging', function(done) {
+					options.eventSources = [
+						{
+							events: [ {
+								title: 'Event A',
+								className: 'event-a',
+								start: '2014-11-04T01:00:00',
+								end: '2014-11-04T03:00:00'
+							} ]
+						},
+						{
+							overlap: function() {
+								return true;
+							},
+							events: [ {
+								title: 'Event B',
+								className: 'event-b',
+								start: '2014-11-04T05:00:00',
+								end: '2014-11-04T09:00:00'
+							} ]
+						}
+					];
+					testEventDrag(options, '2014-11-04T06:00:00', true, done, 'event-a');
+				});
+			});
+		});
+	});
+
+	describe('when subject event is false', function() {
+		describe('when dragged adjacently after the other event', function() {
+			it('allows dragging', function(done) {
+				options.events = [
+					{
+						title: 'Event A',
+						className: 'event-a',
+						start: '2014-11-04T01:00:00',
+						end: '2014-11-04T03:00:00',
+						overlap: false
+					},
+					{
+						title: 'Event B',
+						className: 'event-b',
+						start: '2014-11-04T05:00:00',
+						end: '2014-11-04T09:00:00'
+					}
+				];
+				testEventDrag(options, '2014-11-04T09:00:00', true, done, 'event-a');
+			});
+		});
+		describe('when dragged intersecting the other event\'s end', function() {
+			it('does not allow dragging', function(done) {
+				options.events = [
+					{
+						title: 'Event A',
+						className: 'event-a',
+						start: '2014-11-04T01:00:00',
+						end: '2014-11-04T03:00:00',
+						overlap: false
+					},
+					{
+						title: 'Event B',
+						className: 'event-b',
+						start: '2014-11-04T05:00:00',
+						end: '2014-11-04T09:00:00'
+					}
+				];
+				testEventDrag(options, '2014-11-04T04:00:00', false, done, 'event-a');
+			});
+		});
+	});
+
+	describe('when subject eventSource is false', function() {
+		describe('when dragged after the other event', function() {
+			it('allows dragging', function(done) {
+				options.eventSources = [
+					{
+						overlap: false,
+						events: [ {
+							title: 'Event A',
+							className: 'event-a',
+							start: '2014-11-04T01:00:00',
+							end: '2014-11-04T03:00:00'
+						} ]
+					},
+					{
+						events: [ {
+							title: 'Event B',
+							className: 'event-b',
+							start: '2014-11-04T05:00:00',
+							end: '2014-11-04T09:00:00'
+						} ]
+					}
+				];
+				testEventDrag(options, '2014-11-04T09:00:00', true, done, 'event-a');
+			});
+		});
+		describe('when dragged over the other event', function() {
+			it('does not allow dragging', function(done) {
+				options.eventSources = [
+					{
+						overlap: false,
+						events: [ {
+							title: 'Event A',
+							className: 'event-a',
+							start: '2014-11-04T01:00:00',
+							end: '2014-11-04T03:00:00'
+						} ]
+					},
+					{
+						events: [ {
+							title: 'Event B',
+							className: 'event-b',
+							start: '2014-11-04T05:00:00',
+							end: '2014-11-04T09:00:00'
+						} ]
+					}
+				];
+				testEventDrag(options, '2014-11-04T06:00:00', false, done, 'event-a');
+			});
+		});
+	});
+
+	describe('when subject eventSource is a function', function() {
+		describe('when dragged over an intersecting event', function() {
+			describe('and function returns false', function() {
+				it('does not allow dragging', function(done) {
+					options.eventSources = [
+						{
+							overlap: function(otherEvent, thisEvent) {
+								// checking parameters here
+								expect(otherEvent.title).toBe('Event B');
+								expect(thisEvent.title).toBe('Event A');
+								return false;
+							},
+							events: [ {
+								title: 'Event A',
+								className: 'event-a',
+								start: '2014-11-04T01:00:00',
+								end: '2014-11-04T03:00:00'
+							} ]
+						},
+						{
+							events: [ {
+								title: 'Event B',
+								className: 'event-b',
+								start: '2014-11-04T05:00:00',
+								end: '2014-11-04T09:00:00'
+							} ]
+						}
+					];
+					testEventDrag(options, '2014-11-04T06:00:00', false, done, 'event-a');
+				});
+			});
+			describe('and function returns true', function() {
+				it('allows dragging', function(done) {
+					options.eventSources = [
+						{
+							overlap: function(otherEvent, thisEvent) {
+								return true;
+							},
+							events: [ {
+								title: 'Event A',
+								className: 'event-a',
+								start: '2014-11-04T01:00:00',
+								end: '2014-11-04T03:00:00'
+							} ]
+						},
+						{
+							events: [ {
+								title: 'Event B',
+								className: 'event-b',
+								start: '2014-11-04T05:00:00',
+								end: '2014-11-04T09:00:00'
+							} ]
+						}
+					];
+					testEventDrag(options, '2014-11-04T06:00:00', true, done, 'event-a');
+				});
+			});
+		});
+		describe('when other eventSource is ALSO a function', function() {
+			describe('and only the subject\'s function returns false', function() {
+				it('disallows dragging', function(done) {
+					options.eventSources = [
+						{
+							overlap: function(otherEvent, thisEvent) {
+								return false;
+							},
+							events: [ {
+								title: 'Event A',
+								className: 'event-a',
+								start: '2014-11-04T01:00:00',
+								end: '2014-11-04T03:00:00'
+							} ]
+						},
+						{
+							overlap: function(otherEvent, thisEvent) {
+								return true;
+							},
+							events: [ {
+								title: 'Event B',
+								className: 'event-b',
+								start: '2014-11-04T05:00:00',
+								end: '2014-11-04T09:00:00'
+							} ]
+						}
+					];
+					testEventDrag(options, '2014-11-04T06:00:00', false, done, 'event-a');
+				});
+			});
+			describe('and only the other\'s function returns false', function() {
+				it('disallows dragging', function(done) {
+					options.eventSources = [
+						{
+							overlap: function(otherEvent, thisEvent) {
+								return true;
+							},
+							events: [ {
+								title: 'Event A',
+								className: 'event-a',
+								start: '2014-11-04T01:00:00',
+								end: '2014-11-04T03:00:00'
+							} ]
+						},
+						{
+							overlap: function(otherEvent, thisEvent) {
+								return false;
+							},
+							events: [ {
+								title: 'Event B',
+								className: 'event-b',
+								start: '2014-11-04T05:00:00',
+								end: '2014-11-04T09:00:00'
+							} ]
+						}
+					];
+					testEventDrag(options, '2014-11-04T06:00:00', false, done, 'event-a');
+				});
+			});
+			describe('and neither function returns false', function() {
+				it('allows dragging', function(done) {
+					options.eventSources = [
+						{
+							overlap: function(otherEvent, thisEvent) {
+								return true;
+							},
+							events: [ {
+								title: 'Event A',
+								className: 'event-a',
+								start: '2014-11-04T01:00:00',
+								end: '2014-11-04T03:00:00'
+							} ]
+						},
+						{
+							overlap: function(otherEvent, thisEvent) {
+								return true;
+							},
+							events: [ {
+								title: 'Event B',
+								className: 'event-b',
+								start: '2014-11-04T05:00:00',
+								end: '2014-11-04T09:00:00'
+							} ]
+						}
+					];
+					testEventDrag(options, '2014-11-04T06:00:00', true, done, 'event-a');
+				});
+			});
+		});
+	});
+
+	describe('when eventOverlap is false', function() {
+		describe('when dragged adjacently after another event', function() {
+			it('allows dragging', function(done) {
+				options.eventOverlap = false;
+				options.events = [
+					{
+						title: 'Event A',
+						className: 'event-a',
+						start: '2014-11-04T01:00:00',
+						end: '2014-11-04T03:00:00'
+					},
+					{
+						title: 'Event B',
+						className: 'event-b',
+						start: '2014-11-04T05:00:00',
+						end: '2014-11-04T09:00:00'
+					}
+				];
+				testEventDrag(options, '2014-11-04T09:00:00', true, done, 'event-a');
+			});
+		});
+		describe('when dragged intersecting another event', function() {
+			it('does not allow dragging', function(done) {
+				options.eventOverlap = false;
+				options.events = [
+					{
+						title: 'Event A',
+						className: 'event-a',
+						start: '2014-11-04T01:00:00',
+						end: '2014-11-04T03:00:00'
+					},
+					{
+						title: 'Event B',
+						className: 'event-b',
+						start: '2014-11-04T05:00:00',
+						end: '2014-11-04T09:00:00'
+					}
+				];
+				testEventDrag(options, '2014-11-04T06:00:00', false, done, 'event-a');
+			});
+		});
+	});
+
+	describe('when eventOverlap is a function', function() {
+		describe('when no intersecting events upon drag', function() {
+			it('does not get called, allows dragging', function(done) {
+				options.eventOverlap = function() { };
+				options.events = [
+					{
+						title: 'Event A',
+						className: 'event-a',
+						start: '2014-11-04T01:00:00',
+						end: '2014-11-04T03:00:00'
+					},
+					{
+						title: 'Event B',
+						className: 'event-b',
+						start: '2014-11-04T03:00:00',
+						end: '2014-11-04T07:00:00'
+					}
+				];
+				spyOn(options, 'eventOverlap').and.callThrough();
+				testEventDrag(options, '2014-11-04T06:00:00', true, function() {
+					expect(options.eventOverlap).not.toHaveBeenCalled();
+					done();
+				}, 'event-b');
+			});
+		});
+		describe('when an intersection and returning true', function() {
+			it('allows dragging AND gets called', function(done) {
+				options.eventOverlap = function(stillEvent, movingEvent) {
+					// checks arguments here
+					expect(stillEvent.title).toBe('Event B');
+					expect(movingEvent.title).toBe('Event A');
+					return true;
+				};
+				options.events = [
+					{
+						title: 'Event A',
+						className: 'event-a',
+						start: '2014-11-04T01:00:00',
+						end: '2014-11-04T03:00:00'
+					},
+					{
+						title: 'Event B',
+						className: 'event-b',
+						start: '2014-11-04T05:00:00',
+						end: '2014-11-04T09:00:00'
+					}
+				];
+				spyOn(options, 'eventOverlap').and.callThrough();
+				testEventDrag(options, '2014-11-04T06:00:00', true, function() {
+					expect(options.eventOverlap).toHaveBeenCalled();
+					done();
+				}, 'event-a');
+			});
+		});
+		describe('when an intersection and returning false', function() {
+			it('disallows dragging AND gets called', function(done) {
+				options.eventOverlap = function() {
+					return false;
+				};
+				options.events = [
+					{
+						title: 'Event A',
+						className: 'event-a',
+						start: '2014-11-04T01:00:00',
+						end: '2014-11-04T03:00:00'
+					},
+					{
+						title: 'Event B',
+						className: 'event-b',
+						start: '2014-11-04T05:00:00',
+						end: '2014-11-04T09:00:00'
+					}
+				];
+				spyOn(options, 'eventOverlap').and.callThrough();
+				testEventDrag(options, '2014-11-04T06:00:00', false, function() {
+					expect(options.eventOverlap).toHaveBeenCalled();
+					done();
+				}, 'event-a');
+			});
+		});
+	});
+});
+
+describe('selectOverlap', function() {
+	var options;
+
+	beforeEach(function() {
+		options = {
+			defaultDate: '2014-11-12',
+			defaultView: 'agendaWeek',
+			scrollTime: '00:00'
+		};
+		affix('#cal');
+		$('#cal').width(1100);
+	});
+
+	describe('as false', function() {
+		beforeEach(function() {
+			options.selectOverlap = false;
+		});
+		describe('when dragged adjacently before an event', function() {
+			it('allows selection', function(done) {
+				options.events = [ {
+					title: 'Event A',
+					start: '2014-11-12T04:00:00',
+					end: '2014-11-12T06:00:00'
+				} ];
+				testSelection(options, '01:00', '2014-11-12T04:00:00', true, done);
+			});
+		});
+		describe('when dragged adjacently after an event', function() {
+			it('allows selection', function(done) {
+				options.events = [ {
+					title: 'Event A',
+					start: '2014-11-12T04:00:00',
+					end: '2014-11-12T06:00:00'
+				} ];
+				testSelection(options, '06:00', '2014-11-12T12:00:00', true, done);
+			});
+		});
+		describe('when dragged intersecting an event\'s start', function() {
+			describe('when no timezone', function() {
+				it('does not allow selection', function(done) {
+					options.events = [ {
+						title: 'Event A',
+						start: '2014-11-12T04:00:00',
+						end: '2014-11-12T06:00:00'
+					} ];
+					testSelection(options, '01:00', '2014-11-12T05:00:00', false, done);
+				});
+			});
+			describe('when UTC timezone', function() {
+				it('does not allow selection', function(done) {
+					options.timezone = 'UTC';
+					options.events = [ {
+						title: 'Event A',
+						start: '2014-11-12T04:00:00+00:00',
+						end: '2014-11-12T06:00:00+00:00'
+					} ];
+					testSelection(options, '01:00', '2014-11-12T05:00:00+00:00', false, done);
+				});
+			});
+		});
+		describe('when dragged intersecting an event\'s end', function() {
+			describe('when in agendaWeek view with timed events', function() {
+				describe('when no timezone', function() {
+					it('does not allow selection', function(done) {
+						options.events = [ {
+							title: 'Event A',
+							start: '2014-11-12T04:00:00',
+							end: '2014-11-12T06:00:00'
+						} ];
+						testSelection(options, '05:00', '2014-11-12T08:00:00', false, done);
+					});
+				});
+				describe('when UTC timezone', function() {
+					it('does not allow selection', function(done) {
+						options.timezone = 'UTC';
+						options.events = [ {
+							title: 'Event A',
+							start: '2014-11-12T04:00:00+00:00',
+							end: '2014-11-12T06:00:00+00:00'
+						} ];
+						testSelection(options, '05:00', '2014-11-12T08:00:00+00:00', false, done);
+					});
+				});
+			});
+			describe('when in month view', function() {
+				beforeEach(function() {
+					options.defaultView = 'month';
+				});
+				describe('with all-day event', function() {
+					it('does not allow selection', function(done) {
+						options.events = [ {
+							title: 'Event A',
+							start: '2014-11-12',
+							end: '2014-11-14'
+						} ];
+						testSelection(options, null, '2014-11-13', false, done);
+					});
+				});
+				describe('with timed event', function() {
+					it('does not allow selection', function(done) {
+						options.events = [ {
+							title: 'Event A',
+							start: '2014-11-12T05:00:00',
+							end: '2014-11-14T20:00:00'
+						} ];
+						testSelection(options, null, '2014-11-13', false, done);
+					});
+				});
+			});
+		});
+		describe('when dragged to be encompassed by an event', function() {
+			it('does not allow selection', function(done) {
+				options.events = [ {
+					title: 'Event A',
+					start: '2014-11-12T04:00:00',
+					end: '2014-11-12T10:00:00'
+				} ];
+				testSelection(options, '05:00', '2014-11-12T08:00:00', false, done);
+			});
+		});
+	});
+
+	describe('as a function', function() {
+		describe('when no intersecting events when selecting', function() {
+			it('does not get called, allows selection', function(done) {
+				options.selectOverlap = function() { };
+				options.events = [ {
+					title: 'Event A',
+					start: '2014-11-12T04:00:00',
+					end: '2014-11-12T06:00:00'
+				} ];
+				spyOn(options, 'selectOverlap').and.callThrough();
+				testSelection(options, '08:00', '2014-11-12T10:00:00', true, function() {
+					expect(options.selectOverlap).not.toHaveBeenCalled();
+					done();
+				});
+			});
+		});
+		describe('when an intersection and returning true', function() {
+			it('allows selection', function(done) {
+				options.selectOverlap = function(o) {
+					// checks arguments here
+					expect(o.title).toBe('Event A');
+					expect(arguments[1]).toBeFalsy();
+					return true;
+				};
+				options.events = [ {
+					title: 'Event A',
+					start: '2014-11-12T04:00:00',
+					end: '2014-11-12T06:00:00'
+				} ];
+				spyOn(options, 'selectOverlap').and.callThrough();
+				testSelection(options, '05:00', '2014-11-12T07:00:00', true, function() {
+					expect(options.selectOverlap).toHaveBeenCalled();
+					done();
+				});
+			});
+		});
+		describe('when an intersection and returning false', function() {
+			it('does not allow selection', function(done) {
+				options.selectOverlap = function() {
+					return false;
+				};
+				options.events = [ {
+					title: 'Event A',
+					start: '2014-11-12T04:00:00',
+					end: '2014-11-12T06:00:00'
+				} ];
+				spyOn(options, 'selectOverlap').and.callThrough();
+				testSelection(options, '05:00', '2014-11-12T07:00:00', false, function() {
+					expect(options.selectOverlap).toHaveBeenCalled();
+					done();
+				});
+			});
+		});
+	});
+
+	describe('as true and an event object\'s overlap is false', function() {
+		it('is not affected AND allows the selection', function(done) {
+			options.selectOverlap = true;
+			options.events = [ {
+				title: 'Event A',
+				start: '2014-11-12T04:00:00',
+				end: '2014-11-12T06:00:00',
+				overlap: false
+			} ];
+			testSelection(options, '05:00', '2014-11-12T07:00:00', true, done);
+		});
+	});
+});

+ 16 - 6
tests/lib/dnd-resize-utils.js

@@ -1,5 +1,5 @@
 
-function testEventDrag(options, dropDate, expectSuccess, callback) {
+function testEventDrag(options, dropDate, expectSuccess, callback, eventClassName) {
 	var eventsRendered = false;
 
 	options.editable = true;
@@ -16,7 +16,7 @@ function testEventDrag(options, dropDate, expectSuccess, callback) {
 		eventsRendered = true;
 
 		dropDate = calendar.moment(dropDate);
-		eventEl = $('.fc-event:first');
+		eventEl = $('.' + (eventClassName || 'fc-event') + ':first');
 		expect(eventEl.length).toBe(1);
 		
 		if (dropDate.hasTime()) {
@@ -45,8 +45,18 @@ function testEventDrag(options, dropDate, expectSuccess, callback) {
 
 				dragEl.simulate('drop', {
 					callback: function() {
-						var eventObj = calendar.clientEvents()[0];
-						var successfulDrop = eventObj.start.format() == dropDate.format();
+						var eventObj;
+						var successfulDrop;
+
+						if (eventClassName) {
+							eventObj = calendar.clientEvents(function(o) {
+								return o.className.join(' ') === eventClassName;
+							})[0];
+						}
+						else {
+							eventObj = calendar.clientEvents()[0];
+						}
+						successfulDrop = eventObj.start.format() == dropDate.format();
 
 						expect(allowed).toBe(successfulDrop);
 						expect(allowed).toBe(expectSuccess);
@@ -61,7 +71,7 @@ function testEventDrag(options, dropDate, expectSuccess, callback) {
 }
 
 
-function testEventResize(options, resizeDate, expectSuccess, callback) {
+function testEventResize(options, resizeDate, expectSuccess, callback, eventClassName) {
 	var eventsRendered = false;
 
 	options.editable = true;
@@ -78,7 +88,7 @@ function testEventResize(options, resizeDate, expectSuccess, callback) {
 		eventsRendered = true;
 
 		resizeDate = calendar.moment(resizeDate);
-		eventEl = $('.fc-event:last');
+		eventEl = $('.' + (eventClassName || 'fc-event') + ':last');
 		dragEl = eventEl.find('.fc-resizer');
 
 		if (resizeDate.hasTime()) {