|
|
@@ -0,0 +1,351 @@
|
|
|
+import '../../../helpers/bootstrap-5'
|
|
|
+import AddSeats, {
|
|
|
+ MAX_NUMBER_OF_USERS,
|
|
|
+} from '@/features/group-management/components/add-seats/add-seats'
|
|
|
+import { SplitTestProvider } from '@/shared/context/split-test-context'
|
|
|
+
|
|
|
+describe('<AddSeats />', function () {
|
|
|
+ beforeEach(function () {
|
|
|
+ this.totalLicenses = 5
|
|
|
+
|
|
|
+ cy.window().then(win => {
|
|
|
+ win.metaAttributesCache.set('ol-groupName', 'My Awesome Team')
|
|
|
+ win.metaAttributesCache.set('ol-subscriptionId', '123')
|
|
|
+ win.metaAttributesCache.set(
|
|
|
+ 'ol-subscriptionEndsAt',
|
|
|
+ '2025-01-01T12:00:00.000Z'
|
|
|
+ )
|
|
|
+ win.metaAttributesCache.set('ol-totalLicenses', this.totalLicenses)
|
|
|
+ })
|
|
|
+
|
|
|
+ cy.mount(
|
|
|
+ <SplitTestProvider>
|
|
|
+ <AddSeats />
|
|
|
+ </SplitTestProvider>
|
|
|
+ )
|
|
|
+
|
|
|
+ cy.findByRole('button', { name: /add users/i })
|
|
|
+ cy.findByTestId('add-more-users-group-form')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('renders the back button', function () {
|
|
|
+ cy.findByTestId('group-heading').within(() => {
|
|
|
+ cy.findByRole('button', { name: /back to subscription/i }).should(
|
|
|
+ 'have.attr',
|
|
|
+ 'href',
|
|
|
+ '/user/subscription'
|
|
|
+ )
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ it('shows the group name', function () {
|
|
|
+ cy.findByTestId('group-heading').within(() => {
|
|
|
+ cy.findByRole('heading', { name: 'My Awesome Team' })
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ it('shows the "Add more users" label', function () {
|
|
|
+ cy.findByText(/add more users/i)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('shows the maximum supported users', function () {
|
|
|
+ cy.findByText(
|
|
|
+ new RegExp(
|
|
|
+ `your current plan supports up to ${this.totalLicenses} users`,
|
|
|
+ 'i'
|
|
|
+ )
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ it('shows instructions on how to reduce users on a plan', function () {
|
|
|
+ cy.contains(
|
|
|
+ /if you want to reduce the number of users on your plan, please contact customer support/i
|
|
|
+ ).within(() => {
|
|
|
+ cy.findByRole('link', { name: /contact customer support/i }).should(
|
|
|
+ 'have.attr',
|
|
|
+ 'href',
|
|
|
+ '/contact'
|
|
|
+ )
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ it('shows the "Upgrade my plan" link', function () {
|
|
|
+ cy.findByRole('link', { name: /upgrade my plan/i }).should(
|
|
|
+ 'have.attr',
|
|
|
+ 'href',
|
|
|
+ '/user/subscription/group/upgrade-subscription'
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ it('renders the cancel button', function () {
|
|
|
+ cy.findByRole('button', { name: /cancel/i }).should(
|
|
|
+ 'have.attr',
|
|
|
+ 'href',
|
|
|
+ '/user/subscription'
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ describe('cost summary', function () {
|
|
|
+ beforeEach(function () {
|
|
|
+ cy.findByLabelText(/how many users do you want to add/i).as('input')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('shows the title', function () {
|
|
|
+ cy.findByTestId('cost-summary').within(() => {
|
|
|
+ cy.findByText(/cost summary/i)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ describe('shows default content when', function () {
|
|
|
+ afterEach(function () {
|
|
|
+ cy.findByTestId('cost-summary').within(() => {
|
|
|
+ cy.findByText(
|
|
|
+ /enter the number of users you’d like to add to see the cost breakdown/i
|
|
|
+ )
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ it('leaves input empty', function () {
|
|
|
+ cy.get('@input').should('have.value', '')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('fills in a non-numeric value', function () {
|
|
|
+ cy.get('@input').type('ab')
|
|
|
+ cy.findByText(/value must be a number/i)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('fills in a decimal value', function () {
|
|
|
+ cy.get('@input').type('1.5')
|
|
|
+ cy.findByText(/value must be a whole number/i)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('fills in a "0" value', function () {
|
|
|
+ cy.get('@input').type('0')
|
|
|
+ cy.findByText(/value must be at least 1/i)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('fills in a value and clears the input', function () {
|
|
|
+ cy.get('@input').type('a{backspace}')
|
|
|
+ cy.get('@input').should('have.text', '')
|
|
|
+ cy.findByText(/this field is required/i)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ describe('entered more than the maximum allowed number of users', function () {
|
|
|
+ beforeEach(function () {
|
|
|
+ this.numberOfUsersExceedingMaxLimit = MAX_NUMBER_OF_USERS + 1
|
|
|
+
|
|
|
+ cy.get('@input').type(this.numberOfUsersExceedingMaxLimit.toString())
|
|
|
+ cy.findByRole('button', { name: /add users/i }).should('not.exist')
|
|
|
+ cy.findByRole('button', { name: /send request/i }).as('sendRequestBtn')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('renders a notification', function () {
|
|
|
+ cy.findByTestId('cost-summary').should('not.exist')
|
|
|
+ cy.findByRole('alert').should(
|
|
|
+ 'contain.text',
|
|
|
+ `If you want more than ${MAX_NUMBER_OF_USERS} users on your plan, we need to add them for you. Just click Send request below and we’ll be happy to help.`
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ describe('request', function () {
|
|
|
+ afterEach(function () {
|
|
|
+ cy.findByRole('button', { name: /go to subscriptions/i }).should(
|
|
|
+ 'have.attr',
|
|
|
+ 'href',
|
|
|
+ '/user/subscription'
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ function makeRequest(statusCode: number, adding: string) {
|
|
|
+ cy.intercept(
|
|
|
+ 'POST',
|
|
|
+ '/user/subscription/group/add-users/sales-contact-form',
|
|
|
+ {
|
|
|
+ statusCode,
|
|
|
+ }
|
|
|
+ ).as('addUsersRequest')
|
|
|
+ cy.get('@sendRequestBtn').click()
|
|
|
+ cy.get('@addUsersRequest').its('request.body').should('deep.equal', {
|
|
|
+ adding,
|
|
|
+ })
|
|
|
+ cy.findByTestId('add-more-users-group-form').should('not.exist')
|
|
|
+ }
|
|
|
+
|
|
|
+ it('sends a request that succeeds', function () {
|
|
|
+ makeRequest(204, this.numberOfUsersExceedingMaxLimit.toString())
|
|
|
+ cy.findByTestId('title').should(
|
|
|
+ 'contain.text',
|
|
|
+ 'We’ve got your request'
|
|
|
+ )
|
|
|
+ cy.findByText(/our team will get back to you shortly/i)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('sends a request that fails', function () {
|
|
|
+ makeRequest(400, this.numberOfUsersExceedingMaxLimit.toString())
|
|
|
+ cy.findByTestId('title').should(
|
|
|
+ 'contain.text',
|
|
|
+ 'Something went wrong'
|
|
|
+ )
|
|
|
+ cy.contains(
|
|
|
+ /it looks like that didn’t work. You can try again or get in touch with our Support team for more help/i
|
|
|
+ ).within(() => {
|
|
|
+ cy.findByRole('link', { name: /get in touch/i }).should(
|
|
|
+ 'have.attr',
|
|
|
+ 'href',
|
|
|
+ '/contact'
|
|
|
+ )
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ describe('entered less than the maximum allowed number of users', function () {
|
|
|
+ beforeEach(function () {
|
|
|
+ this.adding = 1
|
|
|
+
|
|
|
+ cy.findByRole('button', { name: /add users/i }).as('addUsersBtn')
|
|
|
+ cy.findByRole('button', { name: /send request/i }).should('not.exist')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('renders the preview data', function () {
|
|
|
+ this.body = {
|
|
|
+ change: {
|
|
|
+ type: 'add-on-update',
|
|
|
+ addOn: {
|
|
|
+ code: 'additional-license',
|
|
|
+ quantity: this.totalLicenses + this.adding,
|
|
|
+ prevQuantity: this.totalLicenses,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ currency: 'USD',
|
|
|
+ immediateCharge: {
|
|
|
+ subtotal: 100,
|
|
|
+ tax: 20,
|
|
|
+ total: 120,
|
|
|
+ },
|
|
|
+ nextInvoice: {
|
|
|
+ date: '2025-12-01T00:00:00.000Z',
|
|
|
+ plan: {
|
|
|
+ name: 'Overleaf Standard Group',
|
|
|
+ amount: 0,
|
|
|
+ },
|
|
|
+ subtotal: 895,
|
|
|
+ tax: {
|
|
|
+ rate: 0.2,
|
|
|
+ },
|
|
|
+ total: 1000,
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ cy.intercept('POST', '/user/subscription/group/add-users/preview', {
|
|
|
+ statusCode: 200,
|
|
|
+ body: this.body,
|
|
|
+ }).as('addUsersRequest')
|
|
|
+ cy.get('@input').type(this.adding.toString())
|
|
|
+
|
|
|
+ cy.findByTestId('cost-summary').within(() => {
|
|
|
+ cy.contains(
|
|
|
+ new RegExp(
|
|
|
+ `you’re adding ${this.adding} users to your plan giving you a total of ${this.body.change.addOn.quantity} users`,
|
|
|
+ 'i'
|
|
|
+ )
|
|
|
+ )
|
|
|
+
|
|
|
+ cy.findByTestId('plan').within(() => {
|
|
|
+ cy.findByText(
|
|
|
+ `${this.body.nextInvoice.plan.name} x ${this.adding} Seats`
|
|
|
+ )
|
|
|
+ cy.findByTestId('price').should(
|
|
|
+ 'have.text',
|
|
|
+ `$${this.body.immediateCharge.subtotal}.00`
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ cy.findByTestId('tax').within(() => {
|
|
|
+ cy.findByText(
|
|
|
+ new RegExp(
|
|
|
+ `sales tax · ${this.body.nextInvoice.tax.rate * 100}%`,
|
|
|
+ 'i'
|
|
|
+ )
|
|
|
+ )
|
|
|
+ cy.findByTestId('price').should(
|
|
|
+ 'have.text',
|
|
|
+ `$${this.body.immediateCharge.tax}.00`
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ cy.findByTestId('total').within(() => {
|
|
|
+ cy.findByText(/total due today/i)
|
|
|
+ cy.findByTestId('price').should(
|
|
|
+ 'have.text',
|
|
|
+ `$${this.body.immediateCharge.total}.00`
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ cy.findByText(
|
|
|
+ /we’ll charge you now for the cost of your additional users based on the remaining months of your current subscription/i
|
|
|
+ )
|
|
|
+ cy.findByText(
|
|
|
+ /after that, we’ll bill you \$1,000.00 \+ applicable taxes annually on December 1, unless you cancel/i
|
|
|
+ )
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ describe('request', function () {
|
|
|
+ afterEach(function () {
|
|
|
+ cy.findByRole('button', { name: /go to subscriptions/i }).should(
|
|
|
+ 'have.attr',
|
|
|
+ 'href',
|
|
|
+ '/user/subscription'
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ function makeRequest(statusCode: number, adding: string) {
|
|
|
+ cy.intercept('POST', '/user/subscription/group/add-users/create', {
|
|
|
+ statusCode,
|
|
|
+ }).as('addUsersRequest')
|
|
|
+ cy.get('@input').type(adding)
|
|
|
+ cy.get('@addUsersBtn').click()
|
|
|
+ cy.get('@addUsersRequest')
|
|
|
+ .its('request.body')
|
|
|
+ .should('deep.equal', {
|
|
|
+ adding: Number(adding),
|
|
|
+ })
|
|
|
+ cy.findByTestId('add-more-users-group-form').should('not.exist')
|
|
|
+ }
|
|
|
+
|
|
|
+ it('sends a request that succeeds', function () {
|
|
|
+ makeRequest(204, this.adding.toString())
|
|
|
+ cy.findByTestId('title').should(
|
|
|
+ 'contain.text',
|
|
|
+ 'You’ve added more users'
|
|
|
+ )
|
|
|
+ cy.findByText(/you’ve added more users to your subscription/i)
|
|
|
+ cy.findByRole('link', { name: /invite people/i }).should(
|
|
|
+ 'have.attr',
|
|
|
+ 'href',
|
|
|
+ '/manage/groups/123/members'
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ it('sends a request that fails', function () {
|
|
|
+ makeRequest(400, this.adding.toString())
|
|
|
+ cy.findByTestId('title').should(
|
|
|
+ 'contain.text',
|
|
|
+ 'Something went wrong'
|
|
|
+ )
|
|
|
+ cy.contains(
|
|
|
+ /it looks like that didn’t work. You can try again or get in touch with our Support team for more help/i
|
|
|
+ ).within(() => {
|
|
|
+ cy.findByRole('link', { name: /get in touch/i }).should(
|
|
|
+ 'have.attr',
|
|
|
+ 'href',
|
|
|
+ '/contact'
|
|
|
+ )
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
+})
|