dblock / slack-strava

(Re)Post Strava activities to Slack
https://slava.playplay.io
MIT License
37 stars 6 forks source link

Mongo::Error::OperationFailure: [11000]: E11000 duplicate key error collection: game-bot.users index: user_id_1_team_id_1 dup key #136

Closed dblock closed 2 years ago

dblock commented 2 years ago

Logs contain similar errors to https://github.com/dblock/slack-gamebot/issues/205

potential patch

diff --git a/slack-strava/models/user.rb b/slack-strava/models/user.rb
index 3ab64fc..a3a4ce6 100644
--- a/slack-strava/models/user.rb
+++ b/slack-strava/models/user.rb
@@ -64,6 +64,8 @@ class User

     instance_info = Hashie::Mash.new(client.web_client.users_info(user: slack_id)).user

+    raise "Missing users_info for #{slack_id}." unless instance_info
+
     if instance && (
       instance.user_name != instance_info.name ||
       instance.is_bot != instance_info.is_bot ||
@@ -78,9 +80,11 @@ class User
       )
     end

+    instance ||= User.where(team: client.owner, user_id: instance_info.id).first
+
     instance ||= User.create!(
       team: client.owner,
-      user_id: slack_id,
+      user_id: instance_info.id,
       user_name: instance_info.name,
       is_bot: instance_info.is_bot,
       is_admin: instance_info.is_admin,
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index c70da31..376e105 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -32,7 +32,7 @@ describe User do
         expect {
           user = User.find_create_or_update_by_slack_id!(client, 'whatever')
           expect(user).to_not be_nil
-          expect(user.user_id).to eq 'whatever'
+          expect(user.user_id).to eq 'U007'
           expect(user.user_name).to eq 'username'
           expect(user.is_admin).to be true
           expect(user.is_bot).to be false
@@ -67,6 +67,19 @@ describe User do
         expect(user.is_owner).to be true
       end
     end
+    context 'with a user with info matching an existing user id' do
+      let!(:user) { Fabricate(:user, team: team, is_admin: true, user_id: 'U007') }
+      it 'updates the fields of the existing user' do
+        expect {
+          User.find_create_or_update_by_slack_id!(client, 'whatever')
+        }.to_not change(User, :count)
+        user.reload
+        expect(user.user_id).to eq 'U007'
+        expect(user.is_admin).to be true
+        expect(user.is_bot).to be false
+        expect(user.is_owner).to be false
+      end
+    end
   end
   context 'sync_new_strava_activities!' do
     context 'recent created_at', vcr: { cassette_name: 'strava/user_sync_new_strava_activities', allow_playback_repeats: true } do