Skip to content

Commit

Permalink
Merge branch 'develop' into feature/CXSPA-981
Browse files Browse the repository at this point in the history
  • Loading branch information
Pio-Bar authored Mar 22, 2024
2 parents 59c848b + 1c6cffb commit 28f1bf2
Show file tree
Hide file tree
Showing 39 changed files with 494 additions and 168 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ describe('ConfigAttributeHeaderComponent', () => {
productConfigurator: {
enableNavigationToConflict: false,
descriptions: {
addDescriptions: true,
attributeDescriptionLength: 100,
valueDescriptionLength: 70,
},
Expand Down Expand Up @@ -1124,14 +1123,14 @@ describe('ConfigAttributeHeaderComponent', () => {
});

it('should return default value if attributeDescriptionLength setting is not provided', () => {
(configuratorUISettingsConfig.productConfigurator.descriptions ??=
{}).attributeDescriptionLength = undefined;
((configuratorUISettingsConfig.productConfigurator ??=
{}).descriptions ??= {}).attributeDescriptionLength = undefined;
expect(component.getAttributeDescriptionLength()).toEqual(100);
});

it('should return set value if attributeDescriptionLength setting is 110', () => {
(configuratorUISettingsConfig.productConfigurator.descriptions ??=
{}).attributeDescriptionLength = 110;
((configuratorUISettingsConfig.productConfigurator ??=
{}).descriptions ??= {}).attributeDescriptionLength = 110;
expect(component.getAttributeDescriptionLength()).toEqual(110);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,26 @@ describe('ConfiguratorAttributeBaseComponent', () => {
});
});

describe('getImageLabel', () => {
it('should return image label without ellipsis', () => {
const label = 'BLACK';
const techName = 'BLK';
const techLabel = label + ' / [' + techName + ']';
expect(classUnderTest.getImageLabel(true, label, techName)).toEqual(
techLabel
);
});

it('should return image label with ellipsis', () => {
const label = 'String value 0 make text long make text long';
const techName = 'techName';
const techLabel = label.substring(0, 16).concat('...');
expect(classUnderTest.getImageLabel(true, label, techName)).toEqual(
techLabel
);
});
});

describe('getValuePrice', () => {
it('should return empty string in case value is undefined', () => {
expect(classUnderTest['getValuePrice'](undefined)).toEqual('');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class ConfiguratorAttributeBaseComponent {
private static PREFIX_LABEL = 'label';
private static PREFIX_OPTION_PRICE_VALUE = 'price--optionsPriceValue';
private static PREFIX_DDLB_OPTION_PRICE_VALUE = 'option--price';
protected static MAX_IMAGE_LABEL_CHARACTERS = 16;

/**
* Creates unique key for config value on the UI
Expand Down Expand Up @@ -166,6 +167,33 @@ export class ConfiguratorAttributeBaseComponent {
return title;
}

/**
* Retrieves image label with or without technical name depending whether the expert mode is set or not.
* If the length of the label is longer than 'MAX_IMAGE_LABEL_CHARACTERS' characters, it will be shortened and ellipsis will be added at the end.
*
* @param expMode - Is expert mode set?
* @param label - value label
* @param techName - value technical name
* @param value - Configurator value
*/
getImageLabel(
expMode: boolean,
label: string | undefined,
techName: string | undefined,
value?: Configurator.Value
): string {
const labelForImage = this.getLabel(expMode, label, techName, value);
return labelForImage?.trim().length >=
ConfiguratorAttributeBaseComponent.MAX_IMAGE_LABEL_CHARACTERS
? labelForImage
.substring(
0,
ConfiguratorAttributeBaseComponent.MAX_IMAGE_LABEL_CHARACTERS
)
.concat('...')
: labelForImage;
}

/**
* Fetches the first image for a given value
* @param value Value
Expand Down Expand Up @@ -308,6 +336,7 @@ export class ConfiguratorAttributeBaseComponent {
?.valueDescriptionLength ?? 70
);
}

protected isReadOnly(attribute: Configurator.Attribute): boolean {
if (attribute.uiType) {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
}
}}
</label>
<ng-container *ngIf="!config.features?.attributeTypesV2">
<ng-container *ngIf="!config.features?.productConfiguratorAttributeTypesV2">
<select
id="{{ createAttributeIdForConfigurator(attribute) }}"
class="form-control"
Expand All @@ -38,7 +38,7 @@
</select>
</ng-container>

<ng-container *ngIf="config.features?.attributeTypesV2">
<ng-container *ngIf="config.features?.productConfiguratorAttributeTypesV2">
<div class="cx-value-label-pair">
<select
id="{{ createAttributeIdForConfigurator(attribute) }}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ class MockConfigUtilsService {
}

class MockConfig {
features = [{ attributeTypesV2: false }];
features = [{ productConfiguratorAttributeTypesV2: false }];
}

describe('ConfigAttributeDropDownComponent', () => {
describe('ConfiguratorAttributeDropDownComponent', () => {
let component: ConfiguratorAttributeDropDownComponent;
let htmlElem: HTMLElement;
let fixture: ComponentFixture<ConfiguratorAttributeDropDownComponent>;
Expand Down Expand Up @@ -130,7 +130,7 @@ describe('ConfigAttributeDropDownComponent', () => {
};

config = TestBed.inject(Config);
(config.features ?? {}).attributeTypesV2 = false;
(config.features ?? {}).productConfiguratorAttributeTypesV2 = false;
fixture.detectChanges();
return component;
}
Expand Down Expand Up @@ -204,7 +204,7 @@ describe('ConfigAttributeDropDownComponent', () => {
);
});

it('should not render cx-value-label-pair div in case attributeTypesV2 feature flag is disabled', () => {
it('should not render cx-value-label-pair div in case productConfiguratorAttributeTypesV2 feature flag is disabled', () => {
createComponentWithData();
(component.attribute.values ?? [{ description: '' }])[0].description =
'Here is a description at value level';
Expand All @@ -216,9 +216,9 @@ describe('ConfigAttributeDropDownComponent', () => {
);
});

it('should render cx-value-label-pair div in case attributeTypesV2 feature flag is enabled', () => {
it('should render cx-value-label-pair div in case productConfiguratorAttributeTypesV2 feature flag is enabled', () => {
createComponentWithData();
(config.features ?? {}).attributeTypesV2 = true;
(config.features ?? {}).productConfiguratorAttributeTypesV2 = true;
fixture.detectChanges();
CommonConfiguratorTestUtilsService.expectElementPresent(
expect,
Expand All @@ -227,7 +227,7 @@ describe('ConfigAttributeDropDownComponent', () => {
);
});

it('should not render description in case attributeTypesV2 feature flag is disabled', () => {
it('should not render description in case productConfiguratorAttributeTypesV2 feature flag is disabled', () => {
createComponentWithData();
(component.attribute.values ?? [{ description: '' }])[0].description =
'Here is a description at value level';
Expand All @@ -239,9 +239,9 @@ describe('ConfigAttributeDropDownComponent', () => {
);
});

it('should render description in case attributeTypesV2 feature flag is enabled', () => {
it('should render description in case productConfiguratorAttributeTypesV2 feature flag is enabled', () => {
createComponentWithData();
(config.features ?? {}).attributeTypesV2 = true;
(config.features ?? {}).productConfiguratorAttributeTypesV2 = true;
(component.attribute.values ?? [{ description: '' }])[0].description =
'Here is a description at value level';
fixture.detectChanges();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class ConfiguratorAttributeDropDownComponent
);

this.group = attributeComponentContext.group.id;
useFeatureStyles('attributeTypesV2');
useFeatureStyles('productConfiguratorAttributeTypesV2');
}

ngOnInit() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class MockConfigUtilsService {
}
}

describe('ConfigAttributeInputFieldComponent', () => {
describe('ConfiguratorAttributeInputFieldComponent', () => {
let component: ConfiguratorAttributeInputFieldComponent;
let fixture: ComponentFixture<ConfiguratorAttributeInputFieldComponent>;
let htmlElem: HTMLElement;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div id="{{ createAttributeIdForConfigurator(attribute) }}" class="cx-row">
<ng-container *ngIf="!config.features?.attributeTypesV2">
<ng-container *ngIf="!config.features?.productConfiguratorAttributeTypesV2">
<div
*ngFor="let value of attribute.values; let i = index"
id="{{
Expand Down Expand Up @@ -53,27 +53,14 @@
/>
<div *ngIf="!getImage(value)" class="cx-img-dummy"></div>
{{ getLabel(expMode, value.valueDisplay, value.valueCode) }}
<button
*ngIf="value.description"
[cxPopover]="value.description"
[cxPopoverOptions]="{
placement: 'auto',
class: 'cx-value-description',
appendToBody: true,
displayCloseButton: true,
}"
[attr.aria-label]="'configurator.a11y.description' | cxTranslate"
>
<cx-icon [type]="iconTypes.INFO"> </cx-icon>
</button>
<cx-configurator-price
[formula]="extractValuePriceFormulaParameters(value)"
></cx-configurator-price>
</label>
</div>
</div>
</ng-container>
<ng-container *ngIf="config.features?.attributeTypesV2">
<ng-container *ngIf="config.features?.productConfiguratorAttributeTypesV2">
<ng-container *ngFor="let value of attribute.values; let i = index">
<div
*ngIf="isValueDisplayed(attribute, value)"
Expand Down Expand Up @@ -138,7 +125,20 @@
*ngIf="!getImage(value)"
[ngClass]="getImgStyleClasses(attribute, value, 'cx-img-dummy')"
></div>
{{ getLabel(expMode, value.valueDisplay, value.valueCode) }}
{{ getImageLabel(expMode, value.valueDisplay, value.valueCode) }}
<button
*ngIf="value.description"
[cxPopover]="value.description"
[cxPopoverOptions]="{
placement: 'auto',
class: 'cx-value-description',
appendToBody: true,
displayCloseButton: true,
}"
[attr.aria-label]="'configurator.a11y.description' | cxTranslate"
>
<cx-icon [type]="iconTypes.INFO"></cx-icon>
</button>
<cx-configurator-price
[formula]="extractValuePriceFormulaParameters(value)"
></cx-configurator-price>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ import { ReactiveFormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { NgSelectModule } from '@ng-select/ng-select';
import { Config, I18nTestingModule } from '@spartacus/core';
import { IconTestingModule, PopoverModule } from '@spartacus/storefront';
import { CommonConfiguratorTestUtilsService } from '../../../../../common/testing/common-configurator-test-utils.service';
import { ConfiguratorCommonsService } from '../../../../core/facade/configurator-commons.service';
import { ConfiguratorGroupsService } from '../../../../core/facade/configurator-groups.service';
import { Configurator } from '../../../../core/model/configurator.model';
import { ConfiguratorTestUtils } from '../../../../testing/configurator-test-utils';
import { ConfiguratorPriceComponentOptions } from '../../../price/configurator-price.component';
import { ConfiguratorStorefrontUtilsService } from '../../../service/configurator-storefront-utils.service';
import { ConfiguratorAttributeMultiSelectionImageComponent } from './configurator-attribute-multi-selection-image.component';
import { ConfiguratorAttributeCompositionContext } from '../../composition/configurator-attribute-composition.model';
import { ConfiguratorCommonsService } from '../../../../core/facade/configurator-commons.service';
import { ConfiguratorTestUtils } from '../../../../testing/configurator-test-utils';
import { IconTestingModule, PopoverModule } from '@spartacus/storefront';
import { ConfiguratorAttributeMultiSelectionImageComponent } from './configurator-attribute-multi-selection-image.component';

class MockGroupService {}

Expand All @@ -44,10 +44,10 @@ class MockConfiguratorCommonsService {
}

class MockConfig {
features = [{ attributeTypesV2: false }];
features = [{ productConfiguratorAttributeTypesV2: false }];
}

describe('ConfigAttributeMultiSelectionImageComponent', () => {
describe('ConfiguratorAttributeMultiSelectionImageComponent', () => {
let component: ConfiguratorAttributeMultiSelectionImageComponent;
let fixture: ComponentFixture<ConfiguratorAttributeMultiSelectionImageComponent>;
let htmlElem: HTMLElement;
Expand Down Expand Up @@ -159,7 +159,7 @@ describe('ConfigAttributeMultiSelectionImageComponent', () => {
values: values,
};
config = TestBed.inject(Config);
config.features.attributeTypesV2 = false;
(config.features ?? {}).productConfiguratorAttributeTypesV2 = false;
fixture.detectChanges();
});

Expand All @@ -175,6 +175,8 @@ describe('ConfigAttributeMultiSelectionImageComponent', () => {
});

it('should render 2 info icons at value level when value has a description', () => {
(config.features ?? {}).productConfiguratorAttributeTypesV2 = true;
fixture.detectChanges();
CommonConfiguratorTestUtilsService.expectNumberOfElements(
expect,
htmlElem,
Expand All @@ -184,6 +186,8 @@ describe('ConfigAttributeMultiSelectionImageComponent', () => {
});

it('should render popover with description at value level after clicking on info icon', () => {
(config.features ?? {}).productConfiguratorAttributeTypesV2 = true;
fixture.detectChanges();
const infoButton = fixture.debugElement.query(
By.css('button[ng-reflect-cx-popover]')
).nativeElement;
Expand All @@ -193,7 +197,7 @@ describe('ConfigAttributeMultiSelectionImageComponent', () => {
);
expect(description).toBeTruthy();
expect(description.nativeElement.innerText).toBe(
component.attribute.values[1].description
(component.attribute.values ?? [{ description: '' }])[1]?.description
);
});

Expand Down Expand Up @@ -226,7 +230,7 @@ describe('ConfigAttributeMultiSelectionImageComponent', () => {
});

describe('select multi images', () => {
it('should call service for update when attributeTypesV2 feature flag is disabled', () => {
it('should call service for update when productConfiguratorAttributeTypesV2 feature flag is disabled', () => {
spyOn(
component['configuratorCommonsService'],
'updateConfiguration'
Expand All @@ -237,8 +241,8 @@ describe('ConfigAttributeMultiSelectionImageComponent', () => {
).toHaveBeenCalled();
});

it('should not call service in case uiType READ_ONLY_MULTI_SELECTION_IMAGE and attributeTypesV2 feature flag is enabled', () => {
config.features.attributeTypesV2 = true;
it('should not call service in case uiType READ_ONLY_MULTI_SELECTION_IMAGE and productConfiguratorAttributeTypesV2 feature flag is enabled', () => {
(config.features ?? {}).productConfiguratorAttributeTypesV2 = true;
spyOn(
component['configuratorCommonsService'],
'updateConfiguration'
Expand Down Expand Up @@ -267,8 +271,8 @@ describe('ConfigAttributeMultiSelectionImageComponent', () => {
});

describe('label styling', () => {
it('should set cursor to default in case attributeTypesV2 feature flag is enabled', () => {
config.features.attributeTypesV2 = true;
it('should set cursor to default in case productConfiguratorAttributeTypesV2 feature flag is enabled', () => {
(config.features ?? {}).productConfiguratorAttributeTypesV2 = true;
component.attribute.uiType =
Configurator.UiType.READ_ONLY_MULTI_SELECTION_IMAGE;
value1.selected = true;
Expand Down Expand Up @@ -335,6 +339,8 @@ describe('ConfigAttributeMultiSelectionImageComponent', () => {
});

it("should contain button elements with 'aria-label' attribute that point out that there is a description for the current value", () => {
(config.features ?? {}).productConfiguratorAttributeTypesV2 = true;
fixture.detectChanges();
CommonConfiguratorTestUtilsService.expectElementContainsA11y(
expect,
htmlElem,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class ConfiguratorAttributeMultiSelectionImageComponent
this.ownerKey = attributeComponentContext.owner.key;
this.expMode = attributeComponentContext.expMode;

useFeatureStyles('attributeTypesV2');
useFeatureStyles('productConfiguratorAttributeTypesV2');
}

attributeCheckBoxForms = new Array<UntypedFormControl>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class ConfiguratorAttributeSingleSelectionBundleDropdownComponent
);

this.group = attributeComponentContext.group.id;
useFeatureStyles('attributeTypesV2');
useFeatureStyles('productConfiguratorAttributeTypesV2');
}

ngOnInit() {
Expand Down
Loading

0 comments on commit 28f1bf2

Please sign in to comment.