Test Example: API Response Schema and Content Validation for Product Metadata

API Response Schema and Content Validation for Product Metadata

GET Request:

https://www.iqos.com/content/pmisite/gb/en/product.editorialProperties.productDetail.T1701262369386.V0189584000_9283711_7101_4202.json

The Response:

Click here to see the response:
"{\"pmi_G0001462_04_gb-assetID\":\"pmintl/product/$PRESET$/VEEV+ONE+Refreshing+Starter+Kit-pmi_G0001462_04_gb-1710753478115.png\",\"sling:resourceType\":\"pmisite/components/content/productDetail\",\"pmi_G0001462_01_gb-assetID\":\"pmintl/product/$PRESET$/VEEV+ONE+Refreshing+Starter+Kit-pmi_G0001462_01_gb-1710753478108.png\",\"pmi_G0000872_01_gb-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+Kit+Neon+Limited+Edition-pmi_G0000872_01_gb-1712741939207.png\",\"technicalDetails\":\"Technical Details\",\"pmi_G0001297_03_gb-assetType\":\"Image\",\"imageserverurl\":\"/is/image/\",\"pmi_G0000873_04_gb-assetType\":\"Image\",\"jcr:created\":\"Wed Jun 28 2023 08:38:21 GMT+0000\",\"pmi_G0001462_03_gb-assetType\":\"Image\",\"chooseSize\":\"Dimensions:\",\"pmi_G0001462_02_gb-assetType\":\"Image\",\"pmi_G0000873_02_gb-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+Prime+Kit+Neon+Limited+Edition-pmi_G0000873_02_gb-1712741939218.png\",\"pmi_G0000873_00_gb-assetType\":\"Image\",\"pmi_ILUMAPRIMENeonStarterKit_00_gb-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+PRIME+Limited+Edition+Neon+Purple+Starter+Kit-pmi_ILUMAPRIMENeonStarterKit_00_gb-1712756188739.png\",\"pmi_G0001297_02_gb-assetID\":\"pmintl/product/$PRESET$/VEEV+NOW+Blue+Mint+Disposable+Single+Pack-pmi_G0001297_02_gb-1699533693148.png\",\"pmi_G0000873_01_gb-assetType\":\"Image\",\"earnPointsIcon\":\"/vanity/content/dam/iqos/global/marketing/brand/graphics/star.svg/star.T1626178818278.V0189584000_9283711_7101_4202.svg\",\"pmi_TEREAMixedBundle_00_gb-assetID\":\"pmintl/product/$PRESET$/TEREA+Mixed+Bundle-pmi_TEREAMixedBundle_00_gb-1711635461330.png\",\"pmi_G0000001_00_gb-assetType\":\"Image\",\"pmi_G0000590_01-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+One+Kit+Pebble+Beige-pmi_G0000590_01-1668515315409.png\",\"pmi_G0001297_01_gb-assetID\":\"pmintl/product/$PRESET$/VEEV+NOW+Blue+Mint+Disposable+Single+Pack-pmi_G0001297_01_gb-1699533693139.png\",\"jcr:primaryType\":\"nt:unstructured\",\"pmi_G0000595_00-assetType\":\"Image\",\"earnPointsTextAfter\":\"for IQOS Club for this purchase\",\"pmi_G0000872_00_gb-assetType\":\"Image\",\"pmi_G0000872_02_gb-assetType\":\"Image\",\"pmi_G0001619_00_gb-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+ONE+Kit+Neon+Purple+Limited+Edition-pmi_G0001619_00_gb-1712742075289.png\",\"pmi_G0000599_00-assetType\":\"Image\",\"pmi_G0000595_00-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+Prime+Kit+Golden+Khaki-pmi_G0000595_00-1667395511458.png\",\"pmi_G0001297_04_gb-assetID\":\"pmintl/product/$PRESET$/VEEV+NOW+Blue+Mint+Disposable+Single+Pack-pmi_G0001297_04_gb-1699533693143.png\",\"bundleLowStockMessage\":\"LOW STOCK\",\"bundleWarrantyMessage\":\"One year warranty\",\"pmi_IQOSILUMAOneStarterKit_00_gb-assetType\":\"Image\",\"pmi_G0000873_03_gb-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+Prime+Kit+Neon+Limited+Edition-pmi_G0000873_03_gb-1712741939220.png\",\"pmi_G0000692_00_gb-assetID\":\"pmintl/product/$PRESET$/TEREA+AMBER+PACK-pmi_G0000692_00_gb-1692716262049.png\",\"addToCart\":\"Add To Cart\",\"pmi_G0001462_00_gb-assetID\":\"pmintl/product/$PRESET$/VEEV+ONE+Refreshing+Starter+Kit-pmi_G0001462_00_gb-1710753478131.png\",\"pmi_B0000070_00-assetID\":\"pmintl/product/$PRESET$/IQOS+DUO+Cleaning+Tool-pmi_B0000070_00-1626178027876.png\",\"pmi_B0000070_00-assetType\":\"Image\",\"pmi_G0001297_05_gb-assetID\":\"pmintl/product/$PRESET$/VEEV+NOW+Blue+Mint+Disposable+Single+Pack-pmi_G0001297_05_gb-1699533693141.png\",\"jcr:createdBy\":\"akumarwa_PMINTL.NET#EXT#@IQOSonline.onmicrosoft.com\",\"pmi_G0000599_00-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+Kit+Pebble+Beige-pmi_G0000599_00-1667395411628.png\",\"pmi_IQOSSummerHEETSBundle_00_gb-assetType\":\"Image\",\"pmi_IQOSILUMAStarterKit_00_gb-assetType\":\"Image\",\"pmi_IQOSILUMAPrimeStarterKit_00_gb-assetID\":\"pmintl/product/$PRESET$/IQOS+Iluma+Prime+Starter+Kit-pmi_IQOSILUMAPrimeStarterKit_00_gb-1692716557570.png\",\"shareSite\":\"Share\",\"earnPointsText\":\"You Could earn up to\",\"pmi_IQOSILUMAPrimeStarterKit_00_gb-assetType\":\"Image\",\"jcr:lastModified\":\"Wed Jun 28 2023 08:41:35 GMT+0000\",\"bundleOutOfStockMessage\":\"OUT OF STOCK\",\"pmi_G0000001_00_gb-assetID\":\"pmintl/product/$PRESET$/HEETS+AMBER+BUNDLE+%2810%29-pmi_G0000001_00_gb-1658147853256.jpg\",\"pmi_ILUMAONENeonStarterKit_00_gb-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+ONE+Limited+Edition+Neon+Purple+Starter+Kit-pmi_ILUMAONENeonStarterKit_00_gb-1712756188737.png\",\"pmi_IQOSSummerHEETSBundle_00_gb-assetID\":\"pmintl/product/$PRESET$/Summer+HEETS+Bundle-pmi_IQOSSummerHEETSBundle_00_gb-1687797439876.png\",\"pmi_G0000873_04_gb-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+Prime+Kit+Neon+Limited+Edition-pmi_G0000873_04_gb-1712741939221.png\",\"pmi_G0001297_00_gb-assetID\":\"pmintl/product/$PRESET$/VEEV+NOW+Blue+Mint+Disposable+Single+Pack-pmi_G0001297_00_gb-1699533693146.png\",\"carton\":\"Carton\",\"pmi_G0000872_01_gb-assetType\":\"Image\",\"pmi_G0000873_01_gb-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+Prime+Kit+Neon+Limited+Edition-pmi_G0000873_01_gb-1712741939216.png\",\"ILUMAONENeonStarterKit_00-assetType\":\"\",\"pmi_G0001297_05_gb-assetType\":\"Image\",\"selectQuantity\":\"Select quantity\",\"pmi_TEREAMixedBundle_00_gb-assetType\":\"Image\",\"pmi_G0000590_00-assetType\":\"Image\",\"pmi_G0001297_01_gb-assetType\":\"Image\",\"pmi_G0001297_03_gb-assetID\":\"pmintl/product/$PRESET$/VEEV+NOW+Blue+Mint+Disposable+Single+Pack-pmi_G0001297_03_gb-1699533693144.png\",\"pmi_G0001619_00_gb-assetType\":\"Image\",\"insufficientErrorStock\":\"%s is out of stock. Please, select a different colour.\",\"backallProducts\":\"Back\",\"pmi_G0001450_00_gb-assetType\":\"Image\",\"pmi_ILUMAONENeonStarterKit_00_gb-assetType\":\"Image\",\"pmi_IQOSILUMAStarterKit_00_gb-assetID\":\"pmintl/product/$PRESET$/IQOS+Iluma+Starter+Kit-pmi_IQOSILUMAStarterKit_00_gb-1692716557569.png\",\"pmi_G0001462_00_gb-assetType\":\"Image\",\"pmi_G0001462_01_gb-assetType\":\"Image\",\"pmi_G0000873_02_gb-assetType\":\"Image\",\"pmi_G0000873_03_gb-assetType\":\"Image\",\"shareProduct\":\"Share Product\",\"chooseColor\":\"Select Color\",\"pmi_G0000692_00_gb-assetType\":\"Image\",\"oneSize\":\"One Size\",\"codeLabel\":\"Product code: \",\"pmi_G0001462_02_gb-assetID\":\"pmintl/product/$PRESET$/VEEV+ONE+Refreshing+Starter+Kit-pmi_G0001462_02_gb-1710753478109.png\",\"pmi_G0001462_04_gb-assetType\":\"Image\",\"pmi_G0001462_05_gb-assetType\":\"Image\",\"pmi_ILUMAPRIMENeonStarterKit_00_gb-assetType\":\"Image\",\"pmi_G0000872_02_gb-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+Kit+Neon+Limited+Edition-pmi_G0000872_02_gb-1712741939210.png\",\"bundleSubtitle\":\"Get two accessories to add colour and personalise your IQOS and save 20%.\",\"description\":\"Description\",\"pmi_G0001297_04_gb-assetType\":\"Image\",\"pmi_G0001462_03_gb-assetID\":\"pmintl/product/$PRESET$/VEEV+ONE+Refreshing+Starter+Kit-pmi_G0001462_03_gb-1710753478106.png\",\"pmi_G0000873_00_gb-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+Prime+Kit+Neon+Limited+Edition-pmi_G0000873_00_gb-1712741939213.png\",\"bundleColor\":\"Select your preferred options below and add to cart\",\"pmi_G0001297_02_gb-assetType\":\"Image\",\"bundleDeliveryMessage\":\"Free next day delivery and easy returns\",\"ILUMAONENeonStarterKit_00-assetID\":\"\",\"pmi_G0001297_00_gb-assetType\":\"Image\",\"jcr:lastModifiedBy\":\"akumarwa_PMINTL.NET#EXT#@IQOSonline.onmicrosoft.com\",\"newCollection\":\"New Collection\",\"pmi_G0000872_00_gb-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+Kit+Neon+Limited+Edition-pmi_G0000872_00_gb-1712741939204.png\",\"pmi_G0000689_00-assetType\":\"Image\",\"pmi_IQOSILUMAOneStarterKit_00_gb-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+ONE+Starter+Kit-pmi_IQOSILUMAOneStarterKit_00_gb-1711531426197.png\",\"pmi_G0001462_05_gb-assetID\":\"pmintl/product/$PRESET$/VEEV+ONE+Refreshing+Starter+Kit-pmi_G0001462_05_gb-1710753478134.png\",\"quantityLabel\":\"QTY\",\"pmi_G0000590_01-assetType\":\"Image\",\"pmi_G0001450_00_gb-assetID\":\"pmintl/product/$PRESET$/VEEV+One+Mango-pmi_G0001450_00_gb-1717656955813.png\",\"singlePack\":\"Single Pack\",\"pmi_G0000689_00-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+USB+C+Power+Adaptor+Cream-pmi_G0000689_00-1668597154154.png\",\"pmi_G0000590_00-assetID\":\"pmintl/product/$PRESET$/IQOS+ILUMA+One+Kit+Pebble+Beige-pmi_G0000590_00-1711359406933.png\",\"shippingNote\":\"You will receive it soon!\"}"


