master
1require "rails_helper"
2
3describe User do
4 describe "#create" do
5 it "saves a new user to the database" do
6 user = create(:user)
7
8 saved_user = User.find(user.id)
9 expect(saved_user.username).to eql(user.username)
10 expect(saved_user.email).to eql(user.email)
11 expect(saved_user.password).to be_nil
12 end
13
14 it "lowercases the username" do
15 user = create(:user, username: "UpCASE")
16 expect(user.reload.username).to eql("upcase")
17 end
18
19 it "lowercases the email" do
20 user = create(:user, email: FFaker::Internet.email.upcase)
21 expect(user.reload.email).to eql(user.email.downcase)
22 end
23 end
24
25 describe "validations" do
26 context "username" do
27 it "is invalid when the username is missing" do
28 user = User.new(username: nil)
29 expect(user).to_not be_valid
30 expect(user.errors[:username]).to_not be_empty
31 end
32
33 it "is invalid if invalid characters are in the username" do
34 user = User.new(username: "$()")
35 expect(user).to_not be_valid
36 expect(user.errors[:username]).to_not be_empty
37 end
38
39 it "is invalid if the username is already taken" do
40 create(:user, username: "blah", email: "blah@example.com")
41 user = build(:user, username: "blah", email: "blahblah@example.com")
42 expect(user).to_not be_valid
43 expect(user.errors[:username]).to_not be_empty
44 end
45 end
46
47 describe "#email" do
48 it "is invalid when the email is missing" do
49 user = User.new(email: nil)
50 expect(user).to_not be_valid
51 expect(user.errors[:email]).to_not be_empty
52 end
53
54 it "is invalid when the email is not in the correct format" do
55 user = User.new(email: "blah")
56 expect(user).to_not be_valid
57 expect(user.errors[:email]).to_not be_empty
58 end
59
60 it "is invalid if the email address is already registered" do
61 create(:user, username: "blahblah", email: "blah@example.com")
62 second_user = build(:user, username: "blah", email: "blah@example.com")
63 expect(second_user).to_not be_valid
64 expect(second_user.errors[:email]).to_not be_empty
65 end
66 end
67
68 describe "terms_and_conditions" do
69 it "is invalid if terms and conditions is unchecked" do
70 user = User.new(terms_and_conditions: false)
71 expect(user).to_not be_valid
72 expect(user.errors[:terms_and_conditions]).to_not be_empty
73 end
74 end
75
76 it "is valid when it is" do
77 user = User.new(
78 username: "coolio",
79 email: "notblank@example.com",
80 password: "legit",
81 terms_and_conditions: "1")
82 expect(user).to be_valid
83 end
84 end
85
86 describe "USERNAME_REGEX" do
87 it "does not match" do
88 expect(User::USERNAME_REGEX).to_not match("$username")
89 expect(User::USERNAME_REGEX).to_not match("!username")
90 expect(User::USERNAME_REGEX).to_not match("@username")
91 end
92
93 it "matches" do
94 expect(User::USERNAME_REGEX).to match("username")
95 expect(User::USERNAME_REGEX).to match("user.name")
96 expect(User::USERNAME_REGEX).to match("user_name")
97 expect(User::USERNAME_REGEX).to match("user-name")
98 expect(User::USERNAME_REGEX).to match("username1")
99 end
100 end
101
102
103 describe "#to_param" do
104 it "returns the username as the uniq identifier" do
105 user = build(:user)
106 expect(user.to_param).to eql(user.username)
107 end
108 end
109
110 describe "#personal_record_for" do
111 include_context "stronglifts_program"
112 let(:user) { create(:user) }
113 let(:recommendation) { routine_a.recommendations.find_by(exercise: squat) }
114
115 before :each do
116 workout = user.workouts.create!(
117 routine: routine_a,
118 occurred_at: DateTime.now.utc
119 )
120 workout.train(squat, 201, repetitions: recommendation.repetitions)
121 workout.train(squat, 202, repetitions: recommendation.repetitions)
122 workout.train(squat, 210, repetitions: recommendation.repetitions - 1)
123 workout.train(squat, 204, repetitions: recommendation.repetitions)
124 workout.train(squat, 205, repetitions: recommendation.repetitions)
125 end
126
127 it "returns the users maximum amount of weight lifted" do
128 expect(user.personal_record_for(squat)).to eql(205.0)
129 end
130 end
131
132 describe "#begin_workout" do
133 subject { create(:user) }
134 let(:routine) { create(:routine) }
135 let(:today) { DateTime.now }
136
137 it "creates a new training session" do
138 result = subject.begin_workout(routine, today, 200)
139 expect(result).to be_persisted
140 expect(subject.workouts.count).to eql(1)
141 expect(subject.workouts.first).to eql(result)
142 expect(result.routine).to eql(routine)
143 expect(result.occurred_at).to eql(today.utc)
144 expect(result.body_weight).to eql(200.lbs)
145 end
146
147 it "returns the existing workout for that day" do
148 result = subject.begin_workout(routine, today, 200)
149 expect(subject.begin_workout(routine, today, 200)).to eql(result)
150 end
151
152 it "returns different sessions for different days" do
153 todays_result = subject.begin_workout(routine, today, 200)
154 tomorrows_result = subject.begin_workout(routine, DateTime.tomorrow, 200)
155 expect(todays_result).to_not eql(tomorrows_result)
156 end
157 end
158
159 describe "when destroying a training session" do
160 include_context "stronglifts_program"
161 subject { create(:user) }
162
163 it "removes all the associations" do
164 workout = subject.begin_workout(routine_a, Date.today, 200)
165 workout.train(squat, 200, repetitions: 5)
166 workout.train(squat, 200, repetitions: 5)
167 workout.train(squat, 200, repetitions: 5)
168 workout.train(squat, 200, repetitions: 5)
169 workout.train(squat, 200, repetitions: 5)
170
171 subject.workouts.destroy_all
172
173 expect(Workout.all).to be_empty
174 expect(ExerciseSet.all).to be_empty
175 end
176 end
177
178 describe "#profile" do
179 let(:user) { create(:user) }
180
181 it "creates a new profile" do
182 expect(user.profile).to be_present
183 expect(user.profile.other?).to be_truthy
184 expect(user.profile.social_tolerance).to be_nil
185 end
186 end
187
188 describe "#login" do
189 context "when credentials are correct" do
190 it "returns true" do
191 user = create(:user, password: "password", password_confirmation: "password")
192 result = User.login(user.email.upcase, "password")
193 expect(result).to be_instance_of(UserSession)
194 expect(result.user).to eql(user)
195 end
196
197 it "is case in-sensitive for username" do
198 user = create(:user, username: "upcase", password: "password", password_confirmation: "password")
199 result = User.login("UPcase", "password")
200 expect(result).to be_instance_of(UserSession)
201 expect(result.user).to eql(user)
202 end
203 end
204
205 context "when the email is not registered" do
206 it { expect(User.login("sofake@noteven.com", "password")).to be_falsey }
207 end
208
209 context "when the username is not registered" do
210 it { expect(User.login("sofake", "password")).to be_falsey }
211 end
212 end
213
214 describe "#add_to_inbox" do
215 include_context "stronglifts_program"
216 subject { create(:user) }
217 let(:email) { build(:email, :with_attachment) }
218
219 it "records the email" do
220 subject.add_to_inbox(email)
221 expect(subject.received_emails.count).to eql(1)
222 received_email = subject.received_emails.first
223 expect(received_email.to.map(&:symbolize_keys)).to match_array(email.to)
224 expect(received_email.from.symbolize_keys).to eql(email.from)
225 expect(received_email.subject).to eql(email.subject)
226 expect(received_email.body).to eql(email.body)
227 end
228 end
229
230 describe "#next_workout_for" do
231 subject { create(:user) }
232 let(:routine) { create(:routine) }
233 let(:body_weight) { rand(300) }
234
235 it "includes the body weight from the previous workout" do
236 create(:workout, user: subject, body_weight: body_weight)
237
238 workout = subject.next_workout_for(routine)
239 expect(workout.body_weight).to eql(body_weight)
240 end
241
242 it "uses the correct routine" do
243 workout = subject.next_workout_for(routine)
244 expect(workout.routine).to eql(routine)
245 end
246
247 it "prepares the correct number of sets" do
248 squat = create(:squat)
249 routine.add_exercise(squat, sets: 3)
250 workout = subject.next_workout_for(routine)
251 expect(workout.exercise_sets.length).to eql(3)
252 end
253 end
254
255 describe "#next_routine" do
256 include_context "stronglifts_program"
257 subject { create(:user) }
258
259 it "routines the next workout" do
260 create(:workout, routine: routine_a, user: subject)
261 expect(subject.next_routine).to eql(routine_b)
262 end
263
264 it "returns the first routine in the program" do
265 expect(subject.next_routine).to eql(routine_a)
266 end
267 end
268
269 describe "#last_workout" do
270 include_context "stronglifts_program"
271 subject { create(:user) }
272
273 it "returns the last workout" do
274 workout = create(:workout, user: subject, routine: routine_a)
275 expect(subject.last_workout).to eql(workout)
276 end
277
278 it "returns the last workout that included a specific exercise" do
279 deadlift_workout = create(:workout, user: subject, routine: routine_b)
280 deadlift_workout.train(deadlift, 315.lbs, repetitions: 5)
281 bench_workout = create(:workout, user: subject, routine: routine_a)
282 bench_workout.train(bench_press, 195.lbs, repetitions: 5)
283
284 expect(subject.last_workout(deadlift)).to eql(deadlift_workout)
285 end
286
287 it "returns nil when no workouts have been completed" do
288 expect(subject.last_workout).to be_nil
289 end
290
291 it "returns nil when the exercise has not been performed" do
292 bench_workout = create(:workout, user: subject, routine: routine_a)
293 bench_workout.train(bench_press, 195.lbs, repetitions: 5)
294
295 expect(subject.last_workout(deadlift)).to be_nil
296 end
297 end
298end