Skip to content
This repository has been archived by the owner on Apr 20, 2023. It is now read-only.

Commit

Permalink
Support import of transformation settings
Browse files Browse the repository at this point in the history
  • Loading branch information
pestevez committed Mar 12, 2018
1 parent 9ea73f8 commit a55459f
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 2 deletions.
7 changes: 6 additions & 1 deletion src/js/components/TransformationSettings.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class TransformationSettings extends React.Component<Props> {
name="audienceNetworkId"
placeholder="123456"
onChange={this.handleAudienceNetworkPlacementIdChanged}
value={this.props.settings.adsSettings.audienceNetworkPlacementId}
/>
</div>
</div>
Expand All @@ -89,6 +90,7 @@ class TransformationSettings extends React.Component<Props> {
placeholder="<script>...</script>"
onChange={this.handleAdsRawHtmlChanged}
rows="4"
value={this.props.settings.adsSettings.rawHtml}
/>
</div>
</div>
Expand Down Expand Up @@ -127,6 +129,7 @@ class TransformationSettings extends React.Component<Props> {
name="styleName"
placeholder="default"
onChange={this.handleStyleNameChanged}
value={this.props.settings.styleName}
/>
</div>
</div>
Expand All @@ -147,6 +150,7 @@ class TransformationSettings extends React.Component<Props> {
name="pixelId"
placeholder="123456"
onChange={this.handleFbPixelIdChanged}
value={this.props.settings.analyticsSettings.fbPixelId}
/>
</div>
<label className="sub-label" htmlFor="analyticsRawHtml">
Expand All @@ -160,6 +164,7 @@ class TransformationSettings extends React.Component<Props> {
placeholder="<script>...</script>"
onChange={this.handleAnalyticsRawHtmlChanged}
rows="4"
value={this.props.settings.analyticsSettings.rawHtml}
/>
</div>
</div>
Expand All @@ -172,9 +177,9 @@ class TransformationSettings extends React.Component<Props> {
</label>
<div className="field">
<select
defaultValue=""
name="adsType"
onChange={this.handleAdsTypeChanged}
value={this.props.settings.adsSettings.type}
>
<option value={AdsTypes.NONE}>None</option>
<option value={AdsTypes.AUDIENCE_NETWORK}>
Expand Down
57 changes: 56 additions & 1 deletion src/js/utils/RuleExporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ import { RulePropertyFactory } from '../models/RuleProperty';
import RulePropertyTypes from '../models/RulePropertyTypes';
import { RuleUtils } from '../utils/RuleUtils';
import { RulePropertyUtils } from '../utils/RulePropertyUtils';
import SettingsActions from '../data/SettingsActions';

export type JSONFormat = {
ads?: { audience_network_placement_id?: string, raw_html?: string },
analytics?: { fb_pixel_id?: string, raw_html?: string },
rules: RuleJSON[],
styleName?: string
style_name?: string
};

type RulePropertyJSON = {
Expand Down Expand Up @@ -65,6 +68,58 @@ class RuleExporter {
rules
.filter(rule => rule != null)
.forEach(rule => (rule != null ? RuleActions.addRule(rule) : null));

this.importSettings(json);
}

static importSettings(json: JSONFormat): void {
// Restore style name, if present
if (json.style_name) {
SettingsActions.editStyleName(json.style_name);
}

this.importAdsSettings(json);
this.importAnalyticsSettings(json);
}

static importAdsSettings(json: JSONFormat): void {
const { ads } = json;

// Restore Ads Settings, if present
if (ads) {
if (ads.audience_network_placement_id) {
SettingsActions.editAudienceNetworkPlacementId(
ads.audience_network_placement_id
);
SettingsActions.editAdsType(AdsTypes.AUDIENCE_NETWORK);
return;
} else if (ads.raw_html) {
SettingsActions.editAdsRawHtml(ads.raw_html);
SettingsActions.editAdsType(AdsTypes.RAW_HTML);
return;
}
}

SettingsActions.editAdsType(AdsTypes.NONE);
}

static importAnalyticsSettings(json: JSONFormat): void {
const { analytics } = json;
// Restore Analytics Settings, if present
if (!analytics) {
return;
}
const { fb_pixel_id: fbPixelId, raw_html: rawHtml } = analytics;

// Restore FB Pixel ID, if present
if (fbPixelId) {
SettingsActions.editFbPixelId(fbPixelId);
}

// Restore Analytics Raw HTML, if present
if (rawHtml) {
SettingsActions.editAnalyticsRawHtml(rawHtml);
}
}

static export(
Expand Down
164 changes: 164 additions & 0 deletions src/js/utils/__tests__/RuleExporter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@

import { Map, Set } from 'immutable';
import AdsTypes from '../../data/AdsTypes';
import RulesEditorDispatcher from '../../data/RulesEditorDispatcher';
import RuleExporter from '../RuleExporter';
import { RuleFactory } from '../../models/Rule';
import { RuleDefinitionFactory } from '../../models/RuleDefinition';
import { RulePropertyDefinitionFactory } from '../../models/RulePropertyDefinition';
import { RulePropertyFactory } from '../../models/RuleProperty';
import RulePropertyTypes from '../../models/RulePropertyTypes';
import SettingsActionTypes from '../../data/SettingsActionTypes';
import { TransformationSettingsFactory } from '../../models/TransformationSettings';

// Replace the default dispatcher with an automatic mock
jest.mock('../../data/RulesEditorDispatcher');

// Rules that are always included in the exported file
const defaultExportedRules = [{ class: 'TextNodeRule' }];

Expand Down Expand Up @@ -86,6 +91,29 @@ describe('RuleExporter', () => {
});

describe('Settings', () => {
beforeEach(() => {
// Clear information of previous calls to the dispatch mock function
RulesEditorDispatcher.dispatch.mockClear();
});

it('should import style name', () => {
const styleName = 'style' + Math.random().toString();
const importedObj = {
rules: [],
style_name: styleName,
};

RuleExporter.import(JSON.stringify(importedObj), Map());

// Inspect all the arguments (array) passed to the dispatch function
expect(RulesEditorDispatcher.dispatch.mock.calls).toContainEqual([
{
type: SettingsActionTypes.EDIT_STYLE_NAME,
styleName: styleName,
},
]);
});

it('should not export style name by default', () => {
const exported = RuleExporter.export(
Map(),
Expand All @@ -108,6 +136,100 @@ describe('RuleExporter', () => {
});

describe('Ads Settings', () => {
it('should import Audience Network Placement ID', () => {
const audienceNetworkPlacementId = Math.random().toString();
const importedObj = {
rules: [],
ads: {
audience_network_placement_id: audienceNetworkPlacementId,
},
};

RuleExporter.import(JSON.stringify(importedObj), Map());

// Inspect all the arguments (array) passed to the dispatch function
expect(RulesEditorDispatcher.dispatch.mock.calls).toContainEqual([
{
// Expected action to set AN ID
type: SettingsActionTypes.EDIT_AUDIENCE_NETWORK_PLACEMENT_ID,
audienceNetworkPlacementId: audienceNetworkPlacementId,
},
]);
expect(RulesEditorDispatcher.dispatch.mock.calls).toContainEqual([
{
// Expected action to set Ads type
type: SettingsActionTypes.EDIT_ADS_TYPE,
adsType: AdsTypes.AUDIENCE_NETWORK,
},
]);
});

it('should import Ads Raw HTML', () => {
const rawHtml = Math.random().toString();
const importedObj = {
rules: [],
ads: {
raw_html: rawHtml,
},
};

RuleExporter.import(JSON.stringify(importedObj), Map());

// Inspect all the arguments (array) passed to the dispatch function
expect(RulesEditorDispatcher.dispatch.mock.calls).toContainEqual([
{
// Expected action to set Raw HTML
type: SettingsActionTypes.EDIT_ADS_RAW_HTML,
adsRawHtml: rawHtml,
},
]);
expect(RulesEditorDispatcher.dispatch.mock.calls).toContainEqual([
{
// Expected action to set Ads type
type: SettingsActionTypes.EDIT_ADS_TYPE,
adsType: AdsTypes.RAW_HTML,
},
]);
});

it('should import no ads if null', () => {
const importedObj = {
rules: [],
// ads: undefined, Excluded
};

RuleExporter.import(JSON.stringify(importedObj), Map());

// Inspect all the arguments (array) passed to the dispatch function
expect(RulesEditorDispatcher.dispatch.mock.calls).toContainEqual([
{
// Expected action to set Raw HTML
type: SettingsActionTypes.EDIT_ADS_TYPE,
adsType: AdsTypes.NONE,
},
]);
});

it('should import no ads if no ads values', () => {
const importedObj = {
rules: [],
ads: {
// no ads values
},
};

RuleExporter.import(JSON.stringify(importedObj), Map());

// Inspect all the arguments (array) passed to the dispatch function
expect(RulesEditorDispatcher.dispatch.mock.calls).toContainEqual([
{
// Expected action to set Raw HTML
type: SettingsActionTypes.EDIT_ADS_TYPE,
adsType: AdsTypes.NONE,
},
]);
});

it('should not export Ads Settings by default', () => {
const exported = RuleExporter.export(Map());

Expand Down Expand Up @@ -210,6 +332,48 @@ describe('RuleExporter', () => {
});

describe('Analytics Settings', () => {
it('should import FB Pixel ID', () => {
const fbPixelId = Math.random().toString();
const importedObj = {
rules: [],
analytics: {
fb_pixel_id: fbPixelId,
},
};

RuleExporter.import(JSON.stringify(importedObj), Map());

// Inspect all the arguments (array) passed to the dispatch function
expect(RulesEditorDispatcher.dispatch.mock.calls).toContainEqual([
{
// Expected action to set FB Pixel ID
type: SettingsActionTypes.EDIT_FB_PIXEL_ID,
fbPixelId: fbPixelId,
},
]);
});

it('should import Analytics Raw HTML', () => {
const rawHtml = Math.random().toString();
const importedObj = {
rules: [],
analytics: {
raw_html: rawHtml,
},
};

RuleExporter.import(JSON.stringify(importedObj), Map());

// Inspect all the arguments (array) passed to the dispatch function
expect(RulesEditorDispatcher.dispatch.mock.calls).toContainEqual([
{
// Expected action to set Raw HTML
type: SettingsActionTypes.EDIT_ANALYTICS_RAW_HTML,
analyticsRawHtml: rawHtml,
},
]);
});

it('should not export Analytics Settings by default', () => {
const exported = RuleExporter.export(Map());

Expand Down

0 comments on commit a55459f

Please sign in to comment.