Skip to content

Commit

Permalink
Updates 'teams cache remove' command to support the new client. Closes
Browse files Browse the repository at this point in the history
  • Loading branch information
MathijsVerbeeck authored and Adam-it committed Oct 30, 2024
1 parent b184dfb commit 37fe144
Show file tree
Hide file tree
Showing 4 changed files with 240 additions and 46 deletions.
11 changes: 10 additions & 1 deletion docs/docs/cmd/teams/cache/cache-remove.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ m365 teams cache remove [options]
## Options

```md definition-list
`-c, --client`
: Teams client to target. Possible values are: `new` or `classic`. Default value is `new`.

`-f, --force`
: Don't prompt for confirmation
```
Expand Down Expand Up @@ -43,12 +46,18 @@ The command works only on Windows and macOS. If you run it on a different operat

## Examples

Removes the Microsoft Teams client cache
Removes the Microsoft Teams client cache for the new client.

```sh
m365 teams cache remove
```

Removes the Microsoft Teams client cache for the classic client.

```sh
m365 teams cache remove --client classic
```

## Response

The command won't return a response on success.
Expand Down
12 changes: 12 additions & 0 deletions docs/docs/v10-upgrade-guidance.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,18 @@ Please update your scripts not to use the `overwrite` option.

## Teams

### Enhanced `teams cache remove` command

We enhanced the [teams cache remove](./cmd/teams/cache/cache-remove.mdx) command to support the removal of the cache from the new Teams client. We also made it so that by default, the command will remove the cache for the `new` client.

To still support the old client, we have added the option `--client`, in which you can specify `classic` as value to remove the cache of the old Teams client.

#### What action do I need to take?

Add the `--client` option to your scripts to specify which client's cache you want to remove. Otherwise, upon the release of v10, it will attempt to remove the cache from the new client.

## Teams

### Removes duplicate property from 'teams tab list' command.

For the [teams tab list](./cmd/teams/tab/tab-list.mdx) command we removed the `teamsAppTabId` from the command output as it was a duplicate of the `teamsApp/id` property.
Expand Down
150 changes: 139 additions & 11 deletions src/m365/teams/commands/cache/cache-remove.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { session } from '../../../../utils/session.js';
import { sinonUtil } from '../../../../utils/sinonUtil.js';
import commands from '../../commands.js';
import command from './cache-remove.js';
import os, { homedir } from 'os';

