Skip to content

Commit

Permalink
Captains can reset seasons by confirming the team name.
Browse files Browse the repository at this point in the history
  • Loading branch information
dblock committed Dec 21, 2015
1 parent 2f1fa3b commit 16685ab
Show file tree
Hide file tree
Showing 12 changed files with 38 additions and 42 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### Changelog

* [#46](https://github.com/dblock/slack-gamebot/issues/46): Captains can reset seasons by confirming the team name - [@dblock](https://github.com/dblock).
* [#46](https://github.com/dblock/slack-gamebot/issues/46): Added `team`, `promote` and `demote` commands, selecting captains - [@dblock](https://github.com/dblock).
* [#49](https://github.com/dblock/slack-gamebot/issues/49): Disallow indexing by serving a robots.txt - [@dblock](https://github.com/dblock).
* [#48](https://github.com/dblock/slack-gamebot/issues/48): API failures return 400 status code with a hypermedia response - [@dblock](https://github.com/dblock).
Expand Down
8 changes: 0 additions & 8 deletions DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@ If your bot servces one team, set SLACK_API_TOKEN from the Bot integration setti
heroku config:add SLACK_API_TOKEN=...
```

#### GAMEBOT_SECRET

If your bot services one team, DM Slack-Gamebot using this secret to perform a season reset. Only tell GameBot captains.

```
heroku config:add GAMEBOT_SECRET=...
```

#### GAMEBOT_ALIASES

Optional names for this bot.
Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,32 +203,32 @@ Victor Barna promoted Wang Hoe and Deng Yaping to captain.

#### gamebot demote me

Demotes from captain to a normal user. Must be a captain and the team must have other captains to do that.
Demotes from captain to a normal user. Must be a captain and the team must have other captains to do this.

```
gamebot demote me
Victor Barna is no longer captain.
```

#### gamebot reset [secret]
#### gamebot team

Direct-message gamebot to reset all users and pending challenges.
Display current team's info, including captains.

```
gamebot reset <secret>
gamebot team
Welcome to the new season!
Team _China_, captains Deng Yaping and Victor Barna.
```

#### gamebot team
#### gamebot reset <team name>

Display current team's info, including captains.
Direct-message gamebot to reset all users and pending challenges. Must be a captain to do this.

```
gamebot team
gamebot reset China
Team _China_, captains Deng Yaping and Victor Barna.
Welcome to the new season!
```

#### gamebot season
Expand Down
3 changes: 1 addition & 2 deletions slack-gamebot/api/endpoints/teams_endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ class TeamsEndpoint < Grape::API
team = Team.create!(
token: rc['bot']['bot_access_token'],
team_id: rc['team_id'],
name: rc['team_name'],
secret: SecureRandom.hex(16)
name: rc['team_name']
)

SlackGamebot::Service.start!(team)
Expand Down
1 change: 1 addition & 0 deletions slack-gamebot/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def ensure_a_team_captain!
next if team.captains.count > 0
user = team.users.asc(:_id).first
user.promote!
team.unset :secret
logger.info "#{team}: promoted #{user} to captain."
end
end
Expand Down
2 changes: 1 addition & 1 deletion slack-gamebot/commands/demote.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Commands
class Demote < SlackRubyBot::Commands::Base
def self.call(client, data, match)
user = ::User.find_create_or_update_by_slack_id!(client, data.user)
if match['expression'] != 'me'
if !match.names.include?('expression') || match['expression'] != 'me'
send_message_with_gif client, data.channel, 'You can only demote yourself, try _demote me_.', 'help'
logger.info "DEMOTE: #{user.user_name}, failed, not me"
elsif !user.captain?
Expand Down
20 changes: 11 additions & 9 deletions slack-gamebot/commands/reset.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ module SlackGamebot
module Commands
class Reset < SlackRubyBot::Commands::Base
def self.call(client, data, match)
team = ::Team.first # TODO: locate a user's team
fail ArgumentError, 'Missing team secret.' unless team && team.secret.present?
arguments = match['expression'].split.reject(&:blank?) if match.names.include?('expression')
secret = arguments.first if arguments
fail ArgumentError, 'Missing secret.' unless secret.present?
fail ArgumentError, 'Invalid secret.' unless secret == team.secret
user = ::User.find_create_or_update_by_slack_id!(client, data.user)
::Season.create!(team: team, created_by: user)
send_message_with_gif client, data.channel, 'Welcome to the new season!', 'season'
logger.info "RESET: #{data.user}"
if !user.captain?
send_message_with_gif client, data.channel, "You're not a captain, sorry.", 'sorry'
logger.info "RESET: #{user.user_name}, failed, not captain"
elsif !match.names.include?('expression') || match['expression'] != user.team.name
send_message_with_gif client, data.channel, "Invalid team name, confirm with _reset #{user.team.name}_.", 'help'
logger.info "RESET: #{user.user_name}, failed, invalid team name"
else
::Season.create!(team: user.team, created_by: user)
send_message_with_gif client, data.channel, 'Welcome to the new season!', 'season'
logger.info "RESET: #{data.user}"
end
end
end
end
Expand Down
2 changes: 0 additions & 2 deletions slack-gamebot/models/team.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ class Team
field :name, type: String
field :domain, type: String
field :token, type: String
field :secret, type: String

validates_uniqueness_of :token, message: 'has already been used'
validates_presence_of :token
Expand Down Expand Up @@ -36,7 +35,6 @@ def self.find_or_create_from_env!
team.team_id = info['team']['id']
team.name = info['team']['name']
team.domain = info['team']['domain']
team.secret = ENV['GAMEBOT_SECRET']
team.save!
team
end
Expand Down
1 change: 0 additions & 1 deletion spec/api/endpoints/teams_endpoint_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
expect(team.name).to eq 'team_name'
team = Team.find(team.id)
expect(team.token).to eq 'token'
expect(team.secret).to_not be_blank
end.to change(Team, :count).by(1)
end
it 'returns a useful error when team already exists' do
Expand Down
1 change: 0 additions & 1 deletion spec/fabricators/team_fabricator.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
Fabricator(:team) do
token { Fabricate.sequence(:team_token) { |i| "abc-#{i}" } }
secret { Fabricate.sequence(:team_secret) { |i| "secret#{i}" } }
team_id { Fabricate.sequence(:team_id) { |i| "T#{i}" } }
name { Faker::Name.first_name }
end
1 change: 0 additions & 1 deletion spec/models/team_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
expect(team.team_id).to eq 'T04KB5WQH'
expect(team.name).to eq 'dblock'
expect(team.domain).to eq 'dblockdotorg'
expect(team.secret).to eq 'secret'
expect(team.token).to eq 'token'
end
end
Expand Down
22 changes: 14 additions & 8 deletions spec/slack-gamebot/commands/reset_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,40 @@
describe SlackGamebot::Commands::Reset, vcr: { cassette_name: 'user_info' } do
let(:team) { Team.first || Fabricate(:team) }
let(:app) { SlackGamebot::Server.new(team: team) }
it 'requires a secret' do
it 'requires a captain' do
Fabricate(:user, captain: true, team: team)
Fabricate(:user, user_name: 'username')
expect(::User).to_not receive(:reset_all!).with(team)
expect(message: "#{SlackRubyBot.config.user} reset").to respond_with_error('Missing secret.')
expect(message: "#{SlackRubyBot.config.user} reset").to respond_with_slack_message("You're not a captain, sorry.")
end
it 'requires a valid secret' do
it 'requires a team name' do
expect(::User).to_not receive(:reset_all!).with(team)
expect(message: "#{SlackRubyBot.config.user} reset invalid").to respond_with_error('Invalid secret.')
expect(message: "#{SlackRubyBot.config.user} reset").to respond_with_slack_message("Invalid team name, confirm with _reset #{team.name}_.")
end
it 'resets with the correct secret' do
it 'requires a matching team name' do
expect(::User).to_not receive(:reset_all!).with(team)
expect(message: "#{SlackRubyBot.config.user} reset invalid").to respond_with_slack_message("Invalid team name, confirm with _reset #{team.name}_.")
end
it 'resets with the correct team name' do
Fabricate(:match)
expect(::User).to receive(:reset_all!).with(team).once
expect(message: "#{SlackRubyBot.config.user} reset #{team.secret}").to respond_with_slack_message('Welcome to the new season!')
expect(message: "#{SlackRubyBot.config.user} reset #{team.name}").to respond_with_slack_message('Welcome to the new season!')
end
it 'cancels open challenges' do
proposed_challenge = Fabricate(:challenge, state: ChallengeState::PROPOSED)

accepted_challenge = Fabricate(:challenge, state: ChallengeState::PROPOSED)
accepted_challenge.accept!(accepted_challenge.challenged.first)

expect(message: "#{SlackRubyBot.config.user} reset #{team.secret}").to respond_with_slack_message('Welcome to the new season!')
expect(message: "#{SlackRubyBot.config.user} reset #{team.name}").to respond_with_slack_message('Welcome to the new season!')

expect(proposed_challenge.reload.state).to eq ChallengeState::CANCELED
expect(accepted_challenge.reload.state).to eq ChallengeState::CANCELED
end
it 'resets user stats' do
Fabricate(:match)
user = Fabricate(:user, elo: 48, losses: 1, wins: 2, tau: 0.5)
expect(message: "#{SlackRubyBot.config.user} reset #{team.secret}").to respond_with_slack_message('Welcome to the new season!')
expect(message: "#{SlackRubyBot.config.user} reset #{team.name}").to respond_with_slack_message('Welcome to the new season!')
user.reload
expect(user.wins).to eq 0
expect(user.losses).to eq 0
Expand Down

0 comments on commit 16685ab

Please sign in to comment.