diff --git a/client/config/routes.js b/client/config/routes.js index 2d5516b2f..d5316ddc0 100755 --- a/client/config/routes.js +++ b/client/config/routes.js @@ -60,6 +60,13 @@ module.exports = [ ) { keypather.get(ModalService, 'modalLayers[0].modal.controller.close()'); }, + onEnter: function ( + ModalService + ) { + ModalService.modalLayers.forEach(function (openModal) { + openModal.close(); + }); + }, resolve: { grantedOrgs: function (fetchGrantedGithubOrgs) { return fetchGrantedGithubOrgs(); diff --git a/client/controllers/controllerInstance.js b/client/controllers/controllerInstance.js index 6e4fee42f..2becb0e41 100644 --- a/client/controllers/controllerInstance.js +++ b/client/controllers/controllerInstance.js @@ -206,7 +206,7 @@ function ControllerInstance( }); }); - if (ahaGuide.isInGuide()) { + if (ahaGuide.isInGuide() && !ahaGuide.isPersonalAccount()) { if (keypather.get(instancesByPod, 'models.length')) { if (instancesByPod.models.some(function (instance) { return instance.attrs.hasAddedBranches || keypather.get(instance, 'children.models.length'); diff --git a/client/directives/accountsSelect/directiveAccountsSelect.js b/client/directives/accountsSelect/directiveAccountsSelect.js index 5f0101f74..ac4b1a8b8 100644 --- a/client/directives/accountsSelect/directiveAccountsSelect.js +++ b/client/directives/accountsSelect/directiveAccountsSelect.js @@ -91,13 +91,7 @@ function accountsSelect ( keypather.set($scope, 'popoverAccountMenu.data.currentOrg', currentOrg); keypather.set($scope, 'popoverAccountMenu.data.orgs', $scope.data.orgs); keypather.set($scope, 'popoverAccountMenu.data.user', $scope.data.user); - - // Integrations modal - if ($scope.data.user.oauthName() === $state.params.userName) { - $scope.popoverAccountMenu.data.showIntegrations = false; - } else { - $scope.popoverAccountMenu.data.showIntegrations = true; - } + keypather.set($scope, 'popoverAccountMenu.data.showIntegrations', true); }); $scope.getBadgeCount = function () { diff --git a/client/directives/components/gitHubIntegration/githubIntegrationController.js b/client/directives/components/gitHubIntegration/githubIntegrationController.js index fc8114367..3c0334605 100644 --- a/client/directives/components/gitHubIntegration/githubIntegrationController.js +++ b/client/directives/components/gitHubIntegration/githubIntegrationController.js @@ -20,6 +20,7 @@ function GithubIntegrationController( var GIC = this; var org = keypather.get(currentOrg, 'github.attrs.login'); GIC.organizationName = org; + GIC.isPersonalAccount = keypather.get(currentOrg, 'poppa.attrs.isPersonalAccount'); function checkRunnabot() { return isRunnabotPartOfOrg(org) diff --git a/client/directives/components/gitHubIntegration/githubIntegrationView.jade b/client/directives/components/gitHubIntegration/githubIntegrationView.jade index 96bf17e93..d5f3ebd61 100644 --- a/client/directives/components/gitHubIntegration/githubIntegrationView.jade +++ b/client/directives/components/gitHubIntegration/githubIntegrationView.jade @@ -7,19 +7,19 @@ img.shrink.img.img-comment( //- if NOT a personal account p.grid-content.shrink.p.text-center.weight-light.margin-top-md.margin-bottom-md( - ng-if = "!$root.featureFlags.isPersonalAccount" + ng-if = "!GIC.isPersonalAccount" ) {{!$root.featureFlags.ahaBranchUrlStep ? 'Now you can invite our bot to your GitHub org to get notifications on your pull requests:' : 'Invite our bot to your GitHub org to get notifications on your pull requests:'}} //- if is personal account AND phase 2 implemented p.grid-content.shrink.p.text-center.weight-light.margin-top-md.margin-bottom-md( - ng-if = "$root.featureFlags.isPersonalAccount && $root.featureFlags.personalAccountsPhase2" + ng-if = "GIC.isPersonalAccount && $root.featureFlags.personalAccountsPhase2" ) Now you can get environment br.hidden-xxs | notifications on your pull requests. //- if is personal accounts AND phase 2 is NOT implemented p.grid-content.shrink.p.text-center.weight-light.margin-top-md.margin-bottom-md( - ng-if = "$root.featureFlags.isPersonalAccount && !$root.featureFlags.personalAccountsPhase2" + ng-if = "GIC.isPersonalAccount && !$root.featureFlags.personalAccountsPhase2" ) We only support pull request notifications with GitHub teams, but it looks like you’re using a personal account. //- if checking whether the user is an admin, or checking whether runnabot has been enabled @@ -33,7 +33,7 @@ a.grid-block.align-center.shrink.btn.btn-md.green( data-event-name = "Clicked Invite Runnabot button" ng-disabled = "!GIC.isAdmin" ng-click = "GIC.pollCheckRunnabot()" - ng-hide = "$root.isLoading.checkRunnabot || GIC.hasRunnabot || $root.featureFlags.isPersonalAccount" + ng-hide = "$root.isLoading.checkRunnabot || GIC.hasRunnabot || GIC.isPersonalAccount" ng-href = "https://github.com/orgs/{{GIC.organizationName}}/invitations/runnabot/edit" target = "_blank" ) @@ -54,7 +54,7 @@ a.grid-block.align-center.shrink.btn.btn-md.green( 'text-red': !GIC.isAdmin\ }" ng-hide = "$root.isLoading.checkRunnabot" - ng-if = "!$root.featureFlags.isPersonalAccount && !$root.featureFlags.personalAccountsPhase2 && !GIC.hasRunnabot" + ng-if = "!GIC.isPersonalAccount && !$root.featureFlags.personalAccountsPhase2 && !GIC.hasRunnabot" ) span( ng-if = "GIC.isAdmin" @@ -71,7 +71,7 @@ a.grid-block.align-center.shrink.btn.btn-md.green( //- button for personal accounts label.grid-block.shrink.align-center.label.well.gray.padding-xs( - ng-hide = "$root.isLoading.checkRunnabot || !$root.featureFlags.isPersonalAccount || !$root.featureFlags.personalAccountsPhase2" + ng-hide = "$root.isLoading.checkRunnabot || !GIC.isPersonalAccount || !$root.featureFlags.personalAccountsPhase2" ng-init = "personalRunnabot = false" ) .grid-content Enable PR Notifications @@ -84,7 +84,7 @@ label.grid-block.shrink.align-center.label.well.gray.padding-xs( //- disclaimer for personal accounts .small.text-gray.text-center.margin-top-xxs( - ng-hide = "$root.isLoading.checkRunnabot || personalRunnabot || !$root.featureFlags.isPersonalAccount || !$root.featureFlags.personalAccountsPhase2" + ng-hide = "$root.isLoading.checkRunnabot || personalRunnabot || !GIC.isPersonalAccount || !$root.featureFlags.personalAccountsPhase2" ) Our GitHub bot will join your repos as a collaborator. //- hiding until praful writes his doc //- br @@ -92,7 +92,7 @@ label.grid-block.shrink.align-center.label.well.gray.padding-xs( //- show after successfully inviting runnabot (for both orgs and personal accounts) .grid-block.align-center.shrink.runnabot-success( - ng-show = "(!$root.featureFlags.isPersonalAccount && GIC.hasRunnabot && !$root.isLoading.checkRunnabot) || $root.featureFlags.isPersonalAccount && personalRunnabot" + ng-show = "(!GIC.isPersonalAccount && GIC.hasRunnabot && !$root.isLoading.checkRunnabot) || $root.featureFlags.isPersonalAccount && personalRunnabot" ) img.grid-content.shrink.img( height = "36" @@ -109,7 +109,7 @@ label.grid-block.shrink.align-center.label.well.gray.padding-xs( p.small.text-gray.text-left Thanks! See you soon on your pull requests. button.btn.btn-md.white( - ng-if = "$root.featureFlags.isPersonalAccount && !$root.featureFlags.personalAccountsPhase2 && !$root.isLoading.checkRunnabot" + ng-if = "$root.featureFlags.personalAccounts && GIC.isPersonalAccount && !$root.isLoading.checkRunnabot" ui-sref = "orgSelect" ui-sref-opts = "{reload: true}" ) Switch to a Team diff --git a/client/directives/modals/ahaModal/ahaModalController.js b/client/directives/modals/ahaModal/ahaModalController.js index 604547ab0..8d4c0d60d 100644 --- a/client/directives/modals/ahaModal/ahaModalController.js +++ b/client/directives/modals/ahaModal/ahaModalController.js @@ -15,6 +15,7 @@ function AhaModalController( fetchOwnerRepos, fetchStackInfo, github, + keypather, loading, ModalService, @@ -105,7 +106,8 @@ function AhaModalController( loading('startDemo', true); var loadingName = 'startDemo' + stackName.charAt(0).toUpperCase() + stackName.slice(1); loading(loadingName, true); - github.forkRepo('RunnableDemo', repoMapping[stackName], currentOrg.github.oauthName()) + var isPersonalAccount = keypather.get(currentOrg, 'poppa.attrs.isPersonalAccount'); + github.forkRepo('RunnableDemo', repoMapping[stackName], currentOrg.github.oauthName(), isPersonalAccount) .then(function () { return findRepo(repoMapping[stackName]); }) diff --git a/client/directives/modals/modalChooseOrganization/chooseOrganizationModalController.js b/client/directives/modals/modalChooseOrganization/chooseOrganizationModalController.js index fe35b6dab..f17d6f0aa 100644 --- a/client/directives/modals/modalChooseOrganization/chooseOrganizationModalController.js +++ b/client/directives/modals/modalChooseOrganization/chooseOrganizationModalController.js @@ -11,6 +11,7 @@ function ChooseOrganizationModalController( ahaGuide, configEnvironment, createNewSandboxForUserService, + currentOrg, customWindowService, errs, eventTracking, @@ -183,9 +184,13 @@ function ChooseOrganizationModalController( }); }; COMC.getSelectedOrg = function (selectedOrgName) { - return COMC.allAccounts.models.find(function (org) { + var selectedOrg = COMC.allAccounts.models.find(function (org) { return selectedOrgName.toLowerCase() === org.oauthName().toLowerCase(); }); + if (!selectedOrg) { + selectedOrg = COMC.user; + } + return selectedOrg; }; COMC.isChoosingOrg = ahaGuide.isChoosingOrg; diff --git a/client/directives/modals/modalChooseOrganization/orgSelectModalView.jade b/client/directives/modals/modalChooseOrganization/orgSelectModalView.jade index 162d2aab4..d6dfded40 100644 --- a/client/directives/modals/modalChooseOrganization/orgSelectModalView.jade +++ b/client/directives/modals/modalChooseOrganization/orgSelectModalView.jade @@ -24,6 +24,24 @@ xlink:href = "#icons-arrow-down" ) + ol.grid-block.vertical.list + li.grid-block.align-center.list-item.btn.white( + ng-if = "$root.featureFlags.personalAccounts" + data-event-name = "PA Selected" + ng-click = "COMC.actions.createOrCheckDock(COMC.user.oauthName())" + title = "{{COMC.user.oauthName()}}" + ) + img.grid-content.shrink( + height = "30" + ng-src = "{{COMC.user.gravitar()}}" + width = "30" + ) + span.grid-content.text-left.text-overflow {{COMC.user.oauthName()}} + svg.grid-content.iconnables.icons-arrow-forward.shrink + use( + xlink:href = "#icons-arrow-down" + ) + ol.margin-top-sm.grid-block.vertical.list li.grid-block.align-center.list-item.btn.white( data-event-name = "Clicked to Grant Access View" diff --git a/client/directives/modals/settingsModal/forms/teamManagementForm/alternateInviteModalView.jade b/client/directives/modals/settingsModal/forms/teamManagementForm/alternateInviteModalView.jade new file mode 100644 index 000000000..04a5d1890 --- /dev/null +++ b/client/directives/modals/settingsModal/forms/teamManagementForm/alternateInviteModalView.jade @@ -0,0 +1,29 @@ +.grid-block.vertical.align-center.justify-center.modal-body + svg.iconnables.icons-close( + ng-click = "IMC.close()" + ) + use( + xlink:href = "#icons-close" + ) + img.grid-block.shrink.margin-top-md( + height = "150" + src = "/build/images/runnabear-add.svg" + width = "150" + ) + p.grid-block.shrink.p.weight-light.text-center.margin-bottom-md.margin-top-md( + | {{IMC.getTextForInviteModal()}} + +footer.modal-footer + button.btn.btn-block.btn-md.white( + ui-sref = "orgSelect" + ng-if = "IMC.isPersonalAccount" + ) Switch to a Team + a.btn.btn-block.btn-md.white( + ng-href = "https://github.com/orgs/{{IMC.teamName}}/people" + ng-if = "!IMC.isPersonalAccount && IMC.orgMembers.all.length === 1" + target = "_blank" + ) See Team on GitHub + button.btn.btn-block.btn-md.white( + ng-if = "!IMC.isPersonalAccount && IMC.invitedAll && IMC.orgMembers.all.length > 1" + ng-click = "IMC.close()" + ) Close diff --git a/client/directives/modals/settingsModal/forms/teamManagementForm/inviteModalController.js b/client/directives/modals/settingsModal/forms/teamManagementForm/inviteModalController.js index fbffd367f..8fd414e9f 100644 --- a/client/directives/modals/settingsModal/forms/teamManagementForm/inviteModalController.js +++ b/client/directives/modals/settingsModal/forms/teamManagementForm/inviteModalController.js @@ -16,17 +16,23 @@ function InviteModalController( inviteGithubUserToRunnable, loading, + isPersonalAccount, teamName, - unInvitedMembers, + orgMembers, close ) { var IMC = this; angular.extend(IMC, { - name: 'inviteModal', activeUserId: null, + invitedAll: null, + invitesSent: false, + isPersonalAccount: isPersonalAccount, + orgMembers: orgMembers, + name: 'inviteModal', sendingInviteUserId: null, sending: false, - invitesSent: false + showAlternateInviteModal: null, + teamName: teamName }); // Load uninvited members if they are not passed in @@ -34,13 +40,13 @@ function InviteModalController( $q.when(true) .then(function () { // Empty array is valid input - if (!unInvitedMembers && !Array.isArray(unInvitedMembers)) { + if (!orgMembers.uninvited && !Array.isArray(orgMembers.uninvited)) { return fetchOrgMembers($state.params.userName, true) .then(function (members) { return members.uninvited; }); } - return unInvitedMembers; + return orgMembers.uninvited; }) .then(function (unInvitedMembers) { unInvitedMembers.forEach(function (member) { @@ -52,11 +58,12 @@ function InviteModalController( } }); IMC.unInvitedMembers = unInvitedMembers; + IMC.invitedAll = IMC.orgMembers.all.length === IMC.orgMembers.registered.length + IMC.orgMembers.invited.length; + IMC.showAlternateInviteModal = IMC.isPersonalAccount || IMC.invitedAll || !IMC.unInvitedMembers.length; loading(IMC.name, false); }) .catch(errs.handler); - IMC.sendInvitation = function (user) { IMC.sendingInviteUserId = user.id; IMC.setActiveUserId(null); @@ -85,4 +92,16 @@ function InviteModalController( $rootScope.$emit('updateTeammateInvitations', IMC.invitesSent); close(IMC.invitesSent); }; + + IMC.getTextForInviteModal = function () { + if (IMC.isPersonalAccount) { + return 'We only support having teammates with GitHub teams, but it looks like you\'re using a personal account.'; + } + if (IMC.orgMembers.all.length === 1) { + return 'You\'re the only one in this team. Add teammates to your GitHub team before inviting them to Runnable.'; + } + if (IMC.invitedAll && IMC.orgMembers.all.length > 1) { + return 'You\'re amazing! You\'ve already invited everyone on your GitHub team to Runnable.'; + } + }; } diff --git a/client/directives/modals/settingsModal/forms/teamManagementForm/inviteModalView.jade b/client/directives/modals/settingsModal/forms/teamManagementForm/inviteModalView.jade index 3f44e7a55..90aae9a3c 100644 --- a/client/directives/modals/settingsModal/forms/teamManagementForm/inviteModalView.jade +++ b/client/directives/modals/settingsModal/forms/teamManagementForm/inviteModalView.jade @@ -1,37 +1,11 @@ .modal-backdrop.in .modal-dialog.modal-xs.modal-invite( - ng-if = "$root.featureFlags.isPersonalAccount" + ng-if = "$root.featureFlags.personalAccounts && IMC.showAlternateInviteModal" + ng-include = "'alternateInviteModalView'" ) - .grid-block.vertical.align-center.justify-center.modal-body - svg.iconnables.icons-close( - ng-click = "IMC.close()" - ) - use( - xlink:href = "#icons-close" - ) - img.grid-block.shrink.margin-top-md( - height = "150" - src = "/build/images/runnabear-add.svg" - width = "150" - ) - p.grid-block.shrink.p.weight-light.text-center.margin-bottom-md.margin-top-md - | We only support having teammates with GitHub teams, but it looks like you’re using a personal account. - //- | You’re the only one in this team. Add teammates to your GitHub team before inviting them to Runnable. - //- | You’re amazing! You’ve already invited everyone on your GitHub team to Runnable. - footer.modal-footer - button.btn.btn-block.btn-md.white( - ui-sref = "orgSelect" - ui-sref-opts = "{reload: true}" - ) Switch to a Team - //- a.btn.btn-block.btn-md.white( - //- ng-href = "https://github.com/orgs/{{THISORGNAME}}/people" - //- target = "_blank" - //- ) See Team on GitHub - //- button.btn.btn-block.btn-md.white( - //- ng-click = "IMC.close()" - //- ) Close + .modal-dialog.modal-xs.modal-sheet.modal-invite( - ng-if = "!$root.featureFlags.isPersonalAccount" + ng-if = "!IMC.showAlternateInviteModal" ) header.modal-header Invite Teammate svg.iconnables.icons-close( diff --git a/client/directives/modals/settingsModal/forms/teamManagementForm/teamManagementFormController.js b/client/directives/modals/settingsModal/forms/teamManagementForm/teamManagementFormController.js index 468b2389b..f45bb3d45 100644 --- a/client/directives/modals/settingsModal/forms/teamManagementForm/teamManagementFormController.js +++ b/client/directives/modals/settingsModal/forms/teamManagementForm/teamManagementFormController.js @@ -11,6 +11,7 @@ function TeamManagementFormController( $rootScope, $scope, $state, + currentOrg, errs, fetchOrgMembers, inviteGithubUserToRunnable, @@ -20,7 +21,8 @@ function TeamManagementFormController( var TMMC = this; angular.extend(TMMC, { loading: true, - members: null + members: null, + isPersonalAccount: keypather.get(currentOrg, 'poppa.attrs.isPersonalAccount') }); // Load initial state @@ -36,6 +38,7 @@ function TeamManagementFormController( $scope.$on('$destroy', newInviteAddedWatchterUnbind); function fetchMembers () { + var currentUser; return fetchOrgMembers($state.params.userName, true) .then(function (members) { TMMC.loading = false; @@ -55,10 +58,16 @@ function TeamManagementFormController( } }; }; + if (TMMC.isPersonalAccount) { + currentUser = keypather.get(currentOrg, 'github.attrs'); + TMMC.members.registered.push(currentUser); + return; + } TMMC.members.invited.forEach(setEmail('userInvitation.attrs.recipient.email')); TMMC.members.registered.forEach(setEmail('userModel.attrs.accounts.github.emails[0].value')); TMMC.members.uninvited.forEach(setEmail(null)); }); + } TMMC.openInvitationModal = function () { @@ -68,7 +77,8 @@ function TeamManagementFormController( templateUrl: 'inviteModalView', inputs: { teamName: $state.params.userName, - unInvitedMembers: TMMC.members.uninvited + orgMembers: TMMC.members, + isPersonalAccount: TMMC.isPersonalAccount } }) .then(function (modal) { diff --git a/client/directives/modals/settingsModal/forms/teamManagementForm/teamManagementFormView.jade b/client/directives/modals/settingsModal/forms/teamManagementForm/teamManagementFormView.jade index 26053f7fd..7b078f0fe 100644 --- a/client/directives/modals/settingsModal/forms/teamManagementForm/teamManagementFormView.jade +++ b/client/directives/modals/settingsModal/forms/teamManagementForm/teamManagementFormView.jade @@ -17,7 +17,6 @@ .label-col.full-width Teammates a.small.link.float-right( ng-click = "TMMC.openInvitationModal()" - ng-if = "TMMC.members.uninvited.length > 0 || $root.featureFlags.isPersonalAccount" ) svg.iconnables.icons-team-invite use( @@ -74,7 +73,7 @@ xlink:href = "#icons-overflow" ) p.small.text-center.padding-xxs( - ng-if = "!$root.featureFlags.isPersonalAccount" + ng-if = "!TMMC.isPersonalAccount" ) a.link( href = "mailto:support@runnable.com" diff --git a/client/directives/modals/settingsModal/settingsModalController.js b/client/directives/modals/settingsModal/settingsModalController.js index 1e72b02e0..786fa835c 100644 --- a/client/directives/modals/settingsModal/settingsModalController.js +++ b/client/directives/modals/settingsModal/settingsModalController.js @@ -8,6 +8,7 @@ require('app') */ function SettingsModalController( close, + keypather, subTab, tab, currentOrg @@ -20,4 +21,5 @@ function SettingsModalController( }); SEMC.currentOrg = currentOrg; SEMC.showFooter = true; + SEMC.isPersonalAccount = keypather.get(currentOrg, 'poppa.attrs.isPersonalAccount'); } diff --git a/client/directives/modals/settingsModal/settingsModalView.jade b/client/directives/modals/settingsModal/settingsModalView.jade index 85b414f77..af0c4476d 100644 --- a/client/directives/modals/settingsModal/settingsModalView.jade +++ b/client/directives/modals/settingsModal/settingsModalView.jade @@ -3,7 +3,12 @@ header.grid-block.vertical.align-center.modal-header .container-title-wrapper .server-status-card-pop-over.no-touching - .container-title {{SEMC.currentOrg.github.attrs.login}} Settings + .container-title( + ng-if = "!SEMC.isPersonalAccount" + ) {{SEMC.currentOrg.github.attrs.login}} Settings + .container-title( + ng-if = "SEMC.isPersonalAccount" + ) Settings svg.iconnables.icons-close( ng-click = "SEMC.close()" ) diff --git a/client/services/ahaGuideService.js b/client/services/ahaGuideService.js index e2dc605b2..d434e615c 100644 --- a/client/services/ahaGuideService.js +++ b/client/services/ahaGuideService.js @@ -31,6 +31,10 @@ function ahaGuide( } function refreshHasRunnabot() { if (hasRunnabot) { return true; } + if (keypather.get(currentOrg, 'poppa.attrs.isPersonalAccount') && getCurrentStep() === 4) { + endGuide(); + return; + } return isRunnabotPartOfOrg(keypather.get(currentOrg, 'github.attrs.login')) .then(function (runnabot) { if (runnabot && isInGuide()) { @@ -304,6 +308,10 @@ function ahaGuide( return keypather.get(currentOrg, 'poppa.attrs.metadata.hasConfirmedSetup'); } + function isPersonalAccount () { + return keypather.get(currentOrg, 'poppa.attrs.isPersonalAccount'); + } + function updateCurrentOrg (updatedOrg) { if (keypather.has(updatedOrg, 'metadata.hasAha') && keypather.has(updatedOrg, 'metadata.hasConfirmedSetup')) { currentOrg.poppa.attrs.metadata = updatedOrg.metadata; @@ -393,6 +401,7 @@ function ahaGuide( hasDemoRepo: hasDemoRepo, hasRunnabot: refreshHasRunnabot, isInGuide: isInGuide, + isPersonalAccount: isPersonalAccount, resetGuide: resetGuide, skipBranchMilestone: skipBranchMilestone, stepList: stepList, diff --git a/client/services/githubService.js b/client/services/githubService.js index cbacd26f0..f0d81a463 100644 --- a/client/services/githubService.js +++ b/client/services/githubService.js @@ -32,14 +32,17 @@ function github( }); } return { - forkRepo: function (repoOwner, repoName, targetOrg) { - return makeGhRequest({ + forkRepo: function (repoOwner, repoName, targetOrg, isPersonalAccount) { + var ghRequest = { method: 'post', url: githubAPIUrl + '/repos/' + repoOwner + '/' + repoName + '/forks', - data: { + }; + if (!isPersonalAccount) { + ghRequest.data = { organization: targetOrg - } - }); + }; + } + return makeGhRequest(ghRequest); } }; } diff --git a/test/unit/controllers/controllerInstance.unit.js b/test/unit/controllers/controllerInstance.unit.js index 08cea70b9..1086b0f8a 100644 --- a/test/unit/controllers/controllerInstance.unit.js +++ b/test/unit/controllers/controllerInstance.unit.js @@ -64,6 +64,7 @@ describe('controllerInstance'.bold.underline.blue, function () { isAddingFirstRepo: sinon.stub().returns(false), getCurrentStep: sinon.stub().returns(1), isInGuide: sinon.stub().returns(true), + isPersonalAccount: sinon.stub().returns(false), steps: { ADD_FIRST_BRANCH: 123 } diff --git a/test/unit/directives/modals/settingsModal/inviteModalController.unit.js b/test/unit/directives/modals/settingsModal/inviteModalController.unit.js index 5560073c6..ada549cdb 100644 --- a/test/unit/directives/modals/settingsModal/inviteModalController.unit.js +++ b/test/unit/directives/modals/settingsModal/inviteModalController.unit.js @@ -15,17 +15,25 @@ var $q; describe('InviteModalController'.bold.underline.blue, function () { var IMC; + var closeSettingsModalStub; var inviteGithubUserToRunnableStub; + var isPersonalAccountMock; var fetchUserStub; var fetchGithubOrgIdStub; var fetchOrgMembersStub; - var user; var errs; + var user; var username = 'purpleBear'; var userId = 777; var userEmail = 'purplebear@codenow.com'; var orgId = 787; var unInvitedMembers; + var orgMembersMock = { + uninvited: undefined, + all: [], + invited: [], + registered: [] + }; var closeStub = sinon.stub(); function setup (initWithoutUninvitedMembers) { @@ -50,7 +58,13 @@ describe('InviteModalController'.bold.underline.blue, function () { fetchOrgMembersStub = sinon.stub().returns($q.when({ uninvited: unInvitedMembers })); return fetchOrgMembersStub; }); + $provide.factory('closeSettingsModal', function () { + closeSettingsModalStub = sinon.stub().returns(true); + return closeSettingsModalStub; + }) $provide.value('teamName', 'hello'); + $provide.value('isPersonalAccount', isPersonalAccountMock); + $provide.value('orgMembers', orgMembersMock); $provide.value('unInvitedMembers', (function () { if (initWithoutUninvitedMembers) { return null; @@ -174,4 +188,65 @@ describe('InviteModalController'.bold.underline.blue, function () { }); }); + describe('showing the correct invite modal', function () { + beforeEach(function () { + isPersonalAccountMock = false; + orgMembersMock = { + all: [1, 2, 3], + registered: [1, 2], + uninvited: [1], + invited: [] + }; + }); + + it('should not show the alternate invite modal for orgs w/ uninvited members', function () { + setup(); + $scope.$digest(); + expect(IMC.showAlternateInviteModal).to.equal(false); + }); + + it('should show the alternate invite modal for personal accounts', function () { + isPersonalAccountMock = true; + setup(); + $scope.$digest(); + expect(IMC.showAlternateInviteModal).to.equal(true); + }); + + it('should show the alternate invite modal for full orgs', function () { + orgMembersMock.invited = ['new guy']; + setup(); + $scope.$digest(); + expect(IMC.showAlternateInviteModal).to.equal(true); + }); + + it('should show the alternate invite modal for one person orgs', function () { + orgMembersMock.all = ['one guy']; + orgMembersMock.registered = ['one guy']; + orgMembersMock.invited = []; + orgMembersMock.uninvited = []; + setup(); + $scope.$digest(); + expect(IMC.showAlternateInviteModal).to.equal(true); + }); + }); + + describe('invite modal user message', function () { + beforeEach(function () { + setup(); + }); + + it('should select the correct caption for a given scenario', function () { + IMC.isPersonalAccount = true; + var message = IMC.getTextForInviteModal(); + expect(message).to.equal('We only support having teammates with GitHub teams, but it looks like you\'re using a personal account.'); + IMC.isPersonalAccount = false; + IMC.orgMembers.all = [1]; + var message = IMC.getTextForInviteModal(); + expect(message).to.equal('You\'re the only one in this team. Add teammates to your GitHub team before inviting them to Runnable.'); + IMC.orgMembers.all = [1, 2]; + IMC.invitedAll = true; + var message = IMC.getTextForInviteModal(); + expect(message).to.equal('You\'re amazing! You\'ve already invited everyone on your GitHub team to Runnable.'); + }); + }); });