describe(commands.CACHE_REMOVE, () => {
const processOutput = `ProcessId
Expand All @@ -20,6 +21,7 @@ describe(commands.CACHE_REMOVE, () => {
11352`;
let log: string[];
let logger: Logger;
let loggerLogSpy: sinon.SinonSpy;
let commandInfo: CommandInfo;

before(() => {
Expand All @@ -45,6 +47,7 @@ describe(commands.CACHE_REMOVE, () => {
log.push(msg);
}
};
loggerLogSpy = sinon.spy(logger, 'log');

sinon.stub(cli, 'promptForConfirmation').resolves(true);
});
Expand Down Expand Up @@ -84,6 +87,16 @@ describe(commands.CACHE_REMOVE, () => {
assert(confirmationStub.calledOnce);
});

it('fails validation if client is not a valid client option', async () => {
sinon.stub(process, 'platform').value('win32');
const actual = await command.validate({
options: {
client: 'invalid'
}
}, commandInfo);
assert.notStrictEqual(actual, true);
});

it('fails validation if called from docker container.', async () => {
sinon.stub(process, 'platform').value('win32');
sinon.stub(process, 'env').value({ 'CLIMICROSOFT365_ENV': 'docker' });
Expand Down Expand Up @@ -114,7 +127,7 @@ describe(commands.CACHE_REMOVE, () => {
assert.strictEqual(actual, true);
});

it('fails to remove teams cache when exec fails randomly when killing teams.exe process', async () => {
it('fails to remove teams cache when exec fails randomly when killing teams.exe process using classic client', async () => {
sinon.stub(process, 'platform').value('win32');
sinon.stub(process, 'env').value({ 'CLIMICROSOFT365_ENV': '' });
sinon.stub(fs, 'existsSync').returns(true);
Expand All @@ -125,10 +138,10 @@ describe(commands.CACHE_REMOVE, () => {
}
throw 'Invalid request';
});
await assert.rejects(command.action(logger, { options: { force: true } } as any), new CommandError('random error'));
await assert.rejects(command.action(logger, { options: { client: 'classic', force: true } } as any), new CommandError('random error'));
});

it('fails to remove teams cache when exec fails randomly when removing cache folder', async () => {
it('fails to remove teams cache when exec fails randomly when removing cache folder using classic client', async () => {
sinon.stub(process, 'platform').value('win32');
sinon.stub(process, 'env').value({ 'CLIMICROSOFT365_ENV': '', APPDATA: 'C:\\Users\\Administrator\\AppData\\Roaming' });
sinon.stub(process, 'kill' as any).returns(null);
Expand All @@ -143,10 +156,41 @@ describe(commands.CACHE_REMOVE, () => {
}
throw 'Invalid request';
});
await assert.rejects(command.action(logger, { options: { force: true } } as any), new CommandError('random error'));
await assert.rejects(command.action(logger, { options: { client: 'classic', force: true } } as any), new CommandError('random error'));
});

it('shows error message when exec fails when removing the teams cache folder on mac os', async () => {
const deleteError = {
code: 1,
killed: false,
signal: null,
cmd: 'rm -r "/Users/John/Library/Group Containers/UBF8T346G9.com.microsoft.teams"',
stdout: '',
stderr: 'rm: /Users/John/Library/Group Containers/UBF8T346G9.com.microsoft.teams: Operation not permitted\\n'
};

sinon.stub(process, 'platform').value('darwin');
sinon.stub(process, 'env').value({ 'CLIMICROSOFT365_ENV': '' });
sinon.stub(process, 'kill' as any).returns(null);
sinon.stub(fs, 'existsSync').returns(true);

sinon.stub(command, 'exec' as any).callsFake(async (opts) => {
if (opts === `ps ax | grep MacOS/MSTeams -m 1 | grep -v grep | awk '{ print $1 }'`) {
return {};
}
if (opts === `rm -r "${homedir}/Library/Group Containers/UBF8T346G9.com.microsoft.teams"`) {
return;
}
if (opts === `rm -r "${homedir}/Library/Containers/com.microsoft.teams2"`) {
throw deleteError;
}
throw 'Invalid request';
});
await command.action(logger, { options: { force: true } } as any);
assert(loggerLogSpy.calledWith('Deleting the folder failed. Please have a look at the following URL to delete the folders manually: https://answers.microsoft.com/en-us/msteams/forum/all/clearing-cache-on-microsoft-teams/35876f6b-eb1a-4b77-bed1-02ce3277091f'));
});

it('removes Teams cache from macOs platform without prompting.', async () => {
it('removes Teams cache from macOs platform without prompting using classic client', async () => {
sinon.stub(process, 'platform').value('darwin');
sinon.stub(process, 'env').value({ 'CLIMICROSOFT365_ENV': '' });
sinon.stub(command, 'exec' as any).returns({ stdout: '' });
Expand All @@ -156,13 +200,14 @@ describe(commands.CACHE_REMOVE, () => {
await command.action(logger, {
options: {
force: true,
verbose: true
verbose: true,
client: 'classic'
}
});
assert(true);
});

it('removes teams cache when teams is currently not active', async () => {
it('removes teams cache when teams is currently not active using the classic client', async () => {
sinon.stub(process, 'platform').value('win32');
sinon.stub(process, 'env').value({ 'CLIMICROSOFT365_ENV': '', APPDATA: 'C:\\Users\\Administrator\\AppData\\Roaming' });
sinon.stub(process, 'kill' as any).returns(null);
Expand All @@ -180,13 +225,14 @@ describe(commands.CACHE_REMOVE, () => {
await command.action(logger, {
options: {
force: true,
verbose: true
verbose: true,
client: 'classic'
}
});
assert(true);
});

it('removes Teams cache from win32 platform without prompting.', async () => {
it('removes Teams cache from win32 platform without prompting using the classic client', async () => {
sinon.stub(process, 'platform').value('win32');
sinon.stub(process, 'env').value({ 'CLIMICROSOFT365_ENV': '', APPDATA: 'C:\\Users\\Administrator\\AppData\\Roaming' });
sinon.stub(process, 'kill' as any).returns(null);
Expand All @@ -200,6 +246,30 @@ describe(commands.CACHE_REMOVE, () => {
throw 'Invalid request';
});
sinon.stub(fs, 'existsSync').returns(true);
await command.action(logger, {
options: {
force: true,
verbose: true,
client: 'classic'
}
});
assert(true);
});

it('removes Teams cache from win32 platform without prompting using the new client', async () => {
sinon.stub(process, 'platform').value('win32');
sinon.stub(process, 'env').value({ 'CLIMICROSOFT365_ENV': '', APPDATA: 'C:\\Users\\Administrator\\AppData\\Roaming', LOCALAPPDATA: 'C:\\Users\\Administrator\\AppData\\Local' });
sinon.stub(process, 'kill' as any).returns(null);
sinon.stub(command, 'exec' as any).callsFake(async (opts) => {
if (opts === 'wmic process where caption="ms-teams.exe" get ProcessId') {
return { stdout: processOutput };
}
if (opts === 'rmdir /s /q "C:\\Users\\Administrator\\AppData\\Local\\Packages\\MSTeams_8wekyb3d8bbwe\\LocalCache\\Microsoft\\MSTeams"') {
return;
}
throw 'Invalid request';
});
sinon.stub(fs, 'existsSync').returns(true);
await command.action(logger, {
options: {
force: true,
Expand All @@ -209,7 +279,7 @@ describe(commands.CACHE_REMOVE, () => {
assert(true);
});

it('removes Teams cache from darwin platform with prompting.', async () => {
it('removes Teams cache from darwin platform with prompting using the classic client', async () => {
sinon.stub(process, 'platform').value('darwin');
sinon.stub(process, 'env').value({ 'CLIMICROSOFT365_ENV': '' });
sinon.stub(command, 'exec' as any).returns({ stdout: 'pid' });
Expand All @@ -218,12 +288,70 @@ describe(commands.CACHE_REMOVE, () => {

await command.action(logger, {
options: {
debug: true
debug: true,
client: 'classic'
}
});
assert(true);
});

it('removes Teams cache from darwin platform with prompting', async () => {
sinon.stub(process, 'platform').value('darwin');
sinon.stub(process, 'env').value({ 'CLIMICROSOFT365_ENV': '' });
sinon.stub(command, 'exec' as any).returns({ stdout: '1111' });
sinon.stub(process, 'kill' as any).returns(null);
sinon.stub(fs, 'existsSync').returns(true);

await command.action(logger, {
options: {
debug: true,
client: 'new'
}
});
assert(true);
});

it('removes teams cache when teams is currently not running on macOS', async () => {
sinon.stub(process, 'platform').value('darwin');
sinon.stub(process, 'env').value({ 'CLIMICROSOFT365_ENV': '' });
sinon.stub(process, 'kill' as any).returns(null);
sinon.stub(command, 'exec' as any).callsFake(async (opts) => {
if (opts === `ps ax | grep MacOS/MSTeams -m 1 | grep -v grep | awk '{ print $1 }'`) {
return {};
}
if (opts === `rm -r "${os.homedir()}/Library/Group Containers/UBF8T346G9.com.microsoft.teams"`) {
return;
}
if (opts === `rm -r "${os.homedir()}/Library/Containers/com.microsoft.teams2"`) {
return;
}
throw 'Invalid request';
});
sinon.stub(fs, 'existsSync').returns(true);

await command.action(logger, {
options: {
force: true,
verbose: true,
client: 'new'
}
});
assert(true);
});


it('aborts cache clearing when no cache folder is found using the classic client', async () => {
sinon.stub(process, 'platform').value('darwin');
sinon.stub(process, 'env').value({ 'CLIMICROSOFT365_ENV': '' });
sinon.stub(fs, 'existsSync').returns(false);
await command.action(logger, {
options: {
verbose: true,
client: 'classic'
}
});
});

it('aborts cache clearing when no cache folder is found', async () => {
sinon.stub(process, 'platform').value('darwin');
sinon.stub(process, 'env').value({ 'CLIMICROSOFT365_ENV': '' });
Expand Down
Loading

0 comments on commit 37fe144

Please sign in to comment.