diff --git a/services/web/frontend/js/features/project-list/components/table/project-tools/buttons/project-tools-more-dropdown-button.tsx b/services/web/frontend/js/features/project-list/components/table/project-tools/buttons/project-tools-more-dropdown-button.tsx
index 0d7ba75283..656637b290 100644
--- a/services/web/frontend/js/features/project-list/components/table/project-tools/buttons/project-tools-more-dropdown-button.tsx
+++ b/services/web/frontend/js/features/project-list/components/table/project-tools/buttons/project-tools-more-dropdown-button.tsx
@@ -17,12 +17,8 @@ function ProjectToolsMoreDropdownButton() {
{t('more')}
-
-
-
-
-
-
+
+
)
diff --git a/services/web/scripts/recurly/collect_paypal_past_due_invoice.mjs b/services/web/scripts/recurly/collect_paypal_past_due_invoice.mjs
index 2bf827bae8..7f058b800b 100644
--- a/services/web/scripts/recurly/collect_paypal_past_due_invoice.mjs
+++ b/services/web/scripts/recurly/collect_paypal_past_due_invoice.mjs
@@ -25,7 +25,7 @@ const handleAPIError = async (source, id, error) => {
* USERS_COLLECTED: string[],
* }>}
*/
-const main = async () => {
+export async function collectPastDueInvoices(DRY_RUN = false) {
const attemptInvoiceCollection = async invoice => {
const isPaypal = await isAccountUsingPaypal(invoice)
@@ -84,8 +84,6 @@ const main = async () => {
}
}
- const argv = minimist(process.argv.slice(2))
- const DRY_RUN = argv.n !== undefined
const INVOICES_COLLECTED = []
const INVOICES_COLLECTED_SUCCESS = []
const USERS_COLLECTED = []
@@ -105,19 +103,22 @@ const main = async () => {
}
} finally {
logger.info(
- `DONE (DRY_RUN=${DRY_RUN}). ${INVOICES_COLLECTED.length} invoices collection attempts for ${USERS_COLLECTED.length} users. ${INVOICES_COLLECTED_SUCCESS.length} successful collections`
- )
- console.dir(
{
INVOICES_COLLECTED,
INVOICES_COLLECTED_SUCCESS,
USERS_COLLECTED,
},
- { maxArrayLength: null }
+ `DONE (DRY_RUN=${DRY_RUN}). ${INVOICES_COLLECTED.length} invoices collection attempts for ${USERS_COLLECTED.length} users. ${INVOICES_COLLECTED_SUCCESS.length} successful collections`
)
}
}
+async function main() {
+ const argv = minimist(process.argv.slice(2))
+ const DRY_RUN = argv.n !== undefined
+ await collectPastDueInvoices(DRY_RUN)
+}
+
if (fileURLToPath(import.meta.url) === process.argv[1]) {
try {
await scriptRunner(main)
@@ -128,5 +129,3 @@ if (fileURLToPath(import.meta.url) === process.argv[1]) {
process.exit(1)
}
}
-
-export default { main }
diff --git a/services/web/test/acceptance/src/CollectPayPalPastDueInvoiceTest.mjs b/services/web/test/acceptance/src/CollectPayPalPastDueInvoiceTest.mjs
index db75aa6a47..6e44f0e041 100644
--- a/services/web/test/acceptance/src/CollectPayPalPastDueInvoiceTest.mjs
+++ b/services/web/test/acceptance/src/CollectPayPalPastDueInvoiceTest.mjs
@@ -2,12 +2,10 @@ import sinon from 'sinon'
import chai, { expect } from 'chai'
import chaiAsPromised from 'chai-as-promised'
import sinonChai from 'sinon-chai'
-import CollectPaypalPastDueInvoice from '../../../scripts/recurly/collect_paypal_past_due_invoice.mjs'
+import { collectPastDueInvoices } from '../../../scripts/recurly/collect_paypal_past_due_invoice.mjs'
import RecurlyWrapper from '../../../app/src/Features/Subscription/RecurlyWrapper.js'
import OError from '@overleaf/o-error'
-const { main } = CollectPaypalPastDueInvoice
-
chai.use(chaiAsPromised)
chai.use(sinonChai)
@@ -213,7 +211,7 @@ describe('CollectPayPalPastDueInvoice', function () {
it('collects one valid invoice', async function () {
fakeApiRequests([200])
- const r = await main()
+ const r = await collectPastDueInvoices()
expect(r).to.eql({
INVOICES_COLLECTED: [200],
INVOICES_COLLECTED_SUCCESS: [200],
@@ -224,7 +222,7 @@ describe('CollectPayPalPastDueInvoice', function () {
it('collects several pages', async function () {
// 10 invoices, from 200 to 209
fakeApiRequests([...Array(10).keys()].map(i => i + 200))
- const r = await main()
+ const r = await collectPastDueInvoices()
expect(r).to.eql({
INVOICES_COLLECTED: [200, 201, 202, 203, 204, 205, 206, 207, 208, 209],
@@ -253,7 +251,7 @@ describe('CollectPayPalPastDueInvoice', function () {
it("resolves when no invoices are processed so we don't fail in staging", async function () {
fakeApiRequests([404])
- const r = await main()
+ const r = await collectPastDueInvoices()
expect(r).to.eql({
INVOICES_COLLECTED: [404],
INVOICES_COLLECTED_SUCCESS: [],
@@ -263,7 +261,7 @@ describe('CollectPayPalPastDueInvoice', function () {
it('doesnt reject when there are no invoices', async function () {
fakeApiRequests([])
- const r = await main()
+ const r = await collectPastDueInvoices()
expect(r).to.eql({
INVOICES_COLLECTED: [],
INVOICES_COLLECTED_SUCCESS: [],
@@ -273,7 +271,7 @@ describe('CollectPayPalPastDueInvoice', function () {
it("resolves when collection is partially successful so we don't fail in prod", async function () {
fakeApiRequests([200, 404])
- const r = await main()
+ const r = await collectPastDueInvoices()
expect(r).to.eql({
INVOICES_COLLECTED: [200, 404],
INVOICES_COLLECTED_SUCCESS: [200],
diff --git a/services/web/test/frontend/cut-log-noise.ts b/services/web/test/frontend/cut-log-noise.ts
index feba2e2383..61432d388d 100644
--- a/services/web/test/frontend/cut-log-noise.ts
+++ b/services/web/test/frontend/cut-log-noise.ts
@@ -8,3 +8,8 @@ if (process.env.VERBOSE_LOGGING === 'true') {
debugConsole.warn = () => {}
debugConsole.error = () => {}
}
+
+before(function () {
+ // Range.getClientRects doesn't exist yet in jsdom
+ window.Range.prototype.getClientRects = () => [] as any as DOMRectList
+})
diff --git a/services/web/test/frontend/features/project-list/components/current-plan-widget.test.tsx b/services/web/test/frontend/features/project-list/components/current-plan-widget.test.tsx
index 00a8593169..4ad1bc7443 100644
--- a/services/web/test/frontend/features/project-list/components/current-plan-widget.test.tsx
+++ b/services/web/test/frontend/features/project-list/components/current-plan-widget.test.tsx
@@ -340,8 +340,6 @@ describe('', function () {
'/learn/how-to/Overleaf_premium_features'
)
- fireEvent.click(links[0])
-
window.metaAttributesCache.delete('ol-usersBestSubscription')
})
}
diff --git a/services/web/test/frontend/features/source-editor/extensions/scroll-position.test.ts b/services/web/test/frontend/features/source-editor/extensions/scroll-position.test.ts
index d5b9b68781..953982c0ed 100644
--- a/services/web/test/frontend/features/source-editor/extensions/scroll-position.test.ts
+++ b/services/web/test/frontend/features/source-editor/extensions/scroll-position.test.ts
@@ -37,15 +37,10 @@ describe('CodeMirror scroll position extension', function () {
sinon
.stub(HTMLElement.prototype, 'getBoundingClientRect')
.returns({ top: 100, left: 0, right: 500, bottom: 200 } as DOMRect)
-
- // Range.getClientRects doesn't exist yet in jsdom
- window.Range.prototype.getClientRects = sinon.stub().returns([])
})
afterEach(function () {
sinon.restore()
- // @ts-ignore
- delete window.Range.prototype.getClientRects
})
it('stores scroll position when the view is destroyed', async function () {