| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- import { expect, vi } from 'vitest'
- import sinon from 'sinon'
- const modulePath =
- '../../../../app/src/Features/Subscription/TeamInvitesController'
- describe('TeamInvitesController', function () {
- beforeEach(async function (ctx) {
- ctx.user = { _id: '!@312431', email: 'user@email.com' }
- ctx.adminUserId = '123jlkj'
- ctx.subscriptionId = '123434325412'
- ctx.user_email = 'bob@gmail.com'
- ctx.req = {
- session: {
- user: {
- _id: ctx.adminUserId,
- email: ctx.user_email,
- },
- },
- params: {},
- query: {},
- ip: '0.0.0.0',
- }
- ctx.subscription = {
- _id: ctx.subscriptionId,
- }
- ctx.TeamInvitesHandler = {
- promises: {
- acceptInvite: sinon.stub().resolves(ctx.subscription),
- getInvite: sinon.stub().resolves({
- invite: {
- email: ctx.user.email,
- token: 'token123',
- inviterName: ctx.user_email,
- },
- subscription: ctx.subscription,
- }),
- },
- }
- ctx.SubscriptionLocator = {
- promises: {
- hasSSOEnabled: sinon.stub().resolves(true),
- getUsersSubscription: sinon.stub().resolves(),
- },
- }
- ctx.ErrorController = { notFound: sinon.stub() }
- ctx.SessionManager = {
- getLoggedInUserId(session) {
- return session.user?._id
- },
- getSessionUser(session) {
- return session.user
- },
- }
- ctx.UserAuditLogHandler = {
- promises: {
- addEntry: sinon.stub().resolves(),
- },
- }
- ctx.UserGetter = {
- promises: {
- getUser: sinon.stub().resolves(ctx.user),
- getUserByMainEmail: sinon.stub().resolves(ctx.user),
- getUserByAnyEmail: sinon.stub().resolves(ctx.user),
- },
- }
- ctx.EmailHandler = {
- sendDeferredEmail: sinon.stub().resolves(),
- }
- ctx.RateLimiter = {
- RateLimiter: class {},
- }
- vi.doMock(
- '../../../../app/src/Features/Subscription/TeamInvitesHandler',
- () => ({
- default: ctx.TeamInvitesHandler,
- })
- )
- vi.doMock(
- '../../../../app/src/Features/Authentication/SessionManager',
- () => ({
- default: ctx.SessionManager,
- })
- )
- vi.doMock(
- '../../../../app/src/Features/Subscription/SubscriptionLocator',
- () => ({
- default: ctx.SubscriptionLocator,
- })
- )
- vi.doMock('../../../../app/src/Features/User/UserAuditLogHandler', () => ({
- default: ctx.UserAuditLogHandler,
- }))
- vi.doMock('../../../../app/src/Features/Errors/ErrorController', () => ({
- default: ctx.ErrorController,
- }))
- vi.doMock('../../../../app/src/Features/User/UserGetter', () => ({
- default: ctx.UserGetter,
- }))
- vi.doMock('../../../../app/src/Features/Email/EmailHandler', () => ({
- default: ctx.EmailHandler,
- }))
- vi.doMock(
- '../../../../app/src/infrastructure/RateLimiter',
- () => ctx.RateLimiter
- )
- vi.doMock('../../../../app/src/infrastructure/Modules', () => ({
- default: (ctx.Modules = {
- promises: {
- hooks: {
- fire: sinon.stub().resolves([]),
- },
- },
- }),
- }))
- vi.doMock(
- '../../../../app/src/Features/SplitTests/SplitTestHandler',
- () => ({
- default: (ctx.SplitTestHandler = {
- promises: {
- getAssignment: sinon.stub().resolves({}),
- },
- }),
- })
- )
- ctx.Controller = (await import(modulePath)).default
- })
- describe('acceptInvite', function () {
- it('should add an audit log entry', async function (ctx) {
- await new Promise(resolve => {
- ctx.req.params.token = 'foo'
- ctx.req.session.user = ctx.user
- const res = {
- json: () => {
- sinon.assert.calledWith(
- ctx.UserAuditLogHandler.promises.addEntry,
- ctx.user._id,
- 'accept-group-invitation',
- ctx.user._id,
- ctx.req.ip,
- { subscriptionId: ctx.subscriptionId }
- )
- resolve()
- },
- }
- ctx.Controller.acceptInvite(ctx.req, res)
- })
- })
- })
- describe('viewInvite', function () {
- const req = {
- params: { token: 'token123' },
- query: {},
- session: {
- user: { _id: 'user123' },
- },
- }
- describe('hasIndividualPaidSubscription', function () {
- it('is true for personal subscription', async function (ctx) {
- await new Promise(resolve => {
- ctx.SubscriptionLocator.promises.getUsersSubscription.resolves({
- recurlySubscription_id: 'subscription123',
- groupPlan: false,
- })
- const res = {
- render: (template, data) => {
- expect(data.hasIndividualPaidSubscription).to.be.true
- resolve()
- },
- }
- ctx.Controller.viewInvite(req, res)
- })
- })
- it('is true for group subscriptions', async function (ctx) {
- await new Promise(resolve => {
- ctx.SubscriptionLocator.promises.getUsersSubscription.resolves({
- recurlySubscription_id: 'subscription123',
- groupPlan: true,
- })
- const res = {
- render: (template, data) => {
- expect(data.hasIndividualPaidSubscription).to.be.false
- resolve()
- },
- }
- ctx.Controller.viewInvite(req, res)
- })
- })
- it('is false for canceled subscriptions', async function (ctx) {
- await new Promise(resolve => {
- ctx.SubscriptionLocator.promises.getUsersSubscription.resolves({
- recurlySubscription_id: 'subscription123',
- groupPlan: false,
- recurlyStatus: {
- state: 'canceled',
- },
- })
- const res = {
- render: (template, data) => {
- expect(data.hasIndividualPaidSubscription).to.be.false
- resolve()
- },
- }
- ctx.Controller.viewInvite(req, res)
- })
- })
- })
- describe('when user is logged out', function () {
- it('renders logged out invite page', async function (ctx) {
- await new Promise(resolve => {
- const res = {
- render: (template, data) => {
- expect(template).to.equal('subscriptions/team/invite_logged_out')
- expect(data.groupSSOActive).to.be.undefined
- resolve()
- },
- }
- ctx.Controller.viewInvite(
- { params: { token: 'token123' }, session: {} },
- res
- )
- })
- })
- it('includes groupSSOActive flag when the group has SSO enabled', async function (ctx) {
- await new Promise(resolve => {
- ctx.Modules.promises.hooks.fire = sinon.stub().resolves([true])
- const res = {
- render: (template, data) => {
- expect(data.groupSSOActive).to.be.true
- resolve()
- },
- }
- ctx.Controller.viewInvite(
- { params: { token: 'token123' }, session: {} },
- res
- )
- })
- })
- })
- it('renders the view', async function (ctx) {
- await new Promise(resolve => {
- const res = {
- render: template => {
- expect(template).to.equal('subscriptions/team/invite')
- resolve()
- },
- }
- ctx.Controller.viewInvite(req, res)
- })
- })
- })
- })
|