Test Script:

// Log the entire response to understand its structure
console.log("Response data:", responseBody);

let jsonData;
try {
    jsonData = JSON.parse(responseBody);
} catch (e) {
    pm.test("Response is valid JSON", function () {
        pm.expect.fail("Response is not valid JSON");
    });
}

// 1. Ensure response contains certain essential keys, if they exist
pm.test("Response contains essential keys", function () {
    const essentialKeys = [
        "pmi_G0001462_04_gb-assetID",
        "pmi_G0001462_01_gb-assetID",
        "pmi_G0000872_01_gb-assetID",
        "pmi_G0001297_03_gb-assetType",
        "imageserverurl",
        "technicalDetails",
        "chooseSize",
        "bundleLowStockMessage",
        "bundleOutOfStockMessage",
        "pmi_G0000001_00_gb-assetID",
        "pmi_G0000872_02_gb-assetID",
        "quantityLabel",
        // Add more keys as necessary
    ];

    essentialKeys.forEach(key => {
        if (jsonData.hasOwnProperty(key)) {
            pm.expect(jsonData).to.have.property(key);
        } else {
            console.warn(`Missing key in response: ${key}`);
        }
    });
});

// 2. Verify certain fields match patterns if they exist
pm.test("Check specific fields follow expected patterns", function () {
    const imageUrlPattern = /^pmintl\/product\/\$PRESET\$\/.+\.png$/;

    // Check that keys ending with "-assetID" match the image pattern
    Object.keys(jsonData).forEach(key => {
        if (key.endsWith("-assetID") && typeof jsonData[key] === "string") {
            pm.expect(jsonData[key]).to.match(imageUrlPattern, `${key} does not match the pattern`);
        }
    });

    // Verify that `imageserverurl` exists and starts with `/is/image/`
    if (jsonData.imageserverurl) {
        pm.expect(jsonData.imageserverurl).to.be.a("string");
        pm.expect(jsonData.imageserverurl).to.equal("/is/image/");
    } else {
        console.warn("Missing 'imageserverurl' field in response.");
    }
});

