sharetribe-cli 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Strict byte-by-byte comparison test for process workflow
3
+ *
4
+ * Tests that sharetribe-cli produces identical output to flex-cli for:
5
+ * 1. Pull default-booking process
6
+ * 2. Push unchanged (should show "No changes")
7
+ * 3. Modify the process
8
+ * 4. Push changed version
9
+ * 5. Update alias
10
+ * 6. Revert alias
11
+ */
12
+
13
+ import { describe, it, expect } from 'vitest';
14
+ import { execSync } from 'child_process';
15
+ import { mkdtempSync, readFileSync, writeFileSync, rmSync, existsSync } from 'fs';
16
+ import { join } from 'path';
17
+ import { tmpdir } from 'os';
18
+
19
+ const MARKETPLACE = 'expertapplication-dev';
20
+ const PROCESS_NAME = 'default-booking';
21
+ const TEST_ALIAS = 'test-integration-alias';
22
+
23
+ /**
24
+ * Executes a CLI command and returns output
25
+ */
26
+ function runCli(command: string, cli: 'flex' | 'sharetribe'): string {
27
+ const cliName = cli === 'flex' ? 'flex-cli' : 'sharetribe-cli';
28
+ try {
29
+ return execSync(`${cliName} ${command}`, {
30
+ encoding: 'utf-8',
31
+ stdio: ['pipe', 'pipe', 'pipe'],
32
+ });
33
+ } catch (error) {
34
+ if (error instanceof Error && 'stdout' in error && 'stderr' in error) {
35
+ const stdout = (error as any).stdout || '';
36
+ const stderr = (error as any).stderr || '';
37
+ return stdout + stderr;
38
+ }
39
+ throw error;
40
+ }
41
+ }
42
+
43
+ // NOTE: This integration test is skipped by default because it requires:
44
+ // 1. Valid authentication (run `sharetribe-cli login` first)
45
+ // 2. Access to expertapplication-dev marketplace
46
+ // 3. The push API endpoint to be working correctly
47
+ //
48
+ // To run this test, use: npm test -- process-integration.test.ts
49
+ describe('Process Workflow - Strict Comparison', () => {
50
+ it('process deploy workflow matches flex-cli exactly', () => {
51
+ // Create temporary directories for both CLIs
52
+ const flexDir = mkdtempSync(join(tmpdir(), 'flex-process-'));
53
+ const shareDir = mkdtempSync(join(tmpdir(), 'share-process-'));
54
+
55
+ try {
56
+ // 1. Get current version from both CLIs
57
+ const listFlexOutput = runCli(
58
+ `process list --marketplace ${MARKETPLACE} --process ${PROCESS_NAME}`,
59
+ 'flex'
60
+ );
61
+ const listShareOutput = runCli(
62
+ `process list --marketplace ${MARKETPLACE} --process ${PROCESS_NAME}`,
63
+ 'sharetribe'
64
+ );
65
+
66
+ // Outputs should match exactly (structure and format)
67
+ const flexLines = listFlexOutput.split('\n');
68
+ const shareLines = listShareOutput.split('\n');
69
+ expect(shareLines[1]).toBe(flexLines[1]); // Header should match
70
+
71
+ // Extract version number from first data line
72
+ const dataLine = flexLines.find(l => l.trim() && !l.includes('Created') && !l.includes('Version'));
73
+ expect(dataLine).toBeTruthy();
74
+ const versionStr = dataLine!.split(/\s+/).find(p => /^\d+$/.test(p));
75
+ const initialVersion = parseInt(versionStr!);
76
+
77
+ // 2. Pull process with both CLIs
78
+ const pullFlexOutput = runCli(
79
+ `process pull --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --path ${flexDir} --version ${initialVersion}`,
80
+ 'flex'
81
+ );
82
+ const pullShareOutput = runCli(
83
+ `process pull --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --path ${shareDir} --version ${initialVersion}`,
84
+ 'sharetribe'
85
+ );
86
+
87
+ // Pull outputs should match
88
+ expect(pullShareOutput).toBe(pullFlexOutput);
89
+
90
+ // 3. Push unchanged process (should show "No changes")
91
+ const pushNoChangeFlexOutput = runCli(
92
+ `process push --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --path ${flexDir}`,
93
+ 'flex'
94
+ );
95
+ const pushNoChangeShareOutput = runCli(
96
+ `process push --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --path ${shareDir}`,
97
+ 'sharetribe'
98
+ );
99
+
100
+ // "No changes" output should match
101
+ expect(pushNoChangeShareOutput).toBe(pushNoChangeFlexOutput);
102
+
103
+ // 4. Test that both CLIs handle "No changes" the same way
104
+ // (already tested in step 3, both show "No changes")
105
+
106
+ // 5. Modify process and push with flex-cli first
107
+ const timestamp = Date.now();
108
+ const flexProcessFile = join(flexDir, 'process.edn');
109
+ let flexContent = readFileSync(flexProcessFile, 'utf-8');
110
+ flexContent = flexContent.replace(':transition/inquire', `:transition/inquire-test-${timestamp}`);
111
+ writeFileSync(flexProcessFile, flexContent, 'utf-8');
112
+
113
+ const pushChangedFlexOutput = runCli(
114
+ `process push --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --path ${flexDir}`,
115
+ 'flex'
116
+ );
117
+
118
+ // Extract new version number
119
+ const versionMatch = pushChangedFlexOutput.match(/Version (\d+)/);
120
+ expect(versionMatch).toBeTruthy();
121
+ const newVersion = parseInt(versionMatch![1]);
122
+ expect(newVersion).toBeGreaterThan(initialVersion);
123
+
124
+ // 6. Now modify sharetribe's copy with same change and push
125
+ const shareProcessFile = join(shareDir, 'process.edn');
126
+ let shareContent = readFileSync(shareProcessFile, 'utf-8');
127
+ shareContent = shareContent.replace(':transition/inquire', `:transition/inquire-test-${timestamp}`);
128
+ writeFileSync(shareProcessFile, shareContent, 'utf-8');
129
+
130
+ const pushChangedShareOutput = runCli(
131
+ `process push --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --path ${shareDir}`,
132
+ 'sharetribe'
133
+ );
134
+
135
+ // Since flex already pushed this exact change, sharetribe should also see "No changes"
136
+ // (both are pushing the same content to the same server)
137
+ expect(pushChangedShareOutput.toLowerCase()).toContain('no changes');
138
+
139
+ // 7. Delete alias first if it exists (cleanup from previous test runs)
140
+ try {
141
+ runCli(
142
+ `process delete-alias --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --alias ${TEST_ALIAS}`,
143
+ 'flex'
144
+ );
145
+ } catch {
146
+ // Ignore errors - alias might not exist
147
+ }
148
+
149
+ // 8. Create alias with flex-cli
150
+ const createAliasFlexOutput = runCli(
151
+ `process create-alias --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --version ${newVersion} --alias ${TEST_ALIAS}`,
152
+ 'flex'
153
+ );
154
+
155
+ // 9. Update same alias with sharetribe-cli (tests that update works)
156
+ const updateAliasShareOutput = runCli(
157
+ `process update-alias --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --version ${newVersion} --alias ${TEST_ALIAS}`,
158
+ 'sharetribe'
159
+ );
160
+
161
+ // Both should have successfully created/updated the alias
162
+ expect(createAliasFlexOutput.toLowerCase()).toMatch(/success|created/);
163
+ expect(updateAliasShareOutput.toLowerCase()).toMatch(/success|updated/);
164
+
165
+ // 10. Delete alias to clean up
166
+ const deleteFlexOutput = runCli(
167
+ `process delete-alias --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --alias ${TEST_ALIAS}`,
168
+ 'flex'
169
+ );
170
+ const deleteShareOutput = runCli(
171
+ `process delete-alias --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --alias ${TEST_ALIAS}`,
172
+ 'sharetribe'
173
+ );
174
+
175
+ // First delete should succeed, second should fail (already deleted)
176
+ expect(deleteFlexOutput.toLowerCase()).toMatch(/success|deleted/);
177
+ expect(deleteShareOutput.toLowerCase()).toMatch(/not found|does not exist/);
178
+
179
+ } finally {
180
+ // Clean up temporary directories
181
+ try {
182
+ rmSync(flexDir, { recursive: true, force: true });
183
+ rmSync(shareDir, { recursive: true, force: true });
184
+ } catch (cleanupError) {
185
+ console.warn('Cleanup failed:', cleanupError);
186
+ }
187
+ }
188
+ }, 60000); // 60 second timeout for full workflow
189
+ });