Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src/components: add FormAddSubsidiary component for displaying subsidiary (address) form fields #728

Merged
merged 6 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/components/__tests__/FormAddCompany.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ const selectorFormTitle = 'form-add-company-title';
const selectorFormPermission = 'form-add-company-permission';
const selectorFormName = 'form-add-company-name';
const selectorFormVatId = 'form-add-company-vat-id';
const selectorFormStreet = 'form-add-company-street';
const selectorFormHouseNumber = 'form-add-company-house-number';
const selectorFormCity = 'form-add-company-city';
const selectorFormZip = 'form-add-company-zip';
const selectorFormCityChallenge = 'form-add-company-city-challenge';
const selectorFormDepartment = 'form-add-company-department';
const selectorFormStreet = 'form-add-subsidiary-street';
const selectorFormHouseNumber = 'form-add-subsidiary-house-number';
const selectorFormCity = 'form-add-subsidiary-city';
const selectorFormZip = 'form-add-subsidiary-zip';
const selectorFormCityChallenge = 'form-add-subsidiary-city-challenge';
const selectorFormDepartment = 'form-add-subsidiary-department';

describe('<FormAddCompany>', () => {
// default form state (make a deep copy of empty state)
Expand Down
128 changes: 128 additions & 0 deletions src/components/__tests__/FormAddSubsidiary.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { ref } from 'vue';
import FormAddSubsidiary from 'components/form/FormAddSubsidiary.vue';
import { i18n } from '../../boot/i18n';
import { vModelAdapter } from '../../../test/cypress/utils';
import { deepObjectWithSimplePropsCopy } from '../../../src/utils';

// selectors
const selectorFormStreet = 'form-add-subsidiary-street';
const selectorFormHouseNumber = 'form-add-subsidiary-house-number';
const selectorFormCity = 'form-add-subsidiary-city';
const selectorFormZip = 'form-add-subsidiary-zip';
const selectorFormCityChallenge = 'form-add-subsidiary-city-challenge';
const selectorFormDepartment = 'form-add-subsidiary-department';

// variables
const testData = {
street: 'Main Street',
houseNumber: '42',
city: 'Praha',
zip: '11000',
cityChallenge: '', // added from fixture
department: 'IT Department',
};

const emptyData = {
street: '',
houseNumber: '',
city: '',
zip: '',
cityChallenge: '',
department: '',
};

const model = ref(deepObjectWithSimplePropsCopy(emptyData));

describe('<FormAddSubsidiary>', () => {
it('has translation for all strings', () => {
cy.testLanguageStringsInContext([], 'index.component', i18n);
});

context('desktop', () => {
beforeEach(() => {
cy.fixture('cityChallengeResponse').then((cityChallengeResponse) => {
testData.cityChallenge = cityChallengeResponse.results[0].id;
cy.wrap(cityChallengeResponse.results[0]).as('cityChallenge');
});
model.value = deepObjectWithSimplePropsCopy(emptyData);
cy.mount(FormAddSubsidiary, {
props: {
...vModelAdapter(model),
},
});
cy.viewport('macbook-16');
});

coreTests();
desktopTests();
});

context('mobile', () => {
beforeEach(() => {
cy.fixture('cityChallengeResponse').then((cityChallengeResponse) => {
testData.cityChallenge = cityChallengeResponse.results[0].id;
cy.wrap(cityChallengeResponse.results[0]).as('cityChallenge');
});
model.value = deepObjectWithSimplePropsCopy(emptyData);
cy.mount(FormAddSubsidiary, {
props: {
...vModelAdapter(model),
},
});

cy.viewport('iphone-6');
});

coreTests();
});
});

function coreTests() {
it('renders component', () => {
// address fields
cy.dataCy(selectorFormStreet).should('be.visible');
cy.dataCy(selectorFormHouseNumber).should('be.visible');
cy.dataCy(selectorFormCity).should('be.visible');
cy.dataCy(selectorFormZip).should('be.visible');
cy.dataCy(selectorFormCityChallenge).should('be.visible');
cy.dataCy(selectorFormDepartment).should('be.visible');
});

it('updates model when fields are filled', () => {
// street
cy.dataCy(selectorFormStreet).find('input').type(testData.street);
cy.wrap(model).its('value.street').should('equal', testData.street);
// house number
cy.dataCy(selectorFormHouseNumber).find('input').type(testData.houseNumber);
cy.wrap(model)
.its('value.houseNumber')
.should('equal', testData.houseNumber);
// city
cy.dataCy(selectorFormCity).find('input').type(testData.city);
cy.wrap(model).its('value.city').should('equal', testData.city);
// ZIP
cy.dataCy(selectorFormZip).find('input').type(testData.zip);
cy.wrap(model).its('value.zip').should('equal', testData.zip);
// city challenge
cy.get('@cityChallenge').then((city) => {
cy.dataCy(selectorFormCityChallenge).click();
cy.get('.q-menu').contains(city.name).click();
cy.wrap(model)
.its('value.cityChallenge')
.should('equal', testData.cityChallenge);
});
// department
cy.dataCy(selectorFormDepartment).type(testData.department);
cy.wrap(model).its('value.department').should('equal', testData.department);
cy.wrap(model).should('deep.include', {
value: testData,
});
});
}

function desktopTests() {
it('renders some fields side by side', () => {
cy.testElementsSideBySide(selectorFormStreet, selectorFormHouseNumber);
cy.testElementsSideBySide(selectorFormCity, selectorFormZip);
});
}
9 changes: 9 additions & 0 deletions src/components/__tests__/FormFieldCompanyAddress.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ describe('<FormFieldCompanyAddress>', () => {
'buttonAddSubsidiary',
'hintAddress',
'labelAddress',
'textSubsidiaryAddress',
'titleAddAddress',
],
'form.company',
Expand Down Expand Up @@ -100,12 +101,20 @@ describe('<FormFieldCompanyAddress>', () => {
it('renders dialog for adding a new address', () => {
cy.dataCy('button-add-address').click();
cy.dataCy('dialog-add-address').should('be.visible');
// title
cy.dataCy('dialog-add-address')
.find('h3')
.should('be.visible')
.and('have.css', 'font-size', '20px')
.and('have.css', 'font-weight', '500')
.and('contain', i18n.global.t('form.company.titleAddAddress'));
// message
cy.dataCy('add-subsidiary-text')
.should('be.visible')
.and('contain', i18n.global.t('form.company.textSubsidiaryAddress'));
// form
cy.dataCy('form-add-subsidiary').should('be.visible');
// buttons
cy.dataCy('dialog-button-cancel')
.should('be.visible')
.and('have.text', i18n.global.t('navigation.discard'));
Expand Down
12 changes: 7 additions & 5 deletions src/components/__tests__/FormFieldSelectTable.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,13 @@ describe('<FormFieldSelectTable>', () => {
// fill in form
cy.dataCy('form-add-company-name').find('input').type('AutoMat');
cy.dataCy('form-add-company-vat-id').find('input').type('87654321');
cy.dataCy('form-add-company-street').find('input').type('Slezská');
cy.dataCy('form-add-company-house-number').find('input').type('2033/11');
cy.dataCy('form-add-company-city').find('input').type('Praha');
cy.dataCy('form-add-company-zip').find('input').type('120 00');
cy.dataCy('form-add-company-city-challenge').click();
cy.dataCy('form-add-subsidiary-street').find('input').type('Slezská');
cy.dataCy('form-add-subsidiary-house-number')
.find('input')
.type('2033/11');
cy.dataCy('form-add-subsidiary-city').find('input').type('Praha');
cy.dataCy('form-add-subsidiary-zip').find('input').type('120 00');
cy.dataCy('form-add-subsidiary-city-challenge').click();
cy.get('.q-menu').should('be.visible').find('.q-item').first().click();
// submit
cy.dataCy('dialog-button-submit').click();
Expand Down
8 changes: 8 additions & 0 deletions src/components/enums/Form.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export enum FormSubsidiaryAddressFields {
street = 'street',
houseNumber = 'houseNumber',
city = 'city',
zip = 'zip',
cityChallenge = 'cityChallenge',
department = 'deparment',
}
110 changes: 9 additions & 101 deletions src/components/form/FormAddCompany.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import { computed, defineComponent, nextTick, ref } from 'vue';

// components
import FormAddSubsidiary from './FormAddSubsidiary.vue';
import FormFieldTextRequired from '../global/FormFieldTextRequired.vue';
import FormFieldBusinessId from '../form/FormFieldBusinessId.vue';

Expand All @@ -42,11 +43,12 @@ import { useValidation } from '../../composables/useValidation';
import { OrganizationType } from '../types/Organization';

// types
import type { FormCompanyFields, FormOption } from '../types/Form';
import type { FormCompanyFields } from '../types/Form';

export default defineComponent({
name: 'FormAddCompany',
components: {
FormAddSubsidiary,
FormFieldTextRequired,
FormFieldBusinessId,
},
Expand All @@ -67,21 +69,6 @@ export default defineComponent({
setup(props, { emit }) {
const company = ref(props.modelValue);

const optionsCityChallenge: FormOption[] = [
{
label: 'City 1',
value: 'city-1',
},
{
label: 'City 2',
value: 'city-2',
},
{
label: 'City 3',
value: 'city-3',
},
];

const onUpdate = (): void => {
// wait for next tick to emit the value after update
nextTick((): void => {
Expand All @@ -103,7 +90,6 @@ export default defineComponent({
return {
addressIndex,
company,
optionsCityChallenge,
OrganizationType,
isVatShown,
isFilled,
Expand Down Expand Up @@ -168,90 +154,12 @@ export default defineComponent({
{{ $t('form.company.textSubsidiaryAddress') }}
</p>
</div>
<div class="row q-col-gutter-lg">
<div class="col-12 col-sm-6">
<form-field-text-required
v-model="company.address[addressIndex].street"
name="street"
label="form.labelStreet"
@update:model-value="onUpdate"
data-cy="form-add-company-street"
/>
</div>
<div class="col-12 col-sm-6">
<form-field-text-required
v-model="company.address[addressIndex].houseNumber"
name="houseNumber"
label="form.labelHouseNumber"
@update:model-value="onUpdate"
data-cy="form-add-company-house-number"
/>
</div>
<div class="col-12 col-sm-6">
<form-field-text-required
v-model="company.address[addressIndex].city"
name="city"
label="form.labelCity"
@update:model-value="onUpdate"
data-cy="form-add-company-city"
/>
</div>
<div class="col-12 col-sm-6">
<form-field-text-required
v-model="company.address[addressIndex].zip"
name="zip"
label="form.labelZip"
@update:model-value="onUpdate"
data-cy="form-add-company-zip"
/>
</div>
<div class="col-12">
<label
for="form-city-challenge"
class="text-caption text-bold text-gray-10"
>{{ $t('form.company.labelCityChallenge') }}</label
>
<q-select
dense
outlined
emit-value
map-options
v-model="company.address[addressIndex].cityChallenge"
:rules="[
(val) =>
isFilled(val) ||
$t('form.messageFieldRequired', {
fieldName: $t('form.labelCity'),
}),
]"
id="form-city-challenge"
:hint="$t('form.company.hintCityChallenge')"
:options="optionsCityChallenge"
class="q-mt-sm"
data-cy="form-add-company-city-challenge"
></q-select>
</div>
<div class="col-12">
<label
for="form-department"
class="text-caption text-bold text-gray-10"
>
{{ $t('form.company.labelDepartment') }}
</label>
<q-input
dense
outlined
lazy-rules
hide-bottom-space
v-model="company.address[addressIndex].department"
id="form-department"
name="department"
:hint="$t('form.company.hintDepartment')"
class="q-mt-sm"
data-cy="form-add-company-department"
/>
</div>
</div>
<!-- TODO: validate the method of accessing address -->
<form-add-subsidiary
v-model="company.address[addressIndex]"
@update:model-value="onUpdate"
data-cy="form-add-company-subsidiary"
/>
</div>
</div>
</template>
Loading
Loading