fraternity 0.0.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.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +62 -0
- data/README.md +145 -0
- data/Rakefile +29 -0
- data/fraternity.gemspec +29 -0
- data/lib/fraternity/bidder.rb +14 -0
- data/lib/fraternity/configuration.rb +9 -0
- data/lib/fraternity/perp_error.rb +3 -0
- data/lib/fraternity/pledge.rb +45 -0
- data/lib/fraternity/repositories/pledge_repository.rb +28 -0
- data/lib/fraternity/repositories.rb +33 -0
- data/lib/fraternity/temporary_token.rb +9 -0
- data/lib/fraternity/token_mismatch_error.rb +7 -0
- data/lib/fraternity/version.rb +3 -0
- data/lib/fraternity.rb +42 -0
- data/lib/generators/fraternity/templates/migration/create_pledges.rb +14 -0
- data/spec/fraternity/configuration_spec.rb +6 -0
- data/spec/fraternity/pledge_spec.rb +105 -0
- data/spec/fraternity/repositories/pledge_repository_spec.rb +56 -0
- data/spec/fraternity/repositories_spec.rb +8 -0
- data/spec/fraternity/temporary_token_spec.rb +9 -0
- data/spec/fraternity/token_mismatch_error_spec.rb +8 -0
- data/spec/fraternity_spec.rb +99 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/repository_helper.rb +6 -0
- metadata +126 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 368f6c901620e8bfbcbc5629d415e279065d4256
|
4
|
+
data.tar.gz: 69c4ce243b0eced4e297b46209a9ae4928bfb555
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 369a256c3764c6f2b86730b79d06c913221cee6663ea948f537f17f889bc4babfde4a9f9ed28f1142935e9030e1c5d65a9fab55659e3e1a4884e612bf8aa0dd0
|
7
|
+
data.tar.gz: cf7db18d627e19eafe6c19b93d0025c6977605891ab975825adeab378277bc978ee4d9dac4bbe8e3a604b4a077f482ad9b83e951f076e09933e980706470504c
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
repo_token: 0434oPH5AmyPXuVPweKtCWtPXgI5ytvyN
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
/coverage
|
data/.rspec
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.2.0
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
fraternity (0.0.1)
|
5
|
+
lotus-model
|
6
|
+
lotus-validations
|
7
|
+
rake
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
coveralls (0.7.2)
|
13
|
+
multi_json (~> 1.3)
|
14
|
+
rest-client (= 1.6.7)
|
15
|
+
simplecov (>= 0.7)
|
16
|
+
term-ansicolor (= 1.2.2)
|
17
|
+
thor (= 0.18.1)
|
18
|
+
diff-lcs (1.2.5)
|
19
|
+
docile (1.1.5)
|
20
|
+
lotus-model (0.2.1)
|
21
|
+
lotus-utils (~> 0.3, >= 0.3.2)
|
22
|
+
sequel (~> 4.9)
|
23
|
+
lotus-utils (0.3.3)
|
24
|
+
lotus-validations (0.2.3)
|
25
|
+
lotus-utils (~> 0.3, >= 0.3.3)
|
26
|
+
mime-types (2.4.3)
|
27
|
+
multi_json (1.10.1)
|
28
|
+
rake (10.4.2)
|
29
|
+
rest-client (1.6.7)
|
30
|
+
mime-types (>= 1.16)
|
31
|
+
rspec (3.1.0)
|
32
|
+
rspec-core (~> 3.1.0)
|
33
|
+
rspec-expectations (~> 3.1.0)
|
34
|
+
rspec-mocks (~> 3.1.0)
|
35
|
+
rspec-core (3.1.7)
|
36
|
+
rspec-support (~> 3.1.0)
|
37
|
+
rspec-expectations (3.1.2)
|
38
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
39
|
+
rspec-support (~> 3.1.0)
|
40
|
+
rspec-mocks (3.1.3)
|
41
|
+
rspec-support (~> 3.1.0)
|
42
|
+
rspec-support (3.1.2)
|
43
|
+
sequel (4.18.0)
|
44
|
+
simplecov (0.9.1)
|
45
|
+
docile (~> 1.1.0)
|
46
|
+
multi_json (~> 1.0)
|
47
|
+
simplecov-html (~> 0.8.0)
|
48
|
+
simplecov-html (0.8.0)
|
49
|
+
sqlite3 (1.3.10)
|
50
|
+
term-ansicolor (1.2.2)
|
51
|
+
tins (~> 0.8)
|
52
|
+
thor (0.18.1)
|
53
|
+
tins (0.13.2)
|
54
|
+
|
55
|
+
PLATFORMS
|
56
|
+
ruby
|
57
|
+
|
58
|
+
DEPENDENCIES
|
59
|
+
coveralls
|
60
|
+
fraternity!
|
61
|
+
rspec
|
62
|
+
sqlite3
|
data/README.md
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
Fraternity
|
2
|
+
==========
|
3
|
+
|
4
|
+
[ ](https://codeship.com/projects/57522)
|
5
|
+
[](https://coveralls.io/r/brilliantfantastic/fraternity)
|
6
|
+
[](https://codeclimate.com/github/brilliantfantastic/fraternity)
|
7
|
+
|
8
|
+
## DESCRIPTION
|
9
|
+
|
10
|
+
An easier way to rush for a beta.
|
11
|
+
|
12
|
+
A gem allows you to collect and store (using only [the Lotus framework](http://lotusrb.com) as of now) a list of pledges who would like access to your beta. You can send out bids to those pledges and allow them to gain access to your beta.
|
13
|
+
|
14
|
+
## INSTALLATION
|
15
|
+
|
16
|
+
Add this line to your Gemfile:
|
17
|
+
|
18
|
+
```
|
19
|
+
gem 'fraternity'
|
20
|
+
```
|
21
|
+
|
22
|
+
And then execute:
|
23
|
+
|
24
|
+
```
|
25
|
+
bundle install
|
26
|
+
```
|
27
|
+
|
28
|
+
Or install it yourself:
|
29
|
+
|
30
|
+
```
|
31
|
+
gem install fraternity
|
32
|
+
```
|
33
|
+
|
34
|
+
Create the database table needed:
|
35
|
+
|
36
|
+
```
|
37
|
+
bundle exec rake fraternity:install DESTINATION="db/migrate"
|
38
|
+
```
|
39
|
+
|
40
|
+
The above will create the following table.
|
41
|
+
|
42
|
+
```
|
43
|
+
create_table :pledges do |t|
|
44
|
+
t.primary_key :id
|
45
|
+
String :token
|
46
|
+
String :email
|
47
|
+
String :first_name
|
48
|
+
String :last_name
|
49
|
+
Integer :initiation_number
|
50
|
+
DateTime :invited_at
|
51
|
+
DateTime :accepted_at
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
## USAGE
|
56
|
+
|
57
|
+
If you are unfamiliar with the terminology, you can read up at [http://www.unlv.edu/getinvolved/greek-definitions](http://www.unlv.edu/getinvolved/greek-definitions).
|
58
|
+
|
59
|
+
### Configuring
|
60
|
+
|
61
|
+
In order to use your Fraternity, you have to configure it before you use it.
|
62
|
+
|
63
|
+
```
|
64
|
+
Fraternity.configure do |config|
|
65
|
+
configure.database_url = ENV["DATABASE_URL"]
|
66
|
+
configure.send_invite = lambda do |pledge|
|
67
|
+
BetaMailer.invite_email(pledge).deliver
|
68
|
+
end
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
72
|
+
### Pledging
|
73
|
+
|
74
|
+
To sign up pledges, you first need to rush. Collect email addresses (and any additional information) to get in line for membership at the frat house.
|
75
|
+
|
76
|
+
```
|
77
|
+
params = { email: "jeremy.piven@example.com" } # Optional attributes you want to save such as first_name, last_name, etc.
|
78
|
+
pledge = Fraternity.rush! params
|
79
|
+
```
|
80
|
+
|
81
|
+
The above saves the information to the pledges database and creates a token for a `Pledge`
|
82
|
+
|
83
|
+
### Moving up the initiation line
|
84
|
+
|
85
|
+
**Coming soon**
|
86
|
+
|
87
|
+
### Inviting a new pledge
|
88
|
+
|
89
|
+
Send out email invitations to the next set of pledges based on their initiation number. A quota is specified for the number you want to invite.
|
90
|
+
|
91
|
+
```
|
92
|
+
invited = Fraternity.bid! quota
|
93
|
+
```
|
94
|
+
|
95
|
+
The above saves the date/time of the invite to all the invited pledges and returns an array of the invited.
|
96
|
+
|
97
|
+
The above will also call the `send_invite` proc that you have set up in the configuration. You are responsible for sending the invite to the pledge any way you like.
|
98
|
+
|
99
|
+
Find out if a pledge has been invited
|
100
|
+
|
101
|
+
```
|
102
|
+
Fraternity::Pledge.find(123).invited?
|
103
|
+
```
|
104
|
+
|
105
|
+
Resend an invite
|
106
|
+
|
107
|
+
```
|
108
|
+
Fraternity::Pledge.find(123).bid!
|
109
|
+
```
|
110
|
+
|
111
|
+
### Accepting a pledge
|
112
|
+
|
113
|
+
Check to see if a pledge is ready to be crossed into a full time member (invited and not crossed)
|
114
|
+
|
115
|
+
```
|
116
|
+
Fraternity::Pledge.find(token).ready?
|
117
|
+
```
|
118
|
+
|
119
|
+
Check to see if a pledge has been crossed into a full member
|
120
|
+
|
121
|
+
```
|
122
|
+
Fraternity::Pledge.find(token).crossed?
|
123
|
+
```
|
124
|
+
|
125
|
+
Convert the pledge into a full member (accept the invitation).
|
126
|
+
|
127
|
+
```
|
128
|
+
Fraternity::Pledge.cross! token
|
129
|
+
```
|
130
|
+
|
131
|
+
## CONTRIBUTING
|
132
|
+
|
133
|
+
1. Clone the repository `git clone https://github.com/brilliantfantastic/fraternity`
|
134
|
+
1. Create a feature branch `git checkout -b my-awesome-feature`
|
135
|
+
1. Codez!
|
136
|
+
1. Commit your changes (small commits please)
|
137
|
+
1. Push your new branch `git push origin my-awesome-feature`
|
138
|
+
1. Create a pull request `hub pull-request -b brilliantfantastic:master -h brilliantfantastic:my-awesome-feature`
|
139
|
+
|
140
|
+
## RELEASING A NEW GEM
|
141
|
+
|
142
|
+
1. Bump the VERSION in `lib/fraternity/version.rb`
|
143
|
+
1. Commit changes and push to GitHub
|
144
|
+
1. run `bundle exec rake build`
|
145
|
+
1. run `bundle exec rake release`
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "rspec/core/rake_task"
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
task default: :spec
|
7
|
+
rescue LoadError
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'coveralls/rake/task'
|
11
|
+
Coveralls::RakeTask.new
|
12
|
+
|
13
|
+
namespace :fraternity do
|
14
|
+
task :install do
|
15
|
+
# read the migration
|
16
|
+
base_file_name = "create_pledges.rb"
|
17
|
+
template = File.join File.dirname(__FILE__), "lib/generators/fraternity/templates/migration", base_file_name
|
18
|
+
contents = File.open(template) { |f| f.read }
|
19
|
+
|
20
|
+
# create the migration
|
21
|
+
destination = ENV["DESTINATION"] || "."
|
22
|
+
unless File.directory?(destination)
|
23
|
+
FileUtils.mkdir_p destination
|
24
|
+
end
|
25
|
+
timestamp = Time.now.to_i
|
26
|
+
destination_file = File.join destination, "#{timestamp}_#{base_file_name}"
|
27
|
+
File.open(destination_file, 'w') { |f| f.write(contents) }
|
28
|
+
end
|
29
|
+
end
|
data/fraternity.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fraternity/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "fraternity"
|
8
|
+
spec.version = Fraternity::VERSION
|
9
|
+
|
10
|
+
spec.authors = ["Jamie Wright"]
|
11
|
+
spec.email = ["jamie@brilliantfantastic.com"]
|
12
|
+
|
13
|
+
spec.summary = "An easier way to rush for a beta"
|
14
|
+
spec.description = %q{
|
15
|
+
Collect and store a list of pledges who would like access to your beta. You can send out bids to those
|
16
|
+
pledges and allow them to gain access to your beta.
|
17
|
+
}
|
18
|
+
|
19
|
+
spec.homepage = "http://github.com/brilliantfantastic/fraternity"
|
20
|
+
spec.license = "MIT"
|
21
|
+
|
22
|
+
spec.files = `git ls-files`.split($/)
|
23
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_dependency "rake"
|
27
|
+
spec.add_dependency "lotus-model"
|
28
|
+
spec.add_dependency "lotus-validations"
|
29
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "lotus/validations"
|
2
|
+
|
3
|
+
module Fraternity
|
4
|
+
class Pledge
|
5
|
+
include Lotus::Validations
|
6
|
+
|
7
|
+
attr_accessor :id, :email, :first_name, :last_name, :token, :initiation_number, :invited_at, :accepted_at
|
8
|
+
|
9
|
+
validates :email, presence: true, format: /[-0-9a-zA-Z.+_]+@[-0-9a-zA-Z.+_]+\.[a-zA-Z]{2,4}/
|
10
|
+
validates :token, presence: true
|
11
|
+
validates :initiation_number, presence: true
|
12
|
+
|
13
|
+
def initialize(attributes={})
|
14
|
+
|
15
|
+
@id, @email, @first_name, @last_name, @token, @initiation_number, @invited_at, @accepted_at =
|
16
|
+
attributes.values_at :id, :email, :first_name, :last_name, :token, :initiation_number, :invited_at, :accepted_at
|
17
|
+
end
|
18
|
+
|
19
|
+
def bid!
|
20
|
+
Bidder.new(self).bid!
|
21
|
+
end
|
22
|
+
|
23
|
+
def invite!
|
24
|
+
self.invited_at = DateTime.now
|
25
|
+
end
|
26
|
+
|
27
|
+
def invited?
|
28
|
+
!self.invited_at.nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
def cross!(token)
|
32
|
+
raise Fraternity::PerpError if !invited?
|
33
|
+
raise Fraternity::TokenMismatchError.new(self.token, token) if token != self.token
|
34
|
+
self.accepted_at = DateTime.now
|
35
|
+
end
|
36
|
+
|
37
|
+
def crossed?
|
38
|
+
!self.accepted_at.nil?
|
39
|
+
end
|
40
|
+
|
41
|
+
def ready?
|
42
|
+
self.invited? && !self.crossed?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'lotus/repository'
|
2
|
+
|
3
|
+
module Fraternity
|
4
|
+
module Repositories
|
5
|
+
class PledgeRepository
|
6
|
+
include Lotus::Repository
|
7
|
+
|
8
|
+
def self.find_by_id(id)
|
9
|
+
query do
|
10
|
+
where(id: id)
|
11
|
+
end.first
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.find_by_token(token)
|
15
|
+
query do
|
16
|
+
where(token: token)
|
17
|
+
end.first
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.oldest_uninvited_by_initiation_number(limit=8)
|
21
|
+
query do
|
22
|
+
where(invited_at: nil).
|
23
|
+
order(:initiation_number)
|
24
|
+
end.limit(limit)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "lotus/model/mapper"
|
2
|
+
require "lotus/model/adapters/sql_adapter"
|
3
|
+
require_relative "repositories/pledge_repository"
|
4
|
+
|
5
|
+
module Fraternity
|
6
|
+
module Repositories
|
7
|
+
@@mapping = Lotus::Model::Mapper.new do
|
8
|
+
collection :pledges do
|
9
|
+
entity Fraternity::Pledge
|
10
|
+
repository PledgeRepository
|
11
|
+
|
12
|
+
attribute :id, Integer
|
13
|
+
attribute :email, String
|
14
|
+
attribute :first_name, String
|
15
|
+
attribute :last_name, String
|
16
|
+
attribute :token, String
|
17
|
+
attribute :initiation_number, Integer
|
18
|
+
attribute :invited_at, DateTime
|
19
|
+
attribute :accepted_at, DateTime
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.mapping
|
24
|
+
@@mapping
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.initiation!(database_url)
|
28
|
+
adapter = Lotus::Model::Adapters::SqlAdapter.new(mapping, database_url)
|
29
|
+
PledgeRepository.adapter = adapter
|
30
|
+
mapping.load!
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/fraternity.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require "fraternity/version"
|
2
|
+
require "fraternity/bidder"
|
3
|
+
require "fraternity/configuration"
|
4
|
+
require "fraternity/perp_error"
|
5
|
+
require "fraternity/pledge"
|
6
|
+
require "fraternity/repositories"
|
7
|
+
require "fraternity/temporary_token"
|
8
|
+
require "fraternity/token_mismatch_error"
|
9
|
+
|
10
|
+
module Fraternity
|
11
|
+
def self.configuration
|
12
|
+
@configuration ||= Fraternity::Configuration.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.configure(initiate=true)
|
16
|
+
yield configuration if block_given?
|
17
|
+
Repositories.initiation! configuration.database_url if initiate
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.rush(params={})
|
21
|
+
params[:token] ||= TemporaryToken.generate_random_token
|
22
|
+
params[:initiation_number] ||= Time.now.to_i
|
23
|
+
Fraternity::Pledge.new params
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.rush!(params)
|
27
|
+
Repositories::PledgeRepository.create self.rush(params)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.bid!(quota)
|
31
|
+
Repositories::PledgeRepository.oldest_uninvited_by_initiation_number(quota).collect do |pledge|
|
32
|
+
pledge.bid!
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.find(identifier)
|
37
|
+
if identifier.is_a? Integer
|
38
|
+
return Repositories::PledgeRepository.find_by_id identifier
|
39
|
+
end
|
40
|
+
Repositories::PledgeRepository.find_by_token identifier
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
describe Fraternity::Pledge do
|
2
|
+
describe "validations" do
|
3
|
+
it "requires an email address" do
|
4
|
+
pledge = Fraternity::Pledge.new
|
5
|
+
expect(pledge).to_not be_valid
|
6
|
+
expect(pledge.errors.for(:email).first.validation).to eq :presence
|
7
|
+
end
|
8
|
+
|
9
|
+
it "requires a valid email address" do
|
10
|
+
pledge = Fraternity::Pledge.new email: "blah@test"
|
11
|
+
expect(pledge).to_not be_valid
|
12
|
+
expect(pledge.errors.for(:email).first.validation).to eq :format
|
13
|
+
end
|
14
|
+
|
15
|
+
it "requires a token" do
|
16
|
+
pledge = Fraternity::Pledge.new email: "jimmy@example.com", token: ""
|
17
|
+
expect(pledge).to_not be_valid
|
18
|
+
expect(pledge.errors.for(:token).first.validation).to eq :presence
|
19
|
+
end
|
20
|
+
|
21
|
+
it "requires an initiation number" do
|
22
|
+
pledge = Fraternity::Pledge.new email: "jimmy@example.com", token: "123456", initiation_number: ""
|
23
|
+
expect(pledge).to_not be_valid
|
24
|
+
expect(pledge.errors.for(:initiation_number).first.validation).to eq :presence
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#invited?" do
|
29
|
+
it "is not invited if the date and time when they were invited is not set" do
|
30
|
+
pledge = Fraternity::Pledge.new
|
31
|
+
expect(pledge).to_not be_invited
|
32
|
+
end
|
33
|
+
|
34
|
+
it "is invited if the date and time when they were invited is set" do
|
35
|
+
pledge = Fraternity::Pledge.new invited_at: DateTime.now
|
36
|
+
expect(pledge).to be_invited
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#invite!" do
|
41
|
+
it "sets the date and time of when the pledge was invited to the current date and time" do
|
42
|
+
pledge = Fraternity::Pledge.new
|
43
|
+
pledge.invite!
|
44
|
+
expect(pledge).to be_invited
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#crossed?" do
|
49
|
+
it "is not crossed if they have not accepted the invitation" do
|
50
|
+
pledge = Fraternity::Pledge.new
|
51
|
+
expect(pledge).to_not be_crossed
|
52
|
+
end
|
53
|
+
|
54
|
+
it "is crossed if they have accepted the invitation" do
|
55
|
+
pledge = Fraternity::Pledge.new accepted_at: DateTime.now
|
56
|
+
expect(pledge).to be_crossed
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#cross!" do
|
61
|
+
it "sets the date and time of when the pledge has accepted the invite to the current date and time" do
|
62
|
+
token = "12345"
|
63
|
+
pledge = Fraternity::Pledge.new token: token, invited_at: DateTime.now
|
64
|
+
pledge.cross! token
|
65
|
+
expect(pledge).to be_crossed
|
66
|
+
end
|
67
|
+
|
68
|
+
it "does not cross over if the token does not match" do
|
69
|
+
pledge = Fraternity::Pledge.new token: "12345", invited_at: DateTime.now
|
70
|
+
expect { pledge.cross! "blah" }.to raise_error Fraternity::TokenMismatchError
|
71
|
+
end
|
72
|
+
|
73
|
+
it "does not cross over if the pledge was not invited" do
|
74
|
+
token = "12345"
|
75
|
+
pledge = Fraternity::Pledge.new token: token
|
76
|
+
expect { pledge.cross! token }.to raise_error Fraternity::PerpError
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#bid!" do
|
81
|
+
it "updates the date and time they were invited" do
|
82
|
+
pledge = Fraternity::Pledge.new id: 123, token: "12345", email: "jimmy@example.com", invited_at: DateTime.new(2015, 1, 18)
|
83
|
+
allow(Fraternity::Repositories::PledgeRepository).to receive(:persist).and_return pledge
|
84
|
+
pledge.bid!
|
85
|
+
expect(((DateTime.now - pledge.invited_at) * 24 * 60 * 60).to_i).to be < 1
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#ready?" do
|
90
|
+
it "returns true if the pledge is invited but not yet crossed" do
|
91
|
+
pledge = Fraternity::Pledge.new token: "1234", invited_at: DateTime.now
|
92
|
+
expect(pledge).to be_ready
|
93
|
+
end
|
94
|
+
|
95
|
+
it "is not ready if they have not been invited" do
|
96
|
+
pledge = Fraternity::Pledge.new token: "1234"
|
97
|
+
expect(pledge).to_not be_ready
|
98
|
+
end
|
99
|
+
|
100
|
+
it "is not ready if they have crossed" do
|
101
|
+
pledge = Fraternity::Pledge.new token: "1234", invited_at: DateTime.now, accepted_at: DateTime.now
|
102
|
+
expect(pledge).to_not be_ready
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
describe Fraternity::Repositories::PledgeRepository do
|
2
|
+
before { load_repositories! }
|
3
|
+
|
4
|
+
describe ".find_by_token" do
|
5
|
+
let(:token) { "YUSGH764" }
|
6
|
+
let(:pledge) { Fraternity::Repositories::PledgeRepository.create(Fraternity::Pledge.new(email: "jimmy@example.com", token: token, initiation_number: Time.now.to_i)) }
|
7
|
+
|
8
|
+
it "returns the first pledge with the token" do
|
9
|
+
pledge
|
10
|
+
actual = Fraternity::Repositories::PledgeRepository.find_by_token token
|
11
|
+
expect(actual.id).to eq pledge.id
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns nil if the pledge does not exist" do
|
15
|
+
actual = Fraternity::Repositories::PledgeRepository.find_by_token "blah"
|
16
|
+
expect(actual).to be_nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe ".find_by_id" do
|
21
|
+
let(:pledge) { Fraternity::Repositories::PledgeRepository.create(Fraternity::Pledge.new(email: "jimmy@example.com", token: "12345", initiation_number: Time.now.to_i)) }
|
22
|
+
|
23
|
+
it "returns the first pledge with the id" do
|
24
|
+
pledge
|
25
|
+
actual = Fraternity::Repositories::PledgeRepository.find_by_id pledge.id
|
26
|
+
expect(actual.id).to eq pledge.id
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns nil if the pledge does not exist" do
|
30
|
+
actual = Fraternity::Repositories::PledgeRepository.find_by_id 123
|
31
|
+
expect(actual).to be_nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe ".oldest_univited_by_initiation_number" do
|
36
|
+
let(:four_days_ago) { Time.now.to_i - 24 * 60 * 60 * 4 }
|
37
|
+
let(:six_days_ago) { Time.now.to_i - 24 * 60 * 60 * 6 }
|
38
|
+
let(:ten_days_ago) { Time.now.to_i - 24 * 60 * 60 * 10 }
|
39
|
+
|
40
|
+
let(:oldest_pledge) { Fraternity::Repositories::PledgeRepository.create(Fraternity::Pledge.new(email: "jimmy@example.com", token: "1234", initiation_number: ten_days_ago)) }
|
41
|
+
let(:middle_pledge) { Fraternity::Repositories::PledgeRepository.create(Fraternity::Pledge.new(email: "robert@example.com", token: "5678", initiation_number: six_days_ago)) }
|
42
|
+
let(:newest_pledge) { Fraternity::Repositories::PledgeRepository.create(Fraternity::Pledge.new(email: "john@example.com", token: "9123", initiation_number: four_days_ago)) }
|
43
|
+
|
44
|
+
before { [middle_pledge, newest_pledge, oldest_pledge] } # place in database in this order
|
45
|
+
|
46
|
+
it "returns the oldest pledges based on their initiation number" do
|
47
|
+
pledges = Fraternity::Repositories::PledgeRepository.oldest_uninvited_by_initiation_number
|
48
|
+
expect(pledges.map(&:email)).to eq ["jimmy@example.com", "robert@example.com", "john@example.com"]
|
49
|
+
end
|
50
|
+
|
51
|
+
it "returns a limited number of pledges" do
|
52
|
+
pledges = Fraternity::Repositories::PledgeRepository.oldest_uninvited_by_initiation_number(2)
|
53
|
+
expect(pledges.map(&:email)).to eq ["jimmy@example.com", "robert@example.com"]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
describe Fraternity::Repositories do
|
2
|
+
describe ".initiation!" do
|
3
|
+
it "sets the adapters for the repositories to a SQL adapter" do
|
4
|
+
Fraternity::Repositories.initiation! "sqlite://blah.db"
|
5
|
+
expect(Fraternity::Repositories::PledgeRepository.instance_variable_get("@adapter")).to be_instance_of Lotus::Model::Adapters::SqlAdapter
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
describe Fraternity::TokenMismatchError do
|
2
|
+
it "describes the mismatched tokens" do
|
3
|
+
expected = "1234"
|
4
|
+
actual = "5678"
|
5
|
+
error = Fraternity::TokenMismatchError.new expected, actual
|
6
|
+
(expect(error.message)).to eq "Expected token #{expected}, but was #{actual}"
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
describe Fraternity do
|
2
|
+
describe ".bid!" do
|
3
|
+
let(:pledge) { Fraternity::Repositories::PledgeRepository.create(Fraternity::Pledge.new(email: "jimmy@example.com", token: "1234", initiation_number: Time.now.to_i)) }
|
4
|
+
|
5
|
+
before do
|
6
|
+
load_repositories!
|
7
|
+
pledge
|
8
|
+
end
|
9
|
+
|
10
|
+
it "invites the uninvited" do
|
11
|
+
pledges = Fraternity.bid! 5
|
12
|
+
expect(pledges.to_a[0].id).to eq pledge.id
|
13
|
+
expect(pledges.to_a[0]).to be_invited
|
14
|
+
end
|
15
|
+
|
16
|
+
it "sends the invite" do
|
17
|
+
sent_invite = false
|
18
|
+
Fraternity.configure(false) do |c|
|
19
|
+
c.send_invite = lambda do |pledge|
|
20
|
+
sent_invite = true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
pledges = Fraternity.bid! 5
|
24
|
+
expect(sent_invite).to be true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe ".configure" do
|
29
|
+
it "yields an instance of configuration" do
|
30
|
+
Fraternity.configure(false) do |config|
|
31
|
+
expect(config).to eq Fraternity.configuration
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe ".find" do
|
37
|
+
let(:token) { "HJDKSYS6782W" }
|
38
|
+
let(:pledge) { Fraternity::Pledge.new id: 123, token: token, email: "jimmy@example.com" }
|
39
|
+
|
40
|
+
it "returns a pledge based on their token" do
|
41
|
+
allow(Fraternity::Repositories::PledgeRepository).to receive(:find_by_token).and_return pledge
|
42
|
+
actual = Fraternity.find token
|
43
|
+
expect(actual.id).to eq pledge.id
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns a pledge based on their id" do
|
47
|
+
allow(Fraternity::Repositories::PledgeRepository).to receive(:find_by_id).and_return pledge
|
48
|
+
actual = Fraternity.find pledge.id
|
49
|
+
expect(actual.id).to eq pledge.id
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe ".rush" do
|
54
|
+
it "rushes with parameters that describe the pledge" do
|
55
|
+
expect { Fraternity.rush email: "blah" }.to_not raise_error
|
56
|
+
end
|
57
|
+
|
58
|
+
it "creates a new pledge with the specified parameters" do
|
59
|
+
pledge = Fraternity.rush email: "jimmy@example.com"
|
60
|
+
expect(pledge.email).to eq "jimmy@example.com"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "populates a token for the pledge to use for joining" do
|
64
|
+
pledge = Fraternity.rush
|
65
|
+
expect(pledge.token).to_not be_empty
|
66
|
+
end
|
67
|
+
|
68
|
+
it "uses the provided token if there is one" do
|
69
|
+
pledge = Fraternity.rush token: "blah"
|
70
|
+
expect(pledge.token).to eq "blah"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "creates an initiation number" do
|
74
|
+
pledge = Fraternity.rush
|
75
|
+
expect(pledge.initiation_number).to_not be_nil
|
76
|
+
initiated_at = Time.at pledge.initiation_number
|
77
|
+
expect((Time.now - initiated_at).to_i).to be < 1
|
78
|
+
end
|
79
|
+
|
80
|
+
it "uses the provided initiation number if there is one" do
|
81
|
+
pledge = Fraternity.rush initiation_number: 12345
|
82
|
+
expect(pledge.initiation_number).to eq 12345
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe ".rush!" do
|
87
|
+
before { load_repositories! }
|
88
|
+
|
89
|
+
it "creates a new pledge with the specified parameters" do
|
90
|
+
pledge = Fraternity.rush! email: "jimmy@example.com"
|
91
|
+
expect(pledge.email).to eq "jimmy@example.com"
|
92
|
+
end
|
93
|
+
|
94
|
+
it "saves the new pledge to the database" do
|
95
|
+
pledge = Fraternity.rush! email: "jimmy@example.com"
|
96
|
+
expect(pledge.id).to_not be_nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'coveralls'
|
2
|
+
Coveralls.wear!
|
3
|
+
|
4
|
+
require "fraternity"
|
5
|
+
|
6
|
+
ROOT = File.expand_path('../../', __FILE__)
|
7
|
+
Dir[File.join(ROOT, 'spec', 'support', '**/*.rb')].each { |f| require f }
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.expect_with :rspec do |expectations|
|
11
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
12
|
+
end
|
13
|
+
|
14
|
+
config.mock_with :rspec do |mocks|
|
15
|
+
mocks.verify_partial_doubles = true
|
16
|
+
end
|
17
|
+
|
18
|
+
config.filter_run :focus
|
19
|
+
config.run_all_when_everything_filtered = true
|
20
|
+
|
21
|
+
if config.files_to_run.one?
|
22
|
+
config.default_formatter = 'doc'
|
23
|
+
end
|
24
|
+
|
25
|
+
config.profile_examples = 10
|
26
|
+
|
27
|
+
config.order = :random
|
28
|
+
Kernel.srand config.seed
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fraternity
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jamie Wright
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: lotus-model
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: lotus-validations
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: "\n Collect and store a list of pledges who would
|
56
|
+
like access to your beta. You can send out bids to those\n pledges
|
57
|
+
and allow them to gain access to your beta.\n "
|
58
|
+
email:
|
59
|
+
- jamie@brilliantfantastic.com
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- ".coveralls.yml"
|
65
|
+
- ".gitignore"
|
66
|
+
- ".rspec"
|
67
|
+
- ".ruby-version"
|
68
|
+
- Gemfile
|
69
|
+
- Gemfile.lock
|
70
|
+
- README.md
|
71
|
+
- Rakefile
|
72
|
+
- fraternity.gemspec
|
73
|
+
- lib/fraternity.rb
|
74
|
+
- lib/fraternity/bidder.rb
|
75
|
+
- lib/fraternity/configuration.rb
|
76
|
+
- lib/fraternity/perp_error.rb
|
77
|
+
- lib/fraternity/pledge.rb
|
78
|
+
- lib/fraternity/repositories.rb
|
79
|
+
- lib/fraternity/repositories/pledge_repository.rb
|
80
|
+
- lib/fraternity/temporary_token.rb
|
81
|
+
- lib/fraternity/token_mismatch_error.rb
|
82
|
+
- lib/fraternity/version.rb
|
83
|
+
- lib/generators/fraternity/templates/migration/create_pledges.rb
|
84
|
+
- spec/fraternity/configuration_spec.rb
|
85
|
+
- spec/fraternity/pledge_spec.rb
|
86
|
+
- spec/fraternity/repositories/pledge_repository_spec.rb
|
87
|
+
- spec/fraternity/repositories_spec.rb
|
88
|
+
- spec/fraternity/temporary_token_spec.rb
|
89
|
+
- spec/fraternity/token_mismatch_error_spec.rb
|
90
|
+
- spec/fraternity_spec.rb
|
91
|
+
- spec/spec_helper.rb
|
92
|
+
- spec/support/repository_helper.rb
|
93
|
+
homepage: http://github.com/brilliantfantastic/fraternity
|
94
|
+
licenses:
|
95
|
+
- MIT
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.4.5
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: An easier way to rush for a beta
|
117
|
+
test_files:
|
118
|
+
- spec/fraternity/configuration_spec.rb
|
119
|
+
- spec/fraternity/pledge_spec.rb
|
120
|
+
- spec/fraternity/repositories/pledge_repository_spec.rb
|
121
|
+
- spec/fraternity/repositories_spec.rb
|
122
|
+
- spec/fraternity/temporary_token_spec.rb
|
123
|
+
- spec/fraternity/token_mismatch_error_spec.rb
|
124
|
+
- spec/fraternity_spec.rb
|
125
|
+
- spec/spec_helper.rb
|
126
|
+
- spec/support/repository_helper.rb
|