// 3. Ensure each key has a non-empty value
pm.test("All values are not empty", function () {
    Object.entries(jsonData).forEach(([key, value]) => {
        pm.expect(value, `The value for ${key} should not be empty`).to.not.be.null;
        pm.expect(value, `The value for ${key} should not be an empty string`).to.not.equal('');
    });
});

// 4. Validate timestamp and username metadata if present
pm.test("Check metadata fields if present", function () {
    if (jsonData["jcr:created"]) {
        pm.expect(jsonData["jcr:created"]).to.match(
            /\w{3} \w{3} \d{2} \d{4} \d{2}:\d{2}:\d{2} GMT\+0000/
        );
    } else {
        console.warn("Missing 'jcr:created' metadata field.");
    }

    if (jsonData["jcr:lastModified"]) {
        pm.expect(jsonData["jcr:lastModified"]).to.match(
            /\w{3} \w{3} \d{2} \d{4} \d{2}:\d{2}:\d{2} GMT\+0000/
        );
    } else {
        console.warn("Missing 'jcr:lastModified' metadata field.");
    }

    if (jsonData["jcr:createdBy"]) {
        pm.expect(jsonData["jcr:createdBy"]).to.include("PMINTL.NET");
    } else {
        console.warn("Missing 'jcr:createdBy' field.");
    }
});

