@@ -1780,4 +1780,86 @@ describe('useNodePricing', () => {
17801780 } )
17811781 } )
17821782 } )
1783+
1784+ describe ( 'dynamic pricing - ByteDance Seedance video nodes' , ( ) => {
1785+ it ( 'should return base 10s range for PRO 1080p on ByteDanceTextToVideoNode' , ( ) => {
1786+ const { getNodeDisplayPrice } = useNodePricing ( )
1787+ const node = createMockNode ( 'ByteDanceTextToVideoNode' , [
1788+ { name : 'model' , value : 'seedance-1-0-pro' } ,
1789+ { name : 'duration' , value : '10' } ,
1790+ { name : 'resolution' , value : '1080p' }
1791+ ] )
1792+
1793+ const price = getNodeDisplayPrice ( node )
1794+ expect ( price ) . toBe ( '$1.18-$1.22/Run' )
1795+ } )
1796+
1797+ it ( 'should scale to half for 5s PRO 1080p on ByteDanceTextToVideoNode' , ( ) => {
1798+ const { getNodeDisplayPrice } = useNodePricing ( )
1799+ const node = createMockNode ( 'ByteDanceTextToVideoNode' , [
1800+ { name : 'model' , value : 'seedance-1-0-pro' } ,
1801+ { name : 'duration' , value : '5' } ,
1802+ { name : 'resolution' , value : '1080p' }
1803+ ] )
1804+
1805+ const price = getNodeDisplayPrice ( node )
1806+ expect ( price ) . toBe ( '$0.59-$0.61/Run' )
1807+ } )
1808+
1809+ it ( 'should scale for 8s PRO 480p on ByteDanceImageToVideoNode' , ( ) => {
1810+ const { getNodeDisplayPrice } = useNodePricing ( )
1811+ const node = createMockNode ( 'ByteDanceImageToVideoNode' , [
1812+ { name : 'model' , value : 'seedance-1-0-pro' } ,
1813+ { name : 'duration' , value : '8' } ,
1814+ { name : 'resolution' , value : '480p' }
1815+ ] )
1816+
1817+ const price = getNodeDisplayPrice ( node )
1818+ expect ( price ) . toBe ( '$0.18-$0.19/Run' )
1819+ } )
1820+
1821+ it ( 'should scale correctly for 12s PRO 720p on ByteDanceFirstLastFrameNode' , ( ) => {
1822+ const { getNodeDisplayPrice } = useNodePricing ( )
1823+ const node = createMockNode ( 'ByteDanceFirstLastFrameNode' , [
1824+ { name : 'model' , value : 'seedance-1-0-pro' } ,
1825+ { name : 'duration' , value : '12' } ,
1826+ { name : 'resolution' , value : '720p' }
1827+ ] )
1828+
1829+ const price = getNodeDisplayPrice ( node )
1830+ expect ( price ) . toBe ( '$0.61-$0.67/Run' )
1831+ } )
1832+
1833+ it ( 'should collapse to a single value when min and max round equal for LITE 480p 3s on ByteDanceImageReferenceNode' , ( ) => {
1834+ const { getNodeDisplayPrice } = useNodePricing ( )
1835+ const node = createMockNode ( 'ByteDanceImageReferenceNode' , [
1836+ { name : 'model' , value : 'seedance-1-0-lite' } ,
1837+ { name : 'duration' , value : '3' } ,
1838+ { name : 'resolution' , value : '480p' }
1839+ ] )
1840+
1841+ const price = getNodeDisplayPrice ( node )
1842+ expect ( price ) . toBe ( '$0.05/Run' ) // 0.17..0.18 scaled by 0.3 both round to 0.05
1843+ } )
1844+
1845+ it ( 'should return Token-based when required widgets are missing' , ( ) => {
1846+ const { getNodeDisplayPrice } = useNodePricing ( )
1847+ const missingModel = createMockNode ( 'ByteDanceFirstLastFrameNode' , [
1848+ { name : 'duration' , value : '10' } ,
1849+ { name : 'resolution' , value : '1080p' }
1850+ ] )
1851+ const missingResolution = createMockNode ( 'ByteDanceImageToVideoNode' , [
1852+ { name : 'model' , value : 'seedance-1-0-pro' } ,
1853+ { name : 'duration' , value : '10' }
1854+ ] )
1855+ const missingDuration = createMockNode ( 'ByteDanceTextToVideoNode' , [
1856+ { name : 'model' , value : 'seedance-1-0-lite' } ,
1857+ { name : 'resolution' , value : '720p' }
1858+ ] )
1859+
1860+ expect ( getNodeDisplayPrice ( missingModel ) ) . toBe ( 'Token-based' )
1861+ expect ( getNodeDisplayPrice ( missingResolution ) ) . toBe ( 'Token-based' )
1862+ expect ( getNodeDisplayPrice ( missingDuration ) ) . toBe ( 'Token-based' )
1863+ } )
1864+ } )
17831865} )
0 commit comments