Skip to content

Commit

Permalink
#37066 preundeploy only delete subscriptions and extensions with matc…
Browse files Browse the repository at this point in the history
…hing url and topic
  • Loading branch information
mbe1987 committed Sep 9, 2024
1 parent 75eb7b7 commit a71e92b
Show file tree
Hide file tree
Showing 13 changed files with 173 additions and 51 deletions.
26 changes: 11 additions & 15 deletions paypal-commercetools-events/src/connector/actions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ByProjectKeyRequestBuilder } from '@commercetools/platform-sdk/dist/declarations/src/generated/client/by-project-key-request-builder';
import { findMatchingSubscription } from '../service/commercetools.service';

const PAYPAL_PARCEL_ADDED_TO_DELIVERY_KEY = 'paypal-parcelAddedToDelivery';

Expand Down Expand Up @@ -31,22 +32,17 @@ export async function createParcelAddedToDeliverySubscription(
}

export async function deleteParcelAddedToDeliverySubscription(
apiRoot: ByProjectKeyRequestBuilder
apiRoot: ByProjectKeyRequestBuilder,
topicName?: string,
projectId?: string
): Promise<void> {
const {
body: { results: subscriptions },
} = await apiRoot
.subscriptions()
.get({
queryArgs: {
where: `key = "${PAYPAL_PARCEL_ADDED_TO_DELIVERY_KEY}"`,
},
})
.execute();

if (subscriptions.length > 0) {
const subscription = subscriptions[0];

const subscription = await findMatchingSubscription(
apiRoot,
PAYPAL_PARCEL_ADDED_TO_DELIVERY_KEY,
topicName,
projectId
);
if (subscription) {
await apiRoot
.subscriptions()
.withKey({ key: PAYPAL_PARCEL_ADDED_TO_DELIVERY_KEY })
Expand Down
19 changes: 15 additions & 4 deletions paypal-commercetools-events/src/connector/pre-undeploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,28 @@ import dotenv from 'dotenv';
dotenv.config();

import { createApiRoot } from '../client/create.client';
import { assertError } from '../utils/assert.utils';
import { assertError, assertString } from '../utils/assert.utils';
import { deleteParcelAddedToDeliverySubscription } from './actions';
import { readConfiguration } from '../utils/config.utils';

const CONNECT_GCP_TOPIC_NAME_KEY = 'CONNECT_GCP_TOPIC_NAME';
const CONNECT_GCP_PROJECT_ID_KEY = 'CONNECT_GCP_PROJECT_ID';
async function preUndeploy(properties: Map<string, unknown>): Promise<void> {
const topicName = properties.get(CONNECT_GCP_TOPIC_NAME_KEY);
const projectId = properties.get(CONNECT_GCP_PROJECT_ID_KEY);

assertString(topicName, CONNECT_GCP_TOPIC_NAME_KEY);
assertString(projectId, CONNECT_GCP_PROJECT_ID_KEY);

async function preUndeploy(): Promise<void> {
const apiRoot = createApiRoot();
await deleteParcelAddedToDeliverySubscription(apiRoot);
await deleteParcelAddedToDeliverySubscription(apiRoot, topicName, projectId);
}

async function run(): Promise<void> {
try {
await preUndeploy();
readConfiguration(true);
const properties = new Map(Object.entries(process.env));
await preUndeploy(properties);
} catch (error) {
assertError(error);
process.stderr.write(`Post-undeploy failed: ${error.message}\n`);
Expand Down
31 changes: 30 additions & 1 deletion paypal-commercetools-events/src/service/commercetools.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Order, Payment } from '@commercetools/platform-sdk';
import { Order, Payment, Subscription } from '@commercetools/platform-sdk';
import { createApiRoot } from '../client/create.client';
import { ByProjectKeyRequestBuilder } from '@commercetools/platform-sdk/dist/declarations/src/generated/client/by-project-key-request-builder';

export const getOrderById = async (
orderId: string
Expand Down Expand Up @@ -30,3 +31,31 @@ export const getPaymentById = async (
.execute();
return response.body;
};

export const findMatchingSubscription = async (
apiRoot: ByProjectKeyRequestBuilder,
key: string,
topic?: string,
projectId?: string
): Promise<Subscription | undefined> => {
const {
body: { results: subscriptions },
} = await apiRoot
.subscriptions()
.get({
queryArgs: {
where: `key = "${key}"`,
},
})
.execute();
if (!topic && !projectId) {
return subscriptions.length > 0 ? subscriptions[0] : undefined;
}
const fittingSubscriptions = subscriptions.filter(
(subscription) =>
subscription.destination.type === 'GoogleCloudPubSub' &&
subscription.destination.topic === topic &&
subscription.destination.projectId === projectId
);
return fittingSubscriptions.length > 0 ? fittingSubscriptions[0] : undefined;
};
34 changes: 31 additions & 3 deletions paypal-commercetools-events/tests/actions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,19 @@ import {
describe('Testing actions', () => {
test('add extension', async () => {
const apiRequest: any = {
execute: jest.fn(() => ({ body: { results: [{}] } })),
execute: jest.fn(() => ({
body: {
results: [
{
destination: {
type: 'GoogleCloudPubSub',
topic: 'old lorem ipsum',
projectId: 'old lorem ipsum',
},
},
],
},
})),
};
const apiRoot: any = {
subscriptions: jest.fn(() => apiRoot),
Expand All @@ -29,15 +41,31 @@ describe('Testing actions', () => {

test('delete extension', async () => {
const apiRequest: any = {
execute: jest.fn(() => ({ body: { results: [{}] } })),
execute: jest.fn(() => ({
body: {
results: [
{
destination: {
type: 'GoogleCloudPubSub',
topic: 'topic',
projectId: 'projectId',
},
},
],
},
})),
};
const apiRoot: any = {
subscriptions: jest.fn(() => apiRoot),
withKey: jest.fn(() => apiRoot),
delete: jest.fn(() => apiRequest),
get: jest.fn(() => apiRequest),
};
await deleteParcelAddedToDeliverySubscription(apiRoot);
await deleteParcelAddedToDeliverySubscription(
apiRoot,
'topic',
'projectId'
);
expect(apiRoot.get).toBeCalledTimes(1);
expect(apiRoot.delete).toBeCalledTimes(1);
expect(apiRequest.execute).toBeCalledTimes(2);
Expand Down
24 changes: 9 additions & 15 deletions paypal-commercetools-extension/src/connector/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
GRAPHQL_CUSTOMOBJECT_CONTAINER_NAME,
GRAPHQL_CUSTOMOBJECT_KEY_NAME,
} from '../constants';
import { findMatchingExtension } from '../service/commercetools.service';

export const PAYPAL_PAYMENT_EXTENSION_KEY = 'paypal-payment-extension';
export const PAYPAL_CUSTOMER_EXTENSION_KEY = 'paypal-customer-extension';
Expand Down Expand Up @@ -143,22 +144,15 @@ export async function createCustomerUpdateExtension(

export async function deleteExtension(
apiRoot: ByProjectKeyRequestBuilder,
extensionKey: string
extensionKey: string,
applicationUrl: string
): Promise<void> {
const {
body: { results: extensions },
} = await apiRoot
.extensions()
.get({
queryArgs: {
where: `key = "${extensionKey}"`,
},
})
.execute();

if (extensions.length > 0) {
const extension = extensions[0];

const extension = await findMatchingExtension(
apiRoot,
extensionKey,
applicationUrl
);
if (extension) {
await apiRoot
.extensions()
.withKey({ key: extensionKey })
Expand Down
19 changes: 14 additions & 5 deletions paypal-commercetools-extension/src/connector/pre-undeploy.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
import dotenv from 'dotenv';

dotenv.config();

import { createApiRoot } from '../client/create.client';
import { deleteWebhook } from '../service/paypal.service';
import { assertError } from '../utils/assert.utils';
import { assertError, assertString } from '../utils/assert.utils';
import { readConfiguration } from '../utils/config.utils';
import { logger } from '../utils/logger.utils';
import {
deleteExtension,
PAYPAL_CUSTOMER_EXTENSION_KEY,
PAYPAL_PAYMENT_EXTENSION_KEY,
} from './actions';

async function preUndeploy(): Promise<void> {
const CONNECT_APPLICATION_URL_KEY = 'CONNECT_SERVICE_URL';

async function preUndeploy(properties: Map<string, unknown>): Promise<void> {
const apiRoot = createApiRoot();
await deleteExtension(apiRoot, PAYPAL_PAYMENT_EXTENSION_KEY);
await deleteExtension(apiRoot, PAYPAL_CUSTOMER_EXTENSION_KEY);
const applicationUrl = properties.get(CONNECT_APPLICATION_URL_KEY);
assertString(applicationUrl, CONNECT_APPLICATION_URL_KEY);

await deleteExtension(apiRoot, PAYPAL_PAYMENT_EXTENSION_KEY, applicationUrl);
await deleteExtension(apiRoot, PAYPAL_CUSTOMER_EXTENSION_KEY, applicationUrl);
await deleteWebhook();
}

async function run(): Promise<void> {
try {
await preUndeploy();
readConfiguration(true);
const properties = new Map(Object.entries(process.env));
await preUndeploy(properties);
} catch (error) {
assertError(error);
logger.error(error.message);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import {
Cart,
CustomerUpdateAction,
Extension,
Payment,
PaymentAddTransactionAction,
PaymentChangeTransactionStateAction,
PaymentUpdateAction,
Transaction,
TransactionDraft,
} from '@commercetools/platform-sdk';
import { ByProjectKeyRequestBuilder } from '@commercetools/platform-sdk/dist/declarations/src/generated/client/by-project-key-request-builder';
import { createApiRoot } from '../client/create.client';
import { PAYPAL_CUSTOMER_TYPE_KEY } from '../connector/actions';
import CustomError from '../errors/custom.error';
Expand Down Expand Up @@ -317,3 +319,27 @@ export const getPayPalUserId = async (
const user = await getCustomerByCart(cart);
return user?.custom?.fields?.PayPalUserId;
};

export async function findMatchingExtension(
apiRoot: ByProjectKeyRequestBuilder,
extensionKey: string,
applicationUrl: string
): Promise<Extension | undefined> {
const {
body: { results: extensions },
} = await apiRoot
.extensions()
.get({
queryArgs: {
where: `key = "${extensionKey}"`,
},
})
.execute();

const matchingExtensions = extensions.filter(
(extension) =>
extension.destination.type === 'HTTP' &&
extension.destination.url === applicationUrl
);
return matchingExtensions.length > 0 ? matchingExtensions[0] : undefined;
}
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,9 @@ export const handleGetPaymentTokensRequest = async (
);
try {
const response = await getPaymentTokens(customerId);
response.payment_tokens = response.payment_tokens?.filter(({payment_source}) => payment_source && !('apple_pay' in payment_source));
response.payment_tokens = response.payment_tokens?.filter(
({ payment_source }) => payment_source && !('apple_pay' in payment_source)
);
logger.info(JSON.stringify(response));
return updateActions.concat(
handleCustomerResponse('getPaymentTokens', response)
Expand Down
2 changes: 1 addition & 1 deletion paypal-commercetools-extension/tests/.env.test
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ CTP_REGION=europe-west1.gcp
PAYPAL_CLIENT_ID=AeqAtOJS_O82SmxDaKR5TjDNS9r27ATjqsIjDakNOMu4WEVMDJrkp2qMzgd3h1RvKmNsSheFxnbC8wEF
PAYPAL_CLIENT_SECRET=EAVrwQUWGRpxEulrKaRNxBTzxNtPQo7DMRlDQRKMWm2PGirgbOZa55cObkuXDY0VQU4kUJm6mH6bBrsq
PAYPAL_ENVIRONMENT=Sandbox
CONNECT_SERVICE_URL=
CONNECT_SERVICE_URL=https://lorem.ipsum
20 changes: 18 additions & 2 deletions paypal-commercetools-extension/tests/actions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,31 @@ describe('Testing actions', () => {

test('delete extension', async () => {
const apiRequest: any = {
execute: jest.fn(() => ({ body: { results: [{}] } })),
execute: jest.fn(() => ({
body: {
results: [
{
key: PAYPAL_PAYMENT_EXTENSION_KEY,
destination: {
type: 'HTTP',
url: 'https://lorem.ipsum',
},
},
],
},
})),
};
const apiRoot: any = {
extensions: jest.fn(() => apiRoot),
withKey: jest.fn(() => apiRoot),
delete: jest.fn(() => apiRequest),
get: jest.fn(() => apiRequest),
};
await deleteExtension(apiRoot, PAYPAL_PAYMENT_EXTENSION_KEY);
await deleteExtension(
apiRoot,
PAYPAL_PAYMENT_EXTENSION_KEY,
'https://lorem.ipsum'
);
expect(apiRoot.get).toBeCalledTimes(1);
expect(apiRoot.delete).toBeCalledTimes(1);
expect(apiRequest.execute).toBeCalledTimes(2);
Expand Down
2 changes: 1 addition & 1 deletion paypal-commercetools-extension/tests/map.utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { TypedMoney } from '@commercetools/platform-sdk';
import { describe, test } from '@jest/globals';
import { RefundStatusEnum } from '../src/paypal/payments_api';
import {
mapCommercetoolsCarrierToPayPalCarrier,
mapCommercetoolsMoneyToPayPalMoney,
mapPayPalMoneyToCommercetoolsMoney,
mapPayPalPaymentSourceToCommercetoolsMethodInfo,
mapPayPalRefundStatusToCommercetoolsTransactionState,
} from '../src/utils/map.utils';
import { RefundStatusEnum } from '../src/paypal/payments_api';

const refundStatusEnum = (status: string) => {
return status as RefundStatusEnum;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { PaymentReference } from '@commercetools/platform-sdk';
import { describe, expect, test } from '@jest/globals';
import { randomUUID } from 'crypto';
import validator from 'validator';
import { Capture, Order, Refund } from '../src/paypal/checkout_api';
import { PayPalSettings, UpdateActions } from '../src/types/index.types';
import { logger } from '../src/utils/logger.utils';
import validator from 'validator';
import { randomUUID } from 'crypto';

let configMock: any;

Expand Down
13 changes: 12 additions & 1 deletion paypal-commercetools-extension/tests/pre-undeploy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,18 @@ let apiRequest: any = undefined;
let apiRoot: any = undefined;
const mockConfigModule = () => {
apiRequest = {
execute: jest.fn(() => ({ body: { results: [{}] } })),
execute: jest.fn(() => ({
body: {
results: [
{
destination: {
type: 'HTTP',
url: 'https://lorem.ipsum',
},
},
],
},
})),
};
apiRoot = {
extensions: jest.fn(() => apiRoot),
Expand Down

0 comments on commit a71e92b

Please sign in to comment.