@@ -822,6 +822,106 @@ class OmniauthCallbacksControllerTest < ActionController::TestCase
822
822
end
823
823
end
824
824
825
+ test "connect_provider: Performs takeover of an account with matching credential that has no activity" do
826
+ user = create :user , :multi_auth_migrated
827
+
828
+ # Given there exists another user
829
+ # having credential X
830
+ # and having no activity
831
+ other_user = create :user , :multi_auth_migrated
832
+ credential = create :google_authentication_option , user : other_user
833
+ refute other_user . has_activity?
834
+
835
+ # When I attempt to add credential X
836
+ auth = link_credential user ,
837
+ type : credential . credential_type ,
838
+ id : credential . authentication_id
839
+
840
+ # Then I should successfully add credential X
841
+ user . reload
842
+ assert_redirected_to 'http://test.host/users/edit'
843
+ assert_auth_option ( user , auth )
844
+
845
+ # And the other user should be destroyed
846
+ other_user . reload
847
+ assert other_user . deleted?
848
+ end
849
+
850
+ test "connect_provider: Successful takeover also enrolls in replaced user's sections" do
851
+ user = create :user , :multi_auth_migrated
852
+
853
+ # Given there exists another user
854
+ # having credential X
855
+ # and having no activity
856
+ # and enrolled in section Y
857
+ other_user = create :user , :multi_auth_migrated
858
+ credential = create :google_authentication_option , user : other_user
859
+ refute other_user . has_activity?
860
+ section = create :section
861
+ section . students << other_user
862
+
863
+ # When I add credential X
864
+ link_credential user ,
865
+ type : credential . credential_type ,
866
+ id : credential . authentication_id
867
+
868
+ # Then I should be enrolled in section Y instead of the other user
869
+ section . reload
870
+ assert_includes section . students , user
871
+ refute_includes section . students , other_user
872
+ end
873
+
874
+ test "connect_provider: Refuses to link credential if there is an account with matching credential that has activity" do
875
+ user = create :user , :multi_auth_migrated
876
+
877
+ # Given there exists another user
878
+ # having credential X
879
+ # and having activity
880
+ other_user = create :user , :multi_auth_migrated
881
+ credential = create :google_authentication_option , user : other_user
882
+ create :user_level , user : other_user , best_result : ActivityConstants ::MINIMUM_PASS_RESULT
883
+ assert other_user . has_activity?
884
+
885
+ # When I attempt to add credential X
886
+ link_credential user ,
887
+ type : credential . credential_type ,
888
+ id : credential . authentication_id
889
+
890
+ # Then the other user should not be destroyed
891
+ other_user . reload
892
+ refute other_user . deleted?
893
+
894
+ # And I should fail to add credential X
895
+ user . reload
896
+ assert_empty user . authentication_options
897
+
898
+ # And receive a helpful error message about the credential already being in use.
899
+ assert_redirected_to 'http://test.host/users/edit'
900
+ expected_error = I18n . t ( 'auth.already_in_use' , provider : I18n . t ( "auth.google_oauth2" ) )
901
+ assert_equal expected_error , flash . alert
902
+ end
903
+
904
+ test "connect_provider: Presents no-op message if the provided credentials are already linked to user's account" do
905
+ # Given the current user already has credential X
906
+ user = create :user , :multi_auth_migrated
907
+ credential = create :google_authentication_option , user : user
908
+ assert_equal 1 , user . authentication_options . count
909
+
910
+ # When I attempt to add credential X
911
+ link_credential user ,
912
+ type : credential . credential_type ,
913
+ id : credential . authentication_id
914
+
915
+ # Then I should have the same authentication options
916
+ user . reload
917
+ assert_equal 1 , user . authentication_options . count
918
+
919
+ # And receive a friendly notice about already having the credential
920
+ assert_redirected_to 'http://test.host/users/edit'
921
+ expected_notice = I18n . t ( 'auth.already_linked' , provider : I18n . t ( "auth.google_oauth2" ) )
922
+ assert_equal expected_notice , flash . notice
923
+ end
924
+
825
925
private
826
926
827
927
def set_oauth_takeover_session_variables ( provider , user )
@@ -831,6 +931,17 @@ def set_oauth_takeover_session_variables(provider, user)
831
931
@request . session [ ACCT_TAKEOVER_OAUTH_TOKEN ] = '54321'
832
932
end
833
933
934
+ # Try to link a credential to the provided user
935
+ # @return [OmniAuth::AuthHash] the auth hash, useful for validating
936
+ # linked credentials with assert_auth_option
937
+ def link_credential ( user , type :, id :)
938
+ auth = generate_auth_user_hash ( provider : type , uid : id )
939
+ @request . env [ 'omniauth.auth' ] = auth
940
+ setup_should_connect_provider ( user , 2 . days . from_now )
941
+ get :google_oauth2
942
+ auth
943
+ end
944
+
834
945
def generate_auth_user_hash ( args )
835
946
OmniAuth ::AuthHash . new (
836
947
uid : args [ :uid ] || '1111' ,
@@ -863,7 +974,7 @@ def assert_auth_option(user, oauth_hash)
863
974
user : user ,
864
975
hashed_email : User . hash_email ( oauth_hash . info . email ) ,
865
976
credential_type : oauth_hash . provider ,
866
- authentication_id : user . uid ,
977
+ authentication_id : oauth_hash . uid ,
867
978
data : {
868
979
oauth_token : oauth_hash . credentials . token ,
869
980
oauth_token_expiration : oauth_hash . credentials . expires_at ,
0 commit comments