fraternity 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[ ![Codeship Status for brilliantfantastic/fraternity](https://codeship.com/projects/3fe0d950-80a4-0132-9038-321707412590/status?branch=master)](https://codeship.com/projects/57522)
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/brilliantfantastic/fraternity/badge.svg)](https://coveralls.io/r/brilliantfantastic/fraternity)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/brilliantfantastic/fraternity/badges/gpa.svg)](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
|