Skip to content
This repository was archived by the owner on Dec 7, 2021. It is now read-only.

Commit 94df15d

Browse files
tbarlow12wbreza
authored andcommitted
Added tests for project service
1 parent cc98d5f commit 94df15d

File tree

3 files changed

+143
-18
lines changed

3 files changed

+143
-18
lines changed

package-lock.json

Lines changed: 14 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/services/projectService.test.ts

Lines changed: 97 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ import _ from "lodash";
22
import ProjectService, { IProjectService } from "./projectService";
33
import MockFactory from "../common/mockFactory";
44
import { StorageProviderFactory } from "../providers/storage/storageProviderFactory";
5-
import { IProject, IExportFormat, ISecurityToken, AssetState } from "../models/applicationState";
5+
import { IProject, IExportFormat, ISecurityToken,
6+
AssetState, IAsset, IAssetMetadata } from "../models/applicationState";
67
import { constants } from "../common/constants";
78
import { ExportProviderFactory } from "../providers/export/exportProviderFactory";
89
import { generateKey } from "../common/crypto";
910
import { encryptProject } from "../common/utils";
11+
import { AssetService } from "./assetService";
1012

1113
describe("Project Service", () => {
1214
let projectSerivce: IProjectService = null;
@@ -146,15 +148,105 @@ describe("Project Service", () => {
146148
expect(projectSerivce.isDuplicate(testProject, projectList)).toEqual(true);
147149
});
148150

149-
it("deletes all asset metadata files when project is deleted", async () => {
150-
const assets = MockFactory.createTestAssets(10);
151+
function populateProjectAssets(project?: IProject, assetCount = 10) {
152+
if (!project) {
153+
project = MockFactory.createTestProject();
154+
}
155+
const assets = MockFactory.createTestAssets(assetCount);
151156
assets.forEach((asset) => {
152157
asset.state = AssetState.Tagged;
153158
});
154159

155-
testProject.assets = _.keyBy(assets, (asset) => asset.id);
160+
project.assets = _.keyBy(assets, (asset) => asset.id);
161+
return project;
162+
}
163+
164+
it("deletes all asset metadata files when project is deleted", async () => {
165+
const assetCount = 10;
166+
populateProjectAssets(testProject);
156167

157168
await projectSerivce.delete(testProject);
158-
expect(storageProviderMock.deleteFile.mock.calls).toHaveLength(assets.length + 1);
169+
expect(storageProviderMock.deleteFile.mock.calls).toHaveLength(assetCount + 1);
170+
});
171+
172+
it("Deletes tag from all assets within project", async () => {
173+
const tag1 = "tag1";
174+
const tag2 = "tag2";
175+
const region = MockFactory.createTestRegion(undefined, [tag1, tag2]);
176+
const asset: IAsset = {
177+
...MockFactory.createTestAsset("1"),
178+
state: AssetState.Tagged,
179+
};
180+
const assetMetadata = MockFactory.createTestAssetMetadata(asset, [region]);
181+
AssetService.prototype.getAssetMetadata = jest.fn((asset: IAsset) => Promise.resolve(assetMetadata));
182+
183+
const saveMetadata = jest.fn();
184+
AssetService.prototype.save = saveMetadata;
185+
186+
const expectedAssetMetadata: IAssetMetadata = {
187+
...MockFactory.createTestAssetMetadata(
188+
asset,
189+
[
190+
{
191+
...region,
192+
tags: [tag2],
193+
},
194+
],
195+
),
196+
197+
};
198+
const project = populateProjectAssets();
199+
await projectSerivce.deleteTag(project, tag1, assetMetadata);
200+
expect(saveMetadata).toBeCalledWith(expectedAssetMetadata);
201+
});
202+
203+
it("Deletes any empty regions after deleting only tag from region", async () => {
204+
const tag1 = "tag1";
205+
const region = MockFactory.createTestRegion(undefined, [tag1]);
206+
const asset: IAsset = {
207+
...MockFactory.createTestAsset("1"),
208+
state: AssetState.Tagged,
209+
};
210+
const assetMetadata = MockFactory.createTestAssetMetadata(asset, [region]);
211+
AssetService.prototype.getAssetMetadata = jest.fn((asset: IAsset) => Promise.resolve(assetMetadata));
212+
213+
const saveMetadata = jest.fn();
214+
AssetService.prototype.save = saveMetadata;
215+
216+
const expectedAssetMetadata: IAssetMetadata = MockFactory.createTestAssetMetadata(asset, []);
217+
const project = populateProjectAssets();
218+
await projectSerivce.deleteTag(project, tag1, assetMetadata);
219+
expect(saveMetadata).toBeCalledWith(expectedAssetMetadata);
220+
});
221+
222+
it("Updates renamed tag within all assets of project", async () => {
223+
const tag1 = "tag1";
224+
const newTag = "tag2";
225+
const region = MockFactory.createTestRegion(undefined, [tag1]);
226+
const asset: IAsset = {
227+
...MockFactory.createTestAsset("1"),
228+
state: AssetState.Tagged,
229+
};
230+
const assetMetadata = MockFactory.createTestAssetMetadata(asset, [region]);
231+
AssetService.prototype.getAssetMetadata = jest.fn((asset: IAsset) => Promise.resolve(assetMetadata));
232+
233+
const saveMetadata = jest.fn();
234+
AssetService.prototype.save = saveMetadata;
235+
236+
const expectedAssetMetadata: IAssetMetadata = {
237+
...MockFactory.createTestAssetMetadata(
238+
asset,
239+
[
240+
{
241+
...region,
242+
tags: [newTag],
243+
},
244+
],
245+
),
246+
247+
};
248+
const project = populateProjectAssets();
249+
await projectSerivce.renameTag(project, tag1, newTag, assetMetadata);
250+
expect(saveMetadata).toBeCalledWith(expectedAssetMetadata);
159251
});
160252
});

src/services/projectService.ts

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ export interface IProjectService {
2020
save(project: IProject, securityToken: ISecurityToken): Promise<IProject>;
2121
delete(project: IProject): Promise<void>;
2222
isDuplicate(project: IProject, projectList: IProject[]): boolean;
23-
deleteTag(project: IProject, tagName: string, currentAsset: IAssetMetadata): Promise<IAssetMetadata>;
24-
renameTag(project: IProject, tagName: string, newTagName: string, currentAsset: IAssetMetadata): Promise<IAssetMetadata>;
23+
deleteTag(project: IProject, tagName: string,
24+
currentAsset: IAssetMetadata): Promise<IAssetMetadata>;
25+
renameTag(project: IProject, tagName: string, newTagName: string,
26+
currentAsset: IAssetMetadata): Promise<IAssetMetadata>;
2527
}
2628

2729
/**
@@ -111,8 +113,9 @@ export default class ProjectService implements IProjectService {
111113
* @param currentAsset Current asset being viewed. Makes changes and returns updated asset to avoid
112114
* needing to reload the asset in the editor page
113115
*/
114-
public async deleteTag(project: IProject, tagName: string, currentAsset: IAssetMetadata): Promise<IAssetMetadata> {
115-
const transformer = (tags) => tags.filter((t) => t!== tagName);
116+
public async deleteTag(project: IProject, tagName: string,
117+
currentAsset: IAssetMetadata): Promise<IAssetMetadata> {
118+
const transformer = (tags) => tags.filter((t) => t !== tagName);
116119
return await this.updateProjectTags(project, tagName, currentAsset, transformer);
117120
}
118121

@@ -123,7 +126,8 @@ export default class ProjectService implements IProjectService {
123126
* @param currentAsset Current asset being viewed. Makes changes and returns updated asset to avoid
124127
* needing to reload the asset in the editor page
125128
*/
126-
public async renameTag(project: IProject, tagName: string, newTagName: string, currentAsset: IAssetMetadata): Promise<IAssetMetadata> {
129+
public async renameTag(project: IProject, tagName: string, newTagName: string,
130+
currentAsset: IAssetMetadata): Promise<IAssetMetadata> {
127131
const transformer = (tags) => tags.map((t) => (t === tagName) ? newTagName : t);
128132
return await this.updateProjectTags(project, tagName, currentAsset, transformer);
129133
}
@@ -136,9 +140,27 @@ export default class ProjectService implements IProjectService {
136140
* needing to reload the asset in the editor page
137141
* @param transformer Function that accepts array of tags from a region and returns a modified array of tags
138142
*/
139-
private async updateProjectTags(project: IProject, tagName: string, currentAsset: IAssetMetadata, transformer: (tags: string[]) => string[]) {
143+
private async updateProjectTags(project: IProject, tagName: string, currentAsset: IAssetMetadata,
144+
transformer: (tags: string[]) => string[]): Promise<IAssetMetadata> {
140145
const assetService = new AssetService(project);
141146
const assetKeys = Object.keys(project.assets);
147+
// Loop over assets and update if necessary
148+
for (const assetKey of assetKeys) {
149+
const asset = project.assets[assetKey];
150+
if (asset.state !== AssetState.Tagged) {
151+
return;
152+
}
153+
const assetMetadata = await assetService.getAssetMetadata(asset);
154+
const updatedAssetMetadata = this.updateTagInAssetMetadata(assetMetadata, tagName, transformer);
155+
if (updatedAssetMetadata) {
156+
await assetService.save(updatedAssetMetadata);
157+
}
158+
}
159+
/*
160+
TODO: Replace with async
161+
162+
For some reason in tests, the `forEachAsync` is not recognized as a function
163+
142164
await assetKeys.forEachAsync(async (assetKey) => {
143165
const asset = project.assets[assetKey];
144166
if (asset.state !== AssetState.Tagged) {
@@ -150,6 +172,8 @@ export default class ProjectService implements IProjectService {
150172
await assetService.save(updatedAssetMetadata);
151173
}
152174
});
175+
176+
*/
153177
return this.updateTagInAssetMetadata(currentAsset, tagName, transformer);
154178
}
155179

@@ -160,7 +184,8 @@ export default class ProjectService implements IProjectService {
160184
* @param transformer Function that accepts array of tags from a region and returns a modified array of tags
161185
* @returns Modified asset metadata object or null if object does not need to be modified
162186
*/
163-
private updateTagInAssetMetadata(assetMetadata: IAssetMetadata, tagName: string, transformer: (tags: string[]) => string[]) {
187+
private updateTagInAssetMetadata(assetMetadata: IAssetMetadata, tagName: string,
188+
transformer: (tags: string[]) => string[]): IAssetMetadata {
164189
let foundTag = false;
165190
for (const region of assetMetadata.regions) {
166191
if (region.tags.find((t) => t === tagName)) {

0 commit comments

Comments
 (0)