// 5. Check specific product attributes if present
pm.test("Verify product-specific details if available", function () {
    if (jsonData["pmi_G0000872_01_gb-assetID"]) {
        pm.expect(jsonData["pmi_G0000872_01_gb-assetID"]).to.include("IQOS+ILUMA+Kit");
    } else {
        console.warn("Missing 'pmi_G0000872_01_gb-assetID' field.");
    }

    if (jsonData["pmi_G0000873_01_gb-assetType"]) {
        pm.expect(jsonData["pmi_G0000873_01_gb-assetType"]).to.equal("Image");
    } else {
        console.warn("Missing 'pmi_G0000873_01_gb-assetType' field.");
    }
});

// 6. Check bundle messages if present
pm.test("Bundle messages check", function () {
    if (jsonData.bundleLowStockMessage) {
        pm.expect(jsonData.bundleLowStockMessage).to.equal("LOW STOCK");
    } else {
        console.warn("Missing 'bundleLowStockMessage' field.");
    }

    if (jsonData.bundleOutOfStockMessage) {
        pm.expect(jsonData.bundleOutOfStockMessage).to.equal("OUT OF STOCK");
    } else {
        console.warn("Missing 'bundleOutOfStockMessage' field.");
    }

    if (jsonData.bundleDeliveryMessage) {
        pm.expect(jsonData.bundleDeliveryMessage).to.include("Free next day delivery");
    } else {
        console.warn("Missing 'bundleDeliveryMessage' field.");
    }
});

