shared refactor

This commit is contained in:
compilando 2025-02-25 20:30:00 +01:00
parent 49b7ba2c78
commit 079cde591e
16 changed files with 6592 additions and 90 deletions

View file

@ -66,5 +66,11 @@
"tsconfig-paths": "^4.2.0", "tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3", "typescript": "^5.1.3",
"xss": "^1.0.15" "xss": "^1.0.15"
},
"pnpm": {
"onlyBuiltDependencies": [
"@nestjs/core",
"@scarf/scarf"
]
} }
} }

6495
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,9 @@
--DROP TABLE IF EXISTS rices; --DROP TABLE IF EXISTS rices;
CREATE TABLE rices ( CREATE TABLE shared (
id UUID NOT NULL, -- Unique identifier id UUID NOT NULL, -- Unique identifier
slug VARCHAR(75) NOT NULL, -- Unique user-friendly identifier slug VARCHAR(75) NOT NULL, -- Unique user-friendly identifier
type INTEGER DEFAULT 0 NOT NULL, -- Type: 1-WORKSPACE 2-RICE
version VARCHAR(10) NOT NULL, -- Data version version VARCHAR(10) NOT NULL, -- Data version
os VARCHAR(30) NOT NULL, -- Operating system os VARCHAR(30) NOT NULL, -- Operating system
name VARCHAR(75) NOT NULL, -- Name of the rice name VARCHAR(75) NOT NULL, -- Name of the rice
@ -19,7 +20,7 @@ CREATE TABLE rices (
CREATE OR REPLACE FUNCTION increment_visits(slug_param TEXT) CREATE OR REPLACE FUNCTION increment_visits(slug_param TEXT)
RETURNS VOID AS $$ RETURNS VOID AS $$
BEGIN BEGIN
UPDATE rices UPDATE shared
SET visits = visits + 1 SET visits = visits + 1
WHERE slug = slug_param; WHERE slug = slug_param;
END; END;

View file

@ -3,7 +3,7 @@ import { ConfigModule } from '@nestjs/config';
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler'; import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
import { APP_GUARD } from '@nestjs/core'; import { APP_GUARD } from '@nestjs/core';
import { GitHubModule } from './github/github.module'; import { GitHubModule } from './github/github.module';
import { RicesModule } from './rices/rices.module'; import { SharedModule } from './shared/shared.module';
import { ThrottlerExceptionFilter } from './common/filters/throttler-exception.filter'; import { ThrottlerExceptionFilter } from './common/filters/throttler-exception.filter';
@Module({ @Module({
@ -29,7 +29,7 @@ import { ThrottlerExceptionFilter } from './common/filters/throttler-exception.f
}, },
]), ]),
GitHubModule, GitHubModule,
RicesModule, SharedModule,
], ],
controllers: [], controllers: [],
providers: [ providers: [

View file

@ -1,6 +1,6 @@
import { IsString } from 'class-validator'; import { IsString } from 'class-validator';
export class CreateRiceDto { export class CreateSharedDto {
@IsString() @IsString()
name!: string; name!: string;

View file

@ -1,6 +1,6 @@
import { IsString } from 'class-validator'; import { IsString } from 'class-validator';
export class UpdateRiceDto { export class UpdateSharedDto {
@IsString() @IsString()
content!: string; content!: string;
} }

View file

@ -14,24 +14,24 @@ import {
Res, Res,
} from '@nestjs/common'; } from '@nestjs/common';
import { Response } from 'express'; import { Response } from 'express';
import { RicesService } from './rices.service'; import { SharedService } from './shared.service';
import { ApiTags, ApiOperation, ApiResponse, ApiHeader } from '@nestjs/swagger'; import { ApiTags, ApiOperation, ApiResponse, ApiHeader } from '@nestjs/swagger';
@ApiTags('rices') @ApiTags('rices')
@Controller('rices') @Controller('rices')
export class RicesController { export class RicesController {
constructor(private readonly ricesService: RicesService) {} constructor(private readonly sharedService: SharedService) {}
@ApiOperation({ summary: 'Upload a new Rice' }) @ApiOperation({ summary: 'Upload a new Rice' })
@ApiResponse({ status: 201, description: 'Rice successfully created.' }) @ApiResponse({ status: 201, description: 'Rice successfully created.' })
@ApiHeader({ @ApiHeader({
name: 'X-Zen-Rice-Name', name: 'x-zen-shared-name',
description: 'Name of the rice', description: 'Name of the Shared',
required: true, required: true,
}) })
@ApiHeader({ @ApiHeader({
name: 'X-Zen-Rice-Author', name: 'x-zen-shared-author',
description: 'Author of the rice', description: 'Author of the Shared',
required: true, required: true,
}) })
@ApiHeader({ @ApiHeader({
@ -43,14 +43,14 @@ export class RicesController {
async createRice( async createRice(
@Body() content: string, @Body() content: string,
@Headers() headers: Record<string, string>, @Headers() headers: Record<string, string>,
@Headers('x-zen-rices-token') token: string, @Headers('x-zen-shared-token') token: string,
) { ) {
const contentString = const contentString =
typeof content === 'string' ? content : JSON.stringify(content); typeof content === 'string' ? content : JSON.stringify(content);
this.validateFileSize(contentString); // Validate file size this.validateFileSize(contentString); // Validate file size
return this.ricesService.create(contentString, token, headers); return this.sharedService.create(contentString, token, headers);
} }
@ApiOperation({ summary: 'Get information about a Rice' }) @ApiOperation({ summary: 'Get information about a Rice' })
@ -60,7 +60,7 @@ export class RicesController {
}) })
@Get(':slug') @Get(':slug')
async getRice(@Param('slug') slug: string, @Res() res: Response) { async getRice(@Param('slug') slug: string, @Res() res: Response) {
const riceMetadata = await this.ricesService.getRiceMetadata(slug); const riceMetadata = await this.sharedService.getRiceMetadata(slug);
const htmlContent = `<!DOCTYPE html> const htmlContent = `<!DOCTYPE html>
<html lang="en"> <html lang="en">
@ -94,13 +94,13 @@ export class RicesController {
@ApiOperation({ summary: 'Update an existing Rice' }) @ApiOperation({ summary: 'Update an existing Rice' })
@ApiResponse({ status: 200, description: 'Rice successfully updated.' }) @ApiResponse({ status: 200, description: 'Rice successfully updated.' })
@ApiHeader({ @ApiHeader({
name: 'X-Zen-Rice-Name', name: 'x-zen-shared-name',
description: 'Name of the rice', description: 'Name of the shared',
required: true, required: true,
}) })
@ApiHeader({ @ApiHeader({
name: 'X-Zen-Rice-Author', name: 'x-zen-shared-author',
description: 'Author of the rice', description: 'Author of the shared',
required: true, required: true,
}) })
@ApiHeader({ @ApiHeader({
@ -113,14 +113,14 @@ export class RicesController {
@Param('slug') slug: string, @Param('slug') slug: string,
@Body() content: string, @Body() content: string,
@Headers() headers: Record<string, string>, @Headers() headers: Record<string, string>,
@Headers('x-zen-rices-token') token: string, @Headers('x-zen-shared-token') token: string,
) { ) {
const contentString = const contentString =
typeof content === 'string' ? content : JSON.stringify(content); typeof content === 'string' ? content : JSON.stringify(content);
this.validateFileSize(contentString); // Validate file size this.validateFileSize(contentString); // Validate file size
return this.ricesService.update(slug, token, contentString, headers); return this.sharedService.update(slug, token, contentString, headers);
} }
@ApiOperation({ summary: 'Delete an existing Rice' }) @ApiOperation({ summary: 'Delete an existing Rice' })
@ -129,9 +129,9 @@ export class RicesController {
@Delete(':slug') @Delete(':slug')
async removeRice( async removeRice(
@Param('slug') slug: string, @Param('slug') slug: string,
@Headers('x-zen-rices-token') token: string, @Headers('x-zen-shared-token') token: string,
) { ) {
await this.ricesService.remove(slug, token); await this.sharedService.remove(slug, token);
return; return;
} }
@ -150,7 +150,7 @@ export class RicesController {
if (moderationSecret !== process.env.MODERATION_SECRET) { if (moderationSecret !== process.env.MODERATION_SECRET) {
throw new UnauthorizedException('Invalid moderation secret'); throw new UnauthorizedException('Invalid moderation secret');
} }
await this.ricesService.moderateRemove(slug); await this.sharedService.moderateRemove(slug);
return; return;
} }

View file

@ -1,15 +1,15 @@
// src/rices/rices.module.ts // src/rices/rices.module.ts
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { RicesService } from './rices.service'; import { SharedService } from './shared.service';
import { GitHubModule } from '../github/github.module'; import { GitHubModule } from '../github/github.module';
import { RicesController } from './rices.controller'; import { RicesController } from './rices.controller';
import { SupabaseService } from '../supabase/supabase.service'; import { SupabaseService } from '../supabase/supabase.service';
@Module({ @Module({
imports: [GitHubModule], imports: [GitHubModule],
providers: [RicesService, SupabaseService], providers: [SharedService, SupabaseService],
controllers: [RicesController], controllers: [RicesController],
exports: [RicesService], exports: [SharedService],
}) })
export class RicesModule {} export class SharedModule {}

View file

@ -17,7 +17,7 @@ import { SupabaseService } from '../supabase/supabase.service';
const userAgentRegex = /ZenBrowser\/(\d+\.\d\w?\.\d) \((.+)\)/; const userAgentRegex = /ZenBrowser\/(\d+\.\d\w?\.\d) \((.+)\)/;
@Injectable() @Injectable()
export class RicesService { export class SharedService {
constructor( constructor(
private readonly gitHubService: GitHubService, private readonly gitHubService: GitHubService,
private readonly supabaseService: SupabaseService, private readonly supabaseService: SupabaseService,
@ -31,8 +31,8 @@ export class RicesService {
) { ) {
try { try {
// Validate headers // Validate headers
const name = headers['x-zen-rice-name']; const name = headers['x-zen-shared-name'];
const author = headers['x-zen-rice-author']; const author = headers['x-zen-shared-author'];
const userAgent = headers['user-agent']; const userAgent = headers['user-agent'];
if (!name || !author || !userAgent) { if (!name || !author || !userAgent) {
@ -58,13 +58,13 @@ export class RicesService {
// Validate lengths // Validate lengths
if (name.length > 75) { if (name.length > 75) {
throw new BadRequestException( throw new BadRequestException(
`The value of X-Zen-Rice-Name exceeds the maximum allowed length of 75 characters.`, `The value of x-zen-shared-name exceeds the maximum allowed length of 75 characters.`,
); );
} }
if (author.length > 100) { if (author.length > 100) {
throw new BadRequestException( throw new BadRequestException(
`The value of X-Zen-Rice-Author exceeds the maximum allowed length of 100 characters.`, `The value of x-zen-shared-author exceeds the maximum allowed length of 100 characters.`,
); );
} }
@ -113,7 +113,7 @@ export class RicesService {
'MAX_RICES_BY_TOKEN', 'MAX_RICES_BY_TOKEN',
5, 5,
); );
const tokenCount = await this.supabaseService.countRicesByToken(token); const tokenCount = await this.supabaseService.countSharedByToken(token);
if (tokenCount >= tokenMaxCount) { if (tokenCount >= tokenMaxCount) {
throw new ConflictException( throw new ConflictException(
`The token '${token}' is already associated with 5 or more rices.`, `The token '${token}' is already associated with 5 or more rices.`,
@ -135,7 +135,7 @@ export class RicesService {
}; };
// Insert metadata into Supabase // Insert metadata into Supabase
await this.supabaseService.insertRice(metadata); await this.supabaseService.insertShared(metadata);
const uploadedFilePath = `rices/${slug}/data.zenrice`; const uploadedFilePath = `rices/${slug}/data.zenrice`;
await this.gitHubService.createOrUpdateFile( await this.gitHubService.createOrUpdateFile(
@ -153,7 +153,7 @@ export class RicesService {
async findOne(slug: string) { async findOne(slug: string) {
// Check if the rice exists in the database // Check if the rice exists in the database
const rice = await this.supabaseService.getRiceBySlug(slug); const rice = await this.supabaseService.getSharedBySlug(slug);
if (!rice) throw new NotFoundException('Rice not found'); if (!rice) throw new NotFoundException('Rice not found');
// Fetch the file from GitHub // Fetch the file from GitHub
@ -171,7 +171,7 @@ export class RicesService {
} }
async getRiceMetadata(slug: string) { async getRiceMetadata(slug: string) {
const rice = await this.supabaseService.getRiceBySlug(slug); const rice = await this.supabaseService.getSharedBySlug(slug);
if (!rice) throw new NotFoundException('Rice not found'); if (!rice) throw new NotFoundException('Rice not found');
return rice; return rice;
@ -216,7 +216,7 @@ export class RicesService {
const [, version, os] = match; const [, version, os] = match;
// Check if the rice exists // Check if the rice exists
const rice = await this.supabaseService.getRiceBySlug(slug); const rice = await this.supabaseService.getSharedBySlug(slug);
if (!rice) { if (!rice) {
throw new NotFoundException('Rice not found'); throw new NotFoundException('Rice not found');
} }
@ -233,7 +233,7 @@ export class RicesService {
updated_at: new Date().toISOString(), updated_at: new Date().toISOString(),
}; };
await this.supabaseService.updateRice(slug, updatedMetadata); await this.supabaseService.updateShared(slug, updatedMetadata);
const uploadedFilePath = `rices/${slug}/data.zenrice`; const uploadedFilePath = `rices/${slug}/data.zenrice`;
await this.gitHubService.createOrUpdateFile( await this.gitHubService.createOrUpdateFile(
@ -250,7 +250,7 @@ export class RicesService {
} }
async remove(slug: string, token: string): Promise<void> { async remove(slug: string, token: string): Promise<void> {
const rice = await this.supabaseService.getRiceBySlug(slug); const rice = await this.supabaseService.getSharedBySlug(slug);
if (!rice) throw new NotFoundException('Rice not found'); if (!rice) throw new NotFoundException('Rice not found');
if (rice.token !== token) throw new UnauthorizedException('Invalid token'); if (rice.token !== token) throw new UnauthorizedException('Invalid token');
@ -259,7 +259,7 @@ export class RicesService {
throw new UnauthorizedException('Invalid token.'); throw new UnauthorizedException('Invalid token.');
} }
await this.supabaseService.deleteRice(slug); await this.supabaseService.deleteShared(slug);
const folderPath = `rices/${slug}`; const folderPath = `rices/${slug}`;
@ -289,13 +289,13 @@ export class RicesService {
public async moderateRemove(slug: string): Promise<void> { public async moderateRemove(slug: string): Promise<void> {
try { try {
// 1. Check if rice exists in Supabase // 1. Check if rice exists in Supabase
const rice = await this.supabaseService.getRiceBySlug(slug); const rice = await this.supabaseService.getSharedBySlug(slug);
if (!rice) { if (!rice) {
throw new NotFoundException('Rice not found'); throw new NotFoundException('Rice not found');
} }
// 2. Delete metadata from Supabase // 2. Delete metadata from Supabase
await this.supabaseService.deleteRice(slug); await this.supabaseService.deleteShared(slug);
// 3. Delete data.zenrice from GitHub // 3. Delete data.zenrice from GitHub
const riceJsonPath = `rices/${slug}/data.zenrice`; const riceJsonPath = `rices/${slug}/data.zenrice`;

View file

@ -17,42 +17,42 @@ export class SupabaseService {
this.supabase = createClient(this.supabase_url, this.supabase_key); this.supabase = createClient(this.supabase_url, this.supabase_key);
} }
async insertRice(metadata: any) { async insertShared(metadata: any) {
const { error } = await this.supabase.from('rices').insert(metadata); const { error } = await this.supabase.from('shared').insert(metadata);
if (error) { if (error) {
this.logger.error( this.logger.error(
`Failed to insert rice: ${error.message}`, `Failed to insert shared: ${error.message}`,
error.details, error.details,
); );
throw new Error(`Failed to insert rice: ${error.message}`); throw new Error(`Failed to insert shared: ${error.message}`);
} }
} }
async getRiceById(id: string) { async getSharedById(id: string) {
const { data, error } = await this.supabase const { data, error } = await this.supabase
.from('rices') .from('shared')
.select('*') .select('*')
.eq('id', id) .eq('id', id)
.single(); .single();
if (error) { if (error) {
this.logger.error( this.logger.error(
`Failed to fetch rice with ID ${id}: ${error.message}`, `Failed to fetch shared with ID ${id}: ${error.message}`,
error.details, error.details,
); );
throw new Error(`Failed to fetch rice: ${error.message}`); throw new Error(`Failed to fetch shared: ${error.message}`);
} }
return data; return data;
} }
async getRiceBySlug(slug: string) { async getSharedBySlug(slug: string) {
const { data, error } = await this.supabase const { data, error } = await this.supabase
.from('rices') .from('shared')
.select('*') .select('*')
.eq('slug', slug) .eq('slug', slug)
.single(); .single();
if (error) { if (error) {
this.logger.error( this.logger.error(
`Failed to fetch rice with slug ${slug}: ${error.message}`, `Failed to fetch shared with slug ${slug}: ${error.message}`,
error.details, error.details,
); );
return null; return null;
@ -60,48 +60,48 @@ export class SupabaseService {
return data; return data;
} }
async getRiceByName(name: string) { async getSharedByName(name: string) {
const { data, error } = await this.supabase const { data, error } = await this.supabase
.from('rices') .from('shared')
.select('*') .select('*')
.eq('name', name) .eq('name', name)
.single(); .single();
if (error && error.code !== 'PGRST116') { if (error && error.code !== 'PGRST116') {
// Handle "no rows found" separately // Handle "no rows found" separately
this.logger.error( this.logger.error(
`Failed to fetch rice with name ${name}: ${error.message}`, `Failed to fetch shared with name ${name}: ${error.message}`,
error.details, error.details,
); );
throw new Error(`Failed to fetch rice: ${error.message}`); throw new Error(`Failed to fetch shared: ${error.message}`);
} }
return data; return data;
} }
async updateRice(slug: string, metadata: any) { async updateShared(slug: string, metadata: any) {
const { error } = await this.supabase const { error } = await this.supabase
.from('rices') .from('shared')
.update(metadata) .update(metadata)
.eq('slug', slug); .eq('slug', slug);
if (error) { if (error) {
this.logger.error( this.logger.error(
`Failed to update rice with slug ${slug}: ${error.message}`, `Failed to update shared with slug ${slug}: ${error.message}`,
error.details, error.details,
); );
throw new Error(`Failed to update rice: ${error.message}`); throw new Error(`Failed to update shared: ${error.message}`);
} }
} }
async deleteRice(slug: string) { async deleteShared(slug: string) {
const { error } = await this.supabase const { error } = await this.supabase
.from('rices') .from('shared')
.delete() .delete()
.eq('slug', slug); .eq('slug', slug);
if (error) { if (error) {
this.logger.error( this.logger.error(
`Failed to delete rice with slug ${slug}: ${error.message}`, `Failed to delete shared with slug ${slug}: ${error.message}`,
error.details, error.details,
); );
throw new Error(`Failed to delete rice: ${error.message}`); throw new Error(`Failed to delete shared: ${error.message}`);
} }
} }
@ -112,7 +112,7 @@ export class SupabaseService {
if (error) { if (error) {
this.logger.error( this.logger.error(
`Failed to increment visits for rice with slug ${slug}: ${error.message}`, `Failed to increment visits for shared with slug ${slug}: ${error.message}`,
error.details, error.details,
); );
throw new Error(`Failed to increment visits: ${error.message}`); throw new Error(`Failed to increment visits: ${error.message}`);
@ -121,27 +121,27 @@ export class SupabaseService {
async updateLevel(slug: string, level: number) { async updateLevel(slug: string, level: number) {
const { error } = await this.supabase const { error } = await this.supabase
.from('rices') .from('shared')
.update({ level }) .update({ level })
.eq('slug', slug); .eq('slug', slug);
if (error) { if (error) {
this.logger.error( this.logger.error(
`Failed to update level for rice with slug ${slug}: ${error.message}`, `Failed to update level for shared with slug ${slug}: ${error.message}`,
error.details, error.details,
); );
throw new Error(`Failed to update rice level: ${error.message}`); throw new Error(`Failed to update shared level: ${error.message}`);
} }
} }
async countRicesByToken(token: string): Promise<number> { async countSharedByToken(token: string): Promise<number> {
const { data, error, count } = await this.supabase const { data, error, count } = await this.supabase
.from('rices') // Nombre de tu tabla en Supabase .from('shared') // Nombre de tu tabla en Supabase
.select('*', { count: 'exact' }) .select('*', { count: 'exact' })
.eq('token', token); .eq('token', token);
if (error) { if (error) {
console.error('Error counting rices by token:', error); console.error('Error counting shared by token:', error);
throw new Error('Failed to count rices by token'); throw new Error('Failed to count shared by token');
} }
return count || 0; return count || 0;

View file

@ -48,7 +48,7 @@ describe('Rices API E2E', () => {
expect(slug).toBeDefined(); expect(slug).toBeDefined();
expect(token).toBeDefined(); expect(token).toBeDefined();
const riceInDatabase = await supabaseService.getRiceBySlug(slug); const riceInDatabase = await supabaseService.getSharedBySlug(slug);
expect(riceInDatabase).not.toBeNull(); expect(riceInDatabase).not.toBeNull();
expect(riceInDatabase.name).toBe('Test Rice'); expect(riceInDatabase.name).toBe('Test Rice');
@ -67,12 +67,12 @@ describe('Rices API E2E', () => {
const { slug } = createResponse.body; const { slug } = createResponse.body;
const initialData = await supabaseService.getRiceBySlug(slug); const initialData = await supabaseService.getSharedBySlug(slug);
expect(initialData.visits).toBe(0); expect(initialData.visits).toBe(0);
await request(app.getHttpServer()).get(`/rices/${slug}`).expect(200); await request(app.getHttpServer()).get(`/rices/${slug}`).expect(200);
const updatedData = await supabaseService.getRiceBySlug(slug); const updatedData = await supabaseService.getSharedBySlug(slug);
expect(updatedData.visits).toBe(1); expect(updatedData.visits).toBe(1);
}); });
@ -87,14 +87,14 @@ describe('Rices API E2E', () => {
const updateResponse = await request(app.getHttpServer()) const updateResponse = await request(app.getHttpServer())
.put(`/rices/${slug}`) .put(`/rices/${slug}`)
.set('x-zen-rices-token', token) .set('x-zen-shared-token', token)
.field('name', 'Updated Rice') .field('name', 'Updated Rice')
.attach('file', path.join(__dirname, 'files', 'example_update.zenrice')) .attach('file', path.join(__dirname, 'files', 'example_update.zenrice'))
.expect(200); .expect(200);
expect(updateResponse.body.message).toBe(`ok`); expect(updateResponse.body.message).toBe(`ok`);
const updatedData = await supabaseService.getRiceBySlug(slug); const updatedData = await supabaseService.getSharedBySlug(slug);
expect(updatedData.name).toBe('Updated Rice'); expect(updatedData.name).toBe('Updated Rice');
const updatedFile = await gitHubService.getFileContent( const updatedFile = await gitHubService.getFileContent(
@ -116,10 +116,10 @@ describe('Rices API E2E', () => {
await request(app.getHttpServer()) await request(app.getHttpServer())
.delete(`/rices/${slug}`) .delete(`/rices/${slug}`)
.set('x-zen-rices-token', token) .set('x-zen-shared-token', token)
.expect(204); .expect(204);
const riceInDatabase = await supabaseService.getRiceBySlug(slug); const riceInDatabase = await supabaseService.getSharedBySlug(slug);
expect(riceInDatabase).toBeNull(); expect(riceInDatabase).toBeNull();
const fileInGitHub = await gitHubService.getFileContent( const fileInGitHub = await gitHubService.getFileContent(
@ -142,7 +142,7 @@ describe('Rices API E2E', () => {
.set('x-moderation-secret', moderationSecret) .set('x-moderation-secret', moderationSecret)
.expect(204); .expect(204);
const riceInDatabase = await supabaseService.getRiceBySlug(slug); const riceInDatabase = await supabaseService.getSharedBySlug(slug);
expect(riceInDatabase).toBeNull(); expect(riceInDatabase).toBeNull();
const fileInGitHub = await gitHubService.getFileContent( const fileInGitHub = await gitHubService.getFileContent(
@ -165,7 +165,7 @@ describe('Rices API E2E', () => {
.set('x-moderation-secret', 'wrongSecret') .set('x-moderation-secret', 'wrongSecret')
.expect(401); .expect(401);
const riceInDatabase = await supabaseService.getRiceBySlug(slug); const riceInDatabase = await supabaseService.getSharedBySlug(slug);
expect(riceInDatabase).not.toBeNull(); expect(riceInDatabase).not.toBeNull();
}); });
}); });

View file

@ -2,8 +2,8 @@
POST {{baseUrl}}/rices POST {{baseUrl}}/rices
Content-Type: application/json Content-Type: application/json
X-Zen-Rice-Name: cool-zenrice-test-base x-zen-shared-name: cool-zenrice-test-base
X-Zen-Rice-Author: jhon@doe.com x-zen-shared-author: jhon@doe.com
User-Agent: ZenBrowser/1.2b.0 (EndeavourOS x86_64) User-Agent: ZenBrowser/1.2b.0 (EndeavourOS x86_64)
{ {

View file

@ -4,9 +4,9 @@
POST {{baseUrl}}/rices POST {{baseUrl}}/rices
Content-Type: application/json Content-Type: application/json
X-Zen-Rice-Name: cool-zenrice-test-base5 x-zen-shared-name: cool-zenrice-test-base
X-Zen-Rice-Author: jhon@doe.com x-zen-shared-author: jhon@doe.com
x-zen-rices-token: {{previous_token}} x-zen-shared-token: {{previous_token}}
User-Agent: ZenBrowser/1.2b.0 (EndeavourOS x86_64) User-Agent: ZenBrowser/1.2b.0 (EndeavourOS x86_64)
{ {

View file

@ -4,7 +4,7 @@
PUT {{baseUrl}}/rices/{{previous_slug}} PUT {{baseUrl}}/rices/{{previous_slug}}
Content-Type: application/json Content-Type: application/json
x-zen-rices-token: {{previous_token}} x-zen-shared-token: {{previous_token}}
User-Agent: ZenBrowser/1.2b.0 (EndeavourOS x86_64) User-Agent: ZenBrowser/1.2b.0 (EndeavourOS x86_64)
{ {

View file

@ -3,4 +3,4 @@
@previous_token = 03fbfdb4-d3a5-4d64-8740-feac7d32e7a8 @previous_token = 03fbfdb4-d3a5-4d64-8740-feac7d32e7a8
DELETE {{baseUrl}}/rices/{{previous_slug}} DELETE {{baseUrl}}/rices/{{previous_slug}}
x-zen-rices-token: {{previous_token}} x-zen-shared-token: {{previous_token}}