corkboard 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.env.template +1 -0
- data/.gitignore +15 -0
- data/.rspec.template +2 -0
- data/.rvmrc.template +4 -0
- data/.wiprc +0 -0
- data/.yardopts +1 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +223 -0
- data/app/assets/images/corkboard/.gitkeep +0 -0
- data/corkboard.gemspec +41 -0
- data/lib/corkboard/version.rb +1 -1
- data/script/rails +8 -0
- data/spec/controllers/corkboard/application_controller_spec.rb +7 -0
- data/spec/controllers/corkboard/authorizations_controller_spec.rb +26 -0
- data/spec/controllers/corkboard/board_controller_spec.rb +29 -0
- data/spec/controllers/corkboard/posts_controller_spec.rb +7 -0
- data/spec/corkboard/client_spec.rb +52 -0
- data/spec/corkboard/clients/instagram_spec.rb +30 -0
- data/spec/corkboard/engine_spec.rb +11 -0
- data/spec/corkboard/provider_spec.rb +28 -0
- data/spec/corkboard/providers/instagram_spec.rb +44 -0
- data/spec/corkboard/publishers/mock_spec.rb +12 -0
- data/spec/corkboard/publishers/pusher_spec.rb +12 -0
- data/spec/corkboard/service/config_spec.rb +12 -0
- data/spec/corkboard_spec.rb +136 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +65 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/corkboard.rb +45 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/jasmine.rb +5 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/db/.gitkeep +0 -0
- data/spec/dummy/db/migrate/20121212222912_create_corkboard_authorizations.corkboard.rb +18 -0
- data/spec/dummy/db/schema.rb +31 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/helpers/corkboard/application_helper_spec.rb +7 -0
- data/spec/javascripts/fixtures/board.html +3 -0
- data/spec/javascripts/helpers/jasmine-jquery.js +340 -0
- data/spec/javascripts/spec.css +3 -0
- data/spec/javascripts/spec.js +5 -0
- data/spec/javascripts/spec_helper.js +41 -0
- data/spec/javascripts/specs/corkboard/app/board_spec.js +68 -0
- data/spec/javascripts/specs/corkboard/base_spec.js +17 -0
- data/spec/javascripts/specs/corkboard/lib/publisher_spec.js +101 -0
- data/spec/javascripts/specs/corkboard/lib/weighted_randomizer_spec.js +23 -0
- data/spec/javascripts/specs/corkboard_spec.js +45 -0
- data/spec/javascripts/support/jasmine.yml +75 -0
- data/spec/javascripts/support/jasmine_config.rb +1 -0
- data/spec/models/corkboard/authorization_spec.rb +7 -0
- data/spec/models/corkboard/post_spec.rb +7 -0
- data/spec/models/corkboard/subscription_spec.rb +7 -0
- data/spec/requests/authorizations_spec.rb +39 -0
- data/spec/requests/board_spec.rb +70 -0
- data/spec/routing/authorizations_routing_spec.rb +25 -0
- data/spec/routing/board_routing_spec.rb +7 -0
- data/spec/routing/posts_routing_spec.rb +15 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/support/helpers/config_helpers.rb +26 -0
- data/spec/support/helpers/controller_helpers.rb +12 -0
- data/spec/support/helpers/post_helpers.rb +119 -0
- data/vendor/assets/javascripts/jquery.masonry-extensions.js +203 -0
- data/vendor/assets/javascripts/jquery.masonry.js +499 -0
- data/vendor/assets/javascripts/modernizr.js +821 -0
- data/vendor/assets/javascripts/pusher.js +48 -0
- metadata +176 -11
@@ -0,0 +1,41 @@
|
|
1
|
+
(function($, g) {
|
2
|
+
$.extend(g, {
|
3
|
+
context : function(description, definitions) {
|
4
|
+
return jasmine.getEnv().describe(description, definitions);
|
5
|
+
},
|
6
|
+
|
7
|
+
fixture : function(path, load) {
|
8
|
+
function readonly() {
|
9
|
+
return readFixtures(path);
|
10
|
+
}
|
11
|
+
|
12
|
+
function rendered() {
|
13
|
+
loadFixtures(path);
|
14
|
+
return $('#jasmine-fixtures').children();
|
15
|
+
}
|
16
|
+
|
17
|
+
return (load ? rendered() : readonly());
|
18
|
+
},
|
19
|
+
|
20
|
+
before : function(callback) {
|
21
|
+
return jasmine.getEnv().beforeEach(callback);
|
22
|
+
},
|
23
|
+
|
24
|
+
after : function(callback) {
|
25
|
+
return jasmine.getEnv().afterEach(callback);
|
26
|
+
},
|
27
|
+
|
28
|
+
undefine : function(object, property) {
|
29
|
+
var original = object[property];
|
30
|
+
object[property] = undefined;
|
31
|
+
|
32
|
+
jasmine.getEnv().currentSpec.after(function() {
|
33
|
+
object[property] = original;
|
34
|
+
});
|
35
|
+
}
|
36
|
+
});
|
37
|
+
|
38
|
+
function parseKey(content) {
|
39
|
+
return /define\(["']([a-z:_-]+)["']/.exec(content)[1];
|
40
|
+
}
|
41
|
+
})(jQuery, this);
|
@@ -0,0 +1,68 @@
|
|
1
|
+
describe("corkboard/app/corkboard.js", function() {
|
2
|
+
it("defines $.corkboard.Board", function() {
|
3
|
+
expect($.corkboard.Board).toBeDefined();
|
4
|
+
});
|
5
|
+
|
6
|
+
describe("Board", function() {
|
7
|
+
describe("constructor", function() {
|
8
|
+
var constructor = $.corkboard.Board;
|
9
|
+
|
10
|
+
context("given a valid jQuery object for the 'board' content", function() {
|
11
|
+
before(function() {
|
12
|
+
fixture('board.html', true);
|
13
|
+
spyOn($.corkboard, 'Publisher');
|
14
|
+
});
|
15
|
+
|
16
|
+
it("creates a Publisher instance for the board", function() {
|
17
|
+
var publisher = $.corkboard.Publisher;
|
18
|
+
var instance = new constructor($('#corkboard'));
|
19
|
+
|
20
|
+
expect(publisher).toHaveBeenCalled();
|
21
|
+
expect(publisher.mostRecentCall.args[0]).toBe('article#corkboard');
|
22
|
+
expect(publisher.mostRecentCall.args[1]).toEqual(instance.updated);
|
23
|
+
});
|
24
|
+
});
|
25
|
+
|
26
|
+
context("given an invalid (zero-length) jQuery object for the 'board' content", function() {
|
27
|
+
before(function() {
|
28
|
+
spyOn($.corkboard, 'Publisher');
|
29
|
+
});
|
30
|
+
|
31
|
+
it("does nothing", function() {
|
32
|
+
var instance = new constructor($('#corkboard'));
|
33
|
+
expect($.corkboard.Publisher).not.toHaveBeenCalled();
|
34
|
+
});
|
35
|
+
});
|
36
|
+
});
|
37
|
+
|
38
|
+
describe("#updated", function() {
|
39
|
+
context("called with the updated posts container and a list of new entries", function() {
|
40
|
+
var instance, posts, entry;
|
41
|
+
var constructor = $.corkboard.Board;
|
42
|
+
|
43
|
+
before(function() {
|
44
|
+
fixture('board.html', true);
|
45
|
+
spyOn($.corkboard, 'Publisher');
|
46
|
+
|
47
|
+
instance = new constructor($('#corkboard'));
|
48
|
+
posts = $('ul.corkboard.posts');
|
49
|
+
entry = $('<li class="entry">').appendTo(posts);
|
50
|
+
});
|
51
|
+
|
52
|
+
it("updates the layout", function() {
|
53
|
+
spyOn(posts, 'masonry');
|
54
|
+
|
55
|
+
instance.updated(posts, entry);
|
56
|
+
expect(posts.masonry).toHaveBeenCalled();
|
57
|
+
});
|
58
|
+
|
59
|
+
it("reveals the entries", function() {
|
60
|
+
spyOn(entry, 'fadeIn');
|
61
|
+
|
62
|
+
instance.updated(posts, entry);
|
63
|
+
expect(entry.fadeIn).toHaveBeenCalledWith('slow');
|
64
|
+
});
|
65
|
+
});
|
66
|
+
});
|
67
|
+
});
|
68
|
+
});
|
@@ -0,0 +1,17 @@
|
|
1
|
+
describe("corkboard/base.js", function() {
|
2
|
+
it("defines $.corkboard", function() {
|
3
|
+
expect($.corkboard).toBeDefined();
|
4
|
+
});
|
5
|
+
|
6
|
+
describe("$.corkboard.defaults", function() {
|
7
|
+
var defaults = $.corkboard.defaults;
|
8
|
+
|
9
|
+
it("is defined", function() {
|
10
|
+
expect(defaults).toBeDefined();
|
11
|
+
});
|
12
|
+
|
13
|
+
it("specifies a value for 'fade', used by visibility transitions", function() {
|
14
|
+
expect(defaults.fade).toEqual('slow');
|
15
|
+
});
|
16
|
+
});
|
17
|
+
});
|
@@ -0,0 +1,101 @@
|
|
1
|
+
describe("corkboard/lib/publisher.js", function() {
|
2
|
+
it("defines $.corkboard.Publisher", function() {
|
3
|
+
expect($.corkboard.Publisher).toBeDefined();
|
4
|
+
});
|
5
|
+
|
6
|
+
describe("Publisher", function() {
|
7
|
+
var mocks;
|
8
|
+
var constructor = $.corkboard.Publisher;
|
9
|
+
|
10
|
+
before(function() {
|
11
|
+
mocks = {
|
12
|
+
channel : {
|
13
|
+
bind : function() {}
|
14
|
+
},
|
15
|
+
pusher : {
|
16
|
+
bind : function() {},
|
17
|
+
subscribe : function() { return mocks.channel }
|
18
|
+
}
|
19
|
+
};
|
20
|
+
});
|
21
|
+
|
22
|
+
describe("constructor", function() {
|
23
|
+
context("given a valid container for the 'board' content", function() {
|
24
|
+
before(function() {
|
25
|
+
fixture('board.html', true);
|
26
|
+
spyOn(window, 'Pusher').andReturn(mocks.pusher);
|
27
|
+
});
|
28
|
+
|
29
|
+
it("opens a Pusher channel for the content updates", function() {
|
30
|
+
var instance = new constructor($('#corkboard'));
|
31
|
+
expect(window.Pusher).toHaveBeenCalledWith($.corkboard.config.pusher);
|
32
|
+
});
|
33
|
+
|
34
|
+
it("retains a reference to the 'board'", function() {
|
35
|
+
var instance = new constructor($('#corkboard'));
|
36
|
+
expect(instance.board).toBe('#corkboard');
|
37
|
+
});
|
38
|
+
|
39
|
+
context("and given a callback", function() {
|
40
|
+
it("retains a reference to the callback", function() {
|
41
|
+
var callback = function callback() {};
|
42
|
+
var instance = new constructor($('#corkboard'), callback);
|
43
|
+
expect(instance.callback).toEqual(callback);
|
44
|
+
});
|
45
|
+
});
|
46
|
+
});
|
47
|
+
|
48
|
+
context("given an invalid selector for the 'board' content", function() {
|
49
|
+
before(function() {
|
50
|
+
spyOn(window, 'Pusher');
|
51
|
+
});
|
52
|
+
|
53
|
+
it("does nothing", function() {
|
54
|
+
var instance = new constructor($('#corkboard'));
|
55
|
+
expect(window.Pusher).not.toHaveBeenCalled();
|
56
|
+
expect(instance.board).not.toBeDefined();
|
57
|
+
});
|
58
|
+
});
|
59
|
+
});
|
60
|
+
|
61
|
+
describe("#publish", function() {
|
62
|
+
before(function() {
|
63
|
+
fixture('board.html', true);
|
64
|
+
spyOn(window, 'Pusher').andReturn(mocks.pusher);
|
65
|
+
});
|
66
|
+
|
67
|
+
context("given JSON for a new post", function() {
|
68
|
+
var json;
|
69
|
+
|
70
|
+
before(function() {
|
71
|
+
json = {
|
72
|
+
eid : 'EXAMPLE',
|
73
|
+
tags : 'EXAMPLE',
|
74
|
+
caption : 'EXAMPLE',
|
75
|
+
image : '/assets/corkboard/image.png'
|
76
|
+
};
|
77
|
+
});
|
78
|
+
|
79
|
+
it("renders a tile for the post", function() {
|
80
|
+
var instance = new constructor($('#corkboard'));
|
81
|
+
expect($('#corkboard li')).not.toExist();
|
82
|
+
|
83
|
+
instance.publish(json);
|
84
|
+
expect($('#corkboard li')).toExist();
|
85
|
+
});
|
86
|
+
|
87
|
+
context("and given a registered callback", function() {
|
88
|
+
it("executes the callback, passing the list of posts as an argument", function() {
|
89
|
+
var callback = jasmine.createSpy('callback');
|
90
|
+
var instance = new constructor($('#corkboard'), callback);
|
91
|
+
|
92
|
+
instance.publish(json);
|
93
|
+
expect(callback).toHaveBeenCalled();
|
94
|
+
expect(callback.mostRecentCall.args[0]).toBe('ul.corkboard.posts');
|
95
|
+
expect(callback.mostRecentCall.args[1]).toBe('li.entry');
|
96
|
+
});
|
97
|
+
});
|
98
|
+
});
|
99
|
+
});
|
100
|
+
});
|
101
|
+
});
|
@@ -0,0 +1,23 @@
|
|
1
|
+
describe("corkboard/lib/weighted_randomizer.js", function() {
|
2
|
+
it("defines $.corkboard.WeightedRandomizer", function() {
|
3
|
+
expect($.corkboard.WeightedRandomizer).toBeDefined();
|
4
|
+
});
|
5
|
+
|
6
|
+
describe("WeightedRandomizer", function() {
|
7
|
+
var constructor = $.corkboard.WeightedRandomizer;
|
8
|
+
|
9
|
+
describe("constructor", function() {
|
10
|
+
it("normalizes the setup data", function() {
|
11
|
+
var instance = new constructor({ one : 2, two : 8 });
|
12
|
+
expect(instance.normalized).toEqual({ one : 0.2, two : 0.8 });
|
13
|
+
});
|
14
|
+
});
|
15
|
+
|
16
|
+
describe("#sample", function() {
|
17
|
+
it("returns a selection from the setup, weighted by value", function() {
|
18
|
+
var instance = new constructor({ one : 0, two : 1000000 });
|
19
|
+
expect(instance.sample()).toEqual('two');
|
20
|
+
});
|
21
|
+
});
|
22
|
+
});
|
23
|
+
});
|
@@ -0,0 +1,45 @@
|
|
1
|
+
describe("corkboard.js", function() {
|
2
|
+
describe("$.corkboard.version", function() {
|
3
|
+
it("is defined", function() {
|
4
|
+
expect($.corkboard.version).toEqual('0.1.0');
|
5
|
+
});
|
6
|
+
});
|
7
|
+
|
8
|
+
describe("$.corkboard.config", function() {
|
9
|
+
var config = $.corkboard.config;
|
10
|
+
|
11
|
+
it("specifies a key for the Pusher service", function() {
|
12
|
+
expect(config.pusher).toBeDefined();
|
13
|
+
});
|
14
|
+
|
15
|
+
it("specifies the display 'weights' for tiles", function() {
|
16
|
+
expect(config.weights).toEqual({
|
17
|
+
s : 10,
|
18
|
+
m : 3,
|
19
|
+
l : 1
|
20
|
+
});
|
21
|
+
});
|
22
|
+
});
|
23
|
+
|
24
|
+
describe("$.fn.corkboard", function() {
|
25
|
+
before(function() {
|
26
|
+
spyOn($.corkboard, 'Board');
|
27
|
+
});
|
28
|
+
|
29
|
+
it("is defined", function() {
|
30
|
+
expect($.fn.corkboard).toBeDefined();
|
31
|
+
});
|
32
|
+
|
33
|
+
it("creates a new Board", function() {
|
34
|
+
var object = $('<div>');
|
35
|
+
var result = object.corkboard();
|
36
|
+
expect($.corkboard.Board).toHaveBeenCalled();
|
37
|
+
});
|
38
|
+
|
39
|
+
it("returns the given jQuery object", function() {
|
40
|
+
var object = $('<div>');
|
41
|
+
var result = object.corkboard();
|
42
|
+
expect(result).toEqual(object);
|
43
|
+
});
|
44
|
+
});
|
45
|
+
});
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# src_files
|
2
|
+
#
|
3
|
+
# Return an array of filepaths relative to src_dir to include before jasmine specs.
|
4
|
+
# Default: []
|
5
|
+
#
|
6
|
+
# EXAMPLE:
|
7
|
+
#
|
8
|
+
# src_files:
|
9
|
+
# - lib/source1.js
|
10
|
+
# - lib/source2.js
|
11
|
+
# - dist/**/*.js
|
12
|
+
#
|
13
|
+
src_files:
|
14
|
+
- vendor/**/*.js
|
15
|
+
|
16
|
+
# stylesheets
|
17
|
+
#
|
18
|
+
# Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs.
|
19
|
+
# Default: []
|
20
|
+
#
|
21
|
+
# EXAMPLE:
|
22
|
+
#
|
23
|
+
# stylesheets:
|
24
|
+
# - css/style.css
|
25
|
+
# - stylesheets/*.css
|
26
|
+
#
|
27
|
+
stylesheets:
|
28
|
+
- spec/helpers/**/*.css
|
29
|
+
|
30
|
+
# helpers
|
31
|
+
#
|
32
|
+
# Return an array of filepaths relative to spec_dir to include before jasmine specs.
|
33
|
+
# Default: ["helpers/**/*.js"]
|
34
|
+
#
|
35
|
+
# EXAMPLE:
|
36
|
+
#
|
37
|
+
# helpers:
|
38
|
+
# - helpers/**/*.js
|
39
|
+
#
|
40
|
+
helpers:
|
41
|
+
- helpers/**/*.js
|
42
|
+
|
43
|
+
# spec_files
|
44
|
+
#
|
45
|
+
# Return an array of filepaths relative to spec_dir to include.
|
46
|
+
# Default: ["**/*[sS]pec.js"]
|
47
|
+
#
|
48
|
+
# EXAMPLE:
|
49
|
+
#
|
50
|
+
# spec_files:
|
51
|
+
# - **/*[sS]pec.js
|
52
|
+
#
|
53
|
+
spec_files:
|
54
|
+
|
55
|
+
# src_dir
|
56
|
+
#
|
57
|
+
# Source directory path. Your src_files must be returned relative to this path. Will use root if left blank.
|
58
|
+
# Default: project root
|
59
|
+
#
|
60
|
+
# EXAMPLE:
|
61
|
+
#
|
62
|
+
# src_dir: public
|
63
|
+
#
|
64
|
+
src_dir:
|
65
|
+
|
66
|
+
# spec_dir
|
67
|
+
#
|
68
|
+
# Spec directory path. Your spec_files must be returned relative to this path.
|
69
|
+
# Default: spec/javascripts
|
70
|
+
#
|
71
|
+
# EXAMPLE:
|
72
|
+
#
|
73
|
+
# spec_dir: spec/javascripts
|
74
|
+
#
|
75
|
+
spec_dir: spec
|
@@ -0,0 +1 @@
|
|
1
|
+
#
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Board", :js => false do
|
4
|
+
describe "GET corkboard/authorizations#index" do
|
5
|
+
context "when the authentication requirement for 'admin' is :disallow!" do
|
6
|
+
it "raises an exception" do
|
7
|
+
with_config(:authentication, { :admin => :disallow! }) do
|
8
|
+
expect { visit corkboard.authorizations_path }
|
9
|
+
.to raise_error(Corkboard::ActionForbidden)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when the authentication requirement for 'admin' is nil" do
|
15
|
+
it "is successful" do
|
16
|
+
with_config(:authentication, { :admin => nil }) do
|
17
|
+
visit corkboard.authorizations_path
|
18
|
+
expect(page).to have_content('Activated Services')
|
19
|
+
expect(page).to have_content('Available Services')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "given an authenticated Admin" do
|
25
|
+
before do
|
26
|
+
Corkboard::ApplicationController.any_instance
|
27
|
+
.stub(:authenticate!).and_return(true)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "is successful" do
|
31
|
+
with_config(:authentication, { :admin => :authenticate! }) do
|
32
|
+
visit corkboard.authorizations_path
|
33
|
+
expect(page).to have_content('Activated Services')
|
34
|
+
expect(page).to have_content('Available Services')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|