diff --git a/Gemfile b/Gemfile
index ef35abc6e..882f14c92 100644
--- a/Gemfile
+++ b/Gemfile
@@ -3,7 +3,7 @@ source 'http://rubygems.org'
gem 'rails', '>= 3.0.0'
gem 'bundler', '>= 1.0.0'
-#gem "chef"
+gem "chef", :require => false
#Security
gem 'devise', '1.1.3'
diff --git a/Gemfile.lock b/Gemfile.lock
index 3a4976383..bd4190fe3 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,6 +1,6 @@
GIT
remote: git://github.com/Empact/roxml.git
- revision: d411519add92e0cd5a985253f376d25c26884324
+ revision: 7ea9a9ffd2338aaef5b04cb792060ae8c98f346a
specs:
roxml (3.1.6)
activesupport (>= 2.3.0)
@@ -39,7 +39,7 @@ GIT
GIT
remote: git://github.com/jnunemaker/mongomapper.git
- revision: fd59b0ab068be7321f8e84b9dc12fb4fa6b8535d
+ revision: b24db29c236f239d6a5a821fb6a444430e89f9d6
branch: rails3
specs:
mongo_mapper (0.8.4)
@@ -117,6 +117,7 @@ GEM
bson (1.1)
bson_ext (1.1)
builder (2.1.2)
+ bunny (0.6.0)
capistrano (2.5.19)
highline
net-scp (>= 1.0.0)
@@ -131,6 +132,20 @@ GEM
rack-test (>= 0.5.4)
selenium-webdriver (>= 0.0.3)
cgi_multipart_eof_fix (2.5.0)
+ chef (0.9.12)
+ bunny (>= 0.6.0)
+ erubis
+ extlib
+ highline
+ json (>= 1.4.4, <= 1.4.6)
+ mixlib-authentication (>= 1.1.0)
+ mixlib-cli (>= 1.1.0)
+ mixlib-config (>= 1.1.2)
+ mixlib-log (>= 1.2.0)
+ moneta
+ ohai (>= 0.5.7)
+ rest-client (>= 1.0.4, < 1.7.0)
+ uuidtools
childprocess (0.1.3)
ffi (~> 0.6.3)
columnize (0.3.1)
@@ -150,7 +165,7 @@ GEM
devise (1.1.3)
bcrypt-ruby (~> 2.1.2)
warden (~> 0.10.7)
- devise_invitable (0.3.4)
+ devise_invitable (0.3.5)
devise (~> 1.1.0)
diff-lcs (1.1.2)
em-websocket (0.1.4)
@@ -159,6 +174,7 @@ GEM
erubis (2.6.6)
abstract (>= 1.0.0)
eventmachine (0.12.10)
+ extlib (0.9.15)
factory_girl (1.3.2)
factory_girl_rails (1.0)
factory_girl (~> 1.3)
@@ -174,7 +190,7 @@ GEM
gherkin (2.2.9)
json (~> 1.4.6)
term-ansicolor (~> 1.0.5)
- haml (3.0.22)
+ haml (3.0.23)
hashie (0.4.0)
highline (1.6.1)
http_connection (1.4.0)
@@ -193,13 +209,19 @@ GEM
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.16)
- mini_fb (1.1.3)
+ mini_fb (1.1.4)
hashie
rest-client
mini_magick (3.0)
subexec (~> 0.0.4)
+ mixlib-authentication (1.1.4)
+ mixlib-log
+ mixlib-cli (1.2.0)
+ mixlib-config (1.1.2)
+ mixlib-log (1.2.0)
mocha (0.9.9)
rake
+ moneta (0.6.0)
mongo (1.1)
bson (>= 1.0.5)
mongrel (1.1.5)
@@ -241,10 +263,17 @@ GEM
oa-core (= 0.1.6)
rack-openid (~> 1.2.0)
ruby-openid-apps-discovery
- oauth (0.4.3)
+ oauth (0.4.4)
oauth2 (0.1.0)
faraday (~> 0.5.0)
multi_json (~> 0.0.4)
+ ohai (0.5.8)
+ extlib
+ json (>= 1.4.4, <= 1.4.6)
+ mixlib-cli
+ mixlib-config
+ mixlib-log
+ systemu
omniauth (0.1.6)
oa-basic (= 0.1.6)
oa-core (= 0.1.6)
@@ -313,6 +342,7 @@ GEM
json_pure
rubyzip
subexec (0.0.4)
+ systemu (1.2.0)
term-ansicolor (1.0.5)
thin (1.2.7)
daemons (>= 1.0.9)
@@ -330,7 +360,7 @@ GEM
uuidtools (2.1.1)
warden (0.10.7)
rack (>= 1.0.0)
- webmock (1.4.0)
+ webmock (1.5.0)
addressable (>= 2.2.2)
crack (>= 0.1.7)
will_paginate (3.0.pre2)
@@ -347,6 +377,7 @@ DEPENDENCIES
bundler (>= 1.0.0)
capybara (~> 0.3.9)
carrierwave!
+ chef
cucumber-rails (= 0.3.2)
database_cleaner (= 0.5.2)
devise (= 1.1.3)
diff --git a/public/javascripts/aspect-edit.js b/public/javascripts/aspect-edit.js
index 8346bb7dd..17c0c673d 100644
--- a/public/javascripts/aspect-edit.js
+++ b/public/javascripts/aspect-edit.js
@@ -27,11 +27,15 @@ var AspectEdit = {
$(".aspect h3").live('focus', AspectEdit.changeName);
},
- startDrag: function(event, ui) {
- $(this).children("img").animate({'height':80, 'width':80, 'opacity':0.8}, 200)
- .tipsy("hide");
+ startDrag: function() {
+ AspectEdit.animateImage($(this).children("img").first());
$(".draggable_info").fadeIn(100);
},
+
+ animateImage: function(image) {
+ image.animate({'height':80, 'width':80, 'opacity':0.8}, 200);
+ image.tipsy("hide");
+ },
duringDrag: function(event, ui) {
$(this).children("img").tipsy("hide"); //ensure this is hidden
diff --git a/spec/javascripts/aspect-edit-spec.js b/spec/javascripts/aspect-edit-spec.js
index 9c2da4621..e71f2dbf2 100644
--- a/spec/javascripts/aspect-edit-spec.js
+++ b/spec/javascripts/aspect-edit-spec.js
@@ -1,8 +1,38 @@
describe("AspectEdit", function() {
-// describe("initialize", function() {
-//
-// });
+ describe("initialize", function() {
+ it("calls draggable on ul .person", function() {
+ spyOn($.fn, "draggable");
+ AspectEdit.initialize();
+ expect($.fn.draggable).toHaveBeenCalledWith(
+ {revert: true, start: AspectEdit.startDrag,
+ drag: AspectEdit.duringDrag, stop: AspectEdit.stopDrag});
+ expect($.fn.draggable.mostRecentCall.object.selector).toEqual("ul .person");
+ });
+ it("calls droppable on .aspect ul.dropzone", function() {
+ spyOn($.fn, "droppable");
+ AspectEdit.initialize();
+ expect($.fn.droppable).toHaveBeenCalledWith({hoverClass: 'active', drop: AspectEdit.onDropMove});
+ expect($.fn.droppable.calls[0].object.selector).toEqual(".aspect ul.dropzone");
+// This would be AWESOME:
+// expect($.fn.droppable)
+// .toHaveBeenCalled()
+// .on(".aspect ul.dropzone")
+// .with({});
+ });
+ });
+
+ describe("startDrag", function() {
+ it("animates the image", function() {
+ $('#jasmine_content').html('
- ' +
+ '
' +
+ '
');
+ spyOn(AspectEdit, "animateImage");
+ $.proxy(AspectEdit.startDrag, $('.person.ui-draggable'))();
+ expect(AspectEdit.animateImage).toHaveBeenCalled();
+ expect(AspectEdit.animateImage.mostRecentCall.args[0]).toHaveClass("avatar");
+ });
+ });
describe("decrementRequestsCounter", function() {
describe("when there is one request", function() {
diff --git a/spec/javascripts/helpers/jasmine-jquery.js b/spec/javascripts/helpers/jasmine-jquery.js
new file mode 100644
index 000000000..0096c4fc5
--- /dev/null
+++ b/spec/javascripts/helpers/jasmine-jquery.js
@@ -0,0 +1,203 @@
+var readFixtures = function() {
+ return jasmine.getFixtures().proxyCallTo_('read', arguments);
+};
+
+var loadFixtures = function() {
+ jasmine.getFixtures().proxyCallTo_('load', arguments);
+};
+
+var setFixtures = function(html) {
+ jasmine.getFixtures().set(html);
+}
+
+var sandbox = function(attributes) {
+ return jasmine.getFixtures().sandbox(attributes);
+};
+
+jasmine.getFixtures = function() {
+ return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures();
+};
+
+jasmine.Fixtures = function() {
+ this.containerId = 'jasmine-fixtures';
+ this.fixturesCache_ = {};
+};
+
+jasmine.Fixtures.prototype.set = function(html) {
+ this.cleanUp();
+ this.createContainer_(html);
+};
+
+jasmine.Fixtures.prototype.load = function() {
+ this.cleanUp();
+ this.createContainer_(this.read.apply(this, arguments));
+};
+
+jasmine.Fixtures.prototype.read = function() {
+ var htmlChunks = [];
+
+ var fixtureUrls = arguments;
+ for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
+ htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex]));
+ }
+
+ return htmlChunks.join('');
+};
+
+jasmine.Fixtures.prototype.clearCache = function() {
+ this.fixturesCache_ = {};
+};
+
+jasmine.Fixtures.prototype.cleanUp = function() {
+ $('#' + this.containerId).remove();
+};
+
+jasmine.Fixtures.prototype.sandbox = function(attributes) {
+ var attributesToSet = attributes || {};
+ return $('').attr(attributesToSet);
+};
+
+jasmine.Fixtures.prototype.createContainer_ = function(html) {
+ var container = $('');
+ container.html(html);
+ $('body').append(container);
+};
+
+jasmine.Fixtures.prototype.getFixtureHtml_ = function(url) {
+ if (typeof this.fixturesCache_[url] == 'undefined') {
+ this.loadFixtureIntoCache_(url);
+ }
+ return this.fixturesCache_[url];
+};
+
+jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function(url) {
+ var self = this;
+ $.ajax({
+ async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
+ cache: false,
+ dataType: 'html',
+ url: url,
+ success: function(data) {
+ self.fixturesCache_[url] = data;
+ }
+ });
+};
+
+jasmine.Fixtures.prototype.proxyCallTo_ = function(methodName, passedArguments) {
+ return this[methodName].apply(this, passedArguments);
+};
+
+
+jasmine.JQuery = function() {};
+
+jasmine.JQuery.browserTagCaseIndependentHtml = function(html) {
+ return $('').append(html).html();
+};
+
+jasmine.JQuery.elementToString = function(element) {
+ return $('').append(element.clone()).html();
+};
+
+jasmine.JQuery.matchersClass = {};
+
+
+(function(){
+ var jQueryMatchers = {
+ toHaveClass: function(className) {
+ return this.actual.hasClass(className);
+ },
+
+ toBeVisible: function() {
+ return this.actual.is(':visible');
+ },
+
+ toBeHidden: function() {
+ return this.actual.is(':hidden');
+ },
+
+ toBeSelected: function() {
+ return this.actual.is(':selected');
+ },
+
+ toBeChecked: function() {
+ return this.actual.is(':checked');
+ },
+
+ toBeEmpty: function() {
+ return this.actual.is(':empty');
+ },
+
+ toExist: function() {
+ return this.actual.size() > 0;
+ },
+
+ toHaveAttr: function(attributeName, expectedAttributeValue) {
+ return hasProperty(this.actual.attr(attributeName), expectedAttributeValue);
+ },
+
+ toHaveId: function(id) {
+ return this.actual.attr('id') == id;
+ },
+
+ toHaveHtml: function(html) {
+ return this.actual.html() == jasmine.JQuery.browserTagCaseIndependentHtml(html);
+ },
+
+ toHaveText: function(text) {
+ return this.actual.text() == text;
+ },
+
+ toHaveValue: function(value) {
+ return this.actual.val() == value;
+ },
+
+ toHaveData: function(key, expectedValue) {
+ return hasProperty(this.actual.data(key), expectedValue);
+ },
+
+ toBe: function(selector) {
+ return this.actual.is(selector);
+ },
+
+ toContain: function(selector) {
+ return this.actual.find(selector).size() > 0;
+ }
+ };
+
+ var hasProperty = function(actualValue, expectedValue) {
+ if (expectedValue === undefined) {
+ return actualValue !== undefined;
+ }
+ return actualValue == expectedValue;
+ };
+
+ var bindMatcher = function(methodName) {
+ var builtInMatcher = jasmine.Matchers.prototype[methodName];
+
+ jasmine.JQuery.matchersClass[methodName] = function() {
+ if (this.actual instanceof jQuery) {
+ var result = jQueryMatchers[methodName].apply(this, arguments);
+ this.actual = jasmine.JQuery.elementToString(this.actual);
+ return result;
+ }
+
+ if (builtInMatcher) {
+ return builtInMatcher.apply(this, arguments);
+ }
+
+ return false;
+ };
+ };
+
+ for(var methodName in jQueryMatchers) {
+ bindMatcher(methodName);
+ }
+})();
+
+beforeEach(function() {
+ this.addMatchers(jasmine.JQuery.matchersClass);
+});
+
+afterEach(function() {
+ jasmine.getFixtures().cleanUp();
+});
\ No newline at end of file