Skip to content
This repository has been archived by the owner on Mar 13, 2021. It is now read-only.

Commit

Permalink
implement next day pickups
Browse files Browse the repository at this point in the history
  • Loading branch information
rkrauskopf committed Sep 15, 2020
1 parent 6cc2897 commit b6f6b70
Show file tree
Hide file tree
Showing 9 changed files with 532 additions and 4 deletions.
3 changes: 2 additions & 1 deletion src/core/test-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { logResults } from "./utils/log-helpers";
import { RateShipmentWithAllServices } from './test-app/tests/rate-shipment-with-all-services';
import { CancelShipment } from './test-app/tests/cancel-shipment';
import { SameDayPickup } from './test-app/tests/same-day-pickup';
import { NextDayPickup } from './test-app/tests/next-day-pickup';

interface TesOptions {
debug?: boolean;
Expand Down Expand Up @@ -156,7 +157,7 @@ function registerTestSuiteModules(app: SdkApp): RegisteredTestSuiteModules {
CreateShipmentWithInsurance,
CreateShipmentReturn
],
schedulePickup: [SameDayPickup],
schedulePickup: [SameDayPickup, NextDayPickup],
rateShipment: [
RateShipment,
RateShipmentWithAllServices
Expand Down
2 changes: 2 additions & 0 deletions src/core/test-app/runner/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { RateShipmentWithAllServicesConfigOptions } from './config/rate-shipment
import { CancelShipmentConfigOptions } from './config/cancel-shipment';
import { CreateShipmentReturnConfigOptions } from './config/create-shipment-return';
import { SameDayPickupConfigOptions } from './config/same-day-pickup';
import { NextDayPickupConfigOptions } from './config/next-day-pickup';

export interface TestsConfig {
// cancelPickups?: (TestOptions & TestOptions) | [TestOptions];
Expand All @@ -26,6 +27,7 @@ export interface TestsConfig {
rateShipment?: RateShipmentConfigOptions | [RateShipmentConfigOptions];
rateShipment_with_all_services?: RateShipmentWithAllServicesConfigOptions | [RateShipmentWithAllServicesConfigOptions];
schedulePickup_same_day?: SameDayPickupConfigOptions | [SameDayPickupConfigOptions];
schedulePickup_next_day?: NextDayPickupConfigOptions | [NextDayPickupConfigOptions];

// createShipment_multi_package?: TestOptions | [TestOptions];
// rateShipmentWithOneService?: RateShipmentConfigOptions | [RateShipmentConfigOptions];
Expand Down
33 changes: 33 additions & 0 deletions src/core/test-app/runner/config/next-day-pickup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {
TimeRangePOJO,
ContactInfoPOJO,
AddressPOJO,
WeightPOJO,
DimensionsPOJO,
} from "@shipengine/connect-sdk";
import { BaseTestConfigOptions } from "./base-test-config-options";


export type PickupPackageConfig = {
packagingName: string;
dimensions?: DimensionsPOJO;
weight?: WeightPOJO;
};

export type PickupShipmentConfig = {
deliveryServiceName: string;
packages: PickupPackageConfig[];
};

export interface NextDayPickupTestParams {
pickupServiceName: string;
deliveryServiceName: string;
address: AddressPOJO;
contact: ContactInfoPOJO;
timeWindow: TimeRangePOJO;
shipments: PickupShipmentConfig[];
}

export interface NextDayPickupConfigOptions
extends NextDayPickupTestParams,
BaseTestConfigOptions {}
25 changes: 23 additions & 2 deletions src/core/test-app/runner/validate-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import {
} from "@shipengine/connect-sdk/lib/internal/common";
import { NewLabel } from "@shipengine/connect-sdk/lib/internal/carriers/documents/new-label";
import { _internal, MonetaryValue } from "@shipengine/connect-sdk/lib/internal/common";
import { NewPackage } from "@shipengine/connect-sdk/lib/internal/carriers/packages/new-package";
import { PickupShipment } from '@shipengine/connect-sdk/lib/internal';

const joiOptions = {
abortEarly: false,
Expand Down Expand Up @@ -171,6 +169,25 @@ const SameDayPickupTestParamsSchema = Joi.object({
}
});

const NextDayPickupTestParamsSchema = Joi.object({
...baseTestParamValidations,
...{
pickupServiceName: Joi.string().optional(),
deliveryServiceName: Joi.string().optional(),
address: Address[_internal].schema.optional(),
contact: ContactInfo[_internal].schema.optional(),
timeWindow: TimeRange[_internal].schema.optional(),
shipments: Joi.object({
deliveryServiceName: Joi.string(),
packages: Joi.array().items(Joi.object({
packagingName: Joi.string(),
dimensions: Dimensions[_internal].schema.optional(),
weight: Weight[_internal].schema.optional()
}))
})
}
});

const TrackShipmentSchema = Joi.object({
...baseTestParamValidations,
...{
Expand Down Expand Up @@ -226,6 +243,10 @@ const testsSchema = Joi.object({
then: Joi.array().items(SameDayPickupTestParamsSchema),
otherwise: SameDayPickupTestParamsSchema,
}),
schedulePickup_next_day: Joi.alternatives().conditional(Joi.array(), {
then: Joi.array().items(NextDayPickupTestParamsSchema),
otherwise: NextDayPickupTestParamsSchema,
}),
trackShipment: Joi.alternatives().conditional(Joi.array(), {
then: Joi.array().items(TrackShipmentSchema),
otherwise: TrackShipmentSchema,
Expand Down
187 changes: 187 additions & 0 deletions src/core/test-app/tests/next-day-pickup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import { DeliveryService, PickupService, LengthUnit, WeightUnit } from "@shipengine/connect-sdk";
import { CarrierApp, PickupRequestPOJO, PickupShipmentPOJO, PickupPackagePOJO } from "@shipengine/connect-sdk/lib/internal";
import Suite from "../runner/suite";
import { initializeTimeStamps } from "../../utils/time-stamps";
import { NextDayPickupTestParams, NextDayPickupConfigOptions } from "../runner/config/next-day-pickup";
import reduceDefaultsWithConfig from "../utils/reduce-defaults-with-config";
import objectToTestTitle from "../utils/object-to-test-title";
import useShipmentAddresses from '../utils/use-shipment-addresses';
import findDeliveryServiceByName from '../utils/find-delivery-service-by-name';
import findPickupServiceByName from '../utils/find-pickup-service-by-name';
import { findDomesticDeliveryService } from '../utils/find-domestic-delivery-service';
import Test from '../runner/test';
import { buildAddress } from '../factories/address';
import findPackagingByName from '../utils/find-packaging-by-name';

interface TestArgs {
title: string;
methodArgs: PickupRequestPOJO;
config: unknown;
testParams: NextDayPickupTestParams;
}

export class NextDayPickup extends Suite {
title = "schedulePickup_next_day";

private deliveryService: DeliveryService | undefined;

private pickupService: PickupService | undefined;

private setDeliveryService(
config: NextDayPickupConfigOptions,
): void {
const carrierApp = this.app as CarrierApp;

if (config.deliveryServiceName) {
this.deliveryService = findDeliveryServiceByName(
config.deliveryServiceName,
carrierApp,
);
} else {
try {
this.deliveryService = findDomesticDeliveryService(carrierApp);
} catch {
this.deliveryService = undefined;
}
}
}

private setPickupService(config: NextDayPickupConfigOptions): void {
const carrierApp = this.app as CarrierApp;

if (config.pickupServiceName) {
this.pickupService = findPickupServiceByName(config.pickupServiceName, carrierApp);
}

else if (carrierApp.pickupServices.length > 0) {
this.pickupService = carrierApp.pickupServices[0];
}
}

buildTestArg(config: NextDayPickupConfigOptions): TestArgs | undefined {
const carrierApp = this.app as CarrierApp;
this.setPickupService(config);
this.setDeliveryService(config);

if (!this.deliveryService || !this.pickupService) return undefined;
const [shipFrom, shipTo] = useShipmentAddresses(this.deliveryService);

if (!shipTo || !shipFrom) return undefined;

const address = buildAddress(`${shipFrom.country}-from`);

const { tomorrowEarlyAM, tomorrowEvening } = initializeTimeStamps();

const defaults: NextDayPickupTestParams = {
pickupServiceName: this.pickupService.name,
deliveryServiceName: this.deliveryService.name,
address,
contact: { name: "John Doe" },
timeWindow: {
startDateTime: tomorrowEarlyAM,
endDateTime: tomorrowEvening
},
shipments: [{
deliveryServiceName: this.deliveryService.name,
packages: [
{
packagingName: this.deliveryService.packaging[0].name,
dimensions: {
length: 12,
width: 12,
height: 12,
unit: LengthUnit.Inches
},
weight: {
unit: WeightUnit.Pounds,
value: 5.0
}
}
]
}]
};

const testParams = reduceDefaultsWithConfig<
NextDayPickupTestParams
>(defaults, config);

const shipments: PickupShipmentPOJO[] = testParams.shipments.map((shipmentParams) => {
const shipment: PickupShipmentPOJO = {
deliveryService: findDeliveryServiceByName(shipmentParams.deliveryServiceName, carrierApp),
packages: shipmentParams.packages.map((pkgParams) => {
const pkg: PickupPackagePOJO = {
packaging: findPackagingByName(pkgParams.packagingName, carrierApp),
dimensions: pkgParams.dimensions,
weight: pkgParams.weight
};

return pkg;
})
}

return shipment;
});

const rateCriteriaPOJO: PickupRequestPOJO = {
pickupService: findPickupServiceByName(testParams.pickupServiceName, carrierApp),
address: testParams.address,
timeWindow: testParams.timeWindow,
contact: testParams.contact,
shipments
};

const title = config.expectedErrorMessage
? `it raises an error when scheduling a next day pickup with ${objectToTestTitle(
testParams,
)}`
: `it schedules a next day pickup with ${objectToTestTitle(
testParams,
)}`;

return {
title,
methodArgs: rateCriteriaPOJO,
config,
testParams
};
}

buildTestArgs(): Array<TestArgs | undefined> {
if (Array.isArray(this.config)) {
return this.config.map((config: NextDayPickupConfigOptions) => {
return this.buildTestArg(config);
});
}

const config = this.config as NextDayPickupConfigOptions;
return [this.buildTestArg(config)];
}

tests(): Test[] {
const testArgs = this.buildTestArgs().filter(args => args !== undefined) as TestArgs[];

if (testArgs.length === 0) {
return [];
}
return testArgs.map((testArg) => {
return this.test(
testArg.title,
testArg.methodArgs,
testArg.config,
async () => {
const carrierApp = this.app as CarrierApp;

const transaction = await this.transaction(testArg.config);

// This should never actually throw because we handle this case up stream.
if (!carrierApp.schedulePickup) {
throw new Error("schedulePickup is not implemented");
}

await carrierApp.schedulePickup(transaction, testArg.methodArgs);

}
);
});
}
}
1 change: 1 addition & 0 deletions src/core/types/timestamps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface TimeStamps {
tomorrowEarly: string;
tomorrowEarlyAM: string;
tomorrow: string;
tomorrowEvening: string;
twoDays: string;
twoDaysEarly: string;
threeDays: string;
Expand Down
4 changes: 3 additions & 1 deletion src/core/utils/time-stamps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ export function initializeTimeStamps(): TimeStamps {
const todayEarly = DateTime.local(date.getFullYear(), date.getMonth() + 1, date.getDate()).plus({ hours: 6 }).toISO();
const today = DateTime.local(date.getFullYear(), date.getMonth() + 1, date.getDate()).plus({ hours: 12 }).toISO();
const todayEvening = DateTime.local(date.getFullYear(), date.getMonth() + 1, date.getDate()).plus({ hours: 18 }).toISO();
const tomorrowEarly = DateTime.local(date.getFullYear(), date.getMonth() + 1, date.getDate()).plus({ days: 1, hours: 9 }).toISO();
const tomorrowEarlyAM = DateTime.local(date.getFullYear(), date.getMonth() + 1, date.getDate()).plus({ days: 1, hours: 6 }).toISO();
const tomorrowEarly = DateTime.local(date.getFullYear(), date.getMonth() + 1, date.getDate()).plus({ days: 1, hours: 9 }).toISO();
const tomorrow = DateTime.local(date.getFullYear(), date.getMonth() + 1, date.getDate()).plus({ days: 1, hours: 12 }).toISO();
const tomorrowEvening = DateTime.local(date.getFullYear(), date.getMonth() + 1, date.getDate()).plus({ days: 1, hours: 18 }).toISO();
const twoDays = DateTime.local(date.getFullYear(), date.getMonth() + 1, date.getDate()).plus({ days: 2, hours: 12 }).toISO();
const twoDaysEarly = DateTime.local(date.getFullYear(), date.getMonth() + 1, date.getDate()).plus({ days: 2, hours: 9 }).toISO();
const threeDays = DateTime.local(date.getFullYear(), date.getMonth() + 1, date.getDate()).plus({ days: 3 }).toISO();
Expand All @@ -26,6 +27,7 @@ export function initializeTimeStamps(): TimeStamps {
tomorrowEarly,
tomorrowEarlyAM,
tomorrow,
tomorrowEvening,
twoDays,
twoDaysEarly,
threeDays
Expand Down
Loading

0 comments on commit b6f6b70

Please sign in to comment.