Skip to content

Commit e0accee

Browse files
committed
Remove most of the engagement workflow tests / Replace with a couple late start & early end tests
Mostly, we just want the engagement status to follow the project status. This is already being tested in engagement.e2e-spec.ts. So I removed all of these. I did add a couple where we think users will be directly interacting with the engagement workflow
1 parent cceaf88 commit e0accee

File tree

3 files changed

+130
-182
lines changed

3 files changed

+130
-182
lines changed
Lines changed: 36 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -1,212 +1,69 @@
11
import { Role } from '~/common';
22
import { EngagementStatus } from '../src/components/engagement/dto';
3-
import { ProjectStep, ProjectType } from '../src/components/project/dto';
43
import {
5-
createFundingAccount,
6-
createInternshipEngagement,
74
createLanguageEngagement,
8-
createLocation,
95
createProject,
10-
createRegion,
116
createSession,
127
createTestApp,
13-
getCurrentEngagementStatus,
148
registerUser,
15-
runAsAdmin,
169
TestApp,
17-
updateProject,
10+
TestUser,
1811
} from './utility';
19-
import {
20-
changeLanguageEngagementStatus,
21-
transitionEngagementToActive,
22-
} from './utility/transition-engagement';
23-
import {
24-
changeProjectStep,
25-
stepsFromEarlyConversationToBeforeActive,
26-
} from './utility/transition-project';
12+
import { EngagementWorkflowTester } from './utility/engagement-workflow.tester';
13+
import { RawLanguageEngagement, RawProject } from './utility/fragments';
14+
import { forceProjectTo } from './utility/transition-project';
2715