Test Comprehension

Here’s a breakdown of each test, explaining what it checks and how it ensures the response is correct:

1. Essential Keys Test

pm.test("Response contains essential keys", function () {
const essentialKeys = [ ... ];
essentialKeys.forEach(key => {
if (jsonData.hasOwnProperty(key)) {
pm.expect(jsonData).to.have.property(key);
} else {
console.warn(`Missing key in response: ${key}`);
}
});
});

Purpose: This test verifies that the essential keys—like pmi_G0001462_04_gb-assetID and imageserverurl—are present in the response. It checks each key individually to confirm it exists and, if any are missing, logs a warning with the specific missing key for easier troubleshooting.

2. Pattern Match for Specific Fields

pm.test("Check specific fields follow expected patterns", function () { ... });

Purpose: This test checks if specific fields in the response follow an expected pattern. For example, keys ending in -assetID should match the format pmintl/product/$PRESET$/.... Additionally, it checks that imageserverurl starts with /is/image/, helping confirm that certain fields have correctly formatted values.

How It Works: The test scans each key in jsonData, identifies those ending in -assetID, and confirms they match the regular expression. For imageserverurl, it checks that the field exists and that its value starts with /is/image/.

3. Non-Empty Values Check

pm.test("All values are not empty", function () { ... });

Purpose: This test ensures that no values in the response are null or empty strings, meaning each key should have a meaningful value.

How It Works: It loops over each key-value pair in jsonData and checks that the value is neither null nor an empty string (''). This helps prevent empty or incomplete data from slipping through.

4. Metadata Fields Validation

pm.test("Check metadata fields if present", function () { ... });

Purpose: This test verifies the presence and formatting of metadata fields, such as jcr:created, jcr:lastModified, and jcr:createdBy. These fields may include timestamps or usernames, which often have specific formats or prefixes.

How It Works: Each metadata field is checked individually. For jcr:created and jcr:lastModified, the test expects a specific timestamp format, like Wed Sep 20 2023 10:00:00 GMT+0000. For jcr:createdBy, the field should include “PMINTL.NET”, indicating it follows the expected naming convention.

5. Product-Specific Attributes

pm.test("Verify product-specific details if available", function () { ... });

Purpose: This test verifies that certain product-specific details, like pmi_G0000872_01_gb-assetID, follow expected conventions. This helps ensure that important identifiers or types are present and accurate.

How It Works: If the field pmi_G0000872_01_gb-assetID exists, the test checks that it includes a specific string (e.g., “IQOS+ILUMA+Kit”). Similarly, pmi_G0000873_01_gb-assetType should be “Image.” If these fields are missing, a warning logs to the console to highlight the missing data without failing the test entirely.

6. Bundle Messages Validation

pm.test("Bundle messages check", function () { ... });

Purpose: This test checks the content of certain “bundle” messages like bundleLowStockMessage, bundleOutOfStockMessage, and bundleDeliveryMessage. These fields are crucial for user-facing messages on stock status and delivery options.

How It Works: The test checks for each message’s expected value if the field is present. For example, bundleLowStockMessage should say “LOW STOCK,” and bundleOutOfStockMessage should be “OUT OF STOCK.” If any field is missing, a warning is logged, keeping the test flexible but informative.

Summary

Together, these tests:

  1. Ensure the presence of key fields.
  2. Check that specific fields follow expected patterns and formats.
  3. Confirm all values are non-empty.
  4. Verify metadata fields follow conventions.
  5. Validate product-specific details.
  6. Check stock-related messages for correct text.

This comprehensive approach covers all critical areas while allowing flexibility for missing non-essential fields, logging detailed messages to make troubleshooting easier if future issues arise.

Scroll to Top