2816
describe('Engagement-Workflow e2e', () => {
2917
let app: TestApp;
18+
let projectManager: TestUser;
19+
let controller: TestUser;
20+
let project: RawProject;
21+
let engagement: RawLanguageEngagement;
3022

3123
beforeAll(async () => {
3224
app = await createTestApp();
3325
await createSession(app);
3426

35-
await registerUser(app, {
36-
roles: [Role.ProjectManager, Role.Controller],
27+
controller = await registerUser(app, {
28+
roles: [Role.Controller],
29+
});
30+
projectManager = await registerUser(app, {
31+
roles: [Role.ProjectManager],
32+
});
33+
34+
project = await createProject(app, {});
35+
engagement = await createLanguageEngagement(app, {
36+
projectId: project.id,
3737
});
38+
await forceProjectTo(app, project.id, 'Active');
3839
});
3940
afterAll(async () => {
4041
await app.close();
4142
});
42-
43-
it("should have engagement status 'InDevelopment' when add language or internship engagement", async () => {
44-
// --- Translation Project with engagement
45-
const transProject = await createProject(app, {
46-
type: ProjectType.MomentumTranslation,
47-
});
48-
49-
const langEngagement = await createLanguageEngagement(app, {
50-
projectId: transProject.id,
51-
});
52-
expect(langEngagement.status.value).toBe(EngagementStatus.InDevelopment);
53-
54-
// --- Intern Project with engagement
55-
const internProject = await createProject(app, {
56-
type: ProjectType.Internship,
57-
});
58-
const internEngagement = await createInternshipEngagement(app, {
59-
projectId: internProject.id,
60-
});
61-
expect(internEngagement.status.value).toBe(EngagementStatus.InDevelopment);
43+
beforeEach(async () => {
44+
await projectManager.login();
6245
});
6346

64-
describe('should test engagement status Active when Project is made Active', () => {
65-
it('translation', async function () {
66-
// --- Translation project
67-
const transProject = await createProject(app, {
68-
type: ProjectType.MomentumTranslation,
69-
});
70-
const langEngagement = await createLanguageEngagement(app, {
71-
projectId: transProject.id,
72-
});
73-
await runAsAdmin(app, async () => {
74-
const fundingAccount = await createFundingAccount(app);
75-
const location = await createLocation(app, {
76-
fundingAccountId: fundingAccount.id,
77-
});
78-
const fieldRegion = await createRegion(app);
79-
await updateProject(app, {
80-
id: transProject.id,
81-
primaryLocationId: location.id,
82-
fieldRegionId: fieldRegion.id,
83-
});
84-
for (const next of stepsFromEarlyConversationToBeforeActive) {
85-
await changeProjectStep(app, transProject.id, next);
86-
}
87-
await changeProjectStep(app, transProject.id, ProjectStep.Active);
88-
});
89-
const lEngagementStatus = await getCurrentEngagementStatus(
90-
app,
91-
langEngagement.id,
92-
);
93-
expect(lEngagementStatus.status.value).toBe(EngagementStatus.Active);
47+
it('Start Late', async () => {
48+
const lateEng = await createLanguageEngagement(app, {
49+
projectId: project.id,
9450
});
95-
it('internship', async function () {
96-
// --- Internship project
97-
const internProject = await createProject(app, {
98-
type: ProjectType.Internship,
99-
});
100-
const internEngagement = await createInternshipEngagement(app, {
101-
projectId: internProject.id,
102-
});
103-
await runAsAdmin(app, async () => {
104-
const fundingAccount = await createFundingAccount(app);
105-
const location = await createLocation(app, {
106-
fundingAccountId: fundingAccount.id,
107-
});
108-
const fieldRegion = await createRegion(app);
51+
const eng = await EngagementWorkflowTester.for(app, lateEng.id);
52+
expect(eng.state).toBe(EngagementStatus.InDevelopment);
10953

110-
await updateProject(app, {
111-
id: internProject.id,
112-
primaryLocationId: location.id,
113-
fieldRegionId: fieldRegion.id,
114-
});
115-
for (const next of stepsFromEarlyConversationToBeforeActive) {
116-
await changeProjectStep(app, internProject.id, next);
117-
}
118-
await changeProjectStep(app, internProject.id, ProjectStep.Active);
119-
});
120-
const lEngagementStatus = await getCurrentEngagementStatus(
121-
app,
122-
internEngagement.id,
123-
);
124-
expect(lEngagementStatus.status.value).toBe(EngagementStatus.Active);
125-
});
54+
await controller.login();
55+
await eng.executeByLabel('Approve');
56+
expect(eng.state).toBe(EngagementStatus.Active);
12657
});
12758

128-
describe('Workflow', () => {
129-
it('engagement completed', async function () {
130-
// --- Engagement to Active
131-
const transProject = await createProject(app, {
132-
type: ProjectType.MomentumTranslation,
133-
});
134-
const langEngagement = await createLanguageEngagement(app, {
135-
projectId: transProject.id,
136-
});
137-
await transitionEngagementToActive(
138-
app,
139-
transProject.id,
140-
langEngagement.id,
141-
);
142-
await runAsAdmin(app, async function () {
143-
await changeProjectStep(
144-
app,
145-
transProject.id,
146-
ProjectStep.DiscussingChangeToPlan,
147-
);
148-
});
149-
await changeLanguageEngagementStatus(
150-
app,
151-
langEngagement.id,
152-
EngagementStatus.ActiveChangedPlan,
153-
);
154-
await runAsAdmin(app, async function () {
155-
await changeProjectStep(app, transProject.id, ProjectStep.Active);
156-
});
157-
await changeLanguageEngagementStatus(
158-
app,
159-
langEngagement.id,
160-
EngagementStatus.FinalizingCompletion,
161-
);
162-
await changeLanguageEngagementStatus(
163-
app,
164-
langEngagement.id,
165-
EngagementStatus.Completed,
166-
);
167-
});
168-
169-
it('engagement terminated', async function () {
170-
const transProject = await createProject(app, {
171-
type: ProjectType.MomentumTranslation,
172-
});
173-
const langEngagement = await createLanguageEngagement(app, {
174-
projectId: transProject.id,
175-
});
176-
await transitionEngagementToActive(
177-
app,
178-
transProject.id,
179-
langEngagement.id,
180-
);
59+
it('End Early', async () => {
60+
const eng = await EngagementWorkflowTester.for(app, engagement.id);
61+
expect(eng.state).toBe(EngagementStatus.Active);
18162

182-
await runAsAdmin(app, async function () {
183-
await changeProjectStep(
184-
app,
185-
transProject.id,
186-
ProjectStep.DiscussingChangeToPlan,
187-
);
188-
});
63+
await eng.executeByLabel('Finalize Completion');
18964

190-
await changeLanguageEngagementStatus(
191-
app,
192-
langEngagement.id,
193-
EngagementStatus.DiscussingSuspension,
194-
);
195-
await changeLanguageEngagementStatus(
196-
app,
197-
langEngagement.id,
198-
EngagementStatus.Suspended,
199-
);
200-
await changeLanguageEngagementStatus(
201-
app,
202-
langEngagement.id,
203-
EngagementStatus.DiscussingTermination,
204-
);
205-
await changeLanguageEngagementStatus(
206-
app,
207-
langEngagement.id,
208-
EngagementStatus.Terminated,
209-
);
210-
});
65+
await controller.login();
66+
await eng.executeByState('Completed');
67+
expect(eng.state).toBe(EngagementStatus.Completed);
21168
});
21269
});
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { ID } from '~/common';
2+
import { IEngagement } from '../../src/components/engagement/dto';
3+
import {
4+
EngagementWorkflowTransition,
5+
ExecuteEngagementTransitionInput,
6+
} from '../../src/components/engagement/workflow/dto';
7+
import { EngagementWorkflow } from '../../src/components/engagement/workflow/engagement-workflow';
8+
import { TestApp } from './create-app';
9+
import { gql } from './gql-tag';
10+
import { Raw } from './raw.type';
11+
import { WorkflowTester } from './workflow.tester';
12+
13+
export class EngagementWorkflowTester extends WorkflowTester<
14+
typeof EngagementWorkflow
15+
> {
16+
static async for(app: TestApp, id: ID) {
17+
const { status: initial } = await EngagementWorkflowTester.getState(
18+
app,
19+
id,
20+
);
21+
return new EngagementWorkflowTester(app, id, initial.value!);
22+
}
23+
24+
protected async fetchTransitions() {
25+
const eng = await EngagementWorkflowTester.getState(this.app, this.id);
26+
return eng.status.transitions;
27+
}
28+
29+
protected async doExecute(input: ExecuteEngagementTransitionInput) {
30+
const result = await this.app.graphql.mutate(
31+
gql`
32+
mutation TransitionEngagement(
33+
$input: ExecuteEngagementTransitionInput!
34+
) {
35+
transitionEngagement(input: $input) {
36+
status {
37+
value
38+
transitions {
39+
key
40+
label
41+
to
42+
type
43+
disabled
44+
disabledReason
45+
}
46+
}
47+
}
48+
}
49+
`,
50+
{ input },
51+
);
52+
const res = await (result.transitionEngagement as ReturnType<
53+
(typeof EngagementWorkflowTester)['getState']
54+
>);
55+
return {
56+
state: res.status.value!,
57+
transitions: res.status.transitions,
58+
};
59+
}
60+
61+
static async getState(app: TestApp, id: ID) {
62+
const result = await app.graphql.query(
63+
gql`
64+
query EngagementTransitions($engagement: ID!) {
65+
engagement(id: $engagement) {
66+
status {
67+
value
68+
transitions {
69+
key
70+
label
71+
to
72+
type
73+
disabled
74+
disabledReason
75+
}
76+
}
77+
statusModifiedAt {
78+
value
79+
}
80+
}
81+
}
82+
`,
83+
{ engagement: id },
84+
);
85+
return result.engagement as Raw<
86+
Pick<IEngagement, 'status' | 'statusModifiedAt'> & {
87+
status: { transitions: EngagementWorkflowTransition[] };
88+
}
89+
>;
90+
}
91+
}

test/utility/workflow.tester.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,14 @@ export abstract class WorkflowTester<
8383
private cachedTransitions: {
8484
state: W['state'];
8585
actorId: string;
86-
transitions: Transition[];
86+
transitions: readonly Transition[];
8787
};
8888

89-
protected abstract fetchTransitions(): Promise<Transition[]>;
89+
protected abstract fetchTransitions(): Promise<readonly Transition[]>;
9090

9191
protected abstract doExecute(
9292
input: InstanceType<ReturnType<typeof ExecuteTransitionInput<W['state']>>>,
93-
): Promise<{ state: W['state']; transitions: Transition[] }>;
93+
): Promise<{ state: W['state']; transitions: readonly Transition[] }>;
9494
}
9595

9696
export class ProjectWorkflowTester extends WorkflowTester<

0 commit comments

Comments